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; + +} | 
