From a61984e52bfd35e19408b7cbdb11e3419f635829 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 2 Feb 2016 07:25:28 +0100
Subject: Given a chance to the caret to get defined before getting drawn.

---
 ChangeLog                   |  18 +++++++
 src/analysis/project.c      |   2 +
 src/gtkext/gtkbufferview.c  |   4 +-
 src/gtkext/gtkstatusstack.c | 121 ++++++++++++++++++++++++++++++++++----------
 src/gtkext/gtkstatusstack.h |   2 +
 src/gui/menus/edition.c     |   6 ++-
 src/gui/status.c            |  19 ++++---
 7 files changed, 136 insertions(+), 36 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d6d3e0b..5fc748f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+16-02-02  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/project.c:
+	Write a note for later.
+
+	* src/gtkext/gtkbufferview.c:
+	Give a chance to the caret to get defined before getting drawn.
+
+	* src/gtkext/gtkstatusstack.c:
+	* src/gtkext/gtkstatusstack.h:
+	Provide a method to reset the information linked to a position.
+
+	* src/gui/menus/edition.c:
+	Take empty positions into account. Fix a bug.
+
+	* src/gui/status.c:
+	Take empty positions into account.
+
 16-02-01  Cyrille Bagard <nocbos@gmail.com>
 
 	* .gitignore:
diff --git a/src/analysis/project.c b/src/analysis/project.c
index 94b01a3..1befb8f 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -575,6 +575,8 @@ void g_study_project_add_loaded_binary(GLoadedBinary *binary, GStudyProject *pro
 
         format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
 
+        /* TODO : se rabattre sur des symboles identifiés comme point d'entrée si on ne trouve pas les principaux ci dessous */
+
         if (g_binary_format_find_symbol_by_label(format, "main", &symbol)
             || g_binary_format_find_symbol_by_label(format, "_start", &symbol)
             || g_binary_format_find_symbol_by_label(format, "entry_point", &symbol))
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
index 0d11de2..0e3beeb 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferview.c
@@ -296,8 +296,6 @@ static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *
 
     view = GTK_BUFFER_VIEW(widget);
 
-    gtk_widget_grab_focus(widget);
-
     real_x = event->x;
     real_y = event->y;
     gtk_view_panel_compute_real_coord(GTK_VIEW_PANEL(view), &real_x, &real_y);
@@ -319,6 +317,8 @@ static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *
     else
         _gtk_buffer_view_move_caret_to(view, real_x, real_y);
 
+    gtk_widget_grab_focus(widget);
+
     return FALSE;
 
 }
diff --git a/src/gtkext/gtkstatusstack.c b/src/gtkext/gtkstatusstack.c
index 148dd03..dbadb22 100644
--- a/src/gtkext/gtkstatusstack.c
+++ b/src/gtkext/gtkstatusstack.c
@@ -41,7 +41,7 @@
 
 
 /* Navigation au sein d'assemblage */
-typedef struct _assembly_info assembly_info;
+typedef union _assembly_info assembly_info;
 
 
 /* Abstration d'une gestion de barre de statut (instance) */
@@ -83,19 +83,25 @@ static void gtk_status_stack_switch(GtkStatusStack *, GtkWidget *);
 
 
 /* Navigation au sein d'assemblage */
-struct _assembly_info
+union _assembly_info
 {
-    mrange_t current;                       /* Emplacement correspondant   */
+    bool reset;                             /* Réinitialisation            */
 
-    char *segment;                          /* Segment d'appartenance      */
+    struct
+    {
+        mrange_t current;                   /* Emplacement correspondant   */
+
+        char *segment;                      /* Segment d'appartenance      */
+
+        VMPA_BUFFER(phys);                  /* Localisation physique       */
+        VMPA_BUFFER(virt);                  /* Localisation virtuelle      */
 
-    VMPA_BUFFER(phys);                      /* Localisation physique       */
-    VMPA_BUFFER(virt);                      /* Localisation virtuelle      */
+        char *symbol;                       /* Eventuel symbole concerné   */
 
-    char *symbol;                           /* Eventuel symbole concerné   */
+        const char *encoding;               /* Encodage de l'instruction   */
+        phys_t size;                        /* Taille de l'instruction     */
 
-    const char *encoding;                   /* Encodage de l'instruction   */
-    phys_t size;                            /* Taille de l'instruction     */
+    };
 
 };
 
