--- /dev/null
+#ifndef MULTIPROGRESS_H
+#define MULTIPROGRESS_H
+
+#include <stdio.h>
+#include <sys/time.h>
+
+struct progress_ttyinfo {
+ FILE *fp; /* terminal stream */
+ char *termbuf, *capbuf; /* buffers for termcap */
+ struct { /* terminal capabilities */
+ unsigned f; /* various flags */
+#define TCF_BCE 1u /* erases to background colour */
+ const char *cr, *up, *ce, *cd; /* cursor motion */
+ const char *mr, *md, *me; /* reverse video, bold */
+ const char *af, *ab, *op; /* colour */
+ } cap;
+ unsigned defwd, defht; /* default width and height */
+};
+#define PROGRESS_TTYINFO_INIT { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
+
+struct progress_state {
+ struct progress_ttyinfo tty; /* terminal state */
+ struct progress_item *items, *end_item; /* list of progress items */
+ unsigned nitems; /* number of items */
+ unsigned last_lines; /* number written last time */
+ struct timeval tv_update; /* last update time */
+};
+#define PROGRESS_STATE_INIT { PROGRESS_TTYINFO_INIT, 0, 0, 0, 0, { 0, 0 } }
+
+struct progress_render_state {
+ const struct progress_ttyinfo *tty; /* terminal state */
+ unsigned width, height; /* terminal size, in characters */
+ char *linebuf; size_t linesz; /* output buffer */
+ char *tempbuf; size_t tempsz; /* scratch buffer */
+ size_t leftsz, rightsz; /* left and right cursors */
+ unsigned leftwd, rightwd; /* left and right widths */
+ char *old_bc, *old_up; /* old fixup strings */
+};
+
+struct progress_item {
+ struct progress_state *parent; /* controlling progress state */
+ struct progress_item *next, *prev; /* forward and backward links */
+ void (*render)(struct progress_item */*item*/, /* render function */
+ struct progress_render_state */*rs*/);
+};
+#define PROGRESS_ITEM_INIT { 0, 0, 0, 0 }
+
+extern int progress_init(struct progress_state */*progress*/);
+extern void progress_free(struct progress_state */*progress*/);
+
+extern int progress_clear(struct progress_state */*progress*/);
+
+extern int progress_update(struct progress_state */*progress*/);
+
+extern int progress_additem(struct progress_state */*progress*/,
+ struct progress_item */*item*/);
+
+extern int progress_removeitem(struct progress_state */*progress*/,
+ struct progress_item */*item*/);
+
+
+extern int progress_vputleft(struct progress_render_state */*render*/,
+ const char */*fmt*/, va_list /*ap*/);
+
+extern int progress_vputright(struct progress_render_state */*render*/,
+ const char */*fmt*/, va_list /*ap*/);
+
+__attribute__((format(printf, 2, 3)))
+extern int progress_putleft(struct progress_render_state */*render*/,
+ const char */*fmt*/, ...);
+
+__attribute__((format(printf, 2, 3)))
+extern int progress_putright(struct progress_render_state */*render*/,
+ const char */*fmt*/, ...);
+
+extern int progress_showbar(struct progress_render_state */*render*/,
+ double /*frac*/);
+
+extern int progress_shownotice(struct progress_render_state */*render*/,
+ int /*bg*/, int /*fg*/);
+
+#endif