summaryrefslogtreecommitdiff
path: root/src/gtkext/gtkblockdisplay.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkext/gtkblockdisplay.c')
-rw-r--r--src/gtkext/gtkblockdisplay.c337
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;
+
+}