From 47be9ff57e72906660bb62a515222f482131e1fb Mon Sep 17 00:00:00 2001 From: Miroslav Grepl Date: Fri, 11 Apr 2014 09:37:53 +0200 Subject: Create setools-3.3.7 git repo --- sediff/progress.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 sediff/progress.c (limited to 'sediff/progress.c') diff --git a/sediff/progress.c b/sediff/progress.c new file mode 100644 index 0000000..efaa120 --- /dev/null +++ b/sediff/progress.c @@ -0,0 +1,202 @@ +/** + * @file + * Routines to show a progress dialog, indicating that the + * application is doing something. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2006-2007 Tresys Technology, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "progress.h" +#include "utilgui.h" + +#include +#include +#include + +struct progress +{ + toplevel_t *top; + GtkWidget *progress; + GtkWidget *label1, *label2; + char *s; + int done; + GCond *cond; + GMutex *mutex; +}; + +progress_t *progress_create(toplevel_t * top) +{ + progress_t *p; + GtkWidget *vbox; + + if ((p = calloc(1, sizeof(*p))) == NULL) { + return NULL; + } + p->top = top; + p->progress = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_modal(GTK_WINDOW(p->progress), TRUE); + gtk_window_set_transient_for(GTK_WINDOW(p->progress), toplevel_get_window(top)); + gtk_window_set_default_size(GTK_WINDOW(p->progress), 300, 100); + vbox = gtk_vbox_new(FALSE, 2); + gtk_container_add(GTK_CONTAINER(p->progress), vbox); + p->label1 = gtk_label_new(NULL); + gtk_container_add(GTK_CONTAINER(vbox), p->label1); + p->label2 = gtk_label_new(NULL); + gtk_container_add(GTK_CONTAINER(vbox), p->label2); + gtk_widget_show(p->label1); + gtk_widget_show(p->label2); + gtk_widget_show(vbox); + util_cursor_wait(p->progress); + p->cond = g_cond_new(); + p->mutex = g_mutex_new(); + return p; +} + +void progress_destroy(progress_t ** progress) +{ + if (progress != NULL && *progress != NULL) { + free((*progress)->s); + g_cond_free((*progress)->cond); + g_mutex_free((*progress)->mutex); + free(*progress); + *progress = NULL; + } +} + +void progress_show(progress_t * progress, const char *title) +{ + gtk_label_set_text(GTK_LABEL(progress->label1), title); + gtk_label_set_text(GTK_LABEL(progress->label2), ""); + gtk_widget_show(progress->progress); + gtk_window_deiconify(GTK_WINDOW(progress->progress)); + gtk_window_set_title(GTK_WINDOW(progress->progress), title); + progress->done = 0; +} + +void progress_hide(progress_t * progress) +{ + gtk_widget_hide(progress->progress); +} + +int progress_wait(progress_t * progress) +{ + GTimeVal wait_time = { 0, 50000 }; + g_mutex_lock(progress->mutex); + while (!progress->done) { + if (progress->s != NULL) { + gtk_label_set_text(GTK_LABEL(progress->label2), progress->s); + free(progress->s); + progress->s = NULL; + } + // only process one event -- the policy source could + // still be loading, and this dialog should not block + // until the entire source has been read + gtk_main_iteration_do(FALSE); + g_cond_timed_wait(progress->cond, progress->mutex, &wait_time); + } + g_mutex_unlock(progress->mutex); + if (progress->done < 0) { + toplevel_ERR(progress->top, GTK_LABEL(progress->label2)->label); + return progress->done; + } else if (progress->done > 1) { + toplevel_WARN(progress->top, GTK_LABEL(progress->label2)->label); + return progress->done - 1; + } else { + progress->done = 0; + return 0; + } +} + +void progress_done(progress_t * progress) +{ + g_mutex_lock(progress->mutex); + progress->done = 1; + g_cond_signal(progress->cond); + g_mutex_unlock(progress->mutex); +} + +void progress_warn(progress_t * progress, char *reason, ...) +{ + gchar *s; + va_list ap; + g_mutex_lock(progress->mutex); + if (reason != NULL) { + va_start(ap, reason); + g_vasprintf(&s, reason, ap); + free(progress->s); + progress->s = s; + va_end(ap); + } + progress->done = 2; + g_cond_signal(progress->cond); + g_mutex_unlock(progress->mutex); +} + +void progress_abort(progress_t * progress, char *reason, ...) +{ + gchar *s; + va_list ap; + g_mutex_lock(progress->mutex); + if (reason != NULL) { + va_start(ap, reason); + g_vasprintf(&s, reason, ap); + free(progress->s); + progress->s = s; + va_end(ap); + } + progress->done = -1; + g_cond_signal(progress->cond); + g_mutex_unlock(progress->mutex); +} + +static void progress_update_label(progress_t * progress, const char *fmt, va_list va_args) +{ + gchar *s = NULL; + g_vasprintf(&s, fmt, va_args); + g_mutex_lock(progress->mutex); + free(progress->s); + progress->s = s; + g_cond_signal(progress->cond); + g_mutex_unlock(progress->mutex); +} + +void progress_update(progress_t * progress, char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + progress_update_label(progress, fmt, ap); + va_end(ap); +} + +void progress_poldiff_handle_func(void *arg, const poldiff_t * diff __attribute__ ((unused)), int level + __attribute__ ((unused)), const char *fmt, va_list va_args) +{ + progress_t *progress = arg; + progress_update_label(progress, fmt, va_args); +} + +void progress_apol_handle_func(void *varg, const apol_policy_t * p __attribute__ ((unused)), int level + __attribute__ ((unused)), const char *fmt, va_list argp) +{ + progress_t *progress = varg; + progress_update_label(progress, fmt, argp); +} -- cgit