diff options
Diffstat (limited to 'src')
46 files changed, 4434 insertions, 1888 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index a01ed63..1250b59 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -81,6 +81,7 @@ libchrysacore4_la_LIBADD =					\  	arch/libarch4.la						\  	common/libcommon4.la					\  	core/libcore4.la						\ +	glibext/libglibext4.la					\  	plugins/libplugins.la  libchrysacore4_la_LDFLAGS =					\ @@ -98,8 +99,10 @@ libchrysacoreui_la_LIBADD =					\  	gtkext/libgtkext4.la					\  	gui/libgui4.la +# -lm: log()  libchrysacoreui_la_LDFLAGS =				\ -	$(LIBGTK4_CFLAGS) -L.libs -lchrysacore4 +	$(LIBGTK4_CFLAGS) -L.libs -lchrysacore4	\ +	-lm diff --git a/src/common/Makefile.am b/src/common/Makefile.am index a57868d..8161f8e 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -17,7 +17,6 @@ libcommon_la_SOURCES =					\  	ibuf.h ibuf.c						\  	io.h io.c							\  	itoa.h itoa.c						\ -	fnv1a.h fnv1a.c						\  	leb128.h leb128.c					\  	macros.h							\  	net.h net.c							\ @@ -58,6 +57,7 @@ libcommon4_la_SOURCES =						\  	datatypes.h								\  	environment.h environment.c				\  	extstr.h extstr.c						\ +	fnv1a.h fnv1a.c							\  	io.h io.c								\  	leb128.h leb128.c						\  	packed.h packed.c						\ diff --git a/src/core/core.c b/src/core/core.c index addd58c..f67e23d 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -183,7 +183,7 @@ void unload_all_core_components(bool cs)  /******************************************************************************  *                                                                             * -*  Paramètres  : selected = liste d'éléments à décharger.                     * +*  Paramètres  : flags = liste d'éléments à charger.                          *  *                                                                             *  *  Description : Charge une sélection d'éléments de base du programme.        *  *                                                                             * @@ -231,7 +231,7 @@ bool load_core_components(AvailableCoreComponent flags)  /******************************************************************************  *                                                                             * -*  Paramètres  : selected = liste d'éléments à décharger.                     * +*  Paramètres  : flags = liste d'éléments à décharger.                        *  *                                                                             *  *  Description : Décharge une sélection d'éléments de base du programme.      *  *                                                                             * diff --git a/src/framework.c b/src/framework.c index b7a1332..96c97c3 100644 --- a/src/framework.c +++ b/src/framework.c @@ -28,6 +28,9 @@  #include "framework.h"  #include "glibext/helpers.h" +#include "gui/core/core.h" +#include "analysis/contents/file.h" // REMME +#include "gtkext/hexview.h" // REMME @@ -249,8 +252,63 @@ static void gtk_chrysalide_framework_activate(GApplication *app)      gtk_window_set_title(window, "Chrysalide");      gtk_window_present(window); + +    do +    { +        GBinContent *cnt; + +        GtkWidget *parent; +        GtkHexView *wgt; + + +#if 0 + +        cnt = g_file_content_new("tmp.bin"); + +        parent = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); +        gtk_box_set_homogeneous(GTK_BOX(parent), FALSE); +        gtk_window_set_child(window, parent); + +        wgt = gtk_hex_view_new(cnt); +        gtk_box_append(GTK_BOX(parent), GTK_WIDGET(wgt)); + +        wgt = gtk_hex_view_new(cnt); +        gtk_box_append(GTK_BOX(parent), GTK_WIDGET(wgt)); + +#else + +        cnt = g_file_content_new("/bin/id"); +        //cnt = g_file_content_new("tmp.bin"); + + +        parent = gtk_scrolled_window_new(); +        gtk_window_set_child(window, parent); + +        wgt = gtk_hex_view_new(cnt); +        gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(parent), GTK_WIDGET(wgt)); + +#endif + + + + +    } +    while (0); + +      /* Chargement des extensions de thème */ +    /* +    css = gtk_css_provider_new(); + +    gtk_css_provider_load_from_resource(css, "/re/chrysalide/framework/glibext/linestyle.css"); + +    gtk_style_context_add_provider_for_display(gtk_widget_get_display(GTK_WIDGET(window)), +                                               GTK_STYLE_PROVIDER(css), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + +    unref_object(css); +    */ +      css = gtk_css_provider_new();      gtk_css_provider_load_from_resource(css, "/re/chrysalide/framework/gtkext/hexview.css"); @@ -287,12 +345,17 @@ int main(int argc, char **argv)      int result;                             /* Bilan de l'exécution        */      GtkChrysalideFramework *app;            /* Gestion d'application GTK   */ +    if (!load_gui_components(AGC_BUFFER_FEATURES)) +        return EXIT_FAILURE; +      app = gtk_chrysalide_framework_new();      result = g_application_run(G_APPLICATION(app), argc, argv);      g_object_unref(G_OBJECT(app)); +    unload_gui_components(AGC_BUFFER_FEATURES); +      return result;  } diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index ba4e3fa..e2c9d69 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -4,10 +4,6 @@ BUILT_SOURCES = chrysamarshal.h chrysamarshal.c resources.h resources.c  noinst_LTLIBRARIES  = libglibext4.la libglibextui.la # libglibext.la  libglibext_la_SOURCES =						\ -	buffercache-int.h						\ -	buffercache.h buffercache.c				\ -	bufferline.h bufferline.c				\ -	chrysamarshal.h chrysamarshal.c			\  	comparison-int.h						\  	comparison.h comparison.c				\  	configuration-int.h						\ @@ -17,11 +13,9 @@ libglibext_la_SOURCES =						\  	gbinarycursor.h gbinarycursor.c			\  	gbinportion-int.h						\  	gbinportion.h gbinportion.c				\ -	displayoptions.h displayoptions.c		\  	glinecursor-int.h						\  	glinecursor.h glinecursor.c				\  	gnhash.h gnhash.c						\ -	linecolumn.h linecolumn.c				\  	notifier.h								\  	objhole.h								\  	proto.h									\ @@ -35,12 +29,10 @@ libglibext_la_SOURCES =						\  if BUILD_GTK_SUPPORT  libglibext_la_SOURCES +=					\ -	bufferview.h bufferview.c				\  	gloadedpanel-int.h						\  	gloadedpanel.h gloadedpanel.c			\  	named-int.h								\ -	named.h named.c							\ -	widthtracker.h widthtracker.c +	named.h named.c  endif @@ -51,6 +43,7 @@ libglibext_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)  libglibext4_la_SOURCES =					\ +	chrysamarshal.h chrysamarshal.c			\  	helpers.h  libglibext4_la_CFLAGS = $(TOOLKIT_CFLAGS) @@ -60,19 +53,37 @@ RES_FILES =									\  	tokenstyle.css  libglibextui_la_SOURCES =					\ +	buffercache-int.h						\ +	buffercache.h buffercache.c				\ +	bufferline-int.h						\ +	bufferline.h bufferline.c				\ +	bufferview-int.h						\ +	bufferview.h bufferview.c				\ +	generator-int.h							\ +	generator.h generator.c					\ +	linecolumn.h linecolumn.c				\ +	linetoken.h linetoken.c					\ +	options-int.h							\ +	options.h options.c						\  	tokenstyle-int.h						\  	tokenstyle.h tokenstyle.c				\ -	resources.h resources.c +	resources.h resources.c					\ +	widthtracker-int.h						\ +	widthtracker.h widthtracker.c  libglibextui_la_CFLAGS = $(LIBGTK4_CFLAGS) +libglibextui_la_LIBADD = 					\ +	generators/libglibextgenerators.la		\ +	options/libglibextoptions.la +  devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)  dev_HEADERS = $(libglibext_la_SOURCES:%c=) -#SUBDIRS = generators +SUBDIRS = generators options  chrysamarshal.h: chrysamarshal.list diff --git a/src/glibext/buffercache-int.h b/src/glibext/buffercache-int.h index 0e831a2..59d273b 100644 --- a/src/glibext/buffercache-int.h +++ b/src/glibext/buffercache-int.h @@ -33,20 +33,20 @@  /* Informations rattachées à la génération d'une ligne */ -typedef struct _generator_link +typedef struct _generator_link_t  { -    GLineGenerator *instance;               /* Fournisseur de contenu      */ +    GTokenGenerator *instance;              /* Fournisseur de contenu      */      size_t repeat;                          /* Compteur de successions     */ -} generator_link; +} generator_link_t;  /* Suivi interne de l'état d'une ligne */ -typedef struct _cache_info +typedef struct _cache_info_t  {      union      { -        generator_link generator;           /* Générateur unique           */ -        generator_link *generators;         /* Liste de générateurs        */ +        generator_link_t generator;         /* Générateur unique           */ +        generator_link_t *generators;       /* Liste de générateurs        */      };      size_t count;                           /* Taille de cette liste       */ @@ -54,7 +54,7 @@ typedef struct _cache_info      BufferLineFlags extra_flags;            /* Propriétés supplémentaires  */ -} cache_info; +} cache_info_t; @@ -66,13 +66,25 @@ struct _GBufferCache  {      GObject parent;                         /* A laisser en premier        */ +    size_t opt_count;                       /* Qté de colonnes en option   */ +    size_t reg_count;                       /* Nombre de colonnes normales */ +#ifndef NDEBUG +    size_t col_count;                       /* Nombre maximum de colonnes  */ +#endif + + + +#if 0      GBinContent *content;                   /* Contenu binaire global      */  #ifdef INCLUDE_GTK_SUPPORT      GWidthTracker *tracker;                 /* Suivi des largeurs          */  #endif +#endif + -    cache_info *lines;                      /* Liste des lignes intégrées  */ + +    cache_info_t *lines;                    /* Liste des lignes intégrées  */      size_t count;                           /* Quantité en cache           */      size_t used;                            /* Quantité utilisée           */      GRWLock access;                         /* Verrou de protection        */ @@ -84,18 +96,20 @@ struct _GBufferCacheClass  {      GObjectClass parent;                    /* A laisser en premier        */ -    gint line_height;                       /* Hauteur maximale des lignes */ -    gint left_margin;                       /* Marge gauche + espace       */ -    gint text_pos;                          /* Début d'impression du code  */ -      /* Signaux */      void (* size_changed) (GBufferCache *, bool, size_t, size_t); +#if 0      void (* line_updated) (GBufferCache *, size_t); +#endif  }; +/* Met en place un nouveau tampon pour lignes quelconques. */ +bool g_buffer_cache_create(GBufferCache *, size_t, size_t); + +  #endif  /* _GLIBEXT_BUFFERCACHE_INT_H */ diff --git a/src/glibext/buffercache.c b/src/glibext/buffercache.c index 78c7479..7856ff2 100644 --- a/src/glibext/buffercache.c +++ b/src/glibext/buffercache.c @@ -37,40 +37,45 @@  /* --------------------- FONCTIONS AUXILIAIRES DE MANIPULATIONS --------------------- */ -/* Gros verrou global pour alléger les structures... */ -G_LOCK_DEFINE_STATIC(_line_update); - -  /* Met en place un nouvel ensemble d'information sur une ligne. */ -static void init_cache_info(cache_info *, GLineGenerator *, size_t, BufferLineFlags); +static void init_cache_info(cache_info_t *, GTokenGenerator *, size_t, BufferLineFlags);  /* Libère la mémoire occupée par des informations sur une ligne. */ -static void release_cache_info(cache_info *); +static void release_cache_info(cache_info_t *); + +/* Force la réinitialisation d'une éventuelle ligne cachée. */ +static void reset_cache_info_line(cache_info_t *); + +/* Suivit les variations du compteur de références d'une ligne. */ +static void on_line_ref_toggle(cache_info_t *, GBufferLine *, gboolean); + +/* Fournit la ligne de tampon correspondant aux générateurs. */ +static GBufferLine *get_cache_info_line(cache_info_t *, size_t, size_t, void *); + +/* Calcule l'indice d'apparition d'un générateur. */ +static size_t compute_cache_info_repetition(const cache_info_t *, GTokenGenerator *); + + + +#if 0 +/* Gros verrou global pour alléger les structures... */ +G_LOCK_DEFINE_STATIC(_line_update); +  /* Ajoute un générateur aux informations sur une ligne. */ -static void extend_cache_info(cache_info *, GLineGenerator *, BufferLineFlags); +static void extend_cache_info(cache_info_t *, GLineGenerator *, BufferLineFlags);  /* Retire un générateur aux informations d'une ligne. */ -static void remove_from_cache_info(cache_info *, GLineGenerator *); +static void remove_from_cache_info(cache_info_t *, GLineGenerator *);  /* Retrouve l'emplacement correspondant à une position de ligne. */ -static void get_cache_info_cursor(const cache_info *, size_t, gint, GLineCursor **); - -/* Suivit les variations du compteur de références d'une ligne. */ -static void on_line_ref_toggle(cache_info *, GBufferLine *, gboolean); +static void get_cache_info_cursor(const cache_info_t *, size_t, gint, GLineCursor **);  #ifdef INCLUDE_GTK_SUPPORT -/* Fournit la ligne de tampon correspondant aux générateurs. */ -static GBufferLine *get_cache_info_line(cache_info *, const GWidthTracker *, size_t, const GBinContent *); -  #endif -/* Force la réinitialisation d'une éventuelle ligne cachée. */ -static void _reset_cache_info_line_unlocked(cache_info *); - -/* Force la réinitialisation d'une éventuelle ligne cachée. */ -static void reset_cache_info_line(cache_info *); +#endif @@ -78,7 +83,7 @@ static void reset_cache_info_line(cache_info *);  /* Taille des allocations de masse */ -#define LINE_ALLOC_BULK 1000 +//#define LINE_ALLOC_BULK 1000  /* Procède à l'initialisation d'une classe de tampon de lignes. */ @@ -93,9 +98,6 @@ static void g_buffer_cache_dispose(GBufferCache *);  /* Procède à la libération totale de la mémoire. */  static void g_buffer_cache_finalize(GBufferCache *); -/* Calcule l'indice d'apparition d'un générateur dans le tampon. */ -static size_t g_buffer_cache_compute_repetition(GBufferCache *, size_t, GLineGenerator *); -  /* ---------------------------------------------------------------------------------- */ @@ -118,12 +120,12 @@ static size_t g_buffer_cache_compute_repetition(GBufferCache *, size_t, GLineGen  *                                                                             *  ******************************************************************************/ -static void init_cache_info(cache_info *info, GLineGenerator *generator, size_t repeat, BufferLineFlags flags) +static void init_cache_info(cache_info_t *info, GTokenGenerator *generator, size_t repeat, BufferLineFlags flags)  {      info->generator.instance = generator;      info->generator.repeat = repeat; -    g_object_ref(G_OBJECT(generator)); +    ref_object(generator);      info->count = 1; @@ -146,16 +148,16 @@ static void init_cache_info(cache_info *info, GLineGenerator *generator, size_t  *                                                                             *  ******************************************************************************/ -static void release_cache_info(cache_info *info) +static void release_cache_info(cache_info_t *info)  {      size_t i;                               /* Boucle de parcours          */      if (info->count == 1) -        g_object_unref(G_OBJECT(info->generator.instance)); +        unref_object(info->generator.instance);      else          for (i = 0; i < info->count; i++) -            g_object_unref(G_OBJECT(info->generators[i].instance)); +            unref_object(info->generators[i].instance);      reset_cache_info_line(info); @@ -164,6 +166,155 @@ static void release_cache_info(cache_info *info)  /******************************************************************************  *                                                                             * +*  Paramètres  : info = informations sur une ligne à venir manipuler.         * +*                                                                             * +*  Description : Force la réinitialisation d'une éventuelle ligne cachée.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void reset_cache_info_line(cache_info_t *info) +{ +    if (info->line != NULL) +    { +        g_object_remove_toggle_ref(G_OBJECT(info->line), (GToggleNotify)on_line_ref_toggle, info); + +        info->line = NULL; + +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : info = informations sur une ligne à venir manipuler.         * +*                line = tampon de lignes à venir supprimer au besoin.         * +*                last = indication sur la valeur du compteur de références.   * +*                                                                             * +*  Description : Suivit les variations du compteur de références d'une ligne. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_line_ref_toggle(cache_info_t *info, GBufferLine *line, gboolean last) +{ +    if (last) +    { +        assert(info->line != NULL); + +        reset_cache_info_line(info); + +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : info      = informations sur une ligne à venir manipuler.    * +*                index     = indice de la ligne à constituer.                 * +*                col_count = quantité de colonnes à considérer.               * +*                data      = éventuelle donnée complémentaire fournie.        * +*                                                                             * +*  Description : Fournit la ligne de tampon correspondant aux générateurs.    * +*                                                                             * +*  Retour      : Ligne déjà en place ou créée pour le besoin.                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GBufferLine *get_cache_info_line(cache_info_t *info, size_t index, size_t col_count, void *data) +{ +    GBufferLine *result;                    /* Construction à retourner    */ +    size_t i;                               /* Boucle de parcours          */ + +    result = info->line; + +    if (result != NULL) +        ref_object(result); + +    else +    { +        result = g_buffer_line_new(col_count); + +        //g_buffer_line_add_flag(result, info->extra_flags); + +        g_object_add_toggle_ref(G_OBJECT(result), (GToggleNotify)on_line_ref_toggle, info); + +        if (info->count == 1) +            g_token_generator_populate_line(info->generator.instance, +                                            index, info->generator.repeat, +                                            result, data); + +        else +            for (i = 0; i < info->count; i++) +                g_token_generator_populate_line(info->generators[i].instance, +                                                index, info->generators[i].repeat, +                                                result, data); + +        info->line = result; + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : info      = informations sur une ligne à consulter.          * +*                generator = générateur associé à au moins une ligne.         * +*                                                                             * +*  Description : Calcule l'indice d'apparition d'un générateur.               * +*                                                                             * +*  Retour      : Indice de répétition, 0 si aucune.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static size_t compute_cache_info_repetition(const cache_info_t *info, GTokenGenerator *generator) +{ +    size_t result;                          /* Compteur à retourner        */ +    size_t i;                               /* Boucle de parcours          */ + +    result = 0; + +    if (info->count == 1) +    { +        if (info->generator.instance == generator) +            result = info->generator.repeat + 1; + +    } + +    else +        for (i = 0; i < info->count; i++) +            if (info->generators[i].instance == generator) +            { +                result = info->generators[i].repeat + 1; +                break; +            } + +    return result; + +} + + + + + +#if 0 +/****************************************************************************** +*                                                                             *  *  Paramètres  : info      = informations concernant une ligne à actualiser.  *  *                generator = générateur à associer à toutes les lignes.       *  *                flags     = propriétés supplémentaires à associer à la ligne.* @@ -176,7 +327,7 @@ static void release_cache_info(cache_info *info)  *                                                                             *  ******************************************************************************/ -static void extend_cache_info(cache_info *info, GLineGenerator *generator, BufferLineFlags flags) +static void extend_cache_info(cache_info_t *info, GLineGenerator *generator, BufferLineFlags flags)  {      generator_link first;                   /* Générateur déjà en place    */      generator_link *new;                    /* Nouveau générateur placé    */ @@ -235,7 +386,7 @@ static void extend_cache_info(cache_info *info, GLineGenerator *generator, Buffe  *                                                                             *  ******************************************************************************/ -static void remove_from_cache_info(cache_info *info, GLineGenerator *generator) +static void remove_from_cache_info(cache_info_t *info, GLineGenerator *generator)  {      generator_link *link;                   /* Accès simplifié             */      size_t i;                               /* Boucle de parcours          */ @@ -326,7 +477,7 @@ static void remove_from_cache_info(cache_info *info, GLineGenerator *generator)  *                                                                             *  ******************************************************************************/ -static void get_cache_info_cursor(const cache_info *info, size_t index, gint x, GLineCursor **cursor) +static void get_cache_info_cursor(const cache_info_t *info, size_t index, gint x, GLineCursor **cursor)  {      const generator_link *generator;        /* Générateur retenu           */ @@ -340,145 +491,18 @@ static void get_cache_info_cursor(const cache_info *info, size_t index, gint x,  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : info = informations sur une ligne à venir manipuler.         * -*                line = tampon de lignes à venir supprimer au besoin.         * -*                last = indication sur la valeur du compteur de références.   * -*                                                                             * -*  Description : Suivit les variations du compteur de références d'une ligne. * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void on_line_ref_toggle(cache_info *info, GBufferLine *line, gboolean last) -{ -    if (last) -    { -        G_LOCK(_line_update); - -        assert(info->line != NULL); - -        _reset_cache_info_line_unlocked(info); - -        G_UNLOCK(_line_update); - -    } - -} -  #ifdef INCLUDE_GTK_SUPPORT -/****************************************************************************** -*                                                                             * -*  Paramètres  : info    = informations sur une ligne à venir manipuler.      * -*                tracker = gestionnaire de largeurs à consulter si besoin est.* -*                index   = indice de la ligne à constituer.                   * -*                content = éventuel contenu binaire brut à imprimer.          * -*                                                                             * -*  Description : Fournit la ligne de tampon correspondant aux générateurs.    * -*                                                                             * -*  Retour      : Ligne déjà en place ou créée pour le besoin.                 * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static GBufferLine *get_cache_info_line(cache_info *info, const GWidthTracker *tracker, size_t index, const GBinContent *content) -{ -    GBufferLine *result;                    /* Construction à retourner    */ -    size_t i;                               /* Boucle de parcours          */ - -    G_LOCK(_line_update); - -    result = info->line; - -    if (result == NULL) -    { -        result = g_buffer_line_new(g_width_tracker_count_columns(tracker)); - -        g_buffer_line_add_flag(result, info->extra_flags); - -        g_object_add_toggle_ref(G_OBJECT(result), (GToggleNotify)on_line_ref_toggle, info); - -        if (info->count == 1) -            g_line_generator_print(info->generator.instance, result, index, -                                   info->generator.repeat, content); - -        else -            for (i = 0; i < info->count; i++) -                g_line_generator_print(info->generators[i].instance, result, index, -                                       info->generators[i].repeat, content); - -        info->line = result; - -    } - -    else -        g_object_ref(G_OBJECT(result)); - -    G_UNLOCK(_line_update); - -    return result; - -}  #endif -/****************************************************************************** -*                                                                             * -*  Paramètres  : info = informations sur une ligne à venir manipuler.         * -*                                                                             * -*  Description : Force la réinitialisation d'une éventuelle ligne cachée.     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void _reset_cache_info_line_unlocked(cache_info *info) -{ -    if (info->line != NULL) -    { -        g_object_remove_toggle_ref(G_OBJECT(info->line), (GToggleNotify)on_line_ref_toggle, info); - -        info->line = NULL; -    } - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : info = informations sur une ligne à venir manipuler.         * -*                                                                             * -*  Description : Force la réinitialisation d'une éventuelle ligne cachée.     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void reset_cache_info_line(cache_info *info) -{ -    G_LOCK(_line_update); - -    _reset_cache_info_line_unlocked(info); - -    G_UNLOCK(_line_update); - -} +#endif  /* ---------------------------------------------------------------------------------- */ @@ -511,10 +535,6 @@ static void g_buffer_cache_class_init(GBufferCacheClass *class)      object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_cache_dispose;      object->finalize = (GObjectFinalizeFunc)g_buffer_cache_finalize; -    class->line_height = 17; -    class->left_margin = 2 * class->line_height; -    class->text_pos = 2.5 * class->line_height; -      /* Signaux */      g_signal_new("size-changed", @@ -525,6 +545,8 @@ static void g_buffer_cache_class_init(GBufferCacheClass *class)                   g_cclosure_user_marshal_VOID__BOOLEAN_ULONG_ULONG,                   G_TYPE_NONE, 3, G_TYPE_BOOLEAN, G_TYPE_ULONG, G_TYPE_ULONG); +#if 0 +      g_signal_new("line-updated",                   G_TYPE_BUFFER_CACHE,                   G_SIGNAL_RUN_LAST, @@ -533,6 +555,8 @@ static void g_buffer_cache_class_init(GBufferCacheClass *class)                   g_cclosure_marshal_VOID__ULONG,                   G_TYPE_NONE, 1, G_TYPE_ULONG); +#endif +  } @@ -550,6 +574,8 @@ static void g_buffer_cache_class_init(GBufferCacheClass *class)  static void g_buffer_cache_init(GBufferCache *cache)  { +#if 0 +      cache->content = NULL;      cache->lines = NULL; @@ -561,6 +587,8 @@ static void g_buffer_cache_init(GBufferCache *cache)      cache->tracker = NULL;  #endif +#endif +  } @@ -578,8 +606,9 @@ static void g_buffer_cache_init(GBufferCache *cache)  static void g_buffer_cache_dispose(GBufferCache *cache)  { +#if 0      size_t i;                               /* Boucle de parcours #1       */ -    cache_info *info;                       /* Accès direct à une ligne    */ +    cache_info_t *info;                       /* Accès direct à une ligne    */      size_t j;                               /* Boucle de parcours #2       */      g_clear_object(&cache->content); @@ -603,6 +632,8 @@ static void g_buffer_cache_dispose(GBufferCache *cache)      g_clear_object(&cache->tracker);  #endif +#endif +      G_OBJECT_CLASS(g_buffer_cache_parent_class)->dispose(G_OBJECT(cache));  } @@ -622,8 +653,10 @@ static void g_buffer_cache_dispose(GBufferCache *cache)  static void g_buffer_cache_finalize(GBufferCache *cache)  { + +#if 0      size_t i;                               /* Boucle de parcours          */ -    cache_info *info;                       /* Accès direct à une ligne    */ +    cache_info_t *info;                       /* Accès direct à une ligne    */      for (i = 0; i < cache->used; i++)      { @@ -639,6 +672,8 @@ static void g_buffer_cache_finalize(GBufferCache *cache)      g_rw_lock_clear(&cache->access); +#endif +      G_OBJECT_CLASS(g_buffer_cache_parent_class)->finalize(G_OBJECT(cache));  } @@ -646,11 +681,10 @@ static void g_buffer_cache_finalize(GBufferCache *cache)  /******************************************************************************  *                                                                             * -*  Paramètres  : content   = éventuel contenu binaire brut à référencer.      * -*                col_count = quantité maximale de colonnes à considérer.      * -*                opt_count = quantité de colonnes optionnelles.               * +*  Paramètres  : opt_count = quantité de colonnes optionnelles.               * +*                reg_count = quantité de colonnes normales à considérer.      *  *                                                                             * -*  Description : Crée un nouveau composant de tampon pour code désassemblé.   * +*  Description : Crée un nouveau tampon pour lignes quelconques.              *  *                                                                             *  *  Retour      : Composant GLib créé.                                         *  *                                                                             * @@ -658,21 +692,14 @@ static void g_buffer_cache_finalize(GBufferCache *cache)  *                                                                             *  ******************************************************************************/ -GBufferCache *g_buffer_cache_new(GBinContent *content, size_t col_count, size_t opt_count) +GBufferCache *g_buffer_cache_new(size_t opt_count, size_t reg_count)  {      GBufferCache *result;                   /* Composant à retourner       */      result = g_object_new(G_TYPE_BUFFER_CACHE, NULL); -    if (content != NULL) -    { -        result->content = content; -        g_object_ref(G_OBJECT(content)); -    } - -#ifdef INCLUDE_GTK_SUPPORT -    result->tracker = g_width_tracker_new(result, col_count, opt_count); -#endif +    if (!g_buffer_cache_create(result, opt_count, reg_count)) +        g_clear_object(&result);      return result; @@ -681,24 +708,30 @@ GBufferCache *g_buffer_cache_new(GBinContent *content, size_t col_count, size_t  /******************************************************************************  *                                                                             * -*  Paramètres  : cache = tampon de lignes à consulter.                        * +*  Paramètres  : cache     = cache de lignes à initialiser.                   * +*                opt_count = quantité de colonnes optionnelles.               * +*                reg_count = quantité de colonnes normales à considérer.      *  *                                                                             * -*  Description : Indique l'éventuel contenu binaire associé au cache.         * +*  Description : Met en place un nouveau tampon pour lignes quelconques.      *  *                                                                             * -*  Retour      : Eventuel contenu renseigné ou NULL.                          * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GBinContent *g_buffer_cache_get_content(const GBufferCache *cache) +bool g_buffer_cache_create(GBufferCache *cache, size_t opt_count, size_t reg_count)  { -    GBinContent *result;                    /* Contenu à retourner         */ +    bool result;                            /* Bilen à retourner           */ -    result = cache->content; +    result = true; -    if (result != NULL) -        g_object_ref(G_OBJECT(result)); +    cache->opt_count = opt_count; +    cache->reg_count = reg_count; + +#ifndef NDEBUG +    cache->col_count = opt_count + reg_count; +#endif      return result; @@ -707,111 +740,191 @@ GBinContent *g_buffer_cache_get_content(const GBufferCache *cache)  /******************************************************************************  *                                                                             * -*  Paramètres  : cache = tampon de lignes à consulter.                        * +*  Paramètres  : cache     = tampon de lignes à consulter.                    * +*                opt_count = quantité de colonnes optionnelles. [OUT]         * +*                reg_count = quantité de colonnes normales à considérer. [OUT]*  *                                                                             * -*  Description : Fournit la hauteur d'impression d'une ligne visualisée.      * +*  Description : Fournit le nombre de colonnes supportées par un tampon.      *  *                                                                             * -*  Retour      : Hauteur de ligne en pixels.                                  * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -gint g_buffer_cache_get_line_height(const GBufferCache *cache) +void g_buffer_cache_count_columns(const GBufferCache *cache, size_t *opt_count, size_t *reg_count)  { -    GBufferCacheClass *class;               /* Classe des tampons          */ +    *opt_count = cache->opt_count; +    *reg_count = cache->reg_count; -    class = G_BUFFER_CACHE_GET_CLASS(cache); +} -    return class->line_height; + +/****************************************************************************** +*                                                                             * +*  Paramètres  : cache = cache de lignes à mettre à jour.                     * +*                write = précise le type d'accès prévu (lecture/écriture).    * +*                lock  = indique le sens du verrouillage à mener.             * +*                                                                             * +*  Description : Met à disposition un encadrement des accès aux lignes.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_buffer_cache_lock_unlock(GBufferCache *cache, bool write, bool lock) +{ +    if (write) +    { +        if (lock) g_rw_lock_writer_lock(&cache->access); +        else g_rw_lock_writer_unlock(&cache->access); +    } +    else +    { +        if (lock) g_rw_lock_reader_lock(&cache->access); +        else g_rw_lock_reader_unlock(&cache->access); +    }  }  /******************************************************************************  *                                                                             * -*  Paramètres  : cache = tampon de lignes à consulter.                        * +*  Paramètres  : cache = instance GLib à consulter.                           *  *                                                                             * -*  Description : Fournit la taille réservée pour la marge gauche.             * +*  Description : Compte le nombre de lignes rassemblées dans un tampon.       *  *                                                                             * -*  Retour      : Largeur en pixels.                                           * +*  Retour      : Nombre de lignes constituant le tampon.                      *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -gint g_buffer_cache_get_left_margin(const GBufferCache *cache) +size_t g_buffer_cache_count_lines(GBufferCache *cache)  { -    GBufferCacheClass *class;               /* Classe des tampons          */ +    size_t result;                          /* Quantité à retourner        */ -    class = G_BUFFER_CACHE_GET_CLASS(cache); +    assert(!g_rw_lock_writer_trylock(&cache->access)); -    return class->left_margin; +    result = cache->used; + +    return result;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : cache = tampon de lignes à consulter.                        * +*  Paramètres  : cache     = instance GLib à modifier.                        * +*                count     = quantité totale de lignes à avoir à disposition. * +*                generator = générateur à associer à toutes les lignes.       *  *                                                                             * -*  Description : Fournit la position de départ pour l'impression de texte.    * +*  Description : Etend un tampon avec un générateur de lignes unique.         *  *                                                                             * -*  Retour      : Position en pixels.                                          * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -gint g_buffer_cache_get_text_position(const GBufferCache *cache) +void g_buffer_cache_extend_with(GBufferCache *cache, size_t count, GTokenGenerator *generator)  { -    GBufferCacheClass *class;               /* Classe des tampons          */ +    size_t index;                           /* Point d'insertion           */ +    size_t repeat;                          /* Compteur de répétition      */ +    size_t i;                               /* Boucle de parcours          */ +    size_t added;                           /* Nombre d'ajouts effectués   */ -    class = G_BUFFER_CACHE_GET_CLASS(cache); +    assert(!g_rw_lock_writer_trylock(&cache->access)); -    return class->text_pos; +    assert(count >= cache->used); -} +    if (count > cache->count) +    { +        cache->lines = realloc(cache->lines, count * sizeof(cache_info_t)); +        cache->count = count; +    } +    index = cache->used; -#ifdef INCLUDE_GTK_SUPPORT +    if (index == 0) +        repeat = 0; +    else +        repeat = compute_cache_info_repetition(&cache->lines[index - 1], generator); + +    for (i = index; i < count; i++) +        init_cache_info(&cache->lines[i], generator, repeat++, BLF_NONE); + +    added = count - cache->used; + +    cache->used = count; + +    if (added > 0) +    { +        //g_width_tracker_update_added(cache->tracker, index, added); + +        g_signal_emit_by_name(cache, "size-changed", true, index, added); + +    } + +}  /******************************************************************************  *                                                                             * -*  Paramètres  : cache = composant GLib à consulter.                          * +*  Paramètres  : cache = instance GLib à modifier.                            * +*                max   = nombre maximal de lignes à conserver.                *  *                                                                             * -*  Description : Fournit un lien vers la structure de suivi de largeurs.      * +*  Description : Réduit le tampon à une quantité de lignes précise.           *  *                                                                             * -*  Retour      : Gestionnaire de largeurs de lignes.                          * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *cache) +void g_buffer_cache_truncate(GBufferCache *cache, size_t max)  { -    GWidthTracker *result;                  /* Instance à retourner    *   */ +    size_t i;                               /* Boucle de parcours          */ +    size_t removed;                         /* Nombre de retraits effectués*/ -    result = cache->tracker; +    assert(!g_rw_lock_writer_trylock(&cache->access)); -    g_object_ref(G_OBJECT(result)); +    for (i = max; i < cache->used; i++) +        release_cache_info(&cache->lines[i]); -    return result; +    if (max < cache->used) +    { +        removed = cache->used - max; + +        cache->used = max; + +        //g_width_tracker_update_deleted(cache->tracker, max, max + removed - 1); + +        g_signal_emit_by_name(cache, "size-changed", false, max, removed); + +    }  } -#endif + + +  /******************************************************************************  *                                                                             * -*  Paramètres  : cache = cache de lignes à mettre à jour.                     * -*                write = précise le type d'accès prévu (lecture/écriture).    * -*                lock  = indique le sens du verrouillage à mener.             * +*  Paramètres  : cache  = visualisation à représenter.                        * +*                cr     = contexte graphique dédié à la procédure.            * +*                column = (première) colonne à traiter.                       * +*                top    = ordonnée attribuée à la première ligne.             * +*                first  = première ligne à dessiner.                          * +*                last   = dernière ligne à dessiner.                          * +*                style  = style de rendu pour les bribes de texte.            *  *                                                                             * -*  Description : Met à disposition un encadrement des accès aux lignes.       * +*  Description : Imprime une partie choisie du tampon contenant des lignes.   *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -819,41 +932,67 @@ GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *cache)  *                                                                             *  ******************************************************************************/ -void g_buffer_cache_lock_unlock(GBufferCache *cache, bool write, bool lock) +void g_buffer_cache_draw(GBufferCache *cache, cairo_t *cr, size_t column, int top, size_t first, size_t last, const GTokenStyle *style)  { -    if (write) -    { -        if (lock) g_rw_lock_writer_lock(&cache->access); -        else g_rw_lock_writer_unlock(&cache->access); -    } -    else +    int y;                                  /* Point de départ en ordonnée */ +    int lheight;                            /* Hauteur d'une ligne         */ +    size_t i;                               /* Boucle de parcours          */ +    GBufferLine *line;                      /* Ligne à venir dessiner      */ + +    if (cache->used > 0)      { -        if (lock) g_rw_lock_reader_lock(&cache->access); -        else g_rw_lock_reader_unlock(&cache->access); +        y = top; + +        lheight = g_token_style_get_line_height(style); + +        g_buffer_cache_rlock(cache); + +        for (i = first; i <= last; i++) +        { +            line = get_cache_info_line(&cache->lines[i], i, cache->opt_count + cache->reg_count, NULL); + +            g_buffer_line_draw(line, cr, column, y, style); + +            unref_object(line); + +            y += lheight; + +        } + +        g_buffer_cache_runlock(cache); +      }  } + + + + + + +#if 0  /******************************************************************************  *                                                                             * -*  Paramètres  : cache = instance GLib à consulter.                           * +*  Paramètres  : cache = tampon de lignes à consulter.                        *  *                                                                             * -*  Description : Compte le nombre de lignes rassemblées dans un tampon.       * +*  Description : Indique l'éventuel contenu binaire associé au cache.         *  *                                                                             * -*  Retour      : Nombre de lignes constituant le tampon.                      * +*  Retour      : Eventuel contenu renseigné ou NULL.                          *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -size_t g_buffer_cache_count_lines(GBufferCache *cache) +GBinContent *g_buffer_cache_get_content(const GBufferCache *cache)  { -    size_t result;                          /* Quantité à retourner        */ +    GBinContent *result;                    /* Contenu à retourner         */ -    assert(!g_rw_lock_writer_trylock(&cache->access)); +    result = cache->content; -    result = cache->used; +    if (result != NULL) +        g_object_ref(G_OBJECT(result));      return result; @@ -862,52 +1001,110 @@ size_t g_buffer_cache_count_lines(GBufferCache *cache)  /******************************************************************************  *                                                                             * -*  Paramètres  : cache     = instance GLib à consulter.                       * -*                index     = indice de la ligne où se trouve le générateur.   * -*                generator = générateur associé à au moins une ligne.         * +*  Paramètres  : cache = tampon de lignes à consulter.                        *  *                                                                             * -*  Description : Calcule l'indice d'apparition d'un générateur dans le tampon.* +*  Description : Fournit la hauteur d'impression d'une ligne visualisée.      *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Hauteur de ligne en pixels.                                  *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static size_t g_buffer_cache_compute_repetition(GBufferCache *cache, size_t index, GLineGenerator *generator) +gint g_buffer_cache_get_line_height(const GBufferCache *cache)  { -    size_t result;                          /* Compteur à retourner        */ -    cache_info *info;                       /* Accès direct à une ligne    */ -    size_t i;                               /* Boucle de parcours          */ +    GBufferCacheClass *class;               /* Classe des tampons          */ -    result = 0; +    class = G_BUFFER_CACHE_GET_CLASS(cache); -    if (index > 0) -    { -        info = &cache->lines[index - 1]; +    return class->line_height; -        if (info->count == 1) -        { -            if (info->generator.instance == generator) -                result = info->generator.repeat + 1; +} -        } -        else -            for (i = 0; i < info->count; i++) -                if (info->generators[i].instance == generator) -                { -                    result = info->generators[i].repeat + 1; -                    break; -                } +/****************************************************************************** +*                                                                             * +*  Paramètres  : cache = tampon de lignes à consulter.                        * +*                                                                             * +*  Description : Fournit la taille réservée pour la marge gauche.             * +*                                                                             * +*  Retour      : Largeur en pixels.                                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    } +gint g_buffer_cache_get_left_margin(const GBufferCache *cache) +{ +    GBufferCacheClass *class;               /* Classe des tampons          */ + +    class = G_BUFFER_CACHE_GET_CLASS(cache); + +    return class->left_margin; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : cache = tampon de lignes à consulter.                        * +*                                                                             * +*  Description : Fournit la position de départ pour l'impression de texte.    * +*                                                                             * +*  Retour      : Position en pixels.                                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +gint g_buffer_cache_get_text_position(const GBufferCache *cache) +{ +    GBufferCacheClass *class;               /* Classe des tampons          */ + +    class = G_BUFFER_CACHE_GET_CLASS(cache); + +    return class->text_pos; + +} + + +#ifdef INCLUDE_GTK_SUPPORT + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : cache = composant GLib à consulter.                          * +*                                                                             * +*  Description : Fournit un lien vers la structure de suivi de largeurs.      * +*                                                                             * +*  Retour      : Gestionnaire de largeurs de lignes.                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *cache) +{ +    GWidthTracker *result;                  /* Instance à retourner    *   */ + +    result = cache->tracker; + +    g_object_ref(G_OBJECT(result));      return result;  } +#endif + + + + + + + +  /******************************************************************************  *                                                                             *  *  Paramètres  : cache     = instance GLib à modifier.                        * @@ -1063,7 +1260,7 @@ void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator  void g_buffer_cache_delete_at(GBufferCache *cache, size_t index)  { -    cache_info *info;                       /* Accès direct à une ligne    */ +    cache_info_t *info;                       /* Accès direct à une ligne    */      assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1107,7 +1304,7 @@ void g_buffer_cache_delete_at(GBufferCache *cache, size_t index)  GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *cache, size_t index, GType type, bool before, bool after)  {      GLineGenerator *result;                 /* Prédécesseur à retourner    */ -    cache_info *info;                       /* Accès direct à une ligne    */ +    cache_info_t *info;                       /* Accès direct à une ligne    */      generator_link *link;                   /* Accès simplifié             */      size_t i;                               /* Boucle de parcours          */      size_t count;                           /* Emplacements occupés        */ @@ -1236,7 +1433,7 @@ void g_buffer_cache_append(GBufferCache *cache, GLineGenerator *generator, Buffe      size_t count;                           /* Nombre de lignes générées   */      size_t index;                           /* Point d'insertion           */      size_t i;                               /* Boucle de parcours          */ -    cache_info *info;                       /* Accès direct à une ligne    */ +    cache_info_t *info;                       /* Accès direct à une ligne    */      size_t repeat;                          /* Compteur de répétition      */      assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1255,146 +1452,37 @@ void g_buffer_cache_append(GBufferCache *cache, GLineGenerator *generator, Buffe      index = cache->used; -    for (i = 0; i < count; i++) -    { -        info = &cache->lines[index + i]; - -        repeat = g_buffer_cache_compute_repetition(cache, index + i, generator); - -        init_cache_info(info, generator, repeat, flags); - -    } - -    cache->used += count; - -#ifdef INCLUDE_GTK_SUPPORT -    g_width_tracker_update_added(cache->tracker, index, count); -#endif - -    g_signal_emit_by_name(cache, "size-changed", true, index, count); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : cache     = instance GLib à modifier.                        * -*                count     = quantité totale de lignes à avoir à disposition. * -*                generator = générateur à associer à toutes les lignes.       * -*                                                                             * -*  Description : Etend un tampon avec un générateur de lignes unique.         * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_buffer_cache_extend_with(GBufferCache *cache, size_t count, GLineGenerator *generator) -{ -    size_t index;                           /* Point d'insertion           */ -    size_t i;                               /* Boucle de parcours          */ -    cache_info *info;                       /* Accès direct à une ligne    */ -    size_t repeat;                          /* Compteur de répétition      */ -    size_t added;                           /* Nombre d'ajouts effectués   */ - -    assert(!g_rw_lock_writer_trylock(&cache->access)); -    assert(count >= cache->used); +    if (index == 0) +        repeat = 0; -    if (count > cache->count) +    else      { -        cache->lines = realloc(cache->lines, count * sizeof(cache_info)); -        cache->count = count; +        info = &cache->lines[index - 1]; +        repeat = compute_cache_info_repetition(info, generator);      } -    index = cache->used; - -    for (i = index; i < count; i++) +    for (i = 0; i < count; i++)      { -        info = &cache->lines[i]; - -        repeat = g_buffer_cache_compute_repetition(cache, i, generator); - -        init_cache_info(info, generator, repeat, BLF_NONE); - +        info = &cache->lines[index + i]; +        init_cache_info(info, generator, repeat++, flags);      } -    added = count - cache->used; +    cache->used += count; -    cache->used = count; +    /* -    if (added > 0) -    {  #ifdef INCLUDE_GTK_SUPPORT -        g_width_tracker_update_added(cache->tracker, index, added); +    g_width_tracker_update_added(cache->tracker, index, count);  #endif -        g_signal_emit_by_name(cache, "size-changed", true, index, added); +    g_signal_emit_by_name(cache, "size-changed", true, index, count); -    } +    */  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : cache = instance GLib à modifier.                            * -*                max   = nombre maximal de lignes à conserver.                * -*                                                                             * -*  Description : Réduit le tampon à une quantité de lignes précise.           * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_buffer_cache_truncate(GBufferCache *cache, size_t max) -{ -    size_t i;                               /* Boucle de parcours #1       */ -    cache_info *info;                       /* Accès direct à une ligne    */ -    size_t j;                               /* Boucle de parcours #2       */ -    size_t removed;                         /* Nombre de retraits effectués*/ - -    assert(!g_rw_lock_writer_trylock(&cache->access)); - -    for (i = max; i < cache->used; i++) -    { -        info = &cache->lines[i]; - -        if (info->count == 1) -            g_object_unref(G_OBJECT(info->generator.instance)); - -        else -        { -            for (j = 0; j < info->count; j++) -                g_object_unref(G_OBJECT(info->generators[j].instance)); - -            free(info->generators); - -        } - -        reset_cache_info_line(info); - -    } - -    if (max < cache->used) -    { -        removed = cache->used - max; - -        cache->used = max; - -#ifdef INCLUDE_GTK_SUPPORT -        g_width_tracker_update_deleted(cache->tracker, max, max + removed - 1); -#endif - -        g_signal_emit_by_name(cache, "size-changed", false, max, removed); - -    } - -} -  #ifdef INCLUDE_GTK_SUPPORT @@ -1444,7 +1532,7 @@ void g_buffer_cache_get_line_cursor(GBufferCache *cache, size_t index, gint x, G  void g_buffer_cache_add_line_flag(GBufferCache *cache, size_t index, BufferLineFlags flag)  { -    cache_info *info;                       /* Accès direct à une ligne    */ +    cache_info_t *info;                       /* Accès direct à une ligne    */      assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1482,7 +1570,7 @@ void g_buffer_cache_add_line_flag(GBufferCache *cache, size_t index, BufferLineF  BufferLineFlags g_buffer_cache_get_line_flags(GBufferCache *cache, size_t index)  {      BufferLineFlags result;                 /* Somme à renvoyer            */ -    cache_info *info;                       /* Accès direct à une ligne    */ +    cache_info_t *info;                       /* Accès direct à une ligne    */      const generator_link *generator;        /* Générateur retenu           */      size_t i;                               /* Boucle de parcours          */ @@ -1528,7 +1616,7 @@ BufferLineFlags g_buffer_cache_get_line_flags(GBufferCache *cache, size_t index)  void g_buffer_cache_remove_line_flag(GBufferCache *cache, size_t index, BufferLineFlags flag)  { -    cache_info *info;                       /* Accès direct à une ligne    */ +    cache_info_t *info;                       /* Accès direct à une ligne    */      assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1621,7 +1709,7 @@ size_t g_buffer_cache_look_for_flag(GBufferCache *cache, size_t start, BufferLin  void g_buffer_cache_refresh_line(GBufferCache *cache, size_t index)  { -    cache_info *info;                       /* Accès direct à une ligne    */ +    cache_info_t *info;                       /* Accès direct à une ligne    */      assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1689,6 +1777,8 @@ void g_buffer_cache_collect_widths(GBufferCache *cache, size_t index, size_t col  {      GBufferLine *line;                      /* Ligne éphémère à mesurer    */ +    // Need lock +      line = get_cache_info_line(&cache->lines[index], cache->tracker, index, cache->content);      g_buffer_line_collect_widths(line, col_count, opt_count, widths, merged); @@ -1723,7 +1813,7 @@ void g_buffer_cache_draw(const GBufferCache *cache, cairo_t *cr, size_t first, s      gint y;                                 /* Point de départ en ordonnée */      bool wait_selection;                    /* Sélection déjà passée ?     */      size_t i;                               /* Boucle de parcours          */ -    cache_info *info;                       /* Accès direct à une ligne    */ +    cache_info_t *info;                       /* Accès direct à une ligne    */      GBufferLine *line;                      /* Ligne à venir dessiner      */      class = G_BUFFER_CACHE_GET_CLASS(cache); @@ -1749,6 +1839,8 @@ void g_buffer_cache_draw(const GBufferCache *cache, cairo_t *cr, size_t first, s              info = &cache->lines[i]; +            // Need lock +              line = get_cache_info_line(info, cache->tracker, i, cache->content);              g_buffer_line_draw(line, i, cr, class->text_pos, y, cache->tracker, options, list); @@ -1784,11 +1876,11 @@ void g_buffer_cache_draw(const GBufferCache *cache, cairo_t *cr, size_t first, s  size_t _g_buffer_cache_find_index_by_cursor(GBufferCache *cache, const GLineCursor *cursor, bool first, size_t start, size_t end)  {      size_t result;                          /* Indice à retourner          */ -    cache_info *found;                      /* Eventuel élément trouvé     */ +    cache_info_t *found;                      /* Eventuel élément trouvé     */      assert(!g_rw_lock_writer_trylock(&cache->access)); -    int find_containing_generator(const GLineCursor *c, const cache_info *i) +    int find_containing_generator(const GLineCursor *c, const cache_info_t *i)      {          const generator_link *generator;    /* Générateur retenu           */ @@ -1802,7 +1894,7 @@ size_t _g_buffer_cache_find_index_by_cursor(GBufferCache *cache, const GLineCurs      } -    found = (cache_info *)bsearch(cursor, &cache->lines[start], end - start + 1, +    found = (cache_info_t *)bsearch(cursor, &cache->lines[start], end - start + 1,                                    sizeof(cache_info), (__compar_fn_t)find_containing_generator);      if (found == NULL) @@ -1898,7 +1990,7 @@ bool g_buffer_cache_get_cursor_coordinates(GBufferCache *cache, const GLineCurso      bool result;                            /* Bilan à retourner           */      size_t index;                           /* Indice de correspondance    */      gint lheight;                           /* Hauteur d'une ligne         */ -    const cache_info *info;                 /* Infos sur une ligne donnée  */ +    const cache_info_t *info;                 /* Infos sur une ligne donnée  */      const generator_link *generator;        /* Générateur retenu           */      assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1944,3 +2036,4 @@ bool g_buffer_cache_get_cursor_coordinates(GBufferCache *cache, const GLineCurso  #endif +#endif diff --git a/src/glibext/buffercache.h b/src/glibext/buffercache.h index 68941c5..87aae4e 100644 --- a/src/glibext/buffercache.h +++ b/src/glibext/buffercache.h @@ -25,6 +25,57 @@  #define _GLIBEXT_BUFFERCACHE_H +#include <gtk/gtk.h> + + +#include "helpers.h" +#include "generator.h" + + + +#define G_TYPE_BUFFER_CACHE (g_buffer_cache_get_type()) + +DECLARE_GTYPE(GBufferCache, g_buffer_cache, G, BUFFER_CACHE); + + +/* Crée un nouveau tampon pour lignes quelconques. */ +GBufferCache *g_buffer_cache_new(size_t, size_t); + +/* Fournit le nombre de colonnes supportées par un tampon. */ +void g_buffer_cache_count_columns(const GBufferCache *, size_t *, size_t *); + +/*  Met à disposition un encadrement des accès aux lignes. */ +void g_buffer_cache_lock_unlock(GBufferCache *, bool, bool); + +#define g_buffer_cache_wlock(cache) g_buffer_cache_lock_unlock(cache, true, true); +#define g_buffer_cache_wunlock(cache) g_buffer_cache_lock_unlock(cache, true, false); + +#define g_buffer_cache_rlock(cache) g_buffer_cache_lock_unlock(cache, false, true); +#define g_buffer_cache_runlock(cache) g_buffer_cache_lock_unlock(cache, false, false); + +/* Compte le nombre de lignes rassemblées dans un tampon. */ +size_t g_buffer_cache_count_lines(GBufferCache *); + +/* Etend un tampon avec un générateur de lignes unique. */ +void g_buffer_cache_extend_with(GBufferCache *, size_t, GTokenGenerator *); + +/* Réduit le tampon à une quantité de lignes précise. */ +void g_buffer_cache_truncate(GBufferCache *, size_t); + + + + +/* Imprime une partie choisie du tampon contenant des lignes. */ +void g_buffer_cache_draw(GBufferCache *, cairo_t *, size_t, int, size_t, size_t, const GTokenStyle *); + + + + + + + +#if 0 +  #include <glib-object.h>  #include <stdbool.h>  #ifdef INCLUDE_GTK_SUPPORT @@ -84,18 +135,18 @@ GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *);  #endif  /*  Met à disposition un encadrement des accès aux lignes. */ -void g_buffer_cache_lock_unlock(GBufferCache *, bool, bool); +//void g_buffer_cache_lock_unlock(GBufferCache *, bool, bool); -#define g_buffer_cache_wlock(cache) g_buffer_cache_lock_unlock(cache, true, true); -#define g_buffer_cache_wunlock(cache) g_buffer_cache_lock_unlock(cache, true, false); +//#define g_buffer_cache_wlock(cache) g_buffer_cache_lock_unlock(cache, true, true); +//#define g_buffer_cache_wunlock(cache) g_buffer_cache_lock_unlock(cache, true, false); -#define g_buffer_cache_rlock(cache) g_buffer_cache_lock_unlock(cache, false, true); -#define g_buffer_cache_runlock(cache) g_buffer_cache_lock_unlock(cache, false, false); +//#define g_buffer_cache_rlock(cache) g_buffer_cache_lock_unlock(cache, false, true); +//#define g_buffer_cache_runlock(cache) g_buffer_cache_lock_unlock(cache, false, false);  /* Compte le nombre de lignes rassemblées dans un tampon. */ -size_t g_buffer_cache_count_lines(GBufferCache *); +//size_t g_buffer_cache_count_lines(GBufferCache *);  /* Insère un générateur dans des lignes à une position donnée. */  void g_buffer_cache_insert_at(GBufferCache *, size_t, GLineGenerator *, BufferLineFlags, bool, bool); @@ -110,10 +161,10 @@ GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *, size_t, GType, boo  void g_buffer_cache_append(GBufferCache *, GLineGenerator *, BufferLineFlags);  /* Etend un tampon avec un générateur de lignes unique. */ -void g_buffer_cache_extend_with(GBufferCache *, size_t, GLineGenerator *); +//void g_buffer_cache_extend_with(GBufferCache *, size_t, GLineGenerator *);  /* Réduit le tampon à une quantité de lignes précise. */ -void g_buffer_cache_truncate(GBufferCache *, size_t); +//void g_buffer_cache_truncate(GBufferCache *, size_t);  #ifdef INCLUDE_GTK_SUPPORT @@ -146,7 +197,7 @@ GBufferLine *g_buffer_cache_find_line_by_index(GBufferCache *, size_t);  void g_buffer_cache_collect_widths(GBufferCache *, size_t, size_t, size_t, gint *, gint *);  /* Imprime une partie choisie du tampon contenant des lignes. */ -void g_buffer_cache_draw(const GBufferCache *, cairo_t *, size_t, size_t, const cairo_rectangle_int_t *, const GDisplayOptions *, const gint *, const segcnt_list *); +//void g_buffer_cache_draw(const GBufferCache *, cairo_t *, size_t, size_t, const cairo_rectangle_int_t *, const GDisplayOptions *, const gint *, const segcnt_list *);  #endif @@ -164,5 +215,8 @@ bool g_buffer_cache_get_cursor_coordinates(GBufferCache *, const GLineCursor *,  #endif +#endif + +  #endif  /* _GLIBEXT_BUFFERCACHE_H */ diff --git a/src/glibext/bufferline-int.h b/src/glibext/bufferline-int.h new file mode 100644 index 0000000..8bee3c2 --- /dev/null +++ b/src/glibext/bufferline-int.h @@ -0,0 +1,94 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bufferline-int.h - prototypes pour la définition interne d'une représentation de fragments de texte en ligne + * + * Copyright (C) 2024 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GLIBEXT_BUFFERLINE_INT_H +#define _GLIBEXT_BUFFERLINE_INT_H + + +#include "bufferline.h" +#include "linecolumn.h" + + + +#if 0 +/* Mémorisation des origines de texte */ +typedef struct _content_origin +{ +    col_coord_t coord;                      /* Localisation d'attachement  */ + +    GObject *creator;                       /* Origine de la création      */ + +} content_origin; +#endif + + +/* Représentation de fragments de texte en ligne (instance) */ +struct _GBufferLine +{ +    GObject parent;                         /* A laisser en premier        */ + +    line_column_t *columns;                 /* Répartition du texte        */ +    size_t col_count;                       /* Nombre de colonnes présentes*/ +    size_t merge_start;                     /* Début de la zone globale    */ + +    BufferLineFlags flags;                  /* Drapeaux particuliers       */ + +#if 0 + +    content_origin *origins;                /* Mémorisation des origines   */ +    size_t ocount;                          /* Nombre de ces mémorisations */ + +#endif + +}; + +/* Représentation de fragments de texte en ligne (classe) */ +struct _GBufferLineClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +#if 0 + +#ifdef INCLUDE_GTK_SUPPORT +    cairo_surface_t *entrypoint_img;        /* Image pour les entrées      */ +    cairo_surface_t *bookmark_img;          /* Image pour les signets      */ +#endif + +    /* Signaux */ + +    void (* content_changed) (GBufferLine *, line_segment *); + +    void (* flip_flag) (GBufferLine *, BufferLineFlags, BufferLineFlags); + +#endif + +}; + + + +/* Met en place une nouvelle représentation de bribes de texte. */ +bool g_buffer_line_create(GBufferLine *, size_t); + + + +#endif  /* _GLIBEXT_BUFFERLINE_INT_H */ diff --git a/src/glibext/bufferline.c b/src/glibext/bufferline.c index 2bdfebc..4862e9f 100644 --- a/src/glibext/bufferline.c +++ b/src/glibext/bufferline.c @@ -24,63 +24,27 @@  #include "bufferline.h" +#include "bufferline-int.h" + + + +#if 0 +  #include <assert.h>  #include <malloc.h>  #include <string.h>  #include "chrysamarshal.h" -#include "linecolumn.h" +//#include "linecolumn.h"  #include "../common/extstr.h"  #include "../core/paths.h" - - -/* ---------------------------- GESTION DE LINE COMPLETE ---------------------------- */ - - -/* Mémorisation des origines de texte */ -typedef struct _content_origin -{ -    col_coord_t coord;                      /* Localisation d'attachement  */ - -    GObject *creator;                       /* Origine de la création      */ - -} content_origin; - -/* Représentation de fragments de texte en ligne (instance) */ -struct _GBufferLine -{ -    GObject parent;                         /* A laisser en premier        */ - -    line_column *columns;                   /* Répartition du texte        */ -    size_t col_count;                       /* Nombre de colonnes présentes*/ -    size_t merge_start;                     /* Début de la zone globale    */ - -    BufferLineFlags flags;                  /* Drapeaux particuliers       */ - -    content_origin *origins;                /* Mémorisation des origines   */ -    size_t ocount;                          /* Nombre de ces mémorisations */ - -}; - -/* Représentation de fragments de texte en ligne (classe) */ -struct _GBufferLineClass -{ -    GObjectClass parent;                    /* A laisser en premier        */ - -#ifdef INCLUDE_GTK_SUPPORT -    cairo_surface_t *entrypoint_img;        /* Image pour les entrées      */ -    cairo_surface_t *bookmark_img;          /* Image pour les signets      */  #endif -    /* Signaux */ -    void (* content_changed) (GBufferLine *, line_segment *); -    void (* flip_flag) (GBufferLine *, BufferLineFlags, BufferLineFlags); - -}; +/* ---------------------------- GESTION DE LINE COMPLETE ---------------------------- */  /* Procède à l'initialisation d'une classe de représentation. */ @@ -106,7 +70,6 @@ static void g_buffer_line_finalize(GBufferLine *);  G_DEFINE_TYPE(GBufferLine, g_buffer_line, G_TYPE_OBJECT); -  /******************************************************************************  *                                                                             *  *  Paramètres  : class = classe de composant GTK à initialiser.               * @@ -131,6 +94,9 @@ static void g_buffer_line_class_init(GBufferLineClass *class)      object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_line_dispose;      object->finalize = (GObjectFinalizeFunc)g_buffer_line_finalize; + +#if 0 +  #ifdef INCLUDE_GTK_SUPPORT      filename = find_pixmap_file("entrypoint.png"); @@ -165,12 +131,14 @@ static void g_buffer_line_class_init(GBufferLineClass *class)                   g_cclosure_user_marshal_VOID__ENUM_ENUM,                   G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); +#endif +  }  /******************************************************************************  *                                                                             * -*  Paramètres  : line = composant GTK à initialiser.                          * +*  Paramètres  : line = composant GLib à initialiser.                         *  *                                                                             *  *  Description : Procède à l'initialisation d'une représentation de fragments.*  *                                                                             * @@ -203,10 +171,12 @@ static void g_buffer_line_init(GBufferLine *line)  static void g_buffer_line_dispose(GBufferLine *line)  { +#if 0      size_t i;                               /* Boucle de parcours          */      for (i = 0; i < line->ocount; i++)          g_object_unref(G_OBJECT(line->origins[i].creator)); +#endif      G_OBJECT_CLASS(g_buffer_line_parent_class)->dispose(G_OBJECT(line)); @@ -235,8 +205,10 @@ static void g_buffer_line_finalize(GBufferLine *line)      if (line->columns != NULL)          free(line->columns); +#if 0      if (line->origins != NULL)          free(line->origins); +#endif      G_OBJECT_CLASS(g_buffer_line_parent_class)->finalize(G_OBJECT(line)); @@ -258,22 +230,195 @@ static void g_buffer_line_finalize(GBufferLine *line)  GBufferLine *g_buffer_line_new(size_t col_count)  {      GBufferLine *result;                    /* Composant à retourner       */ -    size_t i;                               /* Boucle de parcours          */      result = g_object_new(G_TYPE_BUFFER_LINE, NULL); -    result->columns = malloc(col_count * sizeof(line_column)); +    if (!g_buffer_line_create(result, col_count)) +        g_clear_object(&result); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line      = ligne de représentation à initialiser.           * +*                col_count = quantité de colonnes à considérer.               * +*                                                                             * +*  Description : Met en place une nouvelle représentation de bribes de texte. * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_buffer_line_create(GBufferLine *line, size_t col_count) +{ +    bool result;                            /* Bilen à retourner           */ +    size_t i;                               /* Boucle de parcours          */ + +    result = true; + +    line->columns = malloc(col_count * sizeof(line_column_t));      for (i = 0; i < col_count; i++) -        init_line_column(&result->columns[i]); +        init_line_column(&line->columns[i]); -    result->col_count = col_count; +    line->col_count = col_count;      return result;  } + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line    = ligne à venir compléter.                           * +*                column  = colonne de la ligne visée par l'insertion.         * +*                tag     = type de décorateur à utiliser.                     * +*                text    = texte à insérer dans l'existant.                   * +*                length  = taille du texte à traiter.                         * +*                style   = gestionnaire de paramètres de rendu à consulter.   * +*                creator = instance GLib quelconque à associer.               * +*                                                                             * +*  Description : Ajoute du texte à formater dans une ligne donnée.            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_buffer_line_append_text(GBufferLine *line, size_t column, TokenRenderingTag tag, const char *text, size_t length, const GTokenStyle *style, GObject *creator) +{ +    size_t index;                           /* Indice d'insertion          */ +    //content_origin *origin;                 /* Définition d'une origine    */ + +    assert(column < line->col_count); +    assert(length > 0); + +    index = append_text_to_line_column(&line->columns[column], tag, text, length, style); + +    /* +    if (creator != NULL) +    { +        line->origins = realloc(line->origins, ++line->ocount * sizeof(content_origin)); + +        origin = &line->origins[line->ocount - 1]; + +        origin->coord.column = column; +        origin->coord.index = index; + +        origin->creator = creator; +        g_object_ref(G_OBJECT(creator)); + +    } +    */ + +} + + + + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line   = ligne de texte à manipuler.                         * +*                cr     = contexte graphique dédié à la procédure.            * +*                column = (première) colonne à traiter.                       * +*                y      = ordonnée du point d'impression.                     * +*                style  = style de rendu pour les bribes de texte.            * +*                                                                             * +*  Description : Imprime la ligne de texte représentée.                       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_buffer_line_draw(const GBufferLine *line, cairo_t *cr, size_t column, int y, const GTokenStyle *style) +{ +#if 0 +    GBufferLineClass *class;                /* Stockage de briques de base */ +    bool has_src_surface;                   /* Note une présence définie   */ +#endif +    size_t max_column;                      /* Borne de fin des colonnes   */ +    int x;                                  /* Point de départ d'impression*/ +    size_t i;                               /* Boucle de parcours          */ + +    /* +    if (line->flags != BLF_NONE) +    { +        class = G_BUFFER_LINE_GET_CLASS(line); + +        if (line->flags & BLF_ENTRYPOINT) +        { +            cairo_set_source_surface(cairo, class->entrypoint_img, 5, y); +            has_src_surface = true; +        } +        else if (line->flags & BLF_BOOKMARK) +        { +            cairo_set_source_surface(cairo, class->bookmark_img, 5, y); +            has_src_surface = true; +        } +        else +            has_src_surface = false; + +        if (has_src_surface) +            cairo_paint(cairo); + +    } +    */ + + +    /* Détermination de l'éventail des colonnes à traiter */ + +    if (column == line->merge_start) +        max_column = line->col_count; + +    else if (column > line->merge_start) +        max_column = 0; + +    else +        max_column = column + 1; + +    /* Dessin du contenu de ces colonnes */ + +    x = 0; + +    for (i = column; i < max_column; i++) +        draw_line_column(&line->columns[i], cr, &x, y, style); + +} + + + + + + + + + + +#if 0 + +  /******************************************************************************  *                                                                             *  *  Paramètres  : line = ligne à venir compléter.                              * @@ -1492,3 +1637,6 @@ void g_buffer_line_draw(GBufferLine *line, size_t index, cairo_t *cairo, gint x_  #endif + + +#endif diff --git a/src/glibext/bufferline.h b/src/glibext/bufferline.h index f5f25d0..d6a2e2d 100644 --- a/src/glibext/bufferline.h +++ b/src/glibext/bufferline.h @@ -25,10 +25,21 @@  #define _GLIBEXT_BUFFERLINE_H -#include <glib-object.h>  #include <stdbool.h> +#include "helpers.h" +#include "tokenstyle.h" + + + + + +#if 0 + +#include <glib-object.h> + +  #include "gdisplayoptions.h"  #include "linesegment.h"  #ifdef INCLUDE_GTK_SUPPORT @@ -60,6 +71,14 @@ typedef struct _GBufferLineClass GBufferLineClass;  /* Espace entre les colonnes */  #define COL_MARGIN 23 +#endif + + + +#define G_TYPE_BUFFER_LINE (g_buffer_line_get_type()) + +DECLARE_GTYPE(GBufferLine, g_buffer_line, G, BUFFER_LINE); +  /* Propriétés particulières supplémentaires */  typedef enum _BufferLineFlags @@ -76,12 +95,28 @@ typedef enum _BufferLineFlags  } BufferLineFlags; -/* Détermine le type de la représentation de fragments de texte en ligne. */ -GType g_buffer_line_get_type(void); -  /* Crée une nouvelle représentation de fragments de texte. */  GBufferLine *g_buffer_line_new(size_t); + + +/* Ajoute du texte à formater dans une ligne donnée. */ +void g_buffer_line_append_text(GBufferLine *, size_t, TokenRenderingTag, const char *, size_t, const GTokenStyle *, GObject *); + + + +/* Imprime la ligne de texte représentée. */ +void g_buffer_line_draw(const GBufferLine *, cairo_t *, size_t, int, const GTokenStyle *); + + + + + +#if 0 + +/* Détermine le type de la représentation de fragments de texte en ligne. */ +GType g_buffer_line_get_type(void); +  /* Construit le tronc commun d'une ligne autour de sa position. */  void g_buffer_line_fill_phys(GBufferLine *, size_t, MemoryDataSize, const vmpa2t *); @@ -95,7 +130,7 @@ void g_buffer_line_fill_content(GBufferLine *, size_t, const GBinContent *, cons  GObject *g_buffer_line_find_first_segment_creator(const GBufferLine *, size_t);  /* Ajoute du texte à formater dans une ligne donnée. */ -void g_buffer_line_append_text(GBufferLine *, size_t, const char *, size_t, RenderingTagType, GObject *); +//void g_buffer_line_append_text(GBufferLine *, size_t, const char *, size_t, RenderingTagType, GObject *);  /* Remplace du texte dans une ligne donnée. */  bool g_buffer_line_replace_text(GBufferLine *, const GObject *, const char *, size_t); @@ -162,7 +197,10 @@ GObject *g_buffer_line_get_creator_at(const GBufferLine *, size_t, GWidthTracker  bool g_buffer_line_find_near_coord(const GBufferLine *, size_t, col_coord_t *, GWidthTracker *, const GDisplayOptions *, GdkScrollDirection, gint *);  /* Imprime la ligne de texte représentée. */ -void g_buffer_line_draw(GBufferLine *, size_t, cairo_t *, gint, gint, GWidthTracker *, const GDisplayOptions *, const segcnt_list *); +//void g_buffer_line_draw(GBufferLine *, size_t, cairo_t *, gint, gint, GWidthTracker *, const GDisplayOptions *, const segcnt_list *); + +#endif +  #endif diff --git a/src/glibext/bufferview-int.h b/src/glibext/bufferview-int.h new file mode 100644 index 0000000..7751c1e --- /dev/null +++ b/src/glibext/bufferview-int.h @@ -0,0 +1,83 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bufferview.h - prototypes pour l'affichage d'une vue particulière d'un tampon de lignes + * + * Copyright (C) 2016-2024 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GLIBEXT_BUFFERVIEW_INT_H +#define _GLIBEXT_BUFFERVIEW_INT_H + + +#include "bufferview.h" + + +/* Vue d'un tampon pour code désassemblé (instance) */ +struct _GBufferView +{ +    GObject parent;                         /* A laisser en premier        */ + +    GBufferCache *cache;                    /* Tampon du contenu visualisé */ +    GWidthTracker *tracker;                 /* Collecteur de largeurs      */ +    GTokenStyle *style;                     /* Style dédié aux rendus      */ + + + +    bool unrestricted;                      /* Validité des informations   */ + + +    size_t first;                           /* Indice de la première ligne */ +    size_t last;                            /* Indice de la dernière ligne */ + + +#if 0 + +    segcnt_list *highlighted;               /* Segments mis en évidence    */ + +    //bool unrestricted;                      /* Validité des informations   */ +    GLineCursor *start;                     /* Première ligne intégrée     */ +    GLineCursor *end;                       /* Dernière ligne intégrée     */ + +    //size_t first;                           /* Indice de la première ligne */ +    //size_t last;                            /* Indice de la dernière ligne */ + +    GWidthTracker *tracker;                 /* Suivi des largeurs          */ + +#endif + +}; + +/* Vue d'un tampon pour code désassemblé (classe) */ +struct _GBufferViewClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +    /* Signaux */ + +    void (* need_redraw) (GBufferView *); + +}; + + +/* Met en place une nouvelle vue pour un tampon de texte. */ +bool g_buffer_view_create(GBufferView *, GBufferCache *, GTokenStyle *); + + + +#endif  /* _GLIBEXT_BUFFERVIEW_INT_H */ diff --git a/src/glibext/bufferview.c b/src/glibext/bufferview.c index 72740b1..3747e2c 100644 --- a/src/glibext/bufferview.c +++ b/src/glibext/bufferview.c @@ -2,7 +2,7 @@  /* Chrysalide - Outil d'analyse de fichiers binaires   * bufferview.c - affichage d'une vue particulière d'un tampon de lignes   * - * Copyright (C) 2016-2019 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -24,46 +24,17 @@  #include "bufferview.h" -#include <assert.h> - +#include "bufferview-int.h" -/* Vue d'un tampon pour code désassemblé (instance) */ -struct _GBufferView -{ -    GObject parent;                         /* A laisser en premier        */ -    GBufferCache *cache;                    /* Tampon du contenu visualisé */ - -    segcnt_list *highlighted;               /* Segments mis en évidence    */ - -    bool unrestricted;                      /* Validité des informations   */ -    GLineCursor *start;                     /* Première ligne intégrée     */ -    GLineCursor *end;                       /* Dernière ligne intégrée     */ - -    size_t first;                           /* Indice de la première ligne */ -    size_t last;                            /* Indice de la dernière ligne */ - -    GWidthTracker *tracker;                 /* Suivi des largeurs          */ - -}; - -/* Vue d'un tampon pour code désassemblé (classe) */ -struct _GBufferViewClass -{ -    GObjectClass parent;                    /* A laisser en premier        */ - -    /* Signaux */ - -    void (* need_redraw) (GBufferView *); - -}; +/* -------------------------- DEFINITION D'UN NOUVEL OBJET -------------------------- */  /* Procède à l'initialisation d'une classe de vue de tampon. */  static void g_buffer_view_class_init(GBufferViewClass *); -/* Procède à l'initialisation d'une vue d'un tampon pour code. */ +/* Procède à l'initialisation d'une vue d'un tampon. */  static void g_buffer_view_init(GBufferView *);  /* Supprime toutes les références externes. */ @@ -75,23 +46,15 @@ static void g_buffer_view_finalize(GBufferView *);  /* Accompagne une variation de la quantité de lignes du tampon. */  static void on_buffer_cache_size_changed(const GBufferCache *, bool, size_t, size_t, GBufferView *); -/* Réagit à la modification d'une ligne du tampon. */ -static void on_buffer_cache_line_updated(const GBufferCache *, size_t, GBufferView *); - -/* Calcule la position idéale de curseur pour un point donné. */ -static bool _g_buffer_view_compute_caret_full(GBufferView *, gint, GBufferLine *, size_t, const GDisplayOptions *, cairo_rectangle_int_t *, GLineCursor **); - -/* Fournit la ligne présente à une ordonnée donnée. */ -static GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *); - -/* Déplace le curseur au sein d'une vue de tampon. */ -static bool _g_buffer_view_move_caret(GBufferView *, const GBufferLine *, size_t, cairo_rectangle_int_t *, bool, GdkScrollDirection, const GDisplayOptions *); +/* ---------------------------------------------------------------------------------- */ +/*                            DEFINITION D'UN NOUVEL OBJET                            */ +/* ---------------------------------------------------------------------------------- */  /* Détermine le type de la vue d'un tampon pour code désassemblé. */ @@ -100,7 +63,7 @@ G_DEFINE_TYPE(GBufferView, g_buffer_view, G_TYPE_OBJECT);  /******************************************************************************  *                                                                             * -*  Paramètres  : class = classe de composant GTK à initialiser.               * +*  Paramètres  : class = classe de composant GLib à initialiser.              *  *                                                                             *  *  Description : Procède à l'initialisation d'une classe de vue de tampon.    *  *                                                                             * @@ -136,7 +99,7 @@ static void g_buffer_view_class_init(GBufferViewClass *class)  *                                                                             *  *  Paramètres  : view = composant GLib à initialiser.                         *  *                                                                             * -*  Description : Procède à l'initialisation d'une vue d'un tampon pour code.  * +*  Description : Procède à l'initialisation d'une vue d'un tampon.            *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -147,22 +110,26 @@ static void g_buffer_view_class_init(GBufferViewClass *class)  static void g_buffer_view_init(GBufferView *view)  {      view->cache = NULL; - -    view->highlighted = NULL; +    view->tracker = NULL; +    view->style = NULL;      /**       * Inversion du statut pour forcer l'actualisation lors de la création.       */      view->unrestricted = false; +#if 0 +      view->start = NULL;      view->end = NULL; +#endif + + +      view->first = 0;      view->last = 0; -    view->tracker = NULL; -  } @@ -181,11 +148,13 @@ static void g_buffer_view_init(GBufferView *view)  static void g_buffer_view_dispose(GBufferView *view)  {      g_clear_object(&view->cache); +    g_clear_object(&view->tracker); +    g_clear_object(&view->style); +#if 0      g_clear_object(&view->start);      g_clear_object(&view->end); - -    g_clear_object(&view->tracker); +#endif      G_OBJECT_CLASS(g_buffer_view_parent_class)->dispose(G_OBJECT(view)); @@ -206,9 +175,6 @@ static void g_buffer_view_dispose(GBufferView *view)  static void g_buffer_view_finalize(GBufferView *view)  { -    if (view->highlighted != NULL) -        unref_segment_content_list(view->highlighted); -      G_OBJECT_CLASS(g_buffer_view_parent_class)->finalize(G_OBJECT(view));  } @@ -216,38 +182,25 @@ static void g_buffer_view_finalize(GBufferView *view)  /******************************************************************************  *                                                                             * -*  Paramètres  : buffer      = tampon à représenter à l'écran.                * -*                highlighted = gestionnaire de surbrillance pour segments.    * +*  Paramètres  : cache = cache de lignes à présenter à la vue.                * +*                style = modèles de rendus pour tous les types de bribes.     *  *                                                                             * -*  Description : Crée une nouvelle vue d'un tampon pour code désassemblé.     * +*  Description : Crée une nouvelle vue d'un tampon de texte.                  *  *                                                                             * -*  Retour      : Composant GTK créé.                                          * +*  Retour      : Vue de tampon mise en place ou NULL en cas d'erreur.         *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GBufferView *g_buffer_view_new(GBufferCache *cache, segcnt_list *highlighted) +GBufferView *g_buffer_view_new(GBufferCache *cache, GTokenStyle *style)  {      GBufferView *result;                    /* Composant à retourner       */      result = g_object_new(G_TYPE_BUFFER_VIEW, NULL); -    result->cache = cache; -    g_object_ref_sink(G_OBJECT(cache)); - -    g_buffer_view_restrict(result, NULL, NULL); - -    g_signal_connect(cache, "size-changed", G_CALLBACK(on_buffer_cache_size_changed), result); -    g_signal_connect(cache, "line-updated", G_CALLBACK(on_buffer_cache_line_updated), result); - -    if (highlighted != NULL) -    { -        ref_segment_content_list(highlighted); -        result->highlighted = highlighted; -    } -    else -        result->highlighted = init_segment_content_list(); +    if (!g_buffer_view_create(result, cache, style)) +        g_clear_object(&result);      return result; @@ -256,21 +209,50 @@ GBufferView *g_buffer_view_new(GBufferCache *cache, segcnt_list *highlighted)  /******************************************************************************  *                                                                             * -*  Paramètres  : cache = tampon de lignes cohérentes à manipuler.             * -*                index = indice de la première ligne actualisée.              * +*  Paramètres  : view  = vue de tampon à initialiser.                         * +*                cache = cache de lignes à présenter à la vue.                * +*                style = modèles de rendus pour tous les types de bribes.     *  *                                                                             * -*  Description : Réagit à la modification d'une ligne du tampon.              * +*  Description : Met en place une nouvelle vue pour un tampon de texte.       *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static void on_buffer_cache_line_updated(const GBufferCache *cache, size_t index, GBufferView *view) +bool g_buffer_view_create(GBufferView *view, GBufferCache *cache, GTokenStyle *style)  { -    if (view->first <= index && index <= view->last) -        g_signal_emit_by_name(view, "need-redraw"); +    bool result;                            /* Bilan à retourner           */ + +    result = true; + +    view->cache = cache; +    ref_object(cache); + +    view->tracker = g_width_tracker_new(cache); + +    view->style = style; +    ref_object(style); + +    g_buffer_view_restrict(view, NULL, NULL); + +    g_signal_connect(cache, "size-changed", G_CALLBACK(on_buffer_cache_size_changed), view); + + +#if 0 +    g_signal_connect(cache, "line-updated", G_CALLBACK(on_buffer_cache_line_updated), result); + +    if (highlighted != NULL) +    { +        ref_segment_content_list(highlighted); +        result->highlighted = highlighted; +    } +    else +        result->highlighted = init_segment_content_list(); +#endif + +    return result;  } @@ -411,7 +393,32 @@ GBufferCache *g_buffer_view_get_cache(const GBufferView *view)      result = view->cache; -    g_object_ref(G_OBJECT(result)); +    ref_object(result); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : view = visualisateur à consulter.                            * +*                                                                             * +*  Description : Fournit le collecteur de largeurs associé au tampon lié.     * +*                                                                             * +*  Retour      : Collecteur de largeurs des lignes du tampon représenté.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GWidthTracker *g_buffer_view_get_tracker(const GBufferView *view) +{ +    GWidthTracker *result;                  /* Instance à retourner        */ + +    result = view->tracker; + +    ref_object(result);      return result; @@ -432,10 +439,10 @@ GBufferCache *g_buffer_view_get_cache(const GBufferView *view)  *                                                                             *  ******************************************************************************/ -void g_buffer_view_restrict(GBufferView *view, GLineCursor *start, GLineCursor *end) +void g_buffer_view_restrict(GBufferView *view, /*GLineCursor*/void *start, /*GLineCursor*/void *end)  {      bool state;                             /* Nouvel état à proclamer     */ -    GWidthTracker *template;                /* Suivi déjà en place         */ +    //GWidthTracker *template;                /* Suivi déjà en place         */      state = (start == NULL || end == NULL); @@ -443,11 +450,11 @@ void g_buffer_view_restrict(GBufferView *view, GLineCursor *start, GLineCursor *      {          view->unrestricted = state; -        template = g_buffer_cache_get_width_tracker(view->cache); +        //template = g_buffer_cache_get_width_tracker(view->cache);          /* Vérification pour le cas particulier du démarrage */ -        if (view->tracker != NULL) -            g_object_unref(G_OBJECT(view->tracker)); +        //if (view->tracker != NULL) +        //    g_object_unref(G_OBJECT(view->tracker));          g_buffer_cache_rlock(view->cache); @@ -456,12 +463,14 @@ void g_buffer_view_restrict(GBufferView *view, GLineCursor *start, GLineCursor *              view->first = 0;              view->last = g_buffer_cache_count_lines(view->cache) - 1; -            view->tracker = template; +            //view->tracker = template;          }          else          { +            /* +              g_object_ref_sink(G_OBJECT(start));              g_object_ref_sink(G_OBJECT(end)); @@ -475,6 +484,8 @@ void g_buffer_view_restrict(GBufferView *view, GLineCursor *start, GLineCursor *              g_object_unref(G_OBJECT(template)); +            */ +          }          g_buffer_cache_runlock(view->cache); @@ -484,6 +495,156 @@ void g_buffer_view_restrict(GBufferView *view, GLineCursor *start, GLineCursor *  } + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : view   = visualisation à consulter.                          * +*                style  = style de rendu pour les bribes de texte.            * +*                width  = largeur requise pour un affichage complet. [OUT]    * +*                height = hauteur requise pour un affichage complet. [OUT]    * +*                                                                             * +*  Description : Détermine la taille nécessaire à une représentation complète.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_buffer_view_compute_size(const GBufferView *view, int *width, int *height) +{ +    size_t last;                            /* Dernière ligne à dessiner   */ + +    /* Largeur de l'ensemble des colonnes */ + +    g_width_tracker_compute_width(view->tracker, width); + +    /* Hauteur de l'ensemble des lignes */ + +    *height = g_token_style_get_line_height(view->style) * (view->last + 1); + +} + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : view     = visualisation à représenter.                      * +*                cr       = contexte graphique dédié à la procédure.          * +*                column   = (première) colonne à traiter.                     * +*                virt_top = ordonnée présentée au point 0 à l'écran.          * +*                height   = hauteur disponible pour les représentations.      * +*                                                                             * +*  Description : Imprime la visualisation du tampon de lignes quelconques.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, size_t column, int virt_top, int height) +{ +    int 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        */ + +    line_height = g_token_style_get_line_height(view->style); + +    /* Indice et point de départ */ + +    first = view->first; +    first += (virt_top / line_height); + +    cr_y = -(virt_top % line_height); + +    /* Indice de d'arrivée */ + +    last = first + (height / line_height); +    if (height % line_height > 0) last++; + +    last = MIN(last, view->last); + +    /* Phase de dessin ! */ + +    g_buffer_cache_draw(view->cache, cr, column, cr_y, first, last, view->style); + +} + + + + + + + + + + + + + +#if 0 + +#include <assert.h> + + + + +/* Accompagne une variation de la quantité de lignes du tampon. */ +//static void on_buffer_cache_size_changed(const GBufferCache *, bool, size_t, size_t, GBufferView *); + +/* Réagit à la modification d'une ligne du tampon. */ +static void on_buffer_cache_line_updated(const GBufferCache *, size_t, GBufferView *); + +/* Calcule la position idéale de curseur pour un point donné. */ +static bool _g_buffer_view_compute_caret_full(GBufferView *, gint, GBufferLine *, size_t, const GDisplayOptions *, cairo_rectangle_int_t *, GLineCursor **); + +/* Fournit la ligne présente à une ordonnée donnée. */ +static GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *); + +/* Déplace le curseur au sein d'une vue de tampon. */ +static bool _g_buffer_view_move_caret(GBufferView *, const GBufferLine *, size_t, cairo_rectangle_int_t *, bool, GdkScrollDirection, const GDisplayOptions *); + + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : cache = tampon de lignes cohérentes à manipuler.             * +*                index = indice de la première ligne actualisée.              * +*                                                                             * +*  Description : Réagit à la modification d'une ligne du tampon.              * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_buffer_cache_line_updated(const GBufferCache *cache, size_t index, GBufferView *view) +{ +    if (view->first <= index && index <= view->last) +        g_signal_emit_by_name(view, "need-redraw"); + +} + + + + +  /******************************************************************************  *                                                                             *  *  Paramètres  : view  = visualisateur à consulter.                           * @@ -1313,3 +1474,44 @@ bool g_buffer_view_get_cursor_coordinates(GBufferView *view, const GLineCursor *      return result;  } + + + +#endif + + + + + +#if 0 + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : view   = visualisation à consulter.                          * +*                cursor = emplacement à 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]      * +*                                                                             * +*  Description : Indique la position d'affichage d'une adresse donnée.        * +*                                                                             * +*  Retour      : true si l'adresse fait partie du composant, false sinon.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_buffer_view_allocate_widths(GBufferView *view, int width, int height, int fill, int *out) +{ + + + + + + +} + + + +#endif diff --git a/src/glibext/bufferview.h b/src/glibext/bufferview.h index 43e6293..d5af6d1 100644 --- a/src/glibext/bufferview.h +++ b/src/glibext/bufferview.h @@ -2,7 +2,7 @@  /* Chrysalide - Outil d'analyse de fichiers binaires   * bufferview.h - prototypes pour l'affichage d'une vue particulière d'un tampon de lignes   * - * Copyright (C) 2016-2019 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -25,6 +25,48 @@  #define _GLIBEXT_BUFFERVIEW_H +#include "buffercache.h" +#include "helpers.h" +#include "tokenstyle.h" +#include "widthtracker.h" + + + +#define G_TYPE_BUFFER_VIEW (g_buffer_view_get_type()) + +DECLARE_GTYPE(GBufferView, g_buffer_view, G, BUFFER_VIEW); + + +/* Crée une nouvelle vue d'un tampon de texte. */ +GBufferView *g_buffer_view_new(GBufferCache *, GTokenStyle *); + +/* Fournit le tampon de code lié à un visualisateur donné. */ +GBufferCache *g_buffer_view_get_cache(const GBufferView *); + +/* Fournit le collecteur de largeurs associé au tampon lié. */ +GWidthTracker *g_buffer_view_get_tracker(const GBufferView *); + +/* Restreint le champ d'application de l'affichage. */ +void g_buffer_view_restrict(GBufferView *, /*GLineCursor*/void *, /*GLineCursor*/void *); + + + +/* Détermine la taille nécessaire à une représentation complète. */ +void g_buffer_view_compute_size(const GBufferView *, int *, int *); + + + +/* Imprime la visualisation du tampon de lignes quelconques. */ +void g_buffer_view_draw(const GBufferView *, cairo_t *, size_t, int, int); + + + + + + + +#if 0 +  #include <glib-object.h> @@ -52,13 +94,13 @@ typedef struct _GBufferViewClass GBufferViewClass;  GType g_buffer_view_get_type(void);  /* Crée une nouvelle vue d'un tampon pour lignes générées. */ -GBufferView *g_buffer_view_new(GBufferCache *, segcnt_list *); +//GBufferView *g_buffer_view_new(GBufferCache *, segcnt_list *);  /* Fournit le tampon de code lié à un visualisateur donné. */ -GBufferCache *g_buffer_view_get_cache(const GBufferView *); +//GBufferCache *g_buffer_view_get_cache(const GBufferView *);  /* Restreint le champ d'application de l'affichage. */ -void g_buffer_view_restrict(GBufferView *, GLineCursor *, GLineCursor *); +//void g_buffer_view_restrict(GBufferView *, GLineCursor *, GLineCursor *);  /* Indique le champ d'application de l'affichage. */  bool g_buffer_view_get_restrictions(const GBufferView *, GLineCursor **, GLineCursor **); @@ -110,6 +152,9 @@ bool g_buffer_view_get_cursor_coordinates(GBufferView *, const GLineCursor *, bo +#endif + +  #endif  /* _GLIBEXT_BUFFERVIEW_H */ diff --git a/src/glibext/generator-int.h b/src/glibext/generator-int.h index 6952f69..8b7e28d 100644 --- a/src/glibext/generator-int.h +++ b/src/glibext/generator-int.h @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * linegen-int.h - définitions internes propres aux intermédiaires de génération de lignes + * generator-int.h - définitions internes propres aux intermédiaires de génération de lignes à partir de bribres de texte   * - * Copyright (C) 2016-2018 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -21,47 +21,52 @@   */ -#ifndef _GLIBEXT_LINEGEN_INT_H -#define _GLIBEXT_LINEGEN_INT_H +#ifndef _GLIBEXT_GENERATOR_INT_H +#define _GLIBEXT_GENERATOR_INT_H -#include "linegen.h" +#include "generator.h"  /* Indique le nombre de ligne prêtes à être générées. */ -typedef size_t (* linegen_count_lines_fc) (const GLineGenerator *); +typedef size_t (* count_tokgen_lines_fc) (const GTokenGenerator *); + +/* Renseigne sur les propriétés liées à un générateur. */ +typedef BufferLineFlags (* get_tokgen_flags_fc) (const GTokenGenerator *, size_t, size_t); + +/* Imprime dans une ligne de rendu le contenu représenté. */ +typedef void (* populate_tokgen_line_fc) (const GTokenGenerator *, size_t, size_t, GBufferLine *, void *); + +#if 0  /* Retrouve l'emplacement correspondant à une position donnée. */ -typedef void (* linegen_compute_fc) (const GLineGenerator *, gint, size_t, size_t, GLineCursor **); +typedef void (* compute_tokgen_fc) (const GTokenGenerator *, gint, size_t, size_t, GLineCursor **);  /* Détermine si le conteneur s'inscrit dans une plage donnée. */ -typedef int (* linegen_contain_fc) (const GLineGenerator *, size_t, size_t, const GLineCursor *); +typedef int (* contain_tokgen_fc) (const GTokenGenerator *, size_t, size_t, const GLineCursor *); -/* Renseigne sur les propriétés liées à un générateur. */ -typedef BufferLineFlags (* linegen_get_flags_fc) (const GLineGenerator *, size_t, size_t); - -/* Imprime dans une ligne de rendu le contenu représenté. */ -typedef void (* linegen_print_fc) (GLineGenerator *, GBufferLine *, size_t, size_t, const GBinContent *); +#endif  /* Intermédiaire pour la génération de lignes (interface) */ -struct _GLineGeneratorIface +struct _GTokenGeneratorInterface  {      GTypeInterface base_iface;              /* A laisser en premier        */ -    linegen_count_lines_fc count;           /* Décompte des lignes         */ -    linegen_compute_fc compute;             /* Calcul d'emplacement        */ -    linegen_contain_fc contain;             /* Inclusion de positions      */ -    linegen_get_flags_fc get_flags;         /* Récupération des drapeaux   */ -    linegen_print_fc print;                 /* Impression d'une ligne      */ +    count_tokgen_lines_fc count;            /* Décompte des lignes         */ +    get_tokgen_flags_fc get_flags;          /* Récupération des drapeaux   */ +    populate_tokgen_line_fc populate;       /* Impression d'une ligne      */ -}; +#if 0 +    compute_tokgen_fc compute;              /* Calcul d'emplacement        */ +    contain_tokgen_fc contain;              /* Inclusion de positions      */ -/* Redéfinition */ -typedef GLineGeneratorIface GLineGeneratorInterface; +#endif + +}; -#endif  /* _GLIBEXT_LINEGEN_INT_H */ +#endif  /* _GLIBEXT_GENERATOR_INT_H */ diff --git a/src/glibext/generator.c b/src/glibext/generator.c index c5291ab..2d3d349 100644 --- a/src/glibext/generator.c +++ b/src/glibext/generator.c @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * linegen.c - intermédiaires de génération de lignes + * generator.c - intermédiaires de génération de lignes à partir de bribres de texte   * - * Copyright (C) 2016-2018 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -21,23 +21,26 @@   */ -#include "linegen.h" +#include "generator.h"  #include <assert.h> -#include "linegen-int.h" +#include "generator-int.h"  /* Procède à l'initialisation de l'interface de génération. */ -static void g_line_generator_default_init(GLineGeneratorInterface *); +static void g_token_generator_default_init(GTokenGeneratorInterface *); + +/* Indique le nombre de ligne prêtes à être générées. */ +static size_t _g_token_generator_count_one_line(const GTokenGenerator *);  /* Détermine le type d'une interface pour la mise en place de lignes. */ -G_DEFINE_INTERFACE(GLineGenerator, g_line_generator, G_TYPE_OBJECT) +G_DEFINE_INTERFACE(GTokenGenerator, g_token_generator, G_TYPE_OBJECT)  /****************************************************************************** @@ -52,8 +55,32 @@ G_DEFINE_INTERFACE(GLineGenerator, g_line_generator, G_TYPE_OBJECT)  *                                                                             *  ******************************************************************************/ -static void g_line_generator_default_init(GLineGeneratorInterface *iface) +static void g_token_generator_default_init(GTokenGeneratorInterface *iface) +{ +    iface->count = _g_token_generator_count_one_line; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : generator = générateur à consulter.                          * +*                                                                             * +*  Description : Indique le nombre de ligne prêtes à être générées.           * +*                                                                             * +*  Retour      : Nombre de lignes devant apparaître au final.                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static size_t _g_token_generator_count_one_line(const GTokenGenerator *generator)  { +    size_t result;                          /* Décompte à retourner        */ + +    result = 1; + +    return result;  } @@ -70,12 +97,12 @@ static void g_line_generator_default_init(GLineGeneratorInterface *iface)  *                                                                             *  ******************************************************************************/ -size_t g_line_generator_count_lines(const GLineGenerator *generator) +size_t g_token_generator_count_lines(const GTokenGenerator *generator)  {      size_t result;                          /* Décompte à retourner        */ -    GLineGeneratorIface *iface;             /* Interface utilisée          */ +    GTokenGeneratorInterface *iface;        /* Interface utilisée          */ -    iface = G_LINE_GENERATOR_GET_IFACE(generator); +    iface = G_TOKEN_GENERATOR_GET_IFACE(generator);      result = iface->count(generator); @@ -87,31 +114,29 @@ size_t g_line_generator_count_lines(const GLineGenerator *generator)  /******************************************************************************  *                                                                             *  *  Paramètres  : generator = générateur à consulter.                          * -*                x         = position géographique sur la ligne concernée.    *  *                index     = indice de cette même ligne dans le tampon global.*  *                repeat    = indice d'utilisations successives du générateur. *  *                                                                             * -*  Description : Retrouve l'emplacement correspondant à une position donnée.  * +*  Description : Renseigne sur les propriétés liées à un générateur.          *  *                                                                             * -*  Retour      : Emplacement constitué.                                       * +*  Retour      : Propriétés particulières associées.                          *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GLineCursor *g_line_generator_compute_cursor(const GLineGenerator *generator, gint x, size_t index, size_t repeat) +BufferLineFlags g_token_generator_get_flags(const GTokenGenerator *generator, size_t index, size_t repeat)  { -    GLineCursor *result;                    /* Emplacement à renvoyer      */ -    GLineGeneratorIface *iface;             /* Interface utilisée          */ +    BufferLineFlags result;                 /* Fanions à retourner         */ +    GTokenGeneratorInterface *iface;        /* Interface utilisée          */ -    iface = G_LINE_GENERATOR_GET_IFACE(generator); +    iface = G_TOKEN_GENERATOR_GET_IFACE(generator);  #ifndef NDEBUG -    if (iface->count != NULL) -        assert(repeat < g_line_generator_count_lines(generator)); +    assert(repeat < g_token_generator_count_lines(generator));  #endif -    iface->compute(generator, x, index, repeat, &result); +    result = iface->get_flags(generator, index, repeat);      return result; @@ -120,65 +145,65 @@ GLineCursor *g_line_generator_compute_cursor(const GLineGenerator *generator, gi  /******************************************************************************  *                                                                             * -*  Paramètres  : generator = générateur à consulter.                          * +*  Paramètres  : generator = générateur à utiliser pour l'impression.         *  *                index     = indice de cette même ligne dans le tampon global.*  *                repeat    = indice d'utilisations successives du générateur. * -*                cursor    = emplacement à analyser.                          * +*                line      = ligne de rendu à compléter.                      * +*                data      = éventuelle donnée complémentaire fournie.        *  *                                                                             * -*  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   * +*  Description : Etablit dans une ligne de rendu le contenu représenté.       *  *                                                                             * -*  Retour      : Bilan de la détermination, utilisable en comparaisons.       * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -int g_line_generator_contain_cursor(const GLineGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor) +void g_token_generator_populate_line(const GTokenGenerator *generator, size_t index, size_t repeat, GBufferLine *line, void *data)  { -    int result;                             /* Bilan d'analyse à retourner */ -    GLineGeneratorIface *iface;             /* Interface utilisée          */ +    GTokenGeneratorInterface *iface;        /* Interface utilisée          */ -    iface = G_LINE_GENERATOR_GET_IFACE(generator); +    iface = G_TOKEN_GENERATOR_GET_IFACE(generator);  #ifndef NDEBUG -    if (iface->count != NULL) -        assert(repeat < g_line_generator_count_lines(generator)); +    assert(repeat < g_token_generator_count_lines(generator));  #endif -    result = iface->contain(generator, index, repeat, cursor); - -    return result; +    iface->populate(generator, index, repeat, line, data);  } +#if 0 + +  /******************************************************************************  *                                                                             *  *  Paramètres  : generator = générateur à consulter.                          * +*                x         = position géographique sur la ligne concernée.    *  *                index     = indice de cette même ligne dans le tampon global.*  *                repeat    = indice d'utilisations successives du générateur. *  *                                                                             * -*  Description : Renseigne sur les propriétés liées à un générateur.          * +*  Description : Retrouve l'emplacement correspondant à une position donnée.  *  *                                                                             * -*  Retour      : Propriétés particulières associées.                          * +*  Retour      : Emplacement constitué.                                       *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -BufferLineFlags g_line_generator_get_flags(const GLineGenerator *generator, size_t index, size_t repeat) +GLineCursor *g_token_generator_compute_cursor(const GTokenGenerator *generator, gint x, size_t index, size_t repeat)  { -    BufferLineFlags result;                 /* Fanions à retourner         */ -    GLineGeneratorIface *iface;             /* Interface utilisée          */ +    GLineCursor *result;                    /* Emplacement à renvoyer      */ +    GTokenGeneratorInterface *iface;        /* Interface utilisée          */ -    iface = G_LINE_GENERATOR_GET_IFACE(generator); +    iface = G_TOKEN_GENERATOR_GET_IFACE(generator);  #ifndef NDEBUG -    if (iface->count != NULL) -        assert(repeat < g_line_generator_count_lines(generator)); +    assert(repeat < g_token_generator_count_lines(generator));  #endif -    result = iface->get_flags(generator, index, repeat); +    iface->compute(generator, x, index, repeat, &result);      return result; @@ -187,31 +212,35 @@ BufferLineFlags g_line_generator_get_flags(const GLineGenerator *generator, size  /******************************************************************************  *                                                                             * -*  Paramètres  : generator = générateur à utiliser pour l'impression.         * -*                line      = ligne de rendu à compléter.                      * +*  Paramètres  : generator = générateur à consulter.                          *  *                index     = indice de cette même ligne dans le tampon global.*  *                repeat    = indice d'utilisations successives du générateur. * -*                content   = éventuel contenu binaire brut à imprimer.        * +*                cursor    = emplacement à analyser.                          *  *                                                                             * -*  Description : Imprime dans une ligne de rendu le contenu représenté.       * +*  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Bilan de la détermination, utilisable en comparaisons.       *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -void g_line_generator_print(GLineGenerator *generator, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content) +int g_token_generator_contain_cursor(const GTokenGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor)  { -    GLineGeneratorIface *iface;             /* Interface utilisée          */ +    int result;                             /* Bilan d'analyse à retourner */ +    GTokenGeneratorInterface *iface;        /* Interface utilisée          */ -    iface = G_LINE_GENERATOR_GET_IFACE(generator); +    iface = G_TOKEN_GENERATOR_GET_IFACE(generator);  #ifndef NDEBUG -    if (iface->count != NULL) -        assert(repeat < g_line_generator_count_lines(generator)); +    assert(repeat < g_token_generator_count_lines(generator));  #endif -    iface->print(generator, line, index, repeat, content); +    result = iface->contain(generator, index, repeat, cursor); + +    return result;  } + + +#endif diff --git a/src/glibext/generator.h b/src/glibext/generator.h index d40a598..c93e0a0 100644 --- a/src/glibext/generator.h +++ b/src/glibext/generator.h @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * linegen.h - prototypes pour les intermédiaires de génération de lignes + * generator.h - prototypes pour les intermédiaires de génération de lignes à partir de bribres de texte   * - * Copyright (C) 2016-2018 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -21,52 +21,43 @@   */ -#ifndef _GLIBEXT_LINEGEN_H -#define _GLIBEXT_LINEGEN_H - - -#include <glib-object.h> +#ifndef _GLIBEXT_GENERATOR_H +#define _GLIBEXT_GENERATOR_H  #include "bufferline.h" +#include "helpers.h" +/*  #include "glinecursor.h" -#include "../analysis/content.h" +*/ -#define G_TYPE_LINE_GENERATOR               g_line_generator_get_type() -#define G_LINE_GENERATOR(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LINE_GENERATOR, GLineGenerator)) -#define G_LINE_GENERATOR_CLASS(vtable)      (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_LINE_GENERATOR, GLineGeneratorIface)) -#define GTK_IS_LINE_GENERATOR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LINE_GENERATOR)) -#define GTK_IS_LINE_GENERATOR_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_LINE_GENERATOR)) -#define G_LINE_GENERATOR_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_LINE_GENERATOR, GLineGeneratorIface)) +#define G_TYPE_TOKEN_GENERATOR (g_token_generator_get_type()) +DECLARE_INTERFACE(GTokenGenerator, g_token_generator, G, TOKEN_GENERATOR); -/* Intermédiaire pour la génération de lignes (coquille vide) */ -typedef struct _GLineGenerator GLineGenerator; -/* Intermédiaire pour la génération de lignes (interface) */ -typedef struct _GLineGeneratorIface GLineGeneratorIface; +/* Indique le nombre de ligne prêtes à être générées. */ +size_t g_token_generator_count_lines(const GTokenGenerator *); -/* Détermine le type d'une interface pour la mise en place de lignes. */ -GType g_line_generator_get_type(void) G_GNUC_CONST; +/* Renseigne sur les propriétés liées à un générateur. */ +BufferLineFlags g_token_generator_get_flags(const GTokenGenerator *, size_t, size_t); -/* Indique le nombre de ligne prêtes à être générées. */ -size_t g_line_generator_count_lines(const GLineGenerator *); +/* Etablit dans une ligne de rendu le contenu représenté. */ +void g_token_generator_populate_line(const GTokenGenerator *, size_t, size_t, GBufferLine *, void *); -/* Retrouve l'emplacement correspondant à une position donnée. */ -GLineCursor *g_line_generator_compute_cursor(const GLineGenerator *, gint, size_t, size_t); -/* Détermine si le conteneur s'inscrit dans une plage donnée. */ -int g_line_generator_contain_cursor(const GLineGenerator *, size_t, size_t, const GLineCursor *); +#if 0 -/* Renseigne sur les propriétés liées à un générateur. */ -BufferLineFlags g_line_generator_get_flags(const GLineGenerator *, size_t, size_t); +/* Retrouve l'emplacement correspondant à une position donnée. */ +GLineCursor *g_token_generator_compute_cursor(const GTokenGenerator *, gint, size_t, size_t); -/* Imprime dans une ligne de rendu le contenu représenté. */ -void g_line_generator_print(GLineGenerator *, GBufferLine *, size_t, size_t, const GBinContent *); +/* Détermine si le conteneur s'inscrit dans une plage donnée. */ +int g_token_generator_contain_cursor(const GTokenGenerator *, size_t, size_t, const GLineCursor *); +#endif -#endif  /* _GLIBEXT_LINEGEN_H */ +#endif  /* _GLIBEXT_GENERATOR_H */ diff --git a/src/glibext/generators/Makefile.am b/src/glibext/generators/Makefile.am index a332498..e95618f 100644 --- a/src/glibext/generators/Makefile.am +++ b/src/glibext/generators/Makefile.am @@ -3,17 +3,14 @@ noinst_LTLIBRARIES  = libglibextgenerators.la  libglibextgenerators_la_SOURCES =			\ -	prologue.h prologue.c					\ -	rborder.h rborder.c +	hex.h hex.c -if BUILD_GTK_SUPPORT -libglibextgenerators_la_SOURCES +=			\ -	hex.h hex.c -endif +# prologue.h prologue.c					\ +# rborder.h rborder.c -libglibextgenerators_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) +libglibextgenerators_la_CFLAGS = $(TOOLKIT_CFLAGS)  devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%) diff --git a/src/glibext/generators/hex.c b/src/glibext/generators/hex.c index 668ebae..6058825 100644 --- a/src/glibext/generators/hex.c +++ b/src/glibext/generators/hex.c @@ -28,14 +28,26 @@  #include <ctype.h> +#include "../generator-int.h" +#include "../options/hex.h" + + + + +#if 0 + +//#include <ctype.h> + +  #include "../bufferline.h"  #include "../gbinarycursor.h" -#include "../linegen-int.h"  #include "../linesegment.h"  #include "../../core/columns.h"  #include "../../core/params.h"  #include "../../gtkext/hexdisplay.h" +#endif +  /* --------------------------- RENDU AMIQUE D'HEXADECIMAL --------------------------- */ @@ -48,9 +60,13 @@ struct _GHexGenerator      GBinContent *content;                   /* Contenu à représenter       */ +#if 0 +      gint left_start;                        /* Abscisse des impressions    */      gint padding;                           /* Bourrage supplémentaire     */ +#endif +      phys_t bytes_per_line;                  /* Nombre d'octets par ligne   */  }; @@ -60,11 +76,15 @@ struct _GHexGeneratorClass  {      GObjectClass parent;                    /* A laisser en premier        */ +#if 0 +      gint addr_width;                        /* Largeur des positions       */      gint byte_width;                        /* Largeur d'un octet brut     */      gint sep_width;                         /* Largeur de séparation       */      gint char_width;                        /* Largeur d'un caractère      */ +#endif +  }; @@ -75,7 +95,7 @@ static void g_hex_generator_class_init(GHexGeneratorClass *);  static void g_hex_generator_init(GHexGenerator *);  /* Procède à l'initialisation de l'interface de génération. */ -static void g_hex_generator_interface_init(GLineGeneratorInterface *); +static void g_hex_generator_token_generator_iface_init(GTokenGeneratorInterface *);  /* Supprime toutes les références externes. */  static void g_hex_generator_dispose(GHexGenerator *); @@ -91,6 +111,13 @@ static void g_hex_generator_finalize(GHexGenerator *);  /* Indique le nombre de ligne prêtes à être générées. */  static size_t g_hex_generator_count_lines(const GHexGenerator *); +/* Etablit dans une ligne de rendu le contenu représenté. */ +static void g_hex_generator_populate_line(const GHexGenerator *, size_t, size_t, GBufferLine *, void *); + + + + +#if 0  #ifdef INCLUDE_GTK_SUPPORT  /* Retrouve l'emplacement correspondant à une position donnée. */ @@ -106,6 +133,7 @@ static BufferLineFlags g_hex_generator_get_flags(const GHexGenerator *, size_t,  /* Imprime dans une ligne de rendu le contenu représenté. */  static void g_hex_generator_print(GHexGenerator *, GBufferLine *, size_t, size_t); +#endif @@ -116,7 +144,7 @@ static void g_hex_generator_print(GHexGenerator *, GBufferLine *, size_t, size_t  /* Détermine le type du générateur de lignes hexadécimales à la volée. */  G_DEFINE_TYPE_WITH_CODE(GHexGenerator, g_hex_generator, G_TYPE_OBJECT, -                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_hex_generator_interface_init)); +                        G_IMPLEMENT_INTERFACE(G_TYPE_TOKEN_GENERATOR, g_hex_generator_token_generator_iface_init));  /****************************************************************************** @@ -134,13 +162,15 @@ G_DEFINE_TYPE_WITH_CODE(GHexGenerator, g_hex_generator, G_TYPE_OBJECT,  static void g_hex_generator_class_init(GHexGeneratorClass *class)  {      GObjectClass *object;                   /* Autre version de la classe  */ -    line_segment *segment;                  /* Segment de test pour mesure */ +    //line_segment *segment;                  /* Segment de test pour mesure */      object = G_OBJECT_CLASS(class);      object->dispose = (GObjectFinalizeFunc/* ! */)g_hex_generator_dispose;      object->finalize = (GObjectFinalizeFunc)g_hex_generator_finalize; +#if 0 +      /* Mesure de quelques dimensions */      segment = get_new_line_segment(RTT_PHYS_ADDR, "0x00000000", 10); @@ -167,6 +197,8 @@ static void g_hex_generator_class_init(GHexGeneratorClass *class)      release_line_segment(segment); +#endif +  } @@ -184,7 +216,7 @@ static void g_hex_generator_class_init(GHexGeneratorClass *class)  static void g_hex_generator_init(GHexGenerator *generator)  { -    generator->bytes_per_line = 4; +    generator->bytes_per_line = 0;  } @@ -201,15 +233,20 @@ static void g_hex_generator_init(GHexGenerator *generator)  *                                                                             *  ******************************************************************************/ -static void g_hex_generator_interface_init(GLineGeneratorInterface *iface) +static void g_hex_generator_token_generator_iface_init(GTokenGeneratorInterface *iface)  { -    iface->count = (linegen_count_lines_fc)g_hex_generator_count_lines; +    iface->count = (count_tokgen_lines_fc)g_hex_generator_count_lines; + +    iface->populate = (populate_tokgen_line_fc)g_hex_generator_populate_line; + +#if 0  #ifdef INCLUDE_GTK_SUPPORT      iface->compute = (linegen_compute_fc)g_hex_generator_compute_cursor;      iface->contain = (linegen_contain_fc)g_hex_generator_contain_cursor;  #endif      iface->get_flags = (linegen_get_flags_fc)g_hex_generator_get_flags;      iface->print = (linegen_print_fc)g_hex_generator_print; +#endif  } @@ -228,8 +265,7 @@ static void g_hex_generator_interface_init(GLineGeneratorInterface *iface)  static void g_hex_generator_dispose(GHexGenerator *generator)  { -    if (generator->content != NULL) -        g_object_unref(G_OBJECT(generator->content)); +    g_clear_object(&generator->content);      G_OBJECT_CLASS(g_hex_generator_parent_class)->dispose(G_OBJECT(generator)); @@ -274,8 +310,239 @@ GHexGenerator *g_hex_generator_new(GBinContent *content)      result = g_object_new(G_TYPE_HEX_GENERATOR, NULL);      result->content = content; +    ref_object(content); + +    return result; + +} + + +// TODO create... + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : generator = générateur à consulter.                          * +*                                                                             * +*  Description : Fournit le contenu associé au générateur de lignes hexa.     * +*                                                                             * +*  Retour      : Contenu dans lequel puise le générateur pour les lignes.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinContent *g_hex_generator_get_content(const GHexGenerator *generator) +{ +    GBinContent *result;                    /* Référence à retourner       */ + +    result = generator->content; + +    ref_object(result); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : generator = générateur à ajuster.                            * +*                options   = options d'affichage des colonnes.                * +*                style     = style de rendus des bribes de texte.             * +*                width     = largeur disponible pour les différentes colonnes.* +*                                                                             * +*  Description : Détermine la hauteur idéale d'un contenu lié à une largeur.  * +*                                                                             * +*  Retour      : Hauteur nécessaire pour les lignes induites.                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +int g_hex_generator_mesure_height_for_width(GHexGenerator *generator, const GDisplayOptions *options, const GTokenStyle *style, int width) +{ +    int result;                             /* Taille à retourner          */ +    vmpa2t end;                             /* Position terminale          */ +    bool status;                            /* Bilan d'une opération       */ +    int off_size;                           /* Taille des emplacements     */ +    int byte_width;                         /* Largeur d'un octet brut     */ +    int sep_width;                          /* Largeur de séparation       */ +    int char_width;                         /* Largeur d'un caractère      */ +    phys_t i;                               /* Boucle de parcours          */ +    phys_t block_count;                     /* Nombre de blocs d'octets    */ +    int requested;                          /* Espace requis pour X octets */ +    phys_t size;                            /* Taille du contenu binaire   */ +    phys_t line_count;                      /* Nombre de lignes requises   */ + +    result = -1; + +    /* Largeur des positions */ + +    if (g_display_options_get(options, HCO_OFFSET)) +    { +        status = g_binary_content_compute_end_pos(generator->content, &end); +        assert(status); +        if (!status) goto done; + +        off_size = g_token_style_compute_location_width(style, end.physical, false); + +        width -= off_size; + +    } + +    /* Détermination des tailles basiques */ + +    byte_width = g_token_style_measure_width(style, TRT_RAW_CODE, 2 /* 00 */); + +    sep_width = g_token_style_measure_width(style, TRT_RAW_CODE, TAB_SIZE /* \t */); + +    char_width = g_token_style_measure_width(style, TRT_RAW_CODE, 1 /* 0 */); + +    for (i = 4; ; i += 4) +    { +        block_count = (i / 4); + +        requested  = i * byte_width + 3 * block_count * char_width; +        requested += (block_count > 1 ? block_count - 1 : 0) * sep_width; + +        requested += i * char_width; + +        /* Limite atteinte ? */ +        if (requested > width) +        { +            i -= 4; +            break; +        } + +    } + +    if (i == 0) +        i = 4; + +    /* Détermination de la taille pour un nombre de lignes donné */ + +    size = g_binary_content_compute_size(generator->content); + +    line_count = size / i; + +    if (size % i > 0) +        line_count++; + +    result = line_count * g_token_style_get_line_height(style); + + done: + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : generator = générateur à ajuster.                            * +*                options   = options d'affichage des colonnes.                * +*                style     = style de rendus des bribes de texte.             * +*                width     = largeur disponible pour les différentes colonnes.* +*                columns   = largeurs adaptées pour les colonnes. [OUT]       * +*                                                                             * +*  Description : Détermine les différentes largeurs de colonnes requises.     * +*                                                                             * +*  Retour      : true si un changement de contenu a été déterminé.            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_hex_generator_allocate(GHexGenerator *generator, const GDisplayOptions *options, const GTokenStyle *style, int width, int *columns) +{ +    bool result;                            /* Variation d'état à remonter */ +    vmpa2t end;                             /* Position terminale          */ +    bool status;                            /* Bilan d'une opération       */ +    int byte_width;                         /* Largeur d'un octet brut     */ +    int sep_width;                          /* Largeur de séparation       */ +    int char_width;                         /* Largeur d'un caractère      */ +    phys_t i;                               /* Boucle de parcours          */ +    phys_t block_count;                     /* Nombre de blocs d'octets    */ +    int requested;                          /* Espace requis pour X octets */ + +    result = false; + +    /* Largeur des positions */ + +    status = g_binary_content_compute_end_pos(generator->content, &end); +    assert(status); +    if (!status) goto done; + +    columns[HCO_OFFSET] = g_token_style_compute_location_width(style, end.physical, false); + +    if (g_display_options_get(options, HCO_OFFSET)) +        width -= columns[HCO_OFFSET]; + +    /* Détermination des tailles basiques */ + +    byte_width = g_token_style_measure_width(style, TRT_RAW_CODE, 2 /* 00 */); + +    sep_width = g_token_style_measure_width(style, TRT_RAW_CODE, TAB_SIZE /* \t */); + +    char_width = g_token_style_measure_width(style, TRT_RAW_CODE, 1 /* 0 */); + +    for (i = 4; ; i += 4) +    { +        block_count = (i / 4); + +        requested  = i * byte_width + 3 * block_count * char_width; +        requested += (block_count > 1 ? block_count - 1 : 0) * sep_width; + +        requested += i * char_width; + +        /* Limite atteinte ? */ +        if (requested > width) +        { +            i -= 4; +            break; +        } + +    } + +    if (i == 0) +        i = 4; + +    /* Détermination des largeurs de colonnes principales */ + +    columns[HCO_COUNT + 0]  = i * byte_width + 3 * block_count * char_width; +    columns[HCO_COUNT + 0] += (block_count > 1 ? block_count - 1 : 0) * sep_width; + +    columns[HCO_COUNT + 1] = i * char_width; + +    result = (generator->bytes_per_line != i); + +    generator->bytes_per_line = i; + + done: + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : generator = générateur à consulter.                          * +*                                                                             * +*  Description : Indique le nombre d'octets programmés constituer une ligne.  * +*                                                                             * +*  Retour      : Nombre d'octets représentés sur chaque ligne.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    g_object_ref(G_OBJECT(result->content)); +phys_t g_hex_generator_get_bytes_per_line(const GHexGenerator *generator) +{ +    phys_t result;                          /* Quantité d'octets à renvoyer*/ + +    result = generator->bytes_per_line;      return result; @@ -317,6 +584,136 @@ static size_t g_hex_generator_count_lines(const GHexGenerator *generator)  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : generator = générateur à utiliser pour l'impression.         * +*                index     = indice de cette même ligne dans le tampon global.* +*                repeat    = indice d'utilisations successives du générateur. * +*                line      = ligne de rendu à compléter.                      * +*                data      = éventuelle donnée complémentaire fournie.        * +*                                                                             * +*  Description : Etablit dans une ligne de rendu le contenu représenté.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_hex_generator_populate_line(const GHexGenerator *generator, size_t index, size_t repeat, GBufferLine *line, void *data) +{ + + +    //GGenConfig *config;                     /* Configuration à consulter   */ +    bool upper_case;                        /* Casse des données en hexa   */ +#ifndef NDEBUG +    bool status;                            /* Bilan de la consultation    */ +#endif +    const char *hexa;                       /* Chaîne à considérer #0      */ +    const char *ff;                         /* Chaîne à considérer #1      */ +    vmpa2t pos;                             /* Position définie à la volée */ +    phys_t got;                             /* Quantité affichable         */ +    const bin_t *raw;                       /* Accès direct et brut        */ +    phys_t i;                               /* Boucle de parcours          */ +    bin_t byte;                             /* Copie pour confort          */ +    char tmp[2];                            /* Représentation d'un octet   */ + +    static const char hexa_lower[] = "0123456789abcdef"; +    static const char hexa_upper[] = "0123456789ABCDEF"; +    static const char ff_lower[] = "ff"; +    static const char ff_upper[] = "FF"; + +    /* +    config = get_main_configuration(); + +#ifndef NDEBUG +    status = g_generic_config_get_value(config, MPK_HEX_UPPER_CASE, &upper_case); +    assert(status); +#else +    g_generic_config_get_value(config, MPK_HEX_UPPER_CASE, &upper_case); +#endif +    */ + +    upper_case = true; + +    if (upper_case) +    { +        hexa = hexa_upper; +        ff = ff_upper; +    } +    else +    { +        hexa = hexa_lower; +        ff = ff_lower; +    } + +    /* Position physique */ + +    init_vmpa(&pos, generator->bytes_per_line * index, VMPA_NO_VIRTUAL); + +    //g_buffer_line_fill_phys(line, HLC_PHYSICAL, MDS_32_BITS_UNSIGNED, &pos); + +    /* Contenu brut */ + +    got = g_binary_content_compute_size(generator->content) - get_phy_addr(&pos); + +    if (got > generator->bytes_per_line) +        got = generator->bytes_per_line; + +    raw = g_binary_content_get_raw_access(generator->content, &pos, got); + +    for (i = 0; i < got; i++) +    { +        /* Séparation ? */ + +        if (i > 0) +        { +            if (i % 4 == 0) +                g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_NONE, "\t", 1, NULL, NULL); +            else +                g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_NONE, " ", 1, NULL, NULL); +        } + +        /* Binaire brut */ + +        byte = raw[i]; + +        if (byte == 0x00) +            g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_RAW_NULL, "00", 2, NULL, NULL); + +        else if (byte == 0xff) +            g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_RAW_FULL, ff, 2, NULL, NULL); + +        else +        { +            tmp[1] = hexa[byte & 0xf]; +            tmp[0] = hexa[(byte >> 4) & 0xf]; + +            if (isgraph(byte) || byte == ' ') +                g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_RAW_PRINTABLE, tmp, 2, NULL, NULL); +            else +                g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_RAW_NOT_PRINTABLE, tmp, 2, NULL, NULL); + +        } + +        /* Représentation humaine ? */ + +        if (isgraph(byte) || byte == ' ') +            g_buffer_line_append_text(line, HCO_COUNT + 1, TRT_CHR_PRINTABLE, (char *)raw + i, 1, NULL, NULL); +        else +            g_buffer_line_append_text(line, HCO_COUNT + 1, TRT_CHR_NOT_PRINTABLE, ".", 1, NULL, NULL); + +    } + +} + + + + + + + +#if 0  #ifdef INCLUDE_GTK_SUPPORT @@ -538,9 +935,9 @@ static void g_hex_generator_print(GHexGenerator *generator, GBufferLine *line, s          if (i > 0)          {              if (i % 4 == 0) -                g_buffer_line_append_text(line, HLC_BINARY, "\t", 1, RTT_RAW, NULL); +                g_buffer_line_append_text(line, HCO_COUNT + 0, "\t", 1, RTT_RAW, NULL);              else -                g_buffer_line_append_text(line, HLC_BINARY, " ", 1, RTT_RAW, NULL); +                g_buffer_line_append_text(line, HCO_COUNT + 0, " ", 1, RTT_RAW, NULL);          }          /* Binaire brut */ @@ -548,17 +945,17 @@ static void g_hex_generator_print(GHexGenerator *generator, GBufferLine *line, s          byte = raw[i];          if (byte == 0x00) -            g_buffer_line_append_text(line, HLC_BINARY, "00", 2, RTT_RAW_NULL, NULL); +            g_buffer_line_append_text(line, HCO_COUNT + 0, "00", 2, RTT_RAW_NULL, NULL);          else if (byte == 0xff) -            g_buffer_line_append_text(line, HLC_BINARY, ff, 2, RTT_RAW_FULL, NULL); +            g_buffer_line_append_text(line, HCO_COUNT + 0, ff, 2, RTT_RAW_FULL, NULL);          else          {              tmp[1] = hexa[byte & 0xf];              tmp[0] = hexa[(byte >> 4) & 0xf]; -            g_buffer_line_append_text(line, HLC_BINARY, tmp, 2, RTT_RAW, NULL); +            g_buffer_line_append_text(line, HCO_COUNT + 0, tmp, 2, RTT_RAW, NULL);          } @@ -574,30 +971,6 @@ static void g_hex_generator_print(GHexGenerator *generator, GBufferLine *line, s  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : generator = générateur à consulter.                          * -*                                                                             * -*  Description : Fournit le contenu associé au générateur de lignes hexa.     * -*                                                                             * -*  Retour      : Contenu dans lequel puise le générateur pour les lignes.     * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GBinContent *g_hex_generator_get_content(const GHexGenerator *generator) -{ -    GBinContent *result;                    /* Référence à retourner       */ - -    result = generator->content; - -    g_object_ref(G_OBJECT(result)); - -    return result; - -} -  /******************************************************************************  *                                                                             * @@ -665,20 +1038,4 @@ bool g_hex_generator_auto_fit(GHexGenerator *generator, gint left, bool show_pos  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : generator = générateur à consulter.                          * -*                                                                             * -*  Description : Indique le nombre d'octets programmés constituer une ligne.  * -*                                                                             * -*  Retour      : Nombre d'octets représentés sur chaque ligne.                * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -phys_t g_hex_generator_get_bytes_per_line(const GHexGenerator *generator) -{ -    return generator->bytes_per_line; - -} +#endif diff --git a/src/glibext/generators/hex.h b/src/glibext/generators/hex.h index f4aeb03..e404adf 100644 --- a/src/glibext/generators/hex.h +++ b/src/glibext/generators/hex.h @@ -25,30 +25,17 @@  #define _GLIBEXT_GENERATORS_HEX_H -#include <glib-object.h> - - +#include "../helpers.h" +#include "../options.h" +#include "../tokenstyle.h"  #include "../../analysis/content.h" -#define G_TYPE_HEX_GENERATOR            (g_hex_generator_get_type()) -#define G_HEX_GENERATOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_HEX_GENERATOR, GHexGenerator)) -#define G_IS_HEX_GENERATOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_HEX_GENERATOR)) -#define G_HEX_GENERATOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_HEX_GENERATOR, GHexGeneratorClass)) -#define G_IS_HEX_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_HEX_GENERATOR)) -#define G_HEX_GENERATOR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_HEX_GENERATOR, GHexGeneratorClass)) - +#define G_TYPE_HEX_GENERATOR (g_hex_generator_get_type()) -/* Tampon pour générateur de lignes hexadécimales (instance) */ -typedef struct _GHexGenerator GHexGenerator; +DECLARE_GTYPE(GHexGenerator, g_hex_generator, G, HEX_GENERATOR); -/* Tampon pour générateur de lignes hexadécimales (classe) */ -typedef struct _GHexGeneratorClass GHexGeneratorClass; - - -/* Détermine le type du générateur de lignes hexadécimales à la volée. */ -GType g_hex_generator_get_type(void);  /* Crée un nouveau générateur de lignes hexadécimales. */  GHexGenerator *g_hex_generator_new(GBinContent *); @@ -56,8 +43,11 @@ GHexGenerator *g_hex_generator_new(GBinContent *);  /* Fournit le contenu associé au générateur de lignes hexa. */  GBinContent *g_hex_generator_get_content(const GHexGenerator *); -/* Ajuste la génération à une nouvelle largeur de rendu. */ -bool g_hex_generator_auto_fit(GHexGenerator *, gint, bool, gint, gint); +/* Détermine la hauteur idéale d'un contenu lié à une largeur. */ +int g_hex_generator_mesure_height_for_width(GHexGenerator *, const GDisplayOptions *, const GTokenStyle *, int); + +/* Détermine les différentes largeurs de colonnes requises. */ +bool g_hex_generator_allocate(GHexGenerator *, const GDisplayOptions *, const GTokenStyle *, int, int *);  /* Indique le nombre d'octets programmés constituer une ligne. */  phys_t g_hex_generator_get_bytes_per_line(const GHexGenerator *); diff --git a/src/glibext/helpers.h b/src/glibext/helpers.h index 71a7269..04e51ad 100644 --- a/src/glibext/helpers.h +++ b/src/glibext/helpers.h @@ -90,6 +90,36 @@  /** + * Bis repetita pour les interfaces... + */ + +#define DECLARE_INTERFACE(TN, t_n, MOD, NAME)                                               \ +                                                                                            \ +    GType t_n##_get_type(void) G_GNUC_CONST;                                                \ +                                                                                            \ +    /* Coquille vide */                                                                     \ +    typedef struct _##TN TN;                                                                \ +    /* Interface */                                                                         \ +    typedef struct _##TN##Interface TN##Interface;                                          \ +                                                                                            \ +    G_GNUC_UNUSED static inline TN *MOD##_##NAME(gconstpointer obj)                         \ +    {                                                                                       \ +        return G_TYPE_CHECK_INSTANCE_CAST(obj, MOD##_TYPE_##NAME, TN);                      \ +    }                                                                                       \ +                                                                                            \ +    G_GNUC_UNUSED static inline gboolean MOD##_IS_##NAME(gconstpointer obj)                 \ +    {                                                                                       \ +        return G_TYPE_CHECK_INSTANCE_TYPE(obj, MOD##_TYPE_##NAME);                          \ +    }                                                                                       \ +                                                                                            \ +    G_GNUC_UNUSED static inline TN##Interface *MOD##_##NAME##_GET_IFACE(gconstpointer obj)  \ +    {                                                                                       \ +        return G_TYPE_INSTANCE_GET_INTERFACE(obj, MOD##_TYPE_##NAME, TN##Interface);        \ +    } + + + +/**   * Les principales fonctions incrémentant ou réduisant le nombre de références   * attachées à un objet acceptent de simples pointeurs génériques (cf. définitions   * du fichier <glib-2.80>/gobject/gobject.h : @@ -143,7 +173,7 @@          assert(__inst != NULL);                                                     \          g_object_ref(ip);                                                           \      }                                                                               \ -    while (0); +    while (0)  #   define unref_object(ip)                                                         \      do                                                                              \ @@ -153,7 +183,7 @@          assert(__inst != NULL);                                                     \          g_object_unref(ip);                                                         \      }                                                                               \ -    while (0); +    while (0)  #else diff --git a/src/glibext/linecolumn.c b/src/glibext/linecolumn.c index 35f7698..22ff2a4 100644 --- a/src/glibext/linecolumn.c +++ b/src/glibext/linecolumn.c @@ -24,13 +24,9 @@  #include "linecolumn.h" -#include <assert.h>  #include <malloc.h> -#include "../common/extstr.h" - -  /******************************************************************************  *                                                                             * @@ -44,14 +40,12 @@  *                                                                             *  ******************************************************************************/ -void init_line_column(line_column *column) +void init_line_column(line_column_t *column)  { -    column->segments = NULL; +    column->tokens = NULL;      column->count = 0; -#ifdef INCLUDE_GTK_SUPPORT      column->max_width = 0; -#endif  } @@ -68,114 +62,162 @@ void init_line_column(line_column *column)  *                                                                             *  ******************************************************************************/ -void reset_line_column(line_column *column) +void reset_line_column(line_column_t *column)  {      size_t i;                               /* Boucle de parcours          */      for (i = 0; i < column->count; i++) -        release_line_segment(column->segments[i]); +        release_line_token(column->tokens[i]); -    if (column->segments != NULL) +    if (column->tokens != NULL)      { -        free(column->segments); -        column->segments = NULL; +        free(column->tokens); +        column->tokens = NULL;      }      column->count = 0; -#ifdef INCLUDE_GTK_SUPPORT      column->max_width = 0; -#endif  } -#ifdef INCLUDE_GTK_SUPPORT +  /******************************************************************************  *                                                                             * -*  Paramètres  : column = colonne de ligne à mettre à jour.                   * +*  Paramètres  : column = colonne de ligne à venir compléter.                 * +*                tag    = propriétés de la zone de texte.                     * +*                text   = chaîne de caractères à traiter.                     * +*                length = quantité de ces caractères.                         * +*                style  = gestionnaire de paramètres de rendu à consulter.    *  *                                                                             * -*  Description : Recalcule la largeur d'une colonne de segments.              * +*  Description : Ajoute un fragment de texte à une colonne de ligne.          *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Indice du point d'insertion.                                 *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -void refresh_line_column_width(line_column *column) +size_t append_text_to_line_column(line_column_t *column, TokenRenderingTag tag, const char *text, size_t length, const GTokenStyle *style)  { -    size_t i;                               /* Boucle de parcours          */ +    size_t result;                          /* Indice à retourner          */ +    line_token_t *token;                    /* Contenu à représenter       */ -    column->max_width = 0; +    result = column->count; -    for (i = 0; i < column->count; i++) -        column->max_width += get_line_segment_width(column->segments[i]); +    token = get_new_line_token(tag, text, length); + +    column->tokens = realloc(column->tokens, ++column->count * sizeof(line_token_t *)); + +    column->tokens[result] = token; + +    //column->max_width += g_token_style_measure_width(style, tag, length); + +    return result;  } + + + +  /******************************************************************************  *                                                                             * -*  Paramètres  : column  = colonne de ligne à consulter.                      * +*  Paramètres  : column = colonne de ligne de texte à manipuler.              * +*                cr     = contexte graphique à utiliser pour les pinceaux.    * +*                x      = abscisse du point d'impression (à maj). [OUT]       * +*                y      = ordonnée du point d'impression.                     * +*                style  = style de rendu pour les bribes de texte.            *  *                                                                             * -*  Description : Fournit la quantité de pixels requise pour l'impression.     * +*  Description : Imprime le contenu d'une colonne de ligne de texte.          *  *                                                                             * -*  Retour      : Largeur requise par la colonne, en pixel.                    * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -gint get_column_width(const line_column *column) +void draw_line_column(const line_column_t *column, cairo_t *cr, int *x, int y, const GTokenStyle *style)  { -    return column->max_width; +    size_t i;                               /* Boucle de parcours          */ + +    for (i = 0; i < column->count; i++) +        draw_line_token(column->tokens[i], cr, x, y, style);  } -#endif + + + + +#if 0 + +#include <assert.h> +#include <malloc.h> + + +#include "../common/extstr.h" + + + + + +#ifdef INCLUDE_GTK_SUPPORT  /******************************************************************************  *                                                                             * -*  Paramètres  : column  = colonne de ligne à venir compléter.                * -*                text    = texte à insérer dans l'existant.                   * -*                length  = taille du texte à traiter.                         * -*                type    = type de décorateur à utiliser.                     * +*  Paramètres  : column = colonne de ligne à mettre à jour.                   *  *                                                                             * -*  Description : Ajoute un fragment de texte à une colonne de ligne.          * +*  Description : Recalcule la largeur d'une colonne de segments.              *  *                                                                             * -*  Retour      : Indice du point d'insertion.                                 * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -size_t append_text_to_line_column(line_column *column, const char *text, size_t length, RenderingTagType type) +void refresh_line_column_width(line_column *column)  { -    size_t result;                          /* Indice à retourner          */ -    line_segment *segment;                  /* Contenu à représenter       */ +    size_t i;                               /* Boucle de parcours          */ -    result = column->count; +    column->max_width = 0; -    segment = get_new_line_segment(type, text, length); +    for (i = 0; i < column->count; i++) +        column->max_width += get_line_segment_width(column->segments[i]); -    column->segments = realloc(column->segments, ++column->count * sizeof(line_segment *)); +} -    column->segments[result] = segment; -#ifdef INCLUDE_GTK_SUPPORT -    column->max_width += get_line_segment_width(segment); -#endif +/****************************************************************************** +*                                                                             * +*  Paramètres  : column  = colonne de ligne à consulter.                      * +*                                                                             * +*  Description : Fournit la quantité de pixels requise pour l'impression.     * +*                                                                             * +*  Retour      : Largeur requise par la colonne, en pixel.                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    return result; +gint get_column_width(const line_column *column) +{ +    return column->max_width;  } +#endif + + + +  /******************************************************************************  *                                                                             *  *  Paramètres  : column  = colonne de ligne à venir compléter.                * @@ -202,7 +244,7 @@ void replace_text_in_line_column(line_column *column, size_t index, const char *      segment = column->segments[index]; -    type = get_line_segment_type(segment); +    type = get_line_token_type(segment);      release_line_segment(segment); @@ -544,3 +586,5 @@ void export_line_column_segments(const line_column *column, buffer_export_contex      }  } + +#endif diff --git a/src/glibext/linecolumn.h b/src/glibext/linecolumn.h index 6dd50f6..a1757f9 100644 --- a/src/glibext/linecolumn.h +++ b/src/glibext/linecolumn.h @@ -25,39 +25,58 @@  #define _GLIBEXT_LINECOLUMN_H -#include <stdbool.h> -#include <glib-object.h> -#ifdef INCLUDE_GTK_SUPPORT -#   include <gdk/gdk.h> -#endif +#include <sys/types.h> -#include "linesegment.h" +#include "linetoken.h"  /* Informations sur le contenu d'une colonne */ -typedef struct _line_column line_column; - - -/* Informations sur le contenu d'une colonne */ -struct _line_column +typedef struct _line_column_t  { -    line_segment **segments;                /* Liste des segments contenus */ +    line_token_t **tokens;                  /* Liste des segments contenus */      size_t count;                           /* Taille de cette liste       */ -#ifdef INCLUDE_GTK_SUPPORT      int max_width;                          /* Largeur max. de l'espace    */ -#endif -}; +} line_column_t; +  /* Initialise une colonne de ligne. */ -void init_line_column(line_column *); +void init_line_column(line_column_t *);  /* Réinitialise une colonne de ligne. */ -void reset_line_column(line_column *); +void reset_line_column(line_column_t *); + +/* Ajoute un fragment de texte à une colonne de ligne. */ +size_t append_text_to_line_column(line_column_t *, TokenRenderingTag, const char *, size_t, const GTokenStyle *); + + + + +/* Imprime le contenu d'une colonne de ligne de texte. */ +void draw_line_column(const line_column_t *, cairo_t *, int *, int, const GTokenStyle *); + + + + +#if 0 + +#include <stdbool.h> +#include <glib-object.h> +#ifdef INCLUDE_GTK_SUPPORT +#   include <gdk/gdk.h> +#endif + + +#include "linesegment.h" + + + +/* Réinitialise une colonne de ligne. */ +//void reset_line_column(line_column *);  #ifdef INCLUDE_GTK_SUPPORT @@ -70,7 +89,7 @@ gint get_column_width(const line_column *);  #endif  /* Ajoute un fragment de texte à une colonne de ligne. */ -size_t append_text_to_line_column(line_column *, const char *, size_t, RenderingTagType); +//size_t append_text_to_line_column(line_column *, const char *, size_t, RenderingTagType);  /* Remplace un fragment de texte dans une colonne de ligne. */  void replace_text_in_line_column(line_column *, size_t, const char *, size_t); @@ -104,5 +123,8 @@ char *get_line_column_text(const line_column *, bool);  void export_line_column_segments(const line_column *, buffer_export_context *, BufferExportType, int); +#endif + +  #endif  /* _GLIBEXT_LINECOLUMN_H */ diff --git a/src/glibext/linetoken.c b/src/glibext/linetoken.c index 192e030..6caa7df 100644 --- a/src/glibext/linetoken.c +++ b/src/glibext/linetoken.c @@ -1,6 +1,6 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * linesegment.c - concentration d'un fragment de caractères aux propriétés communes + * linetoken.c - concentration d'un fragment de caractères aux propriétés communes   *   * Copyright (C) 2016-2019 Cyrille Bagard   * @@ -21,173 +21,137 @@   */ -#include "linesegment.h" +#include "linetoken.h" -#include <assert.h> -#include <limits.h> +#include <glib.h>  #include <malloc.h> -#include <stdbool.h> -#include <stdlib.h>  #include <string.h> -#include "../common/extstr.h"  #include "../common/fnv1a.h" -#include "../core/paths.h" -#ifdef INCLUDE_GTK_SUPPORT -#   include "../gtkext/rendering.h" -#endif -/* ------------------------ NATURE POUR UN FRAGMENT DE TEXTE ------------------------ */ +/* -------------------- NATURE DE BASE POUR UN FRAGMENT DE TEXTE -------------------- */ -/* Nom des éléments CSS */ +/* Fragment de caractères aux propriétés potentiellement partagées */ +struct _line_token_t +{ +    gint ref_count;                         /* Compteur de références      */ -#define SEGMENT_NAME(s) "token-" s +    TokenRenderingTag tag;                  /* Type de rendu attendu       */ -static const char *_segment_names[RTT_COUNT] = { +    fnv64_t hash;                           /* Empreinte pour comparaisons */ -    [RTT_NONE]          = SEGMENT_NAME("none"), -    [RTT_RAW]           = SEGMENT_NAME("raw"), -    [RTT_RAW_FULL]      = SEGMENT_NAME("raw-full"), -    [RTT_RAW_NULL]      = SEGMENT_NAME("raw-null"), -    [RTT_PRINTABLE]     = SEGMENT_NAME("printable"), -    [RTT_NOT_PRINTABLE] = SEGMENT_NAME("not-printable"), -    [RTT_COMMENT]       = SEGMENT_NAME("comment"), -    [RTT_INDICATION]    = SEGMENT_NAME("indication"), -    [RTT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"), -    [RTT_PHYS_ADDR]     = SEGMENT_NAME("phys-addr"), -    [RTT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"), -    [RTT_VIRT_ADDR]     = SEGMENT_NAME("virt-addr"), -    [RTT_RAW_CODE]      = SEGMENT_NAME("raw-code"), -    [RTT_RAW_CODE_NULL] = SEGMENT_NAME("raw-code-null"), -    [RTT_LABEL]         = SEGMENT_NAME("label"), -    [RTT_INSTRUCTION]   = SEGMENT_NAME("instruction"), -    [RTT_IMMEDIATE]     = SEGMENT_NAME("immediate"), -    [RTT_REGISTER]      = SEGMENT_NAME("register"), -    [RTT_PUNCT]         = SEGMENT_NAME("punct"), -    [RTT_HOOK]          = SEGMENT_NAME("hooks"), -    [RTT_SIGNS]         = SEGMENT_NAME("signs"), -    [RTT_LTGT]          = SEGMENT_NAME("ltgt"), -    [RTT_SECTION]       = SEGMENT_NAME("section"), -    [RTT_SEGMENT]       = SEGMENT_NAME("segment"), -    [RTT_STRING]        = SEGMENT_NAME("string"), -    [RTT_VAR_NAME]      = SEGMENT_NAME("var-name"), -    [RTT_KEY_WORD]      = SEGMENT_NAME("keyword"), -    [RTT_ERROR]         = SEGMENT_NAME("error"), +    size_t length;                          /* Taille du texte brut        */ +    char text[0];                           /* Texte brut conservé         */  }; +/* Fournit l'empreinte d'une bribe de texte pour rendu. */ +static guint hash_line_token(const line_token_t *); -#ifdef INCLUDE_GTK_SUPPORT - -/* Compléments à Cairo */ - -#define CAIRO_FONT_SLANT_COUNT  3 -#define CAIRO_FONT_WEIGHT_COUNT 2 +/* Détermine si deux fragments de texte sont identiques. */ +static bool is_line_token_equal(const line_token_t *, const line_token_t *); -#define CAIRO_FONTS_COUNT (CAIRO_FONT_SLANT_COUNT * CAIRO_FONT_WEIGHT_COUNT) -#define CAIRO_FONT_INDEX(s, w) ((s) + (w) * CAIRO_FONT_WEIGHT_COUNT) - - -/* Propriétés de rendu */ -typedef struct _segment_rendering -{ -    rendering_color_t selection_bg;         /* Fond d'impression           */ -    cairo_t *font_ctxts[CAIRO_FONTS_COUNT]; /* Contextes de police         */ -    double x_advances[CAIRO_FONTS_COUNT];   /* Largeurs par caractère      */ -    rendering_pattern_t patterns[RTT_COUNT];/* Modèles d'impression        */ +/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ -} segment_rendering; +/* Conservation de toutes les créations partagées */ +static GHashTable *_token_htable; +G_LOCK_DEFINE_STATIC(_token_mutex); -/* Configuration globale des rendus */ -static segment_rendering _seg_params; +/* Fournit l'adresse d'un fragment de texte unique. */ +static line_token_t *get_shared_line_token(const line_token_t *); -#endif +/* Abandonne un contenu pour segments. */ +static void release_shared_line_token(line_token_t *); -/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ +/* ---------------------------------------------------------------------------------- */ +/*                      NATURE DE BASE POUR UN FRAGMENT DE TEXTE                      */ +/* ---------------------------------------------------------------------------------- */ +/****************************************************************************** +*                                                                             * +*  Paramètres  : tag    = propriétés de la zone de texte.                     * +*                text   = chaîne de caractères à traiter.                     * +*                length = quantité de ces caractères.                         * +*                                                                             * +*  Description : Crée un nouveau fragment de texte avec des propriétés.       * +*                                                                             * +*  Retour      : Elément créé ou recyclé.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -/* Fragment de caractères aux propriétés potentiellement partagées */ -struct _line_segment +line_token_t *get_new_line_token(TokenRenderingTag tag, const char *text, size_t length)  { -    gint ref_count;                         /* Compteur de références      */ - -#ifdef INCLUDE_GTK_SUPPORT -   rendering_pattern_t *pattern;           /* Propriétés du rendu         */ -#else -    RenderingTagType type;                  /* Type de rendu attendu       */ -#endif - -    fnv64_t hash;                           /* Empreinte pour comparaisons */ -    char text[0];                           /* Texte brut conservé         */ +    line_token_t *result;                   /* Elément à retourner         */ +    char atmp[sizeof(line_token_t) + 128];  /* Allocation static facile    */ +    line_token_t *template;                 /* Contenu à mettre en place ? */ -}; +    assert(length > 0); +    /** +     * L'octet nul final est attendu par la fonction cairo_show_text() +     * pour le rendu. +     */ -/* Conservation de toutes les créations partagées */ -static GHashTable *_segcnt_htable; -G_LOCK_DEFINE_STATIC(_segcnt_mutex); +    if ((length + 1) < (sizeof(atmp) - sizeof(line_token_t))) +        template = (line_token_t *)atmp; +    else +        template = malloc(sizeof(line_token_t) + length + 1); +    template->tag = tag; -/* Fournit l'empreinte d'un contenu pour segments. */ -static guint get_line_segment_hash(const line_segment *); +    template->hash = fnv_64a_hash(text); -/* Détermine si deux contenus pour segments sont identiques. */ -static bool is_line_segment_equal(const line_segment *, const line_segment *); +    template->length = length; -/* Détermine si deux contenus pour segments sont identiques. */ -static line_segment *get_shared_segment_content(const line_segment *); +    memcpy(template->text, text, length); +    template->text[length] = '\0'; -/* Abandonne un contenu pour segments. */ -static void release_shared_segment_content(line_segment *); +    result = get_shared_line_token(template); +    if (template != (line_token_t *)atmp) +        free(template); +    return result; -/* -------------------- GESTION OPTIMALE D'UNE LISTE DE CONTENUS -------------------- */ +} -#ifdef INCLUDE_GTK_SUPPORT +/****************************************************************************** +*                                                                             * +*  Paramètres  : token = fragment de texte à traiter.                         * +*                                                                             * +*  Description : Augmente le compteur de références d'un fragment de texte.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -/* Liste identifiant un ensemble de segments */ -struct _segcnt_list +void ref_line_token(line_token_t *token)  { -    fnv64_t *hashes;                        /* Empreinte pour comparaisons */ -    size_t count;                           /* Nommbre de ces empreintes   */ - -    unsigned int ref_count;                 /* Compteur de références      */ - -}; - - -/* Indique si le contenu d'un segment est notable ou non. */ -bool selection_list_has_segment_content(const segcnt_list *, const line_segment *); - -#endif +    g_atomic_int_inc(&token->ref_count); - - -/* ---------------------------------------------------------------------------------- */ -/*                          NATURE POUR UN FRAGMENT DE TEXTE                          */ -/* ---------------------------------------------------------------------------------- */ - - -#ifdef INCLUDE_GTK_SUPPORT +}  /******************************************************************************  *                                                                             * -*  Paramètres  : -                                                            * +*  Paramètres  : token = fragment de texte à libérer de la mémoire.           *  *                                                                             * -*  Description : Procède à l'initialisation des paramètres de rendu de texte. * +*  Description : Retire une utilisation à un fragment de texte.               *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -195,164 +159,152 @@ bool selection_list_has_segment_content(const segcnt_list *, const line_segment  *                                                                             *  ******************************************************************************/ -bool load_segment_rendering_parameters(void) +void release_line_token(line_token_t *token)  { -    cairo_font_slant_t s;                   /* Boucle de parcours #1       */ -    cairo_font_weight_t w;                  /* Boucle de parcours #2       */ -    cairo_t **cr;                           /* Contexte à créer            */ -    cairo_surface_t *surface;               /* Surface pour dessin Cairo   */ -    cairo_text_extents_t extents;           /* Couverture des caractères   */ -    RenderingTagType i;                     /* Boucle de parcours          */ +    release_shared_line_token(token); -    /* Contextes pour les mesures initiales */ +} -    for (s = CAIRO_FONT_SLANT_NORMAL; s < CAIRO_FONT_SLANT_COUNT; s++) -        for (w = CAIRO_FONT_WEIGHT_NORMAL; w < CAIRO_FONT_WEIGHT_COUNT; w++) -        { -            cr = &_seg_params.font_ctxts[CAIRO_FONT_INDEX(s, w)]; +/****************************************************************************** +*                                                                             * +*  Paramètres  : token = fragment de texte à consulter.                       * +*                                                                             * +*  Description : Fournit l'empreinte d'une bribe de texte pour rendu.         * +*                                                                             * +*  Retour      : Empreinte de lu contenu représenté.                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -            surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); -            *cr = cairo_create(surface); -            cairo_surface_destroy(surface); +static guint hash_line_token(const line_token_t *token) +{ +    return token->hash; -            cairo_select_font_face(*cr, "mono", s, w); -            cairo_set_font_size(*cr, 13); +} -            cairo_text_extents(*cr, "A", &extents); -            _seg_params.x_advances[CAIRO_FONT_INDEX(s, w)] = extents.x_advance; -        } +/****************************************************************************** +*                                                                             * +*  Paramètres  : token = premier fragment de texte à analyser.                * +*                other = second fragment de texte à analyser.                 * +*                                                                             * +*  Description : Détermine si deux fragments de texte sont identiques.        * +*                                                                             * +*  Retour      : Bilan de la comparaison.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    /* Fond d'impression */ +static bool is_line_token_equal(const line_token_t *token, const line_token_t *other) +{ +    bool result;                            /* Résultat à retourner        */ -    _seg_params.selection_bg.has_color = true; -    _seg_params.selection_bg.color.red = 0.5; -    _seg_params.selection_bg.color.green = 0.5; -    _seg_params.selection_bg.color.blue = 0.5; -    _seg_params.selection_bg.color.alpha = 1.0; +    result = (cmp_fnv_64a(token->hash, other->hash) == 0); -    /* Chargement des définitions utiles */ +    if (result) +        result = (token->length == other->length); -    for (i = 0; i < RTT_COUNT; i++) -        load_rendering_pattern(_segment_names[i], &_seg_params.patterns[i]); +    if (result) +        result = (token->tag == other->tag); -    return true; +    if (result) +        result = (strncmp(token->text, other->text, token->length) == 0); + +    return result;  } -#endif -/* ---------------------------------------------------------------------------------- */ -/*                         ISOLATION DE CONTENUS PARTAGEABLES                         */ -/* ---------------------------------------------------------------------------------- */  /******************************************************************************  *                                                                             * -*  Paramètres  : -                                                            * +*  Paramètres  : token = fragment de texte à manipuler.                       * +*                cr    = contexte graphique à utiliser pour les pinceaux.     * +*                x     = abscisse du point d'impression (à maj). [OUT]        * +*                y     = ordonnée du point d'impression.                      * +*                style = style de rendu pour les bribes de texte.             *  *                                                                             * -*  Description : Initialise la table mémorisant les contenus pour segments.   * +*  Description : Imprime le fragment de texte représenté.                     *  *                                                                             * -*  Retour      : Bilan de l'opération.                                        * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool init_segment_content_hash_table(void) +void draw_line_token(const line_token_t *token, cairo_t *cr, int *x, int y, const GTokenStyle *style)  { -    _segcnt_htable = g_hash_table_new_full((GHashFunc)get_line_segment_hash, -                                           (GEqualFunc)is_line_segment_equal, -                                           free, NULL); - -    return (_segcnt_htable != NULL); +    g_token_style_draw_text(style, token->tag, cr, x, y, token->text, token->length);  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : -                                                            * -*                                                                             * -*  Description : Organise la sortie de la table des contenus pour segments.   * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ -void exit_segment_content_hash_table(void) -{ -    assert(g_hash_table_size(_segcnt_htable) == 0); -    g_hash_table_unref(_segcnt_htable); -} + + + +/* ---------------------------------------------------------------------------------- */ +/*                         ISOLATION DE CONTENUS PARTAGEABLES                         */ +/* ---------------------------------------------------------------------------------- */  /******************************************************************************  *                                                                             * -*  Paramètres  : content = contenu pour segment à consulter.                  * +*  Paramètres  : -                                                            *  *                                                                             * -*  Description : Fournit l'empreinte d'un contenu pour segments.              * +*  Description : Initialise la table mémorisant les contenus pour segments.   *  *                                                                             * -*  Retour      : Empreinte de lu contenu représenté.                          * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static guint get_line_segment_hash(const line_segment *content) +bool init_segment_content_hash_table(void)  { -    return content->hash; +    _token_htable = g_hash_table_new_full((GHashFunc)hash_line_token, +                                           (GEqualFunc)is_line_token_equal, +                                           free, NULL); + +    return (_token_htable != NULL);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : content = premier contenu pour segment à analyser.           * -*                other   = second contenu pour segment à analyser.            * +*  Paramètres  : -                                                            *  *                                                                             * -*  Description : Détermine si deux contenus pour segments sont identiques.    * +*  Description : Organise la sortie de la table des contenus pour segments.   *  *                                                                             * -*  Retour      : Bilan de la comparaison.                                     * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static bool is_line_segment_equal(const line_segment *content, const line_segment *other) +void exit_segment_content_hash_table(void)  { -    bool result;                            /* Résultat à retourner        */ - -#ifdef INCLUDE_GTK_SUPPORT -    result = (content->pattern == other->pattern); -#else -    result = (content->type == other->type); -#endif +    assert(g_hash_table_size(_token_htable) == 0); -    if (result) -        result = (cmp_fnv_64a(content->hash, other->hash) == 0); - -    if (result) -        result = (strcmp(content->text, other->text) == 0); - -    return result; +    g_hash_table_unref(_token_htable);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : content = premier contenu pour segment à analyser.           * -*                other   = second contenu pour segment à analyser.            * +*  Paramètres  : template = premier contenu pour segment à rechercher.        *  *                                                                             * -*  Description : Détermine si deux contenus pour segments sont identiques.    * +*  Description : Fournit l'adresse d'un fragment de texte unique.             *  *                                                                             *  *  Retour      : Bilan de la comparaison.                                     *  *                                                                             * @@ -360,34 +312,34 @@ static bool is_line_segment_equal(const line_segment *content, const line_segmen  *                                                                             *  ******************************************************************************/ -static line_segment *get_shared_segment_content(const line_segment *content) +static line_token_t *get_shared_line_token(const line_token_t *template)  { -    line_segment *result;                    /* Contenu partagé à renvoyer  */ +    line_token_t *result;                   /* Contenu partagé à renvoyer  */      gboolean found;                         /* Le contenu existe déjà ?    */      size_t allocated;                       /* Besoin complet en mémoire   */  #ifndef NDEBUG      gboolean created;                       /* Validation de mise en place */  #endif -    G_LOCK(_segcnt_mutex); +    G_LOCK(_token_mutex); -    found = g_hash_table_lookup_extended(_segcnt_htable, content, (gpointer *)&result, NULL); +    found = g_hash_table_lookup_extended(_token_htable, template, (gpointer *)&result, NULL);      if (!found)      { -        allocated = sizeof(line_segment) + strlen(content->text) + 1; +        allocated = sizeof(line_token_t) + template->length + 1; -        result = (line_segment *)malloc(allocated); +        result = malloc(allocated); -        memcpy(result, content, allocated); +        memcpy(result, template, allocated);          g_atomic_int_set(&result->ref_count, 1);  #ifndef NDEBUG -        created = g_hash_table_insert(_segcnt_htable, result, result); +        created = g_hash_table_insert(_token_htable, result, result);          assert(created);  #else -        g_hash_table_insert(_segcnt_htable, result, result); +        g_hash_table_insert(_token_htable, result, result);  #endif      } @@ -400,7 +352,7 @@ static line_segment *get_shared_segment_content(const line_segment *content)      } -    G_UNLOCK(_segcnt_mutex); +    G_UNLOCK(_token_mutex);      return result; @@ -409,7 +361,7 @@ static line_segment *get_shared_segment_content(const line_segment *content)  /******************************************************************************  *                                                                             * -*  Paramètres  : content = contenu pour segments à délaisser.                 * +*  Paramètres  : token = fragment de texte à délaisser.                       *  *                                                                             *  *  Description : Abandonne un contenu pour segments.                          *  *                                                                             * @@ -419,24 +371,24 @@ static line_segment *get_shared_segment_content(const line_segment *content)  *                                                                             *  ******************************************************************************/ -static void release_shared_segment_content(line_segment *content) +static void release_shared_line_token(line_token_t *token)  {  #ifndef NDEBUG      gboolean deleted;                       /* Validation de suppression   */  #endif -    if (g_atomic_int_dec_and_test(&content->ref_count)) +    if (g_atomic_int_dec_and_test(&token->ref_count))      { -        G_LOCK(_segcnt_mutex); +        G_LOCK(_token_mutex);  #ifndef NDEBUG -        deleted = g_hash_table_remove(_segcnt_htable, content); +        deleted = g_hash_table_remove(_token_htable, token);          assert(deleted);  #else -        g_hash_table_remove(_segcnt_htable, content); +        g_hash_table_remove(_token_htable, token);  #endif -        G_UNLOCK(_segcnt_mutex); +        G_UNLOCK(_token_mutex);      } @@ -445,59 +397,240 @@ static void release_shared_segment_content(line_segment *content) + + + + + + + + + + +#if 0 + +#include <assert.h> +#include <limits.h> +#include <malloc.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + + +#include "../common/extstr.h" +//#include "../common/fnv1a.h" +#include "../core/paths.h" +#ifdef INCLUDE_GTK_SUPPORT +#   include "../gtkext/rendering.h" +#endif + + + +/* ------------------------ NATURE POUR UN FRAGMENT DE TEXTE ------------------------ */ + + +/* Nom des éléments CSS */ + +#define SEGMENT_NAME(s) "token-" s + +static const char *_segment_names[RTT_COUNT] = { + +    [RTT_NONE]          = SEGMENT_NAME("none"), +    [RTT_RAW]           = SEGMENT_NAME("raw"), +    [RTT_RAW_FULL]      = SEGMENT_NAME("raw-full"), +    [RTT_RAW_NULL]      = SEGMENT_NAME("raw-null"), +    [RTT_PRINTABLE]     = SEGMENT_NAME("printable"), +    [RTT_NOT_PRINTABLE] = SEGMENT_NAME("not-printable"), +    [RTT_COMMENT]       = SEGMENT_NAME("comment"), +    [RTT_INDICATION]    = SEGMENT_NAME("indication"), +    [RTT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"), +    [RTT_PHYS_ADDR]     = SEGMENT_NAME("phys-addr"), +    [RTT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"), +    [RTT_VIRT_ADDR]     = SEGMENT_NAME("virt-addr"), +    [RTT_RAW_CODE]      = SEGMENT_NAME("raw-code"), +    [RTT_RAW_CODE_NULL] = SEGMENT_NAME("raw-code-null"), +    [RTT_LABEL]         = SEGMENT_NAME("label"), +    [RTT_INSTRUCTION]   = SEGMENT_NAME("instruction"), +    [RTT_IMMEDIATE]     = SEGMENT_NAME("immediate"), +    [RTT_REGISTER]      = SEGMENT_NAME("register"), +    [RTT_PUNCT]         = SEGMENT_NAME("punct"), +    [RTT_HOOK]          = SEGMENT_NAME("hooks"), +    [RTT_SIGNS]         = SEGMENT_NAME("signs"), +    [RTT_LTGT]          = SEGMENT_NAME("ltgt"), +    [RTT_SECTION]       = SEGMENT_NAME("section"), +    [RTT_SEGMENT]       = SEGMENT_NAME("segment"), +    [RTT_STRING]        = SEGMENT_NAME("string"), +    [RTT_VAR_NAME]      = SEGMENT_NAME("var-name"), +    [RTT_KEY_WORD]      = SEGMENT_NAME("keyword"), +    [RTT_ERROR]         = SEGMENT_NAME("error"), + +}; + + +#ifdef INCLUDE_GTK_SUPPORT + +/* Compléments à Cairo */ + +#define CAIRO_FONT_SLANT_COUNT  3 +#define CAIRO_FONT_WEIGHT_COUNT 2 + +#define CAIRO_FONTS_COUNT (CAIRO_FONT_SLANT_COUNT * CAIRO_FONT_WEIGHT_COUNT) +#define CAIRO_FONT_INDEX(s, w) ((s) + (w) * CAIRO_FONT_WEIGHT_COUNT) + + +/* Propriétés de rendu */ +typedef struct _segment_rendering +{ +    rendering_color_t selection_bg;         /* Fond d'impression           */ + +    cairo_t *font_ctxts[CAIRO_FONTS_COUNT]; /* Contextes de police         */ +    double x_advances[CAIRO_FONTS_COUNT];   /* Largeurs par caractère      */ + +    rendering_pattern_t patterns[RTT_COUNT];/* Modèles d'impression        */ + +} segment_rendering; + + +/* Configuration globale des rendus */ +static segment_rendering _seg_params; + +#endif + + + +/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ + + +/* Fragment de caractères aux propriétés potentiellement partagées */ +struct _line_segment +{ +    gint ref_count;                         /* Compteur de références      */ + +#ifdef INCLUDE_GTK_SUPPORT +   rendering_pattern_t *pattern;           /* Propriétés du rendu         */ +#else +    RenderingTagType type;                  /* Type de rendu attendu       */ +#endif + +    fnv64_t hash;                           /* Empreinte pour comparaisons */ +    char text[0];                           /* Texte brut conservé         */ + +}; + + + +/* Détermine si deux contenus pour segments sont identiques. */ +static line_segment *get_shared_segment_content(const line_segment *); + +/* Abandonne un contenu pour segments. */ +static void release_shared_segment_content(line_segment *); + + + +/* -------------------- GESTION OPTIMALE D'UNE LISTE DE CONTENUS -------------------- */ + + +#ifdef INCLUDE_GTK_SUPPORT + +/* Liste identifiant un ensemble de segments */ +struct _segcnt_list +{ +    fnv64_t *hashes;                        /* Empreinte pour comparaisons */ +    size_t count;                           /* Nommbre de ces empreintes   */ + +    unsigned int ref_count;                 /* Compteur de références      */ + +}; + + +/* Indique si le contenu d'un segment est notable ou non. */ +bool selection_list_has_segment_content(const segcnt_list *, const line_segment *); + +#endif + + +  /* ---------------------------------------------------------------------------------- */ -/*                      NATURE DE BASE POUR UN FRAGMENT DE TEXTE                      */ +/*                          NATURE POUR UN FRAGMENT DE TEXTE                          */  /* ---------------------------------------------------------------------------------- */ +#ifdef INCLUDE_GTK_SUPPORT + +  /******************************************************************************  *                                                                             * -*  Paramètres  : type   = propriétés de la zone de texte.                     * -*                text   = chaîne de caractères à traiter.                     * -*                length = quantité de ces caractères.                         * +*  Paramètres  : -                                                            *  *                                                                             * -*  Description : Crée un nouveau fragment de texte avec des propriétés.       * +*  Description : Procède à l'initialisation des paramètres de rendu de texte. *  *                                                                             * -*  Retour      : Elément créé ou recyclé.                                     * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -line_segment *get_new_line_segment(RenderingTagType type, const char *text, size_t length) +bool load_segment_rendering_parameters(void)  { -    line_segment *result;                   /* Elément à retourner         */ -    char atmp[sizeof(line_segment) + 128];  /* Allocation static facile    */ -    line_segment *content;                  /* Contenu à mettre en place ? */ +    cairo_font_slant_t s;                   /* Boucle de parcours #1       */ +    cairo_font_weight_t w;                  /* Boucle de parcours #2       */ +    cairo_t **cr;                           /* Contexte à créer            */ +    cairo_surface_t *surface;               /* Surface pour dessin Cairo   */ +    cairo_text_extents_t extents;           /* Couverture des caractères   */ +    RenderingTagType i;                     /* Boucle de parcours          */ -    assert(length > 0); +    /* Contextes pour les mesures initiales */ -    if (length < (sizeof(atmp) - sizeof(line_segment))) -        content = (line_segment *)atmp; -    else -        content = (line_segment *)malloc(sizeof(line_segment) + length + 1); +    for (s = CAIRO_FONT_SLANT_NORMAL; s < CAIRO_FONT_SLANT_COUNT; s++) +        for (w = CAIRO_FONT_WEIGHT_NORMAL; w < CAIRO_FONT_WEIGHT_COUNT; w++) +        { +            cr = &_seg_params.font_ctxts[CAIRO_FONT_INDEX(s, w)]; -#ifdef INCLUDE_GTK_SUPPORT -    content->pattern = &_seg_params.patterns[type]; -#else -    content->type = type; -#endif +            surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); +            *cr = cairo_create(surface); +            cairo_surface_destroy(surface); -    content->hash = fnv_64a_hash(text); +            cairo_select_font_face(*cr, "mono", s, w); +            cairo_set_font_size(*cr, 13); -    memcpy(content->text, text, length); -    content->text[length] = '\0'; +            cairo_text_extents(*cr, "A", &extents); +            _seg_params.x_advances[CAIRO_FONT_INDEX(s, w)] = extents.x_advance; -    result = get_shared_segment_content(content); +        } -    if (content != (line_segment *)atmp) -        free(content); +    /* Fond d'impression */ -    return result; +    _seg_params.selection_bg.has_color = true; +    _seg_params.selection_bg.color.red = 0.5; +    _seg_params.selection_bg.color.green = 0.5; +    _seg_params.selection_bg.color.blue = 0.5; +    _seg_params.selection_bg.color.alpha = 1.0; + +    /* Chargement des définitions utiles */ + +    for (i = 0; i < RTT_COUNT; i++) +        load_rendering_pattern(_segment_names[i], &_seg_params.patterns[i]); + +    return true;  } +#endif + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/*                      NATURE DE BASE POUR UN FRAGMENT DE TEXTE                      */ +/* ---------------------------------------------------------------------------------- */ + + + +  /******************************************************************************  *                                                                             *  *  Paramètres  : segment = fragment de texte à traiter.                       * @@ -555,7 +688,7 @@ RenderingTagType get_line_segment_type(const line_segment *segment)  #ifdef INCLUDE_GTK_SUPPORT      result = (RenderingTagType)(segment->pattern - _seg_params.patterns);  #else -    result = segment->type; +    result = segment->tag;  #endif      return result; @@ -1204,3 +1337,5 @@ bool selection_list_has_segment_content(const segcnt_list *list, const line_segm  #endif + +#endif diff --git a/src/glibext/linetoken.h b/src/glibext/linetoken.h index 4e06f8c..25c93ed 100644 --- a/src/glibext/linetoken.h +++ b/src/glibext/linetoken.h @@ -1,6 +1,6 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * linesegment.h - prototypes pour la concentration d'un fragment de caractères aux propriétés communes + * linetoken.h - prototypes pour la concentration d'un fragment de caractères aux propriétés communes   *   * Copyright (C) 2016-2019 Cyrille Bagard   * @@ -21,12 +21,61 @@   */ -#ifndef _GLIBEXT_LINESEGMENT_H -#define _GLIBEXT_LINESEGMENT_H +#ifndef _GLIBEXT_LINETOKEN_H +#define _GLIBEXT_LINETOKEN_H -#include <glib-object.h>  #include <stdbool.h> + + +#include "tokenstyle.h" + + + +/* -------------------- NATURE DE BASE POUR UN FRAGMENT DE TEXTE -------------------- */ + + +/* Fragment de caractères aux propriétés potentiellement partagées */ +typedef struct _line_token_t line_token_t; + + +/* Crée un nouveau fragment de texte avec des propriétés. */ +line_token_t *get_new_line_token(TokenRenderingTag, const char *, size_t); + +/* Augmente le compteur de références d'un fragment de texte. */ +void ref_line_token(line_token_t *); + +/* Retire une utilisation à un fragment de texte. */ +void release_line_token(line_token_t *); + + + + + + + +/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ + + +/* Initialise la table mémorisant les contenus pour segments. */ +bool init_segment_content_hash_table(void); + +/* Organise la sortie de la table des contenus pour segments. */ +void exit_segment_content_hash_table(void); + + + +/* Imprime le fragment de texte représenté. */ +void draw_line_token(const line_token_t *, cairo_t *, int *, int, const GTokenStyle *); + + + + + + +#if 0 + +#include <glib-object.h>  #ifdef INCLUDE_GTK_SUPPORT  #   include <gdk/gdk.h>  #   include <pango/pango.h> @@ -58,14 +107,14 @@ bool load_segment_rendering_parameters(void);  /* Fragment de caractères aux propriétés potentiellement partagées */ -typedef struct _line_segment line_segment; +//typedef struct _line_segment line_segment;  /* Initialise la table mémorisant les contenus pour segments. */ -bool init_segment_content_hash_table(void); +//bool init_segment_content_hash_table(void);  /* Organise la sortie de la table des contenus pour segments. */ -void exit_segment_content_hash_table(void); +//void exit_segment_content_hash_table(void); @@ -74,13 +123,13 @@ void exit_segment_content_hash_table(void);  /* Crée un nouveau fragment de texte avec des propriétés. */ -line_segment *get_new_line_segment(RenderingTagType, const char *, size_t); +//line_segment *get_new_line_segment(RenderingTagType, const char *, size_t);  /* Augmente le compteur de références d'un fragment de texte. */ -void ref_line_segment(line_segment *); +//void ref_line_segment(line_segment *);  /* Retire une utilisation à un fragment de texte. */ -void release_line_segment(line_segment *); +//void release_line_segment(line_segment *);  /* Indique le type de rendu associé à un segment de ligne. */  RenderingTagType get_line_segment_type(const line_segment *); @@ -100,7 +149,7 @@ gint get_caret_position_from_line_segment(const line_segment *, gint);  bool move_caret_on_line_segment(const line_segment *, gint *, bool, GdkScrollDirection);  /* Imprime le fragment de texte représenté. */ -void draw_line_segment(const line_segment *, cairo_t *, gint *, gint, const segcnt_list *); +//void draw_line_segment(const line_segment *, cairo_t *, gint *, gint, const segcnt_list *);  #endif @@ -174,6 +223,7 @@ bool add_segment_content_to_selection_list(segcnt_list *, const line_segment *);  #endif +#endif -#endif  /* _GLIBEXT_LINESEGMENT_H */ +#endif  /* _GLIBEXT_LINETOKEN_H */ diff --git a/src/glibext/options/hex.c b/src/glibext/options/hex.c index 5804a57..ab461a7 100644 --- a/src/glibext/options/hex.c +++ b/src/glibext/options/hex.c @@ -101,7 +101,7 @@ static void g_hex_options_init(GHexOptions *options)  #endif                               (const char *[]) { _("Offset") },                               (const bool []) { true }, -                             1); +                             HCO_COUNT);      assert(status); diff --git a/src/glibext/options/hex.h b/src/glibext/options/hex.h index 48ce942..0d187dc 100644 --- a/src/glibext/options/hex.h +++ b/src/glibext/options/hex.h @@ -29,6 +29,16 @@ +/* Liste des colonnes en options */ +typedef enum _HexColumnOptions +{ +    HCO_OFFSET,                             /* Position                    */ + +    HCO_COUNT + +} HexColumnOptions; + +  #define G_TYPE_HEX_OPTIONS (g_hex_options_get_type())  DECLARE_GTYPE(GHexOptions, g_hex_options, G, HEX_OPTIONS); diff --git a/src/glibext/tokenstyle.c b/src/glibext/tokenstyle.c index e797856..df1d42a 100644 --- a/src/glibext/tokenstyle.c +++ b/src/glibext/tokenstyle.c @@ -25,6 +25,7 @@  #include "tokenstyle.h" +#include <math.h>  #include <string.h> @@ -60,34 +61,35 @@ static void g_token_style_finalize(GTokenStyle *);  static const char *_token_names[TRT_COUNT] = { -    [TRT_NONE]          = SEGMENT_NAME("none"), -    [TRT_RAW]           = SEGMENT_NAME("raw"), -    [TRT_RAW_FULL]      = SEGMENT_NAME("raw-full"), -    [TRT_RAW_NULL]      = SEGMENT_NAME("raw-null"), -    [TRT_PRINTABLE]     = SEGMENT_NAME("printable"), -    [TRT_NOT_PRINTABLE] = SEGMENT_NAME("not-printable"), -    [TRT_COMMENT]       = SEGMENT_NAME("comment"), -    [TRT_INDICATION]    = SEGMENT_NAME("indication"), -    [TRT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"), -    [TRT_PHYS_ADDR]     = SEGMENT_NAME("phys-addr"), -    [TRT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"), -    [TRT_VIRT_ADDR]     = SEGMENT_NAME("virt-addr"), -    [TRT_RAW_CODE]      = SEGMENT_NAME("raw-code"), -    [TRT_RAW_CODE_NULL] = SEGMENT_NAME("raw-code-null"), -    [TRT_LABEL]         = SEGMENT_NAME("label"), -    [TRT_INSTRUCTION]   = SEGMENT_NAME("instruction"), -    [TRT_IMMEDIATE]     = SEGMENT_NAME("immediate"), -    [TRT_REGISTER]      = SEGMENT_NAME("register"), -    [TRT_PUNCT]         = SEGMENT_NAME("punct"), -    [TRT_HOOK]          = SEGMENT_NAME("hooks"), -    [TRT_SIGNS]         = SEGMENT_NAME("signs"), -    [TRT_LTGT]          = SEGMENT_NAME("ltgt"), -    [TRT_SECTION]       = SEGMENT_NAME("section"), -    [TRT_SEGMENT]       = SEGMENT_NAME("segment"), -    [TRT_STRING]        = SEGMENT_NAME("string"), -    [TRT_VAR_NAME]      = SEGMENT_NAME("var-name"), -    [TRT_KEY_WORD]      = SEGMENT_NAME("keyword"), -    [TRT_ERROR]         = SEGMENT_NAME("error"), +    [TRT_NONE]              = SEGMENT_NAME("none"), +    [TRT_RAW_PRINTABLE]     = SEGMENT_NAME("raw-printable"), +    [TRT_RAW_NOT_PRINTABLE] = SEGMENT_NAME("raw-not-printable"), +    [TRT_RAW_FULL]          = SEGMENT_NAME("raw-full"), +    [TRT_RAW_NULL]          = SEGMENT_NAME("raw-null"), +    [TRT_CHR_PRINTABLE]     = SEGMENT_NAME("chr-printable"), +    [TRT_CHR_NOT_PRINTABLE] = SEGMENT_NAME("chr-not-printable"), +    [TRT_COMMENT]           = SEGMENT_NAME("comment"), +    [TRT_INDICATION]        = SEGMENT_NAME("indication"), +    [TRT_PHYS_ADDR_PAD]     = SEGMENT_NAME("phys-addr-padding"), +    [TRT_PHYS_ADDR]         = SEGMENT_NAME("phys-addr"), +    [TRT_VIRT_ADDR_PAD]     = SEGMENT_NAME("virt-addr-padding"), +    [TRT_VIRT_ADDR]         = SEGMENT_NAME("virt-addr"), +    [TRT_RAW_CODE]          = SEGMENT_NAME("raw-code"), +    [TRT_RAW_CODE_NULL]     = SEGMENT_NAME("raw-code-null"), +    [TRT_LABEL]             = SEGMENT_NAME("label"), +    [TRT_INSTRUCTION]       = SEGMENT_NAME("instruction"), +    [TRT_IMMEDIATE]         = SEGMENT_NAME("immediate"), +    [TRT_REGISTER]          = SEGMENT_NAME("register"), +    [TRT_PUNCT]             = SEGMENT_NAME("punct"), +    [TRT_HOOK]              = SEGMENT_NAME("hooks"), +    [TRT_SIGNS]             = SEGMENT_NAME("signs"), +    [TRT_LTGT]              = SEGMENT_NAME("ltgt"), +    [TRT_SECTION]           = SEGMENT_NAME("section"), +    [TRT_SEGMENT]           = SEGMENT_NAME("segment"), +    [TRT_STRING]            = SEGMENT_NAME("string"), +    [TRT_VAR_NAME]          = SEGMENT_NAME("var-name"), +    [TRT_KEY_WORD]          = SEGMENT_NAME("keyword"), +    [TRT_ERROR]             = SEGMENT_NAME("error"),  }; @@ -272,12 +274,35 @@ bool g_token_style_create(GTokenStyle *style, GtkWidget *target)  /******************************************************************************  *                                                                             *  *  Paramètres  : style  = gestionnaire de paramètres de rendu à consulter.    * +*                                                                             * +*  Description : Fournit la quantité de pixels requise pour une ligne.        * +*                                                                             * +*  Retour      : Hauteur de chaque ligne de rendu, en pixels.                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +int g_token_style_get_line_height(const GTokenStyle *style) +{ +    int result;                             /* Hauteur à retourner         */ + +    result = style->font_extents.height; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : style  = gestionnaire de paramètres de rendu à consulter.    *  *                tag    = type de rendu sollicité.                            *  *                length = nombre de caractères à mesurer.                     *  *                                                                             *  *  Description : Fournit la quantité de pixels requise pour l'impression.     *  *                                                                             * -*  Retour      : Largeur requise par la colonne, en pixel.                    * +*  Retour      : Largeur requise par la colonne, en pixels.                   *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             * @@ -325,6 +350,13 @@ void g_token_style_draw_text(const GTokenStyle *style, TokenRenderingTag tag, ca      cairo_operator_t old;                   /* Sauvegarde avant changement */      const rendering_property_t *prop;       /* Motif de rendu visé         */ +    /* Cas particulier d'une tabulation */ +    if (length == 1 && (text[0] == '\t' || text[0] == ' ')) +    { +        width = g_token_style_measure_width(style, tag, text[0] == '\t' ? TAB_SIZE : 1); +        goto small_sep; +    } +      selected = false;//selection_list_has_segment_content(list, segment);      width = g_token_style_measure_width(style, tag, length); @@ -378,6 +410,8 @@ void g_token_style_draw_text(const GTokenStyle *style, TokenRenderingTag tag, ca      cairo_show_text(cr, text); + small_sep: +      *x += width;  } @@ -467,6 +501,56 @@ char *g_token_style_append_markup(const GTokenStyle *style, char *base, TokenRen  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : style = gestionnaire de paramètres de rendu à consulter.     * +*                max   = valeur maximale atteignable.                         * +*                virt  = indique une position virtuelle et non physique.      * +*                                                                             * +*  Description : Détermine une taille de localisation, physique ou virtuelle. * +*                                                                             * +*  Retour      : Largeur minimale à observer en pixels.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +int g_token_style_compute_location_width(const GTokenStyle *style, uint64_t max, bool virt) +{ +    int result;                             /* Taille à retourner          */ +    double n;                               /* Nombre de chiffres hexa     */ +    double c;                               /* Valeur ajustée              */ +    TokenRenderingTag tag;                  /* Type de représentation      */ + +    /** +     * Les situations suivantes ont été évaluées : +     * +     *          max        |     n    |  c +     *   ----------------------------------- +     *                   0 |  0       |  0 +     *                   1 |  0,25    |  1 +     *                   f |  1       |  1 +     *                  10 |  1,02187 |  2 +     *                  11 |  1,04248 |  2 +     *                  ff |  2       |  2 +     *                 100 |  2,00141 |  3 +     *            ffffffff |  8       |  8 +     *    ffffffffffffffff | 16       | 16 +     */ + +    n = log1p(max) / log(16); + +    c = ceil(n); + +    tag = virt ? TRT_VIRT_ADDR : TRT_PHYS_ADDR; + +    result = g_token_style_measure_width(style, tag, c); + +    return result; + +} + +  /* ---------------------------------------------------------------------------------- */  /*                          RECEPTACLES DE SIGNAUX CONNECTES                          */ diff --git a/src/glibext/tokenstyle.css b/src/glibext/tokenstyle.css index 0cf9f37..6fb78aa 100644 --- a/src/glibext/tokenstyle.css +++ b/src/glibext/tokenstyle.css @@ -6,21 +6,30 @@  } +.token-raw-printable, +.token-chr-printable { +    color: white; + +} + +.token-raw-not-printable, +.token-chr-not-printable { + +    color: #bbbbbb; + +}  .token-raw-full {      color: white; -    font-style: italic;      font-weight: bold;  }  .token-raw-null { -    color: black; - -    background-color: pink; +    color: #666666;  } diff --git a/src/glibext/tokenstyle.h b/src/glibext/tokenstyle.h index 923b725..2e19b51 100644 --- a/src/glibext/tokenstyle.h +++ b/src/glibext/tokenstyle.h @@ -26,6 +26,8 @@  #define _GLIBEXT_TOKENSTYLE_H +#include <stdbool.h> +#include <stdint.h>  #include <gtk/gtk.h> @@ -38,11 +40,12 @@ typedef enum _TokenRenderingTag  {      TRT_NONE,                               /* Espace ou tabulation        */ -    TRT_RAW,                                /* Contenu brut                */ +    TRT_RAW_PRINTABLE,                      /* Contenu brut                */ +    TRT_RAW_NOT_PRINTABLE,                  /* Contenu brut                */      TRT_RAW_FULL,                           /* Contenu brut et complet     */      TRT_RAW_NULL,                           /* Contenu brut et nul         */ -    TRT_PRINTABLE,                          /* Caractère imprimable        */ -    TRT_NOT_PRINTABLE,                      /* Caractère non imprimable    */ +    TRT_CHR_PRINTABLE,                      /* Caractère imprimable        */ +    TRT_CHR_NOT_PRINTABLE,                  /* Caractère non imprimable    */      TRT_COMMENT,                            /* Commentaire                 */      TRT_INDICATION,                         /* Aide à la lecture           */ @@ -82,6 +85,10 @@ typedef enum _TokenRenderingTag  } TokenRenderingTag; +/* Caractères par tabulation */ +#define TAB_SIZE 2 + +  #define G_TYPE_TOKEN_STYLE (g_token_style_get_type())  DECLARE_GTYPE(GTokenStyle, g_token_style, G, TOKEN_STYLE); @@ -90,6 +97,9 @@ DECLARE_GTYPE(GTokenStyle, g_token_style, G, TOKEN_STYLE);  /* Crée un gestionnaire de style pour le rendu des lignes. */  GTokenStyle *g_token_style_new(GtkWidget *); +/* Fournit la quantité de pixels requise pour une ligne. */ +int g_token_style_get_line_height(const GTokenStyle *); +  /* Fournit la quantité de pixels requise pour l'impression. */  int g_token_style_measure_width(const GTokenStyle *, TokenRenderingTag, size_t); @@ -102,6 +112,9 @@ char *g_token_style_build_markup(const GTokenStyle *, TokenRenderingTag, const c  /* Ajoute du texte enjolivé selon un élément de thème. */  char *g_token_style_append_markup(const GTokenStyle *, char *, TokenRenderingTag, const char *); +/* Détermine une taille de localisation, physique ou virtuelle. */ +int g_token_style_compute_location_width(const GTokenStyle *, uint64_t, bool); +  #endif  /* _GLIBEXT_TOKENSTYLE_H */ diff --git a/src/glibext/widthtracker-int.h b/src/glibext/widthtracker-int.h new file mode 100644 index 0000000..50f5757 --- /dev/null +++ b/src/glibext/widthtracker-int.h @@ -0,0 +1,80 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * widthtracker-int.h - prototypes internes pour le suivi des largeurs associées à un ensemble de lignes + * + * Copyright (C) 2016-2024 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GLIBEXT_WIDTHTRACKER_INT_H +#define _GLIBEXT_WIDTHTRACKER_INT_H + + +#include "widthtracker.h" + + + +/* Portions de largeurs communes */ +typedef struct _common_metrics_t +{ +    size_t first;                           /* Premier indice de portion   */ +    size_t last;                            /* Dernier indice de portion   */ + +    size_t merging_index;                   /* Indice de colonne de fusion */ + +    int *summary;                           /* Compilation de largeurs     */ +    bool cached;                            /* Mise en cache des calculs   */ + +} common_metrics_t; + + +/* Gestionnaire de largeurs associées aux lignes (instance) */ +struct _GWidthTracker +{ +    GObject parent;                         /* A laisser en premier        */ + +    GBufferCache *cache;                    /* Ensemble complet de lignes  */ +    size_t opt_count;                       /* Qté de colonnes en option   */ +    size_t reg_count;                       /* Nombre de colonnes normales */ +#ifndef NDEBUG +    size_t col_count;                       /* Nombre maximum de colonnes  */ +#endif + +    common_metrics_t *locals;               /* Portions représentées       */ +    size_t count;                           /* Quantité de ces portions    */ + +    int *min_widths;                        /* Largeurs requises suivies   */ +    bool *fixed;                            /* Indication d'impositions    */ +    bool cached;                            /* Mise en cache des calculs   */ + +}; + +/* Gestionnaire de largeurs associées aux lignes (classe) */ +struct _GWidthTrackerClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + +/* Met en place un nouveau suivi de largeurs au sein de lignes. */ +bool g_width_tracker_create(GWidthTracker *, GBufferCache *); + + + +#endif  /* _GLIBEXT_WIDTHTRACKER_INT_H */ diff --git a/src/glibext/widthtracker.c b/src/glibext/widthtracker.c index bfeb32c..7e06578 100644 --- a/src/glibext/widthtracker.c +++ b/src/glibext/widthtracker.c @@ -26,6 +26,331 @@  #include <assert.h>  #include <malloc.h> + + +#include "widthtracker-int.h" + + + +/* ---------------------------- PRISE DE MESURES LOCALES ---------------------------- */ + + +/* Supprime de la mémoire une collecte de mesures locales. */ +static void delete_common_metrics(common_metrics_t *); + + + +/* ---------------------------- RASSEMBLEMENT DE MESURES ---------------------------- */ + + +/* Procède à l'initialisation d'une classe de suivi de largeurs. */ +static void g_width_tracker_class_init(GWidthTrackerClass *); + +/* Procède à l'initialisation d'un suivi de largeurs de lignes. */ +static void g_width_tracker_init(GWidthTracker *); + +/* Supprime toutes les références externes. */ +static void g_width_tracker_dispose(GWidthTracker *); + +/* Procède à la libération totale de la mémoire. */ +static void g_width_tracker_finalize(GWidthTracker *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                              PRISE DE MESURES LOCALES                              */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : metrics = mesures locales conservées.                        * +*                                                                             * +*  Description : Supprime de la mémoire une collecte de mesures locales.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void delete_common_metrics(common_metrics_t *metrics) +{ +    free(metrics->summary); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                              RASSEMBLEMENT DE MESURES                              */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type du gestionnaire de largeurs associées aux lignes. */ +G_DEFINE_TYPE(GWidthTracker, g_width_tracker, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : class = classe de composant GLib à initialiser.              * +*                                                                             * +*  Description : Procède à l'initialisation d'une classe de suivi de largeurs.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_width_tracker_class_init(GWidthTrackerClass *class) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ + +    object = G_OBJECT_CLASS(class); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_width_tracker_dispose; +    object->finalize = (GObjectFinalizeFunc)g_width_tracker_finalize; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : tracker = composant GLib à initialiser.                      * +*                                                                             * +*  Description : Procède à l'initialisation d'un suivi de largeurs de lignes. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_width_tracker_init(GWidthTracker *tracker) +{ +    tracker->cache = NULL; +    tracker->opt_count = 0; +    tracker->reg_count = 0; + +    tracker->locals = NULL; +    tracker->count = 0; + +    tracker->min_widths = NULL; +    tracker->fixed = NULL; +    tracker->cached = false; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : tracker = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_width_tracker_dispose(GWidthTracker *tracker) +{ +    g_clear_object(&tracker->cache); + +    G_OBJECT_CLASS(g_width_tracker_parent_class)->dispose(G_OBJECT(tracker)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : tracker = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_width_tracker_finalize(GWidthTracker *tracker) +{ +    size_t i;                               /* Boucle de parcours          */ + +    for (i = 0; i < tracker->count; i++) +        delete_common_metrics(&tracker->locals[i]); + +    if (tracker->locals != NULL) +        free(tracker->locals); + +    if (tracker->min_widths != NULL) +        free(tracker->min_widths); + +    if (tracker->fixed != NULL) +        free(tracker->fixed); + +    G_OBJECT_CLASS(g_width_tracker_parent_class)->finalize(G_OBJECT(tracker)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : cache = tampon de lignes à lier au futur collecteur.         * +*                                                                             * +*  Description : Crée un nouveau suivi de largeurs au sein de lignes.         * +*                                                                             * +*  Retour      : Composant GLib créé.                                         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GWidthTracker *g_width_tracker_new(GBufferCache *cache) +{ +    GWidthTracker *result;                  /* Composant à retourner       */ + +    result = g_object_new(G_TYPE_WIDTH_TRACKER, NULL); + +    if (!g_width_tracker_create(result, cache)) +        g_clear_object(&result); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : tracker = collecteur de largeur à initialiser pleinement.    * +*                cache   = tampon de lignes à lier au futur élément.          * +*                                                                             * +*  Description : Met en place un nouveau suivi de largeurs au sein de lignes. * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_width_tracker_create(GWidthTracker *tracker, GBufferCache *cache) +{ +    bool result;                            /* Bilen à retourner           */ +    size_t col_count;                       /* Nombre maximum de colonnes  */ + +    result = true; + +    tracker->cache = cache; +    ref_object(cache); + +    g_buffer_cache_count_columns(cache, &tracker->opt_count, &tracker->reg_count); + +    col_count = tracker->opt_count + tracker->reg_count; + +#ifndef NDEBUG +    tracker->col_count = col_count; +#endif + +    tracker->min_widths = malloc(col_count * sizeof(int)); +    tracker->fixed = calloc(col_count, sizeof(bool)); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : tracker = gestionnaire de largeurs de lignes à mettre jour.  * +*                col     = indice de colonne visée.                           * +*                                                                             * +*  Description : Indique la largeur minimale pour une colonne donnée.         * +*                                                                             * +*  Retour      : Largeur minimale à imposée, nulle ou positive.               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +int g_width_tracker_get_column_min_width(const GWidthTracker *tracker, size_t col) +{ +    int result;                             /* Largeur à renvoyer          */ + +    assert(col < tracker->col_count); + +    result = tracker->min_widths[col]; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : tracker = gestionnaire de largeurs de lignes à mettre jour.  * +*                col     = indice de colonne visée.                           * +*                width   = largeur minimale à imposer.                        * +*                                                                             * +*  Description : Impose une largeur minimale pour une colonne donnée.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_width_tracker_set_column_min_width(GWidthTracker *tracker, size_t col, int width) +{ +    assert(col < tracker->col_count); + +    if (width < 0) +        width = 0; + +    tracker->min_widths[col] = width; +    tracker->fixed[col] = true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : tracker = gestionnaire de largeurs de lignes à consulter.    * +*                width   = largeur requise pour un affichage complet. [OUT]   * +*                                                                             * +*  Description : Détermine la largeur nécessaire à une pleine représentation. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_width_tracker_compute_width(const GWidthTracker *tracker, int *width) +{ +    size_t i;                               /* Boucle de parcours          */ + +    *width = 0; + +    // FIX access to col_count + +    for (i = 0; i < tracker->col_count; i++) +        *width += tracker->min_widths[i]; + +} + + + + + + +#if 0 + + +//#include <assert.h> +//#include <malloc.h>  #include <stdlib.h>  #include <string.h> @@ -33,7 +358,7 @@  #include <i18n.h> -#include "buffercache.h" +//#include "buffercache.h"  #include "delayed-int.h"  #include "../core/global.h"  #include "../core/nproc.h" @@ -104,56 +429,7 @@ static void g_width_update_collect(GWidthUpdate *, line_width_summary *);  /* ---------------------------- RASSEMBLEMENT DE MESURES ---------------------------- */ -/* Portions de largeurs communes */ -typedef struct _common_metrics -{ -    size_t first;                           /* Premier indice de portion   */ -    size_t last;                            /* Dernier indice de portion   */ - -    line_width_summary summary;             /* Compilation de largeurs     */ -    bool cached;                            /* Mise en cache des calculs   */ - -} common_metrics; - - -/* Gestionnaire de largeurs associées aux lignes (instance) */ -struct _GWidthTracker -{ -    GObject parent;                         /* A laisser en premier        */ - -    GBufferCache *cache;                    /* Ensemble complet de lignes  */ -    size_t col_count;                       /* Nombre maximum de colonnes  */ -    size_t opt_count;                       /* Qté de colonnes en option   */ - -    common_metrics *portions;               /* Portions représentées       */ -    size_t count;                           /* Quantité de ces portions    */ - -    gint *min_widths;                       /* Largeurs min. à respecter   */ - -    line_width_summary summary;             /* Largeurs requises suivies   */ -    bool cached;                            /* Mise en cache des calculs   */ - -}; - -/* Gestionnaire de largeurs associées aux lignes (classe) */ -struct _GWidthTrackerClass -{ -    GObjectClass parent;                    /* A laisser en premier        */ - -}; - - -/* Procède à l'initialisation d'une classe de suivi de largeurs. */ -static void g_width_tracker_class_init(GWidthTrackerClass *); - -/* Procède à l'initialisation d'un suivi de largeurs de lignes. */ -static void g_width_tracker_init(GWidthTracker *); -/* Supprime toutes les références externes. */ -static void g_width_tracker_dispose(GWidthTracker *); - -/* Procède à la libération totale de la mémoire. */ -static void g_width_tracker_finalize(GWidthTracker *);  /* Recherche la portion contenant un indice de ligne donné. */  static size_t g_width_tracker_find_metrics(const GWidthTracker *, size_t); @@ -375,131 +651,6 @@ static void g_width_update_collect(GWidthUpdate *update, line_width_summary *glo  /* ---------------------------------------------------------------------------------- */ -/* Détermine le type du gestionnaire de largeurs associées aux lignes. */ -G_DEFINE_TYPE(GWidthTracker, g_width_tracker, G_TYPE_OBJECT); - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : class = classe de composant GTK à initialiser.               * -*                                                                             * -*  Description : Procède à l'initialisation d'une classe de suivi de largeurs.* -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_width_tracker_class_init(GWidthTrackerClass *class) -{ -    GObjectClass *object;                   /* Autre version de la classe  */ - -    object = G_OBJECT_CLASS(class); - -    object->dispose = (GObjectFinalizeFunc/* ! */)g_width_tracker_dispose; -    object->finalize = (GObjectFinalizeFunc)g_width_tracker_finalize; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : tracker = composant GLib à initialiser.                      * -*                                                                             * -*  Description : Procède à l'initialisation d'un suivi de largeurs de lignes. * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_width_tracker_init(GWidthTracker *tracker) -{ -    tracker->portions = NULL; -    tracker->count = 0; - -    memset(&tracker->summary, 0, sizeof(line_width_summary)); -    tracker->cached = false; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : tracker = instance d'objet GLib à traiter.                   * -*                                                                             * -*  Description : Supprime toutes les références externes.                     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_width_tracker_dispose(GWidthTracker *tracker) -{ -    g_object_unref(G_OBJECT(tracker->cache)); - -    G_OBJECT_CLASS(g_width_tracker_parent_class)->dispose(G_OBJECT(tracker)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : tracker = instance d'objet GLib à traiter.                   * -*                                                                             * -*  Description : Procède à la libération totale de la mémoire.                * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_width_tracker_finalize(GWidthTracker *tracker) -{ -    if (tracker->min_widths != NULL) -        free(tracker->min_widths); - -    G_OBJECT_CLASS(g_width_tracker_parent_class)->finalize(G_OBJECT(tracker)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : cache     = tampon de lignes à lier au futur élément.        * -*                col_count = quantité maximale de colonnes à considérer.      * -*                opt_count = quantité de colonnes optionnelles.               * -*                                                                             * -*  Description : Crée un nouveau suivi de largeurs au sein de lignes.         * -*                                                                             * -*  Retour      : Composant GLib créé.                                         * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GWidthTracker *g_width_tracker_new(GBufferCache *cache, size_t col_count, size_t opt_count) -{ -    GWidthTracker *result;                  /* Composant à retourner       */ - -    result = g_object_new(G_TYPE_WIDTH_TRACKER, NULL); - -    g_object_ref(G_OBJECT(cache)); -    result->cache = cache; - -    result->col_count = col_count; -    result->opt_count = opt_count; - -    result->min_widths = calloc(col_count, sizeof(gint)); - -    return result; - -}  /****************************************************************************** @@ -588,57 +739,6 @@ size_t g_width_tracker_count_columns(const GWidthTracker *tracker)  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : tracker = gestionnaire de largeurs de lignes à mettre jour.  * -*                col     = indice de colonne visée.                           * -*                                                                             * -*  Description : Indique la largeur minimale pour une colonne donnée.         * -*                                                                             * -*  Retour      : Largeur minimale à imposée, nulle ou positive.               * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -gint g_width_tracker_get_column_min_width(GWidthTracker *tracker, size_t col) -{ -    gint result;                            /* Largeur à renvoyer          */ - -    assert(col < tracker->col_count); - -    result = tracker->min_widths[col]; - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : tracker = gestionnaire de largeurs de lignes à mettre jour.  * -*                col     = indice de colonne visée.                           * -*                width   = largeur minimale à imposer.                        * -*                                                                             * -*  Description : Impose une largeur minimale pour une colonne donnée.         * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_width_tracker_set_column_min_width(GWidthTracker *tracker, size_t col, gint width) -{ -    assert(col < tracker->col_count); - -    if (width < 0) -        width = 0; - -    tracker->min_widths[col] = width; - -} -  /******************************************************************************  *                                                                             * @@ -1367,3 +1467,7 @@ gint g_width_tracker_get_local_column_width(GWidthTracker *tracker, size_t index      return result;  } + + +#endif + diff --git a/src/glibext/widthtracker.h b/src/glibext/widthtracker.h index ce0aa93..c67e335 100644 --- a/src/glibext/widthtracker.h +++ b/src/glibext/widthtracker.h @@ -25,6 +25,34 @@  #define _GLIBEXT_WIDTHTRACKER_H +#include "buffercache.h" +#include "helpers.h" + + + +#define G_TYPE_WIDTH_TRACKER (g_width_tracker_get_type()) + +DECLARE_GTYPE(GWidthTracker, g_width_tracker, G, WIDTH_TRACKER); + + +/* Crée un nouveau suivi de largeurs au sein de lignes. */ +GWidthTracker *g_width_tracker_new(GBufferCache *); + +/* Indique la largeur minimale pour une colonne donnée. */ +int g_width_tracker_get_column_min_width(const GWidthTracker *, size_t); + +/* Impose une largeur minimale pour une colonne donnée. */ +void g_width_tracker_set_column_min_width(GWidthTracker *, size_t, int); + +/* Détermine la largeur nécessaire à une pleine représentation. */ +void g_width_tracker_compute_width(const GWidthTracker *, int *); + + + + +#if 0 + +  #include <glib-object.h>  #include <stdbool.h> @@ -74,7 +102,7 @@ typedef struct _GWidthTrackerClass GWidthTrackerClass;  GType g_width_tracker_get_type(void);  /* Crée un nouveau suivi de largeurs au sein de lignes. */ -GWidthTracker *g_width_tracker_new(GBufferCache *, size_t, size_t); +//GWidthTracker *g_width_tracker_new(GBufferCache *, size_t, size_t);  /* Crée un nouveau suivi de largeurs au sein de lignes. */  GWidthTracker *g_width_tracker_new_restricted(const GWidthTracker *, size_t, size_t); @@ -82,12 +110,6 @@ GWidthTracker *g_width_tracker_new_restricted(const GWidthTracker *, size_t, siz  /* Indique le nombre de colonnes prises en compte. */  size_t g_width_tracker_count_columns(const GWidthTracker *); -/* Indique la largeur minimale pour une colonne donnée. */ -gint g_width_tracker_get_column_min_width(GWidthTracker *, size_t); - -/* Impose une largeur minimale pour une colonne donnée. */ -void g_width_tracker_set_column_min_width(GWidthTracker *, size_t, gint); -  /* Prend acte d'un changement sur une ligne pour les largeurs. */  void g_width_tracker_update(GWidthTracker *, size_t); @@ -110,5 +132,8 @@ gint g_width_tracker_get_margin(GWidthTracker *, const GDisplayOptions *);  gint g_width_tracker_get_local_column_width(GWidthTracker *, size_t, size_t, size_t); +#endif + +  #endif  /* _GLIBEXT_WIDTHTRACKER_H */ diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index e33e09e..c9445e6 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -11,8 +11,6 @@ libgtkext_la_SOURCES =						\  	easygtk.h easygtk.c						\  	gtkbinarystrip.h gtkbinarystrip.c		\  	gtkblockdisplay.h gtkblockdisplay.c		\ -	gtkbufferdisplay-int.h					\ -	gtkbufferdisplay.h gtkbufferdisplay.c	\  	gtkdockable-int.h						\  	gtkdockable.h gtkdockable.c				\  	gtkdockstation.h gtkdockstation.c		\ @@ -39,8 +37,11 @@ RES_FILES =									\  libgtkext4_la_SOURCES =						\  	area-int.h								\  	area.h area.c							\ +	bufferview-int.h						\ +	bufferview.h bufferview.c				\  	contentview-int.h						\  	contentview.h contentview.c				\ +	hexview-int.h							\  	hexview.h hexview.c						\  	resources.h resources.c diff --git a/src/gtkext/bufferview-int.h b/src/gtkext/bufferview-int.h index d02aa37..7c9c8e1 100644 --- a/src/gtkext/bufferview-int.h +++ b/src/gtkext/bufferview-int.h @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkbufferdisplay-int.h - prototypes internes pour l'affichage de tampons de lignes + * bufferview-int.h - prototypes internes pour l'affichage de tampons de lignes   * - * Copyright (C) 2016-2019 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -21,27 +21,38 @@   */ -#ifndef _GTK_BUFFERDISPLAY_INT_H -#define _GTK_BUFFERDISPLAY_INT_H +#ifndef _GTKEXT_BUFFERVIEW_INT_H +#define _GTKEXT_BUFFERVIEW_INT_H -#include "gtkbufferdisplay.h" +#include "bufferview.h" +#include "contentview-int.h" -#include "gtkdisplaypanel-int.h" - +#if 0  /* Réagit à un déplacement de curseur. */ -typedef bool (* notify_caret_relocation_fc) (GtkBufferDisplay *, const GdkRectangle *); +typedef bool (* notify_caret_relocation_fc) (GtkBufferView *, const GdkRectangle *); +#endif + +  /* Composant d'affichage de tampon de lignes (instance) */ -struct _GtkBufferDisplay +struct _GtkBufferView  { -    GtkDisplayPanel parent;                 /* A laisser en premier        */ +    GtkContentView parent;                  /* A laisser en premier        */ + +    GBufferView *view;                      /* Vue choisie sur un tampon   */ +    GTokenStyle *style;                     /* Centralisation des styles   */ + +    int virt_top;                           /* Première ordonnée affichée  */ + -    GBufferView *view;                      /* Vue sur le contenu affiché  */ + + +#if 0      cairo_rectangle_int_t caret;            /* Emplacement du curseur #1   */      GLineCursor *cursor;                    /* Emplacement du curseur #2   */ @@ -51,23 +62,29 @@ struct _GtkBufferDisplay      GtkBuilder *builder;                    /* Constructeur à manipuler    */      GtkWidget *bar;                         /* Barre d'outils intégrée     */ +#endif +  };  /* Composant d'affichage de tampon de lignes (classe) */ -struct _GtkBufferDisplayClass +struct _GtkBufferViewClass  { -    GtkDisplayPanelClass parent;            /* A laisser en premier        */ +    GtkContentViewClass parent;             /* A laisser en premier        */ + +#if 0      notify_caret_relocation_fc notify_caret;/* Accompagne un déplacement   */      /* Signaux */ -    void (* reach_limit) (GtkBufferDisplay *, GdkScrollDirection); +    void (* reach_limit) (GtkBufferView *, GdkScrollDirection); + +    void (* prepare_collapsing) (GtkBufferView *, gboolean); -    void (* prepare_collapsing) (GtkBufferDisplay *, gboolean); +#endif  }; -#endif  /* _GTK_BUFFERDISPLAY_INT_H */ +#endif  /* _GTKEXT_BUFFERVIEW_INT_H */ diff --git a/src/gtkext/bufferview.c b/src/gtkext/bufferview.c index 4566cc5..4a700c3 100644 --- a/src/gtkext/bufferview.c +++ b/src/gtkext/bufferview.c @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkbufferdisplay.c - affichage de tampons de lignes + * bufferview.c - affichage de tampons de lignes   * - * Copyright (C) 2016-2019 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -21,9 +21,418 @@   */ -#include "gtkbufferdisplay.h" +#include "bufferview.h" +#include "bufferview-int.h" + + + + + +/* ------------------------- BASES D'UN COMPOSANT GRAPHIQUE ------------------------- */ + + +/* Procède à l'initialisation de l'afficheur de tampons. */ +static void gtk_buffer_view_class_init(GtkBufferViewClass *); + +/* Procède à l'initialisation de l'afficheur de tampons. */ +static void gtk_buffer_view_init(GtkBufferView *); + +/* Supprime toutes les références externes. */ +static void gtk_buffer_view_dispose(GtkBufferView *); + +/* Procède à la libération totale de la mémoire. */ +static void gtk_buffer_view_finalize(GtkBufferView *); + + + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Prend acte de la taille allouée au composant d'affichage. */ +static void gtk_buffer_view_size_allocate(GtkWidget *, int, int, int); + +/* Réagit à un défilement chez une barre associée au composant. */ +static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *, GtkOrientation, GtkAdjustment *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                           BASES D'UN COMPOSANT GRAPHIQUE                           */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type du composant d'affichage générique. */ +G_DEFINE_TYPE(GtkBufferView, gtk_buffer_view, GTK_TYPE_CONTENT_VIEW); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : class = classe GTK à initialiser.                            * +*                                                                             * +*  Description : Procède à l'initialisation de l'afficheur de tampons.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_class_init(GtkBufferViewClass *class) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ +    GtkWidgetClass *widget;                 /* Classe version Widget       */ +    GtkContentViewClass *content;           /* Base d'affichage            */ + +    object = G_OBJECT_CLASS(class); + +    object->dispose = (GObjectFinalizeFunc/* ! */)gtk_buffer_view_dispose; +    object->finalize = (GObjectFinalizeFunc)gtk_buffer_view_finalize; + +    widget = GTK_WIDGET_CLASS(class); + +    widget->size_allocate = gtk_buffer_view_size_allocate; + +    content = GTK_CONTENT_VIEW_CLASS(class); + +    content->adjust = (adjust_scroll_value_fc)gtk_buffer_view_adjust_scroll_value; + + + +#if 0 + +    widget_class->focus_in_event = gtk_buffer_view_focus; +    widget_class->focus_out_event = gtk_buffer_view_focus; +    widget_class->button_press_event = gtk_buffer_view_button_press; +    widget_class->draw = gtk_buffer_view_draw; +    widget_class->key_press_event = gtk_buffer_view_key_press; + +    panel_class = GTK_DISPLAY_PANEL_CLASS(class); + +    panel_class->compute_size = (compute_requested_size_fc)gtk_buffer_view_compute_requested_size; +    panel_class->compute_inc = (compute_scroll_inc_fc)gtk_buffer_view_compute_scroll_inc; +    panel_class->adjust = (adjust_scroll_value_fc)gtk_buffer_view_adjust_scroll_value; +    panel_class->get_coordinates = (get_coordinates_fc)gtk_buffer_view_get_cursor_coordinates; +    panel_class->get_active = (get_active_object_fc)gtk_buffer_view_get_active_object; +    panel_class->move_caret_to = (move_caret_to_fc)_gtk_buffer_view_move_caret_to; +    panel_class->cache_glance = (cache_glance_fc)gtk_buffer_view_cache_glance; + +    panel_class->get_cursor = (get_cursor_fc)gtk_buffer_view_get_cursor; + +    /* Signaux */ + +    g_signal_new("reach-limit", +                 GTK_TYPE_BUFFER_DISPLAY, +                 G_SIGNAL_RUN_LAST, +                 G_STRUCT_OFFSET(GtkBufferViewClass, reach_limit), +                 NULL, NULL, +                 g_cclosure_marshal_VOID__ENUM, +                 G_TYPE_NONE, 1, GTK_TYPE_SCROLL_TYPE); + +    g_signal_new("prepare-collapsing", +                 GTK_TYPE_BUFFER_DISPLAY, +                 G_SIGNAL_RUN_LAST, +                 G_STRUCT_OFFSET(GtkBufferViewClass, prepare_collapsing), +                 NULL, NULL, +                 g_cclosure_marshal_VOID__BOOLEAN, +                 G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + +#endif + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : display = composant GTK à initialiser.                       * +*                                                                             * +*  Description : Procède à l'initialisation de l'afficheur de tampons.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_init(GtkBufferView *view) +{ +    view->view = NULL; +    view->style = g_token_style_new(GTK_WIDGET(view)); + +    view->virt_top = 0; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : display = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_dispose(GtkBufferView *view) +{ +#if 0 + +    if (display->caret_timer != 0) +    { +        g_source_remove(display->caret_timer); +        display->caret_timer = 0; +    } + +    g_clear_object(&display->cursor); + +    g_clear_object(&display->builder); +    g_clear_object(&display->bar); + +#endif + + + + +    g_clear_object(&view->view); +    g_clear_object(&view->style); + +    G_OBJECT_CLASS(gtk_buffer_view_parent_class)->dispose(G_OBJECT(view)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : display = instance d'objet Gtk à traiter.                    * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_finalize(GtkBufferView *view) +{ +    G_OBJECT_CLASS(gtk_buffer_view_parent_class)->finalize(G_OBJECT(view)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : view = composant GTK à consulter.                            * +*                                                                             * +*  Description : Fournit la vue associée au tampon de lignes courant.         * +*                                                                             * +*  Retour      : Vue mise en place.                                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBufferView *gtk_buffer_view_get_view(const GtkBufferView *view) +{ +    GBufferView *result;                    /* Instance à retourner        */ + +    result = view->view; + +    ref_object(result); + +    return result; + +} + + + + + + + + + + + + + + + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : widget = composant GTK à examiner.                           * +*                width  = largeur affectée au composant graphique.            * +*                height = hauteur affectée au composant graphique.            * +*                baseline = ligne de base affectée au composant graphique.    * +*                                                                             * +*  Description : Prend acte de la taille allouée au composant d'affichage.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_size_allocate(GtkWidget *widget, int width, int height, int baseline) +{ +    GtkContentView *base;                   /* Version de base             */ +    GtkBufferView *view;                    /* Version spécialisée         */ +    int full_width;                         /* Largeur idéale complète     */ +    int full_height;                        /* Hauteur idéale complète     */ +    int *min_widths;                        /* Largeurs minimales imposées */ +    int *min_heights;                       /* Hauteurs minimales imposées */ +    size_t i;                               /* Boucle de parcours          */ +    int upper;                              /* Valeur maximale retenue     */ +    GtkAdjustment *adj;                     /* Ajustement à mettre à jour  */ +    int line_height;                        /* Hauteur d'une ligne unique  */ +    int lines_per_page;                     /* Nombre de lignes sur l'écran*/ +    GtkAllocation allocated;                /* Zone allouée                */ +    GWidthTracker *tracker;                 /* Collecteur de largeurs      */ + +    base = GTK_CONTENT_VIEW(widget); +    view = GTK_BUFFER_VIEW(widget); + +    /* Détermination de la surface idéale à afficher */ + +    g_buffer_view_compute_size(view->view, &full_width, &full_height); + +    min_widths = alloca(base->sub_count * sizeof(int)); +    min_heights = alloca(base->sub_count * sizeof(int)); + +    for (i = 0; i < base->sub_count; i++) +    { +        gtk_widget_measure(base->sub_children[i], GTK_ORIENTATION_HORIZONTAL, -1, +                           &min_widths[i], NULL, NULL, NULL); +        full_width += min_widths[i]; + +        gtk_widget_measure(base->sub_children[i], GTK_ORIENTATION_VERTICAL, -1, +                           &min_heights[i], NULL, NULL, NULL); +        full_height += min_heights[i]; + +    } + +    /* Définition des besoins en défilement */ + +    upper = MAX(width, full_width); + +    adj = base->adjustments[GTK_ORIENTATION_HORIZONTAL]; + +    gtk_adjustment_configure(adj, +                             gtk_adjustment_get_value(adj), +                             0, upper, +                             0.1 * width, +                             0.9 * width, +                             width); + +    upper = MAX(height, full_height); + +    line_height = g_token_style_get_line_height(view->style); + +    lines_per_page = height / line_height; +    if (lines_per_page == 0) lines_per_page = 1; + +    adj = base->adjustments[GTK_ORIENTATION_VERTICAL]; + +    gtk_adjustment_configure(adj, +                             gtk_adjustment_get_value(adj), +                             0, upper, +                             line_height * lines_per_page, +                             line_height * lines_per_page * 10, +                             height); + +    /* Placement des composants d'affichage */ + +    tracker = g_buffer_view_get_tracker(view->view); + +    allocated.x = 0; +    allocated.y = 0; +    allocated.height = height; + +    for (i = 0; i < base->sub_count; i++) +    { +        allocated.width = g_width_tracker_get_column_min_width(tracker, i); + +        if ((i + 1) == base->sub_count && allocated.width < (width - allocated.x)) +            allocated.width = width - allocated.x; + +        gtk_widget_size_allocate(base->sub_children[i], &allocated, baseline); + +        allocated.x += allocated.width; + +    } + +    unref_object(tracker); + +    /* Mise à jour des éléments plus internes */ + +    GTK_WIDGET_CLASS(gtk_buffer_view_parent_class)->size_allocate(widget, width, height, baseline); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : view        = panneau d'affichage concerné.                  * +*                orientation = indication sur le défilement à traiter.        * +*                adj         = nouvel ajustement à prendre en compte.         * +*                                                                             * +*  Description : Réagit à un défilement chez une barre associée au composant. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *view, GtkOrientation orientation, GtkAdjustment *adj) +{ +    GtkContentView *base;                   /* Version de base             */ +    size_t i;                               /* Boucle de parcours          */ + +    base = GTK_CONTENT_VIEW(view); + +    if (orientation == GTK_ORIENTATION_HORIZONTAL) +        printf("TODO...\n"); + +    else +    { +        view->virt_top = gtk_adjustment_get_value(adj); + +        for (i = 0; i < base->sub_count; i++) +            gtk_widget_queue_draw(base->sub_children[i]); + +    } + +} + + + + + + + + +#if 0 +  #include <assert.h> @@ -38,16 +447,16 @@  /* Procède à l'initialisation de l'afficheur de tampons. */ -static void gtk_buffer_display_class_init(GtkBufferDisplayClass *); +//static void gtk_buffer_display_class_init(GtkBufferDisplayClass *);  /* Procède à l'initialisation de l'afficheur de tampons. */ -static void gtk_buffer_display_init(GtkBufferDisplay *); +//static void gtk_buffer_display_init(GtkBufferDisplay *);  /* Supprime toutes les références externes. */ -static void gtk_buffer_display_dispose(GtkBufferDisplay *); +//static void gtk_buffer_display_dispose(GtkBufferDisplay *);  /* Procède à la libération totale de la mémoire. */ -static void gtk_buffer_display_finalize(GtkBufferDisplay *); +//static void gtk_buffer_display_finalize(GtkBufferDisplay *);  /* Intègre le focus dans le rendu du composant. */  static gboolean gtk_buffer_display_focus(GtkWidget *, GdkEventFocus *); @@ -882,30 +1291,6 @@ static GLineCursor *gtk_buffer_display_get_cursor(const GtkBufferDisplay *displa  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : display = composant GTK à consulter.                         * -*                                                                             * -*  Description : Fournit la vue associée au tampon de lignes courant.         * -*                                                                             * -*  Retour      : Vue mise en place.                                           * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GBufferView *gtk_buffer_display_get_view(const GtkBufferDisplay *display) -{ -    GBufferView *result;                    /* Instance à retourner        */ - -    result = display->view; - -    g_object_ref(G_OBJECT(result)); - -    return result; - -} -  /* ---------------------------------------------------------------------------------- */ @@ -1437,3 +1822,5 @@ static gboolean on_block_bar_collapsing_leave(GtkWidget *widget, GdkEventCrossin      return FALSE;  } + +#endif diff --git a/src/gtkext/bufferview.h b/src/gtkext/bufferview.h index 8f2d63c..1bdfc80 100644 --- a/src/gtkext/bufferview.h +++ b/src/gtkext/bufferview.h @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkbufferdisplay.h - prototypes pour l'affichage de tampons de lignes + * bufferview.h - prototypes pour l'affichage de tampons de lignes   * - * Copyright (C) 2016-2019 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -21,41 +21,36 @@   */ -#ifndef _GTKEXT_GTKBUFFER_DISPLAY_H -#define _GTKEXT_GTKBUFFER_DISPLAY_H +#ifndef _GTKEXT_BUFFERVIEW_H +#define _GTKEXT_BUFFERVIEW_H -#include <glib-object.h>  #include <gtk/gtk.h>  #include "../glibext/bufferview.h" +#include "../glibext/helpers.h" -#define GTK_TYPE_BUFFER_DISPLAY             (gtk_buffer_display_get_type()) -#define GTK_BUFFER_DISPLAY(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BUFFER_DISPLAY, GtkBufferDisplay)) -#define GTK_BUFFER_DISPLAY_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BUFFER_DISPLAY, GtkBufferDisplayClass)) -#define GTK_IS_BUFFER_DISPLAY(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BUFFER_DISPLAY)) -#define GTK_IS_BUFFER_DISPLAY_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BUFFER_DISPLAY)) -#define GTK_BUFFER_DISPLAY_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BUFFER_VIEW, GtkBufferDisplayClass)) +#define GTK_TYPE_BUFFER_VIEW (gtk_buffer_view_get_type()) +DECLARE_GTYPE(GtkBufferView, gtk_buffer_view, GTK, BUFFER_VIEW); -/* Composant d'affichage de tampon de lignes (instance) */ -typedef struct _GtkBufferDisplay GtkBufferDisplay; -/* Composant d'affichage de tampon de lignes (classe) */ -typedef struct _GtkBufferDisplayClass GtkBufferDisplayClass; + +/* Fournit la vue associée au tampon de lignes courant. */ +GBufferView *gtk_buffer_view_get_view(const GtkBufferView *); + -/* Détermine le type du composant d'affichage de tampon de lignes. */ -GType gtk_buffer_display_get_type(void); -/* Fournit la vue associée au tampon de lignes courant. */ -GBufferView *gtk_buffer_display_get_view(const GtkBufferDisplay *); + +#if 0 +  /* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */ @@ -73,6 +68,9 @@ bool gtk_buffer_display_move_caret_to(GtkBufferDisplay *, bool, gint *);  /* Ajoute une nouvelle barre d'outils pour bloc au composant. */  void gtk_buffer_display_add_block_bar(GtkBufferDisplay *); +#endif + + -#endif  /* _GTKEXT_GTKBUFFER_DISPLAY_H */ +#endif  /* _GTKEXT_BUFFERVIEW_H */ diff --git a/src/gtkext/contentview-int.h b/src/gtkext/contentview-int.h index 25c9ddb..01c0c7a 100644 --- a/src/gtkext/contentview-int.h +++ b/src/gtkext/contentview-int.h @@ -28,11 +28,19 @@  #include "contentview.h" +#include "../glibext/bufferview.h"  #include "../glibext/tokenstyle.h" +/* Réagit à un défilement chez une barre associée au composant. */ +typedef void (* adjust_scroll_value_fc) (GtkContentView *, GtkOrientation, GtkAdjustment *); + + + + +  #if 0  #include <stdbool.h> @@ -52,10 +60,10 @@  typedef void (* compute_requested_size_fc) (GtkDisplayPanel *, gint *, gint *);  /* Détermine la taille des bonds lors de défilements. */ -typedef void (* compute_scroll_inc_fc) (GtkDisplayPanel *, gint, GtkOrientation, gdouble *, gdouble *); +//typedef void (* compute_scroll_inc_fc) (GtkDisplayPanel *, gint, GtkOrientation, gdouble *, gdouble *);  /* Réagit à un défilement chez une barre associée au composant. */ -typedef void (* adjust_scroll_value_fc) (GtkDisplayPanel *, GtkAdjustment *, GtkOrientation); +//typedef void (* adjust_scroll_value_fc) (GtkDisplayPanel *, GtkAdjustment *, GtkOrientation);  /* Ajuste au besoin la zone affichée pour un curseur. */  typedef void (* prepare_for_cursor_fc) (GtkDisplayPanel *, const GLineCursor *); @@ -94,15 +102,18 @@ struct _GtkContentView  {      GtkWidget parent;                       /* A laisser en premier        */ +    GtkAdjustment *adjustments[2];          /* Barres de défilement h. & v.*/ +    GtkScrollablePolicy scroll_policies[2]; /* Politiques de défilement    */ +      GDisplayOptions *options;               /* Options de rendu            */ -    GTokenStyle *style;                     /* Centralisation des styles   */ -#if 0 +    /* Propriété des implémentations */ -    GtkAdjustment *hadjustment;             /* Barre de défilement horiz.  */ -    GtkAdjustment *vadjustment;             /* Barre de défilement vert.   */ -    GtkScrollablePolicy hscroll_policy;     /* Politique horizontale       */            -    GtkScrollablePolicy vscroll_policy;     /* Politique verticale         */            +    GtkWidget * const *sub_children;        /* Composants embarqués        */ +    size_t sub_count;                       /* Quantité de ces composants  */ + + +#if 0      double scale;                           /* Echelle de l'affichage      */ @@ -121,13 +132,14 @@ struct _GtkContentView  /* Composant d'affichage générique (classe) */  struct _GtkContentViewClass  { -    GtkFixedClass parent;                   /* A laisser en premier        */ +    GtkWidgetClass parent;                  /* A laisser en premier        */  #if 0 -      compute_requested_size_fc compute_size; /* Calcul de la taille requise */ -    compute_scroll_inc_fc compute_inc;      /* Calcul des bonds            */ +#endif      adjust_scroll_value_fc adjust;          /* Réaction à un défilement    */ + +#if 0      prepare_for_cursor_fc prepare;          /* Préparation de zone affichée*/      get_coordinates_fc get_coordinates;     /* Conversion adresse <-> pos. */      get_active_object_fc get_active;        /* Infos sur l'objet actif     */ @@ -149,20 +161,20 @@ struct _GtkContentViewClass  }; -#if 0 -  /* Propriétés propres au composant d'affichage */ -typedef enum _ViewPanelProps +typedef enum _ContentViewProps  { -    VPP_0, -    VPP_HADJUSTMENT, -    VPP_VADJUSTMENT, -    VPP_HSCROLL_POLICY, -    VPP_VSCROLL_POLICY +    CVP_0, +    CVP_HADJUSTMENT, +    CVP_VADJUSTMENT, +    CVP_HSCROLL_POLICY, +    CVP_VSCROLL_POLICY -} ViewPanelProps; +} ContentViewProps; +#if 0 +  /* Définit un chemin décrivant la bordure autour du panneau. */  void gtk_display_panel_define_border_path(GtkDisplayPanel *, cairo_t *, const GtkAllocation *); diff --git a/src/gtkext/contentview.c b/src/gtkext/contentview.c index 4b7f79d..77bbb7b 100644 --- a/src/gtkext/contentview.c +++ b/src/gtkext/contentview.c @@ -59,22 +59,51 @@ static void gtk_content_view_dispose(GtkContentView *);  /* Procède à la libération totale de la mémoire. */  static void gtk_content_view_finalize(GtkContentView *); + + + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Définit une propriété du composant d'affichage. */ +static void gtk_content_view_set_property(GObject *, guint, const GValue *, GParamSpec *); + +/* Se débarrsse d'un ajustement pour un défilement donné. */ +static void _gtk_content_view_disconnect_adjustment(GtkContentView *, GtkOrientation); + +/* S'associe à un ajustement pour un défilement donné. */ +static void _gtk_content_view_set_adjustment(GtkContentView *, GtkOrientation, GtkAdjustment *); + +/* Réagit à un défilement chez une barre associée au composant. */ +static void _gtk_content_view_adjustment_value_changed(GtkAdjustment *, GtkContentView *); + +/* Fournit une propriété du composant d'affichage. */ +static void gtk_content_view_get_property(GObject *, guint, GValue *, GParamSpec *); + +/* Fournit les mesures mainimale et idéale du composant. */ +static void gtk_content_view_measure(GtkWidget *, GtkOrientation, int, int *, int *, int *, int *); + + + + +  #if 0  /* Définit une propriété du composant d'affichage. */ -static void gtk_display_panel_set_property(GObject *, guint, const GValue *, GParamSpec *); +//static void gtk_display_panel_set_property(GObject *, guint, const GValue *, GParamSpec *);  /* Fournit une propriété du composant d'affichage. */ -static void gtk_display_panel_get_property(GObject *, guint, GValue *, GParamSpec *); +//static void gtk_display_panel_get_property(GObject *, guint, GValue *, GParamSpec *);  /* Détruit un composant d'affichage. */ -static void gtk_display_panel_destroy(GtkWidget *); +//static void gtk_display_panel_destroy(GtkWidget *);  /* Encadre la construction graphique initiale de l'affichage. */  static void gtk_display_panel_realize(GtkWidget *);  /* S'adapte à la surface concédée par le composant parent. */ -static void gtk_display_panel_size_allocate(GtkWidget *, GtkAllocation *); +//static void gtk_display_panel_size_allocate(GtkWidget *, GtkAllocation *);  /* Fournit la hauteur idéale pour le composant d'affichage. */  static void gtk_display_panel_get_preferred_height(GtkWidget *, gint *, gint *); @@ -83,22 +112,22 @@ static void gtk_display_panel_get_preferred_height(GtkWidget *, gint *, gint *);  static void gtk_display_panel_get_preferred_width(GtkWidget *, gint *, gint *);  /* Détermine la taille des bonds lors de défilements. */ -static void gtk_display_panel_compute_scroll_inc(GtkDisplayPanel *, gint, GtkOrientation, gdouble *, gdouble *); +//static void gtk_display_panel_compute_scroll_inc(GtkDisplayPanel *, gint, GtkOrientation, gdouble *, gdouble *);  /* Détermine la taille allouée pour le contenu. */  static void gtk_display_panel_compute_allocation(GtkDisplayPanel *, GtkAllocation *);  /* Se débarrsse d'un ajustement pour un défilement donné. */ -static void gtk_display_panel_disconnect_adjustment(GtkDisplayPanel *, GtkOrientation); +//static void gtk_display_panel_disconnect_adjustment(GtkDisplayPanel *, GtkOrientation);  /* S'associe à un ajustement pour un défilement donné. */ -static void gtk_display_panel_set_adjustment(GtkDisplayPanel *, GtkOrientation, GtkAdjustment *); +//static void gtk_display_panel_set_adjustment(GtkDisplayPanel *, GtkOrientation, GtkAdjustment *);  /* Ajuste les paramètres de défilement du composant. */ -static void gtk_display_panel_update_adjustment(GtkDisplayPanel *, GtkOrientation); +//static void gtk_display_panel_update_adjustment(GtkDisplayPanel *, GtkOrientation);  /* Réagit à un défilement chez une barre associée au composant.*/ -static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *, GtkDisplayPanel *); +//static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *, GtkDisplayPanel *); @@ -136,8 +165,8 @@ G_DEFINE_TYPE_WITH_CODE(GtkDisplayPanel, gtk_display_panel, GTK_TYPE_FIXED,  /* Détermine le type du composant d'affichage générique. */ -G_DEFINE_TYPE(GtkContentView, gtk_content_view, GTK_TYPE_WIDGET); - +G_DEFINE_TYPE_WITH_CODE(GtkContentView, gtk_content_view, GTK_TYPE_WIDGET, +                        G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE, NULL));  /****************************************************************************** @@ -155,35 +184,43 @@ G_DEFINE_TYPE(GtkContentView, gtk_content_view, GTK_TYPE_WIDGET);  static void gtk_content_view_class_init(GtkContentViewClass *class)  {      GObjectClass *object;                   /* Plus haut niveau équivalent */ -    //GtkWidgetClass *widget;                 /* Classe de haut niveau       */ -    //GtkContentViewClass *panel;            /* Classe de lus bas niveau    */ +    GtkWidgetClass *widget;                 /* Classe de haut niveau       */      object = G_OBJECT_CLASS(class); +    object->set_property = gtk_content_view_set_property; +    object->get_property = gtk_content_view_get_property;      object->dispose = (GObjectFinalizeFunc/* ! */)gtk_content_view_dispose;      object->finalize = (GObjectFinalizeFunc)gtk_content_view_finalize; +    /* Implémentation de l'interface "GtkScrollable" */ +    g_object_class_override_property(object, CVP_HADJUSTMENT, "hadjustment"); +    g_object_class_override_property(object, CVP_VADJUSTMENT, "vadjustment"); +    g_object_class_override_property(object, CVP_HSCROLL_POLICY, "hscroll-policy"); +    g_object_class_override_property(object, CVP_VSCROLL_POLICY, "vscroll-policy"); + + + + + +    widget = GTK_WIDGET_CLASS(class); + +    widget->measure = gtk_content_view_measure; + + + +  #if 0 -    object->set_property = gtk_display_panel_set_property; -    object->get_property = gtk_display_panel_get_property; -    /* Implémentation de l'interface "GtkScrollable" */ -    g_object_class_override_property(object, VPP_HADJUSTMENT, "hadjustment"); -    g_object_class_override_property(object, VPP_VADJUSTMENT, "vadjustment"); -    g_object_class_override_property(object, VPP_HSCROLL_POLICY, "hscroll-policy"); -    g_object_class_override_property(object, VPP_VSCROLL_POLICY, "vscroll-policy");      widget = GTK_WIDGET_CLASS(class); -    widget->destroy = gtk_display_panel_destroy; +    //widget->destroy = gtk_display_panel_destroy;      widget->realize = gtk_display_panel_realize;      widget->size_allocate = gtk_display_panel_size_allocate;      widget->get_preferred_height = gtk_display_panel_get_preferred_height;      widget->get_preferred_width = gtk_display_panel_get_preferred_width; -    panel = GTK_DISPLAY_PANEL_CLASS(class); - -    panel->compute_inc = gtk_display_panel_compute_scroll_inc;      /* Signaux */ @@ -214,8 +251,13 @@ static void gtk_content_view_class_init(GtkContentViewClass *class)  static void gtk_content_view_init(GtkContentView *view)  { +    view->adjustments[GTK_ORIENTATION_HORIZONTAL] = NULL; +    view->adjustments[GTK_ORIENTATION_VERTICAL] = NULL; + +    view->scroll_policies[GTK_ORIENTATION_HORIZONTAL] = GTK_POLICY_AUTOMATIC; +    view->scroll_policies[GTK_ORIENTATION_VERTICAL] = GTK_POLICY_AUTOMATIC; +      view->options = NULL; -    view->style = g_token_style_new(GTK_WIDGET(view)); @@ -272,13 +314,16 @@ static void gtk_display_panel_loaded_interface_init(GLoadedPanelInterface *iface  static void gtk_content_view_dispose(GtkContentView *view)  { +    _gtk_content_view_disconnect_adjustment(view, GTK_ORIENTATION_HORIZONTAL); +    _gtk_content_view_disconnect_adjustment(view, GTK_ORIENTATION_VERTICAL); + +    g_clear_object(&view->adjustments[GTK_ORIENTATION_HORIZONTAL]); +    g_clear_object(&view->adjustments[GTK_ORIENTATION_VERTICAL]); +      g_clear_object(&view->options); -    g_clear_object(&view->style);      /* -    g_clear_object(&panel->hadjustment); -    g_clear_object(&panel->vadjustment);      g_clear_object(&panel->options); @@ -309,7 +354,16 @@ static void gtk_content_view_finalize(GtkContentView *view)  } -#if 0 + + + + + +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             *  *  Paramètres  : object  = instance de composant GTK à manipuler.             * @@ -325,25 +379,25 @@ static void gtk_content_view_finalize(GtkContentView *view)  *                                                                             *  ******************************************************************************/ -static void gtk_display_panel_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +static void gtk_content_view_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)  { -    GtkDisplayPanel *panel;                 /* Autre vision de l'instance  */ +    GtkContentView *view;                   /* Autre vision de l'instance  */ -    panel = GTK_DISPLAY_PANEL(object); +    view = GTK_CONTENT_VIEW(object);      switch (prop_id)      { -        case VPP_HADJUSTMENT: -            gtk_display_panel_set_adjustment(panel, GTK_ORIENTATION_HORIZONTAL, g_value_get_object(value)); +        case CVP_HADJUSTMENT: +            _gtk_content_view_set_adjustment(view, GTK_ORIENTATION_HORIZONTAL, g_value_get_object(value));              break; -        case VPP_VADJUSTMENT: -            gtk_display_panel_set_adjustment(panel, GTK_ORIENTATION_VERTICAL, g_value_get_object(value)); +        case CVP_VADJUSTMENT: +            _gtk_content_view_set_adjustment(view, GTK_ORIENTATION_VERTICAL, g_value_get_object(value));              break; -        case VPP_HSCROLL_POLICY: +        case CVP_HSCROLL_POLICY:              //viewport->priv->hscroll_policy = g_value_get_enum (value);              //gtk_widget_queue_resize (GTK_WIDGET (viewport));              break; -        case VPP_VSCROLL_POLICY: +        case CVP_VSCROLL_POLICY:              //viewport->priv->vscroll_policy = g_value_get_enum (value);              //gtk_widget_queue_resize (GTK_WIDGET (viewport));              break; @@ -357,6 +411,105 @@ static void gtk_display_panel_set_property(GObject *object, guint prop_id, const  /******************************************************************************  *                                                                             * +*  Paramètres  : view        = composant GTK d'affichage à mettre à jour.     * +*                orientation = indication sur le défilement à traiter.        * +*                                                                             * +*  Description : Se débarrsse d'un ajustement pour un défilement donné.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void _gtk_content_view_disconnect_adjustment(GtkContentView *view, GtkOrientation orientation) +{ +    GtkAdjustment **adjp;                   /* Ajustement à manipuler      */ + +    adjp = &view->adjustments[orientation]; + +    if (*adjp != NULL) +    { +        g_signal_handlers_disconnect_by_func(*adjp, _gtk_content_view_adjustment_value_changed, view); +        g_clear_object(adjp); +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : view        = composant GTK d'affichage à mettre à jour.     * +*                orientation = indication sur le défilement à traiter.        * +*                adj         = nouvel ajustement à prendre en compte.         * +*                                                                             * +*  Description : S'associe à un ajustement pour un défilement donné.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void _gtk_content_view_set_adjustment(GtkContentView *view, GtkOrientation orientation, GtkAdjustment *adj) +{ +    GtkAdjustment **adjp;                   /* Ajustement à manipuler      */ + +    adjp = &view->adjustments[orientation]; + +    /* S'il n'y a rien à faire... */ +    if (adj != NULL && adj == *adjp) +        return; + +    if (adj == NULL) +        adj = gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); +    else +        ref_object(adj); + +    _gtk_content_view_disconnect_adjustment(view, orientation); + +    *adjp = adj; + +    g_signal_connect(adj, "value-changed", G_CALLBACK(_gtk_content_view_adjustment_value_changed), view); + +    gtk_widget_queue_allocate(GTK_WIDGET(view)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : adj  = défilement dont une valeur a changé.                  * +*                view = panneau d'affichage concerné.                         * +*                                                                             * +*  Description : Réagit à un défilement chez une barre associée au composant. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void _gtk_content_view_adjustment_value_changed(GtkAdjustment *adj, GtkContentView *view) +{ +    GtkOrientation orientation;             /* Indification de la barre    */ +    GtkContentViewClass *class;             /* Classe de l'instance        */ + +    if (adj == view->adjustments[GTK_ORIENTATION_HORIZONTAL]) +        orientation = GTK_ORIENTATION_HORIZONTAL; +    else +        orientation = GTK_ORIENTATION_VERTICAL; + +    class = GTK_CONTENT_VIEW_GET_CLASS(view); + +    if (class->adjust != NULL) +        class->adjust(view, orientation, adj); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : object  = instance de composant GTK à manipuler.             *  *                prop_id = identifiant de la propriété concernée.             *  *                value   = valeur à renvoyer.                                 * @@ -370,25 +523,25 @@ static void gtk_display_panel_set_property(GObject *object, guint prop_id, const  *                                                                             *  ******************************************************************************/ -static void gtk_display_panel_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +static void gtk_content_view_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)  { -    GtkDisplayPanel *panel;                 /* Autre vision de l'instance  */ +    GtkContentView *view;                   /* Autre vision de l'instance  */ -    panel = GTK_DISPLAY_PANEL(object); +    view = GTK_CONTENT_VIEW(object);      switch (prop_id)      { -        case VPP_HADJUSTMENT: -            g_value_set_object(value, panel->hadjustment); +        case CVP_HADJUSTMENT: +            g_value_set_object(value, view->adjustments[GTK_ORIENTATION_HORIZONTAL]);              break; -        case VPP_VADJUSTMENT: -            g_value_set_object(value, panel->vadjustment); +        case CVP_VADJUSTMENT: +            g_value_set_object(value, view->adjustments[GTK_ORIENTATION_VERTICAL]);              break; -        case VPP_HSCROLL_POLICY: -            g_value_set_enum(value, panel->hscroll_policy); +        case CVP_HSCROLL_POLICY: +            g_value_set_enum(value, view->scroll_policies[GTK_ORIENTATION_HORIZONTAL]);              break; -        case VPP_VSCROLL_POLICY: -            g_value_set_enum(value, panel->vscroll_policy); +        case CVP_VSCROLL_POLICY: +            g_value_set_enum(value, view->scroll_policies[GTK_ORIENTATION_VERTICAL]);              break;          default:              G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -400,6 +553,88 @@ static void gtk_display_panel_get_property(GObject *object, guint prop_id, GValu  /******************************************************************************  *                                                                             * +*  Paramètres  : widget       = composant GTK à examiner.                     * +*                orientation  = direction à observer pour les calculs.        * +*                for_size     = taille de la direction opposée.               * +*                minimum      = taille minimale pour le composant. [OUT]      * +*                natural      = taille idéale pour le composant. [OUT]        * +*                min_baseline = ligne de base minimale. [OUT]                 * +*                nat_baseline = ligne de base idéale. [OUT]                   * +*                                                                             * +*  Description : Fournit les mesures mainimale et idéale du composant.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_content_view_measure(GtkWidget *widget, GtkOrientation orientation, int for_size, int *minimum, int *natural, int *min_baseline, int *nat_baseline) +{ +    GtkContentView *view;                   /* Version spécialisée         */ +    size_t i;                               /* Boucle de parcours          */ +    int min;                                /* Valeur minimale locale      */ +    int nat;                                /* Valeur idéale locale        */ + +    view = GTK_CONTENT_VIEW(widget); + +    if (minimum != NULL) *minimum = 0; +    if (natural != NULL) *natural = 0; + +    /* Demande de hauteur minimale / idéale */ +    if (orientation == GTK_ORIENTATION_VERTICAL) +    { +        for (i = 0; i < view->sub_count; i++) +        { +            gtk_widget_measure(view->sub_children[i], GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL); + +            if (minimum != NULL && min > *minimum) +                *minimum = min; + +            if (natural != NULL && nat > *natural) +                *natural = nat; + +        } + +    } + +    /* Demande de largeur minimale / idéale */ +    else +    { +        for (i = 0; i < view->sub_count; i++) +        { +            gtk_widget_measure(view->sub_children[i], GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL); + +            if (minimum != NULL) *minimum += min; +            if (natural != NULL) *natural += nat; + +        } + +    } + +    if (min_baseline != NULL) *min_baseline = -1; +    if (nat_baseline != NULL) *nat_baseline = -1; + +} + + + + + + + + + + + + + + +#if 0 + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : widget = composant GTK à détruire.                           *  *                                                                             *  *  Description : Détruit un composant d'affichage.                            * @@ -416,8 +651,11 @@ static void gtk_display_panel_destroy(GtkWidget *widget)      panel = GTK_DISPLAY_PANEL(widget); -    gtk_display_panel_disconnect_adjustment(panel, GTK_ORIENTATION_HORIZONTAL); -    gtk_display_panel_disconnect_adjustment(panel, GTK_ORIENTATION_VERTICAL); +    GtkContentView *view;                   /* Autre vision de l'instance  */ + +    view = GTK_CONTENT_VIEW(widget); + +      GTK_WIDGET_CLASS(gtk_display_panel_parent_class)->destroy(widget); @@ -471,32 +709,6 @@ static void gtk_display_panel_realize(GtkWidget *widget)  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : widget     = composant GTK à mettre à jour.                  * -*                allocation = étendue accordée à la vue.                      * -*                                                                             * -*  Description : S'adapte à la surface concédée par le composant parent.      * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void gtk_display_panel_size_allocate(GtkWidget *widget, GtkAllocation *allocation) -{ -    GtkDisplayPanel *panel;                 /* Autre version du composant  */ - -    GTK_WIDGET_CLASS(gtk_display_panel_parent_class)->size_allocate(widget, allocation); - -    panel = GTK_DISPLAY_PANEL(widget); - -    gtk_display_panel_update_adjustment(panel, GTK_ORIENTATION_HORIZONTAL); -    gtk_display_panel_update_adjustment(panel, GTK_ORIENTATION_VERTICAL); - -} -  /******************************************************************************  *                                                                             * @@ -560,29 +772,6 @@ static void gtk_display_panel_get_preferred_width(GtkWidget *widget, gint *minim  } -/****************************************************************************** -*                                                                             * -*  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_display_panel_compute_scroll_inc(GtkDisplayPanel *panel, gint size, GtkOrientation orientation, gdouble *step, gdouble *page) -{ -    *step = size * 0.1; -    *page = size * 0.9; - -} -  /******************************************************************************  *                                                                             * @@ -653,151 +842,8 @@ static void gtk_display_panel_compute_allocation(GtkDisplayPanel *panel, GtkAllo  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : panel       = composant GTK d'affichage à mettre à jour.     * -*                orientation = indication sur le défilement à traiter.        * -*                                                                             * -*  Description : Se débarrsse d'un ajustement pour un défilement donné.       * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void gtk_display_panel_disconnect_adjustment(GtkDisplayPanel *panel, GtkOrientation orientation) -{ -    GtkAdjustment **adjp;                   /* Ajustement à manipuler      */ - -    adjp = orientation == GTK_ORIENTATION_HORIZONTAL ? &panel->hadjustment : &panel->vadjustment; - -    if (*adjp != NULL) -    { -        g_signal_handlers_disconnect_by_func(*adjp, gtk_display_panel_adjustment_value_changed, panel); -        g_object_unref(G_OBJECT(*adjp)); -        *adjp = NULL; -    } - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : panel       = composant GTK d'affichage à mettre à jour.     * -*                orientation = indication sur le défilement à traiter.        * -*                adj         = nouvel ajustement à prendre en compte.         * -*                                                                             * -*  Description : S'associe à un ajustement pour un défilement donné.          * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void gtk_display_panel_set_adjustment(GtkDisplayPanel *panel, GtkOrientation orientation, GtkAdjustment *adj) -{ -    GtkAdjustment **adjp;                   /* Ajustement à manipuler      */ -    adjp = orientation == GTK_ORIENTATION_HORIZONTAL ? &panel->hadjustment : &panel->vadjustment; -    /* S'il n'y a rien à faire... */ -    if (adj != NULL && adj == *adjp) -        return; - -    if (!adj) -        adj = gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); - -    gtk_display_panel_disconnect_adjustment(panel, orientation); - -    *adjp = adj; -    g_object_ref_sink(adj); - -    gtk_display_panel_update_adjustment(panel, orientation); - -    g_signal_connect(adj, "value-changed", G_CALLBACK(gtk_display_panel_adjustment_value_changed), panel); - -    gtk_display_panel_adjustment_value_changed(adj, panel); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : panel       = composant GTK d'affichage à mettre à jour.     * -*                orientation = indication sur le défilement à traiter.        * -*                                                                             * -*  Description : Ajuste les paramètres de défilement du composant.            * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void gtk_display_panel_update_adjustment(GtkDisplayPanel *panel, GtkOrientation orientation) -{ -    GtkAllocation allocation;               /* Emplacement du contenu      */ -    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_display_panel_compute_allocation(panel, &allocation); - -    if (orientation == GTK_ORIENTATION_HORIZONTAL) -    { -        adj = panel->hadjustment; - -        gtk_widget_get_preferred_width(GTK_WIDGET(panel), &req, NULL); -        allocated = allocation.width; - -    } -    else -    { -        adj = panel->vadjustment; - -        gtk_widget_get_preferred_height(GTK_WIDGET(panel), &req, NULL); -        allocated = allocation.height; - -    } - -    GTK_DISPLAY_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), -                             step_inc, -                             page_inc, -                             allocated); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : adj   = défilement dont une valeur a changé.                 * -*                panel = panneau d'affichage concerné.                        * -*                                                                             * -*  Description : Réagit à un défilement chez une barre associée au composant. * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *adj, GtkDisplayPanel *panel) -{ -    GtkOrientation orientation;             /* Indification de la barre    */ - -    orientation = (adj == panel->hadjustment ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL); - -    if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust != NULL) -        GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust(panel, adj, orientation); - -}  /****************************************************************************** diff --git a/src/gtkext/hexview-int.h b/src/gtkext/hexview-int.h new file mode 100644 index 0000000..2b1c570 --- /dev/null +++ b/src/gtkext/hexview-int.h @@ -0,0 +1,71 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * hexview-int.h - définitions internes pour l'affichage de contenus de binaire + * + * Copyright (C) 2016-2024 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GTKEXT_HEXVIEW_INT_H +#define _GTKEXT_HEXVIEW_INT_H + + +#include "bufferview-int.h" +#include "hexview.h" +#include "../glibext/generators/hex.h" + + + +/* Composant d'affichage d'octets bruts et imprimables (instance) */ +struct _GtkHexView +{ +    GtkBufferView parent;                   /* A laisser en premier        */ + +    union +    { +#define _CHILDREN_COUNT 3 + +        GtkWidget *children[_CHILDREN_COUNT];/* Sous-composants d'affichage*/ + +        struct +        { +            GtkWidget *offsets;             /* Affichage des positions     */ +            GtkWidget *hex;                 /* Affichage des octets brut   */ +            GtkWidget *ascii;               /* Affichage des imprimables   */ +        }; + +    }; + +    GHexGenerator *generator;               /* Générateur unique dédié     */ + +}; + +/* Composant d'affichage d'octets bruts et imprimables (classe) */ +struct _GtkHexViewClass +{ +    GtkBufferViewClass parent;              /* A laisser en premier        */ + +}; + + +/* Met en place un nouveau composant d'affichage d'octets bruts. */ +bool gtk_hex_view_create(GtkHexView *, GBinContent *); + + + +#endif  /* _GTKEXT_HEXVIEW_INT_H */ diff --git a/src/gtkext/hexview.c b/src/gtkext/hexview.c index 717c1bc..7363079 100644 --- a/src/gtkext/hexview.c +++ b/src/gtkext/hexview.c @@ -24,45 +24,17 @@  #include "hexview.h" -#include "area.h" -#include "contentview-int.h" - - - -/* ------------------------- BASES D'UN COMPOSANT GRAPHIQUE ------------------------- */ - +#include <alloca.h> +#include <sys/param.h> -/* Composant d'affichage d'octets bruts et imprimables (instance) */ -struct _GtkHexView -{ -    GtkContentView parent;                  /* A laisser en premier        */ - -    union -    { -#define _CHILDREN_COUNT 4 - -        GtkWidget *children[_CHILDREN_COUNT];/* Sous-composants d'affichage*/ - -        struct -        { -            GtkWidget *offsets;             /* Affichage des positions     */ -            GtkWidget *hex;                 /* Affichage des octets brut   */ -            GtkWidget *ascii;               /* Affichage des imprimables   */ -            GtkWidget *vscroll;             /* Barre de défilement         */ -        }; -    }; - -    bool need_vscrolling;                   /* Besoin de défilement ?      */ +#include "area.h" +#include "hexview-int.h" +#include "../glibext/options/hex.h" -}; -/* Composant d'affichage d'octets bruts et imprimables (classe) */ -struct _GtkHexViewClass -{ -    GtkContentViewClass parent;             /* A laisser en premier        */ -}; +/* ------------------------- BASES D'UN COMPOSANT GRAPHIQUE ------------------------- */  /* Procède à l'initialisation de l'afficheur générique. */ @@ -77,6 +49,12 @@ static void gtk_hex_view_dispose(GtkHexView *);  /* Procède à la libération totale de la mémoire. */  static void gtk_hex_view_finalize(GtkHexView *); +/* Procède à l'actualisation de l'affichage d'un sous-composant. */ +static void gtk_hex_view_dispatch_sub_snapshot(GtkWidget *, GtkSnapshot *, GtkWidget *); + +/* Adapte le cache de lignes hexadécimales à la taille courante. */ +static void gtk_hex_view_populate_cache(GtkHexView *); +  void demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot, GtkWidget *parent); @@ -105,7 +83,7 @@ static void gtk_hex_view_measure(GtkWidget *, GtkOrientation, int, int *, int *,  /* Détermine le type du composant d'affichage générique. */ -G_DEFINE_TYPE(GtkHexView, gtk_hex_view, GTK_TYPE_CONTENT_VIEW); +G_DEFINE_TYPE(GtkHexView, gtk_hex_view, GTK_TYPE_BUFFER_VIEW);  /****************************************************************************** @@ -141,7 +119,6 @@ static void gtk_hex_view_class_init(GtkHexViewClass *class)      gtk_widget_class_bind_template_child(widget, GtkHexView, offsets);      gtk_widget_class_bind_template_child(widget, GtkHexView, hex);      gtk_widget_class_bind_template_child(widget, GtkHexView, ascii); -    gtk_widget_class_bind_template_child(widget, GtkHexView, vscroll);      widget->size_allocate = gtk_hex_view_size_allocate;      widget->get_request_mode = gtk_hex_view_get_request_mode; @@ -164,15 +141,31 @@ static void gtk_hex_view_class_init(GtkHexViewClass *class)  static void gtk_hex_view_init(GtkHexView *view)  { +    GtkContentView *base;                   /* Base d'instance supérieure  */ + +    /* Niveau supérieur */ + +    base = GTK_CONTENT_VIEW(view); + +    base->options = G_DISPLAY_OPTIONS(g_hex_options_new()); + +    base->sub_children = view->children; +    base->sub_count = _CHILDREN_COUNT; + +    /* Instance courante */ +      gtk_widget_init_template(GTK_WIDGET(view)); -    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->offsets), demo_snapshot, GTK_WIDGET(view)); +    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->offsets), +                                       gtk_hex_view_dispatch_sub_snapshot, GTK_WIDGET(view)); -    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->hex), demo_snapshot, GTK_WIDGET(view)); +    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->hex), +                                       gtk_hex_view_dispatch_sub_snapshot, GTK_WIDGET(view)); -    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->ascii), demo_snapshot, GTK_WIDGET(view)); +    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->ascii), +                                       gtk_hex_view_dispatch_sub_snapshot, GTK_WIDGET(view)); -    view->need_vscrolling = true; +    view->generator = NULL;  } @@ -193,6 +186,8 @@ static void gtk_hex_view_dispose(GtkHexView *view)  {      gtk_widget_dispose_template(GTK_WIDGET(view), GTK_TYPE_HEX_VIEW); +    g_clear_object(&view->generator); +      G_OBJECT_CLASS(gtk_hex_view_parent_class)->dispose(G_OBJECT(view));  } @@ -217,130 +212,225 @@ static void gtk_hex_view_finalize(GtkHexView *view)  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à exposer de façon brute.          * +*                                                                             * +*  Description : Crée un composant d'affichage d'octets bruts et imprimables. * +*                                                                             * +*  Retour      : Centralisateur mis en place pour un composant GTK donné.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +GtkHexView *gtk_hex_view_new(GBinContent *content) +{ +    GtkHexView *result;                     /* Nouvelle instance à renvoyer*/ +    result = g_object_new(GTK_TYPE_HEX_VIEW, NULL); +    if (!gtk_hex_view_create(result, content)) +        g_clear_object(&result); +    return result; +} -void demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot, GtkWidget *parent) -{ -  GdkRGBA red, green, yellow, blue; -  float w, h; +/****************************************************************************** +*                                                                             * +*  Paramètres  : view    = composant d'affichage à initialiser pleinement.    * +*                content = contenu binaire à exposer de façon brute.          * +*                                                                             * +*  Description : Met en place un nouveau composant d'affichage d'octets bruts.* +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -  gdk_rgba_parse (&red, "red"); -  gdk_rgba_parse (&green, "green"); -  gdk_rgba_parse (&yellow, "yellow"); -  gdk_rgba_parse (&blue, "blue"); +bool gtk_hex_view_create(GtkHexView *view, GBinContent *content) +{ +    bool result;                            /* Bilan à retourner           */ +    GtkBufferView *parent;                  /* Version parente du composant*/ +    GBufferCache *cache;                    /* Tampon à représenter        */ -  w = gtk_widget_get_width (widget) / 2.0; -  h = gtk_widget_get_height (widget) / 2.0; +    result = true; -  h /= 2.0; +    assert(g_display_options_count(GTK_CONTENT_VIEW(view)->options) == 1); -  gtk_snapshot_append_color (snapshot, &red, -                             &GRAPHENE_RECT_INIT(0, 0, w, h)); -  gtk_snapshot_append_color (snapshot, &green, -                             &GRAPHENE_RECT_INIT(w, 0, w, h)); -  gtk_snapshot_append_color (snapshot, &yellow, -                             &GRAPHENE_RECT_INIT(0, h, w, h)); -  gtk_snapshot_append_color (snapshot, &blue, -                             &GRAPHENE_RECT_INIT(w, h, w, h)); +    parent = GTK_BUFFER_VIEW(view); +    cache = g_buffer_cache_new(1, 2); +    parent->view = g_buffer_view_new(cache, parent->style); +    unref_object(cache); -  cairo_t *cr; -  int x; +    view->generator = g_hex_generator_new(content); -  x = 0; +    return result; -  cr = gtk_snapshot_append_cairo(snapshot, &GRAPHENE_RECT_INIT(0, 0, w * 2, h * 2)); +} -  g_token_style_draw_text(GTK_CONTENT_VIEW(parent)->style, -                          TRT_RAW_FULL, -                          cr, -                          &x, 0, -                          "A.A", 3); -  g_token_style_draw_text(GTK_CONTENT_VIEW(parent)->style, -                          TRT_RAW_NULL, -                          cr, -                          &x, 0, -                          "A.A", 3); +/****************************************************************************** +*                                                                             * +*  Paramètres  : widget   = composant GTK à redessiner.                       * +*                snapshot = gestionnaire de noeuds de rendu à solliciter.     * +*                parent   = composant GTK parent et cadre de l'appel.         * +*                                                                             * +*  Description : Procède à l'actualisation de l'affichage d'un sous-composant.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -  cairo_destroy(cr); +static void gtk_hex_view_dispatch_sub_snapshot(GtkWidget *widget, GtkSnapshot *snapshot, GtkWidget *parent) +{ +    GtkHexView *view;                       /* Version spécialisée         */ +    size_t column;                          /* Indice de colonne à traiter */ +    int width;                              /* Largeur à disposition       */ +    int height;                             /* Hauteur à disposition       */ +    cairo_t *cr;                            /* Pinceau pour les dessins    */ +    view = GTK_HEX_VIEW(parent); +    if (widget == view->offsets) +        column = HCO_OFFSET; -} +    else if (widget == view->hex) +        column = HCO_COUNT + 0; +    else +    { +        assert(widget == view->ascii); +        column = HCO_COUNT + 1; +    } +    width = gtk_widget_get_width(widget); +    height = gtk_widget_get_height(widget); +    cr = gtk_snapshot_append_cairo(snapshot, &GRAPHENE_RECT_INIT(0, 0, width, height)); +    g_buffer_view_draw(GTK_BUFFER_VIEW(parent)->view, cr, column, GTK_BUFFER_VIEW(parent)->virt_top, height); +    cairo_destroy(cr); +} -bool g_buffer_view_allocate_widths(void *ptr, int width, int height, int fill, int *out); +/****************************************************************************** +*                                                                             * +*  Paramètres  : view = composant GTK à mettre à jour.                        * +*                                                                             * +*  Description : Adapte le cache de lignes hexadécimales à la taille courante.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -bool g_buffer_view_allocate_widths(void *ptr, int width, int height, int fill, int *out) +static void gtk_hex_view_populate_cache(GtkHexView *view)  { +    GBinContent *content;                   /* Contenu binaire affiché     */ +    phys_t full;                            /* Taille totale à représenter */ +    phys_t line;                            /* Taille représentée par ligne*/ +    size_t needed;                          /* Nombre de lignes nécessaires*/ +    GBufferCache *cache;                    /* Tampon à représenter        */ +    size_t count;                           /* Nombre actuel de lignes     */ -    int i;                                  /* Boucle de parcours          */ +    /* Détermination du besoin */ +    content = g_hex_generator_get_content(view->generator); -    for (i = 0; i < fill; i++) -    { +    full = g_binary_content_compute_size(content); -        if (i == 0) -        { -            out[0] = 40; -        } +    unref_object(content); -        else if ((i + 1) == fill) -        { -            out[i] = width; -        } +    line = g_hex_generator_get_bytes_per_line(view->generator); -        else -        { -            out[i] = 230; -        } +    needed = full / line; +    if (full % line > 0) +        needed++; -        width -= out[i]; +    /* Adaptation du tampon interne ? */ +    cache = g_buffer_view_get_cache(GTK_BUFFER_VIEW(view)->view); +    g_buffer_cache_wlock(cache); -    } +    count = g_buffer_cache_count_lines(cache); + +    if (needed < count) +        g_buffer_cache_truncate(cache, needed); + +    else if (needed > count) +        g_buffer_cache_extend_with(cache, needed, G_TOKEN_GENERATOR(view->generator)); -    return false; +    g_buffer_cache_wunlock(cache); +    unref_object(cache); + +    /* Mise à jour de l'affichage ? */ + +    if (needed != count) +        gtk_widget_queue_resize(GTK_WIDGET(view));  } -int g_buffer_view_measure_height(void *ptr, int width); -int g_buffer_view_measure_height(void *ptr, int width) + + + + + +void demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot, GtkWidget *parent)  { -    int result;                             /* Mesure à retourner          */ +  GdkRGBA red, green, yellow, blue; +  float w, h; -    if (width == -1) -        result = 1; +  gdk_rgba_parse (&red, "red"); +  gdk_rgba_parse (&green, "green"); +  gdk_rgba_parse (&yellow, "yellow"); +  gdk_rgba_parse (&blue, "blue"); -    else -        result = 5000 / width; +  w = gtk_widget_get_width (widget) / 2.0; +  h = gtk_widget_get_height (widget) / 2.0; + +  h /= 2.0; + +  gtk_snapshot_append_color (snapshot, &red, +                             &GRAPHENE_RECT_INIT(0, 0, w, h)); +  gtk_snapshot_append_color (snapshot, &green, +                             &GRAPHENE_RECT_INIT(w, 0, w, h)); +  gtk_snapshot_append_color (snapshot, &yellow, +                             &GRAPHENE_RECT_INIT(0, h, w, h)); +  gtk_snapshot_append_color (snapshot, &blue, +                             &GRAPHENE_RECT_INIT(w, h, w, h)); -    result *= 16; -    return result;  } + + + + + + + + + +  /* ---------------------------------------------------------------------------------- */  /*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */  /* ---------------------------------------------------------------------------------- */ @@ -364,68 +454,56 @@ int g_buffer_view_measure_height(void *ptr, int width)  static void gtk_hex_view_size_allocate(GtkWidget *widget, int width, int height, int baseline)  {      GtkHexView *view;                       /* Version spécialisée         */ -    int vscroll_width;                      /* Largeur idéale de la barre  */ - -    GtkAllocation allocated;                /* Zone allouée                */ +    int *min_widths;                        /* Tailles minimales imposées  */ +    int *final_widths;                      /* Tailles finales retenues    */      size_t i;                               /* Boucle de parcours          */ -    int sub_widths[_CHILDREN_COUNT - 1];    /* Sous-largeurs calculées     */ +    int available;                          /* Largeur disponible          */ +    bool changed;                           /* Détection de variation      */ +    GWidthTracker *tracker;                 /* Collecteur de largeurs      */      view = GTK_HEX_VIEW(widget); -    allocated.y = 0; -    allocated.height = height; - -    /* Barre de défilement ? */ - -    view->need_vscrolling = g_buffer_view_allocate_widths(NULL, width, height, _CHILDREN_COUNT - 1, sub_widths); +    min_widths = alloca(_CHILDREN_COUNT * sizeof(int)); +    final_widths = alloca(_CHILDREN_COUNT * sizeof(int)); -    gtk_widget_set_visible(view->vscroll, view->need_vscrolling); +    for (i = 0; i < _CHILDREN_COUNT; i++) +        gtk_widget_measure(view->children[i], GTK_ORIENTATION_HORIZONTAL, -1, &min_widths[i], NULL, NULL, NULL); -    if (view->need_vscrolling) -    { -        gtk_widget_remove_css_class(widget, "without_vscroll"); -        gtk_widget_add_css_class(widget, "with_vscroll"); -    } -    else -    { -        gtk_widget_remove_css_class(widget, "with_vscroll"); -        gtk_widget_add_css_class(widget, "without_vscroll"); -    } +    /* Passe 1 : tentative sans défilement vertical */ -    /** -     * Validité de la consistence des feuilles CSS : le changement de classe -     * ne doit pas faire évoluer les tailles. -     */ -    assert(view->need_vscrolling == g_buffer_view_allocate_widths(NULL, width, height, _CHILDREN_COUNT - 1, sub_widths)); +    available = width; -    if (view->need_vscrolling) -    { -        gtk_widget_measure(view->vscroll, GTK_ORIENTATION_HORIZONTAL, height, &vscroll_width, NULL, NULL, NULL); +    for (i = 0; i < _CHILDREN_COUNT; i++) +        available -= min_widths[i]; -        allocated.x = width - vscroll_width; -        allocated.width = vscroll_width; +    changed = g_hex_generator_allocate(view->generator, +                                       GTK_CONTENT_VIEW(view)->options, +                                       GTK_BUFFER_VIEW(view)->style, +                                       available, final_widths); -        gtk_widget_size_allocate(view->vscroll, &allocated, baseline); +    /* Application des largeurs calculées */ -        width -= vscroll_width; +    if (changed) +    { +        gtk_hex_view_populate_cache(view); -    } +        tracker = g_buffer_view_get_tracker(GTK_BUFFER_VIEW(view)->view); -    /* Placement des composants d'affichage */ +        for (i = 0; i < _CHILDREN_COUNT; i++) +        { +            final_widths[i] += min_widths[i]; -    g_buffer_view_allocate_widths(NULL, width, height, _CHILDREN_COUNT - 1, sub_widths); +            g_width_tracker_set_column_min_width(tracker, i, final_widths[i]); -    allocated.x = 0; +        } -    for (i = 0; i < (_CHILDREN_COUNT - 1); i++) -    { -        allocated.width = sub_widths[i]; +        unref_object(tracker); -        gtk_widget_size_allocate(view->children[i], &allocated, baseline); +    } -        allocated.x += sub_widths[i]; +    /* Mise à jour des éléments plus internes */ -    } +    GTK_WIDGET_CLASS(gtk_hex_view_parent_class)->size_allocate(widget, width, height, baseline);  } @@ -453,6 +531,17 @@ static GtkSizeRequestMode gtk_hex_view_get_request_mode(GtkWidget *widget)  } + + + + + + + + + + +  /******************************************************************************  *                                                                             *  *  Paramètres  : widget       = composant GTK à examiner.                     * @@ -473,54 +562,60 @@ static GtkSizeRequestMode gtk_hex_view_get_request_mode(GtkWidget *widget)  static void gtk_hex_view_measure(GtkWidget *widget, GtkOrientation orientation, int for_size, int *minimum, int *natural, int *min_baseline, int *nat_baseline)  { +    bool processed;                         /* Calcul de hauteur effectué  */      GtkHexView *view;                       /* Version spécialisée         */      int requested;                          /* Taille requise à priori     */      size_t i;                               /* Boucle de parcours          */      int min;                                /* Valeur minimale locale      */      int nat;                                /* Valeur idéale locale        */ -    view = GTK_HEX_VIEW(widget); +    processed = false;      /* Demande de hauteur minimale / idéale */ -    if (orientation == GTK_ORIENTATION_VERTICAL) +    if (orientation == GTK_ORIENTATION_VERTICAL && for_size != -1)      { -        requested = g_buffer_view_measure_height(NULL, for_size); +        view = GTK_HEX_VIEW(widget); -        if (minimum != NULL) *minimum = requested; -        if (natural != NULL) *natural = requested; +        requested = 0;          for (i = 0; i < _CHILDREN_COUNT; i++)          { -            gtk_widget_measure(view->children[i], GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL); +            gtk_widget_measure(view->children[i], GTK_ORIENTATION_HORIZONTAL, -1, &min, NULL, NULL, NULL); +            requested += min; +        } -            if (minimum != NULL && min > *minimum) -                *minimum = min; +        for_size -= requested; -            if (natural != NULL && nat > *natural) -                *natural = nat; +        if (for_size > 0) +        { +            requested = g_hex_generator_mesure_height_for_width(view->generator, +                                                                GTK_CONTENT_VIEW(view)->options, +                                                                GTK_BUFFER_VIEW(view)->style, +                                                                for_size); -        } +            if (minimum != NULL) *minimum = 0; +            if (natural != NULL) *natural = requested; -    } +            for (i = 0; i < _CHILDREN_COUNT; i++) +            { +                gtk_widget_measure(view->children[i], GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL); -    /* Demande de largeur minimale / idéale */ -    else -    { -        if (minimum != NULL) *minimum = 0; -        if (natural != NULL) *natural = 0; +                if (minimum != NULL && min > *minimum) +                    *minimum = min; -        for (i = 0; i < _CHILDREN_COUNT; i++) -        { -            gtk_widget_measure(view->children[i], GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL); +                if (natural != NULL && nat > *natural) +                    *natural = nat; + +            } -            if (minimum != NULL) *minimum += min; -            if (natural != NULL) *natural += nat; +            processed = true;          }      } -    if (min_baseline != NULL) *min_baseline = -1; -    if (nat_baseline != NULL) *nat_baseline = -1; +    if (!processed) +        GTK_WIDGET_CLASS(gtk_hex_view_parent_class)->measure(widget, orientation, for_size, +                                                           minimum, natural, min_baseline, nat_baseline);  } diff --git a/src/gtkext/hexview.h b/src/gtkext/hexview.h index 8d3129d..2199786 100644 --- a/src/gtkext/hexview.h +++ b/src/gtkext/hexview.h @@ -28,6 +28,7 @@  #include <gtk/gtk.h> +#include "../analysis/content.h"  #include "../glibext/helpers.h" @@ -37,11 +38,8 @@  DECLARE_GTYPE(GtkHexView, gtk_hex_view, GTK, HEX_VIEW); - - - - - +/* Crée un composant d'affichage d'octets bruts et imprimables. */ +GtkHexView *gtk_hex_view_new(GBinContent *); diff --git a/src/gtkext/hexview.ui b/src/gtkext/hexview.ui index df657ca..ae4586c 100644 --- a/src/gtkext/hexview.ui +++ b/src/gtkext/hexview.ui @@ -1,5 +1,5 @@  <interface> -  <template class="GtkHexView" parent="GtkContentView"> +  <template class="GtkHexView" parent="GtkBufferView">      <property name="css-name">GtkHexView</property>      <child>        <object class="GtkComposingArea" id="offsets"> @@ -23,10 +23,5 @@          </style>        </object>      </child> -    <child> -      <object class="GtkScrollbar" id="vscroll"> -        <property name="orientation">1</property> -      </object> -    </child>    </template>  </interface> diff --git a/src/gui/core/Makefile.am b/src/gui/core/Makefile.am index c219655..96ef578 100644 --- a/src/gui/core/Makefile.am +++ b/src/gui/core/Makefile.am @@ -13,7 +13,6 @@ RES_FILES =								\  	../../../pixmaps/snapshot_current.png  libguicore_la_SOURCES =					\ -	core.h core.c						\  	global.h global.c					\  	items.h items.c						\  	panels.h panels.c					\ @@ -23,7 +22,8 @@ libguicore_la_SOURCES =					\  libguicore_la_CFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -libguicore4_la_SOURCES =				\ +libguicore4_la_SOURCES =					\ +	core.h core.c							\  	logs.h logs.c  libguicore4_la_CFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) diff --git a/src/gui/core/core.c b/src/gui/core/core.c index 6bebfe2..2d47dc9 100644 --- a/src/gui/core/core.c +++ b/src/gui/core/core.c @@ -24,6 +24,80 @@  #include "core.h" +#include "../../glibext/linetoken.h" + + + +/* Statuts de chargement */ +static AvailableGuiComponent __loaded = AGC_NONE; + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : flags = liste d'éléments à charger.                          * +*                                                                             * +*  Description : Charge les éléments graphiques de l'éditeur.                 * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_gui_components(AvailableGuiComponent flags) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = true; + +    if ((flags & AGC_BUFFER_FEATURES) != 0 && (__loaded & AGC_BUFFER_FEATURES) == 0) +    { +        result = init_segment_content_hash_table(); +        if (!result) goto done; + +        __loaded |= AGC_BUFFER_FEATURES; + +    } + + done: + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : flags = liste d'éléments à décharger.                        * +*                                                                             * +*  Description : Décharge les éléments graphiques de l'éditeur.               * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_gui_components(AvailableGuiComponent flags) +{ +    if ((flags & AGC_BUFFER_FEATURES) != 0 && (__loaded & AGC_BUFFER_FEATURES) == 0) +    { +        exit_segment_content_hash_table(); + +        __loaded &= ~AGC_BUFFER_FEATURES; + +    } + +} + + + + + + + +#if 0 +  #include "global.h"  #include "items.h"  #include "panels.h" @@ -201,3 +275,5 @@ void unload_all_gui_components(void)      unload_all_themes();  } + +#endif diff --git a/src/gui/core/core.h b/src/gui/core/core.h index c043434..bcb5433 100644 --- a/src/gui/core/core.h +++ b/src/gui/core/core.h @@ -25,10 +25,34 @@  #define _GUI_CORE_CORE_H -#include <glib-object.h>  #include <stdbool.h> + +/* Eléments à (dé)charger disponibles */ +typedef enum _AvailableGuiComponent +{ +    AGC_NONE            = (0 << 0),         /* Statut initial              */ +    AGC_BUFFER_FEATURES = (1 << 0),         /* Tampons de bribes de texte  */ + +} AvailableGuiComponent; + +/* Charge les éléments graphiques de l'éditeur. */ +bool load_gui_components(AvailableGuiComponent); + +/* Décharge les éléments graphiques de l'éditeur. */ +void unload_gui_components(AvailableGuiComponent); + + + + + + +#if 0 + +#include <glib-object.h> + +  #include "../../glibext/configuration.h" @@ -43,5 +67,8 @@ bool complete_loading_of_all_gui_components(GGenConfig *);  void unload_all_gui_components(void); +#endif + +  #endif  /* _GUI_CORE_CORE_H */  | 
