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 | |
parent | 1b5d39bfbc48c33a0ea0924b60e48448c8b45dd4 (diff) |
Rewritten the line buffers using generators and on-demand building to save memory.
Diffstat (limited to 'src/gtkext')
-rw-r--r-- | src/gtkext/Makefile.am | 29 | ||||
-rw-r--r-- | src/gtkext/graph/cluster.c | 48 | ||||
-rw-r--r-- | src/gtkext/graph/cluster.h | 4 | ||||
-rw-r--r-- | src/gtkext/graph/edge.c | 27 | ||||
-rw-r--r-- | src/gtkext/graph/edge.h | 3 | ||||
-rw-r--r-- | src/gtkext/gtkblockdisplay.c (renamed from src/gtkext/gtkblockview.c) | 214 | ||||
-rw-r--r-- | src/gtkext/gtkblockdisplay.h (renamed from src/gtkext/gtkblockview.h) | 28 | ||||
-rw-r--r-- | src/gtkext/gtkbufferdisplay-int.h (renamed from src/gtkext/gtkbufferview-int.h) | 29 | ||||
-rw-r--r-- | src/gtkext/gtkbufferdisplay.c (renamed from src/gtkext/gtkbufferview.c) | 795 | ||||
-rw-r--r-- | src/gtkext/gtkbufferdisplay.h | 70 | ||||
-rw-r--r-- | src/gtkext/gtkbufferview.h | 70 | ||||
-rw-r--r-- | src/gtkext/gtkdisplaypanel-int.h | 6 | ||||
-rw-r--r-- | src/gtkext/gtkdisplaypanel.c | 16 | ||||
-rw-r--r-- | src/gtkext/gtkgraphdisplay.c (renamed from src/gtkext/gtkgraphview.c) | 745 | ||||
-rw-r--r-- | src/gtkext/gtkgraphdisplay.h | 64 | ||||
-rw-r--r-- | src/gtkext/gtkgraphview.h | 64 | ||||
-rw-r--r-- | src/gtkext/gtksourceview.c | 156 | ||||
-rw-r--r-- | src/gtkext/gtksourceview.h | 56 |
18 files changed, 992 insertions, 1432 deletions
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index 45ce4ad..d874ac1 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -1,21 +1,20 @@ noinst_LTLIBRARIES = libgtkext.la -libgtkext_la_SOURCES = \ - easygtk.h easygtk.c \ - gtkbinarystrip.h gtkbinarystrip.c \ - gtkextstatusbar.h gtkextstatusbar.c \ - gtkblockview.h gtkblockview.c \ - gtkbufferview-int.h \ - gtkbufferview.h gtkbufferview.c \ - gtkdisplaypanel-int.h \ - gtkdisplaypanel.h gtkdisplaypanel.c \ - gtkdockable-int.h \ - gtkdockable.h gtkdockable.c \ - gtkdockstation.h gtkdockstation.c \ - gtkgraphview.h gtkgraphview.c \ - gtksourceview.h gtksourceview.c \ - gtkstatusstack.h gtkstatusstack.c \ +libgtkext_la_SOURCES = \ + easygtk.h easygtk.c \ + gtkbinarystrip.h gtkbinarystrip.c \ + gtkextstatusbar.h gtkextstatusbar.c \ + gtkblockdisplay.h gtkblockdisplay.c \ + gtkbufferdisplay-int.h \ + gtkbufferdisplay.h gtkbufferdisplay.c \ + gtkdisplaypanel-int.h \ + gtkdisplaypanel.h gtkdisplaypanel.c \ + gtkdockable-int.h \ + gtkdockable.h gtkdockable.c \ + gtkdockstation.h gtkdockstation.c \ + gtkgraphdisplay.h gtkgraphdisplay.c \ + gtkstatusstack.h gtkstatusstack.c \ support.h support.c libgtkext_la_LIBADD = \ diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c index 06e06c2..558e3cd 100644 --- a/src/gtkext/graph/cluster.c +++ b/src/gtkext/graph/cluster.c @@ -30,8 +30,8 @@ #include <string.h> -#include "../gtkblockview.h" -#include "../gtkbufferview.h" +#include "../gtkblockdisplay.h" +#include "../gtkbufferdisplay.h" #include "../gtkdisplaypanel.h" #include "../../common/sort.h" @@ -104,7 +104,7 @@ struct _GGraphCluster size_t ta_count; /* Quantité de ces accroches */ GBasicBlock *block; /* Bloc d'origine représenté */ - GtkWidget *view; /* Vue graphique associée */ + GtkWidget *display; /* Vue graphique associée */ GtkAllocation alloc; /* Emplacement final du bloc */ leaving_edge **bottom_anchors; /* Accroches inférieures */ @@ -255,7 +255,7 @@ static void g_graph_cluster_init(GGraphCluster *cluster) static void g_graph_cluster_dispose(GGraphCluster *cluster) { g_object_unref(G_OBJECT(cluster->block)); - g_object_unref(G_OBJECT(cluster->view)); + g_object_unref(G_OBJECT(cluster->display)); G_OBJECT_CLASS(g_graph_cluster_parent_class)->dispose(G_OBJECT(cluster)); @@ -301,7 +301,7 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list GGraphCluster *result; /* Structure à retourner */ vmpa2t first; /* Début d'un groupe de lignes */ vmpa2t last; /* Fin d'un groupe de lignes */ - GCodeBuffer *buffer; /* Tampon brut à découper */ + GBufferCache *cache; /* Tampon brut à découper */ GBufferView *view; /* Partie affichée du tampon */ GtkRequisition requisition; /* Taille à l'écran actuelle */ @@ -312,26 +312,26 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list result->block = g_block_list_get_block(list, index); g_object_ref(G_OBJECT(result->block)); - result->view = gtk_block_view_new(); + result->display = gtk_block_display_new(); - gtk_widget_show(result->view); - gtk_display_panel_attach_binary(GTK_DISPLAY_PANEL(result->view), binary, BVW_GRAPH); + gtk_widget_show(result->display); + gtk_display_panel_attach_binary(GTK_DISPLAY_PANEL(result->display), binary, BVW_GRAPH); - gtk_display_panel_show_border(GTK_DISPLAY_PANEL(result->view), true); + gtk_display_panel_show_border(GTK_DISPLAY_PANEL(result->display), true); /* Restriction au bloc basique */ g_basic_block_get_boundary_addresses(result->block, &first, &last); - buffer = g_loaded_binary_get_disassembled_buffer(binary); + cache = g_loaded_binary_get_disassembled_cache(binary); - view = g_buffer_view_new(buffer, highlighted); + view = g_buffer_view_new(cache, highlighted); g_buffer_view_restrict(view, &first, &last); - gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result->view), view); + gtk_buffer_display_set_view(GTK_BUFFER_DISPLAY(result->display), view); /* Détermination d'une position initiale centrée */ - gtk_widget_get_preferred_size(result->view, NULL, &requisition); + gtk_widget_get_preferred_size(result->display, NULL, &requisition); result->alloc.x = -requisition.width / 2; result->alloc.y = 0; @@ -741,7 +741,7 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc if (needed.x < alloc->x) { - alloc->width += (alloc->x + needed.x); + alloc->width += (alloc->x - needed.x); alloc->x = needed.x; } @@ -765,7 +765,7 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc if (needed.x < alloc->x) { - alloc->width += (alloc->x + needed.x); + alloc->width += (alloc->x - needed.x); alloc->x = needed.x; } @@ -800,7 +800,7 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc /****************************************************************************** * * * Paramètres : cluster = encapsulation à traiter. * -* view = support de destination finale. * +* display = support de destination finale. * * * * Description : Dispose chaque noeud sur la surface de destination donnée. * * * @@ -810,23 +810,23 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc * * ******************************************************************************/ -void g_graph_cluster_place(GGraphCluster *cluster, GtkGraphView *view) +void g_graph_cluster_place(GGraphCluster *cluster, GtkGraphDisplay *display) { size_t i; /* Boucle de parcours #1 */ size_t j; /* Boucle de parcours #2 */ - g_object_ref(G_OBJECT(cluster->view)); - gtk_graph_view_put(view, cluster->view, &cluster->alloc); + g_object_ref(G_OBJECT(cluster->display)); + gtk_graph_display_put(display, cluster->display, &cluster->alloc); for (i = 0; i < cluster->ta_count; i++) { g_object_ref(G_OBJECT(cluster->top_anchors[i]->edge)); - gtk_graph_view_add_edge(view, cluster->top_anchors[i]->edge); + gtk_graph_display_add_edge(display, cluster->top_anchors[i]->edge); } for (i = 0; i < cluster->ranks_count; i++) for (j = 0; j < cluster->ranks[i].count; j++) - g_graph_cluster_place(cluster->ranks[i].clusters[j], view); + g_graph_cluster_place(cluster->ranks[i].clusters[j], display); } @@ -1671,9 +1671,9 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi /****************************************************************************** * * -* Paramètres : blocks = ensemble des blocs basiques déjà découpés. * -* views = morceaux de code à afficher de façon organisée. * -* count = quantité de ces morceaux de code. * +* Paramètres : blocXXXXXXXXXXXXXXXXXXXXks = ensemble des blocs basiques déjà découpés. * +* views = morceaux de codXXXXXXXXXXXXXXXXXxe à afficher de façon organisée. * +* count = quantité de ces morceaux de code.XXXXXXXXXXXXXXXXXX * * * * Description : Construit un graphique à partir de blocs basiques. * * * diff --git a/src/gtkext/graph/cluster.h b/src/gtkext/graph/cluster.h index d43622b..9c375d3 100644 --- a/src/gtkext/graph/cluster.h +++ b/src/gtkext/graph/cluster.h @@ -26,7 +26,7 @@ -#include "../gtkgraphview.h" +#include "../gtkgraphdisplay.h" #include "../../analysis/binary.h" #include "../../analysis/disass/block.h" @@ -57,7 +57,7 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *, const GBlockList *, size_t, void g_graph_cluster_compute_needed_alloc(const GGraphCluster *, GtkAllocation *); /* Dispose chaque noeud sur la surface de destination donnée. */ -void g_graph_cluster_place(GGraphCluster *, GtkGraphView *); +void g_graph_cluster_place(GGraphCluster *, GtkGraphDisplay *); diff --git a/src/gtkext/graph/edge.c b/src/gtkext/graph/edge.c index 561b9f3..27400a6 100644 --- a/src/gtkext/graph/edge.c +++ b/src/gtkext/graph/edge.c @@ -267,6 +267,33 @@ void g_graph_edge_resolve(GGraphEdge *edge) /****************************************************************************** * * +* Paramètres : edge = ligne de rendu à modifier dans ses positions. * +* dx = déplacement à effectuer sur l'axe des abscisses. * +* dy = déplacement à effectuer sur l'axe des ordonnées. * +* * +* Description : Opère un décallage du lien dans une direction donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_graph_edge_offset(GGraphEdge *edge, gint dx, gint dy) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < edge->count; i++) + { + edge->points[i].x += dx; + edge->points[i].y += dy; + } + +} + + +/****************************************************************************** +* * * Paramètres : edge = ligne de rendu à manipuler. * * cairo = assistant pour le rendu graphique. * * arrow = indique le besoin en flèche à l'arrivée. * diff --git a/src/gtkext/graph/edge.h b/src/gtkext/graph/edge.h index f60954c..4c43edb 100644 --- a/src/gtkext/graph/edge.h +++ b/src/gtkext/graph/edge.h @@ -81,6 +81,9 @@ void g_graph_edge_get_x_borders(const GGraphEdge *, gint *, gint *); /* Détermine les positions finales d'un lien graphique. */ void g_graph_edge_resolve(GGraphEdge *); +/* Opère un décallage du lien dans une direction donnée. */ +void g_graph_edge_offset(GGraphEdge *, gint, gint); + /* Dessine les liens graphiques enregistrés dans le moteur. */ void g_graph_edge_draw(const GGraphEdge *, cairo_t *, bool); diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockdisplay.c index 82743b0..d53d766 100644 --- a/src/gtkext/gtkblockview.c +++ b/src/gtkext/gtkblockdisplay.c @@ -1,6 +1,6 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkblockview.c - affichage d'un fragment de code d'assemblage + * gtkblockdisplay.c - affichage d'un fragment de code d'assemblage * * Copyright (C) 2008-2012 Cyrille Bagard * @@ -21,62 +21,60 @@ */ -#include "gtkblockview.h" +#include "gtkblockdisplay.h" -#include "gtkbufferview-int.h" +#include "gtkbufferdisplay-int.h" -/* -------------------------- INTERACTION DIRECTE AVEC GTK -------------------------- */ - - /* Composant d'affichage de bloc d'assembleur (instance) */ -struct _GtkBlockView +struct _GtkBlockDisplay { - GtkBufferView parent; /* A laisser en premier */ + GtkBufferDisplay parent; /* A laisser en premier */ }; /* Composant d'affichage de code d'assembleur (classe) */ -struct _GtkBlockViewClass +struct _GtkBlockDisplayClass { - GtkBufferViewClass parent; /* A laisser en premier */ + GtkBufferDisplayClass parent; /* A laisser en premier */ /* Signaux */ - void (* highlight_changed) (GtkBlockView *); + void (* highlight_changed) (GtkBlockDisplay *); }; /* Procède à l'initialisation des afficheurs de bloc assembleur. */ -static void gtk_block_view_class_init(GtkBlockViewClass *); +static void gtk_block_display_class_init(GtkBlockDisplayClass *); /* Procède à l'initialisation de l'afficheur de bloc assembleur. */ -static void gtk_block_view_init(GtkBlockView *); +static void gtk_block_display_init(GtkBlockDisplay *); -/* Réagit à un déplacement de curseur. */ -static bool gtk_block_view_notify_caret_relocation(GtkBlockView *, const GdkRectangle *, const vmpa2t *); +/* 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_view_button_press_event(GtkBlockView *, GdkEventButton *, gpointer); +static gboolean gtk_block_display_button_press(GtkWidget *, GdkEventButton *); /* Redessine l'affichage suite à un changement visuel. */ -static gboolean gtk_block_view_need_redraw(GBufferView *, GtkBlockView *); +static gboolean gtk_block_display_need_redraw(GtkBlockDisplay *, GBufferView *); /* Prend acte de l'association d'un binaire chargé. */ -static void gtk_block_view_attach_binary(GtkBlockView *, GLoadedBinary *); - +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 *); -/* ---------------------------------------------------------------------------------- */ -/* INTERACTION DIRECTE AVEC GTK */ -/* ---------------------------------------------------------------------------------- */ /* Détermine le type du composant d'affichage de bloc en langage d'assemblage. */ -G_DEFINE_TYPE(GtkBlockView, gtk_block_view, GTK_TYPE_BUFFER_VIEW) +G_DEFINE_TYPE(GtkBlockDisplay, gtk_block_display, GTK_TYPE_BUFFER_DISPLAY) /****************************************************************************** @@ -91,22 +89,36 @@ G_DEFINE_TYPE(GtkBlockView, gtk_block_view, GTK_TYPE_BUFFER_VIEW) * * ******************************************************************************/ -static void gtk_block_view_class_init(GtkBlockViewClass *class) +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 */ - GtkBufferViewClass *buffer_class; /* Classe supérieure */ + 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); - buffer_class = GTK_BUFFER_VIEW_CLASS(class); - panel_class->attach = (attach_binary_fc)gtk_block_view_attach_binary; + 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_view_notify_caret_relocation; + buffer_class->notify_caret = (notify_caret_relocation_fc)gtk_block_display_notify_caret_relocation; + + /* Signaux */ g_signal_new("highlight-changed", - GTK_TYPE_BLOCK_VIEW, + GTK_TYPE_BLOCK_DISPLAY, G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GtkBlockViewClass, highlight_changed), + G_STRUCT_OFFSET(GtkBlockDisplayClass, highlight_changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -126,44 +138,46 @@ static void gtk_block_view_class_init(GtkBlockViewClass *class) * * ******************************************************************************/ -static void gtk_block_view_init(GtkBlockView *view) +static void gtk_block_display_init(GtkBlockDisplay *view) { - - /* - g_signal_connect(G_OBJECT(view), "button_press_event", - G_CALLBACK(gtk_block_view_button_press_event), NULL); - */ - - } /****************************************************************************** * * -* Paramètres : view = composant GTK à manipuler. * -* area = emplacement pour le dessin d'un curseur. * -* addr = position dans la mémoire représentée du curseur. * +* Paramètres : display = instance d'objet GLib à traiter. * * * -* Description : Réagit à un déplacement de curseur. * +* Description : Supprime toutes les références externes. * * * -* Retour : true si un changement a été opéré. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static bool gtk_block_view_notify_caret_relocation(GtkBlockView *view, const GdkRectangle *area, const vmpa2t *addr) +static void gtk_block_display_dispose(GtkBlockDisplay *display) { - bool result; /* Bilan à retourner */ + G_OBJECT_CLASS(gtk_block_display_parent_class)->dispose(G_OBJECT(display)); - result = g_buffer_view_highlight_segments(GTK_BUFFER_VIEW(view)->buffer_view, area->x, area->y, - GTK_DISPLAY_PANEL(view)->display); +} - if (result) - g_signal_emit_by_name(view, "highlight-changed"); - return result; +/****************************************************************************** +* * +* 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)); } @@ -180,11 +194,11 @@ static bool gtk_block_view_notify_caret_relocation(GtkBlockView *view, const Gdk * * ******************************************************************************/ -GtkWidget *gtk_block_view_new(void) +GtkWidget *gtk_block_display_new(void) { - GtkBlockView *result; /* Composant à retourner */ + GtkBlockDisplay *result; /* Composant à retourner */ - result = g_object_new(GTK_TYPE_BLOCK_VIEW, NULL); + result = g_object_new(GTK_TYPE_BLOCK_DISPLAY, NULL); return GTK_WIDGET(result); @@ -193,9 +207,8 @@ GtkWidget *gtk_block_view_new(void) /****************************************************************************** * * -* Paramètres : view = composant GTK visé par l'opération. * -* event = informations liées à l'événement. * -* data = donnée non utilisée ici. * +* 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. * * * @@ -205,31 +218,33 @@ GtkWidget *gtk_block_view_new(void) * * ******************************************************************************/ -static gboolean gtk_block_view_button_press_event(GtkBlockView *view, GdkEventButton *event, gpointer data) +static gboolean gtk_block_display_button_press(GtkWidget *widget, GdkEventButton *event) { - GtkBufferView *bview; /* Autre vision du composant */ + 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 */ - if (event->type == GDK_2BUTTON_PRESS) - { - - + GTK_WIDGET_CLASS(gtk_block_display_parent_class)->button_press_event(widget, event); - printf("I feel %s clicked with button %d\n", - event->type == GDK_2BUTTON_PRESS ? "double" : "triple", - event->button); - - bview = GTK_BUFFER_VIEW(view); + 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(bview), &real_x, &real_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)); - g_buffer_view_highlight_segments(gtk_buffer_view_get_buffer(bview), real_x, real_y, NULL); + 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"); } @@ -240,8 +255,8 @@ static gboolean gtk_block_view_button_press_event(GtkBlockView *view, GdkEventBu /****************************************************************************** * * -* Paramètres : view = composant GLib interne. * -* block = composant GTK d'affichage. * +* Paramètres : display = composant GTK d'affichage. * +* view = composant GLib interne. * * * * Description : Redessine l'affichage suite à un changement visuel. * * * @@ -251,9 +266,9 @@ static gboolean gtk_block_view_button_press_event(GtkBlockView *view, GdkEventBu * * ******************************************************************************/ -static gboolean gtk_block_view_need_redraw(GBufferView *view, GtkBlockView *block) +static gboolean gtk_block_display_need_redraw(GtkBlockDisplay *display, GBufferView *view) { - gtk_widget_queue_draw(GTK_WIDGET(block)); + gtk_widget_queue_draw(GTK_WIDGET(display)); return FALSE; @@ -262,8 +277,8 @@ static gboolean gtk_block_view_need_redraw(GBufferView *view, GtkBlockView *bloc /****************************************************************************** * * -* Paramètres : view = composant GTK à mettre à jour. * -* binary = binaire associé à intégrer. * +* Paramètres : display = composant GTK à mettre à jour. * +* binary = binaire associé à intégrer. * * * * Description : Prend acte de l'association d'un binaire chargé. * * * @@ -273,17 +288,50 @@ static gboolean gtk_block_view_need_redraw(GBufferView *view, GtkBlockView *bloc * * ******************************************************************************/ -static void gtk_block_view_attach_binary(GtkBlockView *view, GLoadedBinary *binary) +static void gtk_block_display_attach_binary(GtkBlockDisplay *display, GLoadedBinary *binary) { - GCodeBuffer *buffer; /* Tampon par défaut */ - GBufferView *bview; /* Vue sur ce même tampon */ + GBufferCache *cache; /* Tampon par défaut */ + GBufferView *view; /* Vue sur ce même tampon */ - buffer = g_loaded_binary_get_disassembled_buffer(binary); - bview = g_buffer_view_new(buffer, NULL); + cache = g_loaded_binary_get_disassembled_cache(binary); + view = g_buffer_view_new(cache, NULL); - gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), bview); + gtk_buffer_display_set_view(GTK_BUFFER_DISPLAY(display), view); - g_signal_connect(G_OBJECT(bview), "need-redraw", - G_CALLBACK(gtk_block_view_need_redraw), 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; } diff --git a/src/gtkext/gtkblockview.h b/src/gtkext/gtkblockdisplay.h index 735d128..caef762 100644 --- a/src/gtkext/gtkblockview.h +++ b/src/gtkext/gtkblockdisplay.h @@ -1,6 +1,6 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkblockview.h - prototypes pour l'affichage d'un fragment de code d'assemblage + * gtkblockdisplay.h - prototypes pour l'affichage d'un fragment de code d'assemblage * * Copyright (C) 2008-2014 Cyrille Bagard * @@ -21,8 +21,8 @@ */ -#ifndef _GTKEXT_GTKBLOCKVIEW_H -#define _GTKEXT_GTKBLOCKVIEW_H +#ifndef _GTKEXT_GTKBLOCKDISPLAY_H +#define _GTKEXT_GTKBLOCKDISPLAY_H #include <glib-object.h> @@ -30,27 +30,27 @@ -#define GTK_TYPE_BLOCK_VIEW (gtk_block_view_get_type()) -#define GTK_BLOCK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BLOCK_VIEW, GtkBlockView)) -#define GTK_BLOCK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BLOCK_VIEW, GtkBlockViewClass)) -#define GTK_IS_BLOCK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BLOCK_VIEW)) -#define GTK_IS_BLOCK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BLOCK_VIEW)) -#define GTK_BLOCK_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BLOCK_VIEW, GtkBlockViewClass)) +#define GTK_TYPE_BLOCK_DISPLAY (gtk_block_display_get_type()) +#define GTK_BLOCK_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BLOCK_DISPLAY, GtkBlockDisplay)) +#define GTK_BLOCK_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BLOCK_DISPLAY, GtkBlockDisplayClass)) +#define GTK_IS_BLOCK_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BLOCK_DISPLAY)) +#define GTK_IS_BLOCK_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BLOCK_DISPLAY)) +#define GTK_BLOCK_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BLOCK_DISPLAY, GtkBlockDisplayClass)) /* Composant d'affichage de code d'assembleur (instance) */ -typedef struct _GtkBlockView GtkBlockView; +typedef struct _GtkBlockDisplay GtkBlockDisplay; /* Composant d'affichage de code d'assembleur (classe) */ -typedef struct _GtkBlockViewClass GtkBlockViewClass; +typedef struct _GtkBlockDisplayClass GtkBlockDisplayClass; /* Détermine le type du composant d'affichage de bloc en langage d'assemblage. */ -GType gtk_block_view_get_type(void); +GType gtk_block_display_get_type(void); /* Crée un nouveau composant pour l'affichage de bloc en ASM. */ -GtkWidget *gtk_block_view_new(void); +GtkWidget *gtk_block_display_new(void); -#endif /* _GTKEXT_GTKBLOCKVIEW_H */ +#endif /* _GTKEXT_GTKBLOCKDISPLAY_H */ diff --git a/src/gtkext/gtkbufferview-int.h b/src/gtkext/gtkbufferdisplay-int.h index a7da69d..4406361 100644 --- a/src/gtkext/gtkbufferview-int.h +++ b/src/gtkext/gtkbufferdisplay-int.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkbufferview.h - prototypes pour l'affichage de tampons de lignes + * gtkbufferdisplay-int.h - prototypes internes pour l'affichage de tampons de lignes * - * Copyright (C) 2010-2013 Cyrille Bagard + * Copyright (C) 2016 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,11 +21,11 @@ */ -#ifndef _GTK_BUFFERVIEW_INT_H -#define _GTK_BUFFERVIEW_INT_H +#ifndef _GTK_BUFFERDISPLAY_INT_H +#define _GTK_BUFFERDISPLAY_INT_H -#include "gtkbufferview.h" +#include "gtkbufferdisplay.h" #include "gtkdisplaypanel-int.h" @@ -33,30 +33,25 @@ /* Réagit à un déplacement de curseur. */ -typedef bool (* notify_caret_relocation_fc) (GtkBufferView *, const GdkRectangle *, const vmpa2t *); +typedef bool (* notify_caret_relocation_fc) (GtkBufferDisplay *, const GdkRectangle *, const vmpa2t *); /* Composant d'affichage de tampon de lignes (instance) */ -struct _GtkBufferView +struct _GtkBufferDisplay { GtkDisplayPanel parent; /* A laisser en premier */ - //GCodeBuffer *buffer; /* Code sous forme de texte */ - GBufferView *buffer_view; /* Affichage de cette forme */ - - gint line_height; /* Hauteur maximale des lignes */ - gint left_margin; /* Marge gauche + espace */ - gint left_text; /* Début d'impression du code */ + GBufferView *view; /* Vue sur le contenu affiché */ GdkRectangle caret; /* Emplacement du curseur */ - const vmpa2t *caret_addr; /* Position mémoire du curseur */ /* FIXME : REMME */ + vmpa2t caret_addr; /* Position mémoire du curseur */ guint caret_timer; /* Identifiant du chronomètre */ bool show_caret; /* Bascule entre les affichages*/ }; /* Composant d'affichage de tampon de lignes (classe) */ -struct _GtkBufferViewClass +struct _GtkBufferDisplayClass { GtkDisplayPanelClass parent; /* A laisser en premier */ @@ -64,10 +59,10 @@ struct _GtkBufferViewClass /* Signaux */ - void (* reach_limit) (GtkBufferView *, GdkScrollDirection); + void (* reach_limit) (GtkBufferDisplay *, GdkScrollDirection); }; -#endif /* _GTK_BUFFERVIEW_INT_H */ +#endif /* _GTK_BUFFERDISPLAY_INT_H */ diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferdisplay.c index bafb15d..b510c8f 100644 --- a/src/gtkext/gtkbufferview.c +++ b/src/gtkext/gtkbufferdisplay.c @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkbufferview.c - affichage de tampons de lignes + * gtkbufferdisplay.c - affichage de tampons de lignes * - * Copyright (C) 2010-2014 Cyrille Bagard + * Copyright (C) 2016 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,16 +21,13 @@ */ -#include "gtkbufferview-int.h" +#include "gtkbufferdisplay.h" -#include <gdk/gdkkeysyms.h> +#include "gtkbufferdisplay-int.h" -#include "../arch/target.h" -#include "../common/extstr.h" #include "../core/params.h" -#include "../glibext/chrysamarshal.h" @@ -38,52 +35,46 @@ /* Procède à l'initialisation de l'afficheur de tampons. */ -static void gtk_buffer_view_class_init(GtkBufferViewClass *); +static void gtk_buffer_display_class_init(GtkBufferDisplayClass *); /* Procède à l'initialisation de l'afficheur de tampons. */ -static void gtk_buffer_view_init(GtkBufferView *); +static void gtk_buffer_display_init(GtkBufferDisplay *); /* Supprime toutes les références externes. */ -static void gtk_buffer_view_dispose(GtkBufferView *); +static void gtk_buffer_display_dispose(GtkBufferDisplay *); /* Procède à la libération totale de la mémoire. */ -static void gtk_buffer_view_finalize(GtkBufferView *); +static void gtk_buffer_display_finalize(GtkBufferDisplay *); /* Intègre le focus dans le rendu du composant. */ -static gboolean gtk_buffer_view_focus(GtkWidget *, GdkEventFocus *); +static gboolean gtk_buffer_display_focus(GtkWidget *, GdkEventFocus *); /* Assure la gestion des clics de souris sur le composant. */ -static gboolean gtk_buffer_view_button_press(GtkWidget *, GdkEventButton *); +static gboolean gtk_buffer_display_button_press(GtkWidget *, GdkEventButton *); /* Met à jour l'affichage de la visualisation de code buffer. */ -static gboolean gtk_buffer_view_draw(GtkWidget *, cairo_t *); +static gboolean gtk_buffer_display_draw(GtkWidget *, cairo_t *); /* Prend en compte une frappe de touche sur le composant. */ -static gboolean gtk_buffer_view_key_press(GtkWidget *, GdkEventKey *); - -/* Prépare l'affichage d'une astuce. */ -static gboolean gtk_buffer_view_query_tooltip(GtkWidget *, gint, gint, gboolean, GtkTooltip *); +static gboolean gtk_buffer_display_key_press(GtkWidget *, GdkEventKey *); /* Indique les dimensions de travail du composant d'affichage. */ -static void gtk_buffer_view_compute_requested_size(GtkBufferView *, gint *, gint *); +static void gtk_buffer_display_compute_requested_size(GtkBufferDisplay *, gint *, gint *); /* Détermine la taille des bonds lors de défilements. */ -static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *, gint, GtkOrientation, gdouble *, gdouble *); +static void gtk_buffer_display_compute_scroll_inc(GtkBufferDisplay *, gint, GtkOrientation, gdouble *, gdouble *); /* Réagit à un défilement chez une barre associée au composant. */ -static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *, GtkAdjustment *, GtkOrientation); +static void gtk_buffer_display_adjust_scroll_value(GtkBufferDisplay *, GtkAdjustment *, GtkOrientation); /* Indique la position courante du curseur. */ -static const vmpa2t *gtk_buffer_view_get_caret_location(const GtkBufferView *); +static const vmpa2t *gtk_buffer_display_get_caret_location(const GtkBufferDisplay *); /* Indique la position d'affichage d'une adresse donnée. */ -static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, const vmpa2t *, gint *, gint *, ScrollPositionTweak); - -/* Fournit des éléments liés à la position courante dans la vue. */ -static bool gtk_buffer_view_get_position(const GtkBufferView *, GBufferLine **, GObject **); +static bool gtk_buffer_display_get_address_coordinates(const GtkBufferDisplay *, const vmpa2t *, gint *, gint *, ScrollPositionTweak); /* Place en cache un rendu destiné à l'aperçu graphique rapide. */ -static void gtk_buffer_view_cache_glance(GtkBufferView *, cairo_t *, const GtkAllocation *, double); +static void gtk_buffer_display_cache_glance(GtkBufferDisplay *, cairo_t *, const GtkAllocation *, double); @@ -91,16 +82,16 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *, cairo_t *, const GtkAl /* Déplace le curseur à un emplacement défini. */ -static bool _gtk_buffer_view_move_caret_to(GtkBufferView *, gint, gint); +static bool _gtk_buffer_display_move_caret_to(GtkBufferDisplay *, gint, gint); /* Déplace le curseur en effaçant son éventuelle position. */ -static void gtk_buffer_view_relocate_caret(GtkBufferView *, const GdkRectangle *, const vmpa2t *); +static void gtk_buffer_display_relocate_caret(GtkBufferDisplay *, const GdkRectangle *, const vmpa2t *); /* Redémarre l'affichage du curseur à l'emplacement courant. */ -static void restart_caret_blinking(GtkBufferView *); +static void gtk_buffer_display_restart_caret_blinking(GtkBufferDisplay *); /* Bascule et relance l'affichage du curseur. */ -static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *); +static gboolean gtk_buffer_display_refresh_caret(GtkBufferDisplay *); @@ -110,7 +101,7 @@ static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *); /* Détermine le type du composant d'affichage de tampon de lignes. */ -G_DEFINE_TYPE(GtkBufferView, gtk_buffer_view, GTK_TYPE_DISPLAY_PANEL) +G_DEFINE_TYPE(GtkBufferDisplay, gtk_buffer_display, GTK_TYPE_DISPLAY_PANEL) /****************************************************************************** @@ -125,40 +116,41 @@ G_DEFINE_TYPE(GtkBufferView, gtk_buffer_view, GTK_TYPE_DISPLAY_PANEL) * * ******************************************************************************/ -static void gtk_buffer_view_class_init(GtkBufferViewClass *class) +static void gtk_buffer_display_class_init(GtkBufferDisplayClass *class) { GObjectClass *object; /* Autre version de la classe */ GtkWidgetClass *widget_class; /* Classe version Widget */ GtkDisplayPanelClass *panel_class; /* Classe parente */ object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)gtk_buffer_display_dispose; + object->finalize = (GObjectFinalizeFunc)gtk_buffer_display_finalize; + widget_class = GTK_WIDGET_CLASS(class); - panel_class = GTK_DISPLAY_PANEL_CLASS(class); - object->dispose = (GObjectFinalizeFunc/* ! */)gtk_buffer_view_dispose; - object->finalize = (GObjectFinalizeFunc)gtk_buffer_view_finalize; + widget_class->focus_in_event = gtk_buffer_display_focus; + widget_class->focus_out_event = gtk_buffer_display_focus; + widget_class->button_press_event = gtk_buffer_display_button_press; + widget_class->draw = gtk_buffer_display_draw; + widget_class->key_press_event = gtk_buffer_display_key_press; - widget_class->focus_in_event = gtk_buffer_view_focus; - widget_class->focus_out_event = gtk_buffer_view_focus; - widget_class->button_press_event = gtk_buffer_view_button_press; - widget_class->draw = gtk_buffer_view_draw; - widget_class->key_press_event = gtk_buffer_view_key_press; - widget_class->query_tooltip = gtk_buffer_view_query_tooltip; + panel_class = GTK_DISPLAY_PANEL_CLASS(class); - panel_class->compute_size = (compute_requested_size_fc)gtk_buffer_view_compute_requested_size; - panel_class->compute_inc = (compute_scroll_inc_fc)gtk_buffer_view_compute_scroll_inc; - panel_class->adjust = (adjust_scroll_value_fc)gtk_buffer_view_adjust_scroll_value; + panel_class->compute_size = (compute_requested_size_fc)gtk_buffer_display_compute_requested_size; + panel_class->compute_inc = (compute_scroll_inc_fc)gtk_buffer_display_compute_scroll_inc; + panel_class->adjust = (adjust_scroll_value_fc)gtk_buffer_display_adjust_scroll_value; + panel_class->get_caret_loc = (get_caret_location_fc)gtk_buffer_display_get_caret_location; + panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_display_get_address_coordinates; + panel_class->move_caret_to = (move_caret_to_fc)_gtk_buffer_display_move_caret_to; + panel_class->cache_glance = (cache_glance_fc)gtk_buffer_display_cache_glance; - panel_class->get_caret_loc = (get_caret_location_fc)gtk_buffer_view_get_caret_location; - panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_view_get_address_coordinates; - panel_class->get_position = (get_view_position_fc)gtk_buffer_view_get_position; - panel_class->move_caret_to = (move_caret_to_fc)_gtk_buffer_view_move_caret_to; - panel_class->cache_glance = (cache_glance_fc)gtk_buffer_view_cache_glance; + /* Signaux */ g_signal_new("reach-limit", - GTK_TYPE_BUFFER_VIEW, + GTK_TYPE_BUFFER_DISPLAY, G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GtkBufferViewClass, reach_limit), + G_STRUCT_OFFSET(GtkBufferDisplayClass, reach_limit), NULL, NULL, g_cclosure_marshal_VOID__ENUM, G_TYPE_NONE, 1, GTK_TYPE_SCROLL_TYPE); @@ -168,7 +160,7 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *class) /****************************************************************************** * * -* Paramètres : view = composant GTK à initialiser. * +* Paramètres : display = composant GTK à initialiser. * * * * Description : Procède à l'initialisation de l'afficheur de tampons. * * * @@ -178,25 +170,16 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *class) * * ******************************************************************************/ -static void gtk_buffer_view_init(GtkBufferView *view) +static void gtk_buffer_display_init(GtkBufferDisplay *display) { - GObject *object; /* Autre version de l'instance */ - - object = G_OBJECT(view); - - g_object_set(object, "has-tooltip", TRUE, NULL); - - view->caret.x = 10; - view->caret.y = 10; - view->caret.width = 100; - view->caret.height = 100; + init_vmpa(&display->caret_addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL); } /****************************************************************************** * * -* Paramètres : view = instance d'objet GLib à traiter. * +* Paramètres : display = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * @@ -206,16 +189,19 @@ static void gtk_buffer_view_init(GtkBufferView *view) * * ******************************************************************************/ -static void gtk_buffer_view_dispose(GtkBufferView *view) +static void gtk_buffer_display_dispose(GtkBufferDisplay *display) { - G_OBJECT_CLASS(gtk_buffer_view_parent_class)->dispose(G_OBJECT(view)); + if (display->view != NULL) + g_object_unref(G_OBJECT(display->view)); + + G_OBJECT_CLASS(gtk_buffer_display_parent_class)->dispose(G_OBJECT(display)); } /****************************************************************************** * * -* Paramètres : view = instance d'objet GLib à traiter. * +* Paramètres : display = instance d'objet Gtk à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * @@ -225,9 +211,9 @@ static void gtk_buffer_view_dispose(GtkBufferView *view) * * ******************************************************************************/ -static void gtk_buffer_view_finalize(GtkBufferView *view) +static void gtk_buffer_display_finalize(GtkBufferDisplay *display) { - G_OBJECT_CLASS(gtk_buffer_view_parent_class)->finalize(G_OBJECT(view)); + G_OBJECT_CLASS(gtk_buffer_display_parent_class)->finalize(G_OBJECT(display)); } @@ -245,24 +231,24 @@ static void gtk_buffer_view_finalize(GtkBufferView *view) * * ******************************************************************************/ -static gboolean gtk_buffer_view_focus(GtkWidget *widget, GdkEventFocus *event) +static gboolean gtk_buffer_display_focus(GtkWidget *widget, GdkEventFocus *event) { - GtkBufferView *view; /* Autre version du composant */ + GtkBufferDisplay *display; /* Autre version du composant */ gboolean has_focus; /* Etat courant */ - view = GTK_BUFFER_VIEW(widget); + display = GTK_BUFFER_DISPLAY(widget); has_focus = event->in; if (has_focus) - restart_caret_blinking(view); + gtk_buffer_display_restart_caret_blinking(display); - else if (view->caret_timer != 0) + else if (display->caret_timer != 0) { - g_source_remove(view->caret_timer); - view->caret_timer = 0; + g_source_remove(display->caret_timer); + display->caret_timer = 0; - view->show_caret = true; - gtk_buffer_view_refresh_caret(view); + display->show_caret = true; + gtk_buffer_display_refresh_caret(display); } @@ -284,35 +270,32 @@ static gboolean gtk_buffer_view_focus(GtkWidget *widget, GdkEventFocus *event) * * ******************************************************************************/ -static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *event) +static gboolean gtk_buffer_display_button_press(GtkWidget *widget, GdkEventButton *event) { - GtkBufferView *view; /* Autre version du composant */ + GtkBufferDisplay *display; /* Autre version du composant */ + GBufferCache *cache; /* Contenu représenté */ + gint left_margin; /* Limite entre zones réactives*/ gint real_x; /* Abscisse absolue réelle */ gint real_y; /* Ordonnée absolue réelle */ - GBufferLine *line; /* Ligne à la position courante*/ - view = GTK_BUFFER_VIEW(widget); + display = GTK_BUFFER_DISPLAY(widget); real_x = event->x; real_y = event->y; - gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(view), &real_x, &real_y); + gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(display), &real_x, &real_y); - printf(" !mouse! :: (%g ; %g) -> (%d ; %d)\n", - event->x, event->y, - real_x, real_y); + cache = g_buffer_view_get_cache(display->view); + left_margin = g_buffer_cache_get_left_margin(cache); - if (real_x < view->left_margin) - { - line = g_buffer_view_find_line_at(view->buffer_view, real_y, NULL); - if (line == NULL) return FALSE; + g_object_unref(G_OBJECT(cache)); + if (real_x < left_margin) + { /* TODO */ - printf("Border Line :: %p\n", line); - } else - _gtk_buffer_view_move_caret_to(view, real_x, real_y); + _gtk_buffer_display_move_caret_to(display, real_x, real_y); gtk_widget_grab_focus(widget); @@ -334,22 +317,60 @@ static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton * * * ******************************************************************************/ -static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) +static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr) { - GtkBufferView *view; /* Autre version du composant */ - GtkDisplayPanel *panel; /* Autre version du composant */ + GtkBufferDisplay *display; /* Autre version du composant */ + GtkDisplayPanel *parent; /* Autre version du composant */ GdkWindow *window; /* Fenêtre à redessiner */ cairo_region_t *region; /* Région visible à redessiner */ cairo_rectangle_int_t area; /* Surface correspondante */ GtkStyleContext *context; /* Contexte du thème actuel */ + gint virt_x; /* Abscisse virtuelle */ + gint virt_y; /* Ordonnée virtuelle */ + GBufferCache *cache; /* Contenu représenté */ + gint left_margin; /* Marge gauche + espace */ GdkRGBA color; /* Couleur de thème récupérée */ - gint fake_x; /* Abscisse virtuelle */ - gint fake_y; /* Ordonnée virtuelle */ bool sel_line; /* Souslignage de la sélection */ gint *selected; /* Ordonnée d'une sélection */ - view = GTK_BUFFER_VIEW(widget); - panel = GTK_DISPLAY_PANEL(widget); + + //gboolean status; + + + GtkStyleContext *other; + GtkWidgetPath *path; + + + other = gtk_style_context_new(); + + + path = gtk_widget_path_new (); + gtk_widget_path_append_type (path, GTK_TYPE_SCALE); + //gtk_widget_path_iter_add_class (path, 0, "slider"); + //gtk_widget_path_iter_add_class (path, 0, "scale"); + gtk_style_context_set_path (other, path); + gtk_widget_path_free (path); + + + + + //context = gtk_widget_get_style_context(widget); + + + //gtk_render_background(context, cr, 0, 0, 1000, 1000); + + + //status = GTK_WIDGET_CLASS(gtk_buffer_display_parent_class)->draw(widget, cr); + + //printf("status: %d\n", status); + + //return TRUE; + + + + + display = GTK_BUFFER_DISPLAY(widget); + parent = GTK_DISPLAY_PANEL(widget); window = gtk_widget_get_window(widget); @@ -362,29 +383,56 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) context = gtk_widget_get_style_context(widget); - if (panel->show_border) + if (parent->show_border) { - gtk_display_panel_define_border_path(panel, cr, 0, 0); + gtk_display_panel_define_border_path(parent, cr, 0, 0); cairo_clip(cr); } + + + gtk_render_background(context, cr, area.x, area.y, area.width, area.height); + + + + /* Décallage pour le défilement horizontal */ + + virt_x = 0; + virt_y = 0; + gtk_display_panel_compute_fake_coord(parent, &virt_x, &virt_y); + + cairo_save(cr); + + cairo_translate(cr, virt_x, 0); + + /* Récupération de la limite utile */ + + cache = g_buffer_view_get_cache(display->view); + + left_margin = g_buffer_cache_get_left_margin(cache); + + g_object_unref(G_OBJECT(cache)); + + /* Dessin de la marge gauche */ gtk_style_context_save(context); - gtk_style_context_add_class(context, GTK_STYLE_CLASS_TOOLBAR); + gtk_style_context_add_class(other, GTK_STYLE_CLASS_TOOLBAR); - gtk_style_context_get_background_color(context, GTK_STATE_FLAG_ACTIVE, &color); + gtk_style_context_get_background_color(other, GTK_STATE_FLAG_ACTIVE, &color); cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha); + //cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 1.0); - cairo_rectangle(cr, 0, area.y, view->left_margin, area.height); + cairo_rectangle(cr, 0, area.y, left_margin, area.height); cairo_fill(cr); gtk_style_context_restore(context); /* Fond de la zone de texte */ +#if 1 gtk_style_context_save(context); gtk_style_context_add_class(context, GTK_STYLE_CLASS_VIEW); @@ -393,10 +441,11 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha * 0.7); - cairo_rectangle(cr, view->left_margin, area.y, area.width, area.height); + cairo_rectangle(cr, left_margin, area.y, area.width, area.height); cairo_fill(cr); gtk_style_context_restore(context); +#endif /* Ligne de séparation */ @@ -410,44 +459,50 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) cairo_set_line_width(cr, 1.0); - cairo_move_to(cr, view->left_margin + 0.5, area.y - 0.5); - cairo_line_to(cr, view->left_margin + 0.5, area.y + area.height + 0.5); + cairo_move_to(cr, left_margin + 0.5, area.y - 0.5); + cairo_line_to(cr, left_margin + 0.5, area.y + area.height + 0.5); cairo_stroke(cr); gtk_style_context_restore(context); /* Eventuelle bordure globale */ - if (panel->show_border) - gtk_display_panel_draw_border(panel, cr); + if (parent->show_border) + gtk_display_panel_draw_border(parent, cr); /* Impression du désassemblage */ - if (view->buffer_view != NULL) + if (display->view != NULL) { - fake_x = 0; - fake_y = 0; - gtk_display_panel_compute_fake_coord(GTK_DISPLAY_PANEL(view), &fake_x, &fake_y); - g_generic_config_get_value(get_main_configuration(), MPK_SELECTION_LINE, &sel_line); sel_line &= gtk_widget_has_focus(widget); - if (!sel_line || view->caret_addr == NULL) + if (!sel_line || is_invalid_vmpa(&display->caret_addr)) selected = NULL; else - selected = &view->caret.y; + { + selected = (gint []) { display->caret.y }; + gtk_display_panel_compute_relative_coords(parent, NULL, selected); + } + + area.x -= virt_x; + virt_y += area.y; - g_buffer_view_draw(view->buffer_view, cr, fake_x, fake_y, &area, panel->display, selected); + g_buffer_view_draw(display->view, cr, virt_y, &area, parent->display, selected); } + cairo_restore(cr); + /* Curseur clignotant ? */ + /* if (gtk_widget_is_focus(widget)) { view->show_caret = !view->show_caret; gtk_buffer_view_refresh_caret(view); } + */ cairo_restore(cr); @@ -469,20 +524,16 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) * * ******************************************************************************/ -static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event) +static gboolean gtk_buffer_display_key_press(GtkWidget *widget, GdkEventKey *event) { gboolean result; /* Suites à renvoyer */ - GtkBufferView *view; /* Autre version du composant */ + GdkScrollDirection dir; /* Direction du déplacement */ + GtkBufferDisplay *display; /* Autre version du composant */ GtkDisplayPanel *panel; /* Autre version du composant */ bool ctrl; /* Statut de la touche Contrôle*/ - GdkScrollDirection dir; /* Direction du déplacement */ GdkRectangle area; /* Emplacement de curseur */ - const vmpa2t *addr; /* Adresse du nouveau curseur */ - - result = FALSE; - - view = GTK_BUFFER_VIEW(widget); - panel = GTK_DISPLAY_PANEL(widget); + vmpa2t addr; /* Adresse du nouveau curseur */ + bool status; /* Validité d'un déplacement */ switch (event->keyval) { @@ -507,30 +558,28 @@ static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event) break; default: + result = FALSE; break; } if (result) { - area = view->caret; + display = GTK_BUFFER_DISPLAY(widget); + panel = GTK_DISPLAY_PANEL(widget); + ctrl = (event->state & GDK_CONTROL_MASK); + area = display->caret; - addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, dir, panel->display); + status = g_buffer_view_move_caret(display->view, ctrl, dir, panel->display, &area, &addr); - if (addr != NULL) + if (status) { - gtk_buffer_view_relocate_caret(view, &area, addr); - _gtk_display_panel_scroll_to_address(panel, addr, SPT_RAW, false); + gtk_buffer_display_relocate_caret(display, &area, &addr); + _gtk_display_panel_scroll_to_address(panel, &addr, SPT_RAW, false); } else - g_signal_emit_by_name(view, "reach-limit", dir); - - - - //if (addr == NULL) return FALSE; - - + g_signal_emit_by_name(display, "reach-limit", dir); } @@ -541,172 +590,9 @@ static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event) /****************************************************************************** * * -* 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_buffer_view_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard, GtkTooltip *tooltip) -{ - gboolean result; /* Bilan à retourner */ - GBinFormat *format; /* Format du fichier binaire */ - GtkBufferView *view; /* Autre version du composant */ - gint real_x; /* Abscisse absolue réelle */ - gint real_y; /* Ordonnée absolue réelle */ - GBufferLine *line; /* Ligne en cours de survol */ - GObject *creator; /* Créateur à l'orgine du seg. */ - virt_t virt; /* Adresse virtuelle */ - vmpa2t addr; /* Adresse de destination */ - GBinSymbol *target_sym; /* Symbole présent à l'adresse */ - GBinSymbol *next_sym; /* Symbole suivant l'adresse */ - GCodeBuffer *buffer; /* Tampon où lire les lignes */ - const vmpa2t *stop_addr; /* Adresse associée, pour fin */ - const mrange_t *lrange; /* Couverture d'une ligne */ - size_t count; /* Nbre de lignes max à traiter*/ - char *markup; /* Description à construire */ - size_t i; /* Boucle de parcours */ - size_t index; /* Indice d'une ligne imprimée */ - char *text; /* Contenu à ajouter */ - - if (keyboard) return FALSE; - - result = FALSE; - - format = NULL; - - view = GTK_BUFFER_VIEW(widget); - - /* Récupération de la destination pointée */ - - real_x = x; - real_y = y; - gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(view), &real_x, &real_y); - - line = g_buffer_view_find_line_and_creator_at(view->buffer_view, - &real_x, real_y, NULL, - GTK_DISPLAY_PANEL(view)->display, &creator); - - if (line == NULL || creator == NULL) goto no_tooltip; - - /** - * On fait le pari de reposer uniquement sur des adresses virtuelles ! - * A changer dans un futur ? - */ - - virt = VMPA_NO_VIRTUAL; - - if (G_IS_TARGET_OPERAND(creator)) - virt = g_target_operand_get_addr(G_TARGET_OPERAND(creator)); - - else if (G_IS_IMM_OPERAND(creator)) - { - if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(creator), &virt)) - virt = VMPA_NO_VIRTUAL; - } - - if (virt == VMPA_NO_VIRTUAL) goto no_tooltip; - - init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); - - /* Construction du contenu textuel */ - - format = G_BIN_FORMAT(g_loaded_binary_get_format(GTK_DISPLAY_PANEL(view)->binary)); - - if (!g_binary_format_find_symbol_at(format, &addr, &target_sym)) - goto no_tooltip; - - g_object_unref(G_OBJECT(target_sym)); - - /* Construction du contenu textuel */ - - /** - * Dans le cas des vues de blocs basiques, il est impératif - * de chercher les lignes dans le tampon global, et non uniquement dans - * celui propre au bloc basique courant. - */ - - buffer = g_loaded_binary_get_disassembled_buffer(GTK_DISPLAY_PANEL(view)->binary); - - if (g_binary_format_find_next_symbol_at(format, &addr, &next_sym)) - stop_addr = get_mrange_addr(g_binary_symbol_get_range(next_sym)); - else - stop_addr = NULL; /* Pour GCC */ - - g_generic_config_get_value(get_main_configuration(), MPK_TOOLTIP_SIZE, &count); - - markup = NULL; - - for (i = 0, line = g_code_buffer_find_line_by_addr(buffer, &addr, BLF_NONE, &index); - i < count && line != NULL; - i++, line = g_code_buffer_find_line_by_index(buffer, index + i)) - { - /* Si on commence à marcher sur les plates-bandes du symbole suivant... */ - if (next_sym != NULL) - { - lrange = g_buffer_line_get_range(line); - - if (mrange_contains_addr(lrange, stop_addr)) - break; - - } - - text = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, true); - - if (markup != NULL) - markup = stradd(markup, "\n"); - - if (text != NULL) - markup = stradd(markup, text); - - free(text); - - } - - if (next_sym != NULL) - g_object_unref(G_OBJECT(next_sym)); - - if (markup == NULL) goto no_tooltip; - - /* Impression finale */ - - result = TRUE; - - gtk_tooltip_set_markup(tooltip, markup); - free(markup); - - no_tooltip: - - if (creator != NULL) - g_object_unref(creator); - - /* - FIXME : ref() ! - if (line != NULL) - g_object_unref(G_OBJECT(line)); - */ - - if (format != NULL) - g_object_unref(G_OBJECT(format)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : view = composant GTK à consulter. * -* width = largeur requise à renseigner ou NULL. [OUT] * -* height = hauteur requise à renseigner ou NULL. [OUT] * +* Paramètres : display = composant GTK à consulter. * +* width = largeur requise à renseigner ou NULL. [OUT] * +* height = hauteur requise à renseigner ou NULL. [OUT] * * * * Description : Indique les dimensions de travail du composant d'affichage. * * * @@ -716,20 +602,20 @@ static gboolean gtk_buffer_view_query_tooltip(GtkWidget *widget, gint x, gint y, * * ******************************************************************************/ -static void gtk_buffer_view_compute_requested_size(GtkBufferView *view, gint *width, gint *height) +static void gtk_buffer_display_compute_requested_size(GtkBufferDisplay *display, gint *width, gint *height) { if (width != NULL) { - if (view->buffer_view != NULL) - *width = g_buffer_view_get_width(view->buffer_view, GTK_DISPLAY_PANEL(view)->display); + if (display->view != NULL) + *width = g_buffer_view_get_width(display->view, GTK_DISPLAY_PANEL(display)->display); else *width = 0; } if (height != NULL) { - if (view->buffer_view != NULL) - *height = g_buffer_view_get_height(view->buffer_view); + if (display->view != NULL) + *height = g_buffer_view_get_height(display->view); else *height = 0; } @@ -739,7 +625,7 @@ static void gtk_buffer_view_compute_requested_size(GtkBufferView *view, gint *wi /****************************************************************************** * * -* Paramètres : panel = composant GTK d'affichage à mettre à jour. * +* Paramètres : display = composant GTK d'affichage à consulter. * * size = taille de l'espace dans la direction donnée. * * orientation = indication sur le défilement à traiter. * * step = valeur d'un petit pas de défilement. [OUT] * @@ -753,24 +639,31 @@ static void gtk_buffer_view_compute_requested_size(GtkBufferView *view, gint *wi * * ******************************************************************************/ -static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, GtkOrientation orientation, gdouble *step, gdouble *page) +static void gtk_buffer_display_compute_scroll_inc(GtkBufferDisplay *display, gint size, GtkOrientation orientation, gdouble *step, gdouble *page) { - if (orientation == GTK_ORIENTATION_VERTICAL) + GBufferCache *cache; /* Gestionnaire de lignes */ + + if (orientation == GTK_ORIENTATION_VERTICAL && display->view != NULL) { - *step = 17; // FIXME g_buffer_view_get_line_height(view->buffer_view); + cache = g_buffer_view_get_cache(display->view); + + *step = g_buffer_cache_get_line_height(cache); *page = *step * 10; + + g_object_unref(G_OBJECT(cache)); + } else - GTK_DISPLAY_PANEL_CLASS(gtk_buffer_view_parent_class)->compute_inc(GTK_DISPLAY_PANEL(view), - size, orientation, step, page); + GTK_DISPLAY_PANEL_CLASS(gtk_buffer_display_parent_class)->compute_inc(GTK_DISPLAY_PANEL(display), + size, orientation, step, page); } /****************************************************************************** * * -* Paramètres : view = panneau d'affichage concerné. * +* Paramètres : display = panneau d'affichage concerné. * * adj = défilement dont une valeur a changé. * * orientation = indication sur le défilement à traiter. * * * @@ -782,21 +675,21 @@ static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, G * * ******************************************************************************/ -static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *view, GtkAdjustment *adj, GtkOrientation orientation) +static void gtk_buffer_display_adjust_scroll_value(GtkBufferDisplay *display, GtkAdjustment *adj, GtkOrientation orientation) { GtkWidget *widget; /* Autre vision du composant */ - widget = GTK_WIDGET(view); + widget = GTK_WIDGET(display); if (gtk_widget_get_realized(widget)) - gdk_window_invalidate_rect(gtk_widget_get_window(widget), NULL, false); + gdk_window_invalidate_rect(gtk_widget_get_window(widget), NULL, FALSE); } /****************************************************************************** * * -* Paramètres : view = composant GTK à manipuler. * +* Paramètres : display = composant GTK à manipuler. * * * * Description : Indique la position courante du curseur. * * * @@ -806,20 +699,20 @@ static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *view, GtkAdjustme * * ******************************************************************************/ -static const vmpa2t *gtk_buffer_view_get_caret_location(const GtkBufferView *view) +static const vmpa2t *gtk_buffer_display_get_caret_location(const GtkBufferDisplay *display) { - return view->caret_addr; + return &display->caret_addr; } /****************************************************************************** * * -* Paramètres : view = composant GTK à consulter. * -* addr = adresse à présenter à l'écran. * -* x = position horizontale au sein du composant. [OUT] * -* y = position verticale au sein du composant. [OUT] * -* tweak = adaptation finale à effectuer. * +* Paramètres : display = composant GTK à consulter. * +* addr = adresse à présenter à l'écran. * +* x = position horizontale au sein du composant. [OUT] * +* y = position verticale au sein du composant. [OUT] * +* tweak = adaptation finale à effectuer. * * * * Description : Indique la position d'affichage d'une adresse donnée. * * * @@ -829,21 +722,24 @@ static const vmpa2t *gtk_buffer_view_get_caret_location(const GtkBufferView *vie * * ******************************************************************************/ -static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *view, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak) +static bool gtk_buffer_display_get_address_coordinates(const GtkBufferDisplay *display, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak) { bool result; /* Bilan à remonter */ bool need_code; /* Recherche plus raffinée */ + GBufferCache *cache; /* Gestionnaire de lignes */ int height; /* Hauteur allouée */ need_code = (tweak == SPT_BOTTOM); - result = g_buffer_view_get_address_coordinates(view->buffer_view, addr, x, y, need_code); + cache = g_buffer_view_get_cache(display->view); + + result = g_buffer_view_get_address_coordinates(display->view, addr, need_code, x, y); if (result) { - *x += g_buffer_view_get_margin(view->buffer_view, GTK_DISPLAY_PANEL(view)->display); + *x += g_buffer_view_get_margin(display->view, GTK_DISPLAY_PANEL(display)->display); - height = gtk_widget_get_allocated_height(GTK_WIDGET(view)); + height = gtk_widget_get_allocated_height(GTK_WIDGET(display)); switch (tweak) { @@ -859,58 +755,26 @@ static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *view, c case SPT_BOTTOM: *y -= height; - *y += g_buffer_view_get_line_height(view->buffer_view); + *y += g_buffer_cache_get_line_height(cache); break; } } - return result; + g_object_unref(G_OBJECT(cache)); -} - - -/****************************************************************************** -* * -* Paramètres : view = composant GTK à consulter. * -* line = ligne de tampon où se trouve le curseur. [OUT] * -* creator = instance à l'origine de la représentation. [OUT] * -* * -* Description : Fournit des éléments liés à la position courante dans la vue.* -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool gtk_buffer_view_get_position(const GtkBufferView *view, GBufferLine **line, GObject **creator) -{ - GObject *obj; /* Elément à récupérer */ - - /* Si aucune position n'est définie... */ - if (view->caret_addr == NULL) - return false; - - *line = g_buffer_view_find_line_and_creator_at(view->buffer_view, - (gint []){ view->caret.x }, view->caret.y, NULL, - GTK_DISPLAY_PANEL(view)->display, &obj); - - if (creator != NULL) - *creator = obj; - - return (line != NULL); + return result; } /****************************************************************************** * * -* Paramètres : view = composant GTK à manipuler. * -* cairo = assistant pour la création de rendus. * -* area = taille de la surface réduite à disposition. * -* scale = échelle vis à vis de la taille réelle. * +* Paramètres : display = composant GTK à manipuler. * +* cairo = assistant pour la création de rendus. * +* area = taille de la surface réduite à disposition. * +* scale = échelle vis à vis de la taille réelle. * * * * Description : Place en cache un rendu destiné à l'aperçu graphique rapide. * * * @@ -920,7 +784,7 @@ static bool gtk_buffer_view_get_position(const GtkBufferView *view, GBufferLine * * ******************************************************************************/ -static void gtk_buffer_view_cache_glance(GtkBufferView *view, cairo_t *cairo, const GtkAllocation *area, double scale) +static void gtk_buffer_display_cache_glance(GtkBufferDisplay *display, cairo_t *cairo, const GtkAllocation *area, double scale) { cairo_set_line_width(cairo, 1); cairo_set_source_rgb(cairo, 0.4, 0.4, 0.4); @@ -934,10 +798,10 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *view, cairo_t *cairo, co /****************************************************************************** * * -* Paramètres : view = composant GTK à mettre à jour. * -* buffer = tampon de lignes à encadrer. * +* Paramètres : display = instance d'objet Gtk à actualiser. * +* view = nouvelle vue à associer au composant. * * * -* Description : Prend acte de l'association d'un tampon de lignes. * +* Description : Lie une vue au composant d'affichage de tampon. * * * * Retour : - * * * @@ -945,46 +809,19 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *view, cairo_t *cairo, co * * ******************************************************************************/ -void gtk_buffer_view_attach_buffer(GtkBufferView *view, GBufferView *buffer) +void gtk_buffer_display_set_view(GtkBufferDisplay *display, GBufferView *view) { - gint width; /* Largeur de l'objet actuelle */ - gint height; /* Hauteur de l'objet actuelle */ - - if (view->buffer_view != NULL) - { - //g_object_unref(G_OBJECT(view->buffer)); - g_object_unref(G_OBJECT(view->buffer_view)); - } - - //view->buffer = g_buffer_view_get_buffer(buffer); - //g_object_ref(G_OBJECT(view->buffer)); - - view->buffer_view = buffer; - - /* Taille des marges */ - - view->line_height = g_buffer_view_get_line_height(view->buffer_view); - view->left_margin = 2 * view->line_height; - view->left_text = -2.5 * view->line_height; - - /* Validation finale */ + if (display->view != NULL) + g_object_unref(G_OBJECT(display->view)); - width = g_buffer_view_get_width(view->buffer_view, GTK_DISPLAY_PANEL(view)->display); - height = g_buffer_view_get_height(view->buffer_view); - - width += -view->left_text + 1; - height += 1; - - //gtk_widget_set_size_request(GTK_WIDGET(view), width, height); - - gtk_widget_queue_draw(GTK_WIDGET(view)); + display->view = view; } /****************************************************************************** * * -* Paramètres : view = composant GTK à consulter. * +* Paramètres : display = composant GTK à consulter. * * * * Description : Fournit la vue associée au tampon de lignes courant. * * * @@ -994,11 +831,15 @@ void gtk_buffer_view_attach_buffer(GtkBufferView *view, GBufferView *buffer) * * ******************************************************************************/ -GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *view) +GBufferView *gtk_buffer_display_get_view(const GtkBufferDisplay *display) { - /* TODO : ref... */ + GBufferView *result; /* Instance à retourner */ - return view->buffer_view; + result = display->view; + + g_object_ref(G_OBJECT(result)); + + return result; } @@ -1011,9 +852,9 @@ GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *view) /****************************************************************************** * * -* Paramètres : view = composant GTK à manipuler. * -* x = abscisse proposée pour le nouvel emplacement. * -* y = ordonnée proposée pour le nouvel emplacement. * +* Paramètres : display = composant GTK à manipuler. * +* x = abscisse proposée pour le nouvel emplacement. * +* y = ordonnée proposée pour le nouvel emplacement. * * * * Description : Déplace le curseur à un emplacement défini. * * * @@ -1023,34 +864,28 @@ GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *view) * * ******************************************************************************/ -static bool _gtk_buffer_view_move_caret_to(GtkBufferView *view, gint x, gint y) +static bool _gtk_buffer_display_move_caret_to(GtkBufferDisplay *display, gint x, gint y) { - size_t index; /* Indice de ligne de tampon */ - GBufferLine *line; /* Ligne à la position courante*/ + bool result; /* Bilan à retourner */ GtkDisplayPanel *panel; /* Autre version du composant */ - const vmpa2t *addr; /* Position mémoire associée */ + vmpa2t addr; /* Position mémoire associée */ GdkRectangle new; /* Nouvel emplacement calculé */ - if (x < view->left_margin) return false; + panel = GTK_DISPLAY_PANEL(display); - line = g_buffer_view_find_line_at(view->buffer_view, y, &index); - if (line == NULL) return false; + result = g_buffer_view_compute_caret_full(display->view, x, y, panel->display, &new, &addr); - panel = GTK_DISPLAY_PANEL(view); - - addr = g_buffer_view_compute_caret_full(view->buffer_view, line, index, x, panel->display, &new); - - if (addr != NULL) - gtk_buffer_view_relocate_caret(view, &new, addr); + if (result) + gtk_buffer_display_relocate_caret(display, &new, &addr); - return (addr != NULL); + return result; } /****************************************************************************** * * -* Paramètres : view = composant GTK à manipuler. * +* Paramètres : display = composant GTK à manipuler. * * beginning = précise le coin où se retrouvera le curseur. * * same_x = tente de conserver une même abscisse ou NULL ? * * * @@ -1062,25 +897,39 @@ static bool _gtk_buffer_view_move_caret_to(GtkBufferView *view, gint x, gint y) * * ******************************************************************************/ -bool gtk_buffer_view_move_caret_to(GtkBufferView *view, bool beginning, gint *same_x) +bool gtk_buffer_display_move_caret_to(GtkBufferDisplay *display, bool beginning, gint *same_x) { bool result; /* Bilan à remonter */ + GBufferCache *cache; /* Contenu représenté */ + gint left_margin; /* Limite entre zones réactives*/ gint x; /* Abscisse d'emplacement */ gint y; /* Ordonnée d'emplacement */ if (beginning) { - x = same_x != NULL ? *same_x : view->left_margin * 2; + cache = g_buffer_view_get_cache(display->view); + + left_margin = g_buffer_cache_get_left_margin(cache); + + g_object_unref(G_OBJECT(cache)); + + x = same_x != NULL ? *same_x : left_margin * 2; y = 0; + } else { - if (same_x != NULL) x = *same_x; - gtk_buffer_view_compute_requested_size(view, same_x != NULL ? NULL : &x, &y); + if (same_x != NULL) + x = *same_x; + else + gtk_widget_get_preferred_width(GTK_WIDGET(display), NULL, &x); + + gtk_widget_get_preferred_height(GTK_WIDGET(display), NULL, &y); y--; + } - result = _gtk_buffer_view_move_caret_to(view, x, y); + result = _gtk_buffer_display_move_caret_to(display, x, y); return result; @@ -1089,9 +938,9 @@ bool gtk_buffer_view_move_caret_to(GtkBufferView *view, bool beginning, gint *sa /****************************************************************************** * * -* Paramètres : view = composant GTK à manipuler. * -* area = emplacement pour le dessin d'un curseur. * -* addr = position dans la mémoire représentée du curseur. * +* 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 : Déplace le curseur en effaçant son éventuelle position. * * * @@ -1101,48 +950,48 @@ bool gtk_buffer_view_move_caret_to(GtkBufferView *view, bool beginning, gint *sa * * ******************************************************************************/ -static void gtk_buffer_view_relocate_caret(GtkBufferView *view, const GdkRectangle *area, const vmpa2t *addr) +static void gtk_buffer_display_relocate_caret(GtkBufferDisplay *display, const GdkRectangle *area, const vmpa2t *addr) { bool clear_old; /* Effacement chirurgical */ GdkRectangle old_area; /* Mémorisation de l'ancien */ bool need_redraw; /* Besoin de rafraîchissement ?*/ - if (view->caret_addr != NULL) + if (!is_invalid_vmpa(&display->caret_addr)) { clear_old = true; - old_area = view->caret; + old_area = display->caret; } else clear_old = false; - view->caret = *area; - view->caret_addr = addr; + display->caret = *area; + copy_vmpa(&display->caret_addr, addr); - if (GTK_BUFFER_VIEW_GET_CLASS(view)->notify_caret != NULL) - need_redraw = GTK_BUFFER_VIEW_GET_CLASS(view)->notify_caret(view, area, addr); + if (GTK_BUFFER_DISPLAY_GET_CLASS(display)->notify_caret != NULL) + need_redraw = GTK_BUFFER_DISPLAY_GET_CLASS(display)->notify_caret(display, area, addr); else need_redraw = false; if (need_redraw) - gtk_widget_queue_draw(GTK_WIDGET(view)); + gtk_widget_queue_draw(GTK_WIDGET(display)); else if (clear_old) { - gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(view), &old_area.x, &old_area.y); + gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(display), &old_area.x, &old_area.y); - gtk_widget_queue_draw_area(GTK_WIDGET(view), old_area.x, old_area.y, + gtk_widget_queue_draw_area(GTK_WIDGET(display), old_area.x, old_area.y, old_area.width, old_area.height); } - restart_caret_blinking(view); + gtk_buffer_display_restart_caret_blinking(display); } /****************************************************************************** * * -* Paramètres : view = composant GTK à manipuler. * +* Paramètres : display = composant GTK à manipuler. * * * * Description : Redémarre l'affichage du curseur à l'emplacement courant. * * * @@ -1152,31 +1001,43 @@ static void gtk_buffer_view_relocate_caret(GtkBufferView *view, const GdkRectang * * ******************************************************************************/ -static void restart_caret_blinking(GtkBufferView *view) +static void gtk_buffer_display_restart_caret_blinking(GtkBufferDisplay *display) { - if (view->caret_timer != 0) + + GtkSettings *settings; /* Propriétés du système */ + guint interval; /* Fréquence d'actualisation */ + + if (display->caret_timer != 0) { - g_source_remove(view->caret_timer); - view->caret_timer = 0; + g_source_remove(display->caret_timer); + display->caret_timer = 0; } - if (view->caret_addr != NULL) + if (!is_invalid_vmpa(&display->caret_addr)) { - view->show_caret = false; - gtk_buffer_view_refresh_caret(view); + display->show_caret = false; + gtk_buffer_display_refresh_caret(display); + + settings = gtk_settings_get_default(); - view->caret_timer = g_timeout_add_seconds(1, (GSourceFunc)gtk_buffer_view_refresh_caret, view); + g_object_get(settings, "gtk-cursor-blink-time", &interval, NULL); + + g_object_ref(G_OBJECT(display)); + + display->caret_timer = g_timeout_add_full(G_PRIORITY_DEFAULT, interval, + (GSourceFunc)gtk_buffer_display_refresh_caret, + display, g_object_unref); } - g_signal_emit_by_name(view, "caret-moved", view->caret_addr); + g_signal_emit_by_name(display, "caret-moved", &display->caret_addr); } /****************************************************************************** * * -* Paramètres : view = composant GTK à manipuler. * +* Paramètres : display = composant GTK à manipuler. * * * * Description : Bascule et relance l'affichage du curseur. * * * @@ -1186,7 +1047,7 @@ static void restart_caret_blinking(GtkBufferView *view) * * ******************************************************************************/ -static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *view) +static gboolean gtk_buffer_display_refresh_caret(GtkBufferDisplay *display) { GtkWidget *widget; /* Autre version du composant */ GdkWindow *window; /* Fenêtre de support associée */ @@ -1194,7 +1055,7 @@ static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *view) cairo_t *cr; /* Contexte graphique */ GdkRGBA *color; /* Couleur du curseur */ - widget = GTK_WIDGET(view); + widget = GTK_WIDGET(display); window = gtk_widget_get_window(widget); /** @@ -1204,24 +1065,24 @@ static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *view) */ if (window == NULL) { - view->show_caret = !view->show_caret; + display->show_caret = !display->show_caret; return TRUE; } - area = view->caret; - gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(view), &area.x, &area.y); + area = display->caret; + gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(display), &area.x, &area.y); /* Réinitialisation de la surface */ - if (view->show_caret) + if (display->show_caret) { - view->show_caret = false; + display->show_caret = false; gtk_widget_queue_draw_area(widget, area.x, area.y, area.width, area.height); } /* Dessin */ else { - view->show_caret = true; + display->show_caret = true; cr = gdk_cairo_create(gtk_widget_get_window(widget)); diff --git a/src/gtkext/gtkbufferdisplay.h b/src/gtkext/gtkbufferdisplay.h new file mode 100644 index 0000000..ea06b94 --- /dev/null +++ b/src/gtkext/gtkbufferdisplay.h @@ -0,0 +1,70 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkbufferdisplay.h - prototypes pour l'affichage de tampons de lignes + * + * Copyright (C) 2016 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/>. + */ + + +#ifndef _GTKEXT_GTKBUFFER_DISPLAY_H +#define _GTKEXT_GTKBUFFER_DISPLAY_H + + +#include <glib-object.h> +#include <gtk/gtk.h> + + +#include "../glibext/gbufferview.h" + + + +#define GTK_TYPE_BUFFER_DISPLAY (gtk_buffer_display_get_type()) +#define GTK_BUFFER_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BUFFER_DISPLAY, GtkBufferDisplay)) +#define GTK_BUFFER_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BUFFER_DISPLAY, GtkBufferDisplayClass)) +#define GTK_IS_BUFFER_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BUFFER_DISPLAY)) +#define GTK_IS_BUFFER_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BUFFER_DISPLAY)) +#define GTK_BUFFER_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BUFFER_VIEW, GtkBufferDisplayClass)) + + +/* Composant d'affichage de tampon de lignes (instance) */ +typedef struct _GtkBufferDisplay GtkBufferDisplay; + +/* Composant d'affichage de tampon de lignes (classe) */ +typedef struct _GtkBufferDisplayClass GtkBufferDisplayClass; + + +/* Détermine le type du composant d'affichage de tampon de lignes. */ +GType gtk_buffer_display_get_type(void); + +/* Lie une vue au composant d'affichage de tampon. */ +void gtk_buffer_display_set_view(GtkBufferDisplay *, GBufferView *); + +/* Fournit la vue associée au tampon de lignes courant. */ +GBufferView *gtk_buffer_display_get_view(const GtkBufferDisplay *); + + + +/* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */ + + +/* Déplace le curseur à un emplacement en extrémité. */ +bool gtk_buffer_display_move_caret_to(GtkBufferDisplay *, bool, gint *); + + + +#endif /* _GTKEXT_GTKBUFFER_DISPLAY_H */ diff --git a/src/gtkext/gtkbufferview.h b/src/gtkext/gtkbufferview.h deleted file mode 100644 index 1b13ab0..0000000 --- a/src/gtkext/gtkbufferview.h +++ /dev/null @@ -1,70 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gtkbufferview.h - prototypes pour l'affichage de tampons de lignes - * - * Copyright (C) 2010-2014 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/>. - */ - - -#ifndef _GTK_BUFFERVIEW_H -#define _GTK_BUFFERVIEW_H - - -#include <glib-object.h> -#include <gtk/gtk.h> - - -#include "../glibext/gbufferview.h" - - - -#define GTK_TYPE_BUFFER_VIEW (gtk_buffer_view_get_type()) -#define GTK_BUFFER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BUFFER_VIEW, GtkBufferView)) -#define GTK_BUFFER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BUFFER_VIEW, GtkBufferViewClass)) -#define GTK_IS_BUFFER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BUFFER_VIEW)) -#define GTK_IS_BUFFER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BUFFER_VIEW)) -#define GTK_BUFFER_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BUFFER_VIEW, GtkBufferViewClass)) - - -/* Composant d'affichage de tampon de lignes (instance) */ -typedef struct _GtkBufferView GtkBufferView; - -/* Composant d'affichage de tampon de lignes (classe) */ -typedef struct _GtkBufferViewClass GtkBufferViewClass; - - -/* Détermine le type du composant d'affichage de tampon de lignes. */ -GType gtk_buffer_view_get_type(void); - -/* Prend acte de l'association d'un tampon de lignes. */ -void gtk_buffer_view_attach_buffer(GtkBufferView *, GBufferView *); - -/* Fournit la vue associée au tampon de lignes courant. */ -GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *); - - - -/* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */ - - -/* Déplace le curseur à un emplacement en extrémité. */ -bool gtk_buffer_view_move_caret_to(GtkBufferView *, bool, gint *); - - - -#endif /* _GTK_BUFFERVIEW_H */ diff --git a/src/gtkext/gtkdisplaypanel-int.h b/src/gtkext/gtkdisplaypanel-int.h index bc0e229..f6221d5 100644 --- a/src/gtkext/gtkdisplaypanel-int.h +++ b/src/gtkext/gtkdisplaypanel-int.h @@ -48,9 +48,6 @@ typedef void (* adjust_scroll_value_fc) (GtkDisplayPanel *, GtkAdjustment *, Gtk /* Réagit à la sélection externe d'une adresse. */ typedef void (* define_address_fc) (GtkDisplayPanel *, const vmpa2t *); -/* Actualise les besoins internes avant un redimensionnement. */ -typedef void (* prepare_resize_fc) (GtkDisplayPanel *); - /* Indique la position courante du curseur. */ typedef const vmpa2t * (* get_caret_location_fc) (const GtkDisplayPanel *); @@ -84,9 +81,6 @@ struct _GtkDisplayPanel GLoadedBinary *binary; /* Binaire à visualiser */ - //define_address_fc define; /* Centrage sur une partie */ - prepare_resize_fc resize; /* Prépare une nouvelle taille */ - }; /* Composant d'affichage générique (classe) */ diff --git a/src/gtkext/gtkdisplaypanel.c b/src/gtkext/gtkdisplaypanel.c index 6793d4e..66ec909 100644 --- a/src/gtkext/gtkdisplaypanel.c +++ b/src/gtkext/gtkdisplaypanel.c @@ -641,7 +641,8 @@ static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *adj, GtkDi orientation = (adj == panel->hadjustment ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL); - GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust(panel, adj, orientation); + if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust != NULL) + GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust(panel, adj, orientation); } @@ -832,9 +833,6 @@ static void on_view_panel_binary_display_change(GLoadedBinary *binary, BinaryVie { if (panel->content == view) { - if (panel->resize != NULL) - panel->resize(panel); - gtk_widget_queue_resize(gtk_widget_get_parent(GTK_WIDGET(panel))); gtk_widget_queue_resize(GTK_WIDGET(panel)); gtk_widget_queue_draw(GTK_WIDGET(panel)); @@ -924,23 +922,15 @@ void _gtk_display_panel_scroll_to_address(GtkDisplayPanel *panel, const vmpa2t * double value; /* Valeur courante */ /** - * Si une vue partielle se déplacer via cette fonction, il faut potentiellement + * Si une vue partielle se déplace via cette fonction, il faut potentiellement * rediriger l'appel vers la vue en graphiques parente. */ parent = gtk_widget_get_parent(GTK_WIDGET(panel)); parent = gtk_widget_get_parent(GTK_WIDGET(parent)); - printf(" Widgets : %s -> %s\n", - G_OBJECT_TYPE_NAME(parent), G_OBJECT_TYPE_NAME(panel)); - if (GTK_IS_DISPLAY_PANEL(parent)) - { - printf("reparent !\n"); panel = GTK_DISPLAY_PANEL(parent); - } - else - printf("no need reparent !\n"); if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->define != NULL) GTK_DISPLAY_PANEL_GET_CLASS(panel)->define(panel, addr); diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphdisplay.c index 57bbec0..1d4f831 100644 --- a/src/gtkext/gtkgraphview.c +++ b/src/gtkext/gtkgraphdisplay.c @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkgraphview.c - affichage de morceaux de code sous forme graphique + * gtkgraphdisplay.c - affichage de morceaux de code sous forme graphique * - * Copyright (C) 2009-2014 Cyrille Bagard + * Copyright (C) 2009-2016 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,14 +21,14 @@ */ -#include "gtkgraphview.h" +#include "gtkgraphdisplay.h" #include <assert.h> -#include "gtkblockview.h" -#include "gtkbufferview.h" +#include "gtkblockdisplay.h" +#include "gtkbufferdisplay.h" #include "gtkdisplaypanel-int.h" #include "graph/cluster.h" #include "../analysis/blocks/flow.h" @@ -38,7 +38,7 @@ /* Composant d'affichage sous forme graphique (instance) */ -struct _GtkGraphView +struct _GtkGraphDisplay { GtkDisplayPanel parent; /* A laisser en premier */ GtkWidget *support; /* Support des vues en bloc */ @@ -47,11 +47,7 @@ struct _GtkGraphView GBinRoutine *routine; /* Routine en cours d'affichage*/ segcnt_list *highlighted; /* Segments mis en évidence */ - GtkBufferView **children; /* Liste des sous-blocs */ - GtkAllocation *allocs; /* Emplacements prévisibles */ - size_t children_count; /* Taille de cette liste */ - //GGraphLayout *layout; /* Disposition en graphique */ GGraphCluster *cluster; /* Disposition en graphique */ GGraphEdge **edges; /* Liens entre les noeuds */ @@ -66,7 +62,7 @@ struct _GtkGraphView }; /* Composant d'affichage sous forme graphique (classe) */ -struct _GtkGraphViewClass +struct _GtkGraphDisplayClass { GtkDisplayPanelClass parent; /* A laisser en premier */ @@ -76,77 +72,74 @@ struct _GtkGraphViewClass /* Profondeur de l'ombre */ #define SHADOW_SIZE 4 +/* Marges en bordure de graphique */ +#define GRAPH_MARGIN 23 + /* Initialise la classe générique des graphiques de code. */ -static void gtk_graph_view_class_init(GtkGraphViewClass *); +static void gtk_graph_display_class_init(GtkGraphDisplayClass *); /* Initialise une instance d'afficheur de code en graphique. */ -static void gtk_graph_view_init(GtkGraphView *); +static void gtk_graph_display_init(GtkGraphDisplay *); /* Supprime toutes les références externes. */ -static void gtk_graph_view_dispose(GtkGraphView *); +static void gtk_graph_display_dispose(GtkGraphDisplay *); /* Procède à la libération totale de la mémoire. */ -static void gtk_graph_view_finalize(GtkGraphView *); +static void gtk_graph_display_finalize(GtkGraphDisplay *); /* S'adapte à la surface concédée par le composant parent. */ -static void gtk_graph_view_size_allocate(GtkWidget *, GtkAllocation *); +static void gtk_graph_display_size_allocate(GtkWidget *, GtkAllocation *); /* Centre si possible le contenu du panneau d'affichage. */ -static void gtk_graph_view_update_support_margins(GtkGraphView *, const GtkAllocation *); +static void gtk_graph_display_update_support_margins(GtkGraphDisplay *, const GtkAllocation *); /* Indique les dimensions de travail du composant d'affichage. */ -static void gtk_graph_view_compute_requested_size(GtkGraphView *, gint *, gint *); +static void gtk_graph_display_compute_requested_size(GtkGraphDisplay *, gint *, gint *); /* Réagit à un défilement chez une barre associée au composant. */ -static void gtk_graph_view_adjust_scroll_value(GtkGraphView *, GtkAdjustment *, GtkOrientation); +static void gtk_graph_display_adjust_scroll_value(GtkGraphDisplay *, GtkAdjustment *, GtkOrientation); /* Met à jour l'affichage de la vue sous forme graphique. */ -static gboolean gtk_graph_view_draw(GtkWidget *, cairo_t *, GtkGraphView *); +static gboolean gtk_graph_display_draw(GtkWidget *, cairo_t *, GtkGraphDisplay *); /* Assure la gestion des clics de souris sur le composant. */ -static gboolean gtk_graph_view_button_press(GtkWidget *, GdkEventButton *, GtkGraphView *); +static gboolean gtk_graph_display_button_press(GtkWidget *, GdkEventButton *, GtkGraphDisplay *); /* Assure la gestion des clics de souris sur le composant. */ -static gboolean gtk_graph_view_button_release(GtkWidget *, GdkEventButton *, GtkGraphView *); +static gboolean gtk_graph_display_button_release(GtkWidget *, GdkEventButton *, GtkGraphDisplay *); /* Assure la suivi des déplacements de souris sur le composant. */ -static gboolean gtk_graph_view_motion_notify(GtkWidget *, GdkEventMotion *, GtkGraphView *); - -/* Actualise les besoins internes avant un redimensionnement. */ -static void gtk_graph_view_prepare_resize(GtkGraphView *); +static gboolean gtk_graph_display_motion_notify(GtkWidget *, GdkEventMotion *, GtkGraphDisplay *); /* Réagit à la sélection externe d'une adresse. */ -static void gtk_graph_view_define_main_address(GtkGraphView *, const vmpa2t *); +static void gtk_graph_display_define_main_address(GtkGraphDisplay *, const vmpa2t *); /* Indique la position courante du curseur. */ -static const vmpa2t *gtk_graph_view_get_caret_location(const GtkGraphView *); +static const vmpa2t *gtk_graph_display_get_caret_location(const GtkGraphDisplay *); /* Indique la position d'affichage d'une adresse donnée. */ -static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak); +static bool gtk_graph_display_get_address_coordinates(const GtkGraphDisplay *, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak); /* Déplace le curseur à un emplacement défini. */ -static bool gtk_graph_view_move_caret_to(GtkGraphView *, gint, gint); +static bool gtk_graph_display_move_caret_to(GtkGraphDisplay *, gint, gint); /* Place en cache un rendu destiné à l'aperçu graphique rapide. */ -static void gtk_graph_view_cache_glance(GtkGraphView *, cairo_t *, const GtkAllocation *, double); +static void gtk_graph_display_cache_glance(GtkGraphDisplay *, cairo_t *, const GtkAllocation *, double); /* Supprime tout contenu de l'afficheur de code en graphique. */ -static void gtk_graph_view_reset(GtkGraphView *); - -/* Définit la liste complète des éléments du futur graphique. */ -static GtkBufferView **gtk_graph_view_load_nodes(GtkGraphView *, GLoadedBinary *, const GBinRoutine *); +static void gtk_graph_display_reset(GtkGraphDisplay *); /* Notifie un changement de surbrillance au sein d'un noeud. */ -static void gtk_graph_view_changed_highlights(GtkBlockView *, GtkGraphView *); +static void gtk_graph_display_changed_highlights(GtkBlockDisplay *, GtkGraphDisplay *); /* Notifie une incapacité de déplacement au sein d'un noeud. */ -static void gtk_graph_view_reach_caret_limit(GtkBufferView *, GdkScrollDirection, GtkGraphView *); +static void gtk_graph_display_reach_caret_limit(GtkBufferDisplay *, GdkScrollDirection, GtkGraphDisplay *); /* Détermine le type du composant d'affichage en graphique. */ -G_DEFINE_TYPE(GtkGraphView, gtk_graph_view, GTK_TYPE_DISPLAY_PANEL) +G_DEFINE_TYPE(GtkGraphDisplay, gtk_graph_display, GTK_TYPE_DISPLAY_PANEL) /****************************************************************************** @@ -161,7 +154,7 @@ G_DEFINE_TYPE(GtkGraphView, gtk_graph_view, GTK_TYPE_DISPLAY_PANEL) * * ******************************************************************************/ -static void gtk_graph_view_class_init(GtkGraphViewClass *class) +static void gtk_graph_display_class_init(GtkGraphDisplayClass *class) { GObjectClass *object; /* Autre version de la classe */ GtkWidgetClass *widget_class; /* Classe de haut niveau */ @@ -169,30 +162,30 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *class) object = G_OBJECT_CLASS(class); - object->dispose = (GObjectFinalizeFunc/* ! */)gtk_graph_view_dispose; - object->finalize = (GObjectFinalizeFunc)gtk_graph_view_finalize; + object->dispose = (GObjectFinalizeFunc/* ! */)gtk_graph_display_dispose; + object->finalize = (GObjectFinalizeFunc)gtk_graph_display_finalize; widget_class = GTK_WIDGET_CLASS(class); - widget_class->size_allocate = gtk_graph_view_size_allocate; + widget_class->size_allocate = gtk_graph_display_size_allocate; panel_class = GTK_DISPLAY_PANEL_CLASS(class); - panel_class->compute_size = (compute_requested_size_fc)gtk_graph_view_compute_requested_size; - panel_class->adjust = (adjust_scroll_value_fc)gtk_graph_view_adjust_scroll_value; - panel_class->define = (define_address_fc)gtk_graph_view_define_main_address; + panel_class->compute_size = (compute_requested_size_fc)gtk_graph_display_compute_requested_size; + panel_class->adjust = (adjust_scroll_value_fc)gtk_graph_display_adjust_scroll_value; + panel_class->define = (define_address_fc)gtk_graph_display_define_main_address; - panel_class->get_caret_loc = (get_caret_location_fc)gtk_graph_view_get_caret_location; - panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates; - panel_class->move_caret_to = (move_caret_to_fc)gtk_graph_view_move_caret_to; - panel_class->cache_glance = (cache_glance_fc)gtk_graph_view_cache_glance; + panel_class->get_caret_loc = (get_caret_location_fc)gtk_graph_display_get_caret_location; + panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_graph_display_get_address_coordinates; + panel_class->move_caret_to = (move_caret_to_fc)gtk_graph_display_move_caret_to; + panel_class->cache_glance = (cache_glance_fc)gtk_graph_display_cache_glance; } /****************************************************************************** * * -* Paramètres : view = instance GTK à initialiser. * +* Paramètres : display = instance GTK à initialiser. * * * * Description : Initialise une instance d'afficheur de code en graphique. * * * @@ -202,64 +195,42 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *class) * * ******************************************************************************/ -static void gtk_graph_view_init(GtkGraphView *view) +static void gtk_graph_display_init(GtkGraphDisplay *display) { - GtkDisplayPanel *panel; /* Instance parente #1 */ - //GtkBinView *binview; /* Instance parente #2 */ - - panel = GTK_DISPLAY_PANEL(view); - - panel->resize = (prepare_resize_fc)gtk_graph_view_prepare_resize; - ////////viewpanel->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates; - - //binview = GTK_BIN_VIEW(view); - - //binview->set_lines = (set_rendering_lines_fc)gtk_graph_view_set_rendering_lines; - //binview->define_address = (define_main_address_fc)gtk_graph_view_define_main_address; - //binview->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates; - - view->support = gtk_fixed_new(); - gtk_widget_set_has_window(view->support, TRUE); - gtk_widget_set_can_focus(view->support, TRUE); + display->support = gtk_fixed_new(); + gtk_widget_set_has_window(display->support, TRUE); + gtk_widget_set_can_focus(display->support, TRUE); - g_signal_connect(G_OBJECT(view->support), "draw", - G_CALLBACK(gtk_graph_view_draw), view); + g_signal_connect(G_OBJECT(display->support), "draw", + G_CALLBACK(gtk_graph_display_draw), display); - g_signal_connect(G_OBJECT(view->support), "button-press-event", - G_CALLBACK(gtk_graph_view_button_press), view); - g_signal_connect(G_OBJECT(view->support), "button-release-event", - G_CALLBACK(gtk_graph_view_button_release), view); - g_signal_connect(G_OBJECT(view->support), "motion-notify-event", - G_CALLBACK(gtk_graph_view_motion_notify), view); + g_signal_connect(G_OBJECT(display->support), "button-press-event", + G_CALLBACK(gtk_graph_display_button_press), display); + g_signal_connect(G_OBJECT(display->support), "button-release-event", + G_CALLBACK(gtk_graph_display_button_release), display); + g_signal_connect(G_OBJECT(display->support), "motion-notify-event", + G_CALLBACK(gtk_graph_display_motion_notify), display); - gtk_widget_add_events(view->support, + gtk_widget_add_events(display->support, GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); - gtk_widget_show(view->support); + gtk_widget_show(display->support); - gtk_fixed_put(GTK_FIXED(view), view->support, 0, 0); + gtk_fixed_put(GTK_FIXED(display), display->support, 0, 0); - //view->mutex = g_mutex_new(); - //view->cond = g_cond_new(); + display->extender = gtk_fixed_new(); + gtk_widget_set_margin_end(display->extender, 1); + gtk_widget_set_margin_top(display->extender, 1); - view->extender = gtk_fixed_new(); - - gtk_widget_set_margin_end(view->extender, 1); - gtk_widget_set_margin_top(view->extender, 1); - - gtk_widget_show(view->extender); - - - view->cluster = NULL; - + gtk_widget_show(display->extender); } /****************************************************************************** * * -* Paramètres : view = instance d'objet GLib à traiter. * +* Paramètres : display = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * @@ -269,24 +240,20 @@ static void gtk_graph_view_init(GtkGraphView *view) * * ******************************************************************************/ -static void gtk_graph_view_dispose(GtkGraphView *view) +static void gtk_graph_display_dispose(GtkGraphDisplay *display) { - g_object_unref(G_OBJECT(view->extender)); + g_object_unref(G_OBJECT(display->extender)); - if (view->cluster != NULL) - { - g_object_unref(G_OBJECT(view->cluster)); - view->cluster = NULL; - } + gtk_graph_display_reset(display); - G_OBJECT_CLASS(gtk_graph_view_parent_class)->dispose(G_OBJECT(view)); + G_OBJECT_CLASS(gtk_graph_display_parent_class)->dispose(G_OBJECT(display)); } /****************************************************************************** * * -* Paramètres : view = instance d'objet GLib à traiter. * +* Paramètres : display = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * @@ -296,9 +263,9 @@ static void gtk_graph_view_dispose(GtkGraphView *view) * * ******************************************************************************/ -static void gtk_graph_view_finalize(GtkGraphView *view) +static void gtk_graph_display_finalize(GtkGraphDisplay *display) { - G_OBJECT_CLASS(gtk_graph_view_parent_class)->finalize(G_OBJECT(view)); + G_OBJECT_CLASS(gtk_graph_display_parent_class)->finalize(G_OBJECT(display)); } @@ -316,21 +283,22 @@ static void gtk_graph_view_finalize(GtkGraphView *view) * * ******************************************************************************/ -static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +static void gtk_graph_display_size_allocate(GtkWidget *widget, GtkAllocation *allocation) { - GtkGraphView *view; /* Autre version du composant */ + GtkGraphDisplay *display; /* Autre version du composant */ - GTK_WIDGET_CLASS(gtk_graph_view_parent_class)->size_allocate(widget, allocation); + GTK_WIDGET_CLASS(gtk_graph_display_parent_class)->size_allocate(widget, allocation); - view = GTK_GRAPH_VIEW(widget); + display = GTK_GRAPH_DISPLAY(widget); - gtk_graph_view_update_support_margins(view, allocation); + gtk_graph_display_update_support_margins(display, allocation); } + /****************************************************************************** * * -* Paramètres : view = panneau dont le contenu est à déplacer. * +* Paramètres : display = panneau dont le contenu est à déplacer. * * allocation = étendue accordée à la vue. * * * * Description : Centre si possible le contenu du panneau d'affichage. * @@ -341,14 +309,14 @@ static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *alloc * * ******************************************************************************/ -static void gtk_graph_view_update_support_margins(GtkGraphView *view, const GtkAllocation *allocation) +static void gtk_graph_display_update_support_margins(GtkGraphDisplay *display, const GtkAllocation *allocation) { gint width; /* Largeur totale du support */ gint height; /* Hauteur totale du support */ gint start; /* Bordure horizontale */ gint top; /* Bordure verticale */ - gtk_graph_view_compute_requested_size(view, &width, &height); + gtk_graph_display_compute_requested_size(display, &width, &height); if (width > allocation->width) start = 0; @@ -360,17 +328,17 @@ static void gtk_graph_view_update_support_margins(GtkGraphView *view, const GtkA else top = (allocation->height - height) / 2; - gtk_widget_set_margin_start(view->support, start); - gtk_widget_set_margin_top(view->support, top); + gtk_widget_set_margin_start(display->support, start); + gtk_widget_set_margin_top(display->support, top); } /****************************************************************************** * * -* Paramètres : view = composant GTK à consulter. * -* width = largeur requise à renseigner ou NULL. [OUT] * -* height = hauteur requise à renseigner ou NULL. [OUT] * +* Paramètres : display = composant GTK à consulter. * +* width = largeur requise à renseigner ou NULL. [OUT] * +* height = hauteur requise à renseigner ou NULL. [OUT] * * * * Description : Indique les dimensions de travail du composant d'affichage. * * * @@ -380,18 +348,17 @@ static void gtk_graph_view_update_support_margins(GtkGraphView *view, const GtkA * * ******************************************************************************/ -static void gtk_graph_view_compute_requested_size(GtkGraphView *view, gint *width, gint *height) +static void gtk_graph_display_compute_requested_size(GtkGraphDisplay *display, gint *width, gint *height) { GtkAllocation needed; /* Taille requise */ - gint rwidth; /* Largeur demandée */ - gint rheight; /* Hauteur demandée */ - if (view->cluster != NULL) + if (display->cluster != NULL) { - g_graph_cluster_compute_needed_alloc(view->cluster, &needed); + g_graph_cluster_compute_needed_alloc(display->cluster, &needed); assert(needed.x == 0 && needed.y == 0); - /* TODO : marges ou centrage */ + needed.width += 2 * GRAPH_MARGIN; + needed.height += 2 * GRAPH_MARGIN; } else @@ -400,15 +367,15 @@ static void gtk_graph_view_compute_requested_size(GtkGraphView *view, gint *widt needed.height = 0; } - if (width != NULL) *width = needed.width + SHADOW_SIZE; - if (height != NULL) *height = needed.height + SHADOW_SIZE; + if (width != NULL) *width = needed.width; + if (height != NULL) *height = needed.height; } /****************************************************************************** * * -* Paramètres : view = panneau d'affichage concerné. * +* Paramètres : display = panneau d'affichage concerné. * * adj = défilement dont une valeur a changé. * * orientation = indication sur le défilement à traiter. * * * @@ -420,25 +387,25 @@ static void gtk_graph_view_compute_requested_size(GtkGraphView *view, gint *widt * * ******************************************************************************/ -static void gtk_graph_view_adjust_scroll_value(GtkGraphView *view, GtkAdjustment *adj, GtkOrientation orientation) +static void gtk_graph_display_adjust_scroll_value(GtkGraphDisplay *display, GtkAdjustment *adj, GtkOrientation orientation) { gint fake_x; /* Abscisse virtuelle */ gint fake_y; /* Ordonnée virtuelle */ fake_x = 0; fake_y = 0; - gtk_display_panel_compute_fake_coord(GTK_DISPLAY_PANEL(view), &fake_x, &fake_y); + gtk_display_panel_compute_fake_coord(GTK_DISPLAY_PANEL(display), &fake_x, &fake_y); - gtk_fixed_move(GTK_FIXED(view), view->support, fake_x, -fake_y); + gtk_fixed_move(GTK_FIXED(display), display->support, fake_x, -fake_y); } /****************************************************************************** * * -* Paramètres : widget = composant GTK à redessiner. * -* cr = contexte graphique associé à l'événement. * -* view = support maître à consulter. * +* Paramètres : widget = composant GTK à redessiner. * +* cr = contexte graphique associé à l'événement. * +* display = support maître à consulter. * * * * Description : Met à jour l'affichage de la vue sous forme graphique. * * * @@ -448,7 +415,7 @@ static void gtk_graph_view_adjust_scroll_value(GtkGraphView *view, GtkAdjustment * * ******************************************************************************/ -static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView *view) +static gboolean gtk_graph_display_draw(GtkWidget *widget, cairo_t *cr, GtkGraphDisplay *display) { size_t i; /* Boucle de parcours */ @@ -458,6 +425,10 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView gint j; /* Boucle de parcours */ cairo_pattern_t *pattern; /* Zones d'application */ + /* On évite l'extenseur de support... */ + if (!GTK_IS_DISPLAY_PANEL(child)) + return; + gtk_widget_get_allocation(child, &alloc); for (j = 1; j < SHADOW_SIZE; j++) @@ -486,17 +457,10 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView } - gtk_container_foreach(GTK_CONTAINER(view->support), (GtkCallback)draw_shadow, NULL); - - - for (i = 0; i < view->edges_count; i++) - g_graph_edge_draw(view->edges[i], cr, true); - + gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)draw_shadow, NULL); - /* - if (view->layout != NULL) - g_graph_layout_draw(view->layout, cr, true); - */ + for (i = 0; i < display->edges_count; i++) + g_graph_edge_draw(display->edges[i], cr, true); return FALSE; @@ -505,9 +469,9 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView /****************************************************************************** * * -* Paramètres : widget = composant GTK visé par l'opération. * -* event = informations liées à l'événement. * -* view = support maître à consulter. * +* Paramètres : widget = composant GTK visé par l'opération. * +* event = informations liées à l'événement. * +* display = support maître à consulter. * * * * Description : Assure la gestion des clics de souris sur le composant. * * * @@ -517,7 +481,7 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView * * ******************************************************************************/ -static gboolean gtk_graph_view_button_press(GtkWidget *widget, GdkEventButton *event, GtkGraphView *view) +static gboolean gtk_graph_display_button_press(GtkWidget *widget, GdkEventButton *event, GtkGraphDisplay *display) { gboolean result; /* Poursuite à faire suivre */ GtkScrolledWindow *support; /* Support défilant associé */ @@ -529,21 +493,21 @@ static gboolean gtk_graph_view_button_press(GtkWidget *widget, GdkEventButton *e if (event->button == 1) { - support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(view))); + support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(display))); hadj = gtk_scrolled_window_get_hadjustment(support); vadj = gtk_scrolled_window_get_vadjustment(support); - view->big_enough = (gtk_adjustment_get_upper(hadj) > gtk_adjustment_get_page_size(hadj) + display->big_enough = (gtk_adjustment_get_upper(hadj) > gtk_adjustment_get_page_size(hadj) || gtk_adjustment_get_upper(vadj) > gtk_adjustment_get_page_size(vadj)); - if (view->big_enough) + if (display->big_enough) { - view->start_x = event->x_root; - view->start_y = event->y_root; + display->start_x = event->x_root; + display->start_y = event->y_root; - view->ref_h = gtk_adjustment_get_value(hadj); - view->ref_v = gtk_adjustment_get_value(vadj); + display->ref_h = gtk_adjustment_get_value(hadj); + display->ref_v = gtk_adjustment_get_value(vadj); cursor = gdk_cursor_new(GDK_FLEUR); gdk_window_set_cursor(gtk_widget_get_window(widget), cursor); @@ -562,9 +526,9 @@ static gboolean gtk_graph_view_button_press(GtkWidget *widget, GdkEventButton *e /****************************************************************************** * * -* Paramètres : widget = composant GTK visé par l'opération. * -* event = informations liées à l'événement. * -* view = support maître à consulter. * +* Paramètres : widget = composant GTK visé par l'opération. * +* event = informations liées à l'événement. * +* display = support maître à consulter. * * * * Description : Assure la gestion des clics de souris sur le composant. * * * @@ -574,9 +538,9 @@ static gboolean gtk_graph_view_button_press(GtkWidget *widget, GdkEventButton *e * * ******************************************************************************/ -static gboolean gtk_graph_view_button_release(GtkWidget *widget, GdkEventButton *event, GtkGraphView *view) +static gboolean gtk_graph_display_button_release(GtkWidget *widget, GdkEventButton *event, GtkGraphDisplay *display) { - if (event->button == 1 && view->big_enough) + if (event->button == 1 && display->big_enough) gdk_window_set_cursor(gtk_widget_get_window(widget), NULL); return FALSE; @@ -586,9 +550,9 @@ static gboolean gtk_graph_view_button_release(GtkWidget *widget, GdkEventButton /****************************************************************************** * * -* Paramètres : widget = composant GTK visé par l'opération. * -* event = informations liées à l'événement. * -* view = support maître à consulter. * +* Paramètres : widget = composant GTK visé par l'opération. * +* event = informations liées à l'événement. * +* display = support maître à consulter. * * * * Description : Assure la suivi des déplacements de souris sur le composant. * * * @@ -598,7 +562,7 @@ static gboolean gtk_graph_view_button_release(GtkWidget *widget, GdkEventButton * * ******************************************************************************/ -static gboolean gtk_graph_view_motion_notify(GtkWidget *widget, GdkEventMotion *event, GtkGraphView *view) +static gboolean gtk_graph_display_motion_notify(GtkWidget *widget, GdkEventMotion *event, GtkGraphDisplay *display) { gdouble diff_x; /* Evolution sur les abscisses */ gdouble diff_y; /* Evolution sur les ordonnées */ @@ -607,21 +571,21 @@ static gboolean gtk_graph_view_motion_notify(GtkWidget *widget, GdkEventMotion * GtkAdjustment *vadj; /* Gestionnaire du défilement */ gdouble value; /* Nouvelle valeur bornée */ - if (event->state & GDK_BUTTON1_MASK && view->big_enough) + if (event->state & GDK_BUTTON1_MASK && display->big_enough) { - diff_x = view->start_x - event->x_root; - diff_y = view->start_y - event->y_root; + diff_x = display->start_x - event->x_root; + diff_y = display->start_y - event->y_root; - support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(view))); + support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(display))); hadj = gtk_scrolled_window_get_hadjustment(support); vadj = gtk_scrolled_window_get_vadjustment(support); - value = CLAMP(view->ref_h + diff_x, gtk_adjustment_get_lower(hadj), + value = CLAMP(display->ref_h + diff_x, gtk_adjustment_get_lower(hadj), gtk_adjustment_get_upper(hadj) - gtk_adjustment_get_page_size(hadj)); gtk_adjustment_set_value(hadj, value); - value = CLAMP(view->ref_v + diff_y, gtk_adjustment_get_lower(vadj), + value = CLAMP(display->ref_v + diff_y, gtk_adjustment_get_lower(vadj), gtk_adjustment_get_upper(vadj) - gtk_adjustment_get_page_size(vadj)); gtk_adjustment_set_value(vadj, value); @@ -634,41 +598,8 @@ static gboolean gtk_graph_view_motion_notify(GtkWidget *widget, GdkEventMotion * /****************************************************************************** * * -* Paramètres : view = composant GTK à mettre à jour. * -* * -* Description : Actualise les besoins internes avant un redimensionnement. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_graph_view_prepare_resize(GtkGraphView *view) -{ - size_t i; /* Boucle de parcours */ - - if (view->children_count > 0) - { - for (i = 0; i < view->children_count; i++) - gtk_widget_queue_resize(GTK_WIDGET(view->children[i])); - - /* - g_graph_layout_refresh(view->layout); - g_graph_layout_place(view->layout, view); - */ - - change_editor_items_current_view_content(GTK_DISPLAY_PANEL(view)); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : view = composant GTK à mettre à jour. * -* addr = adresse sélectionnée de manière externe. * +* Paramètres : display = composant GTK à mettre à jour. * +* addr = adresse sélectionnée de manière externe. * * * * Description : Réagit à la sélection externe d'une adresse. * * * @@ -678,7 +609,7 @@ static void gtk_graph_view_prepare_resize(GtkGraphView *view) * * ******************************************************************************/ -static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t *addr) +static void gtk_graph_display_define_main_address(GtkGraphDisplay *display, const vmpa2t *addr) { bool need_update; /* Mise à jour du contenu ? */ const mrange_t *range; /* Couverture courante */ @@ -690,19 +621,19 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t gint bottom; /* Ordonnée du coin inférieur */ GtkAllocation allocation; /* Espace alloué au panneau */ - if (view->routine == NULL) + if (display->routine == NULL) need_update = true; else { - range = g_binary_routine_get_range(view->routine); + range = g_binary_routine_get_range(display->routine); need_update = !mrange_contains_addr(range, addr); } if (need_update) { - gtk_graph_view_reset(view); + gtk_graph_display_reset(display); - format = g_loaded_binary_get_format(GTK_DISPLAY_PANEL(view)->binary); + format = g_loaded_binary_get_format(GTK_DISPLAY_PANEL(display)->binary); routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count); for (i = 0; i < routines_count; i++) @@ -711,22 +642,22 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t if (mrange_contains_addr(range, addr)) { - view->routine = routines[i]; - g_object_ref(G_OBJECT(view->routine)); + display->routine = routines[i]; + g_object_ref(G_OBJECT(display->routine)); - view->highlighted = init_segment_content_list(); + display->highlighted = init_segment_content_list(); /* - view->children = gtk_graph_view_load_nodes(view, GTK_DISPLAY_PANEL(view)->binary, + display->children = gtk_graph_display_load_nodes(display, GTK_DISPLAY_PANEL(display)->binary, routines[i]); - view->allocs = (GtkAllocation *)calloc(view->children_count, + display->allocs = (GtkAllocation *)calloc(display->children_count, sizeof(GtkAllocation)); - view->layout = g_graph_layout_new(g_binary_routine_get_basic_blocks(view->routine), - view->children, view->children_count); + display->layout = g_graph_layout_new(g_binary_routine_get_basic_blocks(display->routine), + display->children, display->children_count); - g_graph_layout_place(view->layout, view); + g_graph_layout_place(display->layout, display); */ do @@ -737,17 +668,17 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t list = g_binary_routine_get_basic_blocks(routines[i]); #if 0 - view->cluster = g_graph_cluster_new(GTK_DISPLAY_PANEL(view)->binary, - list, 0/* FIXME */, view->highlighted); + display->cluster = g_graph_cluster_new(GTK_DISPLAY_PANEL(display)->binary, + list, 0/* FIXME */, display->highlighted); #endif - view->cluster = bootstrap_graph_cluster(GTK_DISPLAY_PANEL(view)->binary, - list, view->highlighted); + display->cluster = bootstrap_graph_cluster(GTK_DISPLAY_PANEL(display)->binary, + list, display->highlighted); - g_graph_cluster_place(view->cluster, view); + g_graph_cluster_place(display->cluster, display); /** * Comme la taille du support ne peut pas être forcée et @@ -755,18 +686,18 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t * minuscule à l'extrémité de ce support. */ - gtk_graph_view_compute_requested_size(view, &right, &bottom); + gtk_graph_display_compute_requested_size(display, &right, &bottom); - g_object_ref(G_OBJECT(view->extender)); - gtk_fixed_put(GTK_FIXED(view->support), view->extender, right, bottom); + g_object_ref(G_OBJECT(display->extender)); + gtk_fixed_put(GTK_FIXED(display->support), display->extender, right - 1, bottom - 1); /** * Si possible, on centre le contenu obtenu. */ - gtk_widget_get_allocation(GTK_WIDGET(view), &allocation); + gtk_widget_get_allocation(GTK_WIDGET(display), &allocation); - gtk_graph_view_update_support_margins(view, &allocation); + gtk_graph_display_update_support_margins(display, &allocation); @@ -781,7 +712,7 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t } - change_editor_items_current_view_content(GTK_DISPLAY_PANEL(view)); + change_editor_items_current_view_content(GTK_DISPLAY_PANEL(display)); g_object_unref(G_OBJECT(format)); @@ -792,7 +723,7 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t /****************************************************************************** * * -* Paramètres : view = composant GTK à manipuler. * +* Paramètres : display = composant GTK à manipuler. * * * * Description : Indique la position courante du curseur. * * * @@ -802,7 +733,7 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t * * ******************************************************************************/ -static const vmpa2t *gtk_graph_view_get_caret_location(const GtkGraphView *view) +static const vmpa2t *gtk_graph_display_get_caret_location(const GtkGraphDisplay *display) { return NULL; /* FIXME */ @@ -811,11 +742,11 @@ static const vmpa2t *gtk_graph_view_get_caret_location(const GtkGraphView *view) /****************************************************************************** * * -* Paramètres : view = composant GTK à consulter. * -* addr = adresse à présenter à l'écran. * -* x = position horizontale au sein du composant. [OUT] * -* y = position verticale au sein du composant. [OUT] * -* tweak = adaptation finale à effectuer. * +* Paramètres : display = composant GTK à consulter. * +* addr = adresse à présenter à l'écran. * +* x = position horizontale au sein du composant. [OUT] * +* y = position verticale au sein du composant. [OUT] * +* tweak = adaptation finale à effectuer. * * * * Description : Indique la position d'affichage d'une adresse donnée. * * * @@ -825,7 +756,7 @@ static const vmpa2t *gtk_graph_view_get_caret_location(const GtkGraphView *view) * * ******************************************************************************/ -static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak) +static bool gtk_graph_display_get_address_coordinates(const GtkGraphDisplay *display, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak) { /* TODO */ @@ -836,9 +767,9 @@ static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, con /****************************************************************************** * * -* Paramètres : view = composant GTK à manipuler. * -* x = abscisse proposée pour le nouvel emplacement. * -* y = ordonnée proposée pour le nouvel emplacement. * +* Paramètres : display = composant GTK à manipuler. * +* x = abscisse proposée pour le nouvel emplacement. * +* y = ordonnée proposée pour le nouvel emplacement. * * * * Description : Déplace le curseur à un emplacement défini. * * * @@ -848,31 +779,41 @@ static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, con * * ******************************************************************************/ -static bool gtk_graph_view_move_caret_to(GtkGraphView *view, gint x, gint y) +static bool gtk_graph_display_move_caret_to(GtkGraphDisplay *display, gint x, gint y) { bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - GtkDisplayPanel *panel; /* Autre vision d'enfance */ - gint sub_x; /* Abscisse relative à l'enfant*/ - gint sub_y; /* Ordonnée relative à l'enfant*/ result = false; - for (i = 0; i < view->children_count; i++) + void move_caret_to_sub_block(GtkWidget *child, gpointer unused) { - if (x < view->allocs[i].x || x >= (view->allocs[i].x + view->allocs[i].width)) continue; - if (y < view->allocs[i].y || y >= (view->allocs[i].y + view->allocs[i].height)) continue; + GtkAllocation alloc; /* Emplacement réservé */ + GtkDisplayPanel *panel; /* Autre vision d'enfance */ + gint sub_x; /* Abscisse relative à l'enfant*/ + gint sub_y; /* Ordonnée relative à l'enfant*/ + + if (result) + return; + + if (!GTK_IS_BUFFER_DISPLAY(child)) + return; + + gtk_widget_get_allocation(child, &alloc); + + if (x < alloc.x || x >= (alloc.x + alloc.width)) return; + if (y < alloc.y || y >= (alloc.y + alloc.height)) return; - panel = GTK_DISPLAY_PANEL(view->children[i]); + panel = GTK_DISPLAY_PANEL(child); - sub_x = x - view->allocs[i].x; - sub_y = y - view->allocs[i].y; + sub_x = x - alloc.x; + sub_y = y - alloc.y; result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->move_caret_to(panel, sub_x, sub_y); - break; } + gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)move_caret_to_sub_block, NULL); + return result; } @@ -880,10 +821,10 @@ static bool gtk_graph_view_move_caret_to(GtkGraphView *view, gint x, gint y) /****************************************************************************** * * -* Paramètres : view = composant GTK à manipuler. * -* cairo = assistant pour la création de rendus. * -* area = taille de la surface réduite à disposition. * -* scale = échelle vis à vis de la taille réelle. * +* Paramètres : display = composant GTK à manipuler. * +* cr = assistant pour la création de rendus. * +* area = taille de la surface réduite à disposition. * +* scale = échelle vis à vis de la taille réelle. * * * * Description : Place en cache un rendu destiné à l'aperçu graphique rapide. * * * @@ -893,28 +834,34 @@ static bool gtk_graph_view_move_caret_to(GtkGraphView *view, gint x, gint y) * * ******************************************************************************/ -static void gtk_graph_view_cache_glance(GtkGraphView *view, cairo_t *cairo, const GtkAllocation *area, double scale) +static void gtk_graph_display_cache_glance(GtkGraphDisplay *display, cairo_t *cr, const GtkAllocation *area, double scale) { size_t i; /* Boucle de parcours */ - GtkAllocation sub_area; /* Emplacement réservé */ - for (i = 0; i < view->children_count; i++) + void draw_child_glance(GtkWidget *child, gpointer unused) { - sub_area.x = view->allocs[i].x * scale; - sub_area.y = view->allocs[i].y * scale; - sub_area.width = view->allocs[i].width * scale + 1; - sub_area.height = view->allocs[i].height * scale + 1; + GtkAllocation sub_area; /* Emplacement réservé */ + + if (!GTK_IS_BUFFER_DISPLAY(child)) + return; - gtk_display_panel_cache_glance(GTK_DISPLAY_PANEL(view->children[i]), cairo, &sub_area, scale); + gtk_widget_get_allocation(child, &sub_area); + + sub_area.x *= scale; + sub_area.y *= scale; + sub_area.width = sub_area.width * scale + 1; + sub_area.height = sub_area.height * scale + 1; + + gtk_display_panel_cache_glance(GTK_DISPLAY_PANEL(child), cr, &sub_area, scale); } - cairo_scale(cairo, scale, scale); + gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)draw_child_glance, NULL); - /* - if (view->layout != NULL) - g_graph_layout_draw(view->layout, cairo, false); - */ + cairo_scale(cr, scale, scale); + + for (i = 0; i < display->edges_count; i++) + g_graph_edge_draw(display->edges[i], cr, false); } @@ -931,19 +878,19 @@ static void gtk_graph_view_cache_glance(GtkGraphView *view, cairo_t *cairo, cons * * ******************************************************************************/ -GtkWidget *gtk_graph_view_new(void) +GtkWidget *gtk_graph_display_new(void) { - return g_object_new(GTK_TYPE_GRAPH_VIEW, NULL); + return g_object_new(GTK_TYPE_GRAPH_DISPLAY, NULL); } /****************************************************************************** * * -* Paramètres : view = composant GTK à mettre à jour. * -* widget = composant GTK à insérer. * -* x = abscisse du point d'insertion. * -* y = ordonnée du point d'insertion. * +* Paramètres : display = composant GTK à mettre à jour. * +* widget = composant GTK à insérer. * +* x = abscisse du point d'insertion. * +* y = ordonnée du point d'insertion. * * * * Description : Place une vue sous forme de bloc dans le graphique. * * * @@ -954,34 +901,12 @@ GtkWidget *gtk_graph_view_new(void) * * ******************************************************************************/ -void gtk_graph_view_put(GtkGraphView *view, GtkWidget *widget, const GtkAllocation *alloc) +void gtk_graph_display_put(GtkGraphDisplay *display, GtkWidget *widget, const GtkAllocation *alloc) { - size_t i; /* Boucle de parcours */ - GtkWidget *parent; /* Parent en cas de réajustemt.*/ + g_signal_connect(widget, "reach-limit", G_CALLBACK(gtk_graph_display_reach_caret_limit), display); + g_signal_connect(widget, "highlight-changed", G_CALLBACK(gtk_graph_display_changed_highlights), display); - /* - for (i = 0; i < view->children_count; i++) - if (GTK_WIDGET(view->children[i]) == widget) - { - view->allocs[i] = *alloc; - break; - } - - parent = gtk_widget_get_parent(widget); - - if (parent != NULL) - { - g_object_ref(G_OBJECT(widget)); - gtk_container_remove(GTK_CONTAINER(parent), widget); - } - */ - - gtk_fixed_put(GTK_FIXED(view->support), widget, alloc->x, alloc->y); - - /* - if (parent != NULL) - g_object_unref(G_OBJECT(widget)); - */ + gtk_fixed_put(GTK_FIXED(display->support), widget, GRAPH_MARGIN + alloc->x, GRAPH_MARGIN + alloc->y); } @@ -989,8 +914,8 @@ void gtk_graph_view_put(GtkGraphView *view, GtkWidget *widget, const GtkAllocati /****************************************************************************** * * -* Paramètres : view = composant GTK à mettre à jour. * -* edge = lien entre noeuds à conserver. * +* Paramètres : display = composant GTK à mettre à jour. * +* edge = lien entre noeuds à conserver. * * * * Description : Intègre un lien entre blocs graphiques dans l'afficheur. * * * @@ -1000,19 +925,21 @@ void gtk_graph_view_put(GtkGraphView *view, GtkWidget *widget, const GtkAllocati * * ******************************************************************************/ -void gtk_graph_view_add_edge(GtkGraphView *view, GGraphEdge *edge) +void gtk_graph_display_add_edge(GtkGraphDisplay *display, GGraphEdge *edge) { - view->edges = (GGraphEdge **)realloc(view->edges, - ++view->edges_count * sizeof(GGraphEdge *)); + g_graph_edge_offset(edge, GRAPH_MARGIN, GRAPH_MARGIN); - view->edges[view->edges_count - 1] = edge; + display->edges = (GGraphEdge **)realloc(display->edges, + ++display->edges_count * sizeof(GGraphEdge *)); + + display->edges[display->edges_count - 1] = edge; } /****************************************************************************** * * -* Paramètres : view = instance GTK à réinitialiser. * +* Paramètres : display = instance GTK à réinitialiser. * * * * Description : Supprime tout contenu de l'afficheur de code en graphique. * * * @@ -1022,7 +949,7 @@ void gtk_graph_view_add_edge(GtkGraphView *view, GGraphEdge *edge) * * ******************************************************************************/ -static void gtk_graph_view_reset(GtkGraphView *view) +static void gtk_graph_display_reset(GtkGraphDisplay *display) { size_t i; /* Boucle de parcours */ @@ -1038,130 +965,44 @@ static void gtk_graph_view_reset(GtkGraphView *view) } - gtk_container_foreach(GTK_CONTAINER(view->support), (GtkCallback)detach_all_blocks, view->support); - + gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)detach_all_blocks, display->support); - if (view->cluster != NULL) - { - g_object_unref(G_OBJECT(view->cluster)); - view->cluster = NULL; - } - for (i = 0; i < view->edges_count; i++) - g_object_unref(G_OBJECT(view->edges[i])); - if (view->edges_count > 0) + if (display->routine != NULL) { - free(view->edges); - view->edges = NULL; - - view->edges_count = 0; - - } - - - /* - for (i = 0; i < view->links_count; i++) - gtk_object_destroy(GTK_OBJECT(view->links[i])); - - if (view->links_count > 0) - { - free(view->links); - view->links = NULL; - - view->links_count = 0; - + g_object_unref(G_OBJECT(display->routine)); + display->routine = NULL; } - */ - if (view->highlighted) - exit_segment_content_list(view->highlighted); + if (display->highlighted != NULL) + exit_segment_content_list(display->highlighted); - for (i = 0; i < view->children_count; i++) + if (display->cluster != NULL) { - g_signal_handlers_disconnect_by_func(view->children[i], gtk_graph_view_reach_caret_limit, view); - gtk_widget_destroy(GTK_WIDGET(view->children[i])); + g_object_unref(G_OBJECT(display->cluster)); + display->cluster = NULL; } - if (view->children_count > 0) - { - free(view->children); - view->children = NULL; - free(view->allocs); - view->allocs = NULL; - - view->children_count = 0; - - } - -} - - -/****************************************************************************** -* * -* Paramètres : view = composant d'affichage GTK à mettre à jour. * -* routine = routine à présenter via ledit composant. * -* * -* Description : Définit la liste complète des éléments du futur graphique. * -* * -* Retour : Liste d'éléments du graphique à placer. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GtkBufferView **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBinary *binary, const GBinRoutine *routine) -{ - GtkBufferView **result; /* Liste à retourner */ - GCodeBuffer *buffer; /* Tampon brut à découper */ - size_t *count; /* Nombre d'éléments créés. */ - GInstrBlock *main_block; /* Premier bloc rattaché */ - GInstrBlock **blocks; /* Liste des blocs basiques */ - size_t i; /* Boucle de parcours */ - vmpa2t first; /* Début d'un groupe de lignes */ - vmpa2t last; /* Fin d'un groupe de lignes */ - GBufferView *subview; /* Partie affichée du tampon */ - - buffer = g_loaded_binary_get_disassembled_buffer(binary); - - count = &view->children_count; + for (i = 0; i < display->edges_count; i++) + g_object_unref(G_OBJECT(display->edges[i])); - main_block = g_binary_routine_get_basic_blocks(routine); - - blocks = NULL; - *count = 0; - g_instr_block_list_all_blocks(main_block, &blocks, count); - - result = (GtkBufferView **)calloc(*count, sizeof(GtkBufferView *)); - - for (i = 0; i < *count; i++) + if (display->edges_count > 0) { - result[i] = GTK_BUFFER_VIEW(gtk_block_view_new()); - g_signal_connect(result[i], "reach-limit", G_CALLBACK(gtk_graph_view_reach_caret_limit), view); - g_signal_connect(result[i], "highlight-changed", G_CALLBACK(gtk_graph_view_changed_highlights), view); - - gtk_widget_show(GTK_WIDGET(result[i])); - gtk_display_panel_attach_binary(GTK_DISPLAY_PANEL(result[i]), binary, BVW_GRAPH); + free(display->edges); + display->edges = NULL; - gtk_display_panel_show_border(GTK_DISPLAY_PANEL(result[i]), true); - - g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(blocks[i]), &first, &last); - - subview = g_buffer_view_new(buffer, view->highlighted); - g_buffer_view_restrict(subview, &first, &last); - gtk_buffer_view_attach_buffer(result[i], subview); + display->edges_count = 0; } - return result; - } /****************************************************************************** * * -* Paramètres : node = composant d'affichage GTK impliqué dans la procédure. * -* view = support graphique de tous les noeuds. * +* Paramètres : node = composant d'affichage impliqué dans la procédure. * +* display = support graphique de tous les noeuds. * * * * Description : Notifie un changement de surbrillance au sein d'un noeud. * * * @@ -1171,27 +1012,28 @@ static GtkBufferView **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBina * * ******************************************************************************/ -static void gtk_graph_view_changed_highlights(GtkBlockView *node, GtkGraphView *view) +static void gtk_graph_display_changed_highlights(GtkBlockDisplay *node, GtkGraphDisplay *display) { - size_t i; /* Boucle de parcours */ - - for (i = 0; i < view->children_count; i++) + void refresh_highlights(GtkWidget *child, gpointer unused) { - if (view->children[i] == GTK_BUFFER_VIEW(node)) - continue; + if (!GTK_IS_BUFFER_DISPLAY(child)) + return; - gtk_widget_queue_draw(GTK_WIDGET(view->children[i])); + if (child != GTK_WIDGET(node)) + gtk_widget_queue_draw(child); } + gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)refresh_highlights, NULL); + } /****************************************************************************** * * -* Paramètres : node = composant d'affichage GTK impliqué dans la procédure. * -* dir = direction du déplacement souhaité et impossible. * -* view = support graphique de tous les noeuds. * +* Paramètres : node = composant d'affichage impliqué dans la procédure. * +* dir = direction du déplacement souhaité et impossible. * +* display = support graphique de tous les noeuds. * * * * Description : Notifie une incapacité de déplacement au sein d'un noeud. * * * @@ -1201,30 +1043,30 @@ static void gtk_graph_view_changed_highlights(GtkBlockView *node, GtkGraphView * * * ******************************************************************************/ -static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirection dir, GtkGraphView *view) +static void gtk_graph_display_reach_caret_limit(GtkBufferDisplay *node, GdkScrollDirection dir, GtkGraphDisplay *display) { - GBufferView *bview; /* Vue d'un tampon global */ + GBufferView *view; /* Vue d'un tampon global */ vmpa2t first; /* Début d'un groupe de lignes */ vmpa2t last; /* Fin d'un groupe de lignes */ const mrange_t *range; /* Couverture courante */ GArchProcessor *proc; /* Processeur pour instructions*/ - vmpa2t iaddr; /* Adresse du prochain saut */ + vmpa2t iaddr; /* Position de l'instructin */ instr_iter_t *iter; /* Boucle de parcours */ GArchInstruction *instr; /* Instruction à venir visiter */ #ifndef NDEBUG bool is_return; /* Est-ce une instruc. finale ?*/ #endif - size_t i; /* Boucle de parcours */ - bool updated; /* Besoin d'une mise à jour ? */ + GtkBufferDisplay *target; /* Bloc suivant pour le focus */ /* Détermination de l'instruction à cibler */ - bview = gtk_buffer_view_get_buffer(node); - g_buffer_view_get_restrictions(bview, &first, &last); + view = gtk_buffer_display_get_view(node); + g_buffer_view_get_restrictions(view, &first, &last); + g_object_unref(G_OBJECT(view)); - range = g_binary_routine_get_range(view->routine); + range = g_binary_routine_get_range(display->routine); - proc = g_loaded_binary_get_processor(GTK_DISPLAY_PANEL(view)->binary); + proc = g_loaded_binary_get_processor(GTK_DISPLAY_PANEL(display)->binary); init_vmpa(&iaddr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL); @@ -1302,7 +1144,7 @@ static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirec break; case GDK_SCROLL_SMOOTH: - assert(0); /* Argument jamais généré */ + assert(false); /* Argument jamais généré */ break; } @@ -1311,24 +1153,37 @@ static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirec /* Recherche du bloc parent */ - /* FIXME : valid ! */ - if (iaddr.physical == VMPA_NO_PHYSICAL && iaddr.virtual == VMPA_NO_VIRTUAL) + if (is_invalid_vmpa(&iaddr)) return; - for (i = 0; i < view->children_count; i++) + target = NULL; + + void find_target_block(GtkWidget *child, gpointer unused) { - bview = gtk_buffer_view_get_buffer(view->children[i]); - g_buffer_view_get_restrictions(bview, &first, &last); + GtkBufferDisplay *test; /* Candidat potentiel à tester */ + + if (!GTK_IS_BUFFER_DISPLAY(child)) + return; + + test = GTK_BUFFER_DISPLAY(child); + + view = gtk_buffer_display_get_view(test); + g_buffer_view_get_restrictions(view, &first, &last); + g_object_unref(G_OBJECT(view)); if (cmp_vmpa(&first, &iaddr) <= 0 && cmp_vmpa(&iaddr, &last) <= 0) { - assert(node != view->children[i]); - break; + assert(target == NULL); + assert(node != test); + target = test; + return; } } - assert(i < view->children_count || is_return); + gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)find_target_block, NULL); + + assert(target != NULL || is_return); /* Affichage du nouveau curseur */ @@ -1339,29 +1194,29 @@ static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirec * pas intégrées dans les blocs basiques associés. */ - if (i == view->children_count) + if (target == NULL) return; - gtk_widget_grab_focus(GTK_WIDGET(view->children[i])); + gtk_widget_grab_focus(GTK_WIDGET(target)); switch (dir) { + case GDK_SCROLL_UP: case GDK_SCROLL_LEFT: - updated = gtk_buffer_view_move_caret_to(view->children[i], false, NULL); + gtk_buffer_display_move_caret_to(target, false, NULL); break; - case GDK_SCROLL_UP: break; case GDK_SCROLL_RIGHT: - updated = gtk_buffer_view_move_caret_to(view->children[i], true, NULL); + case GDK_SCROLL_DOWN: + gtk_buffer_display_move_caret_to(target, true, NULL); break; - case GDK_SCROLL_DOWN: break; case GDK_SCROLL_SMOOTH: - assert(0); /* Argument jamais généré */ + assert(false); /* Argument jamais généré */ break; } diff --git a/src/gtkext/gtkgraphdisplay.h b/src/gtkext/gtkgraphdisplay.h new file mode 100644 index 0000000..8d553b7 --- /dev/null +++ b/src/gtkext/gtkgraphdisplay.h @@ -0,0 +1,64 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkgraphdisplay.h - prototypes pour l'affichage de morceaux de code sous forme graphique + * + * Copyright (C) 2009-2016 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/>. + */ + + +#ifndef _GTKEXT_GTKGRAPHDISPLAY_H +#define _GTKEXT_GTKGRAPHDISPLAY_H + + +#include <gtk/gtk.h> + + +#include "graph/edge.h" + + + +#define GTK_TYPE_GRAPH_DISPLAY (gtk_graph_display_get_type()) +#define GTK_GRAPH_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_GRAPH_DISPLAY, GtkGraphDisplay)) +#define GTK_GRAPH_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_GRAPH_DISPLAY, GtkGraphDisplayClass)) +#define GTK_IS_GRAPH_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_GRAPH_DISPLAY)) +#define GTK_IS_GRAPH_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_GRAPH_DISPLAY)) +#define GTK_GRAPH_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_GRAPH_DISPLAY, GtkGraphDisplayClass)) + + +/* Composant d'affichage sous forme graphique (instance) */ +typedef struct _GtkGraphDisplay GtkGraphDisplay; + +/* Composant d'affichage sous forme graphique (classe) */ +typedef struct _GtkGraphDisplayClass GtkGraphDisplayClass; + + +/* Détermine le type du composant d'affichage en graphique. */ +GType gtk_graph_display_get_type(void); + +/* Crée un nouveau composant pour l'affichage en graphique. */ +GtkWidget *gtk_graph_display_new(void); + +/* Place une vue sous forme de bloc dans le graphique. */ +void gtk_graph_display_put(GtkGraphDisplay *, GtkWidget *, const GtkAllocation *); + +/* Intègre un lien entre blocs graphiques dans l'afficheur. */ +void gtk_graph_display_add_edge(GtkGraphDisplay *, GGraphEdge *); + + + +#endif /* _GTKEXT_GTKGRAPHDISPLAY_H */ diff --git a/src/gtkext/gtkgraphview.h b/src/gtkext/gtkgraphview.h deleted file mode 100644 index eb3e6ad..0000000 --- a/src/gtkext/gtkgraphview.h +++ /dev/null @@ -1,64 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gtkgraphview.h - prototypes pour l'affichage de morceaux de code sous forme graphique - * - * Copyright (C) 2009-2014 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/>. - */ - - -#ifndef _GTKEXT_GTKGRAPHVIEW_H -#define _GTKEXT_GTKGRAPHVIEW_H - - -#include <gtk/gtk.h> - - -#include "graph/edge.h" - - - -#define GTK_TYPE_GRAPH_VIEW (gtk_graph_view_get_type()) -#define GTK_GRAPH_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_GRAPH_VIEW, GtkGraphView)) -#define GTK_GRAPH_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_GRAPH_VIEW, GtkGraphViewClass)) -#define GTK_IS_GRAPH_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_GRAPH_VIEW)) -#define GTK_IS_GRAPH_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_GRAPH_VIEW)) -#define GTK_GRAPH_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_GRAPH_VIEW, GtkGraphViewClass)) - - -/* Composant d'affichage sous forme graphique (instance) */ -typedef struct _GtkGraphView GtkGraphView; - -/* Composant d'affichage sous forme graphique (classe) */ -typedef struct _GtkGraphViewClass GtkGraphViewClass; - - -/* Détermine le type du composant d'affichage en graphique. */ -GType gtk_graph_view_get_type(void); - -/* Crée un nouveau composant pour l'affichage en graphique. */ -GtkWidget *gtk_graph_view_new(void); - -/* Place une vue sous forme de bloc dans le graphique. */ -void gtk_graph_view_put(GtkGraphView *, GtkWidget *, const GtkAllocation *); - -/* Intègre un lien entre blocs graphiques dans l'afficheur. */ -void gtk_graph_view_add_edge(GtkGraphView *, GGraphEdge *); - - - -#endif /* _GTKEXT_GTKGRAPHVIEW_H */ diff --git a/src/gtkext/gtksourceview.c b/src/gtkext/gtksourceview.c deleted file mode 100644 index 0d2670b..0000000 --- a/src/gtkext/gtksourceview.c +++ /dev/null @@ -1,156 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gtksourceview.c - affichage de code source - * - * Copyright (C) 2010-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 "gtksourceview.h" - - -#include "gtkbufferview-int.h" - - - -/* -------------------------- INTERACTION DIRECTE AVEC GTK -------------------------- */ - - -/* Composant d'affichage de code source (instance) */ -struct _GtkSourceView -{ - GtkBufferView parent; /* A laisser en premier */ - -}; - -/* Composant d'affichage de code source (classe) */ -struct _GtkSourceViewClass -{ - GtkBufferViewClass parent; /* A laisser en premier */ - -}; - - -/* Procède à l'initialisation de l'afficheur de code source. */ -static void gtk_source_view_class_init(GtkSourceViewClass *); - -/* Procède à l'initialisation de l'afficheur de code source. */ -static void gtk_source_view_init(GtkSourceView *); - -/* Prend acte de l'association d'un binaire chargé. */ -static void gtk_source_view_attach_binary(GtkSourceView *, GLoadedBinary *); - - - -/* ---------------------------------------------------------------------------------- */ -/* INTERACTION DIRECTE AVEC GTK */ -/* ---------------------------------------------------------------------------------- */ - - -/* Détermine le type du composant d'affichage de code source. */ -G_DEFINE_TYPE(GtkSourceView, gtk_source_view, GTK_TYPE_BUFFER_VIEW) - - -/****************************************************************************** -* * -* Paramètres : class = classe GTK à initialiser. * -* * -* Description : Procède à l'initialisation de l'afficheur de code source. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_source_view_class_init(GtkSourceViewClass *class) -{ - GtkDisplayPanelClass *panel_class; /* Classe parente */ - - panel_class = GTK_DISPLAY_PANEL_CLASS(class); - - panel_class->attach = (attach_binary_fc)gtk_source_view_attach_binary; - -} - - -/****************************************************************************** -* * -* Paramètres : view = composant GTK à initialiser. * -* * -* Description : Procède à l'initialisation de l'afficheur de code source. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_source_view_init(GtkSourceView *view) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée un nouveau composant pour l'affichage de code source. * -* * -* Retour : Composant GTK créé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *gtk_source_view_new(void) -{ - GtkSourceView *result; /* Composant à retourner */ - - result = g_object_new(GTK_TYPE_SOURCE_VIEW, NULL); - - return GTK_WIDGET(result); - -} - - -/****************************************************************************** -* * -* Paramètres : view = composant GTK à mettre à jour. * -* binary = binaire associé à intégrer. * -* * -* Description : Prend acte de l'association d'un binaire chargé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_source_view_attach_binary(GtkSourceView *view, GLoadedBinary *binary) -{ - GCodeBuffer *buffer; /* Tampon par défaut */ - - buffer = g_loaded_binary_get_decompiled_buffer(binary, -1); - - /* Si une source existe... */ - if (buffer != NULL) - gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), g_buffer_view_new(buffer, NULL)); - -} diff --git a/src/gtkext/gtksourceview.h b/src/gtkext/gtksourceview.h deleted file mode 100644 index 3e4c7c6..0000000 --- a/src/gtkext/gtksourceview.h +++ /dev/null @@ -1,56 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gtksourceview.h - prototypes pour l'affichage de code source - * - * Copyright (C) 2010-2014 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/>. - */ - - -#ifndef _GTK_SOURCEVIEW_H -#define _GTK_SOURCEVIEW_H - - -#include <glib-object.h> -#include <gtk/gtk.h> - - - -#define GTK_TYPE_SOURCE_VIEW (gtk_source_view_get_type()) -#define GTK_SOURCE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_SOURCE_VIEW, GtkSourceView)) -#define GTK_SOURCE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_SOURCE_VIEW, GtkSourceViewClass)) -#define GTK_IS_SOURCE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_SOURCE_VIEW)) -#define GTK_IS_SOURCE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_SOURCE_VIEW)) -#define GTK_SOURCE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_SOURCE_VIEW, GtkSourceViewClass)) - - -/* Composant d'affichage de code source (instance) */ -typedef struct _GtkSourceView GtkSourceView; - -/* Composant d'affichage de code source (classe) */ -typedef struct _GtkSourceViewClass GtkSourceViewClass; - - -/* Détermine le type du composant d'affichage de code source. */ -GType gtk_source_view_get_type(void); - -/* Crée un nouveau composant pour l'affichage de code source. */ -GtkWidget *gtk_source_view_new(void); - - - -#endif /* _GTK_SOURCEVIEW_H */ |