From f6eb49749d627de7d556139a392f73f0ca2862e8 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 31 Jan 2018 23:50:42 +0100
Subject: Provided the current active object in display panels.

---
 ChangeLog                        | 12 +++++++
 src/gtkext/gtkbufferdisplay.c    | 34 ++++++++++++++++++
 src/gtkext/gtkdisplaypanel-int.h |  5 ++-
 src/gtkext/gtkdisplaypanel.c     | 70 ++++++++++++++++---------------------
 src/gtkext/gtkdisplaypanel.h     |  6 ++--
 src/gui/menus/edition.c          | 75 +++++++++++++++++-----------------------
 src/gui/menus/menubar.c          | 15 ++------
 7 files changed, 117 insertions(+), 100 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7995646..bcff8ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 18-01-31  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/gtkext/gtkbufferdisplay.c:
+	* src/gtkext/gtkdisplaypanel-int.h:
+	* src/gtkext/gtkdisplaypanel.c:
+	* src/gtkext/gtkdisplaypanel.h:
+	Provide the current active object in display panels.
+
+	* src/gui/menus/edition.c:
+	* src/gui/menus/menubar.c:
+	Update code.
+
+18-01-31  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/analysis/db/server.c:
 	* src/main.c:
 	Avoid to pollute the configuration directory with old UNIX family sockets.
diff --git a/src/gtkext/gtkbufferdisplay.c b/src/gtkext/gtkbufferdisplay.c
index 3548b3e..d941ff2 100644
--- a/src/gtkext/gtkbufferdisplay.c
+++ b/src/gtkext/gtkbufferdisplay.c
@@ -73,6 +73,9 @@ static const vmpa2t *gtk_buffer_display_get_caret_location(const GtkBufferDispla
 /* Indique la position d'affichage d'une adresse donnée. */
 static bool gtk_buffer_display_get_address_coordinates(const GtkBufferDisplay *, const vmpa2t *, gint *, gint *, ScrollPositionTweak);
 
+/* Fournit l'élément actif lié à la position courante. */
+GObject *gtk_buffer_display_get_active_object(const GtkBufferDisplay *);
+
 /* Place en cache un rendu destiné à l'aperçu graphique rapide. */
 static void gtk_buffer_display_cache_glance(GtkBufferDisplay *, cairo_t *, const GtkAllocation *, double);
 
@@ -142,6 +145,7 @@ static void gtk_buffer_display_class_init(GtkBufferDisplayClass *class)
     panel_class->adjust = (adjust_scroll_value_fc)gtk_buffer_display_adjust_scroll_value;
     panel_class->get_caret_loc = (get_caret_location_fc)gtk_buffer_display_get_caret_location;
     panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_display_get_address_coordinates;
+    panel_class->get_active = (get_active_object_fc)gtk_buffer_display_get_active_object;
     panel_class->move_caret_to = (move_caret_to_fc)_gtk_buffer_display_move_caret_to;
     panel_class->cache_glance = (cache_glance_fc)gtk_buffer_display_cache_glance;
 
@@ -706,6 +710,36 @@ static bool gtk_buffer_display_get_address_coordinates(const GtkBufferDisplay *d
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : display = composant GTK à consulter.                         *
+*                                                                             *
+*  Description : Fournit l'élément actif lié à la position courante.          *
+*                                                                             *
+*  Retour      : Objet actif courant ou NULL si aucun.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GObject *gtk_buffer_display_get_active_object(const GtkBufferDisplay *display)
+{
+    GObject *result;                        /* Trouvaille à retourner      */
+
+    /* Si aucune position n'est définie... */
+    if (is_invalid_vmpa(&display->caret_addr))
+        result = NULL;
+
+    else
+        result = g_buffer_view_find_creator(display->view,
+                                            display->caret.x, display->caret.y,
+                                            GTK_DISPLAY_PANEL(display)->display_options);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : display = composant GTK à manipuler.                         *
 *                cairo   = assistant pour la création de rendus.              *
 *                area    = taille de la surface réduite à disposition.        *
diff --git a/src/gtkext/gtkdisplaypanel-int.h b/src/gtkext/gtkdisplaypanel-int.h
index 4425427..106663f 100644
--- a/src/gtkext/gtkdisplaypanel-int.h
+++ b/src/gtkext/gtkdisplaypanel-int.h
@@ -54,6 +54,9 @@ typedef const vmpa2t * (* get_caret_location_fc) (const GtkDisplayPanel *);
 /* Indique la position d'affichage d'une adresse donnée. */
 typedef bool (* get_addr_coordinates_fc) (const GtkDisplayPanel *, const vmpa2t *, gint *, gint *, ScrollPositionTweak);
 
+/* Fournit l'élément actif lié à la position courante. */
+typedef GObject * (* get_active_object_fc) (const GtkDisplayPanel *);
+
 /* Fournit des éléments liés à la position courante dans la vue. */
 typedef bool (* get_view_position_fc) (const GtkDisplayPanel *, GBufferLine **, GObject **);
 
@@ -95,7 +98,7 @@ struct _GtkDisplayPanelClass
     define_address_fc define;               /* Centrage sur une partie     */
     get_caret_location_fc get_caret_loc;    /* Adresse du curseur          */
     get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */
-    get_view_position_fc get_position;      /* Indications sur la position */
+    get_active_object_fc get_active;        /* Infos sur l'objet actif     */
     move_caret_to_fc move_caret_to;         /* Déplacement du curseur      */
     cache_glance_fc cache_glance;           /* Cache de la mignature       */
 
diff --git a/src/gtkext/gtkdisplaypanel.c b/src/gtkext/gtkdisplaypanel.c
index 989ca85..31b3b58 100644
--- a/src/gtkext/gtkdisplaypanel.c
+++ b/src/gtkext/gtkdisplaypanel.c
@@ -892,6 +892,36 @@ const vmpa2t *gtk_display_panel_get_caret_location(const GtkDisplayPanel *panel)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : panel = composant GTK à consulter.                           *
+*                                                                             *
+*  Description : Fournit l'élément actif lié à la position courante.          *
+*                                                                             *
+*  Retour      : Objet actif courant ou NULL si aucun.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GObject *gtk_display_panel_get_active_object(const GtkDisplayPanel *panel)
+{
+    GObject *result;                        /* Trouvaille à retourner      */
+
+    if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_active == NULL)
+        result = NULL;
+
+    else
+        result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_active(panel);
+
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : panel = composant GTK à manipuler.                           *
 *                addr  = adresse à présenter à l'écran.                       *
 *                tweak = adaptation finale à effectuer.                       *
@@ -994,46 +1024,6 @@ void gtk_display_panel_request_move(GtkDisplayPanel *panel, const vmpa2t *addr)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : panel   = composant GTK à consulter.                         *
-*                line    = ligne de tampon où se trouve le curseur. [OUT]     *
-*                segment = eventuel segment de ligne actif. [OUT]             *
-*                                                                             *
-*  Description : Fournit des éléments liés à la position courante dans la vue.*
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool gtk_display_panel_get_position(const GtkDisplayPanel *panel, GBufferLine **line, GObject **creator)
-{
-    bool result;                            /* Bilan de l'opération        */
-
-    *line = NULL;
-    if (creator != NULL) *creator = NULL;
-
-    if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_position == NULL)
-        return false;
-
-    result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->get_position(panel, line, creator);
-
-    if (result)
-    {
-        g_object_ref(G_OBJECT(*line));
-
-        if (creator != NULL && *creator != NULL)
-            g_object_ref(G_OBJECT(*creator));
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : panel = composant GTK à consulter.                           *
 *                event = informations liées à l'événement.                    *
 *                                                                             *
diff --git a/src/gtkext/gtkdisplaypanel.h b/src/gtkext/gtkdisplaypanel.h
index 7d4c824..5b6de36 100644
--- a/src/gtkext/gtkdisplaypanel.h
+++ b/src/gtkext/gtkdisplaypanel.h
@@ -78,6 +78,9 @@ typedef enum _ScrollPositionTweak
 /* Indique la position courante du curseur. */
 const vmpa2t *gtk_display_panel_get_caret_location(const GtkDisplayPanel *);
 
+/* Fournit l'élément actif lié à la position courante. */
+GObject *gtk_display_panel_get_active_object(const GtkDisplayPanel *);
+
 /* S'assure qu'une adresse donnée est visible à l'écran. */
 void _gtk_display_panel_scroll_to_address(GtkDisplayPanel *, const vmpa2t *, ScrollPositionTweak, bool);
 
@@ -88,9 +91,6 @@ void _gtk_display_panel_scroll_to_address(GtkDisplayPanel *, const vmpa2t *, Scr
 /* Demande à qui veut répondre un déplacement du curseur. */
 void gtk_display_panel_request_move(GtkDisplayPanel *, const vmpa2t *);
 
-/* Fournit des éléments liés à la position courante dans la vue. */
-bool gtk_display_panel_get_position(const GtkDisplayPanel *, GBufferLine **, GObject **);
-
 
 
 #endif  /* _GTKEXT_DISPLAYPANEL_H */
diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c
index 848d04c..08745b6 100644
--- a/src/gui/menus/edition.c
+++ b/src/gui/menus/edition.c
@@ -239,26 +239,21 @@ GtkWidget *build_menu_edition(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *b
 
 void update_access_in_menu_edition(GObject *ref, GtkDisplayPanel *panel, const vmpa2t *addr)
 {
-    bool state;                             /* Etat principal à considérer */
-    gboolean access;                        /* Accès à déterminer          */
-    GBufferLine *line;                      /* Ligne de position courante  */
     GObject *creator;                       /* Créateur à l'orgine du seg. */
+    gboolean access;                        /* Accès à déterminer          */
     GtkWidget *item;                        /* Elément de menu à traiter   */
 
     /* Préliminaire */
 
     if (panel == NULL || addr == NULL)
-    {
-        state = false;
-        line = NULL;
         creator = NULL;
-    }
+
     else
-        state = gtk_display_panel_get_position(panel, &line, &creator);
+        creator = gtk_display_panel_get_active_object(panel);
 
     /* Bascule des opérandes numériques */
 
-    access = (state && G_IS_IMM_OPERAND(creator));
+    access = (G_IS_IMM_OPERAND(creator));
 
     item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_switch_hex"));
     gtk_widget_set_sensitive(item, access);
@@ -277,12 +272,12 @@ void update_access_in_menu_edition(GObject *ref, GtkDisplayPanel *panel, const v
 
     /* Suivi de cibles */
 
-    access = (state && (G_IS_TARGET_OPERAND(creator) || G_IS_IMM_OPERAND(creator)));
+    access = ((G_IS_TARGET_OPERAND(creator) || G_IS_IMM_OPERAND(creator)));
 
     item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_follow_ref"));
     gtk_widget_set_sensitive(item, access);
 
-    access = state;
+    access = (addr != NULL);;
 
     item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_list_xrefs"));
     gtk_widget_set_sensitive(item, access);
@@ -290,7 +285,6 @@ void update_access_in_menu_edition(GObject *ref, GtkDisplayPanel *panel, const v
     /* Nettoyage et sortie finale */
 
     if (creator != NULL) g_object_unref(G_OBJECT(creator));
-    if (line != NULL) g_object_unref(G_OBJECT(line));
 
 }
 
@@ -355,29 +349,28 @@ static void mcb_edition_switch_numeric_operand(GtkMenuItem *menuitem, gpointer u
 {
     ImmOperandDisplay display;              /* Type de basculement         */
     GLoadedPanel *panel;                    /* Afficheur effectif de code  */
-    GBufferLine *line;                      /* Ligne de position courante  */
     GObject *creator;                       /* Créateur à l'orgine du seg. */
-    GDbSwitcher *switcher;                  /* Bascule à mettre en place   */
-    const mrange_t *range;                  /* Emplacement de la ligne     */
+    const vmpa2t *addr;                     /* Position courante           */
     GLoadedBinary *binary;                  /* Binaire en cours d'étude    */
     GArchProcessor *proc;                   /* Propriétaire d'instructions */
     GArchInstruction *instr;                /* Instruction liée à la ligne */
+    GDbSwitcher *switcher;                  /* Bascule à mettre en place   */
 
     display = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(menuitem), "kind_of_switch"));
 
     panel = get_current_view();
 
-    if (GTK_IS_DISPLAY_PANEL(panel)
-        && gtk_display_panel_get_position(GTK_DISPLAY_PANEL(panel), &line, &creator))
+    if (GTK_IS_DISPLAY_PANEL(panel))
     {
+        creator = gtk_display_panel_get_active_object(GTK_DISPLAY_PANEL(panel));
         assert(G_IS_IMM_OPERAND(creator));
 
-        range = g_buffer_line_get_range(line);
+        addr = gtk_display_panel_get_caret_location(GTK_DISPLAY_PANEL(panel));
 
         binary = get_current_binary();
         proc = g_loaded_binary_get_processor(binary);
 
-        instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
+        instr = g_arch_processor_find_instr_by_address(proc, addr);
         assert(instr != NULL);
 
         switcher = g_db_switcher_new(instr, G_IMM_OPERAND(creator), display);
@@ -390,7 +383,6 @@ static void mcb_edition_switch_numeric_operand(GtkMenuItem *menuitem, gpointer u
         g_object_unref(G_OBJECT(binary));
 
         g_object_unref(creator);
-        g_object_unref(G_OBJECT(line));
 
     }
 
@@ -434,7 +426,6 @@ static void mcb_edition_go_back(GtkMenuItem *menuitem, GMenuBar *bar)
 static void mcb_edition_follow_ref(GtkMenuItem *menuitem, gpointer unused)
 {
     GLoadedPanel *panel;                    /* Afficheur effectif de code  */
-    GBufferLine *line;                      /* Ligne de position courante  */
     GObject *creator;                       /* Créateur à l'orgine du seg. */
     bool defined;                           /* Adresse définie ?           */
     vmpa2t addr;                            /* Adresse de destination      */
@@ -442,9 +433,9 @@ static void mcb_edition_follow_ref(GtkMenuItem *menuitem, gpointer unused)
 
     panel = get_current_view();
 
-    if (GTK_IS_DISPLAY_PANEL(panel)
-        && gtk_display_panel_get_position(GTK_DISPLAY_PANEL(panel), &line, &creator))
+    if (GTK_IS_DISPLAY_PANEL(panel))
     {
+        creator = gtk_display_panel_get_active_object(GTK_DISPLAY_PANEL(panel));
         assert(creator != NULL);
 
         defined = false;
@@ -468,7 +459,6 @@ static void mcb_edition_follow_ref(GtkMenuItem *menuitem, gpointer unused)
             gtk_display_panel_request_move(GTK_DISPLAY_PANEL(panel), &addr);
 
         g_object_unref(creator);
-        g_object_unref(G_OBJECT(line));
 
     }
 
@@ -493,21 +483,19 @@ static void mcb_edition_follow_ref(GtkMenuItem *menuitem, gpointer unused)
 static void mcb_edition_list_xrefs(GtkMenuItem *menuitem, GMenuBar *bar)
 {
     GLoadedPanel *panel;                    /* Afficheur effectif de code  */
-    GBufferLine *line;                      /* Ligne de position courante  */
-    const mrange_t *range;                  /* Couverture en mémoire       */
+    const vmpa2t *addr;                     /* Position courante           */
     GLoadedBinary *binary;                  /* Représentation binaire      */
     GArchProcessor *proc;                   /* Processeur de l'architecture*/
     GArchInstruction *instr;                /* Point de croisements        */
     GObject *ref;                           /* Espace de référencements    */
     GtkWidget *dialog;                      /* Boîte de dialogue à montrer */
-    vmpa2t *addr;                           /* Adresse de destination      */
+    vmpa2t *dest;                           /* Adresse de destination      */
 
     panel = get_current_view();
 
-    if (GTK_IS_DISPLAY_PANEL(panel)
-        && gtk_display_panel_get_position(GTK_DISPLAY_PANEL(panel), &line, NULL))
+    if (GTK_IS_DISPLAY_PANEL(panel))
     {
-        range = g_buffer_line_get_range(line);
+        addr = gtk_display_panel_get_caret_location(GTK_DISPLAY_PANEL(panel));
 
         binary = get_current_binary();
         proc = g_loaded_binary_get_processor(binary);
@@ -520,32 +508,33 @@ static void mcb_edition_list_xrefs(GtkMenuItem *menuitem, GMenuBar *bar)
          * Il faut ainsi être plus souple, et se baser sur l'espace couvert par
          * une ligne mais sur l'adresse uniquement.
          */
-        instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
+        instr = g_arch_processor_find_instr_by_address(proc, addr);
 
-        ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar));
+        if (instr != NULL)
+        {
+            ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar));
 
-        dialog = create_gotox_dialog_for_cross_references(GTK_WINDOW(ref), binary, instr, true);
+            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);
+            if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
+            {
+                dest = get_address_from_gotox_dialog(dialog);
 
-            gtk_display_panel_request_move(GTK_DISPLAY_PANEL(panel), addr);
+                gtk_display_panel_request_move(GTK_DISPLAY_PANEL(panel), dest);
 
-            delete_vmpa(addr);
+                delete_vmpa(dest);
 
-        }
+            }
 
-        gtk_widget_destroy(dialog);
+            gtk_widget_destroy(dialog);
 
-        if (instr != NULL)
             g_object_unref(G_OBJECT(instr));
 
+        }
+
         g_object_unref(G_OBJECT(proc));
         g_object_unref(G_OBJECT(binary));
 
-        g_object_unref(G_OBJECT(line));
-
     }
 
     g_object_unref(G_OBJECT(panel));
diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c
index 32a8f20..989d964 100644
--- a/src/gui/menus/menubar.c
+++ b/src/gui/menus/menubar.c
@@ -308,21 +308,13 @@ static void update_menu_bar_for_view(GMenuBar *bar, GtkDisplayPanel *panel)
 
 static void notify_focus_change_for_menu_bar(GMenuBar *bar, GtkDisplayPanel *panel)
 {
-    GBufferLine *line;                      /* Ligne de position courante  */
-    const mrange_t *range;                  /* Couverture en mémoire       */
     const vmpa2t *addr;                     /* Position courante           */
     GEditorItem *item;                      /* Autre version de l'élément  */
 
-    if (panel != NULL && gtk_display_panel_get_position(panel, &line, NULL))
-    {
-        range = g_buffer_line_get_range(line);
-        addr = get_mrange_addr(range);
-    }
+    if (panel != NULL)
+        addr = gtk_display_panel_get_caret_location(panel);
     else
-    {
-        line = NULL;
         addr = NULL;
-    }
 
     item = G_EDITOR_ITEM(bar);
 
@@ -332,9 +324,6 @@ static void notify_focus_change_for_menu_bar(GMenuBar *bar, GtkDisplayPanel *pan
 
     update_access_in_menu_binary(item->ref, panel);
 
-    if (line != NULL)
-        g_object_unref(G_OBJECT(line));
-
 }
 
 
-- 
cgit v0.11.2-87-g4458