summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog25
-rw-r--r--configure.ac2
-rw-r--r--src/arch/archbase.h4
-rw-r--r--src/editor.c15
-rw-r--r--src/glibext/gbufferline.c65
-rw-r--r--src/glibext/gbufferline.h5
-rw-r--r--src/glibext/gbuffersegment.c51
-rw-r--r--src/glibext/gbuffersegment.h3
-rw-r--r--src/glibext/gcodebuffer.c180
-rw-r--r--src/glibext/gcodebuffer.h8
-rw-r--r--src/gtkext/gtkbufferview-int.h9
-rw-r--r--src/gtkext/gtkbufferview.c313
-rw-r--r--src/gtkext/gtkextstatusbar.c12
-rw-r--r--src/gtkext/gtkextstatusbar.h6
-rw-r--r--src/gtkext/gtkviewpanel.c1
-rw-r--r--src/gui/Makefile.am3
-rw-r--r--src/gui/status.c266
-rw-r--r--src/gui/status.h56
18 files changed, 988 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index 1b39630..cdc3e57 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+13-06-02 Cyrille Bagard <nocbos@gmail.com>
+
+ * configure.ac:
+ * src/arch/archbase.h:
+ * src/editor.c:
+ * src/glibext/gbufferline.c:
+ * src/glibext/gbufferline.h:
+ * src/glibext/gbuffersegment.c:
+ * src/glibext/gbuffersegment.h:
+ * src/glibext/gcodebuffer.c:
+ * src/glibext/gcodebuffer.h:
+ * src/gtkext/gtkbufferview.c:
+ * src/gtkext/gtkbufferview-int.h:
+ * src/gtkext/gtkextstatusbar.c:
+ * src/gtkext/gtkextstatusbar.h:
+ * src/gtkext/gtkviewpanel.c:
+ Save some progress about edition views.
+
+ * src/gui/Makefile.am:
+ Add the 'status.[ch]' files to libgui_la_SOURCES.
+
+ * src/gui/status.c:
+ * src/gui/status.h:
+ New entries: put the status bar in a better place.
+
13-05-26 Cyrille Bagard <nocbos@gmail.com>
* src/gtkext/graph/layout.c:
diff --git a/configure.ac b/configure.ac
index 51aa8e3..0ada63a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -234,7 +234,7 @@ AC_SUBST(LIBGRAPH_LIBS)
AC_CONFIG_FILES([stamp-h po/Makefile.in], [echo timestamp > stamp-h])
-AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64,UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT\nVOID:OBJECT,OBJECT" > src/glibext/chrysamarshal.list])
+AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:UINT64,UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT\nVOID:OBJECT,OBJECT" > src/glibext/chrysamarshal.list])
AC_CONFIG_FILES([Makefile
pixmaps/Makefile
diff --git a/src/arch/archbase.h b/src/arch/archbase.h
index ee12674..1169c16 100644
--- a/src/arch/archbase.h
+++ b/src/arch/archbase.h
@@ -38,6 +38,10 @@ typedef uint64_t vmpa_t;
#define VMPA_MAX 0xffffffffffffffffull
+#define VMPA_INVALID 0xffffffffffffffffull
+
+#define VMPA_FMT "0x%llx"
+#define VMPA_FMT_LONG "0x%08llx"
#define VMPA_MAX_SIZE 19
diff --git a/src/editor.c b/src/editor.c
index c533a64..6386858 100644
--- a/src/editor.c
+++ b/src/editor.c
@@ -31,8 +31,8 @@
#include "project.h"
#include "gtkext/easygtk.h"
#include "gtkext/gtkdockstation.h"
-#include "gtkext/gtkextstatusbar.h"
#include "gtkext/support.h"
+#include "gui/status.h"
#include "gui/menus/menubar.h"
#include "gui/panels/panel.h"
#include "gui/tb/source.h"
@@ -137,13 +137,13 @@ GtkWidget *create_editor(void)
GtkWidget *toolbar; /* Barre d'outils */
GtkWidget *vbox1;
- GtkWidget *statusbar;
+ GtkAccelGroup *accgroup;
+ GtkWidget *widget; /* Composant à intégrer */
- GtkAccelGroup *accgroup;
@@ -206,12 +206,13 @@ GtkWidget *create_editor(void)
- statusbar = gtk_extended_status_bar_new();
- g_object_set_data(ref, "statusbar", statusbar);
+ /* Barre de statut générale */
- gtk_widget_show(statusbar);
+ editem = g_status_info_new(ref);
+ register_editor_item(editem);
- gtk_box_pack_start(GTK_BOX(vbox1), statusbar, FALSE, FALSE, 0);
+ widget = g_editor_item_get_widget(editem);
+ gtk_box_pack_start(GTK_BOX(vbox1), widget, FALSE, FALSE, 0);
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index 95d6126..18f8a2a 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -61,7 +61,7 @@ static gint get_column_width(buffer_line_column *);
static void add_segment_to_column(buffer_line_column *, GBufferSegment *);
/* Donne le segment d'une colonne présent à une abscisse donnée. */
-static GBufferSegment *get_segment_at(const buffer_line_column *, gint);
+static GBufferSegment *get_segment_at(const buffer_line_column *, gint *, bool);
/* Met en surbrillance des segments similaires. */
GSList *highlight_all_same_segments(const buffer_line_column *, GSList *, const GBufferSegment *);
@@ -194,7 +194,8 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se
/******************************************************************************
* *
* Paramètres : column = colonne de ligne de texte à consulter. *
-* x = position de recherche à ajuster. *
+* x = position de recherche à ajuster. [OUT] *
+* force = accepte les segments en bordure au pire. *
* *
* Description : Donne le segment d'une colonne présent à une abscisse donnée.*
* *
@@ -204,7 +205,7 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se
* *
******************************************************************************/
-static GBufferSegment *get_segment_at(const buffer_line_column *column, gint x)
+static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, bool force)
{
GBufferSegment *result; /* Trouvaille à retourner */
size_t i; /* Boucle de parcours */
@@ -216,11 +217,11 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint x)
{
width = g_buffer_segment_get_width(column->segments[i]);
- if (width <= x)
- x -= width;
+ if (width > *x || ((i + 1) == column->count && force))
+ result = column->segments[i];
else
- result = column->segments[i];
+ *x -= width;
}
@@ -552,7 +553,8 @@ void g_buffer_line_add_segment(GBufferLine *line, BufferLineColumn index, GBuffe
* *
* Paramètres : line = ligne à venir consulter. *
* max_widths = largeurs de colonne à respecter. *
-* x = position à la colonne visée par la procédure. *
+* x = position à la colonne visée. [OUT] *
+* force = accepte les segments en bordure au pire. *
* *
* Description : Donne le segment présent à une abscisse donnée. *
* *
@@ -562,7 +564,7 @@ void g_buffer_line_add_segment(GBufferLine *line, BufferLineColumn index, GBuffe
* *
******************************************************************************/
-GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint max_widths[BLC_COUNT], gint x)
+GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint max_widths[BLC_COUNT], gint *x, bool force)
{
GBufferSegment *result; /* Trouvaille à retourner */
BufferLineColumn i; /* Boucle de parcours */
@@ -570,11 +572,22 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint
result = NULL;
for (i = BLC_ADDRESS; i < BLC_COUNT; i++)
- if (x < max_widths[i]) break;
- else x -= (max_widths[i] + COL_MARGIN);
+ {
+ /* FIXME : addr/code */
+
+ if (*x < max_widths[i]) break;
+ else *x -= (max_widths[i] + COL_MARGIN);
+
+ }
+
+ if (i == BLC_COUNT && force)
+ {
+ i = BLC_COUNT - 1;
+ *x += (max_widths[i] + COL_MARGIN);
+ }
if (i < BLC_COUNT)
- result = get_segment_at(&line->columns[i], x);
+ result = get_segment_at(&line->columns[i], x, force);
return result;
@@ -583,6 +596,36 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint
/******************************************************************************
* *
+* Paramètres : line = ligne à venir consulter. *
+* caret = position du curseur à faire évoluer. *
+* ctrl = indique la demande d'un parcours rapide. *
+* dir = direction du parcours. *
+* addr = indique si les positions doivent être affichées. *
+* code = indique si le code binaire doit être affiché. *
+* *
+* Description : Déplace le curseur au sein d'une vue de tampon. *
+* *
+* Retour : true si un déplacement a été effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_buffer_line_move_caret(const GBufferLine *line, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool addr, bool code)
+{
+
+ caret->x += (dir == GDK_SCROLL_RIGHT ? 10 : -10);
+
+ return true;
+
+
+ return false;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : line = ligne à venir consulter. *
* list = liste de segments identiques à constituer. *
* ref = segment de référence à comparer avec tous les autres. *
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index 6eb4e27..2a46b5a 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -129,8 +129,11 @@ vmpa_t g_buffer_line_get_address(const GBufferLine *);
/* Ajoute un fragment de texte à une colonne de ligne. */
void g_buffer_line_add_segment(GBufferLine *, BufferLineColumn, GBufferSegment *) __attribute__ ((deprecated));
+/* Déplace le curseur au sein d'une vue de tampon. */
+bool g_buffer_line_move_caret(const GBufferLine *, GdkRectangle *, bool, GdkScrollDirection, bool, bool);
+
/* Donne le segment présent à une abscisse donnée. */
-GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], gint);
+GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], gint *, bool);
/* Met en surbrillance des segments similaires. */
GSList *g_buffer_line_highlight_all_same_segments(const GBufferLine *, GSList *, const GBufferSegment *);
diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c
index 861c7cb..031075c 100644
--- a/src/glibext/gbuffersegment.c
+++ b/src/glibext/gbuffersegment.c
@@ -478,6 +478,57 @@ gint g_buffer_segment_get_width(const GBufferSegment *segment)
/******************************************************************************
* *
+* Paramètres : segment = fragment de texte à consulter. *
+* x = position horizontale au niveau du segment. *
+* *
+* Description : Fournit la position idéale pour un marqueur. *
+* *
+* Retour : Position dans le segment donné. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+gint g_buffer_segment_get_caret_position(const GBufferSegment *segment, gint x)
+{
+ gint result; /* Position à retourner */
+ gint width; /* Largeur du segment */
+ gint char_width; /* Largeur de police fixe */
+
+ width = g_buffer_segment_get_width(segment);
+
+ printf("(seg) x=%d width=%d\n", x, width);
+
+ if (x <= 0)
+ result = 0;
+
+ else if (x >= width)
+ result = width;
+
+ else
+ {
+ if (strlen(segment->text) != segment->glyphs->num_glyphs)
+ {
+
+ printf("STOP ::: %d vs %d\n", strlen(segment->text), segment->glyphs->num_glyphs);
+ exit(0);
+ }
+
+ char_width = width / segment->glyphs->num_glyphs;
+
+ result = (x / char_width) * char_width;
+ if ((x % char_width) > (char_width / 2))
+ result += char_width;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : segment = fragment de texte à manipuler. *
* *
* Description : (Re)charge les couleurs à partir de la liste d'attributs. *
diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h
index 96011bb..bc0d512 100644
--- a/src/glibext/gbuffersegment.h
+++ b/src/glibext/gbuffersegment.h
@@ -86,6 +86,9 @@ const char *g_buffer_segment_get_text(const GBufferSegment *);
/* Fournit la quantité de pixels requise pour l'impression. */
gint g_buffer_segment_get_width(const GBufferSegment *);
+/* Fournit la position idéale pour un marqueur. */
+gint g_buffer_segment_get_caret_position(const GBufferSegment *, gint);
+
/* (Re)charge les couleurs à partir de la liste d'attributs. */
void g_buffer_segment_cache_colors(GBufferSegment *);
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index e81966e..920b17c 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -123,7 +123,7 @@ static void g_code_buffer_class_init(GCodeBufferClass *);
static void g_code_buffer_init(GCodeBuffer *);
/* Convertit une adresse en indice de ligne. */
-static size_t _g_code_buffer_get_index_from_address(GCodeBuffer *, vmpa_t, bool);
+static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *, vmpa_t, bool);
/* Convertit une adresse en indice de ligne. */
static size_t g_code_buffer_get_index_from_address(GCodeBuffer *, vmpa_t, bool);
@@ -411,7 +411,7 @@ GCodeBuffer *g_code_buffer_new(BufferLineColumn main)
* *
******************************************************************************/
-static size_t _g_code_buffer_get_index_from_address(GCodeBuffer *buffer, vmpa_t addr, bool first)
+static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, vmpa_t addr, bool first)
{
size_t result; /* Indice à retourner */
@@ -1053,6 +1053,172 @@ void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool a
/******************************************************************************
* *
+* Paramètres : view = vue de tampon à mettre à jour. *
+* x = abscisse de la zone principale à traiter. *
+* y = ordonnée de la zone principale à traiter. *
+* caret = position du curseur à construire. [OUT] *
+* *
+* Description : Calcule la position idéale de curseur pour un point donné. *
+* *
+* Retour : Adresse si une a pu être déterminée, VMPA_INVALID sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+vmpa_t g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, GdkRectangle *caret)
+{
+ size_t index; /* Indice de la ligne trouvée */
+ GBufferLine *line; /* Ligne sous le pointeur */
+ gint tmp_x; /* Copie de travail modifiable */
+ GBufferSegment *segment; /* Segment visé par le pointeur*/
+ size_t first; /* Première ligne intégrée */
+
+ line = g_buffer_view_find_line_at(view, y, &index);
+ if (line == NULL) return VMPA_INVALID;
+
+ tmp_x = x;
+
+ tmp_x -= view->left_text;
+ if (tmp_x < 0) return VMPA_INVALID;
+
+ segment = g_buffer_line_get_segment_at(line, view->max_widths, &tmp_x, true);
+ if (segment == NULL) printf("no segment\n");
+ if (segment == NULL) return VMPA_INVALID;
+
+ caret->x = (x - tmp_x) + g_buffer_segment_get_caret_position(segment, tmp_x);
+
+ first = g_code_buffer_get_index_from_address(view->buffer, view->start, true);
+ caret->y = (index - first) * view->line_height;
+
+ caret->width = 2;
+ caret->height = view->line_height;
+
+ return g_buffer_line_get_address(line);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = vue de tampon à mettre à jour. *
+* caret = position du curseur à faire évoluer. *
+* ctrl = indique la demande d'un parcours rapide. *
+* dir = direction du parcours. *
+* addr = indique si les positions doivent être affichées. *
+* code = indique si le code binaire doit être affiché. *
+* *
+* Description : Déplace le curseur au sein d'une vue de tampon. *
+* *
+* Retour : Adresse si une a pu être déterminée, VMPA_INVALID sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool addr, bool code)
+{
+ bool result; /* Actualisation à renvoyer */
+ bool computed; /* Récursivité pris en compte */
+ gint lheight; /* Hauteur d'une ligne */
+ gint left_pos; /* Retour à la ligne */
+ gint right_pos; /* Position d'extrème droite */
+ BufferLineColumn i; /* Boucle de parcours */
+ size_t first; /* Première ligne intégrée */
+ size_t last; /* Dernière ligne intégrée */
+ GBufferLine *line; /* Ligne sous le pointeur */
+
+ result = VMPA_INVALID;
+ computed = false;
+
+ switch (dir)
+ {
+ case GDK_SCROLL_UP:
+ case GDK_SCROLL_DOWN:
+ lheight = g_buffer_view_get_line_height(view);
+ break;
+ case GDK_SCROLL_LEFT:
+ case GDK_SCROLL_RIGHT:
+ left_pos = view->left_text;
+ if (addr) left_pos += view->max_widths[BLC_ADDRESS] + COL_MARGIN;
+ if (code) left_pos += view->max_widths[BLC_BINARY] + COL_MARGIN;
+ right_pos = left_pos;
+ for (i = BLC_ASSEMBLY_HEAD; i < BLC_COUNT; i++)
+ right_pos += view->max_widths[i] + COL_MARGIN;
+ break;
+ }
+
+ first = g_code_buffer_get_index_from_address(view->buffer, view->start, true);
+ last = g_code_buffer_get_index_from_address(view->buffer, view->end, false);
+
+ switch (dir)
+ {
+ case GDK_SCROLL_UP:
+ result = (caret->y >= (first * lheight));
+ if (result)
+ caret->y -= lheight;
+ break;
+
+ case GDK_SCROLL_DOWN:
+ result = ((caret->y + lheight) < (last * lheight));
+ if (result)
+ caret->y += lheight;
+ break;
+
+ case GDK_SCROLL_LEFT:
+ line = g_buffer_view_find_line_at(view, caret->y, NULL);
+ if (line == NULL) break;
+
+ result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_LEFT, addr, code);
+
+ if (caret->x < left_pos)
+ {
+ caret->x = right_pos;
+
+ result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_UP, addr, code);
+
+ if (result == VMPA_INVALID)
+ caret->x = left_pos;
+ else
+ computed = true;
+
+ }
+
+ break;
+
+ case GDK_SCROLL_RIGHT:
+ line = g_buffer_view_find_line_at(view, caret->y, NULL);
+ if (line == NULL) break;
+
+ result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_RIGHT, addr, code);
+
+ if (!result)
+ {
+ caret->x = left_pos;
+
+ result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_DOWN, addr, code);
+
+ if (result == VMPA_INVALID)
+ caret->x = right_pos;
+ else
+ computed = true;
+
+ }
+
+ break;
+
+ }
+
+ if (result && !computed)
+ result = g_buffer_view_compute_caret(view, caret->x, caret->y, caret);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = vue de tampon à mettre à jour. *
* *
* Description : Supprime toute mise en évidence de segments. *
@@ -1110,7 +1276,7 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y)
size_t last; /* Dernière ligne intégrée */
size_t i; /* Boucle de parcours */
- line = g_buffer_view_find_line_at(view, y);
+ line = g_buffer_view_find_line_at(view, y, NULL);
if (line == NULL) return;
@@ -1127,7 +1293,7 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y)
x -= view->left_text;
if (x < 0) return;
- segment = g_buffer_line_get_segment_at(line, view->max_widths, x);
+ segment = g_buffer_line_get_segment_at(line, view->max_widths, &x, false);
printf(" ... seg @%d ? %p\n", x, segment);
if (segment == NULL) return;
@@ -1259,6 +1425,7 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd
* *
* Paramètres : view = visualisation à consulter. *
* y = ordonnée comprise dans la ligne recherchée. *
+* idx = indice de la ligne trouvée ou NULL. [OUT] *
* *
* Description : Fournit la ligne présente à une ordonnée donnée. *
* *
@@ -1268,7 +1435,7 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd
* *
******************************************************************************/
-GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y)
+GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
{
gint lheight; /* Hauteur d'une ligne */
size_t index; /* Indice attendu */
@@ -1276,6 +1443,9 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y)
lheight = g_buffer_view_get_line_height(view);
index = y / lheight;
+ if (idx != NULL)
+ *idx = index;
+
return (index < view->buffer->used ? view->buffer->lines[index] : NULL);
}
diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h
index fc4bc66..4ae5c58 100644
--- a/src/glibext/gcodebuffer.h
+++ b/src/glibext/gcodebuffer.h
@@ -124,6 +124,12 @@ gint g_buffer_view_get_line_height(GBufferView *);
/* Fournit les dimensions requises par une visualisation. */
void g_buffer_view_get_size(GBufferView *, gint *, gint *, bool, bool);
+/* Calcule la position idéale de curseur pour un point donné. */
+vmpa_t g_buffer_view_compute_caret(GBufferView *, gint, gint, GdkRectangle *);
+
+/* Déplace le curseur au sein d'une vue de tampon. */
+vmpa_t g_buffer_view_move_caret(GBufferView *, GdkRectangle *, bool, GdkScrollDirection, bool, bool);
+
/* Supprime toute mise en évidence de segments. */
bool g_buffer_view_unhighlight_segments(GBufferView *);
@@ -137,7 +143,7 @@ void g_buffer_view_define_extra_drawing(GBufferView *, buffer_line_draw_fc, void
void g_buffer_view_draw(const GBufferView *, const GdkEventExpose *, GdkGC *, gint, gint, bool, bool);
/* Fournit la ligne présente à une ordonnée donnée. */
-GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint);
+GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *);
/* Indique la position d'affichage d'une adresse donnée. */
bool g_buffer_view_get_address_coordinates(GBufferView *, vmpa_t, gint *, gint *);
diff --git a/src/gtkext/gtkbufferview-int.h b/src/gtkext/gtkbufferview-int.h
index 5d5a407..f57e78a 100644
--- a/src/gtkext/gtkbufferview-int.h
+++ b/src/gtkext/gtkbufferview-int.h
@@ -44,6 +44,11 @@ struct _GtkBufferView
gint left_margin; /* Marge gauche + espace */
gint left_text; /* Début d'impression du code */
+ GdkRectangle caret; /* Emplacement du curseur */
+ vmpa_t caret_addr; /* Position mémoire du curseur */
+ guint caret_timer; /* Identifiant du chronomètre */
+ bool show_caret; /* Bascule entre les affichages*/
+
};
/* Composant d'affichage de tampon de lignes (classe) */
@@ -51,6 +56,10 @@ struct _GtkBufferViewClass
{
GtkViewPanelClass parent; /* A laisser en premier */
+ /* Signaux */
+
+ void (* caret_moved) (GtkBufferView *, vmpa_t);
+
};
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
index 62a861a..6556eb8 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferview.c
@@ -24,6 +24,12 @@
#include "gtkbufferview-int.h"
+#include <gdk/gdkkeysyms.h>
+
+
+#include "../glibext/chrysamarshal.h"
+
+
/* -------------------------- INTERACTION DIRECTE AVEC GTK -------------------------- */
@@ -34,6 +40,12 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *);
/* Procède à l'initialisation de l'afficheur de tampons. */
static void gtk_buffer_view_init(GtkBufferView *);
+/* Intègre le focus dans le rendu du composant. */
+static gboolean gtk_buffer_view_focus(GtkWidget *, GtkDirectionType);
+
+/* Assure la gestion des clics de souris sur le composant. */
+static gboolean gtk_buffer_view_button_press(GtkWidget *, GdkEventButton *);
+
/* Fournit la taille de composant requise pour un plein rendu. */
static void gtk_buffer_view_size_request(GtkWidget *, GtkRequisition *);
@@ -43,6 +55,9 @@ static void gtk_buffer_view_size_allocate(GtkWidget *, GtkAllocation *);
/* Met à jour l'affichage de la visualisation de code buffer. */
static gboolean gtk_buffer_view_expose(GtkWidget *, GdkEventExpose *);
+/* Prend en compte une frappe de touche sur le composant. */
+static gboolean gtk_buffer_view_key_press(GtkWidget *, GdkEventKey *);
+
/* Indique la position d'affichage d'une adresse donnée. */
static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, vmpa_t, gint *, gint *);
@@ -54,6 +69,17 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *, cairo_t *, const GtkAl
+/* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */
+
+
+/* Redémarre l'affichage du curseur à l'emplacement courant. */
+static void restart_caret_blinking(GtkBufferView *);
+
+/* Bascule et relance l'affichage du curseur. */
+static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *);
+
+
+
/* ---------------------------------------------------------------------------------- */
/* INTERACTION DIRECTE AVEC GTK */
/* ---------------------------------------------------------------------------------- */
@@ -81,9 +107,20 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *class)
widget_class = GTK_WIDGET_CLASS(class);
+ widget_class->focus = gtk_buffer_view_focus;
+ widget_class->button_press_event = gtk_buffer_view_button_press;
widget_class->size_request = gtk_buffer_view_size_request;
widget_class->size_allocate = gtk_buffer_view_size_allocate;
widget_class->expose_event = gtk_buffer_view_expose;
+ widget_class->key_press_event = gtk_buffer_view_key_press;
+
+ g_signal_new("caret-moved",
+ GTK_TYPE_BUFFER_VIEW,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GtkBufferViewClass, caret_moved),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__UINT64,
+ G_TYPE_NONE, 1, G_TYPE_UINT64);
}
@@ -110,6 +147,108 @@ static void gtk_buffer_view_init(GtkBufferView *view)
viewpanel->scroll = (scroll_fc)gtk_buffer_view_scroll;
viewpanel->cache_glance = (cache_glance_fc)gtk_buffer_view_cache_glance;
+ view->caret.x = 10;
+ view->caret.y = 10;
+ view->caret.width = 100;
+ view->caret.height = 100;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = composant GTK visé par l'opération. *
+* dir = sens de l'opération : perte ou gain de focus. *
+* *
+* Description : Intègre le focus dans le rendu du composant. *
+* *
+* Retour : FALSE pour poursuivre la propagation de l'événement. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean gtk_buffer_view_focus(GtkWidget *widget, GtkDirectionType direction)
+{
+ GtkBufferView *view; /* Autre version du composant */
+ gboolean has_focus; /* Etat courant */
+
+ view = GTK_BUFFER_VIEW(widget);
+ has_focus = gtk_widget_is_focus(widget);
+
+ if (has_focus)
+ restart_caret_blinking(view);
+
+ else if (view->caret_timer != 0)
+ {
+ g_source_remove(view->caret_timer);
+ view->caret_timer = 0;
+
+ view->show_caret = true;
+ gtk_buffer_view_refresh_caret(view);
+
+ }
+
+ return TRUE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = composant GTK visé par l'opération. *
+* event = informations liées à l'événement. *
+* *
+* Description : Assure la gestion des clics de souris sur le composant. *
+* *
+* Retour : FALSE pour poursuivre la propagation de l'événement. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *event)
+{
+ GtkBufferView *view; /* Autre version du composant */
+ gint real_x; /* Abscisse absolue réelle */
+ gint real_y; /* Ordonnée absolue réelle */
+ vmpa_t addr; /* Position mémoire associée */
+ GdkRectangle new; /* Nouvel emplacement calculé */
+
+ view = GTK_BUFFER_VIEW(widget);
+
+ gtk_widget_grab_focus(widget);
+
+ real_x = event->x;
+ real_y = event->y;
+ gtk_buffer_view_compute_real_coord(view, &real_x, &real_y);
+
+ printf(" mouse :: (%g ; %g) -> (%d ; %d)\n",
+ event->x, event->y,
+ real_x, real_y);
+
+ addr = g_buffer_view_compute_caret(view->buffer_view, real_x, real_y, &new);
+
+ if (addr != VMPA_INVALID)
+ {
+ //gtk_buffer_view_compute_fake_coord(view, &view->caret.x, &view->caret.y);
+
+
+ printf(" mouse --old-- :: (%d ; %d)\n",
+ view->caret.x, view->caret.y);
+
+ gtk_widget_queue_draw_area(GTK_WIDGET(view), view->caret.x, view->caret.y,
+ view->caret.width, view->caret.height);
+
+ view->caret = new;
+ view->caret_addr = addr;
+
+ restart_caret_blinking(view);
+
+ }
+
+ return FALSE;
+
}
@@ -341,6 +480,53 @@ static gboolean gtk_buffer_view_expose(GtkWidget *widget, GdkEventExpose *event)
/******************************************************************************
* *
+* Paramètres : widget = composant visé par l'opération. *
+* event = informations liées à l'événement. *
+* *
+* Description : Prend en compte une frappe de touche sur le composant. *
+* *
+* Retour : FALSE pour poursuivre la propagation de l'événement. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event)
+{
+ gboolean result; /* Suites à renvoyer */
+ bool ctrl; /* Statut de la touche Contrôle*/
+
+ result = FALSE;
+
+ ctrl = (event->state & GDK_CONTROL_MASK);
+
+ switch (event->keyval)
+ {
+ case GDK_KEY_Left:
+ result = TRUE;
+ break;
+ case GDK_KEY_Up:
+ result = TRUE;
+ break;
+ case GDK_KEY_Right:
+ result = TRUE;
+ break;
+ case GDK_KEY_Down:
+ result = TRUE;
+ break;
+ }
+
+
+ printf("ctrl ? %d -- keyval = %d -->> %d\n", ctrl, event->keyval, result);
+
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = composant GTK à consulter. *
* addr = adresse à présenter à l'écran. *
* x = position horizontale au sein du composant. [OUT] *
@@ -480,3 +666,130 @@ GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *view)
return view->buffer_view;
}
+
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONVERSIONS DE COORDONNEES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : view = composant GTK à consulter. *
+* x = abscisse à ajuster. [OUT] *
+* x = ordonnée à ajuster. [OUT] *
+* *
+* Description : Transcrit les coordonnées absolues en coordonnées à l'écran. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void gtk_buffer_view_compute_relative_coords(GtkBufferView *view, gint *x, gint *y)
+{
+ if (x != NULL && GTK_VIEW_PANEL(view)->hadjustment != NULL)
+ *x -= gtk_adjustment_get_value(GTK_VIEW_PANEL(view)->hadjustment);
+
+ if (y != NULL && GTK_VIEW_PANEL(view)->vadjustment != NULL)
+ *y -= gtk_adjustment_get_value(GTK_VIEW_PANEL(view)->vadjustment);
+
+}
+
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* ANIMATION DU CURSEUR */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : view = composant GTK à manipuler. *
+* *
+* Description : Redémarre l'affichage du curseur à l'emplacement courant. *
+* *
+* Retour : TRUE pour poursuivre les basculements automatiques. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void restart_caret_blinking(GtkBufferView *view)
+{
+ if (view->caret_addr == VMPA_INVALID)
+ return;
+
+ if (view->caret_timer != 0)
+ g_source_remove(view->caret_timer);
+
+ view->caret_timer = g_timeout_add_seconds(1, (GSourceFunc)gtk_buffer_view_refresh_caret, view);
+
+ view->show_caret = false;
+ gtk_buffer_view_refresh_caret(view);
+
+ g_signal_emit_by_name(view, "caret-moved", view->caret_addr);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = composant GTK à manipuler. *
+* *
+* Description : Bascule et relance l'affichage du curseur. *
+* *
+* Retour : TRUE pour poursuivre les basculements automatiques. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *view)
+{
+ GtkWidget *widget; /* Autre version du composant */
+ GdkRectangle area; /* Région adaptée à traiter */
+ GdkDrawable *drawable; /* Surface de dessin */
+ GtkStyle *style; /* Style associé au composant */
+ GtkStateType state; /* Etat du composant */
+ GdkGC *gc; /* Contexte graphique */
+
+ widget = GTK_WIDGET(view);
+
+ area = view->caret;
+ gtk_buffer_view_compute_relative_coords(view, &area.x, &area.y);
+
+ /* Réinitialisation de la surface */
+ if (view->show_caret)
+ {
+ view->show_caret = false;
+ gtk_widget_queue_draw_area(widget, area.x, area.y, area.width, area.height);
+ }
+
+ /* Dessin */
+ else
+ {
+ view->show_caret = true;
+
+ drawable = GDK_DRAWABLE(widget->window);
+ state = gtk_widget_get_state(widget);
+ style = gtk_widget_get_style(widget);
+
+ gc = gdk_gc_new(drawable);
+ gdk_gc_set_foreground(gc, &style->text[state]);
+
+ gdk_draw_rectangle(drawable, gc, TRUE, area.x, area.y, area.width, area.height);
+
+ gdk_gc_destroy(gc);
+
+ }
+
+ return TRUE;
+
+}
diff --git a/src/gtkext/gtkextstatusbar.c b/src/gtkext/gtkextstatusbar.c
index dfb08d7..47fc154 100644
--- a/src/gtkext/gtkextstatusbar.c
+++ b/src/gtkext/gtkextstatusbar.c
@@ -124,7 +124,7 @@ guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, g
{
guint result; /* Identifiant à retourner */
- gdk_threads_enter();
+ //gdk_threads_enter();
result = gtk_statusbar_push(GTK_STATUSBAR(bar), bar->context, message);
@@ -145,8 +145,8 @@ guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, g
}
else gtk_widget_hide(GTK_WIDGET(bar->progress));
- gdk_flush();
- gdk_threads_leave();
+ //gdk_flush();
+ //gdk_threads_leave();
return result;
@@ -210,7 +210,7 @@ void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, guint id)
{
size_t i; /* Boucle de parcours */
- gdk_threads_enter();
+ //gdk_threads_enter();
gtk_statusbar_remove(GTK_STATUSBAR(bar), bar->context, id);
@@ -234,7 +234,7 @@ void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, guint id)
else
gtk_widget_hide(GTK_WIDGET(bar->progress));
- gdk_flush();
- gdk_threads_leave();
+ //gdk_flush();
+ //gdk_threads_leave();
}
diff --git a/src/gtkext/gtkextstatusbar.h b/src/gtkext/gtkextstatusbar.h
index 4cba821..b5fe210 100644
--- a/src/gtkext/gtkextstatusbar.h
+++ b/src/gtkext/gtkextstatusbar.h
@@ -34,9 +34,9 @@ G_BEGIN_DECLS
#define GTK_TYPE_EXT_STATUS_BAR (gtk_extended_status_bar_get_type())
-#define GTK_EXT_STATUS_BAR(obj) GTK_CHECK_CAST(obj, gtk_extended_status_bar_get_type (), GtkExtStatusBar)
-#define GTK_EXT_STATUS_BAR_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, gtk_extended_status_bar_get_type(), GtkExtStatusBarClass)
-#define GTK_IS_EXT_STATUS_BAR(obj) GTK_CHECK_TYPE(obj, gtk_extended_status_bar_get_type())
+#define GTK_EXT_STATUS_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, gtk_extended_status_bar_get_type (), GtkExtStatusBar))
+#define GTK_IS_EXT_STATUS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, gtk_extended_status_bar_get_type()))
+#define GTK_EXT_STATUS_BAR_CLASS(klass) (G_LOADED_BINARY_GET_CLASS(klass, gtk_extended_status_bar_get_type(), GtkExtStatusBarClass))
typedef struct _GtkExtStatusBar GtkExtStatusBar;
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index 6d10009..ef1f94d 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -105,6 +105,7 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class)
static void gtk_view_panel_init(GtkViewPanel *panel)
{
gtk_widget_set_has_window(GTK_WIDGET(panel), TRUE);
+ gtk_widget_set_can_focus(GTK_WIDGET(panel), TRUE);
}
diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am
index c0a03f0..2e2bc1c 100644
--- a/src/gui/Makefile.am
+++ b/src/gui/Makefile.am
@@ -3,7 +3,8 @@ noinst_LTLIBRARIES = libgui.la
libgui_la_SOURCES = \
editem-int.h \
- editem.h editem.c
+ editem.h editem.c \
+ status.h status.c
libgui_la_LIBADD = \
menus/libguimenus.la \
diff --git a/src/gui/status.c b/src/gui/status.c
new file mode 100644
index 0000000..16a3ff8
--- /dev/null
+++ b/src/gui/status.c
@@ -0,0 +1,266 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * status.c - affichage d'informations de statut dans la fenêtre principale
+ *
+ * Copyright (C) 2013 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "status.h"
+
+
+#include <string.h>
+
+
+#include <i18n.h>
+
+
+#include "editem-int.h"
+#include "../common/extstr.h"
+#include "../gtkext/gtkbufferview.h"
+#include "../gtkext/gtkblockview.h"
+#include "../gtkext/gtkextstatusbar.h"
+
+
+
+/* Barre de statut de la fenêtre principale (instance) */
+struct _GStatusInfo
+{
+ GEditorItem parent; /* A laisser en premier */
+
+ GObject *caret_instance; /* Dernier émetteur de signaux */
+ guint msg_id; /* Identifiant du dernier msg. */
+
+};
+
+
+/* Barre de statut de la fenêtre principale (classe) */
+struct _GStatusInfoClass
+{
+ GEditorItemClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe de la barre de statut de l'éditeur. */
+static void g_status_info_class_init(GStatusInfoClass *);
+
+/* Initialise une instance de la barre de statut pour l'éditeur. */
+static void g_status_info_init(GStatusInfo *);
+
+/* Lance une actualisation du fait d'un changement de vue. */
+static void update_status_info_for_view(GStatusInfo *, GtkViewPanel *);
+
+/* Imprime la position du parcours courant dans le statut. */
+static void track_caret_address_on_buffer_views(GtkBufferView *, vmpa_t, GStatusInfo *);
+
+
+
+
+/* Indique le type défini pour la barre de statut de la fenêtre principale. */
+G_DEFINE_TYPE(GStatusInfo, g_status_info, G_TYPE_EDITOR_ITEM);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe de la barre de statut de l'éditeur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_status_info_class_init(GStatusInfoClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : bar = instance à initialiser. *
+* *
+* Description : Initialise une instance de la barre de statut pour l'éditeur.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_status_info_init(GStatusInfo *bar)
+{
+ GEditorItem *item; /* Autre version de l'élément */
+
+ item = G_EDITOR_ITEM(bar);
+
+ item->name = "status";
+
+ item->widget = gtk_extended_status_bar_new();
+ gtk_widget_show(item->widget);
+
+ item->update_view = (update_item_view_fc)update_status_info_for_view;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencement global. *
+* *
+* Description : Compose la barre de statut principale. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GEditorItem *g_status_info_new(GObject *ref)
+{
+ GStatusInfo *result; /* Structure à retourner */
+ GEditorItem *item; /* Autre version de l'élément */
+
+ result = g_object_new(G_TYPE_STATUS_INFO, NULL);
+
+ item = G_EDITOR_ITEM(result);
+
+ g_object_ref(ref);
+ item->ref = ref;
+
+ g_object_set_data(ref, "statusbar", item->widget);
+
+ return G_EDITOR_ITEM(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = barre de statut à actualiser. *
+* view = nouveau panneau d'affichage actif. *
+* *
+* Description : Lance une actualisation du fait d'un changement de vue. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void update_status_info_for_view(GStatusInfo *info, GtkViewPanel *view)
+{
+ printf("new view :: %p\n", view);
+
+ //track_caret_address_on_buffer_views
+
+ if (info->caret_instance != NULL)
+ {
+ g_signal_handlers_disconnect_by_func(info->caret_instance,
+ G_CALLBACK(track_caret_address_on_buffer_views),
+ info);
+ g_object_unref(info->caret_instance);
+ }
+
+ if (GTK_IS_BLOCK_VIEW(view))
+ g_signal_connect(view, "caret-moved",
+ G_CALLBACK(track_caret_address_on_buffer_views),
+ info);
+
+ else
+ return;
+
+ info->caret_instance = G_OBJECT(view);
+ g_object_ref(info->caret_instance);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = composant d'affichage parcouru. *
+* addr = nouvelle adresse du curseur courant. *
+* info = barre de statut présentant les informations. *
+* *
+* Description : Imprime la position du parcours courant dans le statut. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void track_caret_address_on_buffer_views(GtkBufferView *view, vmpa_t addr, GStatusInfo *info)
+{
+ GEditorItem *item; /* Autre version de l'élément */
+ char *msg; /* Message à transmettre */
+ char tmp[VMPA_MAX_SIZE]; /* Zone de conversion */
+ GLoadedBinary *binary; /* Binaire courant */
+ GExeFormat *format; /* Format associé au binaire */
+ vmpa_t rel; /* Adresse relative à un symb. */
+ const char *label; /* Désignation d'un symbole */
+
+ item = G_EDITOR_ITEM(info);
+
+ /* Adresse brute */
+
+ msg = strdup(_("Address "));
+
+ snprintf(tmp, VMPA_MAX_SIZE, VMPA_FMT_LONG, addr);
+ msg = stradd(msg, tmp);
+
+ /* Relation avec les symboles */
+
+ binary = G_LOADED_BINARY(g_object_get_data(item->ref, "current_binary"));
+ format = g_loaded_binary_get_format(binary);
+
+ rel = addr;
+
+ if (g_binary_format_resolve_relative_routine(G_BIN_FORMAT(format), &label, &rel))
+ {
+ msg = stradd(msg, _(" at "));
+ msg = stradd(msg, label);
+ msg = stradd(msg, _("+"));
+
+ snprintf(tmp, VMPA_MAX_SIZE, VMPA_FMT, rel);
+ msg = stradd(msg, tmp);
+
+ }
+
+ /* Impression */
+
+ if (info->msg_id > 0)
+ gtk_extended_status_bar_remove(GTK_EXT_STATUS_BAR(item->widget), info->msg_id);
+
+ info->msg_id = gtk_extended_status_bar_push(GTK_EXT_STATUS_BAR(item->widget), msg, FALSE);
+
+
+ printf("---- moved to 0x%08llx\n", addr);
+
+ printf(" MSG '%s'\n", msg);
+
+ //update_menu_project_for_project(bar->project, project, bar);
+
+
+ free(msg);
+
+}
diff --git a/src/gui/status.h b/src/gui/status.h
new file mode 100644
index 0000000..277df4c
--- /dev/null
+++ b/src/gui/status.h
@@ -0,0 +1,56 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * status.h - prototypes pour l'affichage d'informations de statut dans la fenêtre principale
+ *
+ * Copyright (C) 2013 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _GUI_STATUS_H
+#define _GUI_STATUS_H
+
+
+#include "editem.h"
+
+
+
+#define G_TYPE_STATUS_INFO g_status_info_get_type()
+#define G_STATUS_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_status_info_get_type(), GStatusInfo))
+#define G_IS_STATUS_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_status_info_get_type()))
+#define G_STATUS_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_STATUS_INFO, GStatusInfoClass))
+#define G_IS_STATUS_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_STATUS_INFO))
+#define G_STATUS_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_STATUS_INFO, GStatusInfoClass))
+
+
+/* Barre de statut de la fenêtre principale (instance) */
+typedef struct _GStatusInfo GStatusInfo;
+
+/* Barre de statut de la fenêtre principale (classe) */
+typedef struct _GStatusInfoClass GStatusInfoClass;
+
+
+/* Indique le type défini pour la barre de statut de la fenêtre principale. */
+GType g_status_info_get_type(void);
+
+/* Compose la barre de statut principale. */
+GEditorItem *g_status_info_new(GObject *);
+
+
+
+#endif /* _GUI_MENUS_MENUBAR_H */