From ecb9ecc486049fe3bec6ecaeeb27f08f67bf0ef0 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 13 Jun 2009 14:05:50 +0000 Subject: Made the GUI offer to change the view of the current analyzed binary. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@73 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 40 +++ src/editor.c | 133 +++++--- src/gtkext/Makefile.am | 4 +- src/gtkext/easygtk.c | 34 ++ src/gtkext/easygtk.h | 3 + src/gtkext/gtkbinview-int.h | 49 +++ src/gtkext/gtkbinview.c | 30 +- src/gtkext/gtkbinview.h | 3 + src/gtkext/gtkblockview.c | 785 ++++++++++++++++++++++++++++++++++++++++++++ src/gtkext/gtkblockview.h | 99 ++++++ src/gtkext/gtkdockpanel.c | 51 ++- src/gtkext/gtkdockpanel.h | 6 + src/gtkext/gtkgraphview.c | 110 +++++++ src/gtkext/gtkgraphview.h | 56 ++++ src/gtkext/gtksnippet.c | 755 ------------------------------------------ src/gtkext/gtksnippet.h | 117 ------- src/project.c | 156 ++++++++- src/project.h | 18 + 18 files changed, 1493 insertions(+), 956 deletions(-) create mode 100644 src/gtkext/gtkbinview-int.h create mode 100644 src/gtkext/gtkblockview.c create mode 100644 src/gtkext/gtkblockview.h create mode 100644 src/gtkext/gtkgraphview.c create mode 100644 src/gtkext/gtkgraphview.h delete mode 100644 src/gtkext/gtksnippet.c delete mode 100644 src/gtkext/gtksnippet.h diff --git a/ChangeLog b/ChangeLog index d13bebf..e978740 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +09-06-13 Cyrille Bagard + + * src/editor.c: + Make the GUI offer to change the view of the current analyzed binary. + + * src/gtkext/easygtk.c: + * src/gtkext/easygtk.h: + Add a function to create a scrolled window. + + * src/gtkext/gtkbinview.c: + * src/gtkext/gtkbinview.h: + Reorganize the way the binary content is displayed. + + * src/gtkext/gtkbinview-int.h: + New entrie: reorganize the way the binary content is displayed. + + * src/gtkext/gtkblockview.c: + * src/gtkext/gtkblockview.h: + Renamed entries: reorganize the way the binary content is displayed. + + * src/gtkext/gtkdockpanel.c: + * src/gtkext/gtkdockpanel.h: + Allow to look for a dock item with its name and to replace its content. + + * src/gtkext/gtkgraphview.c: + * src/gtkext/gtkgraphview.h: + New entries: reorganize the way the binary content is displayed. + + * src/gtkext/gtksnippet.c: + * src/gtkext/gtksnippet.h: + Deleted entries ; see gtkblockview.[ch]. + + * src/gtkext/Makefile.am: + Add gtkbinview-int.h, gtkgraphview.[ch] and replace gtksnippet.[ch] by + gtkblockview.[ch] in libgtkext_la_SOURCES. + + * src/project.c: + * src/project.h: + Keep track of all displaying supports for loaded binaries. + 09-06-08 Cyrille Bagard * src/analysis/binary.c: diff --git a/src/editor.c b/src/editor.c index 7185e3f..8c28e68 100644 --- a/src/editor.c +++ b/src/editor.c @@ -47,7 +47,6 @@ #include "gtkext/easygtk.h" #include "gtkext/gtkbinview.h" #include "gtkext/gtkdockpanel.h" -#include "gtkext/gtksnippet.h" #include "format/exe_format.h" #include "format/mangling/demangler.h" #include "plugins/pglist.h" @@ -87,12 +86,8 @@ void mcb_file_save_project_as(GtkMenuItem *, gpointer); /* Charge un projet récent et met à jour la liste. */ void mcb_open_recent_project(GtkMenuItem *, gpointer); - -/* Réagit avec le menu "Affichage -> Vue textuelle". */ -void mcb_view_as_text(GtkCheckMenuItem *, gpointer); - -/* Réagit avec le menu "Affichage -> Vue graphique". */ -void mcb_view_as_graph(GtkCheckMenuItem *, gpointer); +/* Réagit avec le menu "Affichage -> Vue xxx". */ +void mcb_view_change_support(GtkRadioMenuItem *, GObject *); /* Réagit avec le menu "Affichage -> Adresse virtuelle". */ void mcb_view_vaddress(GtkCheckMenuItem *, gpointer); @@ -136,6 +131,10 @@ void update_debug_menu_items(GObject *, gboolean); + + + + void open_last_file(GObject *ref); @@ -248,7 +247,7 @@ GtkWidget *create_editor(void) GtkWidget *snippet; GtkWidget *statusbar1; - GtkWidget *binview; + GtkWidget *view; GtkWidget *panel; @@ -324,12 +323,14 @@ GtkWidget *create_editor(void) menubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menubar); - submenuitem = qck_create_radio_menu_item(NULL, NULL, NULL, _("Text view"), G_CALLBACK(mcb_view_as_text), result); + submenuitem = qck_create_radio_menu_item(NULL, NULL, NULL, _("Text view"), G_CALLBACK(mcb_view_change_support), result); + g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(BVW_BLOCK)); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); rgroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(submenuitem)); - submenuitem = qck_create_radio_menu_item(NULL, NULL, rgroup, _("Graph view"), G_CALLBACK(mcb_view_as_graph), result); + submenuitem = qck_create_radio_menu_item(NULL, NULL, rgroup, _("Graph view"), G_CALLBACK(mcb_view_change_support), result); + g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(BVW_GRAPH)); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_separator(); @@ -443,10 +444,12 @@ GtkWidget *create_editor(void) dpanel = gtk_dock_panel_new(); + g_object_set_data(G_OBJECT(result), "binpanel", dpanel); gtk_widget_show(dpanel); gtk_paned_pack1(GTK_PANED(hpaned1), dpanel, TRUE, TRUE); +#if 0 scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); @@ -458,16 +461,18 @@ GtkWidget *create_editor(void) gtk_dock_panel_add_item(dpanel, ditem); - binview = gtk_binview_new(); - g_object_set_data(G_OBJECT(result), "binview", binview); + view = gtk_graph_view_new(); + g_object_set_data(G_OBJECT(result), "grahview", view); //gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolledwindow2), binview); //gtk_container_add(GTK_CONTAINER(scrolledwindow2), binview); + view = gtk_binview_new(); + g_object_set_data(G_OBJECT(result), "binview", view); snippet = gtk_snippet_new(); g_object_set_data(G_OBJECT(result), "snippet", snippet); - gtk_widget_show(binview); + gtk_widget_show(view); /* snippet = gtk_text_view_new (); */ @@ -475,20 +480,20 @@ GtkWidget *create_editor(void) /*gtk_container_add (GTK_CONTAINER (scrolledwindow2), snippet);*/ //gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolledwindow2), snippet); - gtk_container_add(GTK_CONTAINER(binview), snippet); + gtk_container_add(GTK_CONTAINER(view), snippet); //binview = gtk_fixed_new(); - gtk_widget_show(binview); + gtk_widget_show(view); //g_object_set_data(G_OBJECT(result), "binview", binview); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolledwindow2), binview); + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolledwindow2), view); //gtk_container_add(GTK_CONTAINER(scrolledwindow2), binview); - +#endif @@ -712,14 +717,12 @@ void mcb_open_recent_project(GtkMenuItem *menuitem, gpointer data) } - - /****************************************************************************** * * * Paramètres : menuitem = élément de menu ayant basculé. * -* data = adresse de l'espace de référencement global. * +* ref = adresse de l'espace de référencement global. * * * -* Description : Réagit avec le menu "Affichage -> Vue textuelle". * +* Description : Réagit avec le menu "Affichage -> Vue xxx". * * * * Retour : - * * * @@ -727,39 +730,36 @@ void mcb_open_recent_project(GtkMenuItem *menuitem, gpointer data) * * ******************************************************************************/ -void mcb_view_as_text(GtkCheckMenuItem *menuitem, gpointer data) +void mcb_view_change_support(GtkRadioMenuItem *menuitem, GObject *ref) { - gboolean active; /* Etat de sélection du menu */ - - active = gtk_check_menu_item_get_active(menuitem); - - printf("View as text ? %d\n", active); + GSList *group; /* Liste de menus radio */ + GSList *iter; /* Boucle de parcours */ + BinaryView view; /* Nouvelle vue à présenter */ + openida_binary *binary; /* Edition courante */ + GtkWidget *panel; /* Nouveau support à utiliser */ + GtkDockPanel *dpanel; /* Support de panneaux */ + GtkDockItem *ditem; /* Panneau avec ses infos. */ + /* On ne traite qu'une seule fois ! */ + if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return; -} + group = gtk_radio_menu_item_get_group(menuitem); + for (iter = group; iter != NULL; iter = g_slist_next(iter)) + { + if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(iter->data))) continue; -/****************************************************************************** -* * -* Paramètres : menuitem = élément de menu ayant basculé. * -* data = adresse de l'espace de référencement global. * -* * -* Description : Réagit avec le menu "Affichage -> Vue graphique". * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + view = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(iter->data), "kind_of_view")); -void mcb_view_as_graph(GtkCheckMenuItem *menuitem, gpointer data) -{ - gboolean active; /* Etat de sélection du menu */ + binary = (openida_binary *)g_object_get_data(ref, "current_binary"); + panel = get_view_for_openida_project_binary(get_current_openida_project(), binary, view); - active = gtk_check_menu_item_get_active(menuitem); + dpanel = GTK_DOCK_PANEL(g_object_get_data(ref, "binpanel")); + ditem = gtk_dock_panel_item_from_name(dpanel, openida_binary_to_string(binary)); - printf("View as graph ? %d\n", active); + gtk_dock_panel_replace_item_content(dpanel, ditem, panel); + } } @@ -936,6 +936,7 @@ void mcb_select_sections(GtkMenuItem *menuitem, gpointer data) void reload_menu_project(GObject *ref) { +#if 0 GtkWidget *menuitem; /* Menu principal à compléter */ GtkWidget *menubar; /* Support pour éléments */ GList *list; /* Liste des éléments en place */ @@ -973,7 +974,7 @@ void reload_menu_project(GObject *ref) } gtk_widget_set_sensitive(menuitem, count > 0); - +#endif } @@ -1206,12 +1207,50 @@ void update_debug_menu_items(GObject *ref, gboolean stopped) void open_last_file(GObject *ref) { + + GtkWidget *scrolledwindow; + + + GtkWidget *snippet; + + + + GtkDockPanel *dpanel; /* Support de panneaux */ + GtkDockItem *ditem; /* Panneau avec ses infos. */ + openida_binary *binary; + openida_project *project; + + GtkWidget *view; /* Affichage du code binaire */ + + binary = load_binary_file("/tmp/hello"); - gtk_snippet_set_rendering_lines(GTK_SNIPPET(g_object_get_data(ref, "snippet")), get_openida_binary_lines(binary)); + + if (binary == NULL) + { + /* TODO : log ... */ + return; + } + + + project = get_current_openida_project(); + + attach_binary_to_openida_project(project, binary); + + view = get_view_for_openida_project_binary(project, binary, BVW_BLOCK); + + + + + dpanel = GTK_DOCK_PANEL(g_object_get_data(ref, "binpanel")); + + ditem = gtk_dock_item_new(openida_binary_to_string(binary), view); + gtk_dock_panel_add_item(dpanel, ditem); + + g_object_set_data(ref, "current_binary", binary); diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index 021a061..421a1c4 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -5,11 +5,13 @@ noinst_LTLIBRARIES = libgtkext.la libgtkext_la_SOURCES = \ easygtk.h easygtk.c \ + gtkbinview-int.h \ gtkbinview.h gtkbinview.c \ + gtkblockview.h gtkblockview.c \ gtkdockitem.h gtkdockitem.c \ gtkdockpanel.h gtkdockpanel.c \ gtkdropwindow.h gtkdropwindow.c \ - gtksnippet.h gtksnippet.c \ + gtkgraphview.h gtkgraphview.c \ iodamarshal.h iodamarshal.c \ support.h support.c diff --git a/src/gtkext/easygtk.c b/src/gtkext/easygtk.c index f596404..253b4bc 100644 --- a/src/gtkext/easygtk.c +++ b/src/gtkext/easygtk.c @@ -127,6 +127,40 @@ GtkWidget *qck_create_notebook(GObject *object, const char *name) /****************************************************************************** * * +* Paramètres : object = espace dédié à l'inscription de références. * +* name = nom à donner au nouveau composant. * +* * +* Description : Met en place un support avec défilement automatique. * +* * +* Retour : Composant 'GtkWidget' ici créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *qck_create_scrolled_window(GObject *object, const char *name) +{ + GtkWidget *result; /* Instance à renvoyer */ + + result = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(result), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + if (G_IS_OBJECT(object) && name != NULL) + { + gtk_widget_ref(result); + g_object_set_data_full(object, name, result, (GtkDestroyNotify)g_object_unref); + } + + gtk_widget_show(result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : object = espace dédié à l'inscription de références. * * name = nom à donner au nouveau composant. * * filename = chemin d'accès complet au fichier à afficher. * diff --git a/src/gtkext/easygtk.h b/src/gtkext/easygtk.h index 41b24e0..d1d7fbf 100644 --- a/src/gtkext/easygtk.h +++ b/src/gtkext/easygtk.h @@ -38,6 +38,9 @@ GtkWidget *qck_create_frame(const char *, GtkWidget **, guint, guint, guint, gui /* Met en place un support à onglets. */ GtkWidget *qck_create_notebook(GObject *, const char *); +/* Met en place un support avec défilement automatique. */ +GtkWidget *qck_create_scrolled_window(GObject *, const char *); + /* Crée un composant 'GtkImage'. */ GtkWidget *qck_create_image(GObject *, const char *, gchar *); diff --git a/src/gtkext/gtkbinview-int.h b/src/gtkext/gtkbinview-int.h new file mode 100644 index 0000000..33ba33c --- /dev/null +++ b/src/gtkext/gtkbinview-int.h @@ -0,0 +1,49 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtkbinview-int.h - définitions internes propre à l'affichage d'un ou plusieurs morceaux de code + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _GTKEXT_GTKBINVIEW_INT_H +#define _GTKEXT_GTKBINVIEW_INT_H + + +#include "gtkbinview.h" + + +#include + + + +struct _GtkBinview +{ + GtkFixed parent; /* A laisser en premier */ + +}; + +struct _GtkBinviewClass +{ + GtkFixedClass parent; /* A laisser en premier */ + +}; + + + +#endif /* _GTKEXT_GTKBINVIEW_INT_H */ diff --git a/src/gtkext/gtkbinview.c b/src/gtkext/gtkbinview.c index 5ed6388..9ffb5f6 100644 --- a/src/gtkext/gtkbinview.c +++ b/src/gtkext/gtkbinview.c @@ -24,29 +24,19 @@ #include "gtkbinview.h" -#include "gtksnippet.h" +#include "gtkbinview-int.h" -struct _GtkBinview -{ - GtkViewport viewport; - -}; - -struct _GtkBinviewClass -{ - GtkViewportClass parent_class; -}; /* Détermine le type du composant d'affichage des morceaux. */ -G_DEFINE_TYPE(GtkBinview, gtk_binview, GTK_TYPE_VIEWPORT) +G_DEFINE_TYPE(GtkBinview, gtk_binview, GTK_TYPE_FIXED) @@ -68,17 +58,15 @@ G_DEFINE_TYPE(GtkBinview, gtk_binview, GTK_TYPE_VIEWPORT) static void gtk_binview_class_init(GtkBinviewClass *class) { GtkWidgetClass *widget_class; /* Classe de haut niveau */ - GtkViewportClass *viewport_class; /* Classe du niveau supérieur */ widget_class = GTK_WIDGET_CLASS(class); - viewport_class = GTK_VIEWPORT_CLASS(class); } /****************************************************************************** * * -* Paramètres : binview = composant GTK à initialiser. * +* Paramètres : view = composant GTK à initialiser. * * * * Description : Procède à l'initialisation de l'afficheur de morceaux. * * * @@ -88,10 +76,9 @@ static void gtk_binview_class_init(GtkBinviewClass *class) * * ******************************************************************************/ -static void gtk_binview_init(GtkBinview *binview) +static void gtk_binview_init(GtkBinview *view) { - - + gtk_fixed_set_has_window(GTK_FIXED(view), TRUE); } @@ -140,7 +127,7 @@ void gtk_binview_show_vaddress(GtkBinview *binview, gboolean show) list = gtk_container_get_children(GTK_CONTAINER(binview)); for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) - gtk_snippet_show_vaddress(GTK_SNIPPET(iter->data), show); + /*gtk_snippet_show_vaddress(GTK_SNIPPET(iter->data), show)*/; g_list_free(list); @@ -168,7 +155,7 @@ void gtk_binview_show_code(GtkBinview *binview, gboolean show) list = gtk_container_get_children(GTK_CONTAINER(binview)); for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) - gtk_snippet_show_code(GTK_SNIPPET(iter->data), show); + /*gtk_snippet_show_code(GTK_SNIPPET(iter->data), show)*/; g_list_free(list); @@ -195,6 +182,7 @@ void gtk_binview_show_code(GtkBinview *binview, gboolean show) void gtk_binview_scroll_to_address(GtkBinview *binview, uint64_t address) { +#if 0 GList *list; /* Ensemble des enfants */ GList *iter; /* Boucle de parcours */ GtkSnippet *snippet; /* Morceau de code présent */ @@ -220,7 +208,7 @@ void gtk_binview_scroll_to_address(GtkBinview *binview, uint64_t address) } g_list_free(list); - +#endif } diff --git a/src/gtkext/gtkbinview.h b/src/gtkext/gtkbinview.h index 4fafad1..722d10d 100644 --- a/src/gtkext/gtkbinview.h +++ b/src/gtkext/gtkbinview.h @@ -43,6 +43,9 @@ typedef struct _GtkBinview GtkBinview; typedef struct _GtkBinviewClass GtkBinviewClass; +typedef struct _GtkBinview GtkBinView; +typedef struct _GtkBinviewClass GtkBinViewClass; + /* Détermine le type du composant d'affichage des morceaux. */ diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockview.c new file mode 100644 index 0000000..b125c7b --- /dev/null +++ b/src/gtkext/gtkblockview.c @@ -0,0 +1,785 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtkblockview.c - affichage d'un fragment de code d'assemblage + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "gtkblockview.h" + + +#include +#include + + +#include "gtkbinview-int.h" +#include "../common/dllist.h" + + + +#define CONTENT_BUFFER_LEN 64 + +#define MARGIN_SPACE 4 + + + +struct _GtkBlockView +{ + GtkBinView parent; /* A laisser en premier */ + + bool show_vaddress; /* Affichage des adresses ? */ + bool show_code; /* Affichage du code brut ? */ + + PangoLayout *layout; /* Moteur de rendu du code ASM */ + GdkGC *gc; /* Contexte graphique du rendu */ + int line_height; /* Hauteur maximale des lignes */ + + const exe_format *format; /* Format du contenu bianire */ + + GRenderingLine *lines; /* Contenu à représenter */ + +}; + +struct _GtkBlockViewClass +{ + GtkBinViewClass parent; /* A laisser en premier */ + +}; + + + + + + + + +/* Redessine l'affichage suite une mise à jour dans la marge. */ +void gtk_block_view_update_margin(GRenderingLine *, GtkBlockView *); + + + + + +/* Réclame une nouvelle taille adaptée au contenu présent. */ +void gtk_block_view_recompute_size_request(GtkBlockView *); + + + + + + + + +static void gtk_block_view_class_init(GtkBlockViewClass *klass); +static void gtk_block_view_init(GtkBlockView *cpu); +static void gtk_block_view_size_request(GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_block_view_size_allocate(GtkWidget *widget, + GtkAllocation *allocation); +static void gtk_block_view_realize(GtkWidget *widget); + + +static gboolean gtk_block_view_button_press(GtkWidget *, GdkEventButton *event); + +static gboolean gtk_block_view_expose(GtkWidget *widget, + GdkEventExpose *event); +static void gtk_block_view_paint(GtkBlockView *view); +static void gtk_block_view_destroy(GtkObject *object); + + + +G_DEFINE_TYPE(GtkBlockView, gtk_block_view, GTK_TYPE_BIN_VIEW) + + + + +GtkWidget * gtk_block_view_new(void) +{ + GtkBlockView *result; + + result = gtk_type_new(gtk_block_view_get_type()); + + return GTK_WIDGET(result); + +} + + +static void +gtk_block_view_class_init(GtkBlockViewClass *klass) +{ + GtkWidgetClass *widget_class; + GtkObjectClass *object_class; + + + widget_class = (GtkWidgetClass *) klass; + object_class = (GtkObjectClass *) klass; + + + widget_class->button_press_event = gtk_block_view_button_press; + widget_class->realize = gtk_block_view_realize; + widget_class->size_request = gtk_block_view_size_request; + widget_class->size_allocate = gtk_block_view_size_allocate; + widget_class->expose_event = gtk_block_view_expose; + + object_class->destroy = gtk_block_view_destroy; +} + + +static void +gtk_block_view_init(GtkBlockView *view) +{ + +} + + +static void +gtk_block_view_size_request(GtkWidget *widget, + GtkRequisition *requisition) +{ + g_return_if_fail(widget != NULL); + g_return_if_fail(GTK_IS_BLOCK_VIEW(widget)); + g_return_if_fail(requisition != NULL); + + requisition->width = 80; + requisition->height = 100; +} + + +static void +gtk_block_view_size_allocate(GtkWidget *widget, + GtkAllocation *allocation) +{ + g_return_if_fail(widget != NULL); + g_return_if_fail(GTK_IS_BLOCK_VIEW(widget)); + g_return_if_fail(allocation != NULL); + + widget->allocation = *allocation; + + if (GTK_WIDGET_REALIZED(widget)) { + gdk_window_move_resize( + widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height + ); + } +} + + +static void +gtk_block_view_realize(GtkWidget *widget) +{ + GdkWindowAttr attributes; + guint attributes_mask; + GdkColor white; /* Couleur de fond normale */ + + g_return_if_fail(widget != NULL); + g_return_if_fail(GTK_IS_BLOCK_VIEW(widget)); + + GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.event_mask = gtk_widget_get_events(widget) | GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y; + + widget->window = gdk_window_new( + gtk_widget_get_parent_window (widget), + & attributes, attributes_mask + ); + + gdk_window_set_user_data(widget->window, widget); + + widget->style = gtk_style_attach(widget->style, widget->window); + + + gdk_color_white(gtk_widget_get_colormap(widget), &white); + gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &white); + + + GTK_BLOCK_VIEW(widget)->layout = gtk_widget_create_pango_layout(widget, NULL); + GTK_BLOCK_VIEW(widget)->gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); + + gtk_block_view_build_content(GTK_BLOCK_VIEW(widget)); + +} + + +static gboolean gtk_block_view_button_press(GtkWidget *widget, GdkEventButton *event) +{ + gboolean result; /* Décision à retourner */ + GtkBlockView *view; /* Composant GTK réel */ + gdouble y; /* Position à manipuler */ + GRenderingLine *line; /* Ligne de rendu visée */ + + result = FALSE; + + view = GTK_BLOCK_VIEW(widget); + + y = event->y; + line = g_rendering_line_find_by_y(view->lines, &y); + + if (line != NULL) + { + /* Clic dans la marge */ + if (event->type == GDK_BUTTON_PRESS && event->x < (2 * MARGIN_SPACE + view->line_height)) + { + result = TRUE; + g_rendering_line_toggle_flag(line, RLF_BREAK_POINT); + } + + } + + if (result) + { + /* TODO: regions */ + gtk_block_view_paint(view); + } + + return result; + +} + + + +/****************************************************************************** +* * +* Paramètres : line = ligne dont un drapeau a évolué. * +* view = composant GTK à mettre à jour. * +* * +* Description : Redessine l'affichage suite une mise à jour dans la marge. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_block_view_update_margin(GRenderingLine *line, GtkBlockView *view) +{ + + + gtk_block_view_paint(view); + + + + +} + + + + + +static gboolean +gtk_block_view_expose(GtkWidget *widget, + GdkEventExpose *event) +{ + g_return_val_if_fail(widget != NULL, FALSE); + g_return_val_if_fail(GTK_IS_BLOCK_VIEW(widget), FALSE); + g_return_val_if_fail(event != NULL, FALSE); + + gtk_block_view_paint(GTK_BLOCK_VIEW(widget)); + + + + /* + + +gdk_gc_set_clip_region (GdkGC *gc, + const GdkRegion *region); + +gdk_window_invalidate_region (GdkWindow *window, + const GdkRegion *region, + gboolean invalidate_children); +gdk_window_begin_paint_region (GdkWindow *window, + const GdkRegion *region); +void gdk_window_end_paint (GdkWindow *window); + */ + + + + + + + return TRUE; + +} + + +static void +gtk_block_view_paint(GtkBlockView *view) +{ + GtkWidget *widget; /* Version GTK du composant */ + GdkGCValues values; /* Propriétés du contexte */ + GdkColor white; /* Couleur du fond */ + int width; /* Largeur de l'élément */ + int height; /* Hauteur de l'élément */ + GdkColor red; /* Couleur des arrêts */ + PangoLayoutIter *iter; /* Boucle de parcours */ + unsigned int index; /* Indice de la ligne visée */ + int y0; /* Ordonnée du haut d'une ligne*/ + int y1; /* Ordonnée du bas d'une ligne */ + + GRenderingLine *liter; + + + widget = GTK_WIDGET(view); + gdk_gc_get_values(view->gc, &values); + + gdk_color_white(gtk_widget_get_colormap(widget), &white); + gdk_gc_set_foreground(view->gc, &white); + + gtk_widget_get_size_request(widget, &width, &height); + + gdk_draw_rectangle(GDK_DRAWABLE(widget->window), GTK_BLOCK_VIEW(widget)->gc, + TRUE, 0, 0, width, height); + + gdk_color_parse("#ff0000", &red); + gdk_color_alloc(gtk_widget_get_colormap(widget), &red); + gdk_gc_set_foreground(view->gc, &red); + + + index = 0; + iter = pango_layout_get_iter(view->layout); + +#if 0 + for (; index < view->info_count; index++, pango_layout_iter_next_line(iter)) + { + if (!view->info[index].bp_set) continue; + + pango_layout_iter_get_line_yrange(iter, &y0, &y1); + + + + gdk_draw_arc(GDK_DRAWABLE(widget->window), GTK_BLOCK_VIEW(widget)->gc, + FALSE, MARGIN_SPACE, y0 / PANGO_SCALE, + view->line_height - 2, view->line_height - 2, + 0, 360 * 64); + + } +#endif + + pango_layout_iter_free(iter); + + gdk_gc_set_foreground(view->gc, &values.foreground); + + gdk_draw_layout(GDK_DRAWABLE(widget->window), view->gc, + 2 * MARGIN_SPACE + view->line_height, 0, + view->layout); + + + y0 = 0; + + for (/* l! */liter = view->lines; liter != NULL; liter = g_rendering_line_get_next_iter(view->lines, liter)) + { + g_rendering_line_draw(liter, GDK_DRAWABLE(widget->window), view->gc, + MARGIN_SPACE, 2 * MARGIN_SPACE + view->line_height, + y0, view->line_height); + + y0 += view->line_height; + + } + + +} + + +static void +gtk_block_view_destroy(GtkObject *object) +{ + GtkBlockView *cpu; + GtkBlockViewClass *klass; + + g_return_if_fail(object != NULL); + g_return_if_fail(GTK_IS_BLOCK_VIEW(object)); + + cpu = GTK_BLOCK_VIEW(object); + + klass = gtk_type_class(gtk_widget_get_type()); + + if (GTK_OBJECT_CLASS(klass)->destroy) { + (* GTK_OBJECT_CLASS(klass)->destroy) (object); + } +} + + + + + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à mettre à jour. * +* show = état de l'affichage auquel parvenir. * +* * +* Description : Choisit d'afficher les adresses virtuelles ou non. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_block_view_show_vaddress(GtkBlockView *view, gboolean show) +{ + view->show_vaddress = show; + + gtk_block_view_build_content(view); + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à mettre à jour. * +* show = état de l'affichage auquel parvenir. * +* * +* Description : Choisit d'afficher le code brut ou non. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_block_view_show_code(GtkBlockView *view, gboolean show) +{ + view->show_code = show; + + gtk_block_view_build_content(view); + +} + + + + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à mettre à jour. * +* format = format du binaire affiché. * +* * +* Description : Définit le format auquel le contenu est lié. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_block_view_set_format(GtkBlockView *view, const exe_format *format) +{ + view->format = format; + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à mettre à jour. * +* lines = informations à intégrer. * +* * +* Description : Définit les lignes du bloc de représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_block_view_set_rendering_lines(GtkBlockView *view, GRenderingLine *lines) +{ + GRenderingLine *iter; /* Boucle de parcours */ + + view->lines = lines; + + for (iter = lines; iter != NULL; iter = g_rendering_line_get_next_iter(lines, iter)) + g_signal_connect(iter, "rendering-line-flags-changed", + G_CALLBACK(gtk_block_view_update_margin), view); + + g_rendering_line_update_bin_len(lines); + + gtk_block_view_recompute_size_request(view); + +} + + + + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à mettre à jour. * +* * +* Description : Réclame une nouvelle taille adaptée au contenu présent. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_block_view_recompute_size_request(GtkBlockView *view) +{ + int width; /* Largeur de l'objet actuelle */ + int height; /* Hauteur de l'objet actuelle */ + + g_rendering_line_get_size(view->lines, &width, &height, &view->line_height); + + gtk_widget_set_size_request(GTK_WIDGET(view), + width + 2 * MARGIN_SPACE + view->line_height, + height); + +} + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à mettre à jour. * +* * +* Description : Définit le contenu visuel à partir des infos enregistrées. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_block_view_build_content(GtkBlockView *view) +{ +#if 0 + const uint8_t *exe_content; /* Contenu binaire global */ + off_t max_bin_len; /* Taille max du code brut */ + unsigned int i; /* Boucle de traitement */ + off_t bin_len; /* Taille d'instruction */ + char *bin_code; /* Tampon du code binaire */ + char *content; /* Contenu à définir */ + size_t content_len; /* Taille du contenu */ + AdressMode mode; /* Affichage des adresses */ + char buffer[CONTENT_BUFFER_LEN]; /* Zone tampon à utiliser */ + off_t bin_offset; /* Début de l'instruction */ + off_t k; /* Boucle de parcours #2 */ + off_t j; /* Boucle de parcours #1 */ + int width; /* Largeur de l'objet actuelle */ + int height; /* Hauteur de l'objet actuelle */ + PangoLayoutIter *iter; /* Boucle de parcours */ + int y0; /* Ordonnée du haut d'une ligne*/ + int y1; /* Ordonnée du bas d'une ligne */ + + /* Calcul de la largeur maximale brute si besoin est */ + if (view->show_code) + { + exe_content = get_exe_content(view->format, NULL); + + max_bin_len = 1; + + for (i = 0; i < view->info_count; i++) + { + /* Commentaire uniquement */ + if (view->info[i].instr == NULL) continue; + + get_asm_instr_offset_and_length(view->info[i].instr, NULL, &bin_len); + if (bin_len > max_bin_len) max_bin_len = bin_len; + + } + + max_bin_len = max_bin_len * 2 + (max_bin_len - 1); + bin_code = (char *)calloc(max_bin_len + 1, sizeof(char)); + + } + + content_len = strlen("") + 1; + content = (char *)calloc(content_len, sizeof(char)); + strcpy(content, ""); + + mode = ADM_32BITS; /* FIXME */ + + for (i = 0; i < view->info_count; i++) + { + if (i > 0) + { + content = (char *)realloc(content, ++content_len * sizeof(char)); + strcat(content, "\n"); + } + + /* Eventuelle adresse virtuelle */ + + if (view->show_vaddress) + { + switch (mode) + { + case ADM_32BITS: + snprintf(buffer, CONTENT_BUFFER_LEN, + "0x%08llx", + view->info[i].offset); + break; + + case ADM_64BITS: + snprintf(buffer, CONTENT_BUFFER_LEN, + "0x%16llx", + view->info[i].offset); + break; + + } + + content_len += strlen(buffer); + content = (char *)realloc(content, content_len * sizeof(char)); + strcat(content, buffer); + + } + + /* Eventuel code brut */ + + if (view->show_code) + { + k = 0; + + if (view->info[i].instr != NULL) + { + get_asm_instr_offset_and_length(view->info[i].instr, &bin_offset, &bin_len); + + for (j = 0; j < bin_len; j++) + { + if ((j + 1) < bin_len) + k += snprintf(&bin_code[j * (2 + 1)], 4, "%02hhx ", exe_content[bin_offset + j]); + else + k += snprintf(&bin_code[j * (2 + 1)], 3, "%02hhx", exe_content[bin_offset + j]); + } + + } + + for (; k < max_bin_len; k++) + snprintf(&bin_code[k], 2, " "); + + if (view->show_vaddress) content_len += strlen("\t"); + content_len += strlen(bin_code); + content = (char *)realloc(content, content_len * sizeof(char)); + if (view->show_vaddress) strcat(content, "\t"); + strcat(content, bin_code); + + } + + /* Eventuelle instruction */ + + if (view->info[i].instr != NULL) + { + print_hinstruction(view->proc, view->format, view->info[i].instr, buffer, CONTENT_BUFFER_LEN, ASX_INTEL); + + if (view->show_vaddress || view->show_code) content_len += strlen("\t"); + content_len += strlen(buffer); + + content = (char *)realloc(content, content_len * sizeof(char)); + if (view->show_vaddress || view->show_code) strcat(content, "\t"); + strcat(content, buffer); + + } + + /* Eventuel commantaire */ + + if (view->info[i].comment != NULL) + { + if (view->show_vaddress || view->show_code) content_len += strlen("\t"); + content_len += strlen("; ") + strlen(view->info[i].comment) + strlen(""); + + content = (char *)realloc(content, content_len * sizeof(char)); + if (view->show_vaddress || view->show_code) strcat(content, "\t"); + strcat(content, "; "); + strcat(content, view->info[i].comment); + strcat(content, ""); + + } + + } + + content_len += strlen(""); + content = (char *)realloc(content, content_len * sizeof(char)); + strcat(content, ""); + + if (view->show_code) free(bin_code); + + pango_layout_set_markup(view->layout, content, content_len - 1); + + pango_layout_get_pixel_size(view->layout, &width, &height); + + view->line_height = 0; + iter = pango_layout_get_iter(view->layout); + + do + { + pango_layout_iter_get_line_yrange(iter, &y0, &y1); + view->line_height = MAX(view->line_height, (y1 - y0) / PANGO_SCALE); + } + while (pango_layout_iter_next_line(iter)); + + pango_layout_iter_free(iter); + + //gtk_widget_set_size_request(GTK_WIDGET(block_view), width + 2 * MARGIN_SPACE + view->line_height, height); +#endif +} + + + + + + + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à consulter. * +* address = adresse à présenter à l'écran. * +* position = position verticale au sein du composant. [OUT] * +* * +* Description : Indique la position verticale d'une adresse donnée. * +* * +* Retour : TRUE si l'adresse fait partie du composant, FALSE sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gboolean gtk_block_view_get_address_vposition(GtkBlockView *view, uint64_t address, gint *position) +{ + unsigned int i; /* Boucle de parcours */ + + *position = 0; +#if 0 + for (i = 0; i < view->info_count; i++) + { + if (view->info[i].offset == address) break; + else *position += view->line_height; + } +#endif + return false;//(i < view->info_count); + +} + diff --git a/src/gtkext/gtkblockview.h b/src/gtkext/gtkblockview.h new file mode 100644 index 0000000..66117fa --- /dev/null +++ b/src/gtkext/gtkblockview.h @@ -0,0 +1,99 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtkblockview.h - prototypes pour l'affichage d'un fragment de code d'assemblage + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _GTKEXT_GTKBLOCKVIEW_H +#define _GTKEXT_GTKBLOCKVIEW_H + + +#include +#include +#include + + +#include "../analysis/line.h" +#include "../format/exe_format.h" + + + +#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)) + + + +typedef struct _GtkBlockView GtkBlockView; + + +typedef struct _GtkBlockViewClass GtkBlockViewClass; + + + +/* Détermine le type du composant d'affichage en blockique. */ +GType gtk_block_view_get_type(void); + +/* Crée un nouveau composant pour l'affichage en blockique. */ +GtkWidget* gtk_block_view_new(void); + + + + + + + + + + + + +/* Choisit d'afficher les adresses virtuelles ou non. */ +void gtk_block_view_show_vaddress(GtkBlockView *, gboolean); + +/* Choisit d'afficher le code brut ou non. */ +void gtk_block_view_show_code(GtkBlockView *, gboolean); + + + + +/* Définit le format auquel le contenu est lié. */ +void gtk_block_view_set_format(GtkBlockView *, const exe_format *); + +/* Définit les lignes du bloc de représentation. */ +void gtk_block_view_set_rendering_lines(GtkBlockView *, GRenderingLine *); + +/* Définit le contenu visuel à partir des infos enregistrées. */ +void gtk_block_view_build_content(GtkBlockView *); + + + +/* Indique la position verticale d'une adresse donnée. */ +gboolean gtk_block_view_get_address_vposition(GtkBlockView *, uint64_t, gint *); + + + + + + +#endif /* _GTKEXT_GTKBLOCKVIEW_H */ diff --git a/src/gtkext/gtkdockpanel.c b/src/gtkext/gtkdockpanel.c index e7bd14b..41b71aa 100644 --- a/src/gtkext/gtkdockpanel.c +++ b/src/gtkext/gtkdockpanel.c @@ -514,23 +514,35 @@ static void gtk_dock_panel_drag_end_cb(GtkDockPanel *dpanel, GdkDragContext *con /****************************************************************************** * * -* Paramètres : dpanel = composant à l'origine de la manoeuvre. * -* context = contexte de l'opération de "Drag and drop". * -* data = adresse non utilisée ici. * +* Paramètres : dpanel = composant dont le contenu est à parcourir. * +* name = désignation humaine du membre à retrouver. * * * -* Description : Nettoie les traces d'un "Drag and drop". * +* Description : Retrouve un membre du panneau d'après son nom. * * * -* Retour : - * +* Retour : Membre trouvé ou NULL si aucun. * * * * Remarques : - * * * ******************************************************************************/ -static void gtk_dock_panel_drag_data_delete_cb(GtkDockPanel *dpanel, GdkDragContext *context, gpointer data) +GtkDockItem *gtk_dock_panel_item_from_name(GtkDockPanel *dpanel, const char *name) { + GtkDockItem *result; /* Trouvaille à remonter */ + GList *iter; /* Boucle de parcours */ + const char *tmp; /* Autre nom à consulter */ + result = NULL; + for (iter = dpanel->ditems; iter != NULL && result == NULL; iter = g_list_next(iter)) + { + tmp = gtk_dock_item_get_name(GTK_DOCK_ITEM(iter->data)); + + if (strcmp(name, tmp) == 0) + result = GTK_DOCK_ITEM(iter->data); + } + + return result; } @@ -574,6 +586,32 @@ void gtk_dock_panel_add_item(GtkDockPanel *dpanel, GtkDockItem *ditem) * * * Paramètres : dpanel = composant GTK à mettre à jour. * * ditem = nouvel élément à sortir. * +* panel = nouveau panneau à présenter. * +* * +* Description : Remplace le panneau d'un membre actuellement affiché. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_dock_panel_replace_item_content(GtkDockPanel *dpanel, GtkDockItem *ditem, GtkWidget *panel) +{ + gtk_widget_ref(gtk_dock_item_get_panel(ditem)); + gtk_container_remove(GTK_CONTAINER(dpanel->notebook), gtk_dock_item_get_panel(ditem)); + + gtk_dock_item_set_panel(ditem, panel); + + gtk_container_add(GTK_CONTAINER(dpanel->notebook), gtk_dock_item_get_panel(ditem)); + +} + + +/****************************************************************************** +* * +* Paramètres : dpanel = composant GTK à mettre à jour. * +* ditem = nouvel élément à sortir. * * * * Description : Supprime un paquet d'informations à la station dockable. * * * @@ -593,6 +631,7 @@ void gtk_dock_panel_remove_item(GtkDockPanel *dpanel, GtkDockItem *ditem) printf("[rem %p from %p] list len :: %u\n", ditem, dpanel, g_list_length(dpanel->ditems)); + gtk_widget_ref(gtk_dock_item_get_panel(ditem)); gtk_container_remove(GTK_CONTAINER(dpanel->notebook), gtk_dock_item_get_panel(ditem)); //gtk_notebook_remove_page(dpanel->notebook, pos); diff --git a/src/gtkext/gtkdockpanel.h b/src/gtkext/gtkdockpanel.h index 140f812..037ee26 100644 --- a/src/gtkext/gtkdockpanel.h +++ b/src/gtkext/gtkdockpanel.h @@ -73,9 +73,15 @@ GtkType gtk_dock_panel_get_type(void); /* Crée un nouveau composant pour station dockable. */ GtkWidget *gtk_dock_panel_new(void); +/* Retrouve un membre du panneau d'après son nom. */ +GtkDockItem *gtk_dock_panel_item_from_name(GtkDockPanel *, const char *); + /* Ajoute un paquet d'informations à la station dockable. */ void gtk_dock_panel_add_item(GtkDockPanel *, GtkDockItem *); +/* Remplace le panneau d'un membre actuellement affiché. */ +void gtk_dock_panel_replace_item_content(GtkDockPanel *, GtkDockItem *, GtkWidget *); + /* Supprime un paquet d'informations à la station dockable. */ void gtk_dock_panel_remove_item(GtkDockPanel *, GtkDockItem *); diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c new file mode 100644 index 0000000..d843311 --- /dev/null +++ b/src/gtkext/gtkgraphview.c @@ -0,0 +1,110 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtkgraphview.c - affichage de morceaux de code sous forme graphique + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "gtkgraphview.h" + + +#include "gtkbinview-int.h" + + + +/* Représentation de code binaire sous forme graphique (instace) */ +struct _GtkGraphView +{ + GtkBinView parent; /* A laisser en premier */ + +}; + +/* 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étermine le type du composant d'affichage en graphique. */ +G_DEFINE_TYPE(GtkGraphView, gtk_graph_view, GTK_TYPE_BIN_VIEW) + + +/****************************************************************************** +* * +* Paramètres : class = classe GTK à initialiser. * +* * +* Description : Initialise la classe générique des graphiques de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_graph_view_class_init(GtkGraphViewClass *class) +{ + +} + + +/****************************************************************************** +* * +* 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) +{ + +} + + +/****************************************************************************** +* * +* 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); + +} diff --git a/src/gtkext/gtkgraphview.h b/src/gtkext/gtkgraphview.h new file mode 100644 index 0000000..12dd606 --- /dev/null +++ b/src/gtkext/gtkgraphview.h @@ -0,0 +1,56 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtkgraphview.h - prototypes pour l'affichage de morceaux de code sous forme graphique + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _GTKEXT_GTKGRAPHVIEW_H +#define _GTKEXT_GTKGRAPHVIEW_H + + +#include + + + +#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)) + + + +typedef struct _GtkGraphView GtkGraphView; + + +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); + + + +#endif /* _GTKEXT_GTKGRAPHVIEW_H */ diff --git a/src/gtkext/gtksnippet.c b/src/gtkext/gtksnippet.c deleted file mode 100644 index 3d1ed7e..0000000 --- a/src/gtkext/gtksnippet.c +++ /dev/null @@ -1,755 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * gtksnippet.c - affichage d'un fragment de code d'assemblage - * - * Copyright (C) 2008 Cyrille Bagard - * - * This file is part of OpenIDA. - * - * OpenIDA is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * OpenIDA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "gtksnippet.h" - - -#include -#include - - -#include "../common/dllist.h" - - - -#define CONTENT_BUFFER_LEN 64 - -#define MARGIN_SPACE 4 - - - - -/* Redessine l'affichage suite une mise à jour dans la marge. */ -void gtk_snippet_update_margin(GRenderingLine *, GtkSnippet *); - - - - - -/* Réclame une nouvelle taille adaptée au contenu présent. */ -void gtk_snippet_recompute_size_request(GtkSnippet *); - - - - - - - - -static void gtk_snippet_class_init(GtkSnippetClass *klass); -static void gtk_snippet_init(GtkSnippet *cpu); -static void gtk_snippet_size_request(GtkWidget *widget, - GtkRequisition *requisition); -static void gtk_snippet_size_allocate(GtkWidget *widget, - GtkAllocation *allocation); -static void gtk_snippet_realize(GtkWidget *widget); - - -static gboolean gtk_snippet_button_press(GtkWidget *, GdkEventButton *event); - -static gboolean gtk_snippet_expose(GtkWidget *widget, - GdkEventExpose *event); -static void gtk_snippet_paint(GtkSnippet *snippet); -static void gtk_snippet_destroy(GtkObject *object); - - - -G_DEFINE_TYPE(GtkSnippet, gtk_snippet, GTK_TYPE_WIDGET) - - - - -GtkWidget * gtk_snippet_new(void) -{ - GtkSnippet *result; - - result = gtk_type_new(gtk_snippet_get_type()); - - return GTK_WIDGET(result); - -} - - -static void -gtk_snippet_class_init(GtkSnippetClass *klass) -{ - GtkWidgetClass *widget_class; - GtkObjectClass *object_class; - - - widget_class = (GtkWidgetClass *) klass; - object_class = (GtkObjectClass *) klass; - - - widget_class->button_press_event = gtk_snippet_button_press; - widget_class->realize = gtk_snippet_realize; - widget_class->size_request = gtk_snippet_size_request; - widget_class->size_allocate = gtk_snippet_size_allocate; - widget_class->expose_event = gtk_snippet_expose; - - object_class->destroy = gtk_snippet_destroy; -} - - -static void -gtk_snippet_init(GtkSnippet *snippet) -{ - snippet->sel = 0; -} - - -static void -gtk_snippet_size_request(GtkWidget *widget, - GtkRequisition *requisition) -{ - g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_SNIPPET(widget)); - g_return_if_fail(requisition != NULL); - - requisition->width = 80; - requisition->height = 100; -} - - -static void -gtk_snippet_size_allocate(GtkWidget *widget, - GtkAllocation *allocation) -{ - g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_SNIPPET(widget)); - g_return_if_fail(allocation != NULL); - - widget->allocation = *allocation; - - if (GTK_WIDGET_REALIZED(widget)) { - gdk_window_move_resize( - widget->window, - allocation->x, allocation->y, - allocation->width, allocation->height - ); - } -} - - -static void -gtk_snippet_realize(GtkWidget *widget) -{ - GdkWindowAttr attributes; - guint attributes_mask; - GdkColor white; /* Couleur de fond normale */ - - g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_SNIPPET(widget)); - - GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x; - attributes.y = widget->allocation.y; - attributes.width = widget->allocation.width; - attributes.height = widget->allocation.height; - - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.event_mask = gtk_widget_get_events(widget) | GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y; - - widget->window = gdk_window_new( - gtk_widget_get_parent_window (widget), - & attributes, attributes_mask - ); - - gdk_window_set_user_data(widget->window, widget); - - widget->style = gtk_style_attach(widget->style, widget->window); - - - gdk_color_white(gtk_widget_get_colormap(widget), &white); - gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &white); - - - GTK_SNIPPET(widget)->layout = gtk_widget_create_pango_layout(widget, NULL); - GTK_SNIPPET(widget)->gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); - - gtk_snippet_build_content(GTK_SNIPPET(widget)); - -} - - -static gboolean gtk_snippet_button_press(GtkWidget *widget, GdkEventButton *event) -{ - gboolean result; /* Décision à retourner */ - GtkSnippet *snippet; /* Composant GTK réel */ - gdouble y; /* Position à manipuler */ - GRenderingLine *line; /* Ligne de rendu visée */ - - result = FALSE; - - snippet = GTK_SNIPPET(widget); - - y = event->y; - line = g_rendering_line_find_by_y(snippet->lines, &y); - - if (line != NULL) - { - /* Clic dans la marge */ - if (event->type == GDK_BUTTON_PRESS && event->x < (2 * MARGIN_SPACE + snippet->line_height)) - { - result = TRUE; - g_rendering_line_toggle_flag(line, RLF_BREAK_POINT); - } - - } - - if (result) - { - /* TODO: regions */ - gtk_snippet_paint(snippet); - } - - return result; - -} - - - -/****************************************************************************** -* * -* Paramètres : line = ligne dont un drapeau a évolué. * -* snippet = composant GTK à mettre à jour. * -* * -* Description : Redessine l'affichage suite une mise à jour dans la marge. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_update_margin(GRenderingLine *line, GtkSnippet *snippet) -{ - - - gtk_snippet_paint(snippet); - - - - -} - - - - - -static gboolean -gtk_snippet_expose(GtkWidget *widget, - GdkEventExpose *event) -{ - g_return_val_if_fail(widget != NULL, FALSE); - g_return_val_if_fail(GTK_IS_SNIPPET(widget), FALSE); - g_return_val_if_fail(event != NULL, FALSE); - - gtk_snippet_paint(GTK_SNIPPET(widget)); - - - - /* - - -gdk_gc_set_clip_region (GdkGC *gc, - const GdkRegion *region); - -gdk_window_invalidate_region (GdkWindow *window, - const GdkRegion *region, - gboolean invalidate_children); -gdk_window_begin_paint_region (GdkWindow *window, - const GdkRegion *region); -void gdk_window_end_paint (GdkWindow *window); - */ - - - - - - - return TRUE; - -} - - -static void -gtk_snippet_paint(GtkSnippet *snippet) -{ - GtkWidget *widget; /* Version GTK du composant */ - GdkGCValues values; /* Propriétés du contexte */ - GdkColor white; /* Couleur du fond */ - int width; /* Largeur de l'élément */ - int height; /* Hauteur de l'élément */ - GdkColor red; /* Couleur des arrêts */ - PangoLayoutIter *iter; /* Boucle de parcours */ - unsigned int index; /* Indice de la ligne visée */ - int y0; /* Ordonnée du haut d'une ligne*/ - int y1; /* Ordonnée du bas d'une ligne */ - - GRenderingLine *liter; - - - widget = GTK_WIDGET(snippet); - gdk_gc_get_values(snippet->gc, &values); - - gdk_color_white(gtk_widget_get_colormap(widget), &white); - gdk_gc_set_foreground(snippet->gc, &white); - - gtk_widget_get_size_request(widget, &width, &height); - - gdk_draw_rectangle(GDK_DRAWABLE(widget->window), GTK_SNIPPET(widget)->gc, - TRUE, 0, 0, width, height); - - gdk_color_parse("#ff0000", &red); - gdk_color_alloc(gtk_widget_get_colormap(widget), &red); - gdk_gc_set_foreground(snippet->gc, &red); - - - index = 0; - iter = pango_layout_get_iter(snippet->layout); - -#if 0 - for (; index < snippet->info_count; index++, pango_layout_iter_next_line(iter)) - { - if (!snippet->info[index].bp_set) continue; - - pango_layout_iter_get_line_yrange(iter, &y0, &y1); - - - - gdk_draw_arc(GDK_DRAWABLE(widget->window), GTK_SNIPPET(widget)->gc, - FALSE, MARGIN_SPACE, y0 / PANGO_SCALE, - snippet->line_height - 2, snippet->line_height - 2, - 0, 360 * 64); - - } -#endif - - pango_layout_iter_free(iter); - - gdk_gc_set_foreground(snippet->gc, &values.foreground); - - gdk_draw_layout(GDK_DRAWABLE(widget->window), snippet->gc, - 2 * MARGIN_SPACE + snippet->line_height, 0, - snippet->layout); - - - y0 = 0; - - for (/* l! */liter = snippet->lines; liter != NULL; liter = g_rendering_line_get_next_iter(snippet->lines, liter)) - { - g_rendering_line_draw(liter, GDK_DRAWABLE(widget->window), snippet->gc, - MARGIN_SPACE, 2 * MARGIN_SPACE + snippet->line_height, - y0, snippet->line_height); - - y0 += snippet->line_height; - - } - - -} - - -static void -gtk_snippet_destroy(GtkObject *object) -{ - GtkSnippet *cpu; - GtkSnippetClass *klass; - - g_return_if_fail(object != NULL); - g_return_if_fail(GTK_IS_SNIPPET(object)); - - cpu = GTK_SNIPPET(object); - - klass = gtk_type_class(gtk_widget_get_type()); - - if (GTK_OBJECT_CLASS(klass)->destroy) { - (* GTK_OBJECT_CLASS(klass)->destroy) (object); - } -} - - - - - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* show = état de l'affichage auquel parvenir. * -* * -* Description : Choisit d'afficher les adresses virtuelles ou non. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_show_vaddress(GtkSnippet *snippet, gboolean show) -{ - snippet->show_vaddress = show; - - gtk_snippet_build_content(snippet); - -} - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* show = état de l'affichage auquel parvenir. * -* * -* Description : Choisit d'afficher le code brut ou non. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_show_code(GtkSnippet *snippet, gboolean show) -{ - snippet->show_code = show; - - gtk_snippet_build_content(snippet); - -} - - - - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* format = format du binaire affiché. * -* * -* Description : Définit le format auquel le contenu est lié. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_set_format(GtkSnippet *snippet, const exe_format *format) -{ - snippet->format = format; - -} - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* lines = informations à intégrer. * -* * -* Description : Définit les lignes du bloc de représentation. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_set_rendering_lines(GtkSnippet *snippet, GRenderingLine *lines) -{ - GRenderingLine *iter; /* Boucle de parcours */ - - snippet->lines = lines; - - for (iter = lines; iter != NULL; iter = g_rendering_line_get_next_iter(lines, iter)) - g_signal_connect(iter, "rendering-line-flags-changed", - G_CALLBACK(gtk_snippet_update_margin), snippet); - - g_rendering_line_update_bin_len(lines); - - gtk_snippet_recompute_size_request(snippet); - -} - - - - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* * -* Description : Réclame une nouvelle taille adaptée au contenu présent. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_recompute_size_request(GtkSnippet *snippet) -{ - int width; /* Largeur de l'objet actuelle */ - int height; /* Hauteur de l'objet actuelle */ - - g_rendering_line_get_size(snippet->lines, &width, &height, &snippet->line_height); - - gtk_widget_set_size_request(GTK_WIDGET(snippet), - width + 2 * MARGIN_SPACE + snippet->line_height, - height); - -} - - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* * -* Description : Définit le contenu visuel à partir des infos enregistrées. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_build_content(GtkSnippet *snippet) -{ -#if 0 - const uint8_t *exe_content; /* Contenu binaire global */ - off_t max_bin_len; /* Taille max du code brut */ - unsigned int i; /* Boucle de traitement */ - off_t bin_len; /* Taille d'instruction */ - char *bin_code; /* Tampon du code binaire */ - char *content; /* Contenu à définir */ - size_t content_len; /* Taille du contenu */ - AdressMode mode; /* Affichage des adresses */ - char buffer[CONTENT_BUFFER_LEN]; /* Zone tampon à utiliser */ - off_t bin_offset; /* Début de l'instruction */ - off_t k; /* Boucle de parcours #2 */ - off_t j; /* Boucle de parcours #1 */ - int width; /* Largeur de l'objet actuelle */ - int height; /* Hauteur de l'objet actuelle */ - PangoLayoutIter *iter; /* Boucle de parcours */ - int y0; /* Ordonnée du haut d'une ligne*/ - int y1; /* Ordonnée du bas d'une ligne */ - - /* Calcul de la largeur maximale brute si besoin est */ - if (snippet->show_code) - { - exe_content = get_exe_content(snippet->format, NULL); - - max_bin_len = 1; - - for (i = 0; i < snippet->info_count; i++) - { - /* Commentaire uniquement */ - if (snippet->info[i].instr == NULL) continue; - - get_asm_instr_offset_and_length(snippet->info[i].instr, NULL, &bin_len); - if (bin_len > max_bin_len) max_bin_len = bin_len; - - } - - max_bin_len = max_bin_len * 2 + (max_bin_len - 1); - bin_code = (char *)calloc(max_bin_len + 1, sizeof(char)); - - } - - content_len = strlen("") + 1; - content = (char *)calloc(content_len, sizeof(char)); - strcpy(content, ""); - - mode = ADM_32BITS; /* FIXME */ - - for (i = 0; i < snippet->info_count; i++) - { - if (i > 0) - { - content = (char *)realloc(content, ++content_len * sizeof(char)); - strcat(content, "\n"); - } - - /* Eventuelle adresse virtuelle */ - - if (snippet->show_vaddress) - { - switch (mode) - { - case ADM_32BITS: - snprintf(buffer, CONTENT_BUFFER_LEN, - "0x%08llx", - snippet->info[i].offset); - break; - - case ADM_64BITS: - snprintf(buffer, CONTENT_BUFFER_LEN, - "0x%16llx", - snippet->info[i].offset); - break; - - } - - content_len += strlen(buffer); - content = (char *)realloc(content, content_len * sizeof(char)); - strcat(content, buffer); - - } - - /* Eventuel code brut */ - - if (snippet->show_code) - { - k = 0; - - if (snippet->info[i].instr != NULL) - { - get_asm_instr_offset_and_length(snippet->info[i].instr, &bin_offset, &bin_len); - - for (j = 0; j < bin_len; j++) - { - if ((j + 1) < bin_len) - k += snprintf(&bin_code[j * (2 + 1)], 4, "%02hhx ", exe_content[bin_offset + j]); - else - k += snprintf(&bin_code[j * (2 + 1)], 3, "%02hhx", exe_content[bin_offset + j]); - } - - } - - for (; k < max_bin_len; k++) - snprintf(&bin_code[k], 2, " "); - - if (snippet->show_vaddress) content_len += strlen("\t"); - content_len += strlen(bin_code); - content = (char *)realloc(content, content_len * sizeof(char)); - if (snippet->show_vaddress) strcat(content, "\t"); - strcat(content, bin_code); - - } - - /* Eventuelle instruction */ - - if (snippet->info[i].instr != NULL) - { - print_hinstruction(snippet->proc, snippet->format, snippet->info[i].instr, buffer, CONTENT_BUFFER_LEN, ASX_INTEL); - - if (snippet->show_vaddress || snippet->show_code) content_len += strlen("\t"); - content_len += strlen(buffer); - - content = (char *)realloc(content, content_len * sizeof(char)); - if (snippet->show_vaddress || snippet->show_code) strcat(content, "\t"); - strcat(content, buffer); - - } - - /* Eventuel commantaire */ - - if (snippet->info[i].comment != NULL) - { - if (snippet->show_vaddress || snippet->show_code) content_len += strlen("\t"); - content_len += strlen("; ") + strlen(snippet->info[i].comment) + strlen(""); - - content = (char *)realloc(content, content_len * sizeof(char)); - if (snippet->show_vaddress || snippet->show_code) strcat(content, "\t"); - strcat(content, "; "); - strcat(content, snippet->info[i].comment); - strcat(content, ""); - - } - - } - - content_len += strlen(""); - content = (char *)realloc(content, content_len * sizeof(char)); - strcat(content, ""); - - if (snippet->show_code) free(bin_code); - - pango_layout_set_markup(snippet->layout, content, content_len - 1); - - pango_layout_get_pixel_size(snippet->layout, &width, &height); - - snippet->line_height = 0; - iter = pango_layout_get_iter(snippet->layout); - - do - { - pango_layout_iter_get_line_yrange(iter, &y0, &y1); - snippet->line_height = MAX(snippet->line_height, (y1 - y0) / PANGO_SCALE); - } - while (pango_layout_iter_next_line(iter)); - - pango_layout_iter_free(iter); - - //gtk_widget_set_size_request(GTK_WIDGET(snippet), width + 2 * MARGIN_SPACE + snippet->line_height, height); -#endif -} - - - - - - - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à consulter. * -* address = adresse à présenter à l'écran. * -* position = position verticale au sein du composant. [OUT] * -* * -* Description : Indique la position verticale d'une adresse donnée. * -* * -* Retour : TRUE si l'adresse fait partie du composant, FALSE sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -gboolean gtk_snippet_get_address_vposition(GtkSnippet *snippet, uint64_t address, gint *position) -{ - unsigned int i; /* Boucle de parcours */ - - *position = 0; -#if 0 - for (i = 0; i < snippet->info_count; i++) - { - if (snippet->info[i].offset == address) break; - else *position += snippet->line_height; - } -#endif - return false;//(i < snippet->info_count); - -} - diff --git a/src/gtkext/gtksnippet.h b/src/gtkext/gtksnippet.h deleted file mode 100644 index aa388a2..0000000 --- a/src/gtkext/gtksnippet.h +++ /dev/null @@ -1,117 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * gtksnippet.h - prototypes pour l'affichage d'un fragment de code d'assemblage - * - * Copyright (C) 2008 Cyrille Bagard - * - * This file is part of OpenIDA. - * - * OpenIDA is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * OpenIDA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _GTK_SNIPPET_H -#define _GTK_SNIPPET_H - - -#include -#include -#include - - -#include "../analysis/line.h" -#include "../format/exe_format.h" - - - -G_BEGIN_DECLS - - -#define GTK_SNIPPET(obj) GTK_CHECK_CAST(obj, gtk_snippet_get_type (), GtkSnippet) -#define GTK_SNIPPET_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, gtk_snippet_get_type(), GtkSnippetClass) -#define GTK_IS_SNIPPET(obj) GTK_CHECK_TYPE(obj, gtk_snippet_get_type()) - - -typedef struct _GtkSnippet GtkSnippet; -typedef struct _GtkSnippetClass GtkSnippetClass; - - - - - -struct _GtkSnippet { - - GtkWidget widget; /* Présence obligatoire en 1er */ - - bool show_vaddress; /* Affichage des adresses ? */ - bool show_code; /* Affichage du code brut ? */ - - PangoLayout *layout; /* Moteur de rendu du code ASM */ - GdkGC *gc; /* Contexte graphique du rendu */ - int line_height; /* Hauteur maximale des lignes */ - - const exe_format *format; /* Format du contenu bianire */ - - GRenderingLine *lines; /* Contenu à représenter */ - - - gint sel; -}; - -struct _GtkSnippetClass { - GtkWidgetClass parent_class; -}; - - -GtkType gtk_snippet_get_type(void); -void gtk_snippet_set_sel(GtkSnippet *cpu, gint sel); - -GtkWidget * gtk_snippet_new(void); - - - - -/* Choisit d'afficher les adresses virtuelles ou non. */ -void gtk_snippet_show_vaddress(GtkSnippet *, gboolean); - -/* Choisit d'afficher le code brut ou non. */ -void gtk_snippet_show_code(GtkSnippet *, gboolean); - - - - -/* Définit le format auquel le contenu est lié. */ -void gtk_snippet_set_format(GtkSnippet *, const exe_format *); - -/* Définit les lignes du bloc de représentation. */ -void gtk_snippet_set_rendering_lines(GtkSnippet *, GRenderingLine *); - -/* Définit le contenu visuel à partir des infos enregistrées. */ -void gtk_snippet_build_content(GtkSnippet *); - - - -/* Indique la position verticale d'une adresse donnée. */ -gboolean gtk_snippet_get_address_vposition(GtkSnippet *, uint64_t, gint *); - - - -G_END_DECLS - - - - - - -#endif /* _GTK_SNIPPET_H */ diff --git a/src/project.c b/src/project.c index 20ec7c3..dc1efd1 100644 --- a/src/project.c +++ b/src/project.c @@ -33,6 +33,28 @@ #include "xdg.h" #include "xml.h" #include "gtkext/easygtk.h" +#include "gtkext/gtkblockview.h" +#include "gtkext/gtkgraphview.h" + + + + +/* Conservation d'un binaire chargé */ +typedef struct _loaded_binary +{ + openida_binary *binary; /* Binaire en question */ + + GtkWidget *views[BVW_COUNT]; /* Composants pour l'affichage */ + +} loaded_binary; + + +/* Met en place un nouveau binaire pour un projet. */ +loaded_binary *load_openida_binary(openida_binary *); + +/* Fournit un support d'affichage donné pour un binaire chargé. */ +GtkWidget *get_loaded_binary_view(const loaded_binary *, BinaryView); + @@ -42,7 +64,7 @@ struct openida_project { char *filename; /* Lieu d'enregistrement */ - openida_binary **binaries; /* Fichiers binaires associés */ + loaded_binary **binaries; /* Fichiers binaires associés */ size_t binaries_count; /* Nombre de ces fichiers */ @@ -55,6 +77,93 @@ struct openida_project +/****************************************************************************** +* * +* Paramètres : binary = binaire chargé à encadrer. * +* * +* Description : Met en place un nouveau binaire pour un projet. * +* * +* Retour : Adresse de la structure intermédiaire ou NULL si aucune (!). * +* * +* Remarques : - * +* * +******************************************************************************/ + +loaded_binary *load_openida_binary(openida_binary *binary) +{ + loaded_binary *result; /* Structure à renvoyer */ + BinaryView i; /* Boucle de parcours */ + GtkWidget *scrolledwindow; /* Surface d'exposition */ + GtkWidget *view; /* Affichage du binaire */ + + result = (loaded_binary *)calloc(1, sizeof(loaded_binary)); + + result->binary = binary; + + for (i = 0; i < BVW_COUNT; i++) + { + scrolledwindow = qck_create_scrolled_window(NULL, NULL); + + switch (i) + { + default: /* GCC ! */ + case BVW_BLOCK: + view = gtk_block_view_new(); + break; + case BVW_GRAPH: + view = gtk_graph_view_new(); + break; + } + + if (i == 0) + gtk_block_view_set_rendering_lines(GTK_BLOCK_VIEW(view), get_openida_binary_lines(binary)); + + gtk_widget_show(view); + + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolledwindow), view); + + result->views[i] = scrolledwindow; + + } + + return result; + +} + + + + + + + + +/****************************************************************************** +* * +* Paramètres : binary = binaire chargé et encadré. * +* view = type d'affichage requis. * +* * +* Description : Fournit un support d'affichage donné pour un binaire chargé. * +* * +* Retour : Composant GTK dédié à un affichage particulier. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *get_loaded_binary_view(const loaded_binary *binary, BinaryView view) +{ + return binary->views[view]; + +} + + + + + + + + + /****************************************************************************** * * @@ -277,15 +386,10 @@ bool write_openida_project_to_xml(openida_project *project, const char *filename void attach_binary_to_openida_project(openida_project *project, openida_binary *binary) { - project->binaries = (openida_binary **)realloc(project->binaries, - ++project->binaries_count * sizeof(openida_binary *)); - - - - - - project->binaries[project->binaries_count - 1] = binary; + project->binaries = (loaded_binary **)realloc(project->binaries, + ++project->binaries_count * sizeof(loaded_binary *)); + project->binaries[project->binaries_count - 1] = load_openida_binary(binary); } @@ -305,6 +409,7 @@ void attach_binary_to_openida_project(openida_project *project, openida_binary * void detach_binary_to_openida_project(openida_project *project, openida_binary *binary) { +#if 0 size_t i; /* Boucle de parcours */ for (i = 0; i < project->binaries_count; i++) @@ -315,6 +420,39 @@ void detach_binary_to_openida_project(openida_project *project, openida_binary * project->binaries = (openida_binary **)realloc(project->binaries, --project->binaries_count * sizeof(openida_binary *)); +#endif +} + + +/****************************************************************************** +* * +* Paramètres : project = projet à consulter. * +* binary = binaire chargé, encadré et concerné. * +* view = type d'affichage requis. * +* * +* Description : Fournit un support d'affichage donné pour un binaire chargé. * +* * +* Retour : Composant GTK dédié à un affichage particulier. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *get_view_for_openida_project_binary(const openida_project *project, const openida_binary *binary, BinaryView view) +{ + GtkWidget *result; /* Composant GTK à retourner */ + size_t i; /* Boucle de parcours */ + + result = NULL; + + for (i = 0; i < project->binaries_count; i++) + if (project->binaries[i]->binary == binary) + { + result = get_loaded_binary_view(project->binaries[i], view); + break; + } + + return result; } diff --git a/src/project.h b/src/project.h index 64c32bd..cf5613d 100644 --- a/src/project.h +++ b/src/project.h @@ -25,10 +25,25 @@ #define _PROJECT_H +#include + + #include "analysis/binary.h" +/* Type de représentations */ +typedef enum _BinaryView +{ + BVW_BLOCK, /* Version basique */ + BVW_GRAPH, /* Affichage en graphqie */ + + BVW_COUNT + +} BinaryView; + + + /* Propriétés d'un ensemble de fichiers ouverts */ typedef struct openida_project openida_project; @@ -66,6 +81,9 @@ void attach_binary_to_openida_project(openida_project *, openida_binary *); /* Détache un fichier donné à un projet donné. */ void detach_binary_to_openida_project(openida_project *, openida_binary *); +/* Fournit un support d'affichage donné pour un binaire chargé. */ +GtkWidget *get_view_for_openida_project_binary(const openida_project *, const openida_binary *, BinaryView); + /* Fournit l'ensemble des binaires associés à un projet. */ const openida_binary **get_openida_project_binaries(const openida_project *, size_t *); -- cgit v0.11.2-87-g4458