summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-03-08 19:30:52 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-03-08 19:30:52 (GMT)
commit68bb7efaf61e4f5ca2f2cffce84995ffd667c4cc (patch)
tree9b6a6f63ee20b08d8c2ac35849ee051d61787447 /src/gui
parentdc9e68505c4cc7ad208e63dbc7d0e0e8f582d0d9 (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.h4
-rw-r--r--src/gui/editem.c31
-rw-r--r--src/gui/editem.h3
-rw-r--r--src/gui/menus/binary.c2
-rw-r--r--src/gui/menus/edition.c246
-rw-r--r--src/gui/menus/menubar.c71
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. *
* *