diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2014-10-16 23:01:32 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2014-10-16 23:01:32 (GMT) |
commit | ec6aa436f4a1ae486feb7a88b2b8e793b59674d4 (patch) | |
tree | 49798a3502c3e4c807d48a41c11289850024959a /src/gui | |
parent | 6d34dbbb00da0c276261d0e1ce4bf862f22fd8e0 (diff) |
Allowed log messages from every thread contexts.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@415 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/panels/log.c | 218 |
1 files changed, 162 insertions, 56 deletions
diff --git a/src/gui/panels/log.c b/src/gui/panels/log.c index 883c85c..3e56519 100644 --- a/src/gui/panels/log.c +++ b/src/gui/panels/log.c @@ -28,6 +28,7 @@ #include <malloc.h> #include <stdarg.h> #include <stdio.h> +#include <string.h> #include <gtk/gtk.h> @@ -43,10 +44,33 @@ typedef enum _LogColumn } LogColumn; +/* Paramètres à transmettre pour un affichage */ +typedef struct _log_data +{ + GPanelItem *item; /* Intermédiaire mis en place */ + LogMessageType type; /* Type de message à afficher */ + char *msg; /* Contenu du message */ + +} log_data; + +/* Paramètres à transmettre pour un défilement */ +typedef struct _scroll_data +{ + GtkTreeView *treeview; /* Affichage de la liste */ + GtkTreePath *path; /* Chemin d'accès à cibler */ + +} scroll_data; + /* Construit le panneau d'affichage des messages système. */ static GtkWidget *build_log_panel(void); +/* Affiche un message dans le journal des messages système. */ +static void _log_simple_message(LogMessageType, char *); + +/* Affiche un message dans le journal des messages système. */ +static gboolean log_message(log_data *); + /****************************************************************************** @@ -149,126 +173,208 @@ static GtkWidget *build_log_panel(void) void log_simple_message(LogMessageType type, const char *msg) { + _log_simple_message(type, strdup(msg)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = espèce du message à ajouter. * +* msg = message à faire apparaître à l'écran. * +* * +* Description : Affiche un message dans le journal des messages système. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _log_simple_message(LogMessageType type, char *msg) +{ GPanelItem *item; /* Intermédiaire mis en place */ + log_data *data; /* Paramètres à joindre */ + + item = g_panel_item_get(PANEL_LOG_ID); + + data = (log_data *)calloc(1, sizeof(log_data)); + + data->item = item; + data->type = type; + data->msg = msg; + + g_object_ref(G_OBJECT(data->item)); + + g_main_context_invoke(NULL, (GSourceFunc)log_message, data); + +} + + +/****************************************************************************** +* * +* Paramètres : type = espèce du message à ajouter. * +* fmt = format du message à faire apparaître à l'écran. * +* ... = éventuels arguments venant compléter le message. * +* * +* Description : Affiche un message dans le journal des messages système. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void log_variadic_message(LogMessageType type, const char *fmt, ...) +{ + size_t len; /* Taille tampon disponible */ + char *buffer; /* Tampon du msg reconstitué */ + int ret; /* Bilan d'une impression */ + char *ptr; /* Nouvelle allocation */ + va_list ap; /* Liste d'arguments variable */ + + len = VARIADIC_LOG_BUFSIZE; + buffer = calloc(len, sizeof(char)); + + while (buffer != NULL) + { + va_start(ap, fmt); + ret = vsnprintf(buffer, len, fmt, ap); + va_end(ap); + + if (ret >= 0 && ret < len) break; + + else + { + if (ret > -1) len += 1; /* glibc 2.1 */ + else len *= 2; /* glibc 2.0 */ + + if ((ptr = realloc(buffer, len)) == NULL) + { + free(buffer); + buffer = NULL; + } + else buffer = ptr; + + } + + } + + _log_simple_message(type, buffer); + +} + + +/****************************************************************************** +* * +* Paramètres : data = paramètres destinés à l'affichage d'un message. * +* * +* Description : Affiche un message dans le journal des messages système. * +* * +* Retour : - * +* * +* Remarques : Cette fonction, et c'est tout son intérêt, est toujours * +* exécutée dans le contexte GTK principal. * +* * +******************************************************************************/ + +static gboolean log_message(log_data *data) +{ GtkWidget *panel; /* Panneau à traiter */ GtkTreeStore *store; /* Modèle de gestion */ GtkTreeIter iter; /* Point d'insertion */ GtkTreeView *treeview; /* Affichage de la liste */ GtkTreePath *path; /* Chemin d'accès à la ligne */ + scroll_data *sdata; /* Paramètres de défilement */ - item = g_panel_item_get(PANEL_LOG_ID); - panel = g_editor_item_get_widget(G_EDITOR_ITEM(item)); + /* Mise en place du message */ + + panel = g_editor_item_get_widget(G_EDITOR_ITEM(data->item)); store = g_object_get_data(G_OBJECT(panel), "store"); gtk_tree_store_append(store, &iter, NULL); - switch (type) + switch (data->type) { case LMT_INFO: gtk_tree_store_set(store, &iter, LGC_PICTURE, "gtk-info", - LGC_STRING, msg, + LGC_STRING, data->msg, -1); break; case LMT_BAD_BINARY: gtk_tree_store_set(store, &iter, LGC_PICTURE, "gtk-dialog-warning", - LGC_STRING, msg, + LGC_STRING, data->msg, -1); break; case LMT_PROCESS: gtk_tree_store_set(store, &iter, LGC_PICTURE, "gtk-execute", - LGC_STRING, msg, + LGC_STRING, data->msg, -1); break; case LMT_ERROR: gtk_tree_store_set(store, &iter, LGC_PICTURE, "gtk-dialog-error", - LGC_STRING, msg, + LGC_STRING, data->msg, -1); break; case LMT_WARNING: gtk_tree_store_set(store, &iter, LGC_PICTURE, "gtk-dialog-warning", - LGC_STRING, msg, + LGC_STRING, data->msg, -1); break; default: gtk_tree_store_set(store, &iter, - LGC_STRING, msg, + LGC_STRING, data->msg, -1); break; } - treeview = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(panel), "treeview")); - path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); + /* Défilement pour pointer à l'affichage */ - gtk_tree_view_scroll_to_cell(treeview, path, NULL, FALSE, 0.0, 0.0); + gboolean wait_for_scrolling(scroll_data *_data) + { + gtk_tree_view_scroll_to_cell(_data->treeview, _data->path, NULL, FALSE, 0.0, 0.0); - gtk_tree_path_free(path); + g_object_unref(G_OBJECT(_data->treeview)); + gtk_tree_path_free(_data->path); -} + free(_data); + return G_SOURCE_REMOVE; -/****************************************************************************** -* * -* Paramètres : type = espèce du message à ajouter. * -* fmt = format du message à faire apparaître à l'écran. * -* ... = éventuels arguments venant compléter le message. * -* * -* Description : Affiche un message dans le journal des messages système. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + } -void log_variadic_message(LogMessageType type, const char *fmt, ...) -{ - size_t len; /* Taille tampon disponible */ - char *buffer; /* Tampon du msg reconstitué */ - int ret; /* Bilan d'une impression */ - char *ptr; /* Nouvelle allocation */ - va_list ap; /* Liste d'arguments variable */ + treeview = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(panel), "treeview")); + path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); - len = VARIADIC_LOG_BUFSIZE; - buffer = calloc(len, sizeof(char)); + sdata = (scroll_data *)calloc(1, sizeof(log_data)); - while (buffer != NULL) - { - va_start(ap, fmt); - ret = vsnprintf(buffer, len, fmt, ap); - va_end(ap); + sdata->treeview = treeview; + sdata->path = path; - if (ret >= 0 && ret < len) break; + g_object_ref(G_OBJECT(sdata->treeview)); - else - { - if (ret > -1) len += 1; /* glibc 2.1 */ - else len *= 2; /* glibc 2.0 */ + g_idle_add((GSourceFunc)wait_for_scrolling, sdata); - if ((ptr = realloc(buffer, len)) == NULL) - { - free(buffer); - buffer = NULL; - } - else buffer = ptr; + /* Nettoyage de la mémoire */ - } + g_object_unref(G_OBJECT(data->item)); - } + free(data->msg); - log_simple_message(type, buffer); + free(data); - free(buffer); + return G_SOURCE_REMOVE; } |