summaryrefslogtreecommitdiff
path: root/src/gtkext/gtkbinarystrip.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/gtkext/gtkbinarystrip.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/gtkext/gtkbinarystrip.c')
-rw-r--r--src/gtkext/gtkbinarystrip.c462
1 files changed, 462 insertions, 0 deletions
diff --git a/src/gtkext/gtkbinarystrip.c b/src/gtkext/gtkbinarystrip.c
new file mode 100644
index 0000000..3f4a6a6
--- /dev/null
+++ b/src/gtkext/gtkbinarystrip.c
@@ -0,0 +1,462 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gtkbinarystrip.c - affichage d'un binaire sous forme de bande
+ *
+ * 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 "gtkbinarystrip.h"
+
+
+#include "../glibext/chrysamarshal.h"
+
+
+
+/* Affichage d'un binaire en bande (instance) */
+struct _GtkBinaryStrip
+{
+ GtkDrawingArea parent; /* A laisser en premier */
+
+ GLoadedBinary *binary; /* Binaire à représenter */
+ gint display_pos; /* Position à l'écran */
+
+ gint cursor_addr; /* Adresse de la position */
+ gint cursor_pos; /* Position à l'écran */
+
+};
+
+/* Affichage d'un binaire en bande (classe) */
+struct _GtkBinaryStripClass
+{
+ GtkDrawingAreaClass parent; /* A laisser en premier */
+
+ void (* select_address) (GtkBinaryStrip *, vmpa_t);
+
+};
+
+
+/* Taille de l'encoche pour la position */
+#define STRIP_MARKER_SIZE 7
+
+
+/* Procède à l'initialisation de l'afficheur générique. */
+static void gtk_binary_strip_class_init(GtkBinaryStripClass *);
+
+/* Procède à l'initialisation de l'afficheur générique. */
+static void gtk_binary_strip_init(GtkBinaryStrip *);
+
+/* Encadre la préparation à l'affichage du composant. */
+static void gtk_binary_strip_realize(GtkWidget *);
+
+/* Réagit à un changement de taille du composant. */
+static void gtk_binary_strip_size_allocate(GtkWidget *, GtkAllocation *);
+
+/* Suit la progression de la souris sur le composant. */
+static gboolean gtk_binary_strip_button_release(GtkWidget *, GdkEventButton *);
+
+/* Met à jour l'affichage du composant d'affichage. */
+static gboolean gtk_binary_strip_expose(GtkWidget *, GdkEventExpose *);
+
+/* Prépare l'affichage d'une astuce. */
+static gboolean gtk_binary_strip_query_tooltip(GtkWidget *, gint, gint, gboolean, GtkTooltip *);
+
+
+
+/* Détermine le type du composant d'affichage générique. */
+G_DEFINE_TYPE(GtkBinaryStrip, gtk_binary_strip, GTK_TYPE_DRAWING_AREA)
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'afficheur générique. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_binary_strip_class_init(GtkBinaryStripClass *class)
+{
+ GtkWidgetClass *widget_class; /* Classe de haut niveau */
+
+ widget_class = GTK_WIDGET_CLASS(class);
+
+ widget_class->realize = gtk_binary_strip_realize;
+ widget_class->size_allocate = gtk_binary_strip_size_allocate;
+ widget_class->button_release_event = gtk_binary_strip_button_release;
+ widget_class->expose_event = gtk_binary_strip_expose;
+ widget_class->query_tooltip = gtk_binary_strip_query_tooltip;
+
+ g_signal_new("select-address",
+ GTK_TYPE_BINARY_STRIP,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GtkBinaryStripClass, select_address),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__UINT64,
+ G_TYPE_NONE, 1, G_TYPE_UINT64);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : strip = composant GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'afficheur générique. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_binary_strip_init(GtkBinaryStrip *strip)
+{
+ GObject *object; /* Autre version de l'instance */
+ GtkWidget *widget; /* Autre version de l'instance */
+
+ object = G_OBJECT(strip);
+ widget = GTK_WIDGET(strip);
+
+ g_object_set(object, "has-tooltip", TRUE, NULL);
+
+ gtk_widget_set_size_request(widget, 400, 30);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée un nouveau composant pour l'affichage d'une bande. *
+* *
+* Retour : Composant GTK créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GtkWidget *gtk_binary_strip_new(void)
+{
+ GtkBinaryStrip *result; /* Composant à retourner */
+
+ result = g_object_new(GTK_TYPE_BINARY_STRIP, NULL);
+
+ return GTK_WIDGET(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = composant GTK à préparer. *
+* *
+* Description : Encadre la préparation à l'affichage du composant. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_binary_strip_realize(GtkWidget *widget)
+{
+ GdkCursor *cursor; /* Pointeur pour la surface */
+
+ GTK_WIDGET_CLASS(gtk_binary_strip_parent_class)->realize(widget);
+
+ cursor = gdk_cursor_new(GDK_HAND1);
+ gdk_window_set_cursor(widget->window, cursor);
+ gdk_cursor_unref(cursor);
+
+ gtk_widget_add_events(widget, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = composant GTK à préparer. *
+* allocation = nouvelle taille à considérer. *
+* *
+* Description : Réagit à un changement de taille du composant. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_binary_strip_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+{
+ GtkBinaryStrip *strip; /* Autre version du composant */
+ GExeFormat *format; /* Format du binaire */
+ GBinPortion *portions; /* Portions binaires à dessiner*/
+ GdkRectangle area; /* Surface du composant */
+
+ GTK_WIDGET_CLASS(gtk_binary_strip_parent_class)->size_allocate(widget, allocation);
+
+ strip = GTK_BINARY_STRIP(widget);
+
+ if (strip->binary == NULL)
+ return;
+
+ format = g_loaded_binary_get_format(strip->binary);
+ portions = g_exe_format_get_portions(format);
+
+ area.x = 0;
+ area.y = 0;
+ area.width = allocation->width;
+ area.height = allocation->height;
+
+ if (!g_binary_portion_get_pos_from_addr(portions, strip->cursor_addr, &area, &strip->cursor_pos))
+ strip->cursor_pos = 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = composant GTK visé par l'opération. *
+* event = informations liées à l'événement. *
+* *
+* Description : Suit la progression de la souris sur le composant. *
+* *
+* Retour : FALSE pour poursuivre la propagation de l'événement. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean gtk_binary_strip_button_release(GtkWidget *widget, GdkEventButton *event)
+{
+ GtkBinaryStrip *strip; /* Autre version du composant */
+ GExeFormat *format; /* Format du binaire */
+ GBinPortion *portions; /* Portions binaires à dessiner*/
+ GdkRectangle area; /* Surface du composant */
+ vmpa_t addr; /* Adresse à sélectionner */
+
+ if (event->x < 0 || event->y < 0)
+ return FALSE;
+ if (event->x >= widget->allocation.width || event->y >= widget->allocation.height)
+ return FALSE;
+
+ strip = GTK_BINARY_STRIP(widget);
+ format = g_loaded_binary_get_format(strip->binary);
+ portions = g_exe_format_get_portions(format);
+
+ area.x = 0;
+ area.y = 0;
+ area.width = widget->allocation.width;
+ area.height = widget->allocation.height;
+
+ if (g_binary_portion_get_addr_from_pos(portions, event->x, &area, &addr))
+ {
+ strip->cursor_addr = addr;
+ strip->cursor_pos = event->x;
+
+ gtk_widget_queue_draw(GTK_WIDGET(strip));
+
+ g_signal_emit_by_name(strip, "select-address", addr);
+
+ }
+
+ return FALSE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = composant GTK à redessiner. *
+* event = informations liées à l'événement. *
+* *
+* Description : Met à jour l'affichage du composant d'affichage. *
+* *
+* Retour : FALSE pour poursuivre la propagation de l'événement. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean gtk_binary_strip_expose(GtkWidget *widget, GdkEventExpose *event)
+{
+ GtkBinaryStrip *strip; /* Autre vision du composant */
+ cairo_t *cr; /* Contexte graphique */
+ GExeFormat *format; /* Format du binaire */
+ GBinPortion *portions; /* Portions binaires à dessiner*/
+ GdkRectangle full; /* Taille totale de la surface */
+
+ strip = GTK_BINARY_STRIP(widget);
+
+ if (strip->binary == NULL)
+ return FALSE;
+
+ format = g_loaded_binary_get_format(strip->binary);
+ portions = g_exe_format_get_portions(format);
+
+ cr = gdk_cairo_create(widget->window);
+
+ cairo_rectangle(cr,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ cairo_clip(cr);
+
+ /* Dessin des portions de binaire */
+
+ full.x = 0;
+ full.y = 1;
+ full.width = widget->allocation.width;
+ full.height = widget->allocation.height - 1;
+
+ g_binary_portion_draw(portions, cr, &full);
+
+ /* Dessin de la position */
+
+ if (strip->cursor_pos != -1)
+ {
+ cairo_set_line_width(cr, 1);
+
+ cairo_set_source_rgb(cr,
+ (1.0 * widget->style->bg[GTK_STATE_NORMAL].red) / USHRT_MAX,
+ (1.0 * widget->style->bg[GTK_STATE_NORMAL].green) / USHRT_MAX,
+ (1.0 * widget->style->bg[GTK_STATE_NORMAL].blue )/ USHRT_MAX);
+
+ cairo_move_to(cr, strip->cursor_pos, STRIP_MARKER_SIZE);
+ cairo_line_to(cr, strip->cursor_pos + STRIP_MARKER_SIZE, 0);
+ cairo_line_to(cr, strip->cursor_pos - STRIP_MARKER_SIZE, 0);
+ cairo_line_to(cr, strip->cursor_pos, STRIP_MARKER_SIZE);
+ cairo_fill(cr);
+
+ cairo_move_to(cr, strip->cursor_pos, full.height - STRIP_MARKER_SIZE + 1);
+ cairo_line_to(cr, strip->cursor_pos + STRIP_MARKER_SIZE, full.height + 1);
+ cairo_line_to(cr, strip->cursor_pos - STRIP_MARKER_SIZE, full.height + 1);
+ cairo_line_to(cr, strip->cursor_pos, full.height - STRIP_MARKER_SIZE + 1);
+ cairo_fill(cr);
+
+ }
+
+ /* Clôture */
+
+ cairo_destroy (cr);
+
+ return FALSE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = composant GTK visé par l'opération. *
+* x = abscisse de la position du message. *
+* y = ordonnée de la position du message. *
+* keyboard = indique une demande suite à obtiention du focus. *
+* tooltip = astuce à compléter. [OUT] *
+* *
+* Description : Prépare l'affichage d'une astuce. *
+* *
+* Retour : TRUE pour un affichage validé, FALSE sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean gtk_binary_strip_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard, GtkTooltip *tooltip)
+{
+ gboolean result; /* Bilan à retourner */
+ GtkBinaryStrip *strip; /* Autre version du composant */
+ GExeFormat *format; /* Format du binaire */
+ GBinPortion *portions; /* Portions binaires à dessiner*/
+ GdkRectangle area; /* Surface du composant */
+
+ if (keyboard) return FALSE;
+
+ strip = GTK_BINARY_STRIP(widget);
+
+ if (strip->binary != NULL)
+ {
+ format = g_loaded_binary_get_format(strip->binary);
+ portions = g_exe_format_get_portions(format);
+
+ area.x = 0;
+ area.y = 0;
+ area.width = widget->allocation.width;
+ area.height = widget->allocation.height;
+
+ result = g_binary_portion_query_tooltip(portions, x, y, &area, tooltip);
+
+ }
+ else result = FALSE;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : strip = composant GTK à mettre à jour. *
+* binary = nouveau contenu binaire à représenter. *
+* *
+* Description : Attache un nouveau binaire à la barre de représentation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void gtk_binary_strip_attach(GtkBinaryStrip *strip, GLoadedBinary *binary)
+{
+ if (strip->binary != NULL)
+ g_object_unref(G_OBJECT(strip->binary));
+
+ strip->binary = binary;
+ g_object_ref(G_OBJECT(strip->binary));
+
+ gtk_widget_queue_draw(GTK_WIDGET(strip));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : strip = composant GTK à mettre à jour. *
+* binary = nouveau contenu binaire à représenter. *
+* *
+* Description : Place le curseur dans la barre de représentation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+#if 0
+void gtk_binary_strip_locate_cursor(GtkBinaryStrip *strip, vmpa_t addr, bool emit)
+{
+ //srip->cursor_pos = pos;
+
+ gtk_widget_queue_draw(GTK_WIDGET(strip));
+
+}
+#endif