diff options
Diffstat (limited to 'src/glibext/gcodebuffer.c')
-rw-r--r-- | src/glibext/gcodebuffer.c | 483 |
1 files changed, 483 insertions, 0 deletions
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c new file mode 100644 index 0000000..fda2c01 --- /dev/null +++ b/src/glibext/gcodebuffer.c @@ -0,0 +1,483 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gcodebuffer.h - prototypes pour l'affichage d'un fragment de code d'assemblage + * + * Copyright (C) 2010 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 "gcodebuffer.h" + + +#include <malloc.h> +#include <sys/param.h> + + + +/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */ + + +/* Tampon pour code désassemblé (instance) */ +struct _GCodeBuffer +{ + GObject parent; /* A laisser en premier */ + + GBufferLine **lines; /* Liste des lignes intégrées */ + size_t count; /* Quantité en cache */ + size_t used; /* Quantité utilisée */ + +}; + +/* Tampon pour code désassemblé (classe) */ +struct _GCodeBufferClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Taille des allocations de masse */ +#define LINE_ALLOC_BULK 20 + + +/* Procède à l'initialisation d'une classe de tampon de code. */ +static void g_code_buffer_class_init(GCodeBufferClass *); + +/* Procède à l'initialisation d'un tampon pour code désassemblé. */ +static void g_code_buffer_init(GCodeBuffer *); + + + +/* ---------------------- VUE PARTICULIERE D'UN TAMPON DE CODE ---------------------- */ + + +/* Vue d'un tampon pour code désassemblé (instance) */ +struct _GBufferView +{ + GObject parent; /* A laisser en premier */ + + GCodeBuffer *buffer; /* Tampon de code visualisé */ + size_t first; /* Première ligne intégrée */ + size_t last; /* Dernière ligne intégrée */ + + gint line_height; /* Hauteur maximale des lignes */ + gint max_widths[BLC_COUNT]; /* Taille cachée des colonnes */ + gint left_margin; /* Marge gauche + espace */ + gint left_text; /* Début d'impression du code */ + + buffer_line_draw_fc drawing_extra; /* Fonction d'accompagnement */ + void *drawing_data; /* Donnée utilisateur */ + +}; + +/* Vue d'un tampon pour code désassemblé (classe) */ +struct _GBufferViewClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +#define WIDTHS_CACHED(view) ((view)->max_widths[0] != -1) + + +/* Procède à l'initialisation d'une classe de vue de tampon. */ +static void g_buffer_view_class_init(GBufferViewClass *); + +/* Procède à l'initialisation d'une vue d'un tampon pour code. */ +static void g_buffer_view_init(GBufferView *); + +/* Réinitialise le cache des largeurs de colonne calculées. */ +static void g_buffer_view_reset_required_widths(GBufferView *); + +/* Calcule les dimensions requises par une visualisation. */ +static void g_buffer_view_compute_required_widths(GBufferView *); + + + +/* ---------------------------------------------------------------------------------- */ +/* TAMPON POUR CODE DESASSEMBLE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type du composant de tampon pour code désassemblé. */ +G_DEFINE_TYPE(GCodeBuffer, g_code_buffer, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : class = classe de composant GTK à initialiser. * +* * +* Description : Procède à l'initialisation d'une classe de tampon de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_code_buffer_class_init(GCodeBufferClass *class) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = composant GTK à initialiser. * +* * +* Description : Procède à l'initialisation d'un tampon pour code désassemblé.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_code_buffer_init(GCodeBuffer *buffer) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouveau composant de tampon pour code désassemblé. * +* * +* Retour : Composant GTK créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCodeBuffer *g_code_buffer_new(void) +{ + GCodeBuffer *result; /* Composant à retourner */ + + result = g_object_new(G_TYPE_CODE_BUFFER, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = composant GTK à mettre à jour. * +* * +* Description : Ajoute une nouvelle ligne à un tampon pour code désassemblé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer) +{ + GBufferLine *result; /* Instance à retourner */ + + if (buffer->used == buffer->count) + { + buffer->count += LINE_ALLOC_BULK; + buffer->lines = (GBufferLine **)realloc(buffer->lines, + buffer->count * sizeof(GBufferLine *)); + } + + result = g_buffer_line_new(); + buffer->lines[buffer->used++] = result; + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* VUE PARTICULIERE D'UN TAMPON DE CODE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type de la vue d'un tampon pour code désassemblé. */ +G_DEFINE_TYPE(GBufferView, g_buffer_view, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : class = classe de composant GTK à initialiser. * +* * +* Description : Procède à l'initialisation d'une classe de vue de tampon. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_buffer_view_class_init(GBufferViewClass *class) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = composant GTK à initialiser. * +* * +* Description : Procède à l'initialisation d'une vue d'un tampon pour code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_buffer_view_init(GBufferView *buffer) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = tamon à représenter à l'écran. * +* * +* Description : Crée une nouvelle vue d'un tampon pour code désassemblé. * +* * +* Retour : Composant GTK créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBufferView *g_buffer_view_new(GCodeBuffer *buffer) +{ + GBufferView *result; /* Composant à retourner */ + + result = g_object_new(G_TYPE_BUFFER_VIEW, NULL); + + result->buffer = buffer; + result->first = 0; + result->last = buffer->used; + + g_buffer_view_reset_required_widths(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : view = visualisation à consulter. * +* * +* Description : Réinitialise le cache des largeurs de colonne calculées. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_buffer_view_reset_required_widths(GBufferView *view) +{ + unsigned int i; /* Boucle de parcours */ + + for (i = 0; i < BLC_COUNT; i++) + view->max_widths[i] = -1; + +} + + +/****************************************************************************** +* * +* Paramètres : view = visualisation à consulter. * +* * +* Description : Calcule les dimensions requises par une visualisation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_buffer_view_compute_required_widths(GBufferView *view) +{ + GBufferLine **lines; /* Liste des lignes à traiter */ + size_t i; /* Boucle de parcours #1 */ + unsigned int j; /* Boucle de parcours #2 */ + gint width; /* Largeur d'une colonne */ + + lines = view->buffer->lines; + + view->line_height = 17; + + view->left_margin = 2 * view->line_height; + view->left_text = 2.5 * view->line_height; + + for (i = view->first; i < view->last; i++) + for (j = 0; j < BLC_COUNT; j++) + { + width = g_buffer_line_get_width(lines[i], j); + view->max_widths[j] = MAX(view->max_widths[j], width); + } + +} + + +/****************************************************************************** +* * +* Paramètres : view = visualisation à consulter. * +* * +* Description : Fournit la hauteur d'impression d'une ligne visualisée. * +* * +* Retour : Hauteur de ligne en pixel. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gint g_buffer_view_get_line_height(GBufferView *view) +{ + if (!WIDTHS_CACHED(view)) + g_buffer_view_compute_required_widths(view); + + return view->line_height; + +} + + +/****************************************************************************** +* * +* Paramètres : view = visualisation à consulter. * +* width = largeur requise pour une pleine visualisation. [OUT]* +* height = hauteur requise pour une pleine visualisation. [OUT]* +* * +* Description : Fournit les dimensions requises par une visualisation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height) +{ + unsigned int i; /* Boucle de parcours */ + + *width = 0; + *height = view->line_height; + + if (!WIDTHS_CACHED(view)) + g_buffer_view_compute_required_widths(view); + + for (i = 0; i < BLC_COUNT; i++) + *width += view->max_widths[i]; + + *height *= (view->last - view->first); + +} + + +/****************************************************************************** +* * +* Paramètres : view = visualisation à mettre à jour. * +* method = procédure à appeler à chaque dessin de ligne. * +* data = donnée utilisateur à passer lors des appels. * +* * +* Description : Définit à une procédure à appeler lors des dessins de ligne. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_view_define_extra_drawing(GBufferView *view, buffer_line_draw_fc method, void *data) +{ + view->drawing_extra = method; + view->drawing_data = data; + +} + + +/****************************************************************************** +* * +* Paramètres : view = visualisation à représenter. * +* event = informations liées à l'événement. * +* gc = contexte graphique à utiliser pour les pinceaux. * +* fake_x = abscisse réelle du point 0 à l'écran. * +* fake_y = ordonnée réelle du point 0 à l'écran. * +* * +* Description : Imprime la visualisation du tempon de code désassemblé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, GdkGC *gc, gint fake_x, gint fake_y) +{ + GdkDrawable *drawable; /* Surface de dessin */ + gint real_x; /* Abscisse réelle pour tampon */ + gint real_y; /* Ordonnée réelle pour tampon */ + + size_t first; /* Première ligne visée */ + size_t last; /* Dernière ligne visée + 1 */ + gint y; /* Point de départ + décallage */ + + + GBufferLine **lines; /* Liste des lignes à traiter */ + size_t i; /* Boucle de parcours */ + + + drawable = GDK_DRAWABLE(event->window); + + + real_x = fake_x + view->left_text; + real_y = fake_y + event->area.y; + + + + first = (real_y / view->line_height); + last = first + (event->area.height / view->line_height); + if (event->area.height % view->line_height > 0) last++; + + y = event->area.y - (real_y % view->line_height); + + + + lines = view->buffer->lines; + + for (i = first; i < last; i++) + { + /* TODO : skip if... */ + + if (view->drawing_extra != NULL) + view->drawing_extra(lines[i], drawable, gc, fake_x, y, view->drawing_data); + + g_buffer_line_draw(lines[i], drawable, gc, view->max_widths, real_x, y); + + y += view->line_height; + + } + +} |