diff options
Diffstat (limited to 'src/gtkext/gtkblockview.c')
-rw-r--r-- | src/gtkext/gtkblockview.c | 326 |
1 files changed, 262 insertions, 64 deletions
diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockview.c index 23f86ce..ac06af3 100644 --- a/src/gtkext/gtkblockview.c +++ b/src/gtkext/gtkblockview.c @@ -35,10 +35,63 @@ #include "support.h" #include "../analysis/exporter.h" #include "../common/dllist.h" +#include "../glibext/delayed-int.h" -#define MARGIN_SPACE 4 /* TODO : delete me ! */ +#ifndef _ +# define _(str) str +#endif + + + + +/* -------------------------- INSERTION DIFFEREE DE LIGNES -------------------------- */ + + +#define G_TYPE_DELAYED_INSERTION g_delayed_insertion_get_type() +#define G_DELAYED_INSERTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_delayed_insertion_get_type(), GDelayedInsertion)) +#define G_IS_DELAYED_INSERTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_delayed_insertion_get_type())) +#define G_DELAYED_INSERTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DELAYED_INSERTION, GDelayedInsertionClass)) +#define G_IS_DELAYED_INSERTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DELAYED_INSERTION)) +#define G_DELAYED_INSERTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DELAYED_INSERTION, GDelayedInsertionClass)) + + +/* Ensembles binaires à désassembler (instance) */ +typedef struct _GDelayedInsertion +{ + GDelayedWork parent; /* A laisser en premier */ + + GtkBlockView *view; /* Visualisation à constituer */ + + size_t lengths[SAR_COUNT]; /* Différentes tailles de zone */ + +} GDelayedInsertion; + +/* Ensembles binaires à désassembler (classe) */ +typedef struct _GDelayedInsertionClass +{ + GDelayedWorkClass parent; /* A laisser en premier */ + +} GDelayedInsertionClass; + + +/* Indique le type défini pour les tâches d'insertions différées. */ +static GType g_delayed_insertion_get_type(void); + +/* Initialise la classe des tâches d'insertions différées. */ +static void g_delayed_insertion_class_init(GDelayedInsertionClass *); + +/* Initialise une tâche d'insertions différées. */ +static void g_delayed_insertion_init(GDelayedInsertion *); + +/* Crée une tâche d'insertions différées. */ +static GDelayedInsertion *g_delayed_insertion_new(GtkBlockView *); + +/* Assure des insertion de lignes en différé. */ +static void g_delayed_insertion_process(GDelayedInsertion *, GtkExtStatusBar *); + + @@ -76,6 +129,8 @@ struct _GtkBlockViewClass + + static void gtk_text_view2_set_attributes_from_style (GtkTextAttributes *values, GtkStyle *style) @@ -108,6 +163,8 @@ static void gtk_block_view_realize(GtkWidget *); /* Définit les lignes du bloc de représentation. */ static void gtk_block_view_set_rendering_lines(GtkBlockView *, GRenderingLine *, GRenderingLine *); +/* Achève la construction de la visualisation des lignes. */ +static void gtk_block_view_complete_building_content(GDelayedInsertion *, GtkBlockView *); @@ -150,6 +207,171 @@ static void gtk_block_view_destroy(GtkObject *object); + + +/* ---------------------------------------------------------------------------------- */ +/* INSERTION DIFFEREE DE LIGNES */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour les tâches d'insertions différées. */ +G_DEFINE_TYPE(GDelayedInsertion, g_delayed_insertion, G_TYPE_DELAYED_WORK); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des tâches d'insertions différées. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_delayed_insertion_class_init(GDelayedInsertionClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : insertion = instance à initialiser. * +* * +* Description : Initialise une tâche d'insertions différées. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_delayed_insertion_init(GDelayedInsertion *insertion) +{ + G_DELAYED_WORK(insertion)->run = (run_task_fc)g_delayed_insertion_process; + +} + + +/****************************************************************************** +* * +* Paramètres : view = visualisation de lignes à constituer. * +* * +* Description : Crée une tâche d'insertions différées. * +* * +* Retour : Tâche créée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDelayedInsertion *g_delayed_insertion_new(GtkBlockView *view) +{ + GDelayedInsertion *result; /* Tâche à retourner */ + + result = g_object_new(G_TYPE_DELAYED_INSERTION, NULL); + + result->view = view; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : insertion = insertions de lignes à mener. * +* statusbar = barre de statut à tenir informée. * +* * +* Description : Assure des insertion de lignes en différé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_delayed_insertion_process(GDelayedInsertion *insertion, GtkExtStatusBar *statusbar) +{ + GtkBlockView *view; /* Visualisation à constituer */ + GRenderingLine *lines; /* Liste de lignes à intégrer */ + GRenderingLine *last; /* Dernière ligne ou NULL */ + vmpa_t start; /* Adresse de début de parcours*/ + vmpa_t end; /* Adresse de fin de parcours */ + guint id; /* Identifiant de statut */ + GRenderingLine *iter; /* Boucle de parcours */ + GtkTextIter pos; /* Point d'insertion */ + GtkTextMark *mark; /* Marquage de ligne associée */ + vmpa_t done; /* Quantité déjà parcourue */ + + view = insertion->view; + + lines = GTK_BIN_VIEW(view)->lines; + last = GTK_BIN_VIEW(view)->last; + + iter = g_rendering_line_loop_for_code(lines, last); + start = get_rendering_line_address(lines); + + iter = g_rendering_line_get_last_iter(lines, last); + end = get_rendering_line_address(iter) + get_rendering_line_length(iter) - start; + + insertion->lengths[SAR_ADDRESS] = 0; + insertion->lengths[SAR_CODE] = 0; + insertion->lengths[SAR_INSTRUCTION] = 0; + + id = gtk_extended_status_bar_push(statusbar, _("Inserting lines..."), true); + + for (iter = lines; + iter != NULL; + iter = g_rendering_line_get_next_iter(lines, iter, last)) + { + g_signal_connect(iter, "rendering-line-flags-changed", + G_CALLBACK(gtk_block_view_update_margin), view); + + gdk_threads_enter(); + + if (iter != lines) + { + gtk_text_buffer_get_end_iter(view->buffer, &pos); + gtk_text_buffer_insert_with_tags(view->buffer, &pos, "\n", 1, NULL); + } + + gtk_text_buffer_get_end_iter(view->buffer, &pos); + + mark = gtk_text_buffer_create_mark(view->buffer, NULL, &pos, TRUE); + g_object_set_data(G_OBJECT(mark), "line", iter); + + g_content_exporter_add_to_gtk_buffer(G_CONTENT_EXPORTER(iter), view->rendering, + view->buffer, &pos, insertion->lengths); + + gdk_flush (); + gdk_threads_leave(); + + done = get_rendering_line_address(iter) + get_rendering_line_length(iter) - start; + gtk_extended_status_bar_update_activity(statusbar, id, done * 1.0 / end); + + } + + gtk_extended_status_bar_remove(statusbar, id); + +} + + + + + + + + + + + + + + + /* Détermine le type du composant d'affichage en block. */ G_DEFINE_TYPE(GtkBlockView, gtk_block_view, GTK_TYPE_BIN_VIEW) @@ -571,43 +793,6 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event) /* Impression du désassemblage */ - -#if 0 - gdk_window_begin_paint_region(GDK_DRAWABLE(widget->window), event->region); - - gdk_gc_set_clip_region(bview->gc, event->region); - - gdk_gc_get_values(bview->gc, &values); - - gdk_color_white(gtk_widget_get_colormap(widget), &white); - gdk_gc_set_foreground(bview->gc, &white); - - gtk_widget_get_size_request(widget, &width, &height); - - gdk_draw_rectangle(GDK_DRAWABLE(widget->window), bview->gc, - TRUE, 0, 0, width, height); - - gdk_gc_set_foreground(bview->gc, &values.foreground); - /* - y = event->area.y; - iter = g_rendering_line_find_by_y(bview->lines, bview->last, &y); - - y = event->area.y - y; - - for ( ; iter != NULL && y < (event->area.y + event->area.height); - iter = g_rendering_line_get_next_iter(bview->lines, iter, bview->last)) - { - g_rendering_line_draw(iter, GDK_DRAWABLE(widget->window), bview->gc, - MARGIN_SPACE, 2 * MARGIN_SPACE + GTK_BLOCK_VIEW(bview)->line_height, - y, GTK_BLOCK_VIEW(bview)->line_height, GTK_BLOCK_VIEW(bview)->rendering); - - y += GTK_BLOCK_VIEW(bview)->line_height; - - } - */ - gdk_window_end_paint(GDK_DRAWABLE(widget->window)); -#endif - gtk_text_layout_set_screen_width (GTK_BLOCK_VIEW(bview)->layout, MAX (1, 1000)); @@ -730,40 +915,48 @@ void gtk_block_view_set_format(GtkBlockView *view, const exe_format *format) static void gtk_block_view_set_rendering_lines(GtkBlockView *view, GRenderingLine *lines, GRenderingLine *last) { - size_t lengths[SAR_COUNT]; /* Différentes tailles de zone */ - GRenderingLine *iter; /* Boucle de parcours */ - GtkTextIter pos; /* Point d'insertion */ - GtkTextMark *mark; /* Marquage de ligne associée */ - PangoTabArray *tabs; /* Tailles de tabulation */ - GdkRectangle rect; /* Zone d'un point */ + GWorkQueue *queue; /* Gestionnaire de différés */ + GDelayedInsertion *insertion; /* Insertions à mener */ - lengths[SAR_ADDRESS] = 0; - lengths[SAR_CODE] = 0; - lengths[SAR_INSTRUCTION] = 0; + queue = get_work_queue(); - for (iter = GTK_BIN_VIEW(view)->lines; - iter != NULL; - iter = g_rendering_line_get_next_iter(GTK_BIN_VIEW(view)->lines, iter, GTK_BIN_VIEW(view)->last)) - { - g_signal_connect(iter, "rendering-line-flags-changed", - G_CALLBACK(gtk_block_view_update_margin), view); + insertion = g_delayed_insertion_new(view); - if (iter != GTK_BIN_VIEW(view)->lines) - { - gtk_text_buffer_get_end_iter(view->buffer, &pos); - gtk_text_buffer_insert_with_tags(view->buffer, &pos, "\n", 1, NULL); - } + g_signal_connect(insertion, "work-completed", + G_CALLBACK(gtk_block_view_complete_building_content), view); - gtk_text_buffer_get_end_iter(view->buffer, &pos); + g_work_queue_schedule_work(queue, G_DELAYED_WORK(insertion)); - mark = gtk_text_buffer_create_mark(view->buffer, NULL, &pos, TRUE); - g_object_set_data(G_OBJECT(mark), "line", iter); +} - g_content_exporter_add_to_gtk_buffer(G_CONTENT_EXPORTER(iter), view->rendering, - view->buffer, &pos, lengths); - } +/****************************************************************************** +* * +* Paramètres : insertion = travail d'insertion effectué. * +* view = composant GTK à mettre à jour. * +* * +* Description : Achève la construction de la visualisation des lignes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_block_view_complete_building_content(GDelayedInsertion *insertion, GtkBlockView *view) +{ + size_t lengths[SAR_COUNT]; /* Différentes tailles de zone */ + GtkTextIter pos; /* Point d'insertion */ + PangoTabArray *tabs; /* Tailles de tabulation */ + GdkRectangle rect; /* Zone d'un point */ + + lengths[SAR_ADDRESS] = insertion->lengths[SAR_ADDRESS]; + lengths[SAR_CODE] = insertion->lengths[SAR_CODE]; + lengths[SAR_INSTRUCTION] = insertion->lengths[SAR_INSTRUCTION]; + gdk_threads_enter(); + + gtk_text_buffer_get_end_iter(view->buffer, &pos); gtk_text_layout_move_iter_visually(view->layout, &pos, -1); gtk_text_layout_get_iter_location(view->layout, &pos, &rect); @@ -808,6 +1001,11 @@ static void gtk_block_view_set_rendering_lines(GtkBlockView *view, GRenderingLin gtk_block_view_recompute_size_request(view); + gdk_flush (); + gdk_threads_leave(); + + g_signal_emit_by_name(view, "lines-set"); + } |