summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog26
-rw-r--r--plugins/pychrysa/gtkext/viewpanel.c2
-rw-r--r--src/glibext/gcodebuffer.c53
-rw-r--r--src/glibext/gcodebuffer.h2
-rw-r--r--src/gtkext/gtkbufferview.c50
-rw-r--r--src/gtkext/gtkviewpanel-int.h2
-rw-r--r--src/gtkext/gtkviewpanel.c10
-rw-r--r--src/gtkext/gtkviewpanel.h12
-rw-r--r--src/gui/menus/binary.c2
-rw-r--r--src/gui/menus/edition.c2
-rw-r--r--src/gui/panels/bookmarks.c4
-rw-r--r--src/gui/panels/symbols.c2
-rw-r--r--src/gui/tb/portions.c2
-rw-r--r--src/project.c30
14 files changed, 150 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog
index 8eb28e5..6c31b70 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+15-02-25 Cyrille Bagard <nocbos@gmail.com>
+
+ * plugins/pychrysa/gtkext/viewpanel.c:
+ Disable old code.
+
+ * src/glibext/gcodebuffer.c:
+ * src/glibext/gcodebuffer.h:
+ Allow to get coordinates of a line containing code, if possible,
+ for a given address.
+
+ * src/gtkext/gtkbufferview.c:
+ * src/gtkext/gtkviewpanel.c:
+ * src/gtkext/gtkviewpanel.h:
+ * src/gtkext/gtkviewpanel-int.h:
+ Provide tweaks about positions when looking for address coordinates.
+
+ * src/gui/menus/binary.c:
+ * src/gui/menus/edition.c:
+ * src/gui/panels/bookmarks.c:
+ * src/gui/panels/symbols.c:
+ * src/gui/tb/portions.c:
+ Update.
+
+ * src/project.c:
+ Wait a little bit before being abl able to use sizes to compute the position of the entry point.
+
15-02-24 Cyrille Bagard <nocbos@gmail.com>
* src/format/format.c:
diff --git a/plugins/pychrysa/gtkext/viewpanel.c b/plugins/pychrysa/gtkext/viewpanel.c
index d2770c4..f680487 100644
--- a/plugins/pychrysa/gtkext/viewpanel.c
+++ b/plugins/pychrysa/gtkext/viewpanel.c
@@ -116,7 +116,7 @@ static PyObject *py_view_panel_scroll_to_address(PyObject *self, PyObject *args)
ret = PyArg_ParseTuple(args, "K", &addr);
if (!ret) Py_RETURN_NONE;
- gtk_view_panel_scroll_to_address(panel, addr);
+ //gtk_view_panel_scroll_to_address(panel, addr);
Py_RETURN_NONE;
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index afad0f4..4b5378d 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -678,6 +678,9 @@ GBufferLine *g_code_buffer_find_line_by_addr(const GCodeBuffer *buffer, const vm
{
if ((index + 1) == buffer->used) break;
+ /* FIXME : vérifier que l'adresse est toujours celle recherchée ! */
+ /* TODO : passer la recherche de code en option via argument ? */
+
result = buffer->lines[++index];
}
@@ -1756,6 +1759,7 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
* addr = adresse à présenter à l'écran. *
* x = position horizontale au sein du composant. [OUT] *
* y = position verticale au sein du composant. [OUT] *
+* code = s'arrête si possible à une ligne avec code. *
* *
* Description : Indique la position d'affichage d'une adresse donnée. *
* *
@@ -1765,7 +1769,7 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
* *
******************************************************************************/
-bool g_buffer_view_get_address_coordinates(GBufferView *view, const vmpa2t *addr, gint *x, gint *y)
+bool g_buffer_view_get_address_coordinates(GBufferView *view, const vmpa2t *addr, gint *x, gint *y, bool code)
{
bool result; /* Bilan à retourner */
gint lheight; /* Hauteur d'une ligne */
@@ -1784,24 +1788,37 @@ bool g_buffer_view_get_address_coordinates(GBufferView *view, const vmpa2t *addr
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);
- if (view->buffer->used > 0)
- for (i = first; i <= last; i++)
+ for (i = first; i <= last; i++)
+ {
+ /**
+ * Si l'adresse recherchée est plus petite que l'adresse de départ,
+ * on va effectuer un parcours complet pour rien.
+ *
+ * On considère cependant que le seul cas où celà peut arriver
+ * est lorsque que des découpages en blocs sont impliqués.
+ *
+ * Les découpages conduisent alors à la formation de petites zones,
+ * rapides à parcourir.
+ */
+
+ range = g_buffer_line_get_range(view->buffer->lines[i]);
+
+ result = mrange_contains_addr(range, addr);
+ if (result) break;
+
+ *y += lheight;
+
+ }
+
+ if (result && code)
+ for (; i <= last; i++)
{
- /**
- * Si l'adresse recherchée est plus petite que l'adresse de départ,
- * on va effectuer un parcours complet pour rien.
- *
- * On considère cependant que le seul cas où celà peut arriver
- * est lorsque que des découpages en blocs sont impliqués.
- *
- * Les découpages conduisent alors à la formation de petites zones,
- * rapides à parcourir.
- */
-
- range = g_buffer_line_get_range(view->buffer->lines[i]);
-
- result = mrange_contains_addr(range, addr);
- if (result) break;
+ if (g_buffer_line_get_flags(view->buffer->lines[i]) & BLF_HAS_CODE) break;
+
+ if (i == last) break;
+
+ range = g_buffer_line_get_range(view->buffer->lines[i + 1]);
+ if (!mrange_contains_addr(range, addr)) break;
*y += lheight;
diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h
index ddd45db..5fd4e7b 100644
--- a/src/glibext/gcodebuffer.h
+++ b/src/glibext/gcodebuffer.h
@@ -150,7 +150,7 @@ void g_buffer_view_export(const GBufferView *, buffer_export_context *, BufferEx
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 *, const vmpa2t *, gint *, gint *);
+bool g_buffer_view_get_address_coordinates(GBufferView *, const vmpa2t *, gint *, gint *, bool);
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
index f179845..30cf075 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferview.c
@@ -59,7 +59,7 @@ static void gtk_buffer_view_compute_requested_size(GtkBufferView *, gint *, gint
static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *, gint, GtkOrientation, gdouble *, gdouble *);
/* Indique la position d'affichage d'une adresse donnée. */
-static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, const vmpa2t *, gint *, gint *);
+static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, const vmpa2t *, gint *, gint *, ScrollPositionTweak);
/* Place en cache un rendu destiné à l'aperçu graphique rapide. */
static void gtk_buffer_view_cache_glance(GtkBufferView *, cairo_t *, const GtkAllocation *, double);
@@ -474,7 +474,7 @@ static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event)
printf("ctrl ? %d -- keyval = %d -->> %d\n", ctrl, event->keyval, result);
- if (addr != NULL) gtk_view_panel_scroll_to_address(pview, addr);
+ if (addr != NULL) gtk_view_panel_scroll_to_address(pview, addr, SPT_RAW);
printf("\n");
@@ -552,10 +552,11 @@ static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, G
/******************************************************************************
* *
-* Paramètres : view = composant GTK à consulter. *
-* addr = adresse à présenter à l'écran. *
-* x = position horizontale au sein du composant. [OUT] *
-* y = position verticale au sein du composant. [OUT] *
+* Paramètres : view = composant GTK à consulter. *
+* addr = adresse à présenter à l'écran. *
+* x = position horizontale au sein du composant. [OUT] *
+* y = position verticale au sein du composant. [OUT] *
+* tweak = adaptation finale à effectuer. *
* *
* Description : Indique la position d'affichage d'une adresse donnée. *
* *
@@ -565,9 +566,42 @@ static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, G
* *
******************************************************************************/
-static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *view, const vmpa2t *addr, gint *x, gint *y)
+static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *view, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak)
{
- return g_buffer_view_get_address_coordinates(view->buffer_view, addr, x, y);
+ bool result; /* Bilan à remonter */
+ bool need_code; /* Recherche plus raffinée */
+ int height; /* Hauteur allouée */
+
+ need_code = (tweak == SPT_BOTTOM);
+
+ result = g_buffer_view_get_address_coordinates(view->buffer_view, addr, x, y, need_code);
+
+ if (result)
+ {
+ height = gtk_widget_get_allocated_height(GTK_WIDGET(view));
+
+ switch (tweak)
+ {
+ case SPT_RAW:
+ break;
+
+ case SPT_TOP:
+ break;
+
+ case SPT_CENTER:
+ *y -= (height / 2);
+ break;
+
+ case SPT_BOTTOM:
+ *y -= height;
+ *y += g_buffer_view_get_line_height(view->buffer_view);
+ break;
+
+ }
+
+ }
+
+ return result;
}
diff --git a/src/gtkext/gtkviewpanel-int.h b/src/gtkext/gtkviewpanel-int.h
index f33499d..90bd141 100644
--- a/src/gtkext/gtkviewpanel-int.h
+++ b/src/gtkext/gtkviewpanel-int.h
@@ -49,7 +49,7 @@ typedef void (* define_address_fc) (GtkViewPanel *, vmpa_t);
typedef void (* prepare_resize_fc) (GtkViewPanel *);
/* Indique la position d'affichage d'une adresse donnée. */
-typedef bool (* get_addr_coordinates_fc) (const GtkViewPanel *, const vmpa2t *, gint *, gint *);
+typedef bool (* get_addr_coordinates_fc) (const GtkViewPanel *, const vmpa2t *, gint *, gint *, ScrollPositionTweak);
/* Place en cache un rendu destiné à l'aperçu graphique rapide. */
typedef void (* cache_glance_fc) (GtkViewPanel *, cairo_t *, const GtkAllocation *, double);
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index 8e41fa1..40ae038 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -747,7 +747,7 @@ bool gtk_view_panel_contain_address(const GtkViewPanel *panel, vmpa_t addr)
gint dummy_x; /* Abscisse pour l'appel */
gint dummy_y; /* Ordonnée pour l'appel */
- return GTK_VIEW_PANEL_GET_CLASS(panel)->get_coordinates(panel, addr, &dummy_x, &dummy_y);
+ return GTK_VIEW_PANEL_GET_CLASS(panel)->get_coordinates(panel, addr, &dummy_x, &dummy_y, SPT_RAW);
}
@@ -756,6 +756,7 @@ bool gtk_view_panel_contain_address(const GtkViewPanel *panel, vmpa_t addr)
* *
* Paramètres : panel = composant GTK à manipuler. *
* addr = adresse à présenter à l'écran. *
+* tweak = adaptation finale à effectuer. *
* *
* Description : S'assure qu'une adresse donnée est visible à l'écran. *
* *
@@ -765,7 +766,7 @@ bool gtk_view_panel_contain_address(const GtkViewPanel *panel, vmpa_t addr)
* *
******************************************************************************/
-void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr)
+void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr, ScrollPositionTweak tweak)
{
gint x; /* Abscisse à garantir */
gint y; /* Ordonnée à garantir */
@@ -781,7 +782,7 @@ void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr)
*/
- if (GTK_VIEW_PANEL_GET_CLASS(panel)->get_coordinates(panel, addr, &x, &y))
+ if (GTK_VIEW_PANEL_GET_CLASS(panel)->get_coordinates(panel, addr, &x, &y, tweak))
{
viewport = gtk_widget_get_parent(GTK_WIDGET(panel));
@@ -807,12 +808,13 @@ void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr)
page_size = gtk_adjustment_get_page_size(adj);
value = gtk_adjustment_get_value(adj);
- if (y < value)
+ if (y < value || tweak != SPT_RAW)
gtk_adjustment_set_value(adj, y);
else if ((y + step_inc) > (value + page_size))
gtk_adjustment_set_value(adj, y + step_inc - page_size);
+
}
}
diff --git a/src/gtkext/gtkviewpanel.h b/src/gtkext/gtkviewpanel.h
index 95f2084..c733314 100644
--- a/src/gtkext/gtkviewpanel.h
+++ b/src/gtkext/gtkviewpanel.h
@@ -71,8 +71,18 @@ GLoadedBinary *gtk_view_panel_get_binary(const GtkViewPanel *);
/* Indique si la vue contient une addrese donnée. */
bool gtk_view_panel_contain_address(const GtkViewPanel *, vmpa_t);
+/* Adaptation d'une position sur une surface */
+typedef enum _ScrollPositionTweak
+{
+ SPT_RAW, /* Aucun ajustement */
+ SPT_TOP, /* Le plus haut possible */
+ SPT_CENTER, /* Au centre de la surface */
+ SPT_BOTTOM /* Le plus bas possible */
+
+} ScrollPositionTweak;
+
/* S'assure qu'une adresse donnée est visible à l'écran. */
-void gtk_view_panel_scroll_to_address(GtkViewPanel *, const vmpa2t *);
+void gtk_view_panel_scroll_to_address(GtkViewPanel *, const vmpa2t *, ScrollPositionTweak);
/* Place en cache un rendu destiné à l'aperçu graphique rapide. */
void gtk_view_panel_cache_glance(GtkViewPanel *, cairo_t *, const GtkAllocation *, double);
diff --git a/src/gui/menus/binary.c b/src/gui/menus/binary.c
index c7c0347..50a9143 100644
--- a/src/gui/menus/binary.c
+++ b/src/gui/menus/binary.c
@@ -128,7 +128,7 @@ static void mcb_binary_entry_points(GtkMenuItem *menuitem, GMenuBar *bar)
addr = get_address_from_gotox_dialog(dialog);
vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(bar));
- gtk_view_panel_scroll_to_address(vpanel, addr);
+ gtk_view_panel_scroll_to_address(vpanel, addr, SPT_CENTER);
delete_vmpa(addr);
diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c
index eec3016..8893ce9 100644
--- a/src/gui/menus/edition.c
+++ b/src/gui/menus/edition.c
@@ -222,7 +222,7 @@ static void mcb_edition_goto(GtkMenuItem *menuitem, GMenuBar *bar)
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);
+ gtk_view_panel_scroll_to_address(vpanel, addr, SPT_CENTER);
delete_vmpa(addr);
diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c
index 052bf5a..e9ab0d1 100644
--- a/src/gui/panels/bookmarks.c
+++ b/src/gui/panels/bookmarks.c
@@ -647,7 +647,7 @@ static void on_bookmarks_selection_change(GtkTreeSelection *selection, GBookmark
addr = g_db_bookmark_get_address(bookmark);
vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(panel));
- gtk_view_panel_scroll_to_address(vpanel, addr);
+ gtk_view_panel_scroll_to_address(vpanel, addr, SPT_CENTER);
g_object_unref(G_OBJECT(bookmark));
@@ -1081,7 +1081,7 @@ static gboolean on_button_press_over_bookmarks(GtkWidget *widget, GdkEventButton
addr = g_db_bookmark_get_address(bookmark);
vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(panel));
- gtk_view_panel_scroll_to_address(vpanel, addr);
+ gtk_view_panel_scroll_to_address(vpanel, addr, SPT_CENTER);
g_object_unref(G_OBJECT(bookmark));
diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c
index 7be9749..b523cd2 100644
--- a/src/gui/panels/symbols.c
+++ b/src/gui/panels/symbols.c
@@ -562,7 +562,7 @@ static void on_symbols_selection_change(GtkTreeSelection *selection, GSymbolsPan
range = g_binary_symbol_get_range(symbol);
vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(panel));
- gtk_view_panel_scroll_to_address(vpanel, get_mrange_addr(range));
+ gtk_view_panel_scroll_to_address(vpanel, get_mrange_addr(range), SPT_CENTER);
g_object_unref(G_OBJECT(symbol));
diff --git a/src/gui/tb/portions.c b/src/gui/tb/portions.c
index 7e9cb6c..39537eb 100644
--- a/src/gui/tb/portions.c
+++ b/src/gui/tb/portions.c
@@ -246,7 +246,7 @@ static void track_address_on_binary_strip(GtkBinaryStrip *strip, GEditorItem *it
addr = gtk_binary_strip_get_location(strip);
vpanel = g_editor_item_get_current_view(item);
- gtk_view_panel_scroll_to_address(vpanel, addr);
+ gtk_view_panel_scroll_to_address(vpanel, addr, SPT_CENTER);
focus_address_in_editor_items(g_editor_item_get_current_binary(item), addr, item);
diff --git a/src/project.c b/src/project.c
index f3a2702..c8d23f7 100644
--- a/src/project.c
+++ b/src/project.c
@@ -324,24 +324,36 @@ const char *g_study_project_get_filename(const GStudyProject *project)
void g_study_project_add_loaded_binary(GLoadedBinary *binary, GStudyProject *project)
{
size_t index; /* Indice du nouveau binaire */
- GBinFormat *format; /* Format associé au binaire */
- GBinSymbol *symbol; /* Point d'entrée trouvé */
- const mrange_t *range; /* Emplacement de ce point */
index = g_study_project_attach_binary(project, binary);
- g_panel_item_dock(G_PANEL_ITEM(project->binaries[index]->item));
+ gboolean scroll_for_the_first_time(GtkWidget *widget, GdkEvent *event, GLoadedBinary *binary)
+ {
+ GBinFormat *format; /* Format associé au binaire */
+ GBinSymbol *symbol; /* Point d'entrée trouvé */
+ const mrange_t *range; /* Emplacement de ce point */
- format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
+ g_signal_handlers_disconnect_by_func(widget, G_CALLBACK(scroll_for_the_first_time), binary);
- if (g_binary_format_find_symbol_by_label(format, "entry_point", &symbol))
- {
- range = g_binary_symbol_get_range(symbol);
+ format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
- gtk_view_panel_scroll_to_address(project->binaries[index]->views[BVW_BLOCK], get_mrange_addr(range));
+ if (g_binary_format_find_symbol_by_label(format, "entry_point", &symbol))
+ {
+ range = g_binary_symbol_get_range(symbol);
+
+ gtk_view_panel_scroll_to_address(GTK_VIEW_PANEL(widget), get_mrange_addr(range), SPT_CENTER);
+
+ }
+
+ return FALSE;
}
+ g_signal_connect(project->binaries[index]->views[BVW_BLOCK], "size-allocate",
+ G_CALLBACK(scroll_for_the_first_time), binary);
+
+ g_panel_item_dock(G_PANEL_ITEM(project->binaries[index]->item));
+
}