diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2009-06-13 14:05:50 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2009-06-13 14:05:50 (GMT) |
commit | ecb9ecc486049fe3bec6ecaeeb27f08f67bf0ef0 (patch) | |
tree | c4d84575960583ad61981adef6ed8f958ef9d817 | |
parent | fc8324b66dee0abf0a5e5e3cc570e1aed96b80c8 (diff) |
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
-rw-r--r-- | ChangeLog | 40 | ||||
-rw-r--r-- | src/editor.c | 133 | ||||
-rw-r--r-- | src/gtkext/Makefile.am | 4 | ||||
-rw-r--r-- | src/gtkext/easygtk.c | 34 | ||||
-rw-r--r-- | src/gtkext/easygtk.h | 3 | ||||
-rw-r--r-- | src/gtkext/gtkbinview-int.h | 49 | ||||
-rw-r--r-- | src/gtkext/gtkbinview.c | 30 | ||||
-rw-r--r-- | src/gtkext/gtkbinview.h | 3 | ||||
-rw-r--r-- | src/gtkext/gtkblockview.c (renamed from src/gtkext/gtksnippet.c) | 294 | ||||
-rw-r--r-- | src/gtkext/gtkblockview.h | 99 | ||||
-rw-r--r-- | src/gtkext/gtkdockpanel.c | 51 | ||||
-rw-r--r-- | src/gtkext/gtkdockpanel.h | 6 | ||||
-rw-r--r-- | src/gtkext/gtkgraphview.c | 110 | ||||
-rw-r--r-- | src/gtkext/gtkgraphview.h | 56 | ||||
-rw-r--r-- | src/gtkext/gtksnippet.h | 117 | ||||
-rw-r--r-- | src/project.c | 156 | ||||
-rw-r--r-- | src/project.h | 18 |
17 files changed, 870 insertions, 333 deletions
@@ -1,3 +1,43 @@ +09-06-13 Cyrille Bagard <nocbos@gmail.com> + + * 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 <nocbos@gmail.com> * 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GTKEXT_GTKBINVIEW_INT_H +#define _GTKEXT_GTKBINVIEW_INT_H + + +#include "gtkbinview.h" + + +#include <gtk/gtkfixed.h> + + + +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/gtksnippet.c b/src/gtkext/gtkblockview.c index 3d1ed7e..b125c7b 100644 --- a/src/gtkext/gtksnippet.c +++ b/src/gtkext/gtkblockview.c @@ -1,6 +1,6 @@ /* OpenIDA - Outil d'analyse de fichiers binaires - * gtksnippet.c - affichage d'un fragment de code d'assemblage + * gtkblockview.c - affichage d'un fragment de code d'assemblage * * Copyright (C) 2008 Cyrille Bagard * @@ -21,13 +21,14 @@ */ -#include "gtksnippet.h" +#include "gtkblockview.h" #include <malloc.h> #include <string.h> +#include "gtkbinview-int.h" #include "../common/dllist.h" @@ -38,16 +39,45 @@ +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_snippet_update_margin(GRenderingLine *, GtkSnippet *); +void gtk_block_view_update_margin(GRenderingLine *, GtkBlockView *); /* Réclame une nouvelle taille adaptée au contenu présent. */ -void gtk_snippet_recompute_size_request(GtkSnippet *); +void gtk_block_view_recompute_size_request(GtkBlockView *); @@ -56,34 +86,34 @@ 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, +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_snippet_size_allocate(GtkWidget *widget, +static void gtk_block_view_size_allocate(GtkWidget *widget, GtkAllocation *allocation); -static void gtk_snippet_realize(GtkWidget *widget); +static void gtk_block_view_realize(GtkWidget *widget); -static gboolean gtk_snippet_button_press(GtkWidget *, GdkEventButton *event); +static gboolean gtk_block_view_button_press(GtkWidget *, GdkEventButton *event); -static gboolean gtk_snippet_expose(GtkWidget *widget, +static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event); -static void gtk_snippet_paint(GtkSnippet *snippet); -static void gtk_snippet_destroy(GtkObject *object); +static void gtk_block_view_paint(GtkBlockView *view); +static void gtk_block_view_destroy(GtkObject *object); -G_DEFINE_TYPE(GtkSnippet, gtk_snippet, GTK_TYPE_WIDGET) +G_DEFINE_TYPE(GtkBlockView, gtk_block_view, GTK_TYPE_BIN_VIEW) -GtkWidget * gtk_snippet_new(void) +GtkWidget * gtk_block_view_new(void) { - GtkSnippet *result; + GtkBlockView *result; - result = gtk_type_new(gtk_snippet_get_type()); + result = gtk_type_new(gtk_block_view_get_type()); return GTK_WIDGET(result); @@ -91,7 +121,7 @@ GtkWidget * gtk_snippet_new(void) static void -gtk_snippet_class_init(GtkSnippetClass *klass) +gtk_block_view_class_init(GtkBlockViewClass *klass) { GtkWidgetClass *widget_class; GtkObjectClass *object_class; @@ -101,29 +131,29 @@ gtk_snippet_class_init(GtkSnippetClass *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; + 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_snippet_destroy; + object_class->destroy = gtk_block_view_destroy; } static void -gtk_snippet_init(GtkSnippet *snippet) +gtk_block_view_init(GtkBlockView *view) { - snippet->sel = 0; + } static void -gtk_snippet_size_request(GtkWidget *widget, +gtk_block_view_size_request(GtkWidget *widget, GtkRequisition *requisition) { g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_SNIPPET(widget)); + g_return_if_fail(GTK_IS_BLOCK_VIEW(widget)); g_return_if_fail(requisition != NULL); requisition->width = 80; @@ -132,11 +162,11 @@ gtk_snippet_size_request(GtkWidget *widget, static void -gtk_snippet_size_allocate(GtkWidget *widget, +gtk_block_view_size_allocate(GtkWidget *widget, GtkAllocation *allocation) { g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_SNIPPET(widget)); + g_return_if_fail(GTK_IS_BLOCK_VIEW(widget)); g_return_if_fail(allocation != NULL); widget->allocation = *allocation; @@ -152,14 +182,14 @@ gtk_snippet_size_allocate(GtkWidget *widget, static void -gtk_snippet_realize(GtkWidget *widget) +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_SNIPPET(widget)); + g_return_if_fail(GTK_IS_BLOCK_VIEW(widget)); GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); @@ -188,32 +218,32 @@ gtk_snippet_realize(GtkWidget *widget) 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_BLOCK_VIEW(widget)->layout = gtk_widget_create_pango_layout(widget, NULL); + GTK_BLOCK_VIEW(widget)->gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); - gtk_snippet_build_content(GTK_SNIPPET(widget)); + gtk_block_view_build_content(GTK_BLOCK_VIEW(widget)); } -static gboolean gtk_snippet_button_press(GtkWidget *widget, GdkEventButton *event) +static gboolean gtk_block_view_button_press(GtkWidget *widget, GdkEventButton *event) { gboolean result; /* Décision à retourner */ - GtkSnippet *snippet; /* Composant GTK réel */ + GtkBlockView *view; /* Composant GTK réel */ gdouble y; /* Position à manipuler */ GRenderingLine *line; /* Ligne de rendu visée */ result = FALSE; - snippet = GTK_SNIPPET(widget); + view = GTK_BLOCK_VIEW(widget); y = event->y; - line = g_rendering_line_find_by_y(snippet->lines, &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 + snippet->line_height)) + 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); @@ -224,7 +254,7 @@ static gboolean gtk_snippet_button_press(GtkWidget *widget, GdkEventButton *even if (result) { /* TODO: regions */ - gtk_snippet_paint(snippet); + gtk_block_view_paint(view); } return result; @@ -235,8 +265,8 @@ static gboolean gtk_snippet_button_press(GtkWidget *widget, GdkEventButton *even /****************************************************************************** * * -* Paramètres : line = ligne dont un drapeau a évolué. * -* snippet = composant GTK à mettre à jour. * +* 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. * * * @@ -246,11 +276,11 @@ static gboolean gtk_snippet_button_press(GtkWidget *widget, GdkEventButton *even * * ******************************************************************************/ -void gtk_snippet_update_margin(GRenderingLine *line, GtkSnippet *snippet) +void gtk_block_view_update_margin(GRenderingLine *line, GtkBlockView *view) { - gtk_snippet_paint(snippet); + gtk_block_view_paint(view); @@ -262,14 +292,14 @@ void gtk_snippet_update_margin(GRenderingLine *line, GtkSnippet *snippet) static gboolean -gtk_snippet_expose(GtkWidget *widget, +gtk_block_view_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(GTK_IS_BLOCK_VIEW(widget), FALSE); g_return_val_if_fail(event != NULL, FALSE); - gtk_snippet_paint(GTK_SNIPPET(widget)); + gtk_block_view_paint(GTK_BLOCK_VIEW(widget)); @@ -298,7 +328,7 @@ void gdk_window_end_paint (GdkWindow *window); static void -gtk_snippet_paint(GtkSnippet *snippet) +gtk_block_view_paint(GtkBlockView *view) { GtkWidget *widget; /* Version GTK du composant */ GdkGCValues values; /* Propriétés du contexte */ @@ -314,37 +344,37 @@ gtk_snippet_paint(GtkSnippet *snippet) GRenderingLine *liter; - widget = GTK_WIDGET(snippet); - gdk_gc_get_values(snippet->gc, &values); + widget = GTK_WIDGET(view); + gdk_gc_get_values(view->gc, &values); gdk_color_white(gtk_widget_get_colormap(widget), &white); - gdk_gc_set_foreground(snippet->gc, &white); + gdk_gc_set_foreground(view->gc, &white); gtk_widget_get_size_request(widget, &width, &height); - gdk_draw_rectangle(GDK_DRAWABLE(widget->window), GTK_SNIPPET(widget)->gc, + 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(snippet->gc, &red); + gdk_gc_set_foreground(view->gc, &red); index = 0; - iter = pango_layout_get_iter(snippet->layout); + iter = pango_layout_get_iter(view->layout); #if 0 - for (; index < snippet->info_count; index++, pango_layout_iter_next_line(iter)) + for (; index < view->info_count; index++, pango_layout_iter_next_line(iter)) { - if (!snippet->info[index].bp_set) continue; + if (!view->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, + gdk_draw_arc(GDK_DRAWABLE(widget->window), GTK_BLOCK_VIEW(widget)->gc, FALSE, MARGIN_SPACE, y0 / PANGO_SCALE, - snippet->line_height - 2, snippet->line_height - 2, + view->line_height - 2, view->line_height - 2, 0, 360 * 64); } @@ -352,22 +382,22 @@ gtk_snippet_paint(GtkSnippet *snippet) pango_layout_iter_free(iter); - gdk_gc_set_foreground(snippet->gc, &values.foreground); + gdk_gc_set_foreground(view->gc, &values.foreground); - gdk_draw_layout(GDK_DRAWABLE(widget->window), snippet->gc, - 2 * MARGIN_SPACE + snippet->line_height, 0, - snippet->layout); + gdk_draw_layout(GDK_DRAWABLE(widget->window), view->gc, + 2 * MARGIN_SPACE + view->line_height, 0, + view->layout); y0 = 0; - for (/* l! */liter = snippet->lines; liter != NULL; liter = g_rendering_line_get_next_iter(snippet->lines, liter)) + 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), snippet->gc, - MARGIN_SPACE, 2 * MARGIN_SPACE + snippet->line_height, - y0, snippet->line_height); + g_rendering_line_draw(liter, GDK_DRAWABLE(widget->window), view->gc, + MARGIN_SPACE, 2 * MARGIN_SPACE + view->line_height, + y0, view->line_height); - y0 += snippet->line_height; + y0 += view->line_height; } @@ -376,15 +406,15 @@ gtk_snippet_paint(GtkSnippet *snippet) static void -gtk_snippet_destroy(GtkObject *object) +gtk_block_view_destroy(GtkObject *object) { - GtkSnippet *cpu; - GtkSnippetClass *klass; + GtkBlockView *cpu; + GtkBlockViewClass *klass; g_return_if_fail(object != NULL); - g_return_if_fail(GTK_IS_SNIPPET(object)); + g_return_if_fail(GTK_IS_BLOCK_VIEW(object)); - cpu = GTK_SNIPPET(object); + cpu = GTK_BLOCK_VIEW(object); klass = gtk_type_class(gtk_widget_get_type()); @@ -400,7 +430,7 @@ gtk_snippet_destroy(GtkObject *object) /****************************************************************************** * * -* Paramètres : snippet = composant GTK à mettre à jour. * +* Paramètres : view = composant GTK à mettre à jour. * * show = état de l'affichage auquel parvenir. * * * * Description : Choisit d'afficher les adresses virtuelles ou non. * @@ -411,18 +441,18 @@ gtk_snippet_destroy(GtkObject *object) * * ******************************************************************************/ -void gtk_snippet_show_vaddress(GtkSnippet *snippet, gboolean show) +void gtk_block_view_show_vaddress(GtkBlockView *view, gboolean show) { - snippet->show_vaddress = show; + view->show_vaddress = show; - gtk_snippet_build_content(snippet); + gtk_block_view_build_content(view); } /****************************************************************************** * * -* Paramètres : snippet = composant GTK à mettre à jour. * +* Paramètres : view = composant GTK à mettre à jour. * * show = état de l'affichage auquel parvenir. * * * * Description : Choisit d'afficher le code brut ou non. * @@ -433,11 +463,11 @@ void gtk_snippet_show_vaddress(GtkSnippet *snippet, gboolean show) * * ******************************************************************************/ -void gtk_snippet_show_code(GtkSnippet *snippet, gboolean show) +void gtk_block_view_show_code(GtkBlockView *view, gboolean show) { - snippet->show_code = show; + view->show_code = show; - gtk_snippet_build_content(snippet); + gtk_block_view_build_content(view); } @@ -447,7 +477,7 @@ void gtk_snippet_show_code(GtkSnippet *snippet, gboolean show) /****************************************************************************** * * -* Paramètres : snippet = composant GTK à mettre à jour. * +* Paramètres : view = composant GTK à mettre à jour. * * format = format du binaire affiché. * * * * Description : Définit le format auquel le contenu est lié. * @@ -458,16 +488,16 @@ void gtk_snippet_show_code(GtkSnippet *snippet, gboolean show) * * ******************************************************************************/ -void gtk_snippet_set_format(GtkSnippet *snippet, const exe_format *format) +void gtk_block_view_set_format(GtkBlockView *view, const exe_format *format) { - snippet->format = format; + view->format = format; } /****************************************************************************** * * -* Paramètres : snippet = composant GTK à mettre à jour. * +* Paramètres : view = composant GTK à mettre à jour. * * lines = informations à intégrer. * * * * Description : Définit les lignes du bloc de représentation. * @@ -478,19 +508,19 @@ void gtk_snippet_set_format(GtkSnippet *snippet, const exe_format *format) * * ******************************************************************************/ -void gtk_snippet_set_rendering_lines(GtkSnippet *snippet, GRenderingLine *lines) +void gtk_block_view_set_rendering_lines(GtkBlockView *view, GRenderingLine *lines) { GRenderingLine *iter; /* Boucle de parcours */ - snippet->lines = lines; + 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_snippet_update_margin), snippet); + G_CALLBACK(gtk_block_view_update_margin), view); g_rendering_line_update_bin_len(lines); - gtk_snippet_recompute_size_request(snippet); + gtk_block_view_recompute_size_request(view); } @@ -500,7 +530,7 @@ void gtk_snippet_set_rendering_lines(GtkSnippet *snippet, GRenderingLine *lines) /****************************************************************************** * * -* Paramètres : snippet = composant GTK à mettre à jour. * +* Paramètres : view = composant GTK à mettre à jour. * * * * Description : Réclame une nouvelle taille adaptée au contenu présent. * * * @@ -510,15 +540,15 @@ void gtk_snippet_set_rendering_lines(GtkSnippet *snippet, GRenderingLine *lines) * * ******************************************************************************/ -void gtk_snippet_recompute_size_request(GtkSnippet *snippet) +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(snippet->lines, &width, &height, &snippet->line_height); + g_rendering_line_get_size(view->lines, &width, &height, &view->line_height); - gtk_widget_set_size_request(GTK_WIDGET(snippet), - width + 2 * MARGIN_SPACE + snippet->line_height, + gtk_widget_set_size_request(GTK_WIDGET(view), + width + 2 * MARGIN_SPACE + view->line_height, height); } @@ -534,7 +564,7 @@ void gtk_snippet_recompute_size_request(GtkSnippet *snippet) /****************************************************************************** * * -* Paramètres : snippet = composant GTK à mettre à jour. * +* Paramètres : view = composant GTK à mettre à jour. * * * * Description : Définit le contenu visuel à partir des infos enregistrées. * * * @@ -544,7 +574,7 @@ void gtk_snippet_recompute_size_request(GtkSnippet *snippet) * * ******************************************************************************/ -void gtk_snippet_build_content(GtkSnippet *snippet) +void gtk_block_view_build_content(GtkBlockView *view) { #if 0 const uint8_t *exe_content; /* Contenu binaire global */ @@ -566,18 +596,18 @@ void gtk_snippet_build_content(GtkSnippet *snippet) int y1; /* Ordonnée du bas d'une ligne */ /* Calcul de la largeur maximale brute si besoin est */ - if (snippet->show_code) + if (view->show_code) { - exe_content = get_exe_content(snippet->format, NULL); + exe_content = get_exe_content(view->format, NULL); max_bin_len = 1; - for (i = 0; i < snippet->info_count; i++) + for (i = 0; i < view->info_count; i++) { /* Commentaire uniquement */ - if (snippet->info[i].instr == NULL) continue; + if (view->info[i].instr == NULL) continue; - get_asm_instr_offset_and_length(snippet->info[i].instr, NULL, &bin_len); + get_asm_instr_offset_and_length(view->info[i].instr, NULL, &bin_len); if (bin_len > max_bin_len) max_bin_len = bin_len; } @@ -593,7 +623,7 @@ void gtk_snippet_build_content(GtkSnippet *snippet) mode = ADM_32BITS; /* FIXME */ - for (i = 0; i < snippet->info_count; i++) + for (i = 0; i < view->info_count; i++) { if (i > 0) { @@ -603,20 +633,20 @@ void gtk_snippet_build_content(GtkSnippet *snippet) /* Eventuelle adresse virtuelle */ - if (snippet->show_vaddress) + if (view->show_vaddress) { switch (mode) { case ADM_32BITS: snprintf(buffer, CONTENT_BUFFER_LEN, "<span foreground='#333333'>0x%08llx</span>", - snippet->info[i].offset); + view->info[i].offset); break; case ADM_64BITS: snprintf(buffer, CONTENT_BUFFER_LEN, "<span foreground='#333333'>0x%16llx</span>", - snippet->info[i].offset); + view->info[i].offset); break; } @@ -629,13 +659,13 @@ void gtk_snippet_build_content(GtkSnippet *snippet) /* Eventuel code brut */ - if (snippet->show_code) + if (view->show_code) { k = 0; - if (snippet->info[i].instr != NULL) + if (view->info[i].instr != NULL) { - get_asm_instr_offset_and_length(snippet->info[i].instr, &bin_offset, &bin_len); + get_asm_instr_offset_and_length(view->info[i].instr, &bin_offset, &bin_len); for (j = 0; j < bin_len; j++) { @@ -650,40 +680,40 @@ void gtk_snippet_build_content(GtkSnippet *snippet) for (; k < max_bin_len; k++) snprintf(&bin_code[k], 2, " "); - if (snippet->show_vaddress) content_len += strlen("\t"); + if (view->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"); + if (view->show_vaddress) strcat(content, "\t"); strcat(content, bin_code); } /* Eventuelle instruction */ - if (snippet->info[i].instr != NULL) + if (view->info[i].instr != NULL) { - print_hinstruction(snippet->proc, snippet->format, snippet->info[i].instr, buffer, CONTENT_BUFFER_LEN, ASX_INTEL); + print_hinstruction(view->proc, view->format, view->info[i].instr, buffer, CONTENT_BUFFER_LEN, ASX_INTEL); - if (snippet->show_vaddress || snippet->show_code) content_len += strlen("\t"); + if (view->show_vaddress || view->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"); + if (view->show_vaddress || view->show_code) strcat(content, "\t"); strcat(content, buffer); } /* Eventuel commantaire */ - if (snippet->info[i].comment != NULL) + if (view->info[i].comment != NULL) { - if (snippet->show_vaddress || snippet->show_code) content_len += strlen("\t"); - content_len += strlen("<b><span foreground='#003300'>; ") + strlen(snippet->info[i].comment) + strlen("</span></b>"); + if (view->show_vaddress || view->show_code) content_len += strlen("\t"); + content_len += strlen("<b><span foreground='#003300'>; ") + strlen(view->info[i].comment) + strlen("</span></b>"); content = (char *)realloc(content, content_len * sizeof(char)); - if (snippet->show_vaddress || snippet->show_code) strcat(content, "\t"); + if (view->show_vaddress || view->show_code) strcat(content, "\t"); strcat(content, "<b><span foreground='#003300'>; "); - strcat(content, snippet->info[i].comment); + strcat(content, view->info[i].comment); strcat(content, "</span></b>"); } @@ -694,25 +724,25 @@ void gtk_snippet_build_content(GtkSnippet *snippet) content = (char *)realloc(content, content_len * sizeof(char)); strcat(content, "</tt>"); - if (snippet->show_code) free(bin_code); + if (view->show_code) free(bin_code); - pango_layout_set_markup(snippet->layout, content, content_len - 1); + pango_layout_set_markup(view->layout, content, content_len - 1); - pango_layout_get_pixel_size(snippet->layout, &width, &height); + pango_layout_get_pixel_size(view->layout, &width, &height); - snippet->line_height = 0; - iter = pango_layout_get_iter(snippet->layout); + view->line_height = 0; + iter = pango_layout_get_iter(view->layout); do { pango_layout_iter_get_line_yrange(iter, &y0, &y1); - snippet->line_height = MAX(snippet->line_height, (y1 - y0) / PANGO_SCALE); + 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(snippet), width + 2 * MARGIN_SPACE + snippet->line_height, height); + //gtk_widget_set_size_request(GTK_WIDGET(block_view), width + 2 * MARGIN_SPACE + view->line_height, height); #endif } @@ -725,7 +755,7 @@ void gtk_snippet_build_content(GtkSnippet *snippet) /****************************************************************************** * * -* Paramètres : snippet = composant GTK à consulter. * +* Paramètres : view = composant GTK à consulter. * * address = adresse à présenter à l'écran. * * position = position verticale au sein du composant. [OUT] * * * @@ -737,19 +767,19 @@ void gtk_snippet_build_content(GtkSnippet *snippet) * * ******************************************************************************/ -gboolean gtk_snippet_get_address_vposition(GtkSnippet *snippet, uint64_t address, gint *position) +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 < snippet->info_count; i++) + for (i = 0; i < view->info_count; i++) { - if (snippet->info[i].offset == address) break; - else *position += snippet->line_height; + if (view->info[i].offset == address) break; + else *position += view->line_height; } #endif - return false;//(i < snippet->info_count); + 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GTKEXT_GTKBLOCKVIEW_H +#define _GTKEXT_GTKBLOCKVIEW_H + + +#include <stdint.h> +#include <gtk/gtk.h> +#include <cairo.h> + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GTKEXT_GTKGRAPHVIEW_H +#define _GTKEXT_GTKGRAPHVIEW_H + + +#include <gtk/gtkwidget.h> + + + +#define GTK_TYPE_GRAPH_VIEW (gtk_graph_view_get_type()) +#define GTK_GRAPH_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_GRAPH_VIEW, GtkGraphView)) +#define GTK_GRAPH_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_GRAPH_VIEW, GtkGraphViewClass)) +#define GTK_IS_GRAPH_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_GRAPH_VIEW)) +#define GTK_IS_GRAPH_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_GRAPH_VIEW)) +#define GTK_GRAPH_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_GRAPH_VIEW, GtkGraphViewClass)) + + + +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.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 <http://www.gnu.org/licenses/>. - */ - - -#ifndef _GTK_SNIPPET_H -#define _GTK_SNIPPET_H - - -#include <stdint.h> -#include <gtk/gtk.h> -#include <cairo.h> - - -#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 <gtk/gtkwidget.h> + + #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 *); |