diff options
Diffstat (limited to 'src/gtkext/gtkgraphview.c')
-rw-r--r-- | src/gtkext/gtkgraphview.c | 521 |
1 files changed, 61 insertions, 460 deletions
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c index c0ea347..e1a943b 100644 --- a/src/gtkext/gtkgraphview.c +++ b/src/gtkext/gtkgraphview.c @@ -28,6 +28,7 @@ #include "gtkbufferview.h" #include "gtkviewpanel-int.h" #include "graph/layout.h" +#include "../gui/editem.h" @@ -43,6 +44,7 @@ struct _GtkGraphView vmpa_t end; /* Fin de la portion affichée */ GtkViewPanel **childs; /* Liste des sous-blocs */ + GtkAllocation *allocs; /* Emplacements prévisibles */ size_t childs_count; /* Taille de cette liste */ GtkLinkRenderer **links; /* Liste des liens graphiques */ @@ -83,6 +85,9 @@ static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *, vmpa_t, /* Réagit à un défilement quelconque. */ static void gtk_graph_view_scroll(GtkGraphView *); +/* Place en cache un rendu destiné à l'aperçu graphique rapide. */ +static void gtk_graph_view_cache_glance(GtkGraphView *, cairo_t *); + /* Supprime tout contenu de l'afficheur de code en graphique. */ static void gtk_graph_view_reset(GtkGraphView *); @@ -142,6 +147,7 @@ static void gtk_graph_view_init(GtkGraphView *view) viewpanel->define = (define_address_fc)gtk_graph_view_define_main_address; viewpanel->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates; viewpanel->scroll = (scroll_fc)gtk_graph_view_scroll; + viewpanel->cache_glance = (cache_glance_fc)gtk_graph_view_cache_glance; //binview = GTK_BIN_VIEW(view); @@ -335,6 +341,9 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr) view->childs = gtk_graph_view_load_nodes(view, GTK_VIEW_PANEL(view)->binary, start, end); + view->allocs = (GtkAllocation *)calloc(view->childs_count, + sizeof(GtkAllocation)); + build_graph_view(view, view->childs, view->childs_count); break; @@ -343,6 +352,8 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr) } + change_editor_items_current_view_content(GTK_VIEW_PANEL(view)); + } } @@ -396,9 +407,10 @@ static void gtk_graph_view_scroll(GtkGraphView *view) /****************************************************************************** * * -* Paramètres : - * +* Paramètres : view = composant GTK à manipuler. * +* cairo = assistant pour la création de rendus. * * * -* Description : Crée un nouveau composant pour l'affichage en graphique. * +* Description : Place en cache un rendu destiné à l'aperçu graphique rapide. * * * * Retour : - * * * @@ -406,17 +418,48 @@ static void gtk_graph_view_scroll(GtkGraphView *view) * * ******************************************************************************/ -GtkWidget *gtk_graph_view_new(void) +static void gtk_graph_view_cache_glance(GtkGraphView *view, cairo_t *cairo) { - return g_object_new(GTK_TYPE_GRAPH_VIEW, NULL); + size_t i; /* Boucle de parcours */ + GtkAllocation *alloc; /* Emplacement d'un bloc */ -} + cairo_set_line_width(cairo, 2); + cairo_set_source_rgb(cairo, 0, 0, 0); + + for (i = 0; i < view->childs_count; i++) + { + alloc = &view->allocs[i]; + cairo_rectangle(cairo, alloc->x, alloc->y, + alloc->width, alloc->height); + cairo_stroke(cairo); + + } + + for (i = 0; i < view->links_count; i++) + _gtk_link_renderer_draw(view->links[i], cairo, false); + +} +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouveau composant pour l'affichage en graphique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +GtkWidget *gtk_graph_view_new(void) +{ + return g_object_new(GTK_TYPE_GRAPH_VIEW, NULL); +} /****************************************************************************** @@ -435,9 +478,18 @@ GtkWidget *gtk_graph_view_new(void) * * ******************************************************************************/ -void gtk_graph_view_put(GtkGraphView *view, GtkWidget *widget, gint x, gint y) +void gtk_graph_view_put(GtkGraphView *view, GtkWidget *widget, const GtkAllocation *alloc) { - gtk_fixed_put(view->support, widget, x, y); + size_t i; /* Boucle de parcours */ + + for (i = 0; i < view->childs_count; i++) + if (GTK_WIDGET(view->childs[i]) == widget) + { + view->allocs[i] = *alloc; + break; + } + + gtk_fixed_put(view->support, widget, alloc->x, alloc->y); } @@ -505,6 +557,8 @@ static void gtk_graph_view_reset(GtkGraphView *view) { free(view->childs); view->childs = NULL; + free(view->allocs); + view->allocs = NULL; view->childs_count = 0; @@ -513,11 +567,6 @@ static void gtk_graph_view_reset(GtkGraphView *view) } - - - - - /****************************************************************************** * * * Paramètres : view = composant d'affichage GTK à mettre à jour. * @@ -627,451 +676,3 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBinar return result; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if 0 - -#include "gtkbinview-int.h" -#include "gtkblockview.h" -#include "../format/format.h" -#include "../graph/layout.h" - - -#include <malloc.h> - - - -/* Représentation de code binaire sous forme graphique (instace) */ -struct _GtkGraphView -{ - GtkBinView parent; /* A laisser en premier */ - GtkFixed *support; /* Support des vues en bloc */ - - GtkRequisition requisition; /* Espace requis d'affichage */ - - vmpa_t start; /* Début de la portion vue */ - vmpa_t end; /* Fin de la portion affichée */ - - GtkBinView **childs; /* Liste des sous-blocs */ - size_t childs_count; /* Taille de cette liste */ - - size_t ready; /* Construction complète */ - GMutex *mutex; /* Accès à la variable */ - GCond *cond; /* Attente de changement */ - - GtkLinkRenderer **links; /* Liste des liens graphiques */ - size_t links_count; /* Nombre de ces liens */ - -}; - -/* Représentation de code binaire sous forme graphique (classe) */ -struct _GtkGraphViewClass -{ - GtkBinViewClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe générique des graphiques de code. */ -static void gtk_graph_view_class_init(GtkGraphViewClass *); - -/* Initialise une instance d'afficheur de code en graphique. */ -static void gtk_graph_view_init(GtkGraphView *); - -/* Définit les lignes du graphique de représentation. */ -static void gtk_graph_view_set_rendering_lines(GtkGraphView *, GRenderingLine *, GRenderingLine *); - -/* Réagit à la sélection externe d'une adresse. */ -static void gtk_graph_view_define_main_address(GtkGraphView *, vmpa_t); - -/* Indique la position d'affichage d'une adresse donnée. */ -static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *, vmpa_t, gint *, gint *); - -/* Définit la liste complète des éléments du futur graphique. */ -static GtkBinView **gtk_graph_view_load_nodes(GtkGraphView *, GLoadedBinary *, GRenderingLine *, GRenderingLine *); - -/* Prend note de la fin d'une construction d'une visualisation. */ -static void notify_graph_view(GtkBinView *, GtkGraphView *); - - -/* Détermine le type du composant d'affichage en graphique. */ -G_DEFINE_TYPE(GtkGraphView, gtk_graph_view, GTK_TYPE_BIN_VIEW) - - -/****************************************************************************** -* * -* Paramètres : klass = classe GTK à initialiser. * -* * -* Description : Initialise la classe générique des graphiques de code. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_graph_view_class_init(GtkGraphViewClass *klass) -{ - GtkWidgetClass *widget_class; /* Classe version Widget */ - - widget_class = (GtkWidgetClass *)klass; - - widget_class->size_request = gtk_graph_view_size_request; - widget_class->size_allocate = gtk_graph_view_size_allocate; - -} - - -/****************************************************************************** -* * -* Paramètres : view = instance GTK à initialiser. * -* * -* Description : Initialise une instance d'afficheur de code en graphique. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_graph_view_init(GtkGraphView *view) -{ - GtkViewPanel *viewpanel; /* Instance parente #1 */ - GtkBinView *binview; /* Instance parente #2 */ - GdkColor white; /* Couleur de fond normale */ - - viewpanel = GTK_VIEW_PANEL(view); - - viewpanel->scroll = (scroll_fc)gtk_graph_view_scroll; - - 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(gtk_fixed_new()); - gtk_fixed_set_has_window(view->support, TRUE); - - g_signal_connect(G_OBJECT(view->support), "expose-event", - G_CALLBACK(gtk_graph_view_expose), view); - - gtk_widget_show(GTK_WIDGET(view->support)); - - gdk_color_white(gtk_widget_get_colormap(GTK_WIDGET(view->support)), &white); - gtk_widget_modify_bg(GTK_WIDGET(view->support), GTK_STATE_NORMAL, &white); - - gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->support), 0, 0); - - view->mutex = g_mutex_new(); - view->cond = g_cond_new(); - -} - - - - - - - - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : view = composant GTK à mettre à jour. * -* lines = informations à intégrer. * -* last = dernière ligne à intégrer ou NULL pour toutes. * -* * -* Description : Définit les lignes du graphique de représentation. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLine *lines, GRenderingLine *last) -{ - gtk_graph_view_reset(view); - - g_signal_emit_by_name(view, "lines-set"); - -} - - - - - - - - -/****************************************************************************** -* * -* Paramètres : view = composant GTK à mettre à jour. * -* addr = adresse sélectionnée de manière externe. * -* * -* Description : Réagit à la sélection externe d'une adresse. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr) -{ - GExeFormat *format; /* Type de fichier chargé */ - GBinRoutine **routines; /* Liste des routines trouvées */ - size_t routines_count; /* Nombre de ces routines */ - size_t i; /* Boucle de parcours */ - vmpa_t start; /* Début d'une routine */ - vmpa_t end; /* Fin d'une routine */ - GRenderingLine *first; /* Première ligne à traiter */ - GRenderingLine *last; /* Dernière ligne à traiter */ - - if (!(view->start <= addr && addr < view->end)) - { - gtk_graph_view_reset(view); - - format = g_loaded_binary_get_format(GTK_BIN_VIEW(view)->binary); - routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count); - - for (i = 0; i < routines_count; i++) - { - start = g_binary_routine_get_address(routines[i]); - end = start + g_binary_routine_get_size(routines[i]); - - if (start <= addr && addr < end) - { - view->start = start; - view->end = end; - - first = g_rendering_line_find_by_address(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, start); - last = g_rendering_line_find_by_address(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, end - 1); - - view->childs = gtk_graph_view_load_nodes(view, GTK_BIN_VIEW(view)->binary, first, last); - - build_graph_view(view, view->childs, view->childs_count); - - break; - - } - - } - - } - -} - - -/****************************************************************************** -* * -* 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] * -* * -* Description : Indique la position d'affichage d'une adresse donnée. * -* * -* Retour : TRUE si l'adresse fait partie du composant, FALSE sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, vmpa_t addr, gint *x, gint *y) -{ - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - - result = false; - - *x = 0; - *y = 0; - - for (i = 0; i < view->childs_count && !result; i++) - if (view->childs[i]->get_coordinates(view->childs[i], addr, x, y)) - { - *x += GTK_WIDGET(view->childs[i])->allocation.x; - *y += GTK_WIDGET(view->childs[i])->allocation.y; - result = true; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : view = composant d'affichage GTK à mettre à jour. * -* binary = contenu binaire à l'origine des lignes. * -* first = première ligne à analyser. * -* last = dernière ligne à analyser. * -* * -* Description : Définit la liste complète des éléments du futur graphique. * -* * -* Retour : Liste d'éléments du graphique à placer. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GtkBinView **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBinary *binary, GRenderingLine *first, GRenderingLine *last) -{ -#if 0 - GtkBinView **result; /* Liste à retourner */ - size_t *count; /* Nombre d'éléments créés. */ - GRenderingLine *begin; /* Début d'un groupe de lignes */ - GRenderingLine *end; /* Fin d'un groupe de lignes */ - GRenderingLine *iter; /* Boucle de parcours */ - - result = NULL; - - view->ready = 0; - - count = &view->childs_count; - *count = 0; - - /** - * Comme la fonction est appelée depuis un événement et utilise des threads et GTK, - * on doit lever temporairement le verrou GDK. - */ - gdk_flush (); - gdk_threads_leave(); - - begin = NULL; - - for (iter = first; iter != NULL; iter = g_rendering_line_get_next_iter(first, iter, last)) - { - if (begin != NULL && g_rendering_line_has_sources(iter)) - { - result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *)); - - result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new(MRD_GRAPH)); - - g_signal_connect(result[*count - 1], "lines-set", G_CALLBACK(notify_graph_view), view); - - gtk_bin_view_show_border(result[*count - 1], true); - gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end); - - begin = NULL; - - } - - if (begin == NULL) begin = iter; - end = iter; - - if (g_rendering_line_has_destinations(iter)) - { - result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *)); - - result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new(MRD_GRAPH)); - - g_signal_connect(result[*count - 1], "lines-set", G_CALLBACK(notify_graph_view), view); - - gtk_bin_view_show_border(result[*count - 1], true); - gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end); - - begin = NULL; - - } - - } - - if (begin != NULL) - { - result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *)); - - result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new(MRD_GRAPH)); - - g_signal_connect(result[*count - 1], "lines-set", G_CALLBACK(notify_graph_view), view); - - gtk_bin_view_show_border(result[*count - 1], true); - gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end); - - } - - /* Attente de la fin de construction */ - g_mutex_lock(view->mutex); - while (view->ready < *count) - g_cond_wait(view->cond, view->mutex); - g_mutex_unlock(view->mutex); - - gdk_threads_enter(); - - return result; -#endif - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : view = composant d'affichage prêt à utilisation. * -* parent = composant d'affichage supérieur. * -* * -* Description : Prend note de la fin d'une construction d'une visualisation. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void notify_graph_view(GtkBinView *view, GtkGraphView *parent) -{ - g_mutex_lock(parent->mutex); - - parent->ready++; - - g_cond_signal(parent->cond); - g_mutex_unlock(parent->mutex); - - g_signal_handlers_disconnect_by_func(view, G_CALLBACK(notify_graph_view), parent); - - gtk_widget_show(GTK_WIDGET(view)); - -} - - - -#endif |