summaryrefslogtreecommitdiff
path: root/src/glibext/gbinportion.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2013-08-31 15:56:10 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2013-08-31 15:56:10 (GMT)
commited4bb73e5d68c1f81b8e0c3210aa221ec6f2675b (patch)
tree006a4641fc7a5c820d6a4253ff75e79ef01e368b /src/glibext/gbinportion.c
parent4658d4fa406bad4abe36a76746412cf02c984af0 (diff)
Loaded a binary strip into the editor.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@358 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/glibext/gbinportion.c')
-rw-r--r--src/glibext/gbinportion.c938
1 files changed, 938 insertions, 0 deletions
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c
new file mode 100644
index 0000000..8272e55
--- /dev/null
+++ b/src/glibext/gbinportion.c
@@ -0,0 +1,938 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * binportion.c - représentation graphique de portions de binaire
+ *
+ * Copyright (C) 2013 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "gbinportion.h"
+
+
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include <i18n.h>
+
+
+#include "../common/extstr.h"
+
+
+
+/* --------------------------- COULEURS DE REPRESENTATION --------------------------- */
+
+
+/* Information sur une colorisation de portion */
+typedef struct _portion_color
+{
+ bp_color_t code; /* Identifiant pour les usages */
+ char *name; /* Désignation humaine */
+
+ double red; /* Taux de rouge */
+ double green; /* Taux de vert */
+ double blue; /* Taux de bleu */
+ double alpha; /* Transparence */
+
+} portion_color;
+
+
+/* Mémoire centrale... */
+static portion_color *_portion_colors = NULL;
+static size_t _portion_colors_count = 0;
+
+
+/* Compare deux enregistrements de couleur pour portions. */
+static int compare_portion_colors(const portion_color *, const portion_color *);
+
+/* Tente de retrouver une couleur de portion donnée. */
+static portion_color *find_binary_portion_color(bp_color_t);
+
+
+
+/* ------------------------------- PORTION DE BINAIRE ------------------------------- */
+
+
+/* Portion de données binaires quelconques (instance) */
+struct _GBinPortion
+{
+ GObject parent; /* A laisser en premier */
+
+ GBinPortion *container; /* Portion parente ou racine */
+
+ bp_color_t code; /* Code de la couleur de fond */
+
+ char *desc; /* Désignation humaine */
+
+ off_t offset; /* Position physique */
+ off_t size; /* Taille de la partie */
+ vmpa_t addr; /* Adresse associée */
+
+ PortionAccessRights rights; /* Droits d'accès */
+
+ GBinPortion **sub_portions; /* Portions incluses */
+ size_t sub_count; /* Quantité d'inclusions */
+
+#ifdef DEBUG
+ unsigned int valid; /* Instructions reconnues */
+ unsigned int db; /* Instructions non traduites */
+#endif
+
+};
+
+/* Portion de données binaires quelconques (classe) */
+struct _GBinPortionClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des blocs de données binaires. */
+static void g_binary_portion_class_init(GBinPortionClass *);
+
+/* Initialise une instance de bloc de données binaires. */
+static void g_binary_portion_init(GBinPortion *);
+
+/* Supprime toutes les références externes. */
+static void g_binary_portion_dispose(GBinPortion *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_binary_portion_finalize(GBinPortion *);
+
+/* Détermine l'aire d'une sous-portion. */
+static bool g_binary_portion_compute_sub_area(GBinPortion *, GBinPortion *, const GdkRectangle *, GdkRectangle *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* COULEURS DE REPRESENTATION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : a = échantillon n°1 à comparer. *
+* b = échantillon n°2 à comparer. *
+* *
+* Description : Compare deux enregistrements de couleur pour portions. *
+* *
+* Retour : Bilan de la comparaison. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int compare_portion_colors(const portion_color *a, const portion_color *b)
+{
+ int result; /* Bilan à renvoyer */
+
+ if (a->code < b->code)
+ result = -1;
+
+ else if (a->code > b->code)
+ result = 1;
+
+ else
+ result = 0;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : name = désignation humaine de la couleur. *
+* red = taux de rouge dans la couleur. *
+* gren = taux de vert dans la couleur. *
+* blue = taux de bleu dans la couleur. *
+* alpha = transparence de la couleur. *
+* *
+* Description : Enregistre une couleur pour le dessin de portions. *
+* *
+* Retour : true si l'enregistrement a pu être effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_binary_portion_color(const char *name, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
+{
+ bp_color_t code; /* Accès rapide à la couleur */
+ portion_color *new; /* Nouvel élément à constituer */
+
+ /* Vérification de l'unicité des noms */
+
+ code = fnv_64a_hash(name);
+
+ new = find_binary_portion_color(code);
+ if (new != NULL) return false;
+
+ /* Création du nouvel élément */
+
+ _portion_colors = (portion_color *)realloc(_portion_colors,
+ ++_portion_colors_count * sizeof(portion_color));
+
+ new = &_portion_colors[_portion_colors_count - 1];
+
+ /* Définition du nouvel élément */
+
+ new->name = strdup(name);
+ new->code = code;
+
+ new->red = red / 255.0;
+ new->green = green / 255.0;
+ new->blue = blue / 255.0;
+ new->alpha = alpha / 255.0;
+
+ /* Actualisation finale par tri */
+
+ qsort(_portion_colors, _portion_colors_count, sizeof(portion_color),
+ (__compar_fn_t)compare_portion_colors);
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : name = désignation humaine de la couleur. *
+* *
+* Description : Supprime une couleur pour le dessin de portions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void unregister_binary_portion_color(const char *name)
+{
+ bp_color_t code; /* Accès rapide à la couleur */
+ portion_color *item; /* Elément à retirer */
+ size_t left; /* Quantité à déplacer */
+
+ code = fnv_64a_hash(name);
+
+ item = find_binary_portion_color(code);
+ if (item == NULL) return;
+
+ free(item->name);
+
+ left = (size_t)(_portion_colors + _portion_colors_count) - (size_t)(item + 1);
+
+ if (left > 0)
+ memmove(item, item + 1, left);
+
+ _portion_colors = (portion_color *)realloc(_portion_colors,
+ --_portion_colors_count * sizeof(portion_color));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : code = identifiant de la couleur à retrouver. *
+* *
+* Description : Tente de retrouver une couleur de portion donnée. *
+* *
+* Retour : Caractéristiques de la couleur visée, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static portion_color *find_binary_portion_color(bp_color_t code)
+{
+ portion_color *result; /* Elément trouvé à retourner */
+
+ result = (portion_color *)bsearch(&code, _portion_colors,
+ _portion_colors_count, sizeof(portion_color),
+ (__compar_fn_t)compare_portion_colors);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Enregistre les couleurs de base pour le dessin des portions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void init_binary_portion_colors(void)
+{
+ register_binary_portion_color(BPC_RAW, 0, 0, 0, 255);
+ register_binary_portion_color(BPC_CODE, 0, 0, 255, 255);
+ register_binary_portion_color(BPC_DATA, 255, 255, 0, 255);
+ register_binary_portion_color(BPC_DATA_RO, 0, 255, 0, 255);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Supprime les couleurs de base pour le dessin des portions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void exit_binary_portion_colors(void)
+{
+ while (_portion_colors_count > 0)
+ unregister_binary_portion_color(_portion_colors[0].name);
+
+ if (_portion_colors != NULL)
+ {
+ free(_portion_colors);
+ _portion_colors = NULL;
+ }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* PORTION DE BINAIRE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini par la GLib pour les blocs de données. */
+G_DEFINE_TYPE(GBinPortion, g_binary_portion, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des blocs de données binaires. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_binary_portion_class_init(GBinPortionClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_portion_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_binary_portion_finalize;
+
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = instance à initialiser. *
+* *
+* Description : Initialise une instance de bloc de données binaires. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_binary_portion_init(GBinPortion *portion)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_binary_portion_dispose(GBinPortion *portion)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < portion->sub_count; i++)
+ g_object_unref(G_OBJECT(portion->sub_portions[i]));
+
+ G_OBJECT_CLASS(g_binary_portion_parent_class)->dispose(G_OBJECT(portion));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_binary_portion_finalize(GBinPortion *portion)
+{
+ if (portion->desc != NULL)
+ free(portion->desc);
+
+ if (portion->sub_portions != NULL)
+ free(portion->sub_portions);
+
+ G_OBJECT_CLASS(g_binary_portion_parent_class)->finalize(G_OBJECT(portion));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : code = désignation humaine de la couleur de fond. *
+* *
+* Description : Crée une description de partie de code vierge. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinPortion *g_binary_portion_new(const char *code)
+{
+ GBinPortion *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_BIN_PORTION, NULL);
+
+ result->code = fnv_64a_hash(code);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* desc = nom à donner à la partie. *
+* *
+* Description : Attribue une description humaine à une partie de code. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_portion_set_desc(GBinPortion *portion, const char *desc)
+{
+ if (portion->desc != NULL) free(portion->desc);
+
+ portion->desc = strdup(desc);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à consulter. *
+* *
+* Description : Fournit la description attribuée à une partie de code. *
+* *
+* Retour : Nom donné à la partie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *g_binary_portion_get_desc(const GBinPortion *portion)
+{
+ return portion->desc;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* offset = position de la section à conserver. *
+* size = taille de la section à conserver. *
+* addr = adresse de la section à conserver. *
+* *
+* Description : Définit les valeurs utiles d'une partie de code. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_portion_set_values(GBinPortion *portion, off_t offset, off_t size, vmpa_t addr)
+{
+ portion->offset = offset;
+ portion->size = size;
+ portion->addr = addr;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* rights = droits d'accès de la partie. *
+* *
+* Description : Définit les droits associés à une partie de code. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_portion_set_rights(GBinPortion *portion, PortionAccessRights rights)
+{
+ portion->rights = rights;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à consulter. *
+* *
+* Description : Fournit les droits associés à une partie de code. *
+* *
+* Retour : Droits d'accès de la partie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PortionAccessRights g_binary_portion_get_rights(const GBinPortion *portion)
+{
+ return portion->rights;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* sub = portion à inclure dans la définition courante. *
+* *
+* Description : Procède à l'inclusion d'une portion dans une autre. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub)
+{
+ portion->sub_portions = (GBinPortion **)realloc(portion->sub_portions,
+ ++portion->sub_count * sizeof(GBinPortion *));
+
+ portion->sub_portions[portion->sub_count - 1] = sub;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = portion mère à consulter. *
+* sub = portion fille à traiter. *
+* area = étendue de représentation de la portion mère. *
+* sub_area = étendue de représentation de la portion fille. *
+* *
+* Description : Détermine l'aire d'une sous-portion. *
+* *
+* Retour : true si la sous-surface a été calculée correctement. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_binary_portion_compute_sub_area(GBinPortion *portion, GBinPortion *sub, const GdkRectangle *area, GdkRectangle *sub_area)
+{
+ /* On saute les portions comme le segment GNU_STACK... */
+ if (sub->size == 0) return false;
+
+ sub_area->y = area->y;
+ sub_area->height = area->height;
+
+ sub_area->x = area->x + (sub->offset * area->width) / portion->size;
+ sub_area->width = (sub->size * area->width) / portion->size;
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* x = abscisse du point de recherche. *
+* y = ordonnée du point de recherche. *
+* area = étendue de portion mère, puis celle trouvée. [OUT] *
+* *
+* Description : Recherche la portion présente à un point donné. *
+* *
+* Retour : Portion trouvée à l'endroit indiqué. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinPortion *g_binary_portion_find_at_pos(GBinPortion *portion, gint x, GdkRectangle *area)
+{
+ GBinPortion *result; /* Portion à retourner */
+ size_t i; /* Boucle de parcours */
+ GBinPortion *sub; /* Portion incluse à traiter */
+ GdkRectangle sub_area; /* Etendue d'une sous-portion */
+
+ result = NULL;
+
+ for (i = 0; i < portion->sub_count && !result; i++)
+ {
+ sub = portion->sub_portions[i];
+
+ if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area))
+ continue;
+
+ if (sub_area.x <= x && x < (sub_area.x + sub_area.width))
+ {
+ result = sub;
+ *area = sub_area;
+ }
+
+ }
+
+ if (result == NULL)
+ result = portion;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* addr = adresse du point de recherche. *
+* area = étendue de portion mère, puis celle trouvée. [OUT] *
+* *
+* Description : Recherche la portion présente à une adresse donnée. *
+* *
+* Retour : Portion trouvée à l'endroit indiqué. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, vmpa_t addr, GdkRectangle *area)
+{
+ GBinPortion *result; /* Portion à retourner */
+ size_t i; /* Boucle de parcours #1 */
+ GBinPortion *sub; /* Portion incluse à traiter */
+ GdkRectangle sub_area; /* Etendue d'une sous-portion */
+ size_t j; /* Boucle de parcours #2 */
+
+ result = NULL;
+
+ for (i = 0; i < portion->sub_count && !result; i++)
+ {
+ sub = portion->sub_portions[i];
+
+ /* Portion non allouée en mémoire -> adresse nulle ; on écarte */
+ if (sub->addr == 0)
+ continue;
+
+ if (addr < sub->addr || addr >= (sub->addr + sub->size))
+ continue;
+
+ if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area))
+ continue;
+
+ for (j = 0; j < sub->sub_count && !result; j++)
+ result = g_binary_portion_find_at_addr(sub->sub_portions[j], addr, &sub_area);
+
+ if (result == NULL)
+ {
+ result = sub;
+ *area = sub_area;
+ }
+
+ }
+
+ if (result == NULL)
+ result = portion;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* x = abscisse du point de recherche. *
+* area = étendue de représentation de la portion mère. *
+* addr = adresse correspondante. [OUT] *
+* *
+* Description : Fournit la position correspondant à une adresse donnée. *
+* *
+* Retour : Succès de la traduction. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_portion_get_addr_from_pos(GBinPortion *portion, gint x, const GdkRectangle *area, vmpa_t *addr)
+{
+ GdkRectangle owner_area; /* Aire de contenance */
+ GBinPortion *owner; /* Conteneur propriétaire */
+
+ owner_area = *area;
+
+ owner = g_binary_portion_find_at_pos(portion, x, &owner_area);
+ if (owner == NULL) return false;
+
+ *addr = owner->addr + (owner->size * (x - owner_area.x)) / owner_area.width;
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* addr = adresse du point de recherche. *
+* area = étendue de représentation de la portion mère. *
+* x = position correspondante. [OUT] *
+* *
+* Description : Fournit l'adresse correspondant à une position donnée. *
+* *
+* Retour : Succès de la traduction. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_portion_get_pos_from_addr(GBinPortion *portion, vmpa_t addr, const GdkRectangle *area, gint *x)
+{
+ GdkRectangle owner_area; /* Aire de contenance */
+ GBinPortion *owner; /* Conteneur propriétaire */
+ vmpa_t diff; /* Décallage à appliquer */
+
+ owner_area = *area;
+
+ owner = g_binary_portion_find_at_addr(portion, addr, &owner_area);
+ if (owner == NULL) return false;
+
+ diff = addr - owner->addr;
+
+ *x = owner_area.x + (diff * owner_area.width) / owner->size;
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* x = abscisse du point de recherche. *
+* y = ordonnée du point de recherche. *
+* area = étendue de représentation de la portion mère. *
+* tooltip = astuce à compléter. [OUT] *
+* *
+* Description : Prépare une astuce concernant une portion pour son affichage.*
+* *
+* Retour : TRUE pour valider l'affichage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+gboolean g_binary_portion_query_tooltip(GBinPortion *portion, gint x, gint y, const GdkRectangle *area, GtkTooltip *tooltip)
+{
+ GBinPortion *selected; /* Portion à décrire ici */
+ char *markup; /* Description à construire */
+ GBinPortion *iter; /* Remontée hiérarchique */
+ char value[2 * VMPA_MAX_SIZE]; /* Traduction en texte */
+
+ selected = g_binary_portion_find_at_pos(portion, x, (GdkRectangle []) { *area });
+
+ /* Nom */
+
+ if (selected->desc != NULL)
+ {
+ markup = strdup("<b>");
+ markup = stradd(markup, selected->desc);
+ markup = stradd(markup, "</b>\n");
+
+ for (iter = selected->container; iter != NULL; iter = iter->container)
+ if (iter->desc != NULL)
+ {
+ markup = stradd(markup, selected->desc);
+ markup = stradd(markup, "\n");
+ }
+
+ markup = stradd(markup, "\n");
+
+ }
+ else markup = strdup("");
+
+ markup = stradd(markup, "taille : ");
+ snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(selected->size));
+ markup = stradd(markup, value);
+ markup = stradd(markup, "\n");
+
+ /* Localisation */
+
+ markup = stradd(markup, "<b>");
+ markup = stradd(markup, _("Localisation"));
+ markup = stradd(markup, "</b>\n");
+
+ markup = stradd(markup, _("physical: from "));
+ snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(selected->offset));
+ markup = stradd(markup, value);
+ markup = stradd(markup, _(" to "));
+ snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(selected->offset + selected->size));
+ markup = stradd(markup, value);
+ markup = stradd(markup, "\n");
+
+ markup = stradd(markup, _("memory: from "));
+ snprintf(value, 2 * VMPA_MAX_SIZE, VMPA_FMT_LONG, VMPA_CAST(selected->addr));
+ markup = stradd(markup, value);
+ markup = stradd(markup, _(" to "));
+ snprintf(value, 2 * VMPA_MAX_SIZE, VMPA_FMT_LONG, VMPA_CAST(selected->addr + selected->size));
+ markup = stradd(markup, value);
+ markup = stradd(markup, "\n\n");
+
+ /* Droits d'accès */
+
+ markup = stradd(markup, "<b>");
+ markup = stradd(markup, _("Rights"));
+ markup = stradd(markup, "</b>\n");
+
+ snprintf(value, 2 * VMPA_MAX_SIZE, "%s%s%s",
+ selected->rights & PAC_READ ? "r" : "-",
+ selected->rights & PAC_WRITE ? "w" : "-",
+ selected->rights & PAC_EXEC ? "x" : "-");
+
+ markup = stradd(markup, value);
+
+ /* Impression finale */
+
+ gtk_tooltip_set_markup(tooltip, markup);
+ free(markup);
+
+ return TRUE;
+
+}
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à consulter. *
+* cr = contexte graphique pour le dessin. *
+* area = étendue mise à disposition. *
+* *
+* Description : Représente la portion sur une bande dédiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_portion_draw(GBinPortion *portion, cairo_t *cr, const GdkRectangle *area)
+{
+ portion_color *color; /* Couleur du fond */
+ size_t i; /* Boucle de parcours */
+ GBinPortion *sub; /* Portion incluse à montrer */
+ GdkRectangle sub_area; /* Etendue d'une sous-portion */
+
+ /* Dessin de la portion courante */
+
+ cairo_set_line_width(cr, 1.0);
+
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+
+ color = find_binary_portion_color(portion->code);
+
+ if (color != NULL)
+ cairo_set_source_rgba(cr,
+ color->red, color->green, color->blue,
+ color->alpha);
+
+ cairo_rectangle(cr, area->x, area->y, area->width, area->height);
+ cairo_fill(cr);
+
+ if (color != NULL)
+ cairo_set_source_rgba(cr,
+ color->red * 0.7, color->green * 0.7, color->blue * 0.7,
+ color->alpha);
+
+ cairo_rectangle(cr, area->x, area->y, area->width, area->height);
+ cairo_stroke(cr);
+
+ /* Dessin des portions incluses */
+
+ sub_area.y = area->y;
+ sub_area.height = area->height;
+
+ for (i = 0; i < portion->sub_count; i++)
+ {
+ sub = portion->sub_portions[i];
+
+ if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area))
+ continue;
+
+ g_binary_portion_draw(sub, cr, &sub_area);
+
+ }
+
+}