From 4724b73c5161140222cab3c61bb5b3d0c8dde360 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 25 Feb 2015 21:57:42 +0000 Subject: Provided tweaks about positions when looking for address coordinates. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@480 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 26 ++++++++++++++++++ plugins/pychrysa/gtkext/viewpanel.c | 2 +- src/glibext/gcodebuffer.c | 53 ++++++++++++++++++++++++------------- src/glibext/gcodebuffer.h | 2 +- src/gtkext/gtkbufferview.c | 50 ++++++++++++++++++++++++++++------ src/gtkext/gtkviewpanel-int.h | 2 +- src/gtkext/gtkviewpanel.c | 10 ++++--- src/gtkext/gtkviewpanel.h | 12 ++++++++- src/gui/menus/binary.c | 2 +- src/gui/menus/edition.c | 2 +- src/gui/panels/bookmarks.c | 4 +-- src/gui/panels/symbols.c | 2 +- src/gui/tb/portions.c | 2 +- src/project.c | 30 ++++++++++++++------- 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 + + * 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 * 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)); + } -- cgit v0.11.2-87-g4458