diff options
Diffstat (limited to 'src/gtkext/gtkgraphview.c')
-rw-r--r-- | src/gtkext/gtkgraphview.c | 80 |
1 files changed, 72 insertions, 8 deletions
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c index cc2d930..d62cc33 100644 --- a/src/gtkext/gtkgraphview.c +++ b/src/gtkext/gtkgraphview.c @@ -45,6 +45,10 @@ struct _GtkGraphView GtkBinView **childs; /* Liste des sous-blocs */ size_t childs_count; /* Taille de cette liste */ + size_t ready; /* Construction complète */ + GMutex *mutex; /* Accès à la variable */ + GCond *cond; /* Attente de changement */ + GtkLinkRenderer **links; /* Liste des liens graphiques */ size_t links_count; /* Nombre de ces liens */ @@ -80,7 +84,10 @@ static void gtk_graph_view_define_main_address(GtkGraphView *, vmpa_t); static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *, vmpa_t, gint *, gint *); /* Définit la liste complète des éléments du futur graphique. */ -static GtkBinView **gtk_graph_view_load_nodes(GOpenidaBinary *, GRenderingLine *, GRenderingLine *, size_t *); +static GtkBinView **gtk_graph_view_load_nodes(GtkGraphView *, GOpenidaBinary *, GRenderingLine *, GRenderingLine *); + +/* Prend note de la fin d'une construction d'une visualisation. */ +static void notify_graph_view(GtkBinView *, GtkGraphView *); /* Détermine le type du composant d'affichage en graphique. */ @@ -132,6 +139,9 @@ static void gtk_graph_view_init(GtkGraphView *view) binview->define_address = (define_main_address_fc)gtk_graph_view_define_main_address; binview->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates; + view->mutex = g_mutex_new(); + view->cond = g_cond_new(); + } @@ -255,6 +265,8 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLin { gtk_graph_view_reset(view); + g_signal_emit_by_name(view, "lines-set"); + } @@ -308,7 +320,7 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr) first = g_rendering_line_find_by_address(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, start); last = g_rendering_line_find_by_address(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, end - 1); - view->childs = gtk_graph_view_load_nodes(GTK_BIN_VIEW(view)->binary, first, last, &view->childs_count); + view->childs = gtk_graph_view_load_nodes(view, GTK_BIN_VIEW(view)->binary, first, last); build_graph_view(GTK_FIXED(view), view->childs, view->childs_count); @@ -363,10 +375,10 @@ static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, vmp /****************************************************************************** * * -* Paramètres : binary = contenu binaire à l'origine des lignes. * +* Paramètres : view = composant d'affichage GTK à mettre à jour. * +* binary = contenu binaire à l'origine des lignes. * * first = première ligne à analyser. * * last = dernière ligne à analyser. * -* count = nombre d'éléments créés. [OUT] * * * * Description : Définit la liste complète des éléments du futur graphique. * * * @@ -376,16 +388,28 @@ static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, vmp * * ******************************************************************************/ -static GtkBinView **gtk_graph_view_load_nodes(GOpenidaBinary *binary, GRenderingLine *first, GRenderingLine *last, size_t *count) +static GtkBinView **gtk_graph_view_load_nodes(GtkGraphView *view, GOpenidaBinary *binary, GRenderingLine *first, GRenderingLine *last) { GtkBinView **result; /* Liste à retourner */ + size_t *count; /* Nombre d'éléments créés. */ GRenderingLine *begin; /* Début d'un groupe de lignes */ GRenderingLine *end; /* Fin d'un groupe de lignes */ GRenderingLine *iter; /* Boucle de parcours */ result = NULL; + + view->ready = 0; + + count = &view->childs_count; *count = 0; + /** + * Comme la fonction est appelée depuis un événement et utilise des threads et GTK, + * on doit lever temporairement le verrou GDK. + */ + gdk_flush (); + gdk_threads_leave(); + begin = NULL; for (iter = first; iter != NULL; iter = g_rendering_line_get_next_iter(first, iter, last)) @@ -395,7 +419,8 @@ static GtkBinView **gtk_graph_view_load_nodes(GOpenidaBinary *binary, GRendering result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *)); result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new(MRD_GRAPH)); - gtk_widget_show(GTK_WIDGET(result[*count - 1])); + + g_signal_connect(result[*count - 1], "lines-set", G_CALLBACK(notify_graph_view), view); gtk_bin_view_show_border(result[*count - 1], true); gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end); @@ -412,7 +437,8 @@ static GtkBinView **gtk_graph_view_load_nodes(GOpenidaBinary *binary, GRendering result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *)); result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new(MRD_GRAPH)); - gtk_widget_show(GTK_WIDGET(result[*count - 1])); + + g_signal_connect(result[*count - 1], "lines-set", G_CALLBACK(notify_graph_view), view); gtk_bin_view_show_border(result[*count - 1], true); gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end); @@ -428,13 +454,22 @@ static GtkBinView **gtk_graph_view_load_nodes(GOpenidaBinary *binary, GRendering result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *)); result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new(MRD_GRAPH)); - gtk_widget_show(GTK_WIDGET(result[*count - 1])); + + g_signal_connect(result[*count - 1], "lines-set", G_CALLBACK(notify_graph_view), view); gtk_bin_view_show_border(result[*count - 1], true); gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end); } + /* Attente de la fin de construction */ + g_mutex_lock(view->mutex); + while (view->ready < *count) + g_cond_wait(view->cond, view->mutex); + g_mutex_unlock(view->mutex); + + gdk_threads_enter(); + return result; @@ -443,6 +478,35 @@ static GtkBinView **gtk_graph_view_load_nodes(GOpenidaBinary *binary, GRendering /****************************************************************************** * * +* Paramètres : view = composant d'affichage prêt à utilisation. * +* parent = composant d'affichage supérieur. * +* * +* Description : Prend note de la fin d'une construction d'une visualisation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void notify_graph_view(GtkBinView *view, GtkGraphView *parent) +{ + g_mutex_lock(parent->mutex); + + parent->ready++; + + g_cond_signal(parent->cond); + g_mutex_unlock(parent->mutex); + + g_signal_handlers_disconnect_by_func(view, G_CALLBACK(notify_graph_view), parent); + + gtk_widget_show(GTK_WIDGET(view)); + +} + + +/****************************************************************************** +* * * Paramètres : view = composant GTK à mettre à jour. * * links = liens graphiques entre les blocs à intégrer. * * count = quantité de ces liens graphiques. * |