diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-12-30 10:38:52 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-12-30 10:38:52 (GMT) |
commit | 932ea7c83c07d3982fee605c6dd9895fd2753874 (patch) | |
tree | 766ad53bab9e3e3005334c30e823493de8e84168 /src/gtkext/gtkblockdisplay.c | |
parent | 1b5d39bfbc48c33a0ea0924b60e48448c8b45dd4 (diff) |
Rewritten the line buffers using generators and on-demand building to save memory.
Diffstat (limited to 'src/gtkext/gtkblockdisplay.c')
-rw-r--r-- | src/gtkext/gtkblockdisplay.c | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/src/gtkext/gtkblockdisplay.c b/src/gtkext/gtkblockdisplay.c new file mode 100644 index 0000000..d53d766 --- /dev/null +++ b/src/gtkext/gtkblockdisplay.c @@ -0,0 +1,337 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkblockdisplay.c - affichage d'un fragment de code d'assemblage + * + * Copyright (C) 2008-2012 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "gtkblockdisplay.h" + + +#include "gtkbufferdisplay-int.h" + + + +/* Composant d'affichage de bloc d'assembleur (instance) */ +struct _GtkBlockDisplay +{ + GtkBufferDisplay parent; /* A laisser en premier */ + +}; + +/* Composant d'affichage de code d'assembleur (classe) */ +struct _GtkBlockDisplayClass +{ + GtkBufferDisplayClass parent; /* A laisser en premier */ + + /* Signaux */ + + void (* highlight_changed) (GtkBlockDisplay *); + +}; + + +/* Procède à l'initialisation des afficheurs de bloc assembleur. */ +static void gtk_block_display_class_init(GtkBlockDisplayClass *); + +/* Procède à l'initialisation de l'afficheur de bloc assembleur. */ +static void gtk_block_display_init(GtkBlockDisplay *); + +/* Supprime toutes les références externes. */ +static void gtk_block_display_dispose(GtkBlockDisplay *); + +/* Procède à la libération totale de la mémoire. */ +static void gtk_block_display_finalize(GtkBlockDisplay *); + +/* Assure la gestion des clics de souris sur le composant. */ +static gboolean gtk_block_display_button_press(GtkWidget *, GdkEventButton *); + +/* Redessine l'affichage suite à un changement visuel. */ +static gboolean gtk_block_display_need_redraw(GtkBlockDisplay *, GBufferView *); + +/* Prend acte de l'association d'un binaire chargé. */ +static void gtk_block_display_attach_binary(GtkBlockDisplay *, GLoadedBinary *); + +/* Réagit à un déplacement de curseur. */ +static bool gtk_block_display_notify_caret_relocation(GtkBlockDisplay *, const GdkRectangle *, const vmpa2t *); + + + +/* Détermine le type du composant d'affichage de bloc en langage d'assemblage. */ +G_DEFINE_TYPE(GtkBlockDisplay, gtk_block_display, GTK_TYPE_BUFFER_DISPLAY) + + +/****************************************************************************** +* * +* Paramètres : class = classe GTK à initialiser. * +* * +* Description : Procède à l'initialisation des afficheurs de bloc assembleur.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_block_display_class_init(GtkBlockDisplayClass *class) +{ + GObjectClass *object; /* Autre version de la classe */ + GtkWidgetClass *widget_class; /* Classe version Widget */ + GtkDisplayPanelClass *panel_class; /* Classe parente */ + GtkBufferDisplayClass *buffer_class; /* Classe supérieure */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)gtk_block_display_dispose; + object->finalize = (GObjectFinalizeFunc)gtk_block_display_finalize; + + widget_class = GTK_WIDGET_CLASS(class); + + widget_class->button_press_event = gtk_block_display_button_press; + + panel_class = GTK_DISPLAY_PANEL_CLASS(class); + + panel_class->attach = (attach_binary_fc)gtk_block_display_attach_binary; + + buffer_class = GTK_BUFFER_DISPLAY_CLASS(class); + + buffer_class->notify_caret = (notify_caret_relocation_fc)gtk_block_display_notify_caret_relocation; + + /* Signaux */ + + g_signal_new("highlight-changed", + GTK_TYPE_BLOCK_DISPLAY, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkBlockDisplayClass, highlight_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'afficheur de bloc assembleur.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_block_display_init(GtkBlockDisplay *view) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : display = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_block_display_dispose(GtkBlockDisplay *display) +{ + G_OBJECT_CLASS(gtk_block_display_parent_class)->dispose(G_OBJECT(display)); + +} + + +/****************************************************************************** +* * +* Paramètres : display = instance d'objet Gtk à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_block_display_finalize(GtkBlockDisplay *display) +{ + G_OBJECT_CLASS(gtk_block_display_parent_class)->finalize(G_OBJECT(display)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouveau composant pour l'affichage de bloc en ASM. * +* * +* Retour : Composant GTK créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *gtk_block_display_new(void) +{ + GtkBlockDisplay *result; /* Composant à retourner */ + + result = g_object_new(GTK_TYPE_BLOCK_DISPLAY, NULL); + + return GTK_WIDGET(result); + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK visé par l'opération. * +* event = informations liées à l'événement. * +* * +* Description : Assure la gestion des clics de souris sur le composant. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_block_display_button_press(GtkWidget *widget, GdkEventButton *event) +{ + GtkBlockDisplay *display; /* Autre version du composant */ + gint real_x; /* Abscisse absolue réelle */ + gint real_y; /* Ordonnée absolue réelle */ + GBufferView *view; /* Vue du tampon représenté */ + bool changed; /* Suivi des changements */ + + GTK_WIDGET_CLASS(gtk_block_display_parent_class)->button_press_event(widget, event); + + display = GTK_BLOCK_DISPLAY(widget); + + if (event->type == GDK_2BUTTON_PRESS) + { + real_x = event->x; + real_y = event->y; + + gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(display), &real_x, &real_y); + + view = gtk_buffer_display_get_view(GTK_BUFFER_DISPLAY(display)); + + changed = g_buffer_view_highlight_segments(view, real_x, real_y, GTK_DISPLAY_PANEL(display)->display); + + g_object_unref(G_OBJECT(view)); + + if (changed) + g_signal_emit_by_name(display, "highlight-changed"); + + } + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : display = composant GTK d'affichage. * +* view = composant GLib interne. * +* * +* Description : Redessine l'affichage suite à un changement visuel. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_block_display_need_redraw(GtkBlockDisplay *display, GBufferView *view) +{ + gtk_widget_queue_draw(GTK_WIDGET(display)); + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : display = composant GTK à mettre à jour. * +* binary = binaire associé à intégrer. * +* * +* Description : Prend acte de l'association d'un binaire chargé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_block_display_attach_binary(GtkBlockDisplay *display, GLoadedBinary *binary) +{ + GBufferCache *cache; /* Tampon par défaut */ + GBufferView *view; /* Vue sur ce même tampon */ + + cache = g_loaded_binary_get_disassembled_cache(binary); + view = g_buffer_view_new(cache, NULL); + + gtk_buffer_display_set_view(GTK_BUFFER_DISPLAY(display), view); + + g_signal_connect_swapped(G_OBJECT(view), "need-redraw", + G_CALLBACK(gtk_block_display_need_redraw), display); + +} + + +/****************************************************************************** +* * +* Paramètres : display = composant GTK à manipuler. * +* area = emplacement pour le dessin d'un curseur. * +* addr = position dans la mémoire représentée du curseur. * +* * +* Description : Réagit à un déplacement de curseur. * +* * +* Retour : true si un changement a été opéré. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool gtk_block_display_notify_caret_relocation(GtkBlockDisplay *display, const GdkRectangle *area, const vmpa2t *addr) +{ + bool result; /* Bilan à retourner */ + GBufferView *view; /* Vue du tampon représenté */ + + view = gtk_buffer_display_get_view(GTK_BUFFER_DISPLAY(display)); + + result = g_buffer_view_highlight_segments(view, area->x, area->y, GTK_DISPLAY_PANEL(display)->display); + + g_object_unref(G_OBJECT(view)); + + if (result) + g_signal_emit_by_name(display, "highlight-changed"); + + return result; + +} |