From 8043a52accf1b413362c54adb117c7786e237917 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 25 May 2024 15:30:30 +0200 Subject: Rename some files. --- src/glibext/Makefile.am | 6 +- src/glibext/_signal.h | 48 ++ src/glibext/displayoptions.c | 383 +++++++++++ src/glibext/displayoptions.h | 74 +++ src/glibext/gdisplayoptions.c | 383 ----------- src/glibext/gdisplayoptions.h | 74 --- src/glibext/linesegment.c | 1206 ---------------------------------- src/glibext/linesegment.h | 227 ------- src/glibext/linetoken.c | 1206 ++++++++++++++++++++++++++++++++++ src/glibext/linetoken.h | 227 +++++++ src/glibext/signal.h | 48 -- src/glibext/tokenstyle.c | 205 ++++++ src/glibext/tokenstyle.h | 65 ++ src/gtkext/Makefile.am | 7 +- src/gtkext/contentview-int.h | 164 +++++ src/gtkext/contentview.c | 1348 ++++++++++++++++++++++++++++++++++++++ src/gtkext/contentview.h | 78 +++ src/gtkext/gtkdisplaypanel-int.h | 164 ----- src/gtkext/gtkdisplaypanel.c | 1348 -------------------------------------- src/gtkext/gtkdisplaypanel.h | 78 --- src/gtkext/rendering.c | 205 ------ src/gtkext/rendering.h | 65 -- 22 files changed, 3804 insertions(+), 3805 deletions(-) create mode 100644 src/glibext/_signal.h create mode 100644 src/glibext/displayoptions.c create mode 100644 src/glibext/displayoptions.h delete mode 100644 src/glibext/gdisplayoptions.c delete mode 100644 src/glibext/gdisplayoptions.h delete mode 100644 src/glibext/linesegment.c delete mode 100644 src/glibext/linesegment.h create mode 100644 src/glibext/linetoken.c create mode 100644 src/glibext/linetoken.h delete mode 100644 src/glibext/signal.h create mode 100644 src/glibext/tokenstyle.c create mode 100644 src/glibext/tokenstyle.h create mode 100644 src/gtkext/contentview-int.h create mode 100644 src/gtkext/contentview.c create mode 100644 src/gtkext/contentview.h delete mode 100644 src/gtkext/gtkdisplaypanel-int.h delete mode 100644 src/gtkext/gtkdisplaypanel.c delete mode 100644 src/gtkext/gtkdisplaypanel.h delete mode 100644 src/gtkext/rendering.c delete mode 100644 src/gtkext/rendering.h diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index 860f3b9..ac8668c 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -17,7 +17,7 @@ libglibext_la_SOURCES = \ gbinarycursor.h gbinarycursor.c \ gbinportion-int.h \ gbinportion.h gbinportion.c \ - gdisplayoptions.h gdisplayoptions.c \ + displayoptions.h displayoptions.c \ glinecursor-int.h \ glinecursor.h glinecursor.c \ gnhash.h gnhash.c \ @@ -28,9 +28,9 @@ libglibext_la_SOURCES = \ objhole.h \ proto.h \ seq.h seq.c \ - signal.h signal.c \ + _signal.h signal.c \ singleton.h singleton.c \ - linesegment.h linesegment.c \ + linetoken.h linetoken.c \ umemslice-int.h \ umemslice.h umemslice.c diff --git a/src/glibext/_signal.h b/src/glibext/_signal.h new file mode 100644 index 0000000..4f0ab4b --- /dev/null +++ b/src/glibext/_signal.h @@ -0,0 +1,48 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * signal.h - prototypes pour un encadrement des signaux supplémentaire par rapport à celui de la GLib + * + * Copyright (C) 2014-2018 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 . + */ + + +#ifndef _GLIBEXT_SIGNAL_H +#define _GLIBEXT_SIGNAL_H + + +#include +#include +#include +#include +#include + + + +/* Reproduit le comportement de la fonction g_signal_connect(). */ +gulong _g_signal_connect_to_main(gpointer, const gchar *, GCallback, gpointer, GClosureMarshal, GConnectFlags); + + +#define g_signal_connect_to_main(instance, signal, handler, data, marshal) \ + _g_signal_connect_to_main(instance, signal, handler, data, marshal, 0) + +#define g_signal_connect_to_main_swapped(instance, signal, handler, data, marshal) \ + _g_signal_connect_to_main(instance, signal, handler, data, marshal, G_CONNECT_SWAPPED) + + + +#endif /* _GLIBEXT_SIGNAL_H */ diff --git a/src/glibext/displayoptions.c b/src/glibext/displayoptions.c new file mode 100644 index 0000000..a8f835b --- /dev/null +++ b/src/glibext/displayoptions.c @@ -0,0 +1,383 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gdisplayoptions.h - options de rendus des lignes de code + * + * Copyright (C) 2018 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 . + */ + + +#include "gdisplayoptions.h" + + +#include +#include +#include + + +#include "chrysamarshal.h" + + + +/* Options de représentation (instance) */ +struct _GDisplayOptions +{ + GObject parent; /* A laisser en premier */ + + char **names; /* Désignations des options */ + bool *values; /* Valeurs des options */ + size_t count; /* Nombre de ces options */ + +}; + +/* Options de représentation (classe) */ +struct _GDisplayOptionsClass +{ + GObjectClass parent; /* A laisser en premier */ + + /* Signaux */ + + void (* value_changed) (const GDisplayOptions *, gsize, gboolean); + +}; + + +/* Initialise la classe des options pour le rendu des lignes. */ +static void g_display_options_class_init(GDisplayOptionsClass *); + +/* Initialise une instance d'options pour le rendu des lignes. */ +static void g_display_options_init(GDisplayOptions *); + +/* Supprime toutes les références externes. */ +static void g_display_options_dispose(GDisplayOptions *); + +/* Procède à la libération totale de la mémoire. */ +static void g_display_options_finalize(GDisplayOptions *); + + + +/* Indique le type défini pour une ligne de représentation. */ +G_DEFINE_TYPE(GDisplayOptions, g_display_options, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des options pour le rendu des lignes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_display_options_class_init(GDisplayOptionsClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_display_options_dispose; + object->finalize = (GObjectFinalizeFunc)g_display_options_finalize; + + /** + * Note : il n'existe pas de G_TYPE_GSIZE. + * + * Or la documentation précise : + * + * typedef unsigned long gsize; + * + */ + + g_signal_new("value-changed", + G_TYPE_DISPLAY_OPTIONS, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GDisplayOptionsClass, value_changed), + NULL, NULL, + g_cclosure_user_marshal_VOID__ULONG_BOOLEAN, + G_TYPE_NONE, 2, G_TYPE_ULONG, G_TYPE_BOOLEAN); + +} + + +/****************************************************************************** +* * +* Paramètres : options = instance à initialiser. * +* * +* Description : Initialise une instance d'options pour le rendu des lignes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_display_options_init(GDisplayOptions *options) +{ + options->names = NULL; + options->values = NULL; + options->count = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : options = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_display_options_dispose(GDisplayOptions *options) +{ + G_OBJECT_CLASS(g_display_options_parent_class)->dispose(G_OBJECT(options)); + +} + + +/****************************************************************************** +* * +* Paramètres : options = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_display_options_finalize(GDisplayOptions *options) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < options->count; i++) + free(options->names[i]); + + if (options->names != NULL) + free(options->names); + + if (options->values != NULL) + free(options->values); + + G_OBJECT_CLASS(g_display_options_parent_class)->finalize(G_OBJECT(options)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un groupe d'options pour le rendu des lignes. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDisplayOptions *g_display_options_new(void) +{ + GDisplayOptions *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_DISPLAY_OPTIONS, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : template = modèle de groupe à copier. * +* * +* Description : Copie un groupe d'options pour le rendu des lignes. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDisplayOptions *g_display_options_dup(const GDisplayOptions *template) +{ + GDisplayOptions *result; /* Structure à retourner */ + size_t count; /* Nombre d'options à copier */ + size_t i; /* Boucle de parcours */ + + result = g_display_options_new(); + + count = g_display_options_count(template); + + for (i = 0; i < count; i++) + g_display_options_add(result, template->names[i], template->values[i]); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : options = options à consulter. * +* * +* Description : Dénombre la quantité d'options représentées. * +* * +* Retour : Quantité positive ou nulle. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_display_options_count(const GDisplayOptions *options) +{ + size_t result; /* Quantité à retourner */ + + result = options->count; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : options = options à compléter. * +* name = désignation humaine de la nouvelle option. * +* value = valeur initiale de l'option à ajouter. * +* * +* Description : Ajoute une nouvelle option à l'ensemble. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_display_options_add(GDisplayOptions *options, const char *name, bool value) +{ + options->count++; + + options->names = (char **)realloc(options->names, options->count * sizeof(char *)); + options->values = (bool *)realloc(options->values, options->count * sizeof(bool)); + + options->names[options->count - 1] = strdup(name); + options->values[options->count - 1] = value; + +} + + +/****************************************************************************** +* * +* Paramètres : options = options à consulter. * +* index = indice de l'option concernée. * +* * +* Description : Fournit la désignation d'une option donnée. * +* * +* Retour : Nom humainement lisible. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_display_options_get_name(const GDisplayOptions *options, size_t index) +{ + char *result; /* Désignation à retourner */ + + assert(index < options->count); + + if (index < options->count) + result = options->names[index]; + + else + result = NULL; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : options = options à consulter. * +* index = indice de l'option concernée. * +* * +* Description : Fournit la valeur d'une option donnée. * +* * +* Retour : Valeur attribuée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_display_options_get(const GDisplayOptions *options, size_t index) +{ + bool result; /* Valeur à renvoyer */ + + assert(index < options->count); + + if (index < options->count) + result = options->values[index]; + + else + result = false; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : options = options à mettre à jour. * +* index = indice de l'option concernée. * +* value = nouvelle valeur à intégrer. * +* * +* Description : Définit la valeur d'une option donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_display_options_set(GDisplayOptions *options, size_t index, bool value) +{ + bool changed; /* Note un changement */ + + assert(index < options->count); + + if (index < options->count) + { + changed = (options->values[index] != value); + options->values[index] = value; + } + + else + changed = false; + + if (changed) + g_signal_emit_by_name(options, "value-changed", index, value); + +} diff --git a/src/glibext/displayoptions.h b/src/glibext/displayoptions.h new file mode 100644 index 0000000..1a30e81 --- /dev/null +++ b/src/glibext/displayoptions.h @@ -0,0 +1,74 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gdisplayoptions.h - prototypes pour les options de rendus des lignes de code + * + * Copyright (C) 2018 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 . + */ + + +#ifndef _GLIBEXT_GDISPLAYOPTIONS_H +#define _GLIBEXT_GDISPLAYOPTIONS_H + + +#include +#include + + + +#define G_TYPE_DISPLAY_OPTIONS g_display_options_get_type() +#define G_DISPLAY_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DISPLAY_OPTIONS, GDisplayOptions)) +#define G_IS_DISPLAY_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DISPLAY_OPTIONS)) +#define G_DISPLAY_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DISPLAY_OPTIONS, GDisplayOptionsClass)) +#define G_IS_DISPLAY_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DISPLAY_OPTIONS)) +#define G_DISPLAY_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DISPLAY_OPTIONS, GDisplayOptionsClass)) + + +/* Options de représentation (instance) */ +typedef struct _GDisplayOptions GDisplayOptions; + +/* Options de représentation (classe) */ +typedef struct _GDisplayOptionsClass GDisplayOptionsClass; + + +/* Indique le type défini pour des options de représentation. */ +GType g_display_options_get_type(void); + +/* Crée un groupe d'options pour le rendu des lignes. */ +GDisplayOptions *g_display_options_new(void); + +/* Copie un groupe d'options pour le rendu des lignes. */ +GDisplayOptions *g_display_options_dup(const GDisplayOptions *); + +/* Dénombre la quantité d'options représentées. */ +size_t g_display_options_count(const GDisplayOptions *); + +/* Ajoute une nouvelle option à l'ensemble. */ +void g_display_options_add(GDisplayOptions *, const char *, bool); + +/* Fournit la désignation d'une option donnée. */ +const char *g_display_options_get_name(const GDisplayOptions *, size_t); + +/* Fournit la valeur d'une option donnée. */ +bool g_display_options_get(const GDisplayOptions *, size_t); + +/* Définit la valeur d'une option donnée. */ +void g_display_options_set(GDisplayOptions *, size_t, bool); + + + +#endif /* _GLIBEXT_GDISPLAYOPTIONS_H */ diff --git a/src/glibext/gdisplayoptions.c b/src/glibext/gdisplayoptions.c deleted file mode 100644 index a8f835b..0000000 --- a/src/glibext/gdisplayoptions.c +++ /dev/null @@ -1,383 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gdisplayoptions.h - options de rendus des lignes de code - * - * Copyright (C) 2018 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 . - */ - - -#include "gdisplayoptions.h" - - -#include -#include -#include - - -#include "chrysamarshal.h" - - - -/* Options de représentation (instance) */ -struct _GDisplayOptions -{ - GObject parent; /* A laisser en premier */ - - char **names; /* Désignations des options */ - bool *values; /* Valeurs des options */ - size_t count; /* Nombre de ces options */ - -}; - -/* Options de représentation (classe) */ -struct _GDisplayOptionsClass -{ - GObjectClass parent; /* A laisser en premier */ - - /* Signaux */ - - void (* value_changed) (const GDisplayOptions *, gsize, gboolean); - -}; - - -/* Initialise la classe des options pour le rendu des lignes. */ -static void g_display_options_class_init(GDisplayOptionsClass *); - -/* Initialise une instance d'options pour le rendu des lignes. */ -static void g_display_options_init(GDisplayOptions *); - -/* Supprime toutes les références externes. */ -static void g_display_options_dispose(GDisplayOptions *); - -/* Procède à la libération totale de la mémoire. */ -static void g_display_options_finalize(GDisplayOptions *); - - - -/* Indique le type défini pour une ligne de représentation. */ -G_DEFINE_TYPE(GDisplayOptions, g_display_options, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des options pour le rendu des lignes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_display_options_class_init(GDisplayOptionsClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_display_options_dispose; - object->finalize = (GObjectFinalizeFunc)g_display_options_finalize; - - /** - * Note : il n'existe pas de G_TYPE_GSIZE. - * - * Or la documentation précise : - * - * typedef unsigned long gsize; - * - */ - - g_signal_new("value-changed", - G_TYPE_DISPLAY_OPTIONS, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GDisplayOptionsClass, value_changed), - NULL, NULL, - g_cclosure_user_marshal_VOID__ULONG_BOOLEAN, - G_TYPE_NONE, 2, G_TYPE_ULONG, G_TYPE_BOOLEAN); - -} - - -/****************************************************************************** -* * -* Paramètres : options = instance à initialiser. * -* * -* Description : Initialise une instance d'options pour le rendu des lignes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_display_options_init(GDisplayOptions *options) -{ - options->names = NULL; - options->values = NULL; - options->count = 0; - -} - - -/****************************************************************************** -* * -* Paramètres : options = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_display_options_dispose(GDisplayOptions *options) -{ - G_OBJECT_CLASS(g_display_options_parent_class)->dispose(G_OBJECT(options)); - -} - - -/****************************************************************************** -* * -* Paramètres : options = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_display_options_finalize(GDisplayOptions *options) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < options->count; i++) - free(options->names[i]); - - if (options->names != NULL) - free(options->names); - - if (options->values != NULL) - free(options->values); - - G_OBJECT_CLASS(g_display_options_parent_class)->finalize(G_OBJECT(options)); - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée un groupe d'options pour le rendu des lignes. * -* * -* Retour : Adresse de la structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GDisplayOptions *g_display_options_new(void) -{ - GDisplayOptions *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_DISPLAY_OPTIONS, NULL); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : template = modèle de groupe à copier. * -* * -* Description : Copie un groupe d'options pour le rendu des lignes. * -* * -* Retour : Adresse de la structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GDisplayOptions *g_display_options_dup(const GDisplayOptions *template) -{ - GDisplayOptions *result; /* Structure à retourner */ - size_t count; /* Nombre d'options à copier */ - size_t i; /* Boucle de parcours */ - - result = g_display_options_new(); - - count = g_display_options_count(template); - - for (i = 0; i < count; i++) - g_display_options_add(result, template->names[i], template->values[i]); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : options = options à consulter. * -* * -* Description : Dénombre la quantité d'options représentées. * -* * -* Retour : Quantité positive ou nulle. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_display_options_count(const GDisplayOptions *options) -{ - size_t result; /* Quantité à retourner */ - - result = options->count; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : options = options à compléter. * -* name = désignation humaine de la nouvelle option. * -* value = valeur initiale de l'option à ajouter. * -* * -* Description : Ajoute une nouvelle option à l'ensemble. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_display_options_add(GDisplayOptions *options, const char *name, bool value) -{ - options->count++; - - options->names = (char **)realloc(options->names, options->count * sizeof(char *)); - options->values = (bool *)realloc(options->values, options->count * sizeof(bool)); - - options->names[options->count - 1] = strdup(name); - options->values[options->count - 1] = value; - -} - - -/****************************************************************************** -* * -* Paramètres : options = options à consulter. * -* index = indice de l'option concernée. * -* * -* Description : Fournit la désignation d'une option donnée. * -* * -* Retour : Nom humainement lisible. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_display_options_get_name(const GDisplayOptions *options, size_t index) -{ - char *result; /* Désignation à retourner */ - - assert(index < options->count); - - if (index < options->count) - result = options->names[index]; - - else - result = NULL; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : options = options à consulter. * -* index = indice de l'option concernée. * -* * -* Description : Fournit la valeur d'une option donnée. * -* * -* Retour : Valeur attribuée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_display_options_get(const GDisplayOptions *options, size_t index) -{ - bool result; /* Valeur à renvoyer */ - - assert(index < options->count); - - if (index < options->count) - result = options->values[index]; - - else - result = false; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : options = options à mettre à jour. * -* index = indice de l'option concernée. * -* value = nouvelle valeur à intégrer. * -* * -* Description : Définit la valeur d'une option donnée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_display_options_set(GDisplayOptions *options, size_t index, bool value) -{ - bool changed; /* Note un changement */ - - assert(index < options->count); - - if (index < options->count) - { - changed = (options->values[index] != value); - options->values[index] = value; - } - - else - changed = false; - - if (changed) - g_signal_emit_by_name(options, "value-changed", index, value); - -} diff --git a/src/glibext/gdisplayoptions.h b/src/glibext/gdisplayoptions.h deleted file mode 100644 index 1a30e81..0000000 --- a/src/glibext/gdisplayoptions.h +++ /dev/null @@ -1,74 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gdisplayoptions.h - prototypes pour les options de rendus des lignes de code - * - * Copyright (C) 2018 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 . - */ - - -#ifndef _GLIBEXT_GDISPLAYOPTIONS_H -#define _GLIBEXT_GDISPLAYOPTIONS_H - - -#include -#include - - - -#define G_TYPE_DISPLAY_OPTIONS g_display_options_get_type() -#define G_DISPLAY_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DISPLAY_OPTIONS, GDisplayOptions)) -#define G_IS_DISPLAY_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DISPLAY_OPTIONS)) -#define G_DISPLAY_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DISPLAY_OPTIONS, GDisplayOptionsClass)) -#define G_IS_DISPLAY_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DISPLAY_OPTIONS)) -#define G_DISPLAY_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DISPLAY_OPTIONS, GDisplayOptionsClass)) - - -/* Options de représentation (instance) */ -typedef struct _GDisplayOptions GDisplayOptions; - -/* Options de représentation (classe) */ -typedef struct _GDisplayOptionsClass GDisplayOptionsClass; - - -/* Indique le type défini pour des options de représentation. */ -GType g_display_options_get_type(void); - -/* Crée un groupe d'options pour le rendu des lignes. */ -GDisplayOptions *g_display_options_new(void); - -/* Copie un groupe d'options pour le rendu des lignes. */ -GDisplayOptions *g_display_options_dup(const GDisplayOptions *); - -/* Dénombre la quantité d'options représentées. */ -size_t g_display_options_count(const GDisplayOptions *); - -/* Ajoute une nouvelle option à l'ensemble. */ -void g_display_options_add(GDisplayOptions *, const char *, bool); - -/* Fournit la désignation d'une option donnée. */ -const char *g_display_options_get_name(const GDisplayOptions *, size_t); - -/* Fournit la valeur d'une option donnée. */ -bool g_display_options_get(const GDisplayOptions *, size_t); - -/* Définit la valeur d'une option donnée. */ -void g_display_options_set(GDisplayOptions *, size_t, bool); - - - -#endif /* _GLIBEXT_GDISPLAYOPTIONS_H */ diff --git a/src/glibext/linesegment.c b/src/glibext/linesegment.c deleted file mode 100644 index 192e030..0000000 --- a/src/glibext/linesegment.c +++ /dev/null @@ -1,1206 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * linesegment.c - concentration d'un fragment de caractères aux propriétés communes - * - * Copyright (C) 2016-2019 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 . - */ - - -#include "linesegment.h" - - -#include -#include -#include -#include -#include -#include - - -#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é */ - -}; - - -/* Conservation de toutes les créations partagées */ -static GHashTable *_segcnt_htable; -G_LOCK_DEFINE_STATIC(_segcnt_mutex); - - -/* Fournit l'empreinte d'un contenu pour segments. */ -static guint get_line_segment_hash(const line_segment *); - -/* Détermine si deux contenus pour segments sont identiques. */ -static bool is_line_segment_equal(const line_segment *, const line_segment *); - -/* 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 POUR UN FRAGMENT DE TEXTE */ -/* ---------------------------------------------------------------------------------- */ - - -#ifdef INCLUDE_GTK_SUPPORT - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Procède à l'initialisation des paramètres de rendu de texte. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_segment_rendering_parameters(void) -{ - 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 */ - - /* 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)]; - - surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); - *cr = cairo_create(surface); - cairo_surface_destroy(surface); - - 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; - - } - - /* Fond d'impression */ - - _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 - - - -/* ---------------------------------------------------------------------------------- */ -/* ISOLATION DE CONTENUS PARTAGEABLES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Initialise la table mémorisant les contenus pour segments. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool init_segment_content_hash_table(void) -{ - _segcnt_htable = g_hash_table_new_full((GHashFunc)get_line_segment_hash, - (GEqualFunc)is_line_segment_equal, - free, NULL); - - return (_segcnt_htable != NULL); - -} - - -/****************************************************************************** -* * -* 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); - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu pour segment à consulter. * -* * -* Description : Fournit l'empreinte d'un contenu pour segments. * -* * -* Retour : Empreinte de lu contenu représenté. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static guint get_line_segment_hash(const line_segment *content) -{ - return content->hash; - -} - - -/****************************************************************************** -* * -* Paramètres : content = premier contenu pour segment à analyser. * -* other = second contenu pour segment à analyser. * -* * -* Description : Détermine si deux contenus pour segments sont identiques. * -* * -* Retour : Bilan de la comparaison. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool is_line_segment_equal(const line_segment *content, const line_segment *other) -{ - bool result; /* Résultat à retourner */ - -#ifdef INCLUDE_GTK_SUPPORT - result = (content->pattern == other->pattern); -#else - result = (content->type == other->type); -#endif - - if (result) - result = (cmp_fnv_64a(content->hash, other->hash) == 0); - - if (result) - result = (strcmp(content->text, other->text) == 0); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = premier contenu pour segment à analyser. * -* other = second contenu pour segment à analyser. * -* * -* Description : Détermine si deux contenus pour segments sont identiques. * -* * -* Retour : Bilan de la comparaison. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static line_segment *get_shared_segment_content(const line_segment *content) -{ - line_segment *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); - - found = g_hash_table_lookup_extended(_segcnt_htable, content, (gpointer *)&result, NULL); - - if (!found) - { - allocated = sizeof(line_segment) + strlen(content->text) + 1; - - result = (line_segment *)malloc(allocated); - - memcpy(result, content, allocated); - - g_atomic_int_set(&result->ref_count, 1); - -#ifndef NDEBUG - created = g_hash_table_insert(_segcnt_htable, result, result); - assert(created); -#else - g_hash_table_insert(_segcnt_htable, result, result); -#endif - - } - - else - { - assert(result->ref_count < UINT_MAX); - - g_atomic_int_inc(&result->ref_count); - - } - - G_UNLOCK(_segcnt_mutex); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu pour segments à délaisser. * -* * -* Description : Abandonne un contenu pour segments. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void release_shared_segment_content(line_segment *content) -{ -#ifndef NDEBUG - gboolean deleted; /* Validation de suppression */ -#endif - - if (g_atomic_int_dec_and_test(&content->ref_count)) - { - G_LOCK(_segcnt_mutex); - -#ifndef NDEBUG - deleted = g_hash_table_remove(_segcnt_htable, content); - assert(deleted); -#else - g_hash_table_remove(_segcnt_htable, content); -#endif - - G_UNLOCK(_segcnt_mutex); - - } - -} - - - - -/* ---------------------------------------------------------------------------------- */ -/* NATURE DE BASE POUR UN FRAGMENT DE TEXTE */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : type = 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 : - * -* * -******************************************************************************/ - -line_segment *get_new_line_segment(RenderingTagType type, const char *text, size_t length) -{ - line_segment *result; /* Elément à retourner */ - char atmp[sizeof(line_segment) + 128]; /* Allocation static facile */ - line_segment *content; /* Contenu à mettre en place ? */ - - assert(length > 0); - - if (length < (sizeof(atmp) - sizeof(line_segment))) - content = (line_segment *)atmp; - else - content = (line_segment *)malloc(sizeof(line_segment) + length + 1); - -#ifdef INCLUDE_GTK_SUPPORT - content->pattern = &_seg_params.patterns[type]; -#else - content->type = type; -#endif - - content->hash = fnv_64a_hash(text); - - memcpy(content->text, text, length); - content->text[length] = '\0'; - - result = get_shared_segment_content(content); - - if (content != (line_segment *)atmp) - free(content); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à traiter. * -* * -* Description : Augmente le compteur de références d'un fragment de texte. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void ref_line_segment(line_segment *segment) -{ - g_atomic_int_inc(&segment->ref_count); - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à libérer de la mémoire. * -* * -* Description : Retire une utilisation à un fragment de texte. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void release_line_segment(line_segment *segment) -{ - release_shared_segment_content(segment); - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à consulter. * -* * -* Description : Indique le type de rendu associé à un segment de ligne. * -* * -* Retour : Identifiant de type de rendu. * -* * -* Remarques : - * -* * -******************************************************************************/ - -RenderingTagType get_line_segment_type(const line_segment *segment) -{ - RenderingTagType result; /* Résultat à renvoyer */ - -#ifdef INCLUDE_GTK_SUPPORT - result = (RenderingTagType)(segment->pattern - _seg_params.patterns); -#else - result = segment->type; -#endif - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à consulter. * -* markup = indique si le texte doit être décoré ou non. * -* * -* Description : Fournit le texte brut conservé dans le segment. * -* * -* Retour : Texte conservé en interne. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *get_line_segment_text(const line_segment *segment, bool markup) -{ -#ifndef INCLUDE_GTK_SUPPORT - - char *result; /* Description à renvoyer */ - - result = strdup(segment->text); - - return result; - -#else - - char *result; /* Description à renvoyer */ - char color[7]; /* Couleur hexadécimale */ - char *valid; - - /* Résolution du cas simple */ - if (!markup) - return strdup(segment->text); - - result = strdup("pattern->foreground.color.red * 255), - (unsigned char)(segment->pattern->foreground.color.green * 255), - (unsigned char)(segment->pattern->foreground.color.blue * 255)); - - result = stradd(result, color); - - result = stradd(result, "\""); - - /* Style */ - - result = stradd(result, "style=\""); - - switch (segment->pattern->slant) - { - case CAIRO_FONT_SLANT_NORMAL: - result = stradd(result, "normal"); - break; - - case CAIRO_FONT_SLANT_ITALIC: - result = stradd(result, "italic"); - break; - - case CAIRO_FONT_SLANT_OBLIQUE: - result = stradd(result, "oblique"); - break; - - } - - result = stradd(result, "\""); - - /* Epaisseur */ - - result = stradd(result, "weight=\""); - - switch (segment->pattern->weight) - { - case CAIRO_FONT_WEIGHT_NORMAL: - result = stradd(result, "normal"); - break; - - case CAIRO_FONT_WEIGHT_BOLD: - result = stradd(result, "bold"); - break; - - } - - result = stradd(result, "\""); - - /* Conclusion */ - - result = stradd(result, ">"); - - valid = strdup(segment->text); - valid = strrpl(valid, "&", "&"); - valid = strrpl(valid, "<", "<"); - - result = stradd(result, valid); - - free(valid); - - result = stradd(result, ""); - - return result; - -#endif - -} - - -#ifdef INCLUDE_GTK_SUPPORT - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à consulter. * -* * -* Description : Fournit la quantité de pixels requise pour l'impression. * -* * -* Retour : Largeur requise par la colonne, en pixel. * -* * -* Remarques : - * -* * -******************************************************************************/ - -gint get_line_segment_width(const line_segment *segment) -{ - gint result; /* Largeur à retourner */ - cairo_font_slant_t slant; /* Style d'impression */ - cairo_font_weight_t weight; /* Poids de la police */ - size_t length; /* Taille du texte représenté */ - - slant = segment->pattern->slant; - weight = segment->pattern->weight; - - length = strlen(segment->text); - - if (length == 1 && segment->text[0] == '\t') - length = 2; - - result = _seg_params.x_advances[CAIRO_FONT_INDEX(slant, weight)] * length; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à consulter. * -* x = position horizontale au niveau du segment. * -* * -* Description : Fournit la position idéale pour un marqueur. * -* * -* Retour : Position dans le segment donné. * -* * -* Remarques : - * -* * -******************************************************************************/ - -gint get_caret_position_from_line_segment(const line_segment *segment, gint x) -{ - gint result; /* Position à retourner */ - gint width; /* Largeur du segment */ - gint char_width; /* Largeur de police fixe */ - - width = get_line_segment_width(segment); - - if (x <= 0) - result = 0; - - else if (x >= width) - result = width; - - else - { - char_width = width / strlen(segment->text); - - result = (x / char_width) * char_width; - if ((x % char_width) > (char_width / 2)) - result += char_width; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à manipuler. * -* x = position du curseur à faire évoluer. [OUT] * -* ctrl = indique la demande d'un parcours rapide. * -* dir = direction du parcours. * -* * -* Description : Déplace le curseur au sein d'un segment de tampon. * -* * -* Retour : true si un déplacement a été effectué, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool move_caret_on_line_segment(const line_segment *segment, gint *x, bool ctrl, GdkScrollDirection dir) -{ - bool result; /* Bilan d'opération à renvoyer*/ - gint width; /* Largeur du segment */ - gint char_width; /* Largeur de police fixe */ - - result = false; - - width = get_line_segment_width(segment); - char_width = width / strlen(segment->text); - - if (dir == GDK_SCROLL_LEFT) - { - if (*x > width) *x = width + char_width; - - if (*x == 0) goto gbsmc_done; - - if (ctrl) *x = 0; - else *x = MAX(0, *x - char_width); - - result = true; - - } - - else if (dir == GDK_SCROLL_RIGHT) - { - if (*x == width) goto gbsmc_done; - - if (ctrl) *x = width; - else *x = MIN(width, *x + char_width); - - result = true; - - } - - gbsmc_done: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = 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. * -* list = liste de contenus à mettre en évidence. * -* * -* Description : Imprime le fragment de texte représenté. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void draw_line_segment(const line_segment *segment, cairo_t *cr, gint *x, gint y, const segcnt_list *list) -{ - bool selected; /* Marquer une sélection ? */ - gint width; /* Largeur du segment */ - cairo_operator_t old; /* Sauvegarde avant changement */ - const rendering_color_t *used_fg; /* Couleur d'impression utile */ - - selected = selection_list_has_segment_content(list, segment); - - width = get_line_segment_width(segment); - - if (segment->text[0] == '\t' && segment->text[1] == '\0') - goto small_sep; - - /* Fond du texte */ - if (selected) - { - cairo_set_source_rgba(cr, - _seg_params.selection_bg.color.red, - _seg_params.selection_bg.color.green, - _seg_params.selection_bg.color.blue, - _seg_params.selection_bg.color.alpha); - - cairo_rectangle(cr, *x, y, width, 17); - - old = cairo_get_operator(cr); - cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); - cairo_fill(cr); - cairo_set_operator(cr, old); - - } - - /* Couleur d'impression */ - - if (selected) - used_fg = &segment->pattern->inverted; - else - used_fg = &segment->pattern->foreground; - - if (used_fg->has_color) - cairo_set_source_rgba(cr, - used_fg->color.red, - used_fg->color.green, - used_fg->color.blue, - used_fg->color.alpha); - else - cairo_set_source_rgb(cr, 0, 0, 0); - - /* Impression du texte */ - - cairo_select_font_face(cr, "mono", segment->pattern->slant, segment->pattern->weight); - cairo_set_font_size(cr, 13); - - cairo_move_to(cr, *x, y + 17 - 3); /* 3 = font extents.descent */ - - cairo_show_text(cr, segment->text); - - small_sep: - - *x += width; - -} - - -/****************************************************************************** -* * -* Paramètres : ctx = éléments à disposition pour l'exportation. * -* type = type d'exportation attendue. * -* * -* Description : Exporte tous les styles utilisés par des segments. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void export_line_segment_style(buffer_export_context *ctx, BufferExportType type) -{ - size_t i; /* Boucle de parcours */ - const rendering_pattern_t *pattern; /* Modèle à transcrire */ - - for (i = 0; i < RTT_COUNT; i++) - { - pattern = &_seg_params.patterns[i]; - - switch (type) - { - case BET_HTML: - - dprintf(ctx->fd, ".%s {\n", _segment_names[i]); - - if (pattern->foreground.has_color) - dprintf(ctx->fd, "\tcolor: #%02hhx%02hhx%02hhx;\n", - (unsigned char)(pattern->foreground.color.red * 255), - (unsigned char)(pattern->foreground.color.green * 255), - (unsigned char)(pattern->foreground.color.blue * 255)); - - switch (pattern->slant) - { - case CAIRO_FONT_SLANT_ITALIC: - dprintf(ctx->fd, "\tfont-style: italic;\n"); - break; - case CAIRO_FONT_SLANT_OBLIQUE: - dprintf(ctx->fd, "\tfont-style: oblique;\n"); - break; - default: - dprintf(ctx->fd, "\tfont-style: normal;\n"); - break; - } - - switch (pattern->weight) - { - case CAIRO_FONT_WEIGHT_BOLD: - dprintf(ctx->fd, "\tfont-weight: bold;\n"); - break; - default: - dprintf(ctx->fd, "\tfont-weight: normal;\n"); - break; - } - - dprintf(ctx->fd, "}\n"); - - break; - - default: - break; - - } - - } - -} - - -#endif - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à manipuler. * -* ctx = éléments à disposition pour l'exportation. * -* type = type d'exportation attendue. * -* * -* Description : Exporte le fragment de texte représenté. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void export_line_segment(const line_segment *segment, buffer_export_context *ctx, BufferExportType type) -{ - RenderingTagType index; /* Indice du modèle de rendu */ - - switch (type) - { - case BET_HTML: - index = get_line_segment_type(segment); - dprintf(ctx->fd, "", _segment_names[index]); - break; - default: - break; - } - - dprintf(ctx->fd, "%s", segment->text); - - switch (type) - { - case BET_HTML: - dprintf(ctx->fd, ""); - break; - default: - break; - } - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* GESTION OPTIMALE D'UNE LISTE DE CONTENUS */ -/* ---------------------------------------------------------------------------------- */ - - -#ifdef INCLUDE_GTK_SUPPORT - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Initilise une liste de contenus de segments. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -segcnt_list *init_segment_content_list(void) -{ - segcnt_list *result; /* Structure à retourner */ - - result = malloc(sizeof(segcnt_list)); - - result->hashes = NULL; - result->count = 0; - - result->ref_count = 1; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : list = ensemble de références de contenus à traiter. * -* * -* Description : Libère la mémoire occupée par une liste de contenus. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void exit_segment_content_list(segcnt_list *list) -{ - assert(list->ref_count == 0); - - reset_segment_content_list(list); - - free(list); - -} - - -/****************************************************************************** -* * -* Paramètres : list = ensemble de références de contenus à traiter. * -* * -* Description : Incrémente le nombre d'utilisation de la liste de contenus. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void ref_segment_content_list(segcnt_list *list) -{ - assert(list->ref_count > 0); - - list->ref_count++; - -} - - -/****************************************************************************** -* * -* Paramètres : list = ensemble de références de contenus à traiter. * -* * -* Description : Décrémente le nombre d'utilisation de la liste de contenus. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unref_segment_content_list(segcnt_list *list) -{ - assert(list->ref_count > 0); - - list->ref_count--; - -} - - -/****************************************************************************** -* * -* Paramètres : list = ensemble de références de contenus à manipuler. * -* * -* Description : Vide, si besoin est, une liste de contenus de segments. * -* * -* Retour : true si des éléments ont été purgés, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool reset_segment_content_list(segcnt_list *list) -{ - bool result; /* Bilan d'action à renvoyer */ - - result = (list->count > 0); - - if (list->hashes != NULL) - { - free(list->hashes); - list->hashes = NULL; - } - - list->count = 0; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : list = ensemble de références de contenus à manipuler. * -* segment = fragment de texte à conservr. * -* * -* Description : Marque le contenu d'un segment comme remarquable. * -* * -* Retour : true si la liste a été complétée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool add_segment_content_to_selection_list(segcnt_list *list, const line_segment *segment) -{ - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - - static const char white_list[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - result = false; - - for (i = 0; i < (sizeof(white_list) - 1) && !result; i++) - result = (strchr(segment->text, white_list[i]) != NULL); - - if (result) - { - list->hashes = realloc(list->hashes, ++list->count * sizeof(fnv64_t)); - - list->hashes[list->count - 1] = segment->hash; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : list = ensemble de références de contenus à consulter. * -* segment = fragment de texte à comparer. * -* * -* Description : Indique si le contenu d'un segment est notable ou non. * -* * -* Retour : true si le segment a un contenu présent dans la sélection. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool selection_list_has_segment_content(const segcnt_list *list, const line_segment *segment) -{ - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - - result = false; - - for (i = 0; i < list->count && !result; i++) - result = (cmp_fnv_64a(list->hashes[i], segment->hash) == 0); - - return result; - -} - - -#endif diff --git a/src/glibext/linesegment.h b/src/glibext/linesegment.h deleted file mode 100644 index 4859fbb..0000000 --- a/src/glibext/linesegment.h +++ /dev/null @@ -1,227 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * linesegment.h - prototypes pour la concentration d'un fragment de caractères aux propriétés communes - * - * Copyright (C) 2016-2019 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 . - */ - - -#ifndef _GLIBEXT_LINESEGMENT_H -#define _GLIBEXT_LINESEGMENT_H - - -#include -#include -#ifdef INCLUDE_GTK_SUPPORT -# include -# include -#endif - - -#ifdef INCLUDE_GTK_SUPPORT - -/* Liste identifiant un ensemble de segments */ -typedef struct _segcnt_list segcnt_list; - -#endif - - - -/* ------------------------ NATURE POUR UN FRAGMENT DE TEXTE ------------------------ */ - - -#ifdef INCLUDE_GTK_SUPPORT - -/* Procède à l'initialisation des paramètres de rendu de texte. */ -bool load_segment_rendering_parameters(void); - -#endif - - - -/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ - - -/* Fragment de caractères aux propriétés potentiellement partagées */ -typedef struct _line_segment line_segment; - - -/* 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); - - - -/* -------------------- NATURE DE BASE POUR UN FRAGMENT DE TEXTE -------------------- */ - - -/* Types de partie de rendu */ -typedef enum _RenderingTagType -{ - RTT_NONE, /* Espace ou tabulation */ - - RTT_RAW, /* Contenu brut */ - RTT_RAW_FULL, /* Contenu brut et complet */ - RTT_RAW_NULL, /* Contenu brut et nul */ - RTT_PRINTABLE, /* Caractère imprimable */ - RTT_NOT_PRINTABLE, /* Caractère non imprimable */ - - RTT_COMMENT, /* Commentaire */ - RTT_INDICATION, /* Aide à la lecture */ - - RTT_PHYS_ADDR_PAD, /* Position physique (début) */ - RTT_PHYS_ADDR, /* Position physique */ - RTT_VIRT_ADDR_PAD, /* Adresse virtuelle (début) */ - RTT_VIRT_ADDR, /* Adresse virtuelle */ - RTT_RAW_CODE, /* Code binaire brut */ - RTT_RAW_CODE_NULL, /* Code binaire brut et nul */ - - RTT_LABEL, /* Etiquette sur une adresse */ - - RTT_INSTRUCTION, /* Code binaire brut */ - - RTT_IMMEDIATE, /* Valeur immédiate */ - - RTT_REGISTER, /* Registre */ - - RTT_PUNCT, /* Signes de ponctuation */ - RTT_HOOK, /* Crochets '[' et ']' */ - RTT_SIGNS, /* Signes '+', '-' et '*' */ - RTT_LTGT, /* Caractères '<' et '>' */ - - RTT_SECTION, /* Identifiant de section */ - RTT_SEGMENT, /* Indication de segment */ - RTT_STRING, /* Chaîne de caractères avec " */ - - RTT_VAR_NAME, /* Nom de variable */ - - RTT_KEY_WORD, /* Mot clef de langage */ - - RTT_ERROR, /* Erreur "interne" */ - - RTT_COUNT - -} RenderingTagType; - - -/* Crée un nouveau fragment de texte avec des propriétés. */ -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 *); - -/* Retire une utilisation à un fragment de texte. */ -void release_line_segment(line_segment *); - -/* Indique le type de rendu associé à un segment de ligne. */ -RenderingTagType get_line_segment_type(const line_segment *); - -/* Fournit le texte brut conservé dans le segment. */ -char *get_line_segment_text(const line_segment *, bool); - -#ifdef INCLUDE_GTK_SUPPORT - -/* Fournit la quantité de pixels requise pour l'impression. */ -gint get_line_segment_width(const line_segment *); - -/* Fournit la position idéale pour un marqueur. */ -gint get_caret_position_from_line_segment(const line_segment *, gint); - -/* Déplace le curseur au sein d'un segment de tampon. */ -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 *); - -#endif - - -/* Types d'exportation */ -typedef enum _BufferExportType -{ - BET_TEXT, /* Exportation en texte brut */ - BET_HTML, /* Exportation en HTML */ - - BET_COUNT - -} BufferExportType; - -/* Elements sur lesquels une exportation peut s'appuyer */ -typedef struct _buffer_export_context -{ - int fd; /* Flux ouvert en écriture */ - - union - { - /* BET_TEXT */ - char *sep; /* Séparation entre colonnes */ - - /* BET_HTML */ - struct - { - char *font_name; /* Police d'impression */ - char *bg_color; /* Fond du tableau HTML */ - - }; - - }; - -} buffer_export_context; - -#ifdef INCLUDE_GTK_SUPPORT - -/* Exporte tous les styles utilisés par des segments. */ -void export_line_segment_style(buffer_export_context *, BufferExportType); - -#endif - -/* Exporte le fragment de texte représenté. */ -void export_line_segment(const line_segment *, buffer_export_context *, BufferExportType); - - - -/* -------------------- GESTION OPTIMALE D'UNE LISTE DE CONTENUS -------------------- */ - - -#ifdef INCLUDE_GTK_SUPPORT - -/* Initilise une liste de contenus de segments. */ -segcnt_list *init_segment_content_list(void); - -/* Libère la mémoire occupée par une liste de contenus. */ -void exit_segment_content_list(segcnt_list *); - -/* Incrémente le nombre d'utilisation de la liste de contenus. */ -void ref_segment_content_list(segcnt_list *); - -/* Décrémente le nombre d'utilisation de la liste de contenus. */ -void unref_segment_content_list(segcnt_list *); - -/* Vide, si besoin est, une liste de contenus de segments. */ -bool reset_segment_content_list(segcnt_list *); - -/* Marque le contenu d'un segment comme remarquable. */ -bool add_segment_content_to_selection_list(segcnt_list *, const line_segment *); - -#endif - - - -#endif /* _GLIBEXT_LINESEGMENT_H */ diff --git a/src/glibext/linetoken.c b/src/glibext/linetoken.c new file mode 100644 index 0000000..192e030 --- /dev/null +++ b/src/glibext/linetoken.c @@ -0,0 +1,1206 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * linesegment.c - concentration d'un fragment de caractères aux propriétés communes + * + * Copyright (C) 2016-2019 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 . + */ + + +#include "linesegment.h" + + +#include +#include +#include +#include +#include +#include + + +#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é */ + +}; + + +/* Conservation de toutes les créations partagées */ +static GHashTable *_segcnt_htable; +G_LOCK_DEFINE_STATIC(_segcnt_mutex); + + +/* Fournit l'empreinte d'un contenu pour segments. */ +static guint get_line_segment_hash(const line_segment *); + +/* Détermine si deux contenus pour segments sont identiques. */ +static bool is_line_segment_equal(const line_segment *, const line_segment *); + +/* 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 POUR UN FRAGMENT DE TEXTE */ +/* ---------------------------------------------------------------------------------- */ + + +#ifdef INCLUDE_GTK_SUPPORT + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Procède à l'initialisation des paramètres de rendu de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_segment_rendering_parameters(void) +{ + 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 */ + + /* 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)]; + + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); + *cr = cairo_create(surface); + cairo_surface_destroy(surface); + + 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; + + } + + /* Fond d'impression */ + + _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 + + + +/* ---------------------------------------------------------------------------------- */ +/* ISOLATION DE CONTENUS PARTAGEABLES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Initialise la table mémorisant les contenus pour segments. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool init_segment_content_hash_table(void) +{ + _segcnt_htable = g_hash_table_new_full((GHashFunc)get_line_segment_hash, + (GEqualFunc)is_line_segment_equal, + free, NULL); + + return (_segcnt_htable != NULL); + +} + + +/****************************************************************************** +* * +* 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); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu pour segment à consulter. * +* * +* Description : Fournit l'empreinte d'un contenu pour segments. * +* * +* Retour : Empreinte de lu contenu représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static guint get_line_segment_hash(const line_segment *content) +{ + return content->hash; + +} + + +/****************************************************************************** +* * +* Paramètres : content = premier contenu pour segment à analyser. * +* other = second contenu pour segment à analyser. * +* * +* Description : Détermine si deux contenus pour segments sont identiques. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool is_line_segment_equal(const line_segment *content, const line_segment *other) +{ + bool result; /* Résultat à retourner */ + +#ifdef INCLUDE_GTK_SUPPORT + result = (content->pattern == other->pattern); +#else + result = (content->type == other->type); +#endif + + if (result) + result = (cmp_fnv_64a(content->hash, other->hash) == 0); + + if (result) + result = (strcmp(content->text, other->text) == 0); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = premier contenu pour segment à analyser. * +* other = second contenu pour segment à analyser. * +* * +* Description : Détermine si deux contenus pour segments sont identiques. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static line_segment *get_shared_segment_content(const line_segment *content) +{ + line_segment *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); + + found = g_hash_table_lookup_extended(_segcnt_htable, content, (gpointer *)&result, NULL); + + if (!found) + { + allocated = sizeof(line_segment) + strlen(content->text) + 1; + + result = (line_segment *)malloc(allocated); + + memcpy(result, content, allocated); + + g_atomic_int_set(&result->ref_count, 1); + +#ifndef NDEBUG + created = g_hash_table_insert(_segcnt_htable, result, result); + assert(created); +#else + g_hash_table_insert(_segcnt_htable, result, result); +#endif + + } + + else + { + assert(result->ref_count < UINT_MAX); + + g_atomic_int_inc(&result->ref_count); + + } + + G_UNLOCK(_segcnt_mutex); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu pour segments à délaisser. * +* * +* Description : Abandonne un contenu pour segments. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void release_shared_segment_content(line_segment *content) +{ +#ifndef NDEBUG + gboolean deleted; /* Validation de suppression */ +#endif + + if (g_atomic_int_dec_and_test(&content->ref_count)) + { + G_LOCK(_segcnt_mutex); + +#ifndef NDEBUG + deleted = g_hash_table_remove(_segcnt_htable, content); + assert(deleted); +#else + g_hash_table_remove(_segcnt_htable, content); +#endif + + G_UNLOCK(_segcnt_mutex); + + } + +} + + + + +/* ---------------------------------------------------------------------------------- */ +/* NATURE DE BASE POUR UN FRAGMENT DE TEXTE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : type = 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 : - * +* * +******************************************************************************/ + +line_segment *get_new_line_segment(RenderingTagType type, const char *text, size_t length) +{ + line_segment *result; /* Elément à retourner */ + char atmp[sizeof(line_segment) + 128]; /* Allocation static facile */ + line_segment *content; /* Contenu à mettre en place ? */ + + assert(length > 0); + + if (length < (sizeof(atmp) - sizeof(line_segment))) + content = (line_segment *)atmp; + else + content = (line_segment *)malloc(sizeof(line_segment) + length + 1); + +#ifdef INCLUDE_GTK_SUPPORT + content->pattern = &_seg_params.patterns[type]; +#else + content->type = type; +#endif + + content->hash = fnv_64a_hash(text); + + memcpy(content->text, text, length); + content->text[length] = '\0'; + + result = get_shared_segment_content(content); + + if (content != (line_segment *)atmp) + free(content); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à traiter. * +* * +* Description : Augmente le compteur de références d'un fragment de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void ref_line_segment(line_segment *segment) +{ + g_atomic_int_inc(&segment->ref_count); + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à libérer de la mémoire. * +* * +* Description : Retire une utilisation à un fragment de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void release_line_segment(line_segment *segment) +{ + release_shared_segment_content(segment); + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à consulter. * +* * +* Description : Indique le type de rendu associé à un segment de ligne. * +* * +* Retour : Identifiant de type de rendu. * +* * +* Remarques : - * +* * +******************************************************************************/ + +RenderingTagType get_line_segment_type(const line_segment *segment) +{ + RenderingTagType result; /* Résultat à renvoyer */ + +#ifdef INCLUDE_GTK_SUPPORT + result = (RenderingTagType)(segment->pattern - _seg_params.patterns); +#else + result = segment->type; +#endif + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à consulter. * +* markup = indique si le texte doit être décoré ou non. * +* * +* Description : Fournit le texte brut conservé dans le segment. * +* * +* Retour : Texte conservé en interne. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *get_line_segment_text(const line_segment *segment, bool markup) +{ +#ifndef INCLUDE_GTK_SUPPORT + + char *result; /* Description à renvoyer */ + + result = strdup(segment->text); + + return result; + +#else + + char *result; /* Description à renvoyer */ + char color[7]; /* Couleur hexadécimale */ + char *valid; + + /* Résolution du cas simple */ + if (!markup) + return strdup(segment->text); + + result = strdup("pattern->foreground.color.red * 255), + (unsigned char)(segment->pattern->foreground.color.green * 255), + (unsigned char)(segment->pattern->foreground.color.blue * 255)); + + result = stradd(result, color); + + result = stradd(result, "\""); + + /* Style */ + + result = stradd(result, "style=\""); + + switch (segment->pattern->slant) + { + case CAIRO_FONT_SLANT_NORMAL: + result = stradd(result, "normal"); + break; + + case CAIRO_FONT_SLANT_ITALIC: + result = stradd(result, "italic"); + break; + + case CAIRO_FONT_SLANT_OBLIQUE: + result = stradd(result, "oblique"); + break; + + } + + result = stradd(result, "\""); + + /* Epaisseur */ + + result = stradd(result, "weight=\""); + + switch (segment->pattern->weight) + { + case CAIRO_FONT_WEIGHT_NORMAL: + result = stradd(result, "normal"); + break; + + case CAIRO_FONT_WEIGHT_BOLD: + result = stradd(result, "bold"); + break; + + } + + result = stradd(result, "\""); + + /* Conclusion */ + + result = stradd(result, ">"); + + valid = strdup(segment->text); + valid = strrpl(valid, "&", "&"); + valid = strrpl(valid, "<", "<"); + + result = stradd(result, valid); + + free(valid); + + result = stradd(result, ""); + + return result; + +#endif + +} + + +#ifdef INCLUDE_GTK_SUPPORT + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à consulter. * +* * +* Description : Fournit la quantité de pixels requise pour l'impression. * +* * +* Retour : Largeur requise par la colonne, en pixel. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gint get_line_segment_width(const line_segment *segment) +{ + gint result; /* Largeur à retourner */ + cairo_font_slant_t slant; /* Style d'impression */ + cairo_font_weight_t weight; /* Poids de la police */ + size_t length; /* Taille du texte représenté */ + + slant = segment->pattern->slant; + weight = segment->pattern->weight; + + length = strlen(segment->text); + + if (length == 1 && segment->text[0] == '\t') + length = 2; + + result = _seg_params.x_advances[CAIRO_FONT_INDEX(slant, weight)] * length; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à consulter. * +* x = position horizontale au niveau du segment. * +* * +* Description : Fournit la position idéale pour un marqueur. * +* * +* Retour : Position dans le segment donné. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gint get_caret_position_from_line_segment(const line_segment *segment, gint x) +{ + gint result; /* Position à retourner */ + gint width; /* Largeur du segment */ + gint char_width; /* Largeur de police fixe */ + + width = get_line_segment_width(segment); + + if (x <= 0) + result = 0; + + else if (x >= width) + result = width; + + else + { + char_width = width / strlen(segment->text); + + result = (x / char_width) * char_width; + if ((x % char_width) > (char_width / 2)) + result += char_width; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à manipuler. * +* x = position du curseur à faire évoluer. [OUT] * +* ctrl = indique la demande d'un parcours rapide. * +* dir = direction du parcours. * +* * +* Description : Déplace le curseur au sein d'un segment de tampon. * +* * +* Retour : true si un déplacement a été effectué, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool move_caret_on_line_segment(const line_segment *segment, gint *x, bool ctrl, GdkScrollDirection dir) +{ + bool result; /* Bilan d'opération à renvoyer*/ + gint width; /* Largeur du segment */ + gint char_width; /* Largeur de police fixe */ + + result = false; + + width = get_line_segment_width(segment); + char_width = width / strlen(segment->text); + + if (dir == GDK_SCROLL_LEFT) + { + if (*x > width) *x = width + char_width; + + if (*x == 0) goto gbsmc_done; + + if (ctrl) *x = 0; + else *x = MAX(0, *x - char_width); + + result = true; + + } + + else if (dir == GDK_SCROLL_RIGHT) + { + if (*x == width) goto gbsmc_done; + + if (ctrl) *x = width; + else *x = MIN(width, *x + char_width); + + result = true; + + } + + gbsmc_done: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = 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. * +* list = liste de contenus à mettre en évidence. * +* * +* Description : Imprime le fragment de texte représenté. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void draw_line_segment(const line_segment *segment, cairo_t *cr, gint *x, gint y, const segcnt_list *list) +{ + bool selected; /* Marquer une sélection ? */ + gint width; /* Largeur du segment */ + cairo_operator_t old; /* Sauvegarde avant changement */ + const rendering_color_t *used_fg; /* Couleur d'impression utile */ + + selected = selection_list_has_segment_content(list, segment); + + width = get_line_segment_width(segment); + + if (segment->text[0] == '\t' && segment->text[1] == '\0') + goto small_sep; + + /* Fond du texte */ + if (selected) + { + cairo_set_source_rgba(cr, + _seg_params.selection_bg.color.red, + _seg_params.selection_bg.color.green, + _seg_params.selection_bg.color.blue, + _seg_params.selection_bg.color.alpha); + + cairo_rectangle(cr, *x, y, width, 17); + + old = cairo_get_operator(cr); + cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); + cairo_fill(cr); + cairo_set_operator(cr, old); + + } + + /* Couleur d'impression */ + + if (selected) + used_fg = &segment->pattern->inverted; + else + used_fg = &segment->pattern->foreground; + + if (used_fg->has_color) + cairo_set_source_rgba(cr, + used_fg->color.red, + used_fg->color.green, + used_fg->color.blue, + used_fg->color.alpha); + else + cairo_set_source_rgb(cr, 0, 0, 0); + + /* Impression du texte */ + + cairo_select_font_face(cr, "mono", segment->pattern->slant, segment->pattern->weight); + cairo_set_font_size(cr, 13); + + cairo_move_to(cr, *x, y + 17 - 3); /* 3 = font extents.descent */ + + cairo_show_text(cr, segment->text); + + small_sep: + + *x += width; + +} + + +/****************************************************************************** +* * +* Paramètres : ctx = éléments à disposition pour l'exportation. * +* type = type d'exportation attendue. * +* * +* Description : Exporte tous les styles utilisés par des segments. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void export_line_segment_style(buffer_export_context *ctx, BufferExportType type) +{ + size_t i; /* Boucle de parcours */ + const rendering_pattern_t *pattern; /* Modèle à transcrire */ + + for (i = 0; i < RTT_COUNT; i++) + { + pattern = &_seg_params.patterns[i]; + + switch (type) + { + case BET_HTML: + + dprintf(ctx->fd, ".%s {\n", _segment_names[i]); + + if (pattern->foreground.has_color) + dprintf(ctx->fd, "\tcolor: #%02hhx%02hhx%02hhx;\n", + (unsigned char)(pattern->foreground.color.red * 255), + (unsigned char)(pattern->foreground.color.green * 255), + (unsigned char)(pattern->foreground.color.blue * 255)); + + switch (pattern->slant) + { + case CAIRO_FONT_SLANT_ITALIC: + dprintf(ctx->fd, "\tfont-style: italic;\n"); + break; + case CAIRO_FONT_SLANT_OBLIQUE: + dprintf(ctx->fd, "\tfont-style: oblique;\n"); + break; + default: + dprintf(ctx->fd, "\tfont-style: normal;\n"); + break; + } + + switch (pattern->weight) + { + case CAIRO_FONT_WEIGHT_BOLD: + dprintf(ctx->fd, "\tfont-weight: bold;\n"); + break; + default: + dprintf(ctx->fd, "\tfont-weight: normal;\n"); + break; + } + + dprintf(ctx->fd, "}\n"); + + break; + + default: + break; + + } + + } + +} + + +#endif + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à manipuler. * +* ctx = éléments à disposition pour l'exportation. * +* type = type d'exportation attendue. * +* * +* Description : Exporte le fragment de texte représenté. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void export_line_segment(const line_segment *segment, buffer_export_context *ctx, BufferExportType type) +{ + RenderingTagType index; /* Indice du modèle de rendu */ + + switch (type) + { + case BET_HTML: + index = get_line_segment_type(segment); + dprintf(ctx->fd, "", _segment_names[index]); + break; + default: + break; + } + + dprintf(ctx->fd, "%s", segment->text); + + switch (type) + { + case BET_HTML: + dprintf(ctx->fd, ""); + break; + default: + break; + } + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION OPTIMALE D'UNE LISTE DE CONTENUS */ +/* ---------------------------------------------------------------------------------- */ + + +#ifdef INCLUDE_GTK_SUPPORT + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Initilise une liste de contenus de segments. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +segcnt_list *init_segment_content_list(void) +{ + segcnt_list *result; /* Structure à retourner */ + + result = malloc(sizeof(segcnt_list)); + + result->hashes = NULL; + result->count = 0; + + result->ref_count = 1; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de références de contenus à traiter. * +* * +* Description : Libère la mémoire occupée par une liste de contenus. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void exit_segment_content_list(segcnt_list *list) +{ + assert(list->ref_count == 0); + + reset_segment_content_list(list); + + free(list); + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de références de contenus à traiter. * +* * +* Description : Incrémente le nombre d'utilisation de la liste de contenus. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void ref_segment_content_list(segcnt_list *list) +{ + assert(list->ref_count > 0); + + list->ref_count++; + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de références de contenus à traiter. * +* * +* Description : Décrémente le nombre d'utilisation de la liste de contenus. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unref_segment_content_list(segcnt_list *list) +{ + assert(list->ref_count > 0); + + list->ref_count--; + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de références de contenus à manipuler. * +* * +* Description : Vide, si besoin est, une liste de contenus de segments. * +* * +* Retour : true si des éléments ont été purgés, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool reset_segment_content_list(segcnt_list *list) +{ + bool result; /* Bilan d'action à renvoyer */ + + result = (list->count > 0); + + if (list->hashes != NULL) + { + free(list->hashes); + list->hashes = NULL; + } + + list->count = 0; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de références de contenus à manipuler. * +* segment = fragment de texte à conservr. * +* * +* Description : Marque le contenu d'un segment comme remarquable. * +* * +* Retour : true si la liste a été complétée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_segment_content_to_selection_list(segcnt_list *list, const line_segment *segment) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + static const char white_list[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + result = false; + + for (i = 0; i < (sizeof(white_list) - 1) && !result; i++) + result = (strchr(segment->text, white_list[i]) != NULL); + + if (result) + { + list->hashes = realloc(list->hashes, ++list->count * sizeof(fnv64_t)); + + list->hashes[list->count - 1] = segment->hash; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de références de contenus à consulter. * +* segment = fragment de texte à comparer. * +* * +* Description : Indique si le contenu d'un segment est notable ou non. * +* * +* Retour : true si le segment a un contenu présent dans la sélection. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool selection_list_has_segment_content(const segcnt_list *list, const line_segment *segment) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + result = false; + + for (i = 0; i < list->count && !result; i++) + result = (cmp_fnv_64a(list->hashes[i], segment->hash) == 0); + + return result; + +} + + +#endif diff --git a/src/glibext/linetoken.h b/src/glibext/linetoken.h new file mode 100644 index 0000000..4859fbb --- /dev/null +++ b/src/glibext/linetoken.h @@ -0,0 +1,227 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * linesegment.h - prototypes pour la concentration d'un fragment de caractères aux propriétés communes + * + * Copyright (C) 2016-2019 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 . + */ + + +#ifndef _GLIBEXT_LINESEGMENT_H +#define _GLIBEXT_LINESEGMENT_H + + +#include +#include +#ifdef INCLUDE_GTK_SUPPORT +# include +# include +#endif + + +#ifdef INCLUDE_GTK_SUPPORT + +/* Liste identifiant un ensemble de segments */ +typedef struct _segcnt_list segcnt_list; + +#endif + + + +/* ------------------------ NATURE POUR UN FRAGMENT DE TEXTE ------------------------ */ + + +#ifdef INCLUDE_GTK_SUPPORT + +/* Procède à l'initialisation des paramètres de rendu de texte. */ +bool load_segment_rendering_parameters(void); + +#endif + + + +/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ + + +/* Fragment de caractères aux propriétés potentiellement partagées */ +typedef struct _line_segment line_segment; + + +/* 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); + + + +/* -------------------- NATURE DE BASE POUR UN FRAGMENT DE TEXTE -------------------- */ + + +/* Types de partie de rendu */ +typedef enum _RenderingTagType +{ + RTT_NONE, /* Espace ou tabulation */ + + RTT_RAW, /* Contenu brut */ + RTT_RAW_FULL, /* Contenu brut et complet */ + RTT_RAW_NULL, /* Contenu brut et nul */ + RTT_PRINTABLE, /* Caractère imprimable */ + RTT_NOT_PRINTABLE, /* Caractère non imprimable */ + + RTT_COMMENT, /* Commentaire */ + RTT_INDICATION, /* Aide à la lecture */ + + RTT_PHYS_ADDR_PAD, /* Position physique (début) */ + RTT_PHYS_ADDR, /* Position physique */ + RTT_VIRT_ADDR_PAD, /* Adresse virtuelle (début) */ + RTT_VIRT_ADDR, /* Adresse virtuelle */ + RTT_RAW_CODE, /* Code binaire brut */ + RTT_RAW_CODE_NULL, /* Code binaire brut et nul */ + + RTT_LABEL, /* Etiquette sur une adresse */ + + RTT_INSTRUCTION, /* Code binaire brut */ + + RTT_IMMEDIATE, /* Valeur immédiate */ + + RTT_REGISTER, /* Registre */ + + RTT_PUNCT, /* Signes de ponctuation */ + RTT_HOOK, /* Crochets '[' et ']' */ + RTT_SIGNS, /* Signes '+', '-' et '*' */ + RTT_LTGT, /* Caractères '<' et '>' */ + + RTT_SECTION, /* Identifiant de section */ + RTT_SEGMENT, /* Indication de segment */ + RTT_STRING, /* Chaîne de caractères avec " */ + + RTT_VAR_NAME, /* Nom de variable */ + + RTT_KEY_WORD, /* Mot clef de langage */ + + RTT_ERROR, /* Erreur "interne" */ + + RTT_COUNT + +} RenderingTagType; + + +/* Crée un nouveau fragment de texte avec des propriétés. */ +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 *); + +/* Retire une utilisation à un fragment de texte. */ +void release_line_segment(line_segment *); + +/* Indique le type de rendu associé à un segment de ligne. */ +RenderingTagType get_line_segment_type(const line_segment *); + +/* Fournit le texte brut conservé dans le segment. */ +char *get_line_segment_text(const line_segment *, bool); + +#ifdef INCLUDE_GTK_SUPPORT + +/* Fournit la quantité de pixels requise pour l'impression. */ +gint get_line_segment_width(const line_segment *); + +/* Fournit la position idéale pour un marqueur. */ +gint get_caret_position_from_line_segment(const line_segment *, gint); + +/* Déplace le curseur au sein d'un segment de tampon. */ +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 *); + +#endif + + +/* Types d'exportation */ +typedef enum _BufferExportType +{ + BET_TEXT, /* Exportation en texte brut */ + BET_HTML, /* Exportation en HTML */ + + BET_COUNT + +} BufferExportType; + +/* Elements sur lesquels une exportation peut s'appuyer */ +typedef struct _buffer_export_context +{ + int fd; /* Flux ouvert en écriture */ + + union + { + /* BET_TEXT */ + char *sep; /* Séparation entre colonnes */ + + /* BET_HTML */ + struct + { + char *font_name; /* Police d'impression */ + char *bg_color; /* Fond du tableau HTML */ + + }; + + }; + +} buffer_export_context; + +#ifdef INCLUDE_GTK_SUPPORT + +/* Exporte tous les styles utilisés par des segments. */ +void export_line_segment_style(buffer_export_context *, BufferExportType); + +#endif + +/* Exporte le fragment de texte représenté. */ +void export_line_segment(const line_segment *, buffer_export_context *, BufferExportType); + + + +/* -------------------- GESTION OPTIMALE D'UNE LISTE DE CONTENUS -------------------- */ + + +#ifdef INCLUDE_GTK_SUPPORT + +/* Initilise une liste de contenus de segments. */ +segcnt_list *init_segment_content_list(void); + +/* Libère la mémoire occupée par une liste de contenus. */ +void exit_segment_content_list(segcnt_list *); + +/* Incrémente le nombre d'utilisation de la liste de contenus. */ +void ref_segment_content_list(segcnt_list *); + +/* Décrémente le nombre d'utilisation de la liste de contenus. */ +void unref_segment_content_list(segcnt_list *); + +/* Vide, si besoin est, une liste de contenus de segments. */ +bool reset_segment_content_list(segcnt_list *); + +/* Marque le contenu d'un segment comme remarquable. */ +bool add_segment_content_to_selection_list(segcnt_list *, const line_segment *); + +#endif + + + +#endif /* _GLIBEXT_LINESEGMENT_H */ diff --git a/src/glibext/signal.h b/src/glibext/signal.h deleted file mode 100644 index 4f0ab4b..0000000 --- a/src/glibext/signal.h +++ /dev/null @@ -1,48 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * signal.h - prototypes pour un encadrement des signaux supplémentaire par rapport à celui de la GLib - * - * Copyright (C) 2014-2018 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 . - */ - - -#ifndef _GLIBEXT_SIGNAL_H -#define _GLIBEXT_SIGNAL_H - - -#include -#include -#include -#include -#include - - - -/* Reproduit le comportement de la fonction g_signal_connect(). */ -gulong _g_signal_connect_to_main(gpointer, const gchar *, GCallback, gpointer, GClosureMarshal, GConnectFlags); - - -#define g_signal_connect_to_main(instance, signal, handler, data, marshal) \ - _g_signal_connect_to_main(instance, signal, handler, data, marshal, 0) - -#define g_signal_connect_to_main_swapped(instance, signal, handler, data, marshal) \ - _g_signal_connect_to_main(instance, signal, handler, data, marshal, G_CONNECT_SWAPPED) - - - -#endif /* _GLIBEXT_SIGNAL_H */ diff --git a/src/glibext/tokenstyle.c b/src/glibext/tokenstyle.c new file mode 100644 index 0000000..8badf21 --- /dev/null +++ b/src/glibext/tokenstyle.c @@ -0,0 +1,205 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * rendering.h - prototypes pour la transformation de paramètres du thème GTK courant + * + * Copyright (C) 2018 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "rendering.h" + + +#include +#include +#include +#include + + +#include "../common/extstr.h" + + + +/****************************************************************************** +* * +* Paramètres : name = désignation d'un élément dans une feuille de style.* +* pattern = paramètres restitués en interne. |OUT] * +* * +* Description : Récupère les informations de rendus d'un élément de thème. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void load_rendering_pattern(const char *name, rendering_pattern_t *pattern) +{ + GtkStyleContext *context; /* Contexte pour les styles */ + GtkWidgetPath *path; /* Chemin d'accès aux thèmes */ + GdkRGBA *tmp_color; /* Description d'une couleur */ + PangoFontDescription *font_desc; /* Description d'une police */ + + /* Création d'un contexte d'accès */ + + path = gtk_widget_path_new(); + gtk_widget_path_append_type(path, G_TYPE_OBJECT); + + context = gtk_style_context_new(); + gtk_style_context_set_path(context, path); + gtk_style_context_set_screen(context, gdk_screen_get_default()); + + gtk_style_context_add_class(context, name); + + gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_COLOR, &tmp_color, NULL); + + pattern->foreground.has_color = true; + pattern->foreground.color = *tmp_color; + + pattern->inverted.has_color = true; + pattern->inverted.color.red = 1.0 - tmp_color->red; + pattern->inverted.color.green = 1.0 - tmp_color->green; + pattern->inverted.color.blue = 1.0 - tmp_color->blue; + pattern->inverted.color.alpha = tmp_color->alpha; + + gdk_rgba_free(tmp_color); + + gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL); + + switch (pango_font_description_get_style(font_desc)) + { + case PANGO_STYLE_NORMAL: + pattern->slant = CAIRO_FONT_SLANT_NORMAL; + break; + case PANGO_STYLE_ITALIC: + pattern->slant = CAIRO_FONT_SLANT_ITALIC; + break; + case PANGO_STYLE_OBLIQUE: + pattern->slant = CAIRO_FONT_SLANT_OBLIQUE; + break; + } + + switch (pango_font_description_get_weight(font_desc)) + { + case PANGO_WEIGHT_THIN: + case PANGO_WEIGHT_ULTRALIGHT: + case PANGO_WEIGHT_LIGHT: + case PANGO_WEIGHT_SEMILIGHT: + case PANGO_WEIGHT_BOOK: + case PANGO_WEIGHT_NORMAL: + case PANGO_WEIGHT_MEDIUM: + pattern->weight = CAIRO_FONT_WEIGHT_NORMAL; + break; + case PANGO_WEIGHT_SEMIBOLD: + case PANGO_WEIGHT_BOLD: + case PANGO_WEIGHT_ULTRABOLD: + case PANGO_WEIGHT_HEAVY: + case PANGO_WEIGHT_ULTRAHEAVY: + pattern->weight = CAIRO_FONT_WEIGHT_BOLD; + break; + } + + pango_font_description_free(font_desc); + + gtk_widget_path_free(path); + g_object_unref(context); + +} + + +/****************************************************************************** +* * +* Paramètres : text = texte à encadrer par des balises Pango. * +* pattern = paramètres restitués en interne. * +* * +* Description : Enjolive du texte selon les paramètres d'un élément de thème.* +* * +* Retour : Chaîne de caractère à libérer après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *build_pango_markup_for(const char *text, const rendering_pattern_t *pattern) +{ + char *result; /* Construction à retourner */ + char color[10]; /* Définition hexa de couleur */ + + result = strdup(text); + + if (pattern->foreground.has_color) + { + snprintf(color, sizeof(color), "#%02hhx%02hhx%02hhx%02hhx", + (unsigned char)(255 * pattern->foreground.color.red), + (unsigned char)(255 * pattern->foreground.color.green), + (unsigned char)(255 * pattern->foreground.color.blue), + (unsigned char)(255 * pattern->foreground.color.alpha)); + + result = strprep(result, "\">"); + result = strprep(result, color); + result = strprep(result, ""); + + } + + if (pattern->slant == CAIRO_FONT_SLANT_ITALIC || pattern->slant == CAIRO_FONT_SLANT_OBLIQUE) + { + result = strprep(result, ""); + result = stradd(result, ""); + } + + if (pattern->weight == CAIRO_FONT_WEIGHT_BOLD) + { + result = strprep(result, ""); + result = stradd(result, ""); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : base = base de texte à compléter. * +* text = texte à encadrer par des balises Pango. * +* pattern = paramètres restitués en interne. * +* * +* Description : Ajoute du texte enjolivé selon un élément de thème. * +* * +* Retour : Chaîne de caractère à libérer après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *append_pango_markup_with(char *base, const char *text, const rendering_pattern_t *pattern) +{ + char *result; /* Construction à retourner */ + char *tmp; /* Stockage temporaire */ + + tmp = build_pango_markup_for(text, pattern); + + result = stradd(base, tmp); + + free(tmp); + + return result; + +} diff --git a/src/glibext/tokenstyle.h b/src/glibext/tokenstyle.h new file mode 100644 index 0000000..9adfe1a --- /dev/null +++ b/src/glibext/tokenstyle.h @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * rendering.h - prototypes pour la transformation de paramètres du thème GTK courant + * + * Copyright (C) 2018 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _GTKEXT_RENDERING_H +#define _GTKEXT_RENDERING_H + + +#include +#include + + + +/* Restitution d'une couleur */ +typedef struct _rendering_color_t +{ + GdkRGBA color; /* Couleur de rendu */ + bool has_color; /* Définition en place ? */ + +} rendering_color_t; + +/* Restitution d'un élément de thème */ +typedef struct _rendering_pattern_t +{ + rendering_color_t foreground; /* Couleur d'impression */ + rendering_color_t inverted; /* Couleur inversée pour sél. */ + + cairo_font_slant_t slant; /* Style d'impression */ + cairo_font_weight_t weight; /* Poids de la police */ + +} rendering_pattern_t; + + +/* Récupère les informations de rendus d'un élément de thème. */ +void load_rendering_pattern(const char *, rendering_pattern_t *); + +/* Enjolive du texte selon les paramètres d'un élément de thème. */ +char *build_pango_markup_for(const char *, const rendering_pattern_t *); + +/* Ajoute du texte enjolivé selon un élément de thème. */ +char *append_pango_markup_with(char *, const char *, const rendering_pattern_t *); + + + +#endif /* _GTKEXT_RENDERING_H */ diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index 9d3d16c..331375f 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -13,8 +13,6 @@ libgtkext_la_SOURCES = \ gtkblockdisplay.h gtkblockdisplay.c \ gtkbufferdisplay-int.h \ gtkbufferdisplay.h gtkbufferdisplay.c \ - gtkdisplaypanel-int.h \ - gtkdisplaypanel.h gtkdisplaypanel.c \ gtkdockable-int.h \ gtkdockable.h gtkdockable.c \ gtkdockstation.h gtkdockstation.c \ @@ -23,7 +21,6 @@ libgtkext_la_SOURCES = \ hexdisplay.h hexdisplay.c \ named-int.h \ named.h named.c \ - rendering.h rendering.c \ resources.h resources.c \ support.h support.c \ tiledgrid.h tiledgrid.c \ @@ -35,13 +32,15 @@ libgtkext_la_LIBADD = \ libgtkext_la_CFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -UI_FILES_4_ = \ +RES_FILES = \ hexview.css \ hexview.ui libgtkext4_la_SOURCES = \ area-int.h \ area.h area.c \ + contentview-int.h \ + contentview.h contentview.c \ hexview.h hexview.c \ resources.h resources.c diff --git a/src/gtkext/contentview-int.h b/src/gtkext/contentview-int.h new file mode 100644 index 0000000..221d796 --- /dev/null +++ b/src/gtkext/contentview-int.h @@ -0,0 +1,164 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkdisplaypanel-int.h - définitions internes propres à l'affichage de contenus de binaire + * + * Copyright (C) 2016-2019 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 . + */ + + +#ifndef _GTK_DISPLAYPANEL_INT_H +#define _GTK_DISPLAYPANEL_INT_H + + +#include "gtkdisplaypanel.h" + + +#include +#include + + +#include "../analysis/binary.h" +#include "../glibext/gloadedpanel.h" + + + +/* Amplitude de l'arrondi pour les coins */ +#define BORDER_CORNER_RADIUS 10.0 + + +/* Indique les dimensions de travail du composant d'affichage. */ +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 *); + +/* Réagit à un défilement chez une barre associée au composant. */ +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 *); + +/* Indique la position d'affichage d'une adresse donnée. */ +typedef bool (* get_coordinates_fc) (const GtkDisplayPanel *, const GLineCursor *, gint *, gint *, ScrollPositionTweak); + +/* Fournit l'élément actif lié à la position courante. */ +typedef GObject * (* get_active_object_fc) (const GtkDisplayPanel *); + +/* Fournit des éléments liés à la position courante dans la vue. */ +typedef bool (* get_view_position_fc) (const GtkDisplayPanel *, GBufferLine **, GObject **); + +/* Déplace le curseur à un emplacement défini. */ +typedef bool (* move_caret_to_fc) (GtkDisplayPanel *, gint, gint); + +/* Fournit le position courante dans un panneau de chargement. */ +typedef GLineCursor * (* get_cursor_fc) (const GtkDisplayPanel *); + +/* Place en cache un rendu destiné à l'aperçu graphique rapide. */ +typedef void (* cache_glance_fc) (GtkDisplayPanel *, cairo_t *, const GtkAllocation *, double); + +/* Spécifie l'échelle à appliquer à l'affichage du composant. */ +typedef void (* apply_scale_fc) (GtkDisplayPanel *, double, double); + +/* Marque ou non le composant pour une exportation prochaine. */ +typedef void (* prepare_export_fc) (GtkDisplayPanel *, bool); + + + +/* Composant d'affichage générique (instance) */ +struct _GtkDisplayPanel +{ + GtkFixed parent; /* A laisser en premier */ + + GtkAdjustment *hadjustment; /* Barre de défilement horiz. */ + GtkAdjustment *vadjustment; /* Barre de défilement vert. */ + GtkScrollablePolicy hscroll_policy; /* Politique horizontale */ + GtkScrollablePolicy vscroll_policy; /* Politique verticale */ + + double scale; /* Echelle de l'affichage */ + + bool show_border; /* Affichage d'une bordure ? */ + unsigned int view_index; /* Indice du type de contenu */ + GDisplayOptions *options; /* Affichage des colonnes ? */ + + GLoadedBinary *binary; /* Binaire à visualiser */ + + bool export; /* Exportation du rendu ? */ + +}; + +/* Composant d'affichage générique (classe) */ +struct _GtkDisplayPanelClass +{ + GtkFixedClass parent; /* A laisser en premier */ + + compute_requested_size_fc compute_size; /* Calcul de la taille requise */ + compute_scroll_inc_fc compute_inc; /* Calcul des bonds */ + adjust_scroll_value_fc adjust; /* Réaction à un défilement */ + 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 */ + move_caret_to_fc move_caret_to; /* Déplacement du curseur */ + + get_cursor_fc get_cursor; /* Fourniture d'une position */ + cache_glance_fc cache_glance; /* Cache de la mignature */ + + apply_scale_fc scale; /* Mise à jour de l'échelle */ + + prepare_export_fc prepare_export; /* Préparation d'exportation */ + + /* Signaux */ + + void (* scaled) (GtkDisplayPanel *, double, double); + +}; + +/* Propriétés propres au composant d'affichage */ +typedef enum _ViewPanelProps +{ + VPP_0, + VPP_HADJUSTMENT, + VPP_VADJUSTMENT, + VPP_HSCROLL_POLICY, + VPP_VSCROLL_POLICY + +} ViewPanelProps; + + +/* Définit un chemin décrivant la bordure autour du panneau. */ +void gtk_display_panel_define_border_path(GtkDisplayPanel *, cairo_t *, const GtkAllocation *); + +/* Dessine si besoin est une bordure autour du composant. */ +void gtk_display_panel_draw_border(GtkDisplayPanel *, cairo_t *); + + + +/* --------------------------- CONVERSIONS DE COORDONNEES --------------------------- */ + + +/* Transcrit les coordonnées à l'écran en coordonnées absolues. */ +void gtk_display_panel_compute_fake_coord(GtkDisplayPanel *, gint *, gint *); + +/* Transcrit les coordonnées absolues en coordonnées à l'écran. */ +void gtk_display_panel_compute_real_coord(GtkDisplayPanel *, gint *, gint *); + +/* Transcrit les coordonnées absolues en coordonnées à l'écran. */ +void gtk_display_panel_compute_relative_coords(GtkDisplayPanel *, gint *, gint *); + + + +#endif /* _GTK_DISPLAYPANEL_INT_H */ diff --git a/src/gtkext/contentview.c b/src/gtkext/contentview.c new file mode 100644 index 0000000..0f93178 --- /dev/null +++ b/src/gtkext/contentview.c @@ -0,0 +1,1348 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkdisplaypanel.c - affichage de contenus de binaire + * + * Copyright (C) 2016-2019 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 . + */ + + +#include "gtkdisplaypanel.h" + + +#include + + +#include "gtkdisplaypanel-int.h" +#include "../glibext/chrysamarshal.h" +#include "../glibext/gbinarycursor.h" // REMME +#include "../glibext/gloadedpanel-int.h" + + + +/* Procède à l'initialisation de l'afficheur générique. */ +static void gtk_display_panel_class_init(GtkDisplayPanelClass *); + +/* Procède à l'initialisation de l'afficheur générique. */ +static void gtk_display_panel_init(GtkDisplayPanel *); + +/* Procède à l'initialisation de l'interface d'affichage. */ +static void gtk_display_panel_loaded_interface_init(GLoadedPanelInterface *); + +/* Supprime toutes les références externes. */ +static void gtk_display_panel_dispose(GtkDisplayPanel *); + +/* Procède à la libération totale de la mémoire. */ +static void gtk_display_panel_finalize(GtkDisplayPanel *); + +/* Définit une propriété du composant d'affichage. */ +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 *); + +/* Détruit un composant d'affichage. */ +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 *); + +/* Fournit la hauteur idéale pour le composant d'affichage. */ +static void gtk_display_panel_get_preferred_height(GtkWidget *, gint *, gint *); + +/* Fournit la largeur idéale pour le composant d'affichage. */ +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 *); + +/* 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); + +/* S'associe à un ajustement pour un défilement donné. */ +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); + +/* Réagit à un défilement chez une barre associée au composant.*/ +static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *, GtkDisplayPanel *); + + + +/* ----------------------- INTERFACE DE PANNEAU DE CHARGEMENT ----------------------- */ + + +/* Réagit à un changement des règles d'affichage. */ +static void on_display_panel_option_change(GDisplayOptions *, size_t, bool, GtkDisplayPanel *); + +/* Associe à un panneau d'affichage un binaire chargé. */ +static void gtk_display_panel_set_content(GtkDisplayPanel *, GLoadedContent *); + +/* Fournit le contenu associé à un panneau de chargement. */ +static GLoadedContent *gtk_display_panel_get_content(const GtkDisplayPanel *); + +/* Fournit le position courante dans un panneau de chargement. */ +static GLineCursor *gtk_display_panel_get_cursor(const GtkDisplayPanel *); + +/* S'assure qu'un emplacement donné est visible à l'écran. */ +static void gtk_display_panel_scroll_to_cursor(GtkDisplayPanel *, const GLineCursor *, ScrollPositionTweak, bool); + +/* Place en cache un rendu destiné à l'aperçu graphique rapide. */ +static void gtk_display_panel_cache_glance(GtkDisplayPanel *, cairo_t *, const GtkAllocation *, double); + + + +/* Détermine le type du composant d'affichage générique. */ +G_DEFINE_TYPE_WITH_CODE(GtkDisplayPanel, gtk_display_panel, GTK_TYPE_FIXED, + G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE, NULL) + G_IMPLEMENT_INTERFACE(G_TYPE_LOADED_PANEL, gtk_display_panel_loaded_interface_init)); + + +/****************************************************************************** +* * +* Paramètres : class = classe GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'afficheur générique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_class_init(GtkDisplayPanelClass *class) +{ + GObjectClass *object; /* Plus haut niveau équivalent */ + GtkWidgetClass *widget; /* Classe de haut niveau */ + GtkDisplayPanelClass *panel; /* Classe de lus bas niveau */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)gtk_display_panel_dispose; + object->finalize = (GObjectFinalizeFunc)gtk_display_panel_finalize; + 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->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 */ + + g_signal_new("scaled", + GTK_TYPE_DISPLAY_PANEL, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkDisplayPanelClass, scaled), + NULL, NULL, + g_cclosure_user_marshal_VOID__DOUBLE_DOUBLE, + G_TYPE_NONE, 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'afficheur générique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_init(GtkDisplayPanel *panel) +{ + gtk_widget_set_has_window(GTK_WIDGET(panel), TRUE); + gtk_widget_set_can_focus(GTK_WIDGET(panel), TRUE); + + panel->scale = 1.0; + + panel->export = false; + +} + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface d'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_loaded_interface_init(GLoadedPanelInterface *iface) +{ + iface->set_content = (set_loaded_panel_content_fc)gtk_display_panel_set_content; + iface->get_content = (get_loaded_panel_content_fc)gtk_display_panel_get_content; + + iface->get_cursor = (get_loaded_cursor_fc)gtk_display_panel_get_cursor; + iface->scroll = (scroll_loaded_to_cursor_fc)gtk_display_panel_scroll_to_cursor; + + iface->cache_glance = (cache_loaded_glance_fc)gtk_display_panel_cache_glance; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_dispose(GtkDisplayPanel *panel) +{ + g_clear_object(&panel->hadjustment); + g_clear_object(&panel->vadjustment); + + g_clear_object(&panel->options); + + g_clear_object(&panel->binary); + + G_OBJECT_CLASS(gtk_display_panel_parent_class)->dispose(G_OBJECT(panel)); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_finalize(GtkDisplayPanel *panel) +{ + G_OBJECT_CLASS(gtk_display_panel_parent_class)->finalize(G_OBJECT(panel)); + +} + + +/****************************************************************************** +* * +* Paramètres : object = instance de composant GTK à manipuler. * +* prop_id = identifiant de la propriété concernée. * +* value = valeur attribuée. * +* pspec = spécification de la propriété visée. * +* * +* Description : Définit une propriété du composant d'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GtkDisplayPanel *panel; /* Autre vision de l'instance */ + + panel = GTK_DISPLAY_PANEL(object); + + switch (prop_id) + { + case VPP_HADJUSTMENT: + gtk_display_panel_set_adjustment(panel, 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)); + break; + case VPP_HSCROLL_POLICY: + //viewport->priv->hscroll_policy = g_value_get_enum (value); + //gtk_widget_queue_resize (GTK_WIDGET (viewport)); + break; + case VPP_VSCROLL_POLICY: + //viewport->priv->vscroll_policy = g_value_get_enum (value); + //gtk_widget_queue_resize (GTK_WIDGET (viewport)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } + +} + + +/****************************************************************************** +* * +* Paramètres : object = instance de composant GTK à manipuler. * +* prop_id = identifiant de la propriété concernée. * +* value = valeur à renvoyer. * +* pspec = spécification de la propriété visée. * +* * +* Description : Fournit une propriété du composant d'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GtkDisplayPanel *panel; /* Autre vision de l'instance */ + + panel = GTK_DISPLAY_PANEL(object); + + switch (prop_id) + { + case VPP_HADJUSTMENT: + g_value_set_object(value, panel->hadjustment); + break; + case VPP_VADJUSTMENT: + g_value_set_object(value, panel->vadjustment); + break; + case VPP_HSCROLL_POLICY: + g_value_set_enum(value, panel->hscroll_policy); + break; + case VPP_VSCROLL_POLICY: + g_value_set_enum(value, panel->vscroll_policy); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK à détruire. * +* * +* Description : Détruit un composant d'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_destroy(GtkWidget *widget) +{ + GtkDisplayPanel *panel; /* Autre version du composant */ + + panel = GTK_DISPLAY_PANEL(widget); + + gtk_display_panel_disconnect_adjustment(panel, GTK_ORIENTATION_HORIZONTAL); + gtk_display_panel_disconnect_adjustment(panel, GTK_ORIENTATION_VERTICAL); + + GTK_WIDGET_CLASS(gtk_display_panel_parent_class)->destroy(widget); + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK à préparer. * +* * +* Description : Encadre la construction graphique initiale de l'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_realize(GtkWidget *widget) +{ + GtkAllocation allocation; /* Disposition du composant */ + GdkWindowAttr attributes; /* Propriétés du composant */ + guint attributes_mask; /* Masque de prise en compte */ + GdkWindow *window; /* Fenêtre du composant */ + + gtk_widget_get_allocation(widget, &allocation); + + gtk_widget_set_realized(widget, TRUE); + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = allocation.x; + attributes.y = allocation.y; + attributes.width = allocation.width; + attributes.height = allocation.height; + + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.event_mask = gtk_widget_get_events(widget) + | GDK_EXPOSURE_MASK + | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK + | GDK_FOCUS_CHANGE_MASK + | GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y; + + window = gdk_window_new(gtk_widget_get_parent_window(widget), + &attributes, attributes_mask); + + gtk_widget_set_window(widget, window); + gtk_widget_register_window(widget, window); + +} + + +/****************************************************************************** +* * +* 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); + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK à examiner. * +* minimum = hauteur minimale à préciser ou NULL. [OUT] * +* natural = hauteur idéale à préciser ou NULL. [OUT] * +* * +* Description : Fournit la hauteur idéale pour le composant d'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_get_preferred_height(GtkWidget *widget, gint *minimum, gint *natural) +{ + GtkDisplayPanel *panel; /* Autre version du composant */ + gint req; /* Dimension requise */ + + panel = GTK_DISPLAY_PANEL(widget); + + GTK_DISPLAY_PANEL_GET_CLASS(widget)->compute_size(panel, NULL, &req); + + req *= panel->scale; + + if (minimum != NULL) *minimum = req; + if (natural != NULL) *natural = req; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK à examiner. * +* minimum = largeur minimale à préciser ou NULL. [OUT] * +* natural = largeur idéale à préciser ou NULL. [OUT] * +* * +* Description : Fournit la largeur idéale pour le composant d'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_get_preferred_width(GtkWidget *widget, gint *minimum, gint *natural) +{ + GtkDisplayPanel *panel; /* Autre version du composant */ + gint req; /* Dimension requise */ + + panel = GTK_DISPLAY_PANEL(widget); + + GTK_DISPLAY_PANEL_GET_CLASS(widget)->compute_size(panel, &req, NULL); + + req *= panel->scale; + + if (minimum != NULL) *minimum = req; + if (natural != NULL) *natural = req; + +} + + +/****************************************************************************** +* * +* 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; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à consulter. * +* alloc = emplacement à déterminer. [OUT] * +* * +* Description : Détermine la taille allouée pour le contenu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_compute_allocation(GtkDisplayPanel *panel, GtkAllocation *alloc) +{ + GtkWidget *widget; /* Autre vision du composant */ + GtkAllocation allocation; /* Emplacement du composant */ + GtkStyleContext *context; /* Contexte du style */ + GtkStateFlags state; /* Etat du composant */ + GtkBorder padding; /* Espace d'un espacement */ + GtkBorder border; /* Espace d'une bordure */ + + widget = GTK_WIDGET(panel); + + gtk_widget_get_allocation(widget, &allocation); + + context = gtk_widget_get_style_context(widget); + state = gtk_widget_get_state_flags(widget); + + gtk_style_context_save(context); + gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME); + + gtk_style_context_get_padding(context, state, &padding); + gtk_style_context_get_border(context, state, &border); + + gtk_style_context_restore(context); + + /* Positions */ + + if (panel->show_border) + { + alloc->x = border.left; + alloc->y = border.top; + } + else + { + alloc->x = 0; + alloc->y = 0; + } + + alloc->x += padding.left; + alloc->y += padding.top; + + /* Dimensions */ + + if (panel->show_border) + { + alloc->width = MAX (1, allocation.width - alloc->x - padding.right - border.right); + alloc->height = MAX (1, allocation.height - alloc->y - padding.bottom - border.bottom); + } + else + { + alloc->width = MAX (1, allocation.width - alloc->x - padding.right); + alloc->height = MAX (1, allocation.height - alloc->y - padding.bottom); + } + +} + + +/****************************************************************************** +* * +* 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); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à mettre à jour. * +* * +* Description : Indique l'échelle appliquée à l'affichage du composant. * +* * +* Retour : Echelle appliquée à l'affichage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +double gtk_display_panel_get_scale(const GtkDisplayPanel *panel) +{ + double result; /* Echelle à retourner */ + + result = panel->scale; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à mettre à jour. * +* scale = échelle appliquée à l'affichage. * +* * +* Description : Spécifie l'échelle à appliquer à l'affichage du composant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_display_panel_set_scale(GtkDisplayPanel *panel, double scale) +{ + double old_scale; /* Echelle précédente */ + GtkDisplayPanelClass *class; /* Classe associée au composant*/ + + if (scale > 1.0) + scale = 1.0; + + else if (scale < 0.01) + scale = 0.01; + + if (panel->scale != scale) + { + old_scale = panel->scale; + + panel->scale = scale; + + class = GTK_DISPLAY_PANEL_GET_CLASS(panel); + + if (class->scale != NULL) + class->scale(panel, old_scale, scale); + + gtk_widget_queue_resize(GTK_WIDGET(panel)); + + g_signal_emit_by_name(panel, "scaled", old_scale, scale); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à mettre à jour. * +* show = état de l'affichage auquel parvenir. * +* * +* Description : Définit si une bordure est à afficher. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_display_panel_show_border(GtkDisplayPanel *panel, bool show) +{ + panel->show_border = show; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à mettre à jour. * +* export = préparation d'une exportation complète du rendu ? * +* * +* Description : Marque ou non le composant pour une exportation prochaine. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_display_panel_prepare_export(GtkDisplayPanel *panel, bool export) +{ + GtkDisplayPanelClass *class; /* Classe associée au composant*/ + + panel->export = export; + + class = GTK_DISPLAY_PANEL_GET_CLASS(panel); + + if (class->prepare_export != NULL) + class->prepare_export(panel, export); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à venir consulter. * +* cr = contexte graphique associé à l'événement. * +* area = surface à considérer. * +* * +* Description : Définit un chemin décrivant la bordure autour du panneau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_display_panel_define_border_path(GtkDisplayPanel *panel, cairo_t *cr, const GtkAllocation *area) +{ + double degrees; /* Conversion en degrés */ + + degrees = M_PI / 180.0; + + cairo_new_sub_path(cr); + + cairo_arc(cr, + area->x + area->width - BORDER_CORNER_RADIUS - 0.5, + area->y + BORDER_CORNER_RADIUS + 0.5, + BORDER_CORNER_RADIUS, -90 * degrees, 0 * degrees); + + cairo_arc(cr, + area->x + area->width - BORDER_CORNER_RADIUS - 0.5, + area->y + area->height - BORDER_CORNER_RADIUS - 0.5, + BORDER_CORNER_RADIUS, 0 * degrees, 90 * degrees); + + cairo_arc(cr, + area->x + BORDER_CORNER_RADIUS + 0.5, + area->y + area->height - BORDER_CORNER_RADIUS - 0.5, + BORDER_CORNER_RADIUS, 90 * degrees, 180 * degrees); + + cairo_arc(cr, + area->x + BORDER_CORNER_RADIUS + 0.5, + area->y + BORDER_CORNER_RADIUS + 0.5, + BORDER_CORNER_RADIUS, 180 * degrees, 270 * degrees); + + cairo_close_path(cr); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à venir consulter. * +* cr = contexte graphique associé à l'événement. * +* * +* Description : Dessine si besoin est une bordure autour du composant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_display_panel_draw_border(GtkDisplayPanel *panel, cairo_t *cr) +{ + GtkWidget *widget; /* Autre version du composant */ + GtkStyleContext *context; /* Contexte du thème actuel */ + GdkRGBA color; /* Couleur de thème récupérée */ + GtkRequisition req; /* Taille allouée à l'élément */ + GtkAllocation area; /* Emplacement à considérer */ + + if (panel->show_border) + { + widget = GTK_WIDGET(panel); + + gtk_widget_get_preferred_size(widget, NULL, &req); + + context = gtk_widget_get_style_context(widget); + + gtk_style_context_save(context); + + gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME); + + gtk_style_context_get(gtk_widget_get_style_context(widget), + gtk_widget_get_state_flags(widget), + GTK_STYLE_PROPERTY_COLOR, &color, NULL); + + cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha); + + cairo_set_line_width(cr, 1.0); + + gtk_widget_get_preferred_size(GTK_WIDGET(panel), NULL, &req); + + area.x = 0; + area.y = 0; + area.width = req.width; + area.height = req.height; + + gtk_display_panel_define_border_path(panel, cr, &area); + cairo_stroke(cr); + + gtk_style_context_restore(context); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à consulter. * +* cursor = emplacement à présenter à l'écran. * +* x = position horizontale au sein du composant. [OUT] * +* y = position verticale au sein du composant. [OUT] * +* tweak = adaptation finale à effectuer. * +* * +* Description : Indique la position d'affichage d'un emplacement donné. * +* * +* Retour : true si l'adresse fait partie du composant, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool gtk_display_panel_get_cursor_coordinates(const GtkDisplayPanel *panel, const GLineCursor *cursor, gint *x, gint *y, ScrollPositionTweak tweak) +{ + bool result; /* Bilan à remonter */ + + result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_coordinates(panel, cursor, x, y, tweak); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à consulter. * +* * +* Description : Fournit l'élément actif lié à la position courante. * +* * +* Retour : Objet actif courant ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GObject *gtk_display_panel_get_active_object(const GtkDisplayPanel *panel) +{ + GObject *result; /* Trouvaille à retourner */ + + if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_active == NULL) + result = NULL; + + else + result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_active(panel); + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à manipuler. * +* addr = adresse à présenter à l'écran. * +* * +* Description : Demande à qui veut répondre un déplacement du curseur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_display_panel_request_move(GtkDisplayPanel *panel, const vmpa2t *addr) +{ + GLineCursor *___tmp; + + ___tmp = g_binary_cursor_new(); + g_binary_cursor_update(G_BINARY_CURSOR(___tmp), addr); + + g_loaded_panel_request_move(G_LOADED_PANEL(panel), ___tmp, false); + + g_object_unref(G_OBJECT(___tmp)); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à consulter. * +* event = informations liées à l'événement. * +* * +* Description : Transcrit les coordonnées à l'écran en coordonnées absolues. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_display_panel_compute_fake_coord(GtkDisplayPanel *panel, gint *x, gint *y) +{ + if (panel->hadjustment != NULL) + *x -= gtk_adjustment_get_value(panel->hadjustment); + + if (panel->vadjustment != NULL) + *y += gtk_adjustment_get_value(panel->vadjustment); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à consulter. * +* event = informations liées à l'événement. * +* * +* Description : Transcrit les coordonnées absolues en coordonnées à l'écran. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_display_panel_compute_real_coord(GtkDisplayPanel *panel, gint *x, gint *y) +{ + if (x != NULL && panel->hadjustment != NULL) + *x += gtk_adjustment_get_value(panel->hadjustment); + + if (y != NULL && panel->vadjustment != NULL) + *y += gtk_adjustment_get_value(panel->vadjustment); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à consulter. * +* x = abscisse à ajuster. [OUT] * +* x = ordonnée à ajuster. [OUT] * +* * +* Description : Transcrit les coordonnées absolues en coordonnées à l'écran. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_display_panel_compute_relative_coords(GtkDisplayPanel *panel, gint *x, gint *y) +{ + if (x != NULL && panel->hadjustment != NULL) + *x -= gtk_adjustment_get_value(panel->hadjustment); + + if (y != NULL && panel->vadjustment != NULL) + *y -= gtk_adjustment_get_value(panel->vadjustment); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* INTERFACE DE PANNEAU DE CHARGEMENT */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : options = options à mettre à jour. * +* index = indice de l'option concernée. * +* value = nouvelle valeur à intégrer. * +* panel = composant GTK à consulter. * +* * +* Description : Réagit à un changement des règles d'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_display_panel_option_change(GDisplayOptions *options, size_t index, bool value, GtkDisplayPanel *panel) +{ + gtk_widget_queue_resize(gtk_widget_get_parent(GTK_WIDGET(panel))); + gtk_widget_queue_resize(GTK_WIDGET(panel)); + gtk_widget_queue_draw(GTK_WIDGET(panel)); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à mettre à jour. * +* content = binaire associé à intégrer. * +* * +* Description : Associe à un panneau d'affichage un binaire chargé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_set_content(GtkDisplayPanel *panel, GLoadedContent *content) +{ + panel->view_index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); + + panel->options = g_loaded_content_get_display_options(content, panel->view_index); + + panel->binary = G_LOADED_BINARY(content); + + g_signal_connect(panel->options, "value-changed", G_CALLBACK(on_display_panel_option_change), panel); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à consulter. * +* * +* Description : Fournit le contenu associé à un panneau de chargement. * +* * +* Retour : Contenu quelconque chargé en mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GLoadedContent *gtk_display_panel_get_content(const GtkDisplayPanel *panel) +{ + GLoadedContent *result; /* Contenu à retourner */ + + result = G_LOADED_CONTENT(panel->binary); + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à consulter. * +* * +* Description : Fournit le position courante dans un panneau de chargement. * +* * +* Retour : Informations relatives à la position du curseur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GLineCursor *gtk_display_panel_get_cursor(const GtkDisplayPanel *panel) +{ + GLineCursor *result; /* Contenu à retourner */ + + result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_cursor(panel); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à manipuler. * +* cursor = emplacement à présenter à l'écran. * +* tweak = adaptation finale à effectuer. * +* move = doit-on déplacer le curseur à l'adresse indiquée ? * +* * +* Description : S'assure qu'un emplacement donné est visible à l'écran. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_scroll_to_cursor(GtkDisplayPanel *panel, const GLineCursor *cursor, ScrollPositionTweak tweak, bool move) +{ + GtkWidget *parent; /* Support parent à valider */ + GtkDisplayPanelClass *class; /* Classe de l'instance */ + gint x; /* Abscisse à garantir */ + gint y; /* Ordonnée à garantir */ + GtkWidget *viewport; /* Parent avec défilement */ + GtkAdjustment *adj; /* Défilement à mettre à jour */ + gdouble step_inc; /* Valeur d'un petit pas */ + gdouble page_size; /* Taille de l'affichage */ + double value; /* Valeur courante */ + + /** + * Si une vue partielle se déplace via cette fonction, il faut potentiellement + * rediriger l'appel vers la vue en graphiques parente. + */ + + parent = gtk_widget_get_parent(GTK_WIDGET(panel)); + parent = gtk_widget_get_parent(GTK_WIDGET(parent)); + + if (GTK_IS_DISPLAY_PANEL(parent)) + panel = GTK_DISPLAY_PANEL(parent); + + class = GTK_DISPLAY_PANEL_GET_CLASS(panel); + + if (class->prepare != NULL) + class->prepare(panel, cursor); + + if (gtk_display_panel_get_cursor_coordinates(panel, cursor, &x, &y, tweak)) + { + viewport = gtk_widget_get_parent(GTK_WIDGET(panel)); + + /* Eventuel défilement horizontal */ + + g_object_get(G_OBJECT(viewport), "hadjustment", &adj, NULL); + + step_inc = gtk_adjustment_get_step_increment(adj); + page_size = gtk_adjustment_get_page_size(adj); + value = gtk_adjustment_get_value(adj); + + if (x < value) + gtk_adjustment_set_value(adj, x); + + else if ((x + step_inc) > (value + page_size)) + gtk_adjustment_set_value(adj, x + step_inc - page_size); + + /* Eventuel défilement vertical */ + + g_object_get(G_OBJECT(viewport), "vadjustment", &adj, NULL); + + step_inc = gtk_adjustment_get_step_increment(adj); + page_size = gtk_adjustment_get_page_size(adj); + value = gtk_adjustment_get_value(adj); + + if (y < value || tweak != SPT_RAW) + gtk_adjustment_set_value(adj, y); + + else if ((y + step_inc) > (value + page_size)) + gtk_adjustment_set_value(adj, y + step_inc - page_size); + + /* Déplacement du curseur */ + + if (move && gtk_display_panel_get_cursor_coordinates(panel, cursor, &x, &y, SPT_RAW)) + class->move_caret_to(panel, x, y); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à manipuler. * +* cairo = assistant pour la création de rendus. * +* area = taille de la surface réduite à disposition. * +* scale = échelle vis à vis de la taille réelle. * +* * +* Description : Place en cache un rendu destiné à l'aperçu graphique rapide. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_cache_glance(GtkDisplayPanel *panel, cairo_t *cairo, const GtkAllocation *area, double scale) +{ + if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance != NULL) + GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance(panel, cairo, area, scale); + +} diff --git a/src/gtkext/contentview.h b/src/gtkext/contentview.h new file mode 100644 index 0000000..58d460f --- /dev/null +++ b/src/gtkext/contentview.h @@ -0,0 +1,78 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkdisplaypanel.h - prototypes pour l'affichage de contenus de binaire + * + * Copyright (C) 2016-2019 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 . + */ + + +#ifndef _GTKEXT_DISPLAYPANEL_H +#define _GTKEXT_DISPLAYPANEL_H + + +#include +#include + + +#include "../arch/vmpa.h" +#include "../glibext/gloadedpanel.h" + + + +#define GTK_TYPE_DISPLAY_PANEL (gtk_display_panel_get_type()) +#define GTK_DISPLAY_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_DISPLAY_PANEL, GtkDisplayPanel)) +#define GTK_DISPLAY_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_DISPLAY_PANEL, GtkDisplayPanelClass)) +#define GTK_IS_DISPLAY_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_DISPLAY_PANEL)) +#define GTK_IS_DISPLAY_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_DISPLAY_PANEL)) +#define GTK_DISPLAY_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_DISPLAY_PANEL, GtkDisplayPanelClass)) + + +/* Composant d'affichage générique (instance) */ +typedef struct _GtkDisplayPanel GtkDisplayPanel; + +/* Composant d'affichage générique (classe) */ +typedef struct _GtkDisplayPanelClass GtkDisplayPanelClass; + + +/* Détermine le type du composant d'affichage générique. */ +GType gtk_display_panel_get_type(void); + +/* Indique l'échelle appliquée à l'affichage du composant. */ +double gtk_display_panel_get_scale(const GtkDisplayPanel *); + +/* Spécifie l'échelle à appliquer à l'affichage du composant. */ +void gtk_display_panel_set_scale(GtkDisplayPanel *, double); + +/* Définit si une bordure est à afficher. */ +void gtk_display_panel_show_border(GtkDisplayPanel *, bool); + +/* Marque ou non le composant pour une exportation prochaine. */ +void gtk_display_panel_prepare_export(GtkDisplayPanel *, bool); + +/* Indique la position d'affichage d'un emplacement donné. */ +bool gtk_display_panel_get_cursor_coordinates(const GtkDisplayPanel *, const GLineCursor *, gint *, gint *, ScrollPositionTweak); + +/* Fournit l'élément actif lié à la position courante. */ +GObject *gtk_display_panel_get_active_object(const GtkDisplayPanel *); + +/* Demande à qui veut répondre un déplacement du curseur. */ +void gtk_display_panel_request_move(GtkDisplayPanel *, const vmpa2t *); + + + +#endif /* _GTKEXT_DISPLAYPANEL_H */ diff --git a/src/gtkext/gtkdisplaypanel-int.h b/src/gtkext/gtkdisplaypanel-int.h deleted file mode 100644 index 221d796..0000000 --- a/src/gtkext/gtkdisplaypanel-int.h +++ /dev/null @@ -1,164 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gtkdisplaypanel-int.h - définitions internes propres à l'affichage de contenus de binaire - * - * Copyright (C) 2016-2019 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 . - */ - - -#ifndef _GTK_DISPLAYPANEL_INT_H -#define _GTK_DISPLAYPANEL_INT_H - - -#include "gtkdisplaypanel.h" - - -#include -#include - - -#include "../analysis/binary.h" -#include "../glibext/gloadedpanel.h" - - - -/* Amplitude de l'arrondi pour les coins */ -#define BORDER_CORNER_RADIUS 10.0 - - -/* Indique les dimensions de travail du composant d'affichage. */ -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 *); - -/* Réagit à un défilement chez une barre associée au composant. */ -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 *); - -/* Indique la position d'affichage d'une adresse donnée. */ -typedef bool (* get_coordinates_fc) (const GtkDisplayPanel *, const GLineCursor *, gint *, gint *, ScrollPositionTweak); - -/* Fournit l'élément actif lié à la position courante. */ -typedef GObject * (* get_active_object_fc) (const GtkDisplayPanel *); - -/* Fournit des éléments liés à la position courante dans la vue. */ -typedef bool (* get_view_position_fc) (const GtkDisplayPanel *, GBufferLine **, GObject **); - -/* Déplace le curseur à un emplacement défini. */ -typedef bool (* move_caret_to_fc) (GtkDisplayPanel *, gint, gint); - -/* Fournit le position courante dans un panneau de chargement. */ -typedef GLineCursor * (* get_cursor_fc) (const GtkDisplayPanel *); - -/* Place en cache un rendu destiné à l'aperçu graphique rapide. */ -typedef void (* cache_glance_fc) (GtkDisplayPanel *, cairo_t *, const GtkAllocation *, double); - -/* Spécifie l'échelle à appliquer à l'affichage du composant. */ -typedef void (* apply_scale_fc) (GtkDisplayPanel *, double, double); - -/* Marque ou non le composant pour une exportation prochaine. */ -typedef void (* prepare_export_fc) (GtkDisplayPanel *, bool); - - - -/* Composant d'affichage générique (instance) */ -struct _GtkDisplayPanel -{ - GtkFixed parent; /* A laisser en premier */ - - GtkAdjustment *hadjustment; /* Barre de défilement horiz. */ - GtkAdjustment *vadjustment; /* Barre de défilement vert. */ - GtkScrollablePolicy hscroll_policy; /* Politique horizontale */ - GtkScrollablePolicy vscroll_policy; /* Politique verticale */ - - double scale; /* Echelle de l'affichage */ - - bool show_border; /* Affichage d'une bordure ? */ - unsigned int view_index; /* Indice du type de contenu */ - GDisplayOptions *options; /* Affichage des colonnes ? */ - - GLoadedBinary *binary; /* Binaire à visualiser */ - - bool export; /* Exportation du rendu ? */ - -}; - -/* Composant d'affichage générique (classe) */ -struct _GtkDisplayPanelClass -{ - GtkFixedClass parent; /* A laisser en premier */ - - compute_requested_size_fc compute_size; /* Calcul de la taille requise */ - compute_scroll_inc_fc compute_inc; /* Calcul des bonds */ - adjust_scroll_value_fc adjust; /* Réaction à un défilement */ - 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 */ - move_caret_to_fc move_caret_to; /* Déplacement du curseur */ - - get_cursor_fc get_cursor; /* Fourniture d'une position */ - cache_glance_fc cache_glance; /* Cache de la mignature */ - - apply_scale_fc scale; /* Mise à jour de l'échelle */ - - prepare_export_fc prepare_export; /* Préparation d'exportation */ - - /* Signaux */ - - void (* scaled) (GtkDisplayPanel *, double, double); - -}; - -/* Propriétés propres au composant d'affichage */ -typedef enum _ViewPanelProps -{ - VPP_0, - VPP_HADJUSTMENT, - VPP_VADJUSTMENT, - VPP_HSCROLL_POLICY, - VPP_VSCROLL_POLICY - -} ViewPanelProps; - - -/* Définit un chemin décrivant la bordure autour du panneau. */ -void gtk_display_panel_define_border_path(GtkDisplayPanel *, cairo_t *, const GtkAllocation *); - -/* Dessine si besoin est une bordure autour du composant. */ -void gtk_display_panel_draw_border(GtkDisplayPanel *, cairo_t *); - - - -/* --------------------------- CONVERSIONS DE COORDONNEES --------------------------- */ - - -/* Transcrit les coordonnées à l'écran en coordonnées absolues. */ -void gtk_display_panel_compute_fake_coord(GtkDisplayPanel *, gint *, gint *); - -/* Transcrit les coordonnées absolues en coordonnées à l'écran. */ -void gtk_display_panel_compute_real_coord(GtkDisplayPanel *, gint *, gint *); - -/* Transcrit les coordonnées absolues en coordonnées à l'écran. */ -void gtk_display_panel_compute_relative_coords(GtkDisplayPanel *, gint *, gint *); - - - -#endif /* _GTK_DISPLAYPANEL_INT_H */ diff --git a/src/gtkext/gtkdisplaypanel.c b/src/gtkext/gtkdisplaypanel.c deleted file mode 100644 index 0f93178..0000000 --- a/src/gtkext/gtkdisplaypanel.c +++ /dev/null @@ -1,1348 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gtkdisplaypanel.c - affichage de contenus de binaire - * - * Copyright (C) 2016-2019 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 . - */ - - -#include "gtkdisplaypanel.h" - - -#include - - -#include "gtkdisplaypanel-int.h" -#include "../glibext/chrysamarshal.h" -#include "../glibext/gbinarycursor.h" // REMME -#include "../glibext/gloadedpanel-int.h" - - - -/* Procède à l'initialisation de l'afficheur générique. */ -static void gtk_display_panel_class_init(GtkDisplayPanelClass *); - -/* Procède à l'initialisation de l'afficheur générique. */ -static void gtk_display_panel_init(GtkDisplayPanel *); - -/* Procède à l'initialisation de l'interface d'affichage. */ -static void gtk_display_panel_loaded_interface_init(GLoadedPanelInterface *); - -/* Supprime toutes les références externes. */ -static void gtk_display_panel_dispose(GtkDisplayPanel *); - -/* Procède à la libération totale de la mémoire. */ -static void gtk_display_panel_finalize(GtkDisplayPanel *); - -/* Définit une propriété du composant d'affichage. */ -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 *); - -/* Détruit un composant d'affichage. */ -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 *); - -/* Fournit la hauteur idéale pour le composant d'affichage. */ -static void gtk_display_panel_get_preferred_height(GtkWidget *, gint *, gint *); - -/* Fournit la largeur idéale pour le composant d'affichage. */ -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 *); - -/* 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); - -/* S'associe à un ajustement pour un défilement donné. */ -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); - -/* Réagit à un défilement chez une barre associée au composant.*/ -static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *, GtkDisplayPanel *); - - - -/* ----------------------- INTERFACE DE PANNEAU DE CHARGEMENT ----------------------- */ - - -/* Réagit à un changement des règles d'affichage. */ -static void on_display_panel_option_change(GDisplayOptions *, size_t, bool, GtkDisplayPanel *); - -/* Associe à un panneau d'affichage un binaire chargé. */ -static void gtk_display_panel_set_content(GtkDisplayPanel *, GLoadedContent *); - -/* Fournit le contenu associé à un panneau de chargement. */ -static GLoadedContent *gtk_display_panel_get_content(const GtkDisplayPanel *); - -/* Fournit le position courante dans un panneau de chargement. */ -static GLineCursor *gtk_display_panel_get_cursor(const GtkDisplayPanel *); - -/* S'assure qu'un emplacement donné est visible à l'écran. */ -static void gtk_display_panel_scroll_to_cursor(GtkDisplayPanel *, const GLineCursor *, ScrollPositionTweak, bool); - -/* Place en cache un rendu destiné à l'aperçu graphique rapide. */ -static void gtk_display_panel_cache_glance(GtkDisplayPanel *, cairo_t *, const GtkAllocation *, double); - - - -/* Détermine le type du composant d'affichage générique. */ -G_DEFINE_TYPE_WITH_CODE(GtkDisplayPanel, gtk_display_panel, GTK_TYPE_FIXED, - G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE, NULL) - G_IMPLEMENT_INTERFACE(G_TYPE_LOADED_PANEL, gtk_display_panel_loaded_interface_init)); - - -/****************************************************************************** -* * -* Paramètres : class = classe GTK à initialiser. * -* * -* Description : Procède à l'initialisation de l'afficheur générique. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_class_init(GtkDisplayPanelClass *class) -{ - GObjectClass *object; /* Plus haut niveau équivalent */ - GtkWidgetClass *widget; /* Classe de haut niveau */ - GtkDisplayPanelClass *panel; /* Classe de lus bas niveau */ - - object = G_OBJECT_CLASS(class); - - object->dispose = (GObjectFinalizeFunc/* ! */)gtk_display_panel_dispose; - object->finalize = (GObjectFinalizeFunc)gtk_display_panel_finalize; - 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->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 */ - - g_signal_new("scaled", - GTK_TYPE_DISPLAY_PANEL, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GtkDisplayPanelClass, scaled), - NULL, NULL, - g_cclosure_user_marshal_VOID__DOUBLE_DOUBLE, - G_TYPE_NONE, 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à initialiser. * -* * -* Description : Procède à l'initialisation de l'afficheur générique. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_init(GtkDisplayPanel *panel) -{ - gtk_widget_set_has_window(GTK_WIDGET(panel), TRUE); - gtk_widget_set_can_focus(GTK_WIDGET(panel), TRUE); - - panel->scale = 1.0; - - panel->export = false; - -} - - -/****************************************************************************** -* * -* Paramètres : iface = interface GLib à initialiser. * -* * -* Description : Procède à l'initialisation de l'interface d'affichage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_loaded_interface_init(GLoadedPanelInterface *iface) -{ - iface->set_content = (set_loaded_panel_content_fc)gtk_display_panel_set_content; - iface->get_content = (get_loaded_panel_content_fc)gtk_display_panel_get_content; - - iface->get_cursor = (get_loaded_cursor_fc)gtk_display_panel_get_cursor; - iface->scroll = (scroll_loaded_to_cursor_fc)gtk_display_panel_scroll_to_cursor; - - iface->cache_glance = (cache_loaded_glance_fc)gtk_display_panel_cache_glance; - -} - - -/****************************************************************************** -* * -* Paramètres : panel = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_dispose(GtkDisplayPanel *panel) -{ - g_clear_object(&panel->hadjustment); - g_clear_object(&panel->vadjustment); - - g_clear_object(&panel->options); - - g_clear_object(&panel->binary); - - G_OBJECT_CLASS(gtk_display_panel_parent_class)->dispose(G_OBJECT(panel)); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_finalize(GtkDisplayPanel *panel) -{ - G_OBJECT_CLASS(gtk_display_panel_parent_class)->finalize(G_OBJECT(panel)); - -} - - -/****************************************************************************** -* * -* Paramètres : object = instance de composant GTK à manipuler. * -* prop_id = identifiant de la propriété concernée. * -* value = valeur attribuée. * -* pspec = spécification de la propriété visée. * -* * -* Description : Définit une propriété du composant d'affichage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - GtkDisplayPanel *panel; /* Autre vision de l'instance */ - - panel = GTK_DISPLAY_PANEL(object); - - switch (prop_id) - { - case VPP_HADJUSTMENT: - gtk_display_panel_set_adjustment(panel, 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)); - break; - case VPP_HSCROLL_POLICY: - //viewport->priv->hscroll_policy = g_value_get_enum (value); - //gtk_widget_queue_resize (GTK_WIDGET (viewport)); - break; - case VPP_VSCROLL_POLICY: - //viewport->priv->vscroll_policy = g_value_get_enum (value); - //gtk_widget_queue_resize (GTK_WIDGET (viewport)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } - -} - - -/****************************************************************************** -* * -* Paramètres : object = instance de composant GTK à manipuler. * -* prop_id = identifiant de la propriété concernée. * -* value = valeur à renvoyer. * -* pspec = spécification de la propriété visée. * -* * -* Description : Fournit une propriété du composant d'affichage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - GtkDisplayPanel *panel; /* Autre vision de l'instance */ - - panel = GTK_DISPLAY_PANEL(object); - - switch (prop_id) - { - case VPP_HADJUSTMENT: - g_value_set_object(value, panel->hadjustment); - break; - case VPP_VADJUSTMENT: - g_value_set_object(value, panel->vadjustment); - break; - case VPP_HSCROLL_POLICY: - g_value_set_enum(value, panel->hscroll_policy); - break; - case VPP_VSCROLL_POLICY: - g_value_set_enum(value, panel->vscroll_policy); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } - -} - - -/****************************************************************************** -* * -* Paramètres : widget = composant GTK à détruire. * -* * -* Description : Détruit un composant d'affichage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_destroy(GtkWidget *widget) -{ - GtkDisplayPanel *panel; /* Autre version du composant */ - - panel = GTK_DISPLAY_PANEL(widget); - - gtk_display_panel_disconnect_adjustment(panel, GTK_ORIENTATION_HORIZONTAL); - gtk_display_panel_disconnect_adjustment(panel, GTK_ORIENTATION_VERTICAL); - - GTK_WIDGET_CLASS(gtk_display_panel_parent_class)->destroy(widget); - -} - - -/****************************************************************************** -* * -* Paramètres : widget = composant GTK à préparer. * -* * -* Description : Encadre la construction graphique initiale de l'affichage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_realize(GtkWidget *widget) -{ - GtkAllocation allocation; /* Disposition du composant */ - GdkWindowAttr attributes; /* Propriétés du composant */ - guint attributes_mask; /* Masque de prise en compte */ - GdkWindow *window; /* Fenêtre du composant */ - - gtk_widget_get_allocation(widget, &allocation); - - gtk_widget_set_realized(widget, TRUE); - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = allocation.x; - attributes.y = allocation.y; - attributes.width = allocation.width; - attributes.height = allocation.height; - - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.event_mask = gtk_widget_get_events(widget) - | GDK_EXPOSURE_MASK - | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK - | GDK_FOCUS_CHANGE_MASK - | GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y; - - window = gdk_window_new(gtk_widget_get_parent_window(widget), - &attributes, attributes_mask); - - gtk_widget_set_window(widget, window); - gtk_widget_register_window(widget, window); - -} - - -/****************************************************************************** -* * -* 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); - -} - - -/****************************************************************************** -* * -* Paramètres : widget = composant GTK à examiner. * -* minimum = hauteur minimale à préciser ou NULL. [OUT] * -* natural = hauteur idéale à préciser ou NULL. [OUT] * -* * -* Description : Fournit la hauteur idéale pour le composant d'affichage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_get_preferred_height(GtkWidget *widget, gint *minimum, gint *natural) -{ - GtkDisplayPanel *panel; /* Autre version du composant */ - gint req; /* Dimension requise */ - - panel = GTK_DISPLAY_PANEL(widget); - - GTK_DISPLAY_PANEL_GET_CLASS(widget)->compute_size(panel, NULL, &req); - - req *= panel->scale; - - if (minimum != NULL) *minimum = req; - if (natural != NULL) *natural = req; - -} - - -/****************************************************************************** -* * -* Paramètres : widget = composant GTK à examiner. * -* minimum = largeur minimale à préciser ou NULL. [OUT] * -* natural = largeur idéale à préciser ou NULL. [OUT] * -* * -* Description : Fournit la largeur idéale pour le composant d'affichage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_get_preferred_width(GtkWidget *widget, gint *minimum, gint *natural) -{ - GtkDisplayPanel *panel; /* Autre version du composant */ - gint req; /* Dimension requise */ - - panel = GTK_DISPLAY_PANEL(widget); - - GTK_DISPLAY_PANEL_GET_CLASS(widget)->compute_size(panel, &req, NULL); - - req *= panel->scale; - - if (minimum != NULL) *minimum = req; - if (natural != NULL) *natural = req; - -} - - -/****************************************************************************** -* * -* 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; - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à consulter. * -* alloc = emplacement à déterminer. [OUT] * -* * -* Description : Détermine la taille allouée pour le contenu. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_compute_allocation(GtkDisplayPanel *panel, GtkAllocation *alloc) -{ - GtkWidget *widget; /* Autre vision du composant */ - GtkAllocation allocation; /* Emplacement du composant */ - GtkStyleContext *context; /* Contexte du style */ - GtkStateFlags state; /* Etat du composant */ - GtkBorder padding; /* Espace d'un espacement */ - GtkBorder border; /* Espace d'une bordure */ - - widget = GTK_WIDGET(panel); - - gtk_widget_get_allocation(widget, &allocation); - - context = gtk_widget_get_style_context(widget); - state = gtk_widget_get_state_flags(widget); - - gtk_style_context_save(context); - gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME); - - gtk_style_context_get_padding(context, state, &padding); - gtk_style_context_get_border(context, state, &border); - - gtk_style_context_restore(context); - - /* Positions */ - - if (panel->show_border) - { - alloc->x = border.left; - alloc->y = border.top; - } - else - { - alloc->x = 0; - alloc->y = 0; - } - - alloc->x += padding.left; - alloc->y += padding.top; - - /* Dimensions */ - - if (panel->show_border) - { - alloc->width = MAX (1, allocation.width - alloc->x - padding.right - border.right); - alloc->height = MAX (1, allocation.height - alloc->y - padding.bottom - border.bottom); - } - else - { - alloc->width = MAX (1, allocation.width - alloc->x - padding.right); - alloc->height = MAX (1, allocation.height - alloc->y - padding.bottom); - } - -} - - -/****************************************************************************** -* * -* 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); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à mettre à jour. * -* * -* Description : Indique l'échelle appliquée à l'affichage du composant. * -* * -* Retour : Echelle appliquée à l'affichage. * -* * -* Remarques : - * -* * -******************************************************************************/ - -double gtk_display_panel_get_scale(const GtkDisplayPanel *panel) -{ - double result; /* Echelle à retourner */ - - result = panel->scale; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à mettre à jour. * -* scale = échelle appliquée à l'affichage. * -* * -* Description : Spécifie l'échelle à appliquer à l'affichage du composant. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_display_panel_set_scale(GtkDisplayPanel *panel, double scale) -{ - double old_scale; /* Echelle précédente */ - GtkDisplayPanelClass *class; /* Classe associée au composant*/ - - if (scale > 1.0) - scale = 1.0; - - else if (scale < 0.01) - scale = 0.01; - - if (panel->scale != scale) - { - old_scale = panel->scale; - - panel->scale = scale; - - class = GTK_DISPLAY_PANEL_GET_CLASS(panel); - - if (class->scale != NULL) - class->scale(panel, old_scale, scale); - - gtk_widget_queue_resize(GTK_WIDGET(panel)); - - g_signal_emit_by_name(panel, "scaled", old_scale, scale); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à mettre à jour. * -* show = état de l'affichage auquel parvenir. * -* * -* Description : Définit si une bordure est à afficher. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_display_panel_show_border(GtkDisplayPanel *panel, bool show) -{ - panel->show_border = show; - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à mettre à jour. * -* export = préparation d'une exportation complète du rendu ? * -* * -* Description : Marque ou non le composant pour une exportation prochaine. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_display_panel_prepare_export(GtkDisplayPanel *panel, bool export) -{ - GtkDisplayPanelClass *class; /* Classe associée au composant*/ - - panel->export = export; - - class = GTK_DISPLAY_PANEL_GET_CLASS(panel); - - if (class->prepare_export != NULL) - class->prepare_export(panel, export); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à venir consulter. * -* cr = contexte graphique associé à l'événement. * -* area = surface à considérer. * -* * -* Description : Définit un chemin décrivant la bordure autour du panneau. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_display_panel_define_border_path(GtkDisplayPanel *panel, cairo_t *cr, const GtkAllocation *area) -{ - double degrees; /* Conversion en degrés */ - - degrees = M_PI / 180.0; - - cairo_new_sub_path(cr); - - cairo_arc(cr, - area->x + area->width - BORDER_CORNER_RADIUS - 0.5, - area->y + BORDER_CORNER_RADIUS + 0.5, - BORDER_CORNER_RADIUS, -90 * degrees, 0 * degrees); - - cairo_arc(cr, - area->x + area->width - BORDER_CORNER_RADIUS - 0.5, - area->y + area->height - BORDER_CORNER_RADIUS - 0.5, - BORDER_CORNER_RADIUS, 0 * degrees, 90 * degrees); - - cairo_arc(cr, - area->x + BORDER_CORNER_RADIUS + 0.5, - area->y + area->height - BORDER_CORNER_RADIUS - 0.5, - BORDER_CORNER_RADIUS, 90 * degrees, 180 * degrees); - - cairo_arc(cr, - area->x + BORDER_CORNER_RADIUS + 0.5, - area->y + BORDER_CORNER_RADIUS + 0.5, - BORDER_CORNER_RADIUS, 180 * degrees, 270 * degrees); - - cairo_close_path(cr); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à venir consulter. * -* cr = contexte graphique associé à l'événement. * -* * -* Description : Dessine si besoin est une bordure autour du composant. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_display_panel_draw_border(GtkDisplayPanel *panel, cairo_t *cr) -{ - GtkWidget *widget; /* Autre version du composant */ - GtkStyleContext *context; /* Contexte du thème actuel */ - GdkRGBA color; /* Couleur de thème récupérée */ - GtkRequisition req; /* Taille allouée à l'élément */ - GtkAllocation area; /* Emplacement à considérer */ - - if (panel->show_border) - { - widget = GTK_WIDGET(panel); - - gtk_widget_get_preferred_size(widget, NULL, &req); - - context = gtk_widget_get_style_context(widget); - - gtk_style_context_save(context); - - gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME); - - gtk_style_context_get(gtk_widget_get_style_context(widget), - gtk_widget_get_state_flags(widget), - GTK_STYLE_PROPERTY_COLOR, &color, NULL); - - cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha); - - cairo_set_line_width(cr, 1.0); - - gtk_widget_get_preferred_size(GTK_WIDGET(panel), NULL, &req); - - area.x = 0; - area.y = 0; - area.width = req.width; - area.height = req.height; - - gtk_display_panel_define_border_path(panel, cr, &area); - cairo_stroke(cr); - - gtk_style_context_restore(context); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à consulter. * -* cursor = emplacement à présenter à l'écran. * -* x = position horizontale au sein du composant. [OUT] * -* y = position verticale au sein du composant. [OUT] * -* tweak = adaptation finale à effectuer. * -* * -* Description : Indique la position d'affichage d'un emplacement donné. * -* * -* Retour : true si l'adresse fait partie du composant, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool gtk_display_panel_get_cursor_coordinates(const GtkDisplayPanel *panel, const GLineCursor *cursor, gint *x, gint *y, ScrollPositionTweak tweak) -{ - bool result; /* Bilan à remonter */ - - result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_coordinates(panel, cursor, x, y, tweak); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à consulter. * -* * -* Description : Fournit l'élément actif lié à la position courante. * -* * -* Retour : Objet actif courant ou NULL si aucun. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GObject *gtk_display_panel_get_active_object(const GtkDisplayPanel *panel) -{ - GObject *result; /* Trouvaille à retourner */ - - if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_active == NULL) - result = NULL; - - else - result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_active(panel); - - if (result != NULL) - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à manipuler. * -* addr = adresse à présenter à l'écran. * -* * -* Description : Demande à qui veut répondre un déplacement du curseur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_display_panel_request_move(GtkDisplayPanel *panel, const vmpa2t *addr) -{ - GLineCursor *___tmp; - - ___tmp = g_binary_cursor_new(); - g_binary_cursor_update(G_BINARY_CURSOR(___tmp), addr); - - g_loaded_panel_request_move(G_LOADED_PANEL(panel), ___tmp, false); - - g_object_unref(G_OBJECT(___tmp)); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à consulter. * -* event = informations liées à l'événement. * -* * -* Description : Transcrit les coordonnées à l'écran en coordonnées absolues. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_display_panel_compute_fake_coord(GtkDisplayPanel *panel, gint *x, gint *y) -{ - if (panel->hadjustment != NULL) - *x -= gtk_adjustment_get_value(panel->hadjustment); - - if (panel->vadjustment != NULL) - *y += gtk_adjustment_get_value(panel->vadjustment); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à consulter. * -* event = informations liées à l'événement. * -* * -* Description : Transcrit les coordonnées absolues en coordonnées à l'écran. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_display_panel_compute_real_coord(GtkDisplayPanel *panel, gint *x, gint *y) -{ - if (x != NULL && panel->hadjustment != NULL) - *x += gtk_adjustment_get_value(panel->hadjustment); - - if (y != NULL && panel->vadjustment != NULL) - *y += gtk_adjustment_get_value(panel->vadjustment); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à consulter. * -* x = abscisse à ajuster. [OUT] * -* x = ordonnée à ajuster. [OUT] * -* * -* Description : Transcrit les coordonnées absolues en coordonnées à l'écran. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_display_panel_compute_relative_coords(GtkDisplayPanel *panel, gint *x, gint *y) -{ - if (x != NULL && panel->hadjustment != NULL) - *x -= gtk_adjustment_get_value(panel->hadjustment); - - if (y != NULL && panel->vadjustment != NULL) - *y -= gtk_adjustment_get_value(panel->vadjustment); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* INTERFACE DE PANNEAU DE CHARGEMENT */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : options = options à mettre à jour. * -* index = indice de l'option concernée. * -* value = nouvelle valeur à intégrer. * -* panel = composant GTK à consulter. * -* * -* Description : Réagit à un changement des règles d'affichage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void on_display_panel_option_change(GDisplayOptions *options, size_t index, bool value, GtkDisplayPanel *panel) -{ - gtk_widget_queue_resize(gtk_widget_get_parent(GTK_WIDGET(panel))); - gtk_widget_queue_resize(GTK_WIDGET(panel)); - gtk_widget_queue_draw(GTK_WIDGET(panel)); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à mettre à jour. * -* content = binaire associé à intégrer. * -* * -* Description : Associe à un panneau d'affichage un binaire chargé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_set_content(GtkDisplayPanel *panel, GLoadedContent *content) -{ - panel->view_index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); - - panel->options = g_loaded_content_get_display_options(content, panel->view_index); - - panel->binary = G_LOADED_BINARY(content); - - g_signal_connect(panel->options, "value-changed", G_CALLBACK(on_display_panel_option_change), panel); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à consulter. * -* * -* Description : Fournit le contenu associé à un panneau de chargement. * -* * -* Retour : Contenu quelconque chargé en mémoire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GLoadedContent *gtk_display_panel_get_content(const GtkDisplayPanel *panel) -{ - GLoadedContent *result; /* Contenu à retourner */ - - result = G_LOADED_CONTENT(panel->binary); - - if (result != NULL) - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à consulter. * -* * -* Description : Fournit le position courante dans un panneau de chargement. * -* * -* Retour : Informations relatives à la position du curseur. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GLineCursor *gtk_display_panel_get_cursor(const GtkDisplayPanel *panel) -{ - GLineCursor *result; /* Contenu à retourner */ - - result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_cursor(panel); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à manipuler. * -* cursor = emplacement à présenter à l'écran. * -* tweak = adaptation finale à effectuer. * -* move = doit-on déplacer le curseur à l'adresse indiquée ? * -* * -* Description : S'assure qu'un emplacement donné est visible à l'écran. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_scroll_to_cursor(GtkDisplayPanel *panel, const GLineCursor *cursor, ScrollPositionTweak tweak, bool move) -{ - GtkWidget *parent; /* Support parent à valider */ - GtkDisplayPanelClass *class; /* Classe de l'instance */ - gint x; /* Abscisse à garantir */ - gint y; /* Ordonnée à garantir */ - GtkWidget *viewport; /* Parent avec défilement */ - GtkAdjustment *adj; /* Défilement à mettre à jour */ - gdouble step_inc; /* Valeur d'un petit pas */ - gdouble page_size; /* Taille de l'affichage */ - double value; /* Valeur courante */ - - /** - * Si une vue partielle se déplace via cette fonction, il faut potentiellement - * rediriger l'appel vers la vue en graphiques parente. - */ - - parent = gtk_widget_get_parent(GTK_WIDGET(panel)); - parent = gtk_widget_get_parent(GTK_WIDGET(parent)); - - if (GTK_IS_DISPLAY_PANEL(parent)) - panel = GTK_DISPLAY_PANEL(parent); - - class = GTK_DISPLAY_PANEL_GET_CLASS(panel); - - if (class->prepare != NULL) - class->prepare(panel, cursor); - - if (gtk_display_panel_get_cursor_coordinates(panel, cursor, &x, &y, tweak)) - { - viewport = gtk_widget_get_parent(GTK_WIDGET(panel)); - - /* Eventuel défilement horizontal */ - - g_object_get(G_OBJECT(viewport), "hadjustment", &adj, NULL); - - step_inc = gtk_adjustment_get_step_increment(adj); - page_size = gtk_adjustment_get_page_size(adj); - value = gtk_adjustment_get_value(adj); - - if (x < value) - gtk_adjustment_set_value(adj, x); - - else if ((x + step_inc) > (value + page_size)) - gtk_adjustment_set_value(adj, x + step_inc - page_size); - - /* Eventuel défilement vertical */ - - g_object_get(G_OBJECT(viewport), "vadjustment", &adj, NULL); - - step_inc = gtk_adjustment_get_step_increment(adj); - page_size = gtk_adjustment_get_page_size(adj); - value = gtk_adjustment_get_value(adj); - - if (y < value || tweak != SPT_RAW) - gtk_adjustment_set_value(adj, y); - - else if ((y + step_inc) > (value + page_size)) - gtk_adjustment_set_value(adj, y + step_inc - page_size); - - /* Déplacement du curseur */ - - if (move && gtk_display_panel_get_cursor_coordinates(panel, cursor, &x, &y, SPT_RAW)) - class->move_caret_to(panel, x, y); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant GTK à manipuler. * -* cairo = assistant pour la création de rendus. * -* area = taille de la surface réduite à disposition. * -* scale = échelle vis à vis de la taille réelle. * -* * -* Description : Place en cache un rendu destiné à l'aperçu graphique rapide. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_cache_glance(GtkDisplayPanel *panel, cairo_t *cairo, const GtkAllocation *area, double scale) -{ - if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance != NULL) - GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance(panel, cairo, area, scale); - -} diff --git a/src/gtkext/gtkdisplaypanel.h b/src/gtkext/gtkdisplaypanel.h deleted file mode 100644 index 58d460f..0000000 --- a/src/gtkext/gtkdisplaypanel.h +++ /dev/null @@ -1,78 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gtkdisplaypanel.h - prototypes pour l'affichage de contenus de binaire - * - * Copyright (C) 2016-2019 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 . - */ - - -#ifndef _GTKEXT_DISPLAYPANEL_H -#define _GTKEXT_DISPLAYPANEL_H - - -#include -#include - - -#include "../arch/vmpa.h" -#include "../glibext/gloadedpanel.h" - - - -#define GTK_TYPE_DISPLAY_PANEL (gtk_display_panel_get_type()) -#define GTK_DISPLAY_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_DISPLAY_PANEL, GtkDisplayPanel)) -#define GTK_DISPLAY_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_DISPLAY_PANEL, GtkDisplayPanelClass)) -#define GTK_IS_DISPLAY_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_DISPLAY_PANEL)) -#define GTK_IS_DISPLAY_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_DISPLAY_PANEL)) -#define GTK_DISPLAY_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_DISPLAY_PANEL, GtkDisplayPanelClass)) - - -/* Composant d'affichage générique (instance) */ -typedef struct _GtkDisplayPanel GtkDisplayPanel; - -/* Composant d'affichage générique (classe) */ -typedef struct _GtkDisplayPanelClass GtkDisplayPanelClass; - - -/* Détermine le type du composant d'affichage générique. */ -GType gtk_display_panel_get_type(void); - -/* Indique l'échelle appliquée à l'affichage du composant. */ -double gtk_display_panel_get_scale(const GtkDisplayPanel *); - -/* Spécifie l'échelle à appliquer à l'affichage du composant. */ -void gtk_display_panel_set_scale(GtkDisplayPanel *, double); - -/* Définit si une bordure est à afficher. */ -void gtk_display_panel_show_border(GtkDisplayPanel *, bool); - -/* Marque ou non le composant pour une exportation prochaine. */ -void gtk_display_panel_prepare_export(GtkDisplayPanel *, bool); - -/* Indique la position d'affichage d'un emplacement donné. */ -bool gtk_display_panel_get_cursor_coordinates(const GtkDisplayPanel *, const GLineCursor *, gint *, gint *, ScrollPositionTweak); - -/* Fournit l'élément actif lié à la position courante. */ -GObject *gtk_display_panel_get_active_object(const GtkDisplayPanel *); - -/* Demande à qui veut répondre un déplacement du curseur. */ -void gtk_display_panel_request_move(GtkDisplayPanel *, const vmpa2t *); - - - -#endif /* _GTKEXT_DISPLAYPANEL_H */ diff --git a/src/gtkext/rendering.c b/src/gtkext/rendering.c deleted file mode 100644 index 8badf21..0000000 --- a/src/gtkext/rendering.c +++ /dev/null @@ -1,205 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * rendering.h - prototypes pour la transformation de paramètres du thème GTK courant - * - * Copyright (C) 2018 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "rendering.h" - - -#include -#include -#include -#include - - -#include "../common/extstr.h" - - - -/****************************************************************************** -* * -* Paramètres : name = désignation d'un élément dans une feuille de style.* -* pattern = paramètres restitués en interne. |OUT] * -* * -* Description : Récupère les informations de rendus d'un élément de thème. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void load_rendering_pattern(const char *name, rendering_pattern_t *pattern) -{ - GtkStyleContext *context; /* Contexte pour les styles */ - GtkWidgetPath *path; /* Chemin d'accès aux thèmes */ - GdkRGBA *tmp_color; /* Description d'une couleur */ - PangoFontDescription *font_desc; /* Description d'une police */ - - /* Création d'un contexte d'accès */ - - path = gtk_widget_path_new(); - gtk_widget_path_append_type(path, G_TYPE_OBJECT); - - context = gtk_style_context_new(); - gtk_style_context_set_path(context, path); - gtk_style_context_set_screen(context, gdk_screen_get_default()); - - gtk_style_context_add_class(context, name); - - gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_COLOR, &tmp_color, NULL); - - pattern->foreground.has_color = true; - pattern->foreground.color = *tmp_color; - - pattern->inverted.has_color = true; - pattern->inverted.color.red = 1.0 - tmp_color->red; - pattern->inverted.color.green = 1.0 - tmp_color->green; - pattern->inverted.color.blue = 1.0 - tmp_color->blue; - pattern->inverted.color.alpha = tmp_color->alpha; - - gdk_rgba_free(tmp_color); - - gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL); - - switch (pango_font_description_get_style(font_desc)) - { - case PANGO_STYLE_NORMAL: - pattern->slant = CAIRO_FONT_SLANT_NORMAL; - break; - case PANGO_STYLE_ITALIC: - pattern->slant = CAIRO_FONT_SLANT_ITALIC; - break; - case PANGO_STYLE_OBLIQUE: - pattern->slant = CAIRO_FONT_SLANT_OBLIQUE; - break; - } - - switch (pango_font_description_get_weight(font_desc)) - { - case PANGO_WEIGHT_THIN: - case PANGO_WEIGHT_ULTRALIGHT: - case PANGO_WEIGHT_LIGHT: - case PANGO_WEIGHT_SEMILIGHT: - case PANGO_WEIGHT_BOOK: - case PANGO_WEIGHT_NORMAL: - case PANGO_WEIGHT_MEDIUM: - pattern->weight = CAIRO_FONT_WEIGHT_NORMAL; - break; - case PANGO_WEIGHT_SEMIBOLD: - case PANGO_WEIGHT_BOLD: - case PANGO_WEIGHT_ULTRABOLD: - case PANGO_WEIGHT_HEAVY: - case PANGO_WEIGHT_ULTRAHEAVY: - pattern->weight = CAIRO_FONT_WEIGHT_BOLD; - break; - } - - pango_font_description_free(font_desc); - - gtk_widget_path_free(path); - g_object_unref(context); - -} - - -/****************************************************************************** -* * -* Paramètres : text = texte à encadrer par des balises Pango. * -* pattern = paramètres restitués en interne. * -* * -* Description : Enjolive du texte selon les paramètres d'un élément de thème.* -* * -* Retour : Chaîne de caractère à libérer après usage. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *build_pango_markup_for(const char *text, const rendering_pattern_t *pattern) -{ - char *result; /* Construction à retourner */ - char color[10]; /* Définition hexa de couleur */ - - result = strdup(text); - - if (pattern->foreground.has_color) - { - snprintf(color, sizeof(color), "#%02hhx%02hhx%02hhx%02hhx", - (unsigned char)(255 * pattern->foreground.color.red), - (unsigned char)(255 * pattern->foreground.color.green), - (unsigned char)(255 * pattern->foreground.color.blue), - (unsigned char)(255 * pattern->foreground.color.alpha)); - - result = strprep(result, "\">"); - result = strprep(result, color); - result = strprep(result, ""); - - } - - if (pattern->slant == CAIRO_FONT_SLANT_ITALIC || pattern->slant == CAIRO_FONT_SLANT_OBLIQUE) - { - result = strprep(result, ""); - result = stradd(result, ""); - } - - if (pattern->weight == CAIRO_FONT_WEIGHT_BOLD) - { - result = strprep(result, ""); - result = stradd(result, ""); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : base = base de texte à compléter. * -* text = texte à encadrer par des balises Pango. * -* pattern = paramètres restitués en interne. * -* * -* Description : Ajoute du texte enjolivé selon un élément de thème. * -* * -* Retour : Chaîne de caractère à libérer après usage. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *append_pango_markup_with(char *base, const char *text, const rendering_pattern_t *pattern) -{ - char *result; /* Construction à retourner */ - char *tmp; /* Stockage temporaire */ - - tmp = build_pango_markup_for(text, pattern); - - result = stradd(base, tmp); - - free(tmp); - - return result; - -} diff --git a/src/gtkext/rendering.h b/src/gtkext/rendering.h deleted file mode 100644 index 9adfe1a..0000000 --- a/src/gtkext/rendering.h +++ /dev/null @@ -1,65 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * rendering.h - prototypes pour la transformation de paramètres du thème GTK courant - * - * Copyright (C) 2018 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _GTKEXT_RENDERING_H -#define _GTKEXT_RENDERING_H - - -#include -#include - - - -/* Restitution d'une couleur */ -typedef struct _rendering_color_t -{ - GdkRGBA color; /* Couleur de rendu */ - bool has_color; /* Définition en place ? */ - -} rendering_color_t; - -/* Restitution d'un élément de thème */ -typedef struct _rendering_pattern_t -{ - rendering_color_t foreground; /* Couleur d'impression */ - rendering_color_t inverted; /* Couleur inversée pour sél. */ - - cairo_font_slant_t slant; /* Style d'impression */ - cairo_font_weight_t weight; /* Poids de la police */ - -} rendering_pattern_t; - - -/* Récupère les informations de rendus d'un élément de thème. */ -void load_rendering_pattern(const char *, rendering_pattern_t *); - -/* Enjolive du texte selon les paramètres d'un élément de thème. */ -char *build_pango_markup_for(const char *, const rendering_pattern_t *); - -/* Ajoute du texte enjolivé selon un élément de thème. */ -char *append_pango_markup_with(char *, const char *, const rendering_pattern_t *); - - - -#endif /* _GTKEXT_RENDERING_H */ -- cgit v0.11.2-87-g4458