From 05a0e578f49fbd7c8614ce108ba790601663d8cd Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 8 Jun 2013 12:37:43 +0000 Subject: Removed all usages of gdk_threads_enter()/gdk_threads_leave() in the status bar. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@349 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 28 +++ src/analysis/disass/disassembler.c | 2 +- src/analysis/disass/fetch.c | 2 +- src/analysis/disass/fetch.h | 2 +- src/analysis/disass/limit.c | 2 +- src/analysis/disass/limit.h | 2 +- src/analysis/disass/links.c | 2 +- src/analysis/disass/links.h | 2 +- src/analysis/disass/loop.c | 2 +- src/analysis/disass/loop.h | 2 +- src/analysis/disass/macro.c | 2 +- src/analysis/disass/macro.h | 2 +- src/analysis/disass/output.c | 2 +- src/analysis/disass/output.h | 2 +- src/analysis/disass/rank.c | 2 +- src/analysis/disass/rank.h | 2 +- src/glibext/gcodebuffer.c | 2 +- src/gtkext/gtkextstatusbar.c | 342 +++++++++++++++++++++++++++++++------ src/gtkext/gtkextstatusbar.h | 41 ++--- src/gui/status.c | 2 +- 20 files changed, 347 insertions(+), 98 deletions(-) diff --git a/ChangeLog b/ChangeLog index cdc3e57..0fe93d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +13-06-08 Cyrille Bagard + + * src/analysis/disass/disassembler.c: + * src/analysis/disass/fetch.c: + * src/analysis/disass/fetch.h: + * src/analysis/disass/limit.c: + * src/analysis/disass/limit.h: + * src/analysis/disass/links.c: + * src/analysis/disass/links.h: + * src/analysis/disass/loop.c: + * src/analysis/disass/loop.h: + * src/analysis/disass/macro.c: + * src/analysis/disass/macro.h: + * src/analysis/disass/output.c: + * src/analysis/disass/output.h: + * src/analysis/disass/rank.c: + * src/analysis/disass/rank.h: + * src/glibext/gcodebuffer.c: + Update code. + + * src/gtkext/gtkextstatusbar.c: + * src/gtkext/gtkextstatusbar.h: + Remove all usages of gdk_threads_enter()/gdk_threads_leave() in the + status bar. Thus increase the speed of loading and portability. + + * src/gui/status.c: + Update code. + 13-06-02 Cyrille Bagard * configure.ac: diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 74b3add..f5f72f0 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -203,7 +203,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta #endif GBinRoutine **routines; /* Liste des routines trouvées */ size_t routines_count; /* Nombre de ces routines */ - guint id; /* Identifiant de statut */ + bstatus_id_t id; /* Identifiant de statut */ routines = g_binary_format_get_routines(G_BIN_FORMAT(disass->format), &routines_count); diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index a1df5e3..6ad9755 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -45,7 +45,7 @@ * * ******************************************************************************/ -GArchInstruction *disassemble_binary_parts(const GLoadedBinary *binary, GBinPart **parts, size_t count, GtkExtStatusBar *statusbar, guint id) +GArchInstruction *disassemble_binary_parts(const GLoadedBinary *binary, GBinPart **parts, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) { GArchInstruction *result; /* Liste d'instr. à renvoyer */ GBinFormat *format; /* Format du fichier binaire */ diff --git a/src/analysis/disass/fetch.h b/src/analysis/disass/fetch.h index 89c3226..d33784b 100644 --- a/src/analysis/disass/fetch.h +++ b/src/analysis/disass/fetch.h @@ -31,7 +31,7 @@ /* Procède au désassemblage basique d'un contenu binaire. */ -GArchInstruction *disassemble_binary_parts(const GLoadedBinary *, GBinPart **, size_t, GtkExtStatusBar *, guint); +GArchInstruction *disassemble_binary_parts(const GLoadedBinary *, GBinPart **, size_t, GtkExtStatusBar *, bstatus_id_t); diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c index 2598d7e..a000c07 100644 --- a/src/analysis/disass/limit.c +++ b/src/analysis/disass/limit.c @@ -49,7 +49,7 @@ static vmpa_t find_best_ending_address_for_routine(GArchInstruction *, size_t, c * * ******************************************************************************/ -void limit_all_routines(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, guint id) +void limit_all_routines(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) { size_t i; /* Boucle de parcours */ vmpa_t *starts; /* Adresses de départ */ diff --git a/src/analysis/disass/limit.h b/src/analysis/disass/limit.h index 7ef9396..e0d18dc 100644 --- a/src/analysis/disass/limit.h +++ b/src/analysis/disass/limit.h @@ -31,7 +31,7 @@ /* S'assure que toutes les routines ont une taille définie. */ -void limit_all_routines(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); +void limit_all_routines(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index df0c77f..595f783 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -41,7 +41,7 @@ * * ******************************************************************************/ -void establish_links_between_lines(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, guint id) +void establish_links_between_lines(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) { size_t i; /* Boucle de parcours */ vmpa_t start; /* Adresse de départ */ diff --git a/src/analysis/disass/links.h b/src/analysis/disass/links.h index 0ca7816..ec9feac 100644 --- a/src/analysis/disass/links.h +++ b/src/analysis/disass/links.h @@ -30,7 +30,7 @@ /* Etablit les liens entres les différentes lignes de code. */ -void establish_links_between_lines(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); +void establish_links_between_lines(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c index 6fd73f2..dc68253 100644 --- a/src/analysis/disass/loop.c +++ b/src/analysis/disass/loop.c @@ -274,7 +274,7 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end * * ******************************************************************************/ -void detect_loops_in_code(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, guint id) +void detect_loops_in_code(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) { size_t i; /* Boucle de parcours */ vmpa_t start; /* Adresse de départ */ diff --git a/src/analysis/disass/loop.h b/src/analysis/disass/loop.h index 8466405..b8d916f 100644 --- a/src/analysis/disass/loop.h +++ b/src/analysis/disass/loop.h @@ -31,7 +31,7 @@ /* Détecte les boucles dans du code machine. */ -void detect_loops_in_code(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); +void detect_loops_in_code(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c index ebd236a..43c4046 100644 --- a/src/analysis/disass/macro.c +++ b/src/analysis/disass/macro.c @@ -814,7 +814,7 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, const code * * ******************************************************************************/ -void group_routines_instructions(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, guint id) +void group_routines_instructions(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) { size_t i; /* Boucle de parcours */ vmpa_t start; /* Adresse de départ */ diff --git a/src/analysis/disass/macro.h b/src/analysis/disass/macro.h index 64df785..2e3358e 100644 --- a/src/analysis/disass/macro.h +++ b/src/analysis/disass/macro.h @@ -31,7 +31,7 @@ /* Regroupe les instructions par blocs. */ -void group_routines_instructions(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); +void group_routines_instructions(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index 135168e..fd34bc1 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -48,7 +48,7 @@ * * ******************************************************************************/ -void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *format, const GArchInstruction *instrs, GBinRoutine * const *routines, size_t count, GtkExtStatusBar *statusbar, guint id) +void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *format, const GArchInstruction *instrs, GBinRoutine * const *routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) { GLangOutput *output; /* Modèle de sortie adéquat */ GArchProcessor *proc; /* Architecture du binaire */ diff --git a/src/analysis/disass/output.h b/src/analysis/disass/output.h index 81c028d..13b2ef3 100644 --- a/src/analysis/disass/output.h +++ b/src/analysis/disass/output.h @@ -33,7 +33,7 @@ /* Transcrit du code désassemblé en texte humainement lisible. */ -void print_disassembled_instructions(GCodeBuffer *, const GExeFormat *, const GArchInstruction *, GBinRoutine * const *, size_t, GtkExtStatusBar *, guint); +void print_disassembled_instructions(GCodeBuffer *, const GExeFormat *, const GArchInstruction *, GBinRoutine * const *, size_t, GtkExtStatusBar *, bstatus_id_t); diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c index 6f12f31..a1c869f 100644 --- a/src/analysis/disass/rank.c +++ b/src/analysis/disass/rank.c @@ -403,7 +403,7 @@ void rank_routine_blocks(GBinRoutine *routine) * * ******************************************************************************/ -void rank_routines_blocks(GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, guint id) +void rank_routines_blocks(GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) { size_t i; /* Boucle de parcours */ diff --git a/src/analysis/disass/rank.h b/src/analysis/disass/rank.h index 04da689..935d5fb 100644 --- a/src/analysis/disass/rank.h +++ b/src/analysis/disass/rank.h @@ -34,7 +34,7 @@ void rank_routine_blocks(GBinRoutine *); /* Classe les blocs des routines. */ -void rank_routines_blocks(GBinRoutine **, size_t, GtkExtStatusBar *, guint); +void rank_routines_blocks(GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c index 920b17c..914a3d5 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -293,7 +293,7 @@ static void g_buffer_scan_process(GBufferScan *scan, GtkExtStatusBar *statusbar) size_t first; /* Première ligne visée */ size_t last; /* Dernière ligne visée + 1 */ GBufferLine **lines; /* Liste des lignes à traiter */ - guint id; /* Identifiant de statut */ + bstatus_id_t id; /* Identifiant de statut */ size_t i; /* Boucle de parcours */ /* TODO : lock scan->buffer->lines */ diff --git a/src/gtkext/gtkextstatusbar.c b/src/gtkext/gtkextstatusbar.c index 47fc154..9ac2aaf 100644 --- a/src/gtkext/gtkextstatusbar.c +++ b/src/gtkext/gtkextstatusbar.c @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * gtkextstatusbar.h - prototypes pour la barre de statut améliorée * - * Copyright (C) 2009-2012 Cyrille Bagard + * Copyright (C) 2009-2013 Cyrille Bagard * * This file is part of OpenIDA. * @@ -29,6 +29,45 @@ +/* ------------------------- GESTION EXTERIEURE DE LA BARRE ------------------------- */ + + +/* Elément de statut */ +typedef struct _bar_item +{ + char *message; /* Message à afficher */ + bool is_progressive; /* Utilisations de progression */ + double value; /* Valeur courante */ + + size_t index; /* Valeur pour l'identifiant */ + +} bar_item; + + +/* Abstration d'une gestion de barre de statut (instance) */ +struct _GtkExtStatusBar +{ + GtkStatusbar bar; /* Présence obligatoire en 1er */ + + guint context; /* Nouvel identifiant */ + guint cur_msg; /* Message courant */ + + GtkProgressBar *progress; /* Barre de progression */ + + bar_item *stack; /* Pile de statut de la barre */ + size_t stack_size; /* Taille de la pile */ + GMutex stack_access; /* Accès en à la pile */ + +}; + +/* Abstration d'une gestion de barre de statut (classe) */ +struct _GtkExtStatusBarClass +{ + GtkStatusbarClass parent_class; /* Présence obligatoire en 1er */ + +}; + + /* Initialise la classe des barres de statut améliorées. */ static void gtk_extended_status_bar_class_init(GtkExtStatusBarClass *); @@ -37,6 +76,45 @@ static void gtk_extended_status_bar_init(GtkExtStatusBar *); +/* ----------------------- MISES A JOUR EN CONTEXTE PRINCIPAL ----------------------- */ + + +/* Type de commande */ +typedef enum _DelayedUpdateCmd +{ + DUC_CHANGE_CONTENT, /* Elément ajouté ou retiré */ + DUC_UPDATE_ACTIVITY /* Mise à jour de progression */ + +} DelayedUpdateCmd; + +/* Transfert des commandes */ +typedef struct _bar_update_info +{ + GtkExtStatusBar *bar; /* Barre associée */ + DelayedUpdateCmd cmd; /* Type de commande */ + +} bar_update_info; + + +/* Met à jour la partie graphique de la barre de statut. */ +static gboolean gtk_extended_status_update(bar_update_info *); + +/* Libère la mémoire occupée par la transmission. */ +static void free_bar_update_info(bar_update_info *); + +/* Place un nouveau message dans la barre de statut. */ +static void _gtk_extended_status_bar_change_content(GtkExtStatusBar *); + +/* Met à jour la barre de progression de la barre de statut. */ +static void _gtk_extended_status_bar_update_activity(GtkExtStatusBar *); + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION EXTERIEURE DE LA BARRE */ +/* ---------------------------------------------------------------------------------- */ + + /* Détermine le type de la barre de statut améliorée. */ G_DEFINE_TYPE(GtkExtStatusBar, gtk_extended_status_bar, GTK_TYPE_STATUSBAR) @@ -84,6 +162,8 @@ static void gtk_extended_status_bar_init(GtkExtStatusBar *bar) gtk_box_pack_start(GTK_BOX(bar), GTK_WIDGET(bar->progress), FALSE, FALSE, 4); + g_mutex_init(&bar->stack_access); + } @@ -120,33 +200,39 @@ GtkWidget *gtk_extended_status_bar_new(void) * * ******************************************************************************/ -guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, gboolean progressive) +bstatus_id_t gtk_extended_status_bar_push(GtkExtStatusBar *bar, const char *message, bool progressive) { - guint result; /* Identifiant à retourner */ + bstatus_id_t result; /* Identifiant à retourner */ + size_t index; /* Indice du nouvel élément */ + bar_update_info *info; /* Informations à mémoriser */ - //gdk_threads_enter(); + /* Mise à jour de la pile */ - result = gtk_statusbar_push(GTK_STATUSBAR(bar), bar->context, message); + g_mutex_lock(&bar->stack_access); - bar->msg_count++; - bar->msg_id = (guint *)realloc(bar->msg_id, bar->msg_count * sizeof(guint)); - bar->is_progressive = (gboolean *)realloc(bar->is_progressive, bar->msg_count * sizeof(gboolean)); + bar->stack = (bar_item *)realloc(bar->stack, ++bar->stack_size * sizeof(bar_item)); - bar->msg_id[bar->msg_count - 1] = result; - bar->is_progressive[bar->msg_count - 1] = progressive; + index = bar->stack_size - 1; - if (progressive) - { - gtk_progress_bar_set_fraction(bar->progress, 0.0); - gtk_progress_bar_set_text(bar->progress, "0%"); + bar->stack[index].message = strdup(message); + bar->stack[index].is_progressive = progressive; + bar->stack[index].value = 0.0; + bar->stack[index].index = index; - gtk_widget_show(GTK_WIDGET(bar->progress)); + result = &bar->stack[index].index; - } - else gtk_widget_hide(GTK_WIDGET(bar->progress)); + g_mutex_unlock(&bar->stack_access); - //gdk_flush(); - //gdk_threads_leave(); + /* Mise à jour de l'affichage */ + + info = (bar_update_info *)calloc(1, sizeof(bar_update_info)); + + info->bar = bar; + g_object_ref(G_OBJECT(bar)); + info->cmd = DUC_CHANGE_CONTENT; + + gdk_threads_add_idle_full(G_PRIORITY_HIGH_IDLE, (GSourceFunc)gtk_extended_status_update, + info, (GDestroyNotify)free_bar_update_info); return result; @@ -167,28 +253,28 @@ guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, g * * ******************************************************************************/ -void gtk_extended_status_bar_update_activity(GtkExtStatusBar *bar, guint id, gdouble value) +void gtk_extended_status_bar_update_activity(GtkExtStatusBar *bar, bstatus_id_t id, double value) { - gchar percent[5]; /* Pourcentage en version txt. */ + bar_update_info *info; /* Informations à mémoriser */ - if (bar->msg_count == 0) return; + /* Mise à jour de la pile */ - if (id == bar->msg_id[bar->msg_count - 1] && bar->is_progressive[bar->msg_count - 1]) - { - if (value != 1.0 && value - gtk_progress_bar_get_fraction(bar->progress) < 0.01) - return; + g_mutex_lock(&bar->stack_access); - g_snprintf(percent, 5, "%.0f%%", value * 100); + bar->stack[*id].value = value; - gdk_threads_enter(); + g_mutex_unlock(&bar->stack_access); - gtk_progress_bar_set_fraction(bar->progress, value); - gtk_progress_bar_set_text(bar->progress, percent); + /* Mise à jour de l'affichage */ - gdk_flush(); - gdk_threads_leave(); + info = (bar_update_info *)calloc(1, sizeof(bar_update_info)); - } + info->bar = bar; + g_object_ref(G_OBJECT(bar)); + info->cmd = DUC_UPDATE_ACTIVITY; + + gdk_threads_add_idle_full(G_PRIORITY_HIGH_IDLE, (GSourceFunc)gtk_extended_status_update, + info, (GDestroyNotify)free_bar_update_info); } @@ -206,35 +292,191 @@ void gtk_extended_status_bar_update_activity(GtkExtStatusBar *bar, guint id, gdo * * ******************************************************************************/ -void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, guint id) +void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, bstatus_id_t id) { + size_t index; /* Indice de l'élément visé */ size_t i; /* Boucle de parcours */ + bar_update_info *info; /* Informations à mémoriser */ - //gdk_threads_enter(); + /* Mise à jour de la pile */ - gtk_statusbar_remove(GTK_STATUSBAR(bar), bar->context, id); + g_mutex_lock(&bar->stack_access); - for (i = 0; i < bar->msg_count; i++) - if (bar->msg_id[i] == id) - break; + index = *id; - if ((i + 1) < bar->msg_count) + free(bar->stack[index].message); + + if ((index + 1) < bar->stack_size) { - memmove(&bar->msg_id[i], &bar->msg_id[i + 1], (bar->msg_count - i - 1) * sizeof(guint)); - memmove(&bar->is_progressive[i], &bar->is_progressive[i + 1], (bar->msg_count - i - 1) * sizeof(gboolean)); + memmove(&bar->stack[index], &bar->stack[index + 1], + (bar->stack_size - index - 1) * sizeof(bar_item)); + + for (i = index; i < bar->stack_size; i++) + bar->stack[i].index = i; + } - bar->msg_count--; - bar->msg_id = (guint *)realloc(bar->msg_id, bar->msg_count * sizeof(guint)); - bar->is_progressive = (gboolean *)realloc(bar->is_progressive, bar->msg_count * sizeof(gboolean)); + bar->stack = (bar_item *)realloc(bar->stack, --bar->stack_size * sizeof(bar_item)); - if (bar->msg_count > 0 && bar->is_progressive[bar->msg_count - 1]) - gtk_widget_show(GTK_WIDGET(bar->progress)); + g_mutex_unlock(&bar->stack_access); - else + /* Mise à jour de l'affichage */ + + info = (bar_update_info *)calloc(1, sizeof(bar_update_info)); + + info->bar = bar; + g_object_ref(G_OBJECT(bar)); + info->cmd = DUC_CHANGE_CONTENT; + + gdk_threads_add_idle_full(G_PRIORITY_HIGH_IDLE, (GSourceFunc)gtk_extended_status_update, + info, (GDestroyNotify)free_bar_update_info); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* MISES A JOUR EN CONTEXTE PRINCIPAL */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : info = informations à consulter pour l'opération. * +* * +* Description : Met à jour la partie graphique de la barre de statut. * +* * +* Retour : FALSE pour faire disparaître la mise à jour ensuite. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_extended_status_update(bar_update_info *info) +{ + switch (info->cmd) + { + case DUC_CHANGE_CONTENT: + _gtk_extended_status_bar_change_content(info->bar); + /*break;*/ + + case DUC_UPDATE_ACTIVITY: + _gtk_extended_status_bar_update_activity(info->bar); + break; + + } + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : info = informations à libérer de la mémoire. * +* * +* Description : Libère la mémoire occupée par la transmission. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void free_bar_update_info(bar_update_info *info) +{ + g_object_unref(G_OBJECT(info->bar)); + + free(info); + +} + + +/****************************************************************************** +* * +* Paramètres : bar = barre de statut à manipuler. * +* * +* Description : Place un nouveau message dans la barre de statut. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _gtk_extended_status_bar_change_content(GtkExtStatusBar *bar) +{ + size_t top; /* Indice de l'élément visé */ + + g_mutex_lock(&bar->stack_access); + + if (bar->cur_msg > 0) + gtk_statusbar_remove(GTK_STATUSBAR(bar), bar->context, bar->cur_msg); + + if (bar->stack_size == 0) gtk_widget_hide(GTK_WIDGET(bar->progress)); - //gdk_flush(); - //gdk_threads_leave(); + else + { + top = bar->stack_size - 1; + + bar->cur_msg = gtk_statusbar_push(GTK_STATUSBAR(bar), bar->context, + bar->stack[top].message); + + if (bar->stack[top].is_progressive) + gtk_widget_show(GTK_WIDGET(bar->progress)); + else + gtk_widget_hide(GTK_WIDGET(bar->progress)); + + } + + g_mutex_unlock(&bar->stack_access); + +} + + +/****************************************************************************** +* * +* Paramètres : bar = barre de statut à manipuler. * +* * +* Description : Met à jour la barre de progression de la barre de statut. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _gtk_extended_status_bar_update_activity(GtkExtStatusBar *bar) +{ + size_t top; /* Indice de l'élément visé */ + double value; /* Valeur à prendre en compte */ + gchar percent[5]; /* Pourcentage en version txt. */ + + g_mutex_lock(&bar->stack_access); + + if (bar->stack_size > 0) + { + top = bar->stack_size - 1; + + if (bar->stack[top].is_progressive) + { + value = bar->stack[top].value; + + if (value != 1.0 && value - gtk_progress_bar_get_fraction(bar->progress) < 0.01) + goto gesbua_exit; + + g_snprintf(percent, 5, "%.0f%%", value * 100); + + gtk_progress_bar_set_fraction(bar->progress, value); + gtk_progress_bar_set_text(bar->progress, percent); + + } + + } + + gesbua_exit: + + g_mutex_unlock(&bar->stack_access); } diff --git a/src/gtkext/gtkextstatusbar.h b/src/gtkext/gtkextstatusbar.h index b5fe210..3c3da60 100644 --- a/src/gtkext/gtkextstatusbar.h +++ b/src/gtkext/gtkextstatusbar.h @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * gtkextstatusbar.h - prototypes pour la barre de statut améliorée * - * Copyright (C) 2009-2012 Cyrille Bagard + * Copyright (C) 2009-2013 Cyrille Bagard * * This file is part of OpenIDA. * @@ -25,44 +25,26 @@ #define _GTKEXT_GTKEXTSTATUSBAR_H +#include #include -G_BEGIN_DECLS - - - #define GTK_TYPE_EXT_STATUS_BAR (gtk_extended_status_bar_get_type()) #define GTK_EXT_STATUS_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, gtk_extended_status_bar_get_type (), GtkExtStatusBar)) #define GTK_IS_EXT_STATUS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, gtk_extended_status_bar_get_type())) #define GTK_EXT_STATUS_BAR_CLASS(klass) (G_LOADED_BINARY_GET_CLASS(klass, gtk_extended_status_bar_get_type(), GtkExtStatusBarClass)) +/* Abstration d'une gestion de barre de statut (instance) */ typedef struct _GtkExtStatusBar GtkExtStatusBar; -typedef struct _GtkExtStatusBarClass GtkExtStatusBarClass; - - - -struct _GtkExtStatusBar -{ - GtkStatusbar bar; /* Présence obligatoire en 1er */ - guint context; /* Nouvel identifiant */ - - GtkProgressBar *progress; /* Barre de progression */ - - guint *msg_id; /* Liste des identifiants */ - gboolean *is_progressive; /* Utilisations de progression */ - size_t msg_count; /* Nombre de messages empilés */ - -}; +/* Abstration d'une gestion de barre de statut (classe) */ +typedef struct _GtkExtStatusBarClass GtkExtStatusBarClass; -struct _GtkExtStatusBarClass -{ - GtkStatusbarClass parent_class; /* Présence obligatoire en 1er */ -}; +/* Identifiant d'un message de statut */ +typedef size_t * bstatus_id_t; /* Détermine le type de la barre de statut améliorée. */ @@ -72,17 +54,14 @@ GType gtk_extended_status_bar_get_type(void); GtkWidget *gtk_extended_status_bar_new(void); /* Place un nouveau message dans la barre de statut. */ -guint gtk_extended_status_bar_push(GtkExtStatusBar *, const gchar *, gboolean); +bstatus_id_t gtk_extended_status_bar_push(GtkExtStatusBar *, const gchar *, bool); /* Met à jour la barre de progression de la barre de statut. */ -void gtk_extended_status_bar_update_activity(GtkExtStatusBar *, guint, gdouble); +void gtk_extended_status_bar_update_activity(GtkExtStatusBar *, bstatus_id_t, double); /* Retire de la barre un statut, visible ou non. */ -void gtk_extended_status_bar_remove(GtkExtStatusBar *, guint); - - +void gtk_extended_status_bar_remove(GtkExtStatusBar *, bstatus_id_t); -G_END_DECLS #endif /* _GTKEXT_GTKEXTSTATUSBAR_H */ diff --git a/src/gui/status.c b/src/gui/status.c index 16a3ff8..9d035b8 100644 --- a/src/gui/status.c +++ b/src/gui/status.c @@ -45,7 +45,7 @@ struct _GStatusInfo GEditorItem parent; /* A laisser en premier */ GObject *caret_instance; /* Dernier émetteur de signaux */ - guint msg_id; /* Identifiant du dernier msg. */ + bstatus_id_t msg_id; /* Identifiant du dernier msg. */ }; -- cgit v0.11.2-87-g4458