From 6cfa350c21c1e54cf9c597d92a9ea3d1aab01d78 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 3 Apr 2015 13:10:42 +0000 Subject: Tried to show basic blocks in the graphic view again. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@499 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 28 +++++++ src/analysis/disass/output.c | 5 +- src/glibext/gcodebuffer.c | 133 ++++++++++++++++++++++++++---- src/glibext/gcodebuffer.h | 4 +- src/gtkext/graph/layout.c | 15 +++- src/gtkext/graph/node.c | 16 ++-- src/gtkext/graph/node.h | 4 +- src/gtkext/graph/nodes/flow.c | 144 ++++++++++++++++++++++++++++---- src/gtkext/gtkbufferview.c | 35 ++++++-- src/gtkext/gtkgraphview.c | 188 +++++++++++++++++++++++++++--------------- src/gtkext/gtkviewpanel-int.h | 5 +- src/gtkext/gtkviewpanel.c | 14 ++-- src/gui/menus/view.c | 6 +- 13 files changed, 463 insertions(+), 134 deletions(-) diff --git a/ChangeLog b/ChangeLog index cbc0d57..f5359b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +15-04-03 Cyrille Bagard + + * src/analysis/disass/output.c: + Set an empty size for lines showing a routine label. + + * src/glibext/gcodebuffer.c: + * src/glibext/gcodebuffer.h: + Rewrite restrictions for buffer views using the new vmpa_t type. + + * src/gtkext/graph/layout.c: + * src/gtkext/graph/node.c: + * src/gtkext/graph/node.h: + Update code. + + * src/gtkext/graph/nodes/flow.c: + Select only meaningful link when building flow entries/exits. + + * src/gtkext/gtkbufferview.c: + Assign a temporary fake size to the widget. + + * src/gtkext/gtkgraphview.c: + * src/gtkext/gtkviewpanel.c: + * src/gtkext/gtkviewpanel-int.h: + Try to show basic blocks in the graphic view again. + + * src/gui/menus/view.c: + Update old code. + 15-04-01 Cyrille Bagard * src/analysis/disass/macro.c: diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index f1e8a3b..edd6843 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -87,6 +87,7 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form int compared; /* Bilan d'une comparaison */ const char *label; /* Etiquette ciblant un symbole*/ + mrange_t range; /* Couverture sans surface */ GDbComment *comment; /* Commentaire à ajouter */ @@ -216,7 +217,9 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form if (label != NULL) { - line = g_code_buffer_append_new_line(buffer, g_binary_symbol_get_range(symbols[sym_index])); + init_mrange(&range, get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])), 0); + + line = g_code_buffer_append_new_line(buffer, &range); g_buffer_line_fill_mrange(line, msize, msize); g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c index ac6e807..b504473 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -24,8 +24,8 @@ #include "gcodebuffer.h" -#include #include +#include #include @@ -143,8 +143,8 @@ struct _GBufferView GObject parent; /* A laisser en premier */ GCodeBuffer *buffer; /* Tampon de code visualisé */ - vmpa_t start; /* Première ligne intégrée */ - vmpa_t end; /* Dernière ligne intégrée */ + vmpa2t *start; /* Première ligne intégrée */ + vmpa2t *end; /* Dernière ligne intégrée */ size_t first_index; /* Indice de la première ligne */ gint line_height; /* Hauteur maximale des lignes */ @@ -512,7 +512,7 @@ static size_t _g_code_buffer_get_index_from_address_new(const GCodeBuffer *buffe * * * Description : Convertit une adresse en indice de ligne. * * * -* Retour : Indice de l'adresse trouvée, ou 0 en cas d'échec. * +* Retour : Indice de l'adresse trouvée, ou le nombre de lignes sinon. * * * * Remarques : - * * * @@ -521,6 +521,108 @@ static size_t _g_code_buffer_get_index_from_address_new(const GCodeBuffer *buffe static size_t g_code_buffer_get_index_from_address(GCodeBuffer *buffer, const vmpa2t *addr, bool first) { size_t result; /* Indice à retourner */ + GBufferLine **found; /* Renvoi vers une trouvaille */ + const mrange_t *range; /* Couverture d'une ligne */ + + /** + * Si aucune adresse (ie. aucune limite ?) n'est précisée, on se base sur + * la direction pour trouver le bon indice. + */ + + if (addr == NULL) + result = (first ? 0 : buffer->used - 1); + + /** + * Sinon on parcourt méthodiquement toutes les lignes ! + */ + + else + { + +#if 0 + int cmp_addr_and_line(const vmpa2t *addr, const GBufferLine **line) + { + int status; /* Bilan d'une comparaison */ + const mrange_t *lrange; /* Couverture d'une ligne */ + + lrange = g_buffer_line_get_range(*line); + + if (mrange_contains_addr(lrange, addr)) + status = 0; + + else + { + if (cmp_vmpa(addr, get_mrange_addr(lrange)) < 0) + status = -1; + else + status = 1; + } + + return status; + + } + + found = bsearch(addr, buffer->lines, buffer->used, sizeof(GBufferLine *), + (__compar_fn_t)cmp_addr_and_line); +#endif + + + + + found = NULL; + + + + for (result = 0; result < buffer->used; result++) + { + range = g_buffer_line_get_range(buffer->lines[result]); + + if (mrange_contains_addr(range, addr)) + { + found = &buffer->lines[result]; + break; + } + + } + + + if (found == NULL) + result = buffer->used; + + else + { + result = found - buffer->lines; + + //printf(" [index] [B] 0x%08x -> %zu\n", (unsigned int)addr->virtual, result); + + if (first) + for (; result > 0; result--) + { + range = g_buffer_line_get_range(buffer->lines[result - 1]); + if (!mrange_contains_addr(range, addr)) break; + } + + else + for (; (result + 1) < buffer->used; result++) + { + range = g_buffer_line_get_range(buffer->lines[result + 1]); + if (!mrange_contains_addr(range, addr)) break; + } + + //printf(" [A] 0x%08x -> %zu\n", (unsigned int)addr->virtual, result); + + } + + } + + return result; + + + + + +#if 0 + size_t result; /* Indice à retourner */ result = _g_code_buffer_get_index_from_address(buffer, addr, first); @@ -533,7 +635,7 @@ static size_t g_code_buffer_get_index_from_address(GCodeBuffer *buffer, const vm result = 0; return result; - +#endif } @@ -671,6 +773,7 @@ GBufferLine *g_code_buffer_find_line_by_addr(const GCodeBuffer *buffer, const vm if (index == buffer->used) result = NULL; + else { result = buffer->lines[index]; @@ -844,8 +947,8 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer) g_object_ref(G_OBJECT(buffer)); result->buffer = buffer; - result->start = 0; - result->end = VMPA_MAX; + result->start = NULL; + result->end = NULL; return result; @@ -866,10 +969,10 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer) * * ******************************************************************************/ -void g_buffer_view_restrict(GBufferView *view, vmpa_t start, vmpa_t end) +void g_buffer_view_restrict(GBufferView *view, const vmpa2t *start, const vmpa2t *end) { - view->start = start; - view->end = end; + view->start = dup_vmpa(start); + view->end = dup_vmpa(end); } @@ -888,10 +991,10 @@ void g_buffer_view_restrict(GBufferView *view, vmpa_t start, vmpa_t end) * * ******************************************************************************/ -void g_buffer_view_get_restrictions(GBufferView *view, vmpa_t *start, vmpa_t *end) +void g_buffer_view_get_restrictions(GBufferView *view, vmpa2t *start, vmpa2t *end) { - if (start != NULL) *start = view->start; - if (end != NULL) *end = view->end; + if (start != NULL) copy_vmpa(start, view->start); + if (end != NULL) copy_vmpa(end, view->end); } @@ -1081,7 +1184,7 @@ gint g_buffer_view_get_width(GBufferView *view, const bool *display) gint full_width; /* Calcul selon les fusions */ BufferLineColumn i; /* Boucle de parcours */ - if (!WIDTHS_CACHED(view)) + //if (!WIDTHS_CACHED(view)) g_buffer_view_compute_required_widths(view, display); result = view->left_text; @@ -1685,7 +1788,7 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y) 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); - for (i = first; i < last; i++) + for (i = first; i <= last; i++) view->highlighted = g_buffer_line_highlight_all_same_segments(view->buffer->lines[i], view->highlighted, segment); diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h index e607b9c..cb17821 100644 --- a/src/glibext/gcodebuffer.h +++ b/src/glibext/gcodebuffer.h @@ -111,10 +111,10 @@ GType g_buffer_view_get_type(void); GBufferView *g_buffer_view_new(GCodeBuffer *); /* Restreint le champ d'application de l'affichage. */ -void g_buffer_view_restrict(GBufferView *, vmpa_t, vmpa_t); +void g_buffer_view_restrict(GBufferView *, const vmpa2t *, const vmpa2t *); /* Indique le champ d'application de l'affichage. */ -void g_buffer_view_get_restrictions(GBufferView *, vmpa_t *, vmpa_t *); +void g_buffer_view_get_restrictions(GBufferView *, vmpa2t *, vmpa2t *); /* Fournit le tampon de code lié à un visualisateur donné. */ GCodeBuffer *g_buffer_view_get_buffer(const GBufferView *); diff --git a/src/gtkext/graph/layout.c b/src/gtkext/graph/layout.c index 94f59e6..ee91aff 100644 --- a/src/gtkext/graph/layout.c +++ b/src/gtkext/graph/layout.c @@ -160,14 +160,14 @@ bool build_graph_view(GtkGraphView *view, GInstrBlock *blocks, GtkViewPanel **vi static bool rank_graph_nodes(GInstrBlock *block, BlockVisitOrder order, visitor_dot_params *params) { - vmpa_t start; /* Adresse de départ d'un bloc */ + vmpa2t start; /* Adresse de départ d'un bloc */ GGraphNode *node; /* Noeud rattaché */ unsigned int rank; /* Classement du bloc lié */ if (G_IS_FLOW_BLOCK(block)) { g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(block), &start, NULL); - node = find_graph_node_by_start_address(params->nodes, params->count, start); + node = find_graph_node_by_start_address(params->nodes, params->count, &start); rank = g_flow_block_get_rank(G_FLOW_BLOCK(block)); /* BUG_ON(count >= params->count) */ @@ -251,7 +251,7 @@ static void build_graph_ranking(visitor_dot_params *params) static bool register_graph_nodes(GInstrBlock *block, BlockVisitOrder order, visitor_dot_params *params) { char *cmds; /* Raccourci d'usage pratique */ - vmpa_t start; /* Adresse de départ d'un bloc */ + vmpa2t start; /* Adresse de départ d'un bloc */ GGraphNode *node; /* Noeud rattaché */ unsigned int i; /* Boucle de parcours */ char buffer[CLUSTER_DESC_LEN]; /* Tampon pour les commandes */ @@ -261,7 +261,7 @@ static bool register_graph_nodes(GInstrBlock *block, BlockVisitOrder order, visi if (G_IS_FLOW_BLOCK(block)) { g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(block), &start, NULL); - node = find_graph_node_by_start_address(params->nodes, params->count, start); + node = find_graph_node_by_start_address(params->nodes, params->count, &start); cmds = g_graph_node_register_for_dot(node, cmds, params->level); @@ -784,6 +784,13 @@ void g_graph_layout_size_request(const GGraphLayout *layout, GtkRequisition *req requisition->height = g_graph_ranks_get_height(layout->ranks); + + requisition->width = 3000; + requisition->height = 3000; + + + printf("SIZE REQ\n"); + } diff --git a/src/gtkext/graph/node.c b/src/gtkext/graph/node.c index f286457..3801d1a 100644 --- a/src/gtkext/graph/node.c +++ b/src/gtkext/graph/node.c @@ -742,12 +742,12 @@ void g_graph_node_connect(const GGraphNode *node, gint x, gint y, GdkPoint **poi * * ******************************************************************************/ -GtkBufferView *find_graph_view_by_start_address(GtkBufferView **views, size_t count, vmpa_t addr) +GtkBufferView *find_graph_view_by_start_address(GtkBufferView **views, size_t count, const vmpa2t *addr) { GtkBufferView *result; /* Trouvaille à remonter */ size_t i; /* Boucle de parcours */ GBufferView *buffer; /* Tampon d'une partie de code */ - vmpa_t start; /* Adresse de départ du tampon */ + vmpa2t start; /* Adresse de départ du tampon */ result = NULL; @@ -756,7 +756,7 @@ GtkBufferView *find_graph_view_by_start_address(GtkBufferView **views, size_t co buffer = gtk_buffer_view_get_buffer(GTK_BUFFER_VIEW(views[i])); g_buffer_view_get_restrictions(buffer, &start, NULL); - if (start == addr) + if (cmp_vmpa(&start, addr) == 0) result = views[i]; } @@ -783,7 +783,7 @@ GtkBufferView *find_graph_view_by_start_address(GtkBufferView **views, size_t co GGraphNode *convert_blocks_into_nodes(GInstrBlock *block, GtkBufferView **views, size_t count) { GGraphNode *result; /* Instance nouvelle à renvoyer*/ - vmpa_t start; /* Adresse de départ */ + vmpa2t start; /* Adresse de départ */ GtkBufferView *view; /* Vue existante à retrouver */ size_t max; /* Nombre de blocs à gérer */ size_t i; /* Boucle de parcours */ @@ -795,7 +795,7 @@ GGraphNode *convert_blocks_into_nodes(GInstrBlock *block, GtkBufferView **views, if (G_IS_FLOW_BLOCK(block)) { g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(block), &start, NULL); - view = find_graph_view_by_start_address(views, count, start); + view = find_graph_view_by_start_address(views, count, &start); result = g_flow_node_new(G_FLOW_BLOCK(block), view); @@ -890,12 +890,12 @@ GGraphNode *find_node_for_instruction(GGraphNode *nodes, GArchInstruction *instr * * ******************************************************************************/ -GGraphNode *find_graph_node_by_start_address(GGraphNode **nodes, size_t count, vmpa_t addr) +GGraphNode *find_graph_node_by_start_address(GGraphNode **nodes, size_t count, const vmpa2t *addr) { GGraphNode *result; /* Trouvaille à remonter */ size_t i; /* Boucle de parcours */ GBufferView *buffer; /* Tampon d'une partie de code */ - vmpa_t start; /* Adresse de départ du tampon */ + vmpa2t start; /* Adresse de départ du tampon */ result = NULL; @@ -904,7 +904,7 @@ GGraphNode *find_graph_node_by_start_address(GGraphNode **nodes, size_t count, v buffer = gtk_buffer_view_get_buffer(GTK_BUFFER_VIEW(nodes[i]->view)); g_buffer_view_get_restrictions(buffer, &start, NULL); - if (start == addr) + if (cmp_vmpa(&start, addr) == 0) result = nodes[i]; } diff --git a/src/gtkext/graph/node.h b/src/gtkext/graph/node.h index 712d9a3..4dcb02a 100644 --- a/src/gtkext/graph/node.h +++ b/src/gtkext/graph/node.h @@ -166,7 +166,7 @@ void g_graph_node_connect(const GGraphNode *, gint, gint, GdkPoint **, size_t *) /* Recherche une vue donnée dans une série de vues. */ -GtkBufferView *find_graph_view_by_start_address(GtkBufferView **, size_t, vmpa_t); +GtkBufferView *find_graph_view_by_start_address(GtkBufferView **, size_t, const vmpa2t *); /* Réalise une conversion de blocs en noeuds. */ GGraphNode *convert_blocks_into_nodes(GInstrBlock *, GtkBufferView **, size_t); @@ -178,7 +178,7 @@ GGraphNode *find_node_for_instruction(GGraphNode *, GArchInstruction *); /* Recherche un noeud donné dans une série de noeuds. */ -GGraphNode *find_graph_node_by_start_address(GGraphNode **, size_t, vmpa_t); +GGraphNode *find_graph_node_by_start_address(GGraphNode **, size_t, const vmpa2t *); /* Recherche un noeud donné dans une série de noeuds. */ GGraphNode *find_graph_node_by_name(GGraphNode **, size_t, const char *); diff --git a/src/gtkext/graph/nodes/flow.c b/src/gtkext/graph/nodes/flow.c index 7ebaf78..5173810 100644 --- a/src/gtkext/graph/nodes/flow.c +++ b/src/gtkext/graph/nodes/flow.c @@ -24,6 +24,9 @@ #include "flow.h" +#include + + #include "../layout.h" #include "../node-int.h" @@ -242,8 +245,13 @@ GGraphNode *g_flow_node_new(GFlowBlock *block, GtkBufferView *view) result->block = block; result->view = view; + gtk_widget_show(GTK_WIDGET(result->view)); + gtk_widget_size_allocate(GTK_WIDGET(result->view), (GtkAllocation []) { { 0, 0, 100, 100 } }); + gtk_widget_get_preferred_size(GTK_WIDGET(result->view), NULL, &requisition); + printf("PREFERED :: (%d ; %d)\n", requisition.width, requisition.height); + G_GRAPH_NODE(result)->alloc.width = requisition.width; G_GRAPH_NODE(result)->alloc.height = requisition.height; @@ -614,26 +622,76 @@ static void g_flow_node_setup_entry_slots(GFlowNode *node) GArchInstruction **instrs; /* Instr. visée par une autre */ InstructionLinkType *types; /* Type de lien entre lignes */ size_t icount; /* Nombre de liens de dest. */ + size_t usable; /* Nombre de liens utiles ici */ size_t i; /* Boucle de parcours */ + size_t used; /* Nombre de liens utilisés */ g_flow_block_get_boundary(node->block, &first, NULL); icount = g_arch_instruction_get_sources(first, &instrs, &types); - node->entries = (node_slot_t *)calloc(icount, sizeof(node_slot_t)); - node->entries_count = icount; + usable = 0; for (i = 0; i < icount; i++) - { - g_object_ref(instrs[i]); - node->entries[i].instr = instrs[i]; + switch (types[i]) + { + case ILT_EXEC_FLOW: + case ILT_JUMP: + case ILT_CASE_JUMP: + case ILT_JUMP_IF_TRUE: + case ILT_JUMP_IF_FALSE: + case ILT_LOOP: + case ILT_CATCH_EXCEPTION: + usable++; + break; - node->entries[i].type = types[i]; - node->entries[i].group_index = g_arch_instruction_compute_group_index(&instrs[i], - instrs, icount); - node->entries[i].slot_index = i; + default: + break; + } + + if (usable == 0) + { + node->entries = NULL; + node->entries_count = 0; + } + else + { + node->entries = (node_slot_t *)calloc(usable, sizeof(node_slot_t)); + node->entries_count = usable; } + used = 0; + + for (i = 0; i < icount; i++) + switch (types[i]) + { + case ILT_EXEC_FLOW: + case ILT_JUMP: + case ILT_CASE_JUMP: + case ILT_JUMP_IF_TRUE: + case ILT_JUMP_IF_FALSE: + case ILT_LOOP: + case ILT_CATCH_EXCEPTION: + + g_object_ref(instrs[i]); + node->entries[used].instr = instrs[i]; + + node->entries[used].type = types[i]; + node->entries[used].group_index = g_arch_instruction_compute_group_index(&instrs[i], + instrs, icount); + node->entries[used].slot_index = i; + + used++; + + break; + + default: + break; + + } + + assert(used == usable); + } @@ -655,25 +713,75 @@ static void g_flow_node_setup_exit_slots(GFlowNode *node) GArchInstruction **instrs; /* Instr. visée par une autre */ InstructionLinkType *types; /* Type de lien entre lignes */ size_t icount; /* Nombre de liens de dest. */ + size_t usable; /* Nombre de liens utiles ici */ size_t i; /* Boucle de parcours */ + size_t used; /* Nombre de liens utilisés */ g_flow_block_get_boundary(node->block, NULL, &last); icount = g_arch_instruction_get_destinations(last, &instrs, &types, NULL); - node->exits = (node_slot_t *)calloc(icount, sizeof(node_slot_t)); - node->exits_count = icount; + usable = 0; for (i = 0; i < icount; i++) - { - g_object_ref(instrs[i]); - node->exits[i].instr = instrs[i]; + switch (types[i]) + { + case ILT_EXEC_FLOW: + case ILT_JUMP: + case ILT_CASE_JUMP: + case ILT_JUMP_IF_TRUE: + case ILT_JUMP_IF_FALSE: + case ILT_LOOP: + case ILT_CATCH_EXCEPTION: + usable++; + break; - node->exits[i].type = types[i]; - node->exits[i].group_index = g_arch_instruction_compute_group_index(&instrs[i], - instrs, icount); - node->exits[i].slot_index = i; + default: + break; + } + + if (usable == 0) + { + node->exits = NULL; + node->exits_count = 0; } + else + { + node->exits = (node_slot_t *)calloc(usable, sizeof(node_slot_t)); + node->exits_count = usable; + } + + used = 0; + + for (i = 0; i < icount; i++) + switch (types[i]) + { + case ILT_EXEC_FLOW: + case ILT_JUMP: + case ILT_CASE_JUMP: + case ILT_JUMP_IF_TRUE: + case ILT_JUMP_IF_FALSE: + case ILT_LOOP: + case ILT_CATCH_EXCEPTION: + + g_object_ref(instrs[i]); + node->exits[used].instr = instrs[i]; + + node->exits[used].type = types[i]; + node->exits[used].group_index = g_arch_instruction_compute_group_index(&instrs[i], + instrs, icount); + node->exits[used].slot_index = i; + + used++; + + break; + + default: + break; + + } + + assert(used == usable); } diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c index c7c0267..be75d2f 100644 --- a/src/gtkext/gtkbufferview.c +++ b/src/gtkext/gtkbufferview.c @@ -92,6 +92,28 @@ static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *); G_DEFINE_TYPE(GtkBufferView, gtk_buffer_view, GTK_TYPE_VIEW_PANEL) +/* + void (* get_preferred_height) (GtkWidget *widget, + gint *minimum_height, + gint *natural_height); + + void (* get_preferred_width_for_height) (GtkWidget *widget, + gint height, + gint *minimum_width, + gint *natural_width); + void (* get_preferred_width) (GtkWidget *widget, + gint *minimum_width, + gint *natural_width); +*/ + + +void get_preferred(GtkWidget *widget, gint *minimum, gint *natural) +{ + if (minimum != NULL) *minimum = 500; + if (natural != NULL) *natural = 500; +} + + /****************************************************************************** * * * Paramètres : class = classe GTK à initialiser. * @@ -117,6 +139,11 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *class) widget_class->draw = gtk_buffer_view_draw; widget_class->key_press_event = gtk_buffer_view_key_press; + + widget_class->get_preferred_height = get_preferred; + widget_class->get_preferred_width = get_preferred; + + panel_class->compute_size = (compute_requested_size)gtk_buffer_view_compute_requested_size; panel_class->compute_inc = (compute_scroll_inc)gtk_buffer_view_compute_scroll_inc; panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_view_get_address_coordinates; @@ -361,7 +388,7 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) gtk_style_context_add_class(context, GTK_STYLE_CLASS_TROUGH); - gtk_render_background (context, cr, 0, area.y, view->left_margin, area.height); + gtk_render_background(context, cr, 0, area.y, view->left_margin, area.height); gtk_render_frame(context, cr, 0, area.y - 10, view->left_margin, area.height + 20); gtk_style_context_restore(context); @@ -549,12 +576,6 @@ static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, G } - - - - - - /****************************************************************************** * * * Paramètres : view = composant GTK à consulter. * diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c index 0265518..1f8d51c 100644 --- a/src/gtkext/gtkgraphview.c +++ b/src/gtkext/gtkgraphview.c @@ -79,15 +79,15 @@ static gboolean gtk_graph_view_draw(GtkWidget *, cairo_t *, GtkGraphView *); /* Indique les dimensions de travail du composant d'affichage. */ static void gtk_graph_view_compute_requested_size(GtkGraphView *, gint *, gint *); - -/* Réagit à la sélection externe d'une adresse. */ -static void gtk_graph_view_define_main_address(GtkGraphView *, vmpa_t); - /* Actualise les besoins internes avant un redimensionnement. */ static void gtk_graph_view_prepare_resize(GtkGraphView *); + +/* Réagit à la sélection externe d'une adresse. */ +static void gtk_graph_view_define_main_address(GtkGraphView *, const vmpa2t *); + /* Indique la position d'affichage d'une adresse donnée. */ -static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *, vmpa_t, gint *, gint *); +static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak); /* Place en cache un rendu destiné à l'aperçu graphique rapide. */ static void gtk_graph_view_cache_glance(GtkGraphView *, cairo_t *, const GtkAllocation *, double); @@ -129,6 +129,8 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *class) widget_class->size_allocate = gtk_graph_view_size_allocate; panel_class->compute_size = (compute_requested_size)gtk_graph_view_compute_requested_size; + panel_class->define = (define_address_fc)gtk_graph_view_define_main_address; + panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates; } @@ -144,7 +146,7 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *class) * Remarques : - * * * ******************************************************************************/ - +#include "easygtk.h"//////////// static void gtk_graph_view_init(GtkGraphView *view) { GtkViewPanel *viewpanel; /* Instance parente #1 */ @@ -153,7 +155,6 @@ static void gtk_graph_view_init(GtkGraphView *view) viewpanel = GTK_VIEW_PANEL(view); - viewpanel->define = (define_address_fc)gtk_graph_view_define_main_address; viewpanel->resize = (prepare_resize_fc)gtk_graph_view_prepare_resize; ////////viewpanel->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates; viewpanel->cache_glance = (cache_glance_fc)gtk_graph_view_cache_glance; @@ -166,6 +167,7 @@ static void gtk_graph_view_init(GtkGraphView *view) view->support = GTK_FIXED(gtk_fixed_new()); gtk_widget_set_has_window(GTK_WIDGET(view->support), TRUE); + gtk_widget_set_can_focus(GTK_WIDGET(view->support), TRUE); g_signal_connect(G_OBJECT(view->support), "draw", G_CALLBACK(gtk_graph_view_draw), view); @@ -179,6 +181,26 @@ static void gtk_graph_view_init(GtkGraphView *view) gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->support), 0, 0); + //gtk_widget_size_allocate(view->support, (GtkAllocation []){ { 200, 200, 500, 500 } }); + +#if 0 + do + { + GtkWidget *btn; + + btn = qck_create_button(NULL, NULL, "caption 0", NULL, NULL); + gtk_fixed_put(GTK_FIXED(view), btn, 10, 10); + + + btn = qck_create_button(NULL, NULL, "caption 1", NULL, NULL); + gtk_fixed_put(GTK_FIXED(view->support), btn, 100, 100); + + + + } + while (0); +#endif + //view->mutex = g_mutex_new(); //view->cond = g_cond_new(); @@ -215,19 +237,32 @@ static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *alloc GdkWindow *window; /* Fenêtre associée au support */ gboolean changed; /* Changement de valeur ? */ - return; + + printf("GRAPH SIZE ALLOC :: (%d ; %d) - (%d ; %d)\n", + allocation->x, allocation->y, + allocation->width, allocation->height); + + + GTK_WIDGET_CLASS(gtk_graph_view_parent_class)->size_allocate(widget, allocation); + /* Mise à jour GTK */ + /* fixed_class = g_type_class_peek_parent(GTK_GRAPH_VIEW_GET_CLASS(widget)); fixed_class = g_type_class_peek_parent(fixed_class); GTK_WIDGET_CLASS(fixed_class)->size_allocate(widget, allocation); + */ + + panel = GTK_VIEW_PANEL(widget); + /* if (panel->hadjustment == NULL || panel->vadjustment == NULL) return; + */ // !!!! moved !!! gtk_view_panel_compute_allocation(panel, &valloc); @@ -238,8 +273,24 @@ static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *alloc view = GTK_GRAPH_VIEW(widget); window = gtk_widget_get_window(GTK_WIDGET(view->support)); + + + gtk_widget_size_allocate(view->support, (GtkAllocation []){ { 0, 0, 1500, 1500 } }); + + //gdk_window_resize(window, 500, 500); + + /* + printf(" --> cmp :: (%d ; %d) vs (%d ; %d)\n", + gdk_window_get_width(window), gdk_window_get_height(window), + req.width, req.height); + */ + /* if (gdk_window_get_width(window) != req.width || gdk_window_get_height(window) != req.height) gdk_window_resize(window, req.width, req.height); + */ + + return; + /* Défilement horizontal */ @@ -299,7 +350,7 @@ static void gtk_graph_view_compute_requested_size(GtkGraphView *view, gint *widt if (width != NULL && view->layout != NULL) { g_graph_layout_size_request(view->layout, &requisition); - *width = requisition.height; + *width = requisition.width; } if (height != NULL && view->layout != NULL) @@ -340,6 +391,42 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView /****************************************************************************** * * * Paramètres : view = composant GTK à mettre à jour. * +* * +* Description : Actualise les besoins internes avant un redimensionnement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_graph_view_prepare_resize(GtkGraphView *view) +{ + size_t i; /* Boucle de parcours */ + + if (view->children_count > 0) + { + for (i = 0; i < view->children_count; i++) + gtk_widget_queue_resize(GTK_WIDGET(view->children[i])); + + /* + build_graph_view(view, g_binary_routine_get_basic_blocks(view->routine), + view->children, view->children_count); + */ + + g_graph_layout_refresh(view->layout); + g_graph_layout_place(view->layout, view); + + change_editor_items_current_view_content(GTK_VIEW_PANEL(view)); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à mettre à jour. * * addr = adresse sélectionnée de manière externe. * * * * Description : Réagit à la sélection externe d'une adresse. * @@ -350,16 +437,24 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView * * ******************************************************************************/ -static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr) +static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t *addr) { + bool need_update; /* Mise à jour du contenu ? */ + const mrange_t *range; /* Couverture courante */ GExeFormat *format; /* Type de fichier chargé */ GBinRoutine **routines; /* Liste des routines trouvées */ size_t routines_count; /* Nombre de ces routines */ size_t i; /* Boucle de parcours */ - vmpa_t start; /* Début d'une routine */ - vmpa_t end; /* Fin d'une routine */ - if (!(view->start <= addr && addr < view->end)) + if (view->routine == NULL) + need_update = true; + else + { + range = g_binary_routine_get_range(view->routine); + need_update = !mrange_contains_addr(range, addr); + } + + if (need_update) { gtk_graph_view_reset(view); @@ -368,17 +463,13 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr) for (i = 0; i < routines_count; i++) { - start = g_binary_routine_get_address(routines[i]); - end = start + g_binary_routine_get_size(routines[i]); + range = g_binary_routine_get_range(routines[i]); - if (start <= addr && addr < end) + if (mrange_contains_addr(range, addr)) { view->routine = routines[i]; g_object_ref(G_OBJECT(view->routine)); - view->start = start; - view->end = end; - view->children = gtk_graph_view_load_nodes(view, GTK_VIEW_PANEL(view)->binary, routines[i]); @@ -411,46 +502,11 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr) /****************************************************************************** * * -* Paramètres : view = composant GTK à mettre à jour. * -* * -* Description : Actualise les besoins internes avant un redimensionnement. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_graph_view_prepare_resize(GtkGraphView *view) -{ - size_t i; /* Boucle de parcours */ - - if (view->children_count > 0) - { - for (i = 0; i < view->children_count; i++) - gtk_widget_queue_resize(GTK_WIDGET(view->children[i])); - - /* - build_graph_view(view, g_binary_routine_get_basic_blocks(view->routine), - view->children, view->children_count); - */ - - g_graph_layout_refresh(view->layout); - g_graph_layout_place(view->layout, view); - - change_editor_items_current_view_content(GTK_VIEW_PANEL(view)); - - } - -} - - -/****************************************************************************** -* * -* 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. * * * @@ -460,10 +516,9 @@ static void gtk_graph_view_prepare_resize(GtkGraphView *view) * * ******************************************************************************/ -static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, vmpa_t addr, gint *x, gint *y) +static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak) { - - + /* TODO */ return false; @@ -564,7 +619,8 @@ void gtk_graph_view_put(GtkGraphView *view, GtkWidget *widget, const GtkAllocati gtk_container_remove(GTK_CONTAINER(parent), widget); } - gtk_fixed_put(view->support, widget, alloc->x, alloc->y); + //gtk_fixed_put(view->support, widget, alloc->x, alloc->y); + gtk_fixed_put(view->support, widget, i * 200, i * 150); if (parent != NULL) g_object_unref(G_OBJECT(widget)); @@ -665,8 +721,8 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBinar GInstrBlock *main_block; /* Premier bloc rattaché */ GInstrBlock **blocks; /* Liste des blocs basiques */ size_t i; /* Boucle de parcours */ - vmpa_t first; /* Début d'un groupe de lignes */ - vmpa_t last; /* Fin d'un groupe de lignes */ + vmpa2t first; /* Début d'un groupe de lignes */ + vmpa2t last; /* Fin d'un groupe de lignes */ GBufferView *subview; /* Partie affichée du tampon */ buffer = g_loaded_binary_get_disassembled_buffer(binary); @@ -692,7 +748,7 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBinar g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(blocks[i]), &first, &last); subview = g_buffer_view_new(buffer); - g_buffer_view_restrict(subview, first, last); + g_buffer_view_restrict(subview, &first, &last); gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result[i]), subview); } diff --git a/src/gtkext/gtkviewpanel-int.h b/src/gtkext/gtkviewpanel-int.h index 220b253..d51c637 100644 --- a/src/gtkext/gtkviewpanel-int.h +++ b/src/gtkext/gtkviewpanel-int.h @@ -43,7 +43,7 @@ typedef void (* compute_scroll_inc) (GtkViewPanel *, gint, GtkOrientation, gdoub typedef void (* attach_binary_fc) (GtkViewPanel *, GLoadedBinary *); /* Réagit à la sélection externe d'une adresse. */ -typedef void (* define_address_fc) (GtkViewPanel *, vmpa_t); +typedef void (* define_address_fc) (GtkViewPanel *, const vmpa2t *); /* Actualise les besoins internes avant un redimensionnement. */ typedef void (* prepare_resize_fc) (GtkViewPanel *); @@ -76,7 +76,7 @@ struct _GtkViewPanel GLoadedBinary *binary; /* Binaire à visualiser */ attach_binary_fc attach; /* Association avec un binaire */ - define_address_fc define; /* Centrage sur une partie */ + //define_address_fc define; /* Centrage sur une partie */ prepare_resize_fc resize; /* Prépare une nouvelle taille */ cache_glance_fc cache_glance; /* Cache de la mignature */ @@ -89,6 +89,7 @@ struct _GtkViewPanelClass compute_requested_size compute_size; /* Calcul de la taille requise */ compute_scroll_inc compute_inc; /* Calcul des bonds */ + define_address_fc define; /* Centrage sur une partie */ get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */ get_view_position_fc get_position; /* Indications sur la position */ diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c index d434f1e..3c8febd 100644 --- a/src/gtkext/gtkviewpanel.c +++ b/src/gtkext/gtkviewpanel.c @@ -320,6 +320,11 @@ static void gtk_view_panel_size_allocate(GtkWidget *widget, GtkAllocation *alloc GTK_WIDGET_CLASS(gtk_view_panel_parent_class)->size_allocate(widget, allocation); + + printf("[%s / %p] __SIZE :: (%d ; %d)\n", G_OBJECT_TYPE_NAME(widget), widget, + allocation->width, allocation->height); + + panel = GTK_VIEW_PANEL(widget); gtk_view_panel_update_adjustment(panel, GTK_ORIENTATION_HORIZONTAL); @@ -347,6 +352,8 @@ static gboolean gtk_view_panel_draw(GtkWidget *widget, cairo_t *cr) GtkRequisition req; /* Taille allouée à l'élément */ GtkStyleContext *context; /* Contexte du thème actuel */ + GTK_WIDGET_CLASS(gtk_view_panel_parent_class)->draw(widget, cr); + panel = GTK_VIEW_PANEL(widget); if (panel->show_border) @@ -776,11 +783,8 @@ void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr, S gdouble page_size; /* Taille de l'affichage */ double value; /* Valeur courante */ - /* - if (panel->define != NULL) - panel->define(panel, addr); - */ - + if (GTK_VIEW_PANEL_GET_CLASS(panel)->define != NULL) + GTK_VIEW_PANEL_GET_CLASS(panel)->define(panel, addr); if (GTK_VIEW_PANEL_GET_CLASS(panel)->get_coordinates(panel, addr, &x, &y, tweak)) { diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c index 9abcbd3..c907bc8 100644 --- a/src/gui/menus/view.c +++ b/src/gui/menus/view.c @@ -219,8 +219,7 @@ static void mcb_view_change_support(GtkRadioMenuItem *menuitem, GMenuBar *bar) /** * La hiérarchie des composants empilés est la suivante : * - * - GtkBlockView / GtkGraphView / GtkSourceView - * - GtkViewport + * - GtkBlockView / GtkGraphView / GtkSourceView (avec GtkViewport intégré) * - GtkScrolledWindow * - GtkNotebook * - GtkDockStation @@ -228,8 +227,7 @@ static void mcb_view_change_support(GtkRadioMenuItem *menuitem, GMenuBar *bar) */ vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(bar)); - station = gtk_widget_get_parent(GTK_WIDGET(vpanel)); /* GtkViewport */ - station = gtk_widget_get_parent(GTK_WIDGET(station)); /* ScrollWindow */ + station = gtk_widget_get_parent(GTK_WIDGET(vpanel)); /* ScrollWindow */ station = gtk_widget_get_parent(station); /* NoteBook */ station = gtk_widget_get_parent(station); /* DockStation */ -- cgit v0.11.2-87-g4458