Added target progress
This commit is contained in:
parent
4ca4916a79
commit
2298a2d670
1
Makefile
1
Makefile
|
@ -23,6 +23,7 @@ dist:
|
||||||
@$(TAR) $(PACKAGE)-$(VERSION).tar.gz \
|
@$(TAR) $(PACKAGE)-$(VERSION).tar.gz \
|
||||||
$(PACKAGE)-$(VERSION)/src/calendar.c \
|
$(PACKAGE)-$(VERSION)/src/calendar.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/fontsel.c \
|
$(PACKAGE)-$(VERSION)/src/fontsel.c \
|
||||||
|
$(PACKAGE)-$(VERSION)/src/progress.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/run.c \
|
$(PACKAGE)-$(VERSION)/src/run.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/Makefile \
|
$(PACKAGE)-$(VERSION)/src/Makefile \
|
||||||
$(PACKAGE)-$(VERSION)/src/project.conf \
|
$(PACKAGE)-$(VERSION)/src/project.conf \
|
||||||
|
|
15
src/Makefile
15
src/Makefile
|
@ -1,4 +1,4 @@
|
||||||
TARGETS = calendar fontsel run
|
TARGETS = calendar fontsel progress run
|
||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
DESTDIR =
|
DESTDIR =
|
||||||
BINDIR = $(PREFIX)/bin
|
BINDIR = $(PREFIX)/bin
|
||||||
|
@ -27,6 +27,12 @@ fontsel_CFLAGS = $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
|
||||||
fontsel: $(fontsel_OBJS)
|
fontsel: $(fontsel_OBJS)
|
||||||
$(CC) -o fontsel $(fontsel_OBJS) $(LDFLAGSF) $(LDFLAGS)
|
$(CC) -o fontsel $(fontsel_OBJS) $(LDFLAGSF) $(LDFLAGS)
|
||||||
|
|
||||||
|
progress_OBJS = progress.o
|
||||||
|
progress_CFLAGS = $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
|
||||||
|
|
||||||
|
progress: $(progress_OBJS)
|
||||||
|
$(CC) -o progress $(progress_OBJS) $(LDFLAGSF) $(LDFLAGS)
|
||||||
|
|
||||||
run_OBJS = run.o
|
run_OBJS = run.o
|
||||||
run_CFLAGS = $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
|
run_CFLAGS = $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
|
||||||
|
|
||||||
|
@ -39,11 +45,14 @@ calendar.o: calendar.c
|
||||||
fontsel.o: fontsel.c
|
fontsel.o: fontsel.c
|
||||||
$(CC) $(fontsel_CFLAGS) -c fontsel.c
|
$(CC) $(fontsel_CFLAGS) -c fontsel.c
|
||||||
|
|
||||||
|
progress.o: progress.c
|
||||||
|
$(CC) $(progress_CFLAGS) -c progress.c
|
||||||
|
|
||||||
run.o: run.c
|
run.o: run.c
|
||||||
$(CC) $(run_CFLAGS) -c run.c
|
$(CC) $(run_CFLAGS) -c run.c
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) $(calendar_OBJS) $(fontsel_OBJS) $(run_OBJS)
|
$(RM) $(calendar_OBJS) $(fontsel_OBJS) $(progress_OBJS) $(run_OBJS)
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
$(RM) $(TARGETS)
|
$(RM) $(TARGETS)
|
||||||
|
@ -52,11 +61,13 @@ install: all
|
||||||
$(MKDIR) $(DESTDIR)$(BINDIR)
|
$(MKDIR) $(DESTDIR)$(BINDIR)
|
||||||
$(INSTALL) -m 0755 calendar $(DESTDIR)$(BINDIR)/calendar
|
$(INSTALL) -m 0755 calendar $(DESTDIR)$(BINDIR)/calendar
|
||||||
$(INSTALL) -m 0755 fontsel $(DESTDIR)$(BINDIR)/fontsel
|
$(INSTALL) -m 0755 fontsel $(DESTDIR)$(BINDIR)/fontsel
|
||||||
|
$(INSTALL) -m 0755 progress $(DESTDIR)$(BINDIR)/progress
|
||||||
$(INSTALL) -m 0755 run $(DESTDIR)$(BINDIR)/run
|
$(INSTALL) -m 0755 run $(DESTDIR)$(BINDIR)/run
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
$(RM) $(DESTDIR)$(BINDIR)/calendar
|
$(RM) $(DESTDIR)$(BINDIR)/calendar
|
||||||
$(RM) $(DESTDIR)$(BINDIR)/fontsel
|
$(RM) $(DESTDIR)$(BINDIR)/fontsel
|
||||||
|
$(RM) $(DESTDIR)$(BINDIR)/progress
|
||||||
$(RM) $(DESTDIR)$(BINDIR)/run
|
$(RM) $(DESTDIR)$(BINDIR)/run
|
||||||
|
|
||||||
.PHONY: all clean distclean install uninstall
|
.PHONY: all clean distclean install uninstall
|
||||||
|
|
215
src/progress.c
Normal file
215
src/progress.c
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
/* $Id$ */
|
||||||
|
/* Copyright (c) 2007 Pierre Pronchery <khorben@defora.org> */
|
||||||
|
/* This file is part of DeforaOS Desktop Accessories */
|
||||||
|
/* Accessories is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License version 2 as published by the
|
||||||
|
* Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Accessories 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
|
||||||
|
* Accessories; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
* Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
/* TODO:
|
||||||
|
* - speed estimation
|
||||||
|
* - implement -z
|
||||||
|
* - separate preferences from internal data */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* types */
|
||||||
|
typedef struct _Prefs
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
char * filename;
|
||||||
|
size_t length;
|
||||||
|
/* XXX internal data */
|
||||||
|
int fd;
|
||||||
|
int fds[2];
|
||||||
|
pid_t pid;
|
||||||
|
GtkWidget * progress;
|
||||||
|
} Prefs;
|
||||||
|
#define PREFS_z 0x1
|
||||||
|
|
||||||
|
|
||||||
|
/* progress */
|
||||||
|
/* functions */
|
||||||
|
static int _progress_error(char const * message, int ret);
|
||||||
|
static int _progress_exec(Prefs * prefs, char * argv[]);
|
||||||
|
|
||||||
|
/* callbacks */
|
||||||
|
static gboolean _progress_out(GIOChannel * source, GIOCondition condition,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
|
static int _progress(Prefs * prefs, char * argv[])
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
GIOChannel * channel;
|
||||||
|
GtkWidget * window = NULL;
|
||||||
|
GtkWidget * vbox;
|
||||||
|
GtkWidget * widget;
|
||||||
|
|
||||||
|
if(prefs->filename == NULL)
|
||||||
|
prefs->filename = "Standard input";
|
||||||
|
else if((prefs->fd = open(prefs->filename, O_RDONLY)) < 0)
|
||||||
|
return _progress_error(prefs->filename, 1);
|
||||||
|
else if(fstat(prefs->fd, &st) == 0)
|
||||||
|
prefs->length = st.st_size;
|
||||||
|
if(pipe(prefs->fds) != 0)
|
||||||
|
{
|
||||||
|
close(prefs->fd);
|
||||||
|
return _progress_error("pipe", 1);
|
||||||
|
}
|
||||||
|
channel = g_io_channel_unix_new(prefs->fds[1]);
|
||||||
|
g_io_add_watch(channel, G_IO_OUT, _progress_out, prefs);
|
||||||
|
if((prefs->pid = fork()) == -1)
|
||||||
|
{
|
||||||
|
close(prefs->fd);
|
||||||
|
close(prefs->fds[0]);
|
||||||
|
close(prefs->fds[1]);
|
||||||
|
return _progress_error("fork", 1);
|
||||||
|
}
|
||||||
|
if(prefs->pid != 0)
|
||||||
|
return _progress_exec(prefs, argv);
|
||||||
|
close(prefs->fds[0]);
|
||||||
|
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_window_set_title(GTK_WINDOW(window), "Progress");
|
||||||
|
vbox = gtk_vbox_new(FALSE, 0);
|
||||||
|
widget = gtk_label_new(prefs->filename);
|
||||||
|
gtk_box_pack_start(GTK_BOX(vbox), widget, TRUE, TRUE, 4);
|
||||||
|
prefs->progress = gtk_progress_bar_new();
|
||||||
|
gtk_box_pack_start(GTK_BOX(vbox), prefs->progress, TRUE, TRUE, 4);
|
||||||
|
gtk_container_add(GTK_CONTAINER(window), vbox);
|
||||||
|
gtk_container_set_border_width(GTK_CONTAINER(window), 4);
|
||||||
|
gtk_widget_show_all(window);
|
||||||
|
gtk_main();
|
||||||
|
close(prefs->fd);
|
||||||
|
close(prefs->fds[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _progress_error(char const * message, int ret)
|
||||||
|
{
|
||||||
|
GtkWidget * dialog;
|
||||||
|
|
||||||
|
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s: %s",
|
||||||
|
message, strerror(errno));
|
||||||
|
gtk_window_set_title(GTK_WINDOW(dialog), "Error");
|
||||||
|
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int _progress_exec(Prefs * prefs, char * argv[])
|
||||||
|
{
|
||||||
|
close(prefs->fds[1]);
|
||||||
|
if(dup2(prefs->fds[0], 0) == -1)
|
||||||
|
exit(1); /* FIXME warn user */
|
||||||
|
execvp(argv[0], argv);
|
||||||
|
/* FIXME warn user */
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* callbacks */
|
||||||
|
static gboolean _progress_out(GIOChannel * source, GIOCondition condition,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
static size_t cnt = 0;
|
||||||
|
Prefs * prefs = data;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
ssize_t len;
|
||||||
|
gsize written;
|
||||||
|
gdouble fraction;
|
||||||
|
|
||||||
|
/* FIXME use g_io_channel_read too? */
|
||||||
|
if(condition != G_IO_OUT
|
||||||
|
|| (len = read(prefs->fd, buf, sizeof(buf))) < 0)
|
||||||
|
{
|
||||||
|
gtk_main_quit();
|
||||||
|
_progress_error(prefs->filename, 0);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if(g_io_channel_write(source, buf, len, &written) != G_IO_ERROR_NONE
|
||||||
|
|| written != (gsize)len)
|
||||||
|
{
|
||||||
|
/* FIXME it may just be that everything was not written
|
||||||
|
* => put buffer and position in Prefs/Progress */
|
||||||
|
gtk_main_quit();
|
||||||
|
_progress_error(prefs->filename, 0);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
cnt += len;
|
||||||
|
if(prefs->length == 0 || cnt == 0)
|
||||||
|
gtk_progress_bar_pulse(GTK_PROGRESS_BAR(prefs->progress));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fraction = cnt;
|
||||||
|
fraction /= prefs->length;
|
||||||
|
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(prefs->progress),
|
||||||
|
fraction);
|
||||||
|
snprintf(buf, sizeof(buf), "%.1f%%", fraction * 100);
|
||||||
|
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(prefs->progress),
|
||||||
|
buf);
|
||||||
|
}
|
||||||
|
if(len == 0)
|
||||||
|
{
|
||||||
|
gtk_main_quit();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* usage */
|
||||||
|
static int _usage(void)
|
||||||
|
{
|
||||||
|
fputs("Usage: progress [-z][-f file][-l length][-p prefix]"
|
||||||
|
" cmd [args...]\n", stderr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* main */
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
Prefs prefs;
|
||||||
|
int o;
|
||||||
|
char * p;
|
||||||
|
|
||||||
|
memset(&prefs, 0, sizeof(prefs));
|
||||||
|
gtk_init(&argc, &argv);
|
||||||
|
while((o = getopt(argc, argv, "f:z")) != -1)
|
||||||
|
switch(o)
|
||||||
|
{
|
||||||
|
case 'f':
|
||||||
|
prefs.filename = optarg;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
prefs.length = strtol(optarg, &p, 0);
|
||||||
|
/* FIXME check input validation */
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
prefs.flags |= PREFS_z; /* FIXME implement */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return _usage();
|
||||||
|
}
|
||||||
|
if(argc - optind < 1)
|
||||||
|
return _usage();
|
||||||
|
return _progress(&prefs, &argv[optind]) == 0 ? 0 : 2;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
targets=calendar,fontsel,run
|
targets=calendar,fontsel,progress,run
|
||||||
cflags_force=-W -Wall -ansi `pkg-config gtk+-2.0 --cflags`
|
cflags_force=-W -Wall -ansi `pkg-config gtk+-2.0 --cflags`
|
||||||
cflags=-g
|
cflags=-g
|
||||||
ldflags_force=`pkg-config gtk+-2.0 --libs`
|
ldflags_force=`pkg-config gtk+-2.0 --libs`
|
||||||
|
@ -12,6 +12,10 @@ sources=calendar.c
|
||||||
type=binary
|
type=binary
|
||||||
sources=fontsel.c
|
sources=fontsel.c
|
||||||
|
|
||||||
|
[progress]
|
||||||
|
type=binary
|
||||||
|
sources=progress.c
|
||||||
|
|
||||||
[run]
|
[run]
|
||||||
type=binary
|
type=binary
|
||||||
sources=run.c
|
sources=run.c
|
||||||
|
|
Loading…
Reference in New Issue
Block a user