diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-03-08 19:30:52 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-03-08 19:30:52 (GMT) |
commit | 68bb7efaf61e4f5ca2f2cffce84995ffd667c4cc (patch) | |
tree | 9b6a6f63ee20b08d8c2ac35849ee051d61787447 /src/gui | |
parent | dc9e68505c4cc7ad208e63dbc7d0e0e8f582d0d9 (diff) |
Handle cross references as well as entry points.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@482 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/editem-int.h | 4 | ||||
-rw-r--r-- | src/gui/editem.c | 31 | ||||
-rw-r--r-- | src/gui/editem.h | 3 | ||||
-rw-r--r-- | src/gui/menus/binary.c | 2 | ||||
-rw-r--r-- | src/gui/menus/edition.c | 246 | ||||
-rw-r--r-- | src/gui/menus/menubar.c | 71 |
6 files changed, 307 insertions, 50 deletions
diff --git a/src/gui/editem-int.h b/src/gui/editem-int.h index 7dc3ad4..b76769f 100644 --- a/src/gui/editem-int.h +++ b/src/gui/editem-int.h @@ -40,6 +40,9 @@ typedef void (* update_item_binary_fc) (GEditorItem *, GLoadedBinary *); /* Réagit à un changement d'affichage principal de contenu. */ +typedef void (* manage_item_view_fc) (GEditorItem *, GtkViewPanel *, bool); + +/* Réagit à un changement d'affichage principal de contenu. */ typedef void (* update_item_view_fc) (GEditorItem *, GtkViewPanel *); /* Concentre l'attention de l'ensemble sur une adresse donnée. */ @@ -70,6 +73,7 @@ struct _GEditorItemClass GObjectClass parent; /* A laisser en premier */ update_item_binary_fc update_binary; /* Changement de binaire */ + manage_item_view_fc manage_view; /* Gestion des vues manipulées */ update_item_view_fc update_view; /* Rechargement dû à une vue */ update_item_view_fc update_content; /* Rechargement dû à un contenu*/ focus_addr_fc focus_addr; /* Prête attention à une addr. */ diff --git a/src/gui/editem.c b/src/gui/editem.c index cde5d7f..e4c74a9 100644 --- a/src/gui/editem.c +++ b/src/gui/editem.c @@ -229,6 +229,37 @@ void change_editor_items_current_binary(GObject *ref, GLoadedBinary *binary) /****************************************************************************** * * +* Paramètres : view = nouveau panneau d'affichage nouveau. * +* created = fait état d'une création ou d'une destruction. * +* * +* Description : Lance une actualisation liée à une modification du cheptel. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void manage_editor_items_view(GtkViewPanel *view, bool created) +{ + GEditorItem *iter; /* Boucle de parcours */ + GEditorItemClass *klass; /* Classe correspondante */ + + editem_list_for_each(iter, _editem_list) + { + klass = G_EDITOR_ITEM_GET_CLASS(iter); + + if (klass->manage_view != NULL) + klass->manage_view(iter, view, created); + + + } + +} + + +/****************************************************************************** +* * * Paramètres : ref = espace de référencement global. * * view = nouveau panneau d'affichage actif. * * * diff --git a/src/gui/editem.h b/src/gui/editem.h index d1b91a5..827c752 100644 --- a/src/gui/editem.h +++ b/src/gui/editem.h @@ -79,6 +79,9 @@ void register_editor_item(GEditorItem *); /* Lance une actualisation du fait d'un changement de binaire. */ void change_editor_items_current_binary(GObject *, GLoadedBinary *); +/* Lance une actualisation liée à une modification du cheptel. */ +void manage_editor_items_view(GtkViewPanel *, bool); + /* Lance une actualisation du fait d'un changement de vue. */ void change_editor_items_current_view(GObject *, GtkViewPanel *); diff --git a/src/gui/menus/binary.c b/src/gui/menus/binary.c index 50a9143..c93ad57 100644 --- a/src/gui/menus/binary.c +++ b/src/gui/menus/binary.c @@ -121,7 +121,7 @@ static void mcb_binary_entry_points(GtkMenuItem *menuitem, GMenuBar *bar) ref = g_editor_item_get_global_ref(item); binary = g_editor_item_get_current_binary(item); - dialog = create_gotox_dialog(GTK_WINDOW(ref), binary); + dialog = create_gotox_dialog_for_entry_points(GTK_WINDOW(ref), binary); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c index 8893ce9..3c1d6ac 100644 --- a/src/gui/menus/edition.c +++ b/src/gui/menus/edition.c @@ -28,19 +28,27 @@ #include <i18n.h> +#include "../../arch/target.h" #include "../../dialogs/bookmark.h" #include "../../dialogs/goto.h" +#include "../../dialogs/gotox.h" #include "../../gtkext/easygtk.h" #include "../../gtkext/gtkbufferview.h" -/* Réagit avec le menu "Edition -> Signets -> Basculer...". */ -static void mcb_edition_bookmarks_toggle(GtkMenuItem *, GMenuBar *); - /* Réagit avec le menu "Edition -> Aller à l'adresse...". */ static void mcb_edition_goto(GtkMenuItem *, GMenuBar *); +/* Réagit avec le menu "Edition -> Suivre la référence". */ +static void mcb_edition_follow_ref(GtkMenuItem *, GMenuBar *); + +/* Réagit avec le menu "Edition -> Lister toutes les réfs...". */ +static void mcb_edition_list_xrefs(GtkMenuItem *, GMenuBar *); + +/* Réagit avec le menu "Edition -> Signets -> Basculer...". */ +static void mcb_edition_bookmarks_toggle(GtkMenuItem *, GMenuBar *); + /****************************************************************************** @@ -71,6 +79,27 @@ GtkWidget *build_menu_edition(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *b menubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(result), menubar); + submenuitem = qck_create_menu_item(NULL, NULL, _("Go to address..."), + G_CALLBACK(mcb_edition_goto), bar); + add_accelerator_to_menu_item(submenuitem, "<Ctrl>G", accgroup); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_separator(); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_item(ref, "mnu_edit_follow_ref", _("Follow the reference"), + G_CALLBACK(mcb_edition_follow_ref), bar); + add_accelerator_to_menu_item(submenuitem, "Return", accgroup); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_item(ref, "mnu_edit_list_xrefs", _("List all references leading to..."), + G_CALLBACK(mcb_edition_list_xrefs), bar); + add_accelerator_to_menu_item(submenuitem, "X", accgroup); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_separator(); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + submenuitem = qck_create_menu_item(NULL, NULL, _("Bookmarks"), NULL, NULL); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); @@ -82,13 +111,6 @@ GtkWidget *build_menu_edition(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *b add_accelerator_to_menu_item(deepmenuitem, "<Ctrl>D", accgroup); gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(NULL, NULL, _("Go to address..."), - G_CALLBACK(mcb_edition_goto), bar); - add_accelerator_to_menu_item(submenuitem, "<Ctrl>G", accgroup); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); return result; @@ -100,6 +122,171 @@ GtkWidget *build_menu_edition(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *b * Paramètres : menuitem = élément de menu sélectionné. * * bar = barre de menu parente. * * * +* Description : Réagit avec le menu "Edition -> Aller à l'adresse...". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_edition_goto(GtkMenuItem *menuitem, GMenuBar *bar) +{ + GObject *ref; /* Espace de référencements */ + GtkWidget *dialog; /* Boîte de dialogue à montrer */ + vmpa2t *addr; /* Adresse de destination */ + GtkViewPanel *vpanel; /* Afficheur effectif de code */ + + ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar)); + dialog = create_goto_dialog(GTK_WINDOW(ref)); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) + { + addr = get_address_from_goto_dialog(dialog); + + vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(bar)); + gtk_view_panel_scroll_to_address(vpanel, addr, SPT_CENTER); + + delete_vmpa(addr); + + } + + gtk_widget_destroy(dialog); + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* bar = barre de menu parente. * +* * +* Description : Réagit avec le menu "Edition -> Suivre la référence". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_edition_follow_ref(GtkMenuItem *menuitem, GMenuBar *bar) +{ + GtkViewPanel *vpanel; /* Afficheur effectif de code */ + GBufferLine *line; /* Ligne de position courante */ + GBufferSegment *segment; /* Segment actif s'il existe */ + GObject *creator; /* Créateur à l'orgine du seg. */ + virt_t virt; /* Adresse virtuelle */ + vmpa2t addr; /* Adresse de destination */ + + vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(bar)); + + if (gtk_view_panel_get_position(vpanel, &line, &segment)) + { + if (segment != NULL) + creator = g_buffer_segment_get_creator(segment); + else + creator = NULL; + + if (creator != NULL) + { + /** + * On fait le pari de reposer uniquement sur des adresses virtuelles ! + * A changer dans un futur ? + */ + + virt = VMPA_NO_VIRTUAL; + + if (G_IS_TARGET_OPERAND(creator)) + virt = g_target_operand_get_addr(G_TARGET_OPERAND(creator)); + + else if (G_IS_IMM_OPERAND(creator)) + { + if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(creator), &virt)) + virt = VMPA_NO_VIRTUAL; + } + + if (virt != VMPA_NO_VIRTUAL) + { + init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + gtk_view_panel_scroll_to_address(vpanel, &addr, SPT_CENTER); + } + + g_object_unref(creator); + + } + + if (segment != NULL) g_object_unref(G_OBJECT(segment)); + g_object_unref(G_OBJECT(line)); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* bar = barre de menu parente. * +* * +* Description : Réagit avec le menu "Edition -> Lister toutes les réfs...". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_edition_list_xrefs(GtkMenuItem *menuitem, GMenuBar *bar) +{ + GtkViewPanel *vpanel; /* Afficheur effectif de code */ + GBufferLine *line; /* Ligne de position courante */ + const mrange_t *range; /* Couverture en mémoire */ + GLoadedBinary *binary; /* Représentation binaire */ + GArchInstruction *list; /* Ensemble des instructions */ + GArchInstruction *instr; /* Point de croisements */ + GObject *ref; /* Espace de référencements */ + GtkWidget *dialog; /* Boîte de dialogue à montrer */ + vmpa2t *addr; /* Adresse de destination */ + + vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(bar)); + + if (gtk_view_panel_get_position(vpanel, &line, NULL)) + { + range = g_buffer_line_get_range(line); + + binary = g_editor_item_get_current_binary(G_EDITOR_ITEM(bar)); + list = g_loaded_binary_get_instructions(binary); + + instr = g_arch_instruction_find_by_range(list, range); + + ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar)); + + dialog = create_gotox_dialog_for_cross_references(GTK_WINDOW(ref), binary, instr, true); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) + { + addr = get_address_from_gotox_dialog(dialog); + + gtk_view_panel_scroll_to_address(vpanel, addr, SPT_CENTER); + + delete_vmpa(addr); + + } + + gtk_widget_destroy(dialog); + + g_object_unref(G_OBJECT(line)); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* bar = barre de menu parente. * +* * * Description : Réagit avec le menu "Edition -> Signets -> Basculer...". * * * * Retour : - * @@ -192,42 +379,3 @@ static void mcb_edition_bookmarks_toggle(GtkMenuItem *menuitem, GMenuBar *bar) g_object_unref(G_OBJECT(collec)); } - - -/****************************************************************************** -* * -* Paramètres : menuitem = élément de menu sélectionné. * -* bar = barre de menu parente. * -* * -* Description : Réagit avec le menu "Edition -> Aller à l'adresse...". * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void mcb_edition_goto(GtkMenuItem *menuitem, GMenuBar *bar) -{ - GObject *ref; /* Espace de référencements */ - GtkWidget *dialog; /* Boîte de dialogue à montrer */ - vmpa2t *addr; /* Adresse de destination */ - GtkViewPanel *vpanel; /* Afficheur effectif de code */ - - ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar)); - dialog = create_goto_dialog(GTK_WINDOW(ref)); - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) - { - addr = get_address_from_goto_dialog(dialog); - - vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(bar)); - gtk_view_panel_scroll_to_address(vpanel, addr, SPT_CENTER); - - delete_vmpa(addr); - - } - - gtk_widget_destroy(dialog); - -} diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c index 77ff7cd..cc69e0d 100644 --- a/src/gui/menus/menubar.c +++ b/src/gui/menus/menubar.c @@ -72,6 +72,9 @@ static void g_menu_bar_dispose(GMenuBar *); /* Procède à la libération totale de la mémoire. */ static void g_menu_bar_finalize(GMenuBar *); +/* Lance une actualisation liée à une modification du cheptel. */ +static void manage_view_in_menu_bar(GMenuBar *, GtkViewPanel *, bool); + /* Lance une actualisation du fait d'un changement de vue. */ static void update_menu_bar_for_view(GMenuBar *, GtkViewPanel *); @@ -108,6 +111,7 @@ static void g_menu_bar_class_init(GMenuBarClass *klass) editem = G_EDITOR_ITEM_CLASS(klass); + editem->manage_view = (manage_item_view_fc)manage_view_in_menu_bar; editem->update_view = (update_item_view_fc)update_menu_bar_for_view; editem->update_project = (update_project_fc)update_menu_bar_for_project; @@ -247,6 +251,73 @@ GEditorItem *g_menu_bar_new(GObject *ref, GtkAccelGroup *accgroup) /****************************************************************************** * * +* Paramètres : bar = barre de menus à actualiser. * +* view = nouveau panneau d'affichage nouveau. * +* created = fait état d'une création ou d'une destruction. * +* * +* Description : Lance une actualisation liée à une modification du cheptel. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void manage_view_in_menu_bar(GMenuBar *bar, GtkViewPanel *view, bool created) +{ + + gboolean view_got_focus(GtkWidget *widget, GtkDirectionType dir, GObject *ref) + { + GtkWidget *item; + + item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_follow_ref")); + + gtk_widget_set_sensitive(item, TRUE); + + item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_list_xrefs")); + + gtk_widget_set_sensitive(item, TRUE); + + return FALSE; + + } + + gboolean view_lost_focus(GtkWidget *widget, GtkDirectionType dir, GObject *ref) + { + GtkWidget *item; + + item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_follow_ref")); + + gtk_widget_set_sensitive(item, FALSE); + + item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_list_xrefs")); + + gtk_widget_set_sensitive(item, FALSE); + + return FALSE; + + } + + + if (created) + { + g_signal_connect(view, "focus-in-event", G_CALLBACK(view_got_focus), G_EDITOR_ITEM(bar)->ref); + g_signal_connect(view, "focus-out-event", G_CALLBACK(view_lost_focus), G_EDITOR_ITEM(bar)->ref); + } + else + { + g_signal_handlers_disconnect_by_func(view, G_CALLBACK(view_got_focus), G_EDITOR_ITEM(bar)->ref); + g_signal_handlers_disconnect_by_func(view, G_CALLBACK(view_lost_focus), G_EDITOR_ITEM(bar)->ref); + } + + + // update_menu_view_for_view(bar->view, view, bar); + +} + + +/****************************************************************************** +* * * Paramètres : bar = barre de menus à actualiser. * * view = nouveau panneau d'affichage actif. * * * |