@@ -167,6 +173,8 @@ static void gtk_status_stack_init(GtkStatusStack *stack)
     stack->asm_status = build_assembly_status_stack(stack);
     stack->asm_info = (assembly_info *)calloc(1, sizeof(assembly_info));
 
+    reset_assembly_info(stack->asm_info);
+
 }
 
 
@@ -285,6 +293,8 @@ static void gtk_status_stack_switch(GtkStatusStack *stack, GtkWidget *next)
 
 static void reset_assembly_info(assembly_info *info)
 {
+    info->reset = true;
+
     if (info->segment != NULL)
     {
         free(info->segment);
@@ -552,6 +562,31 @@ void gtk_status_stack_update_current_instruction(GtkStatusStack *stack, const GL
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : stack  = barre de statut à actualiser.                       *
+*                                                                             *
+*  Description : Réinitialise les informations associées une position.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void gtk_status_stack_reset_current_instruction(GtkStatusStack *stack)
+{
+    assembly_info *info;                    /* Informations à constituer   */
+
+    info = stack->asm_info;
+
+    reset_assembly_info(info);
+
+    gtk_status_stack_show_current_instruction(stack);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : stack = pile de statuts à manipuler.                         *
 *                                                                             *
 *  Description : S'assure de l'affichage à jour de la partie "assemblage".    *
@@ -577,35 +612,67 @@ static void gtk_status_stack_show_current_instruction(GtkStatusStack *stack)
 
     /* Première partie : navigation */
 
-    label = GTK_LABEL(g_object_get_data(ref, "segment"));
-    gtk_label_set_text(label, info->segment);
+    if (info->reset)
+    {
+        label = GTK_LABEL(g_object_get_data(ref, "segment"));
+        gtk_label_set_text(label, NULL);
+
+        label = GTK_LABEL(g_object_get_data(ref, "phys"));
+        gtk_label_set_text(label, NULL);
+
+        label = GTK_LABEL(g_object_get_data(ref, "virt"));
+        gtk_label_set_text(label, NULL);
 
-    snprintf(raw_pos, sizeof(raw_pos), "phys: %s", info->phys);
+        label = GTK_LABEL(g_object_get_data(ref, "offset"));
+        gtk_label_set_text(label, NULL);
 
-    label = GTK_LABEL(g_object_get_data(ref, "phys"));
-    gtk_label_set_text(label, raw_pos);
+    }
+    else
+    {
+        label = GTK_LABEL(g_object_get_data(ref, "segment"));
+        gtk_label_set_text(label, info->segment);
 
-    snprintf(raw_pos, sizeof(raw_pos), "virt: %s", info->virt);
+        snprintf(raw_pos, sizeof(raw_pos), "phys: %s", info->phys);
 
-    label = GTK_LABEL(g_object_get_data(ref, "virt"));
-    gtk_label_set_text(label, raw_pos);
+        label = GTK_LABEL(g_object_get_data(ref, "phys"));
+        gtk_label_set_text(label, raw_pos);
 
-    label = GTK_LABEL(g_object_get_data(ref, "offset"));
-    gtk_label_set_text(label, info->symbol != NULL ? info->symbol : "");
+        snprintf(raw_pos, sizeof(raw_pos), "virt: %s", info->virt);
+
+        label = GTK_LABEL(g_object_get_data(ref, "virt"));
+        gtk_label_set_text(label, raw_pos);
+
+        label = GTK_LABEL(g_object_get_data(ref, "offset"));
+        gtk_label_set_text(label, info->symbol != NULL ? info->symbol : "");
+
+    }
 
     /* Seconde partie : architecture */
 
-    label = GTK_LABEL(g_object_get_data(ref, "arch"));
-    gtk_label_set_text(label, info->encoding);
+    if (info->reset)
+    {
+        label = GTK_LABEL(g_object_get_data(ref, "arch"));
+        gtk_label_set_text(label, NULL);
+
+        label = GTK_LABEL(g_object_get_data(ref, "size"));
+        gtk_label_set_text(label, NULL);
 
-    if (info->size > 1)
-        asprintf(&content, "%" PRIu64 " %s", (uint64_t)info->size, _("bytes"));
+    }
     else
-        asprintf(&content, "%" PRIu64 " %s", (uint64_t)info->size, _("byte"));
+    {
+        label = GTK_LABEL(g_object_get_data(ref, "arch"));
+        gtk_label_set_text(label, info->encoding);
+
+        if (info->size > 1)
+            asprintf(&content, "%" PRIu64 " %s", (uint64_t)info->size, _("bytes"));
+        else
+            asprintf(&content, "%" PRIu64 " %s", (uint64_t)info->size, _("byte"));
 
-    label = GTK_LABEL(g_object_get_data(ref, "size"));
-    gtk_label_set_text(label, content);
+        label = GTK_LABEL(g_object_get_data(ref, "size"));
+        gtk_label_set_text(label, content);
 
-    free(content);
+        free(content);
+
+    }
 
 }
diff --git a/src/gtkext/gtkstatusstack.h b/src/gtkext/gtkstatusstack.h
index 9d25c8f..8e93708 100644
--- a/src/gtkext/gtkstatusstack.h
+++ b/src/gtkext/gtkstatusstack.h
@@ -71,6 +71,8 @@ GtkWidget *gtk_status_stack_new(void);
 /* Actualise les informations liées une position d'assemblage. */
 void gtk_status_stack_update_current_instruction(GtkStatusStack *, const GLoadedBinary *, const GArchInstruction *);
 
+/* Réinitialise les informations associées une position. */
+void gtk_status_stack_reset_current_instruction(GtkStatusStack *);
 
 
 
diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c
index c742098..2cc22b2 100644
--- a/src/gui/menus/edition.c
+++ b/src/gui/menus/edition.c
@@ -252,8 +252,12 @@ void update_access_in_menu_edition(GObject *ref, GtkBufferView *view, const vmpa
 
     /* Préliminaire */
 
-    if (view == NULL)
+    if (view == NULL || addr == NULL)
+    {
         state = false;
+        line = NULL;
+        segment = NULL;
+    }
     else
         state = gtk_view_panel_get_position(GTK_VIEW_PANEL(view), &line, &segment);
 
diff --git a/src/gui/status.c b/src/gui/status.c
index 8db4f3a..a3daded 100644
--- a/src/gui/status.c
+++ b/src/gui/status.c
@@ -254,14 +254,21 @@ static void focus_address_in_status_info(GStatusInfo *info, GLoadedBinary *binar
     GArchInstruction *instr;                /* Instruction présente        */
     GEditorItem *item;                      /* Autre version de l'élément  */
 
-    proc = g_loaded_binary_get_processor(binary);
+    if (addr == NULL)
+        gtk_status_stack_reset_current_instruction(GTK_STATUS_STACK(item->widget));
 
-    instr = _g_arch_processor_find_instr_by_address(proc, addr, true);
-    assert(instr != NULL);
+    else
+    {
+        proc = g_loaded_binary_get_processor(binary);
 
-    item = G_EDITOR_ITEM(info);
-    gtk_status_stack_update_current_instruction(GTK_STATUS_STACK(item->widget), binary, instr);
+        instr = _g_arch_processor_find_instr_by_address(proc, addr, true);
+        assert(instr != NULL);
+
+        item = G_EDITOR_ITEM(info);
+        gtk_status_stack_update_current_instruction(GTK_STATUS_STACK(item->widget), binary, instr);
+
+        g_object_unref(G_OBJECT(proc));
 
-    g_object_unref(G_OBJECT(proc));
+    }
 
 }
-- 
cgit v0.11.2-87-g4458