---
Makefile | 9 ++-
drw.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
drw.h | 61 ++++++++++++++++++
tabbed.c | 214 ++++++++++++++-------------------------------------------------
util.c | 17 +++++
util.h | 6 ++
6 files changed, 342 insertions(+), 172 deletions(-)
create mode 100644 drw.c
create mode 100644 drw.h
create mode 100644 util.c
create mode 100644 util.h
diff --git a/Makefile b/Makefile
index 32cc25b..998e58d 100644
--- a/Makefile
+++ b/Makefile
_AT_@ -3,7 +3,9 @@
include config.mk
-SRC = tabbed.c
+SRC = tabbed.c \
+ drw.c \
+ util.c
OBJ = ${SRC:.c=.o}
all: options tabbed
_AT_@ -24,9 +26,10 @@ config.h:
_AT_echo creating $@ from config.def.h
_AT_cp config.def.h $@
-tabbed: tabbed.o
+# TODO explicit deps suck
+tabbed: tabbed.o drw.o drw.h util.c util.h util.o
_AT_echo CC -o $@
- _AT_${CC} -o $@ tabbed.o ${LDFLAGS}
+ _AT_${CC} -o $@ tabbed.o drw.o util.o ${LDFLAGS}
clean:
_AT_echo cleaning
diff --git a/drw.c b/drw.c
new file mode 100644
index 0000000..749795d
--- /dev/null
+++ b/drw.c
_AT_@ -0,0 +1,207 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+
+#include "drw.h"
+#include "util.h"
+
+Drw *
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) {
+ Drw *drw = (Drw *)calloc(1, sizeof(Drw));
+ if(!drw)
+ return NULL;
+ drw->dpy = dpy;
+ drw->screen = screen;
+ drw->root = root;
+ drw->w = w;
+ drw->h = h;
+ drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
+ drw->gc = XCreateGC(dpy, root, 0, NULL);
+ XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
+ return drw;
+}
+
+void
+drw_resize(Drw *drw, unsigned int w, unsigned int h) {
+ if(!drw)
+ return;
+ drw->w = w;
+ drw->h = h;
+ if(drw->drawable != 0)
+ XFreePixmap(drw->dpy, drw->drawable);
+ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
+}
+
+void
+drw_free(Drw *drw) {
+ XFreePixmap(drw->dpy, drw->drawable);
+ XFreeGC(drw->dpy, drw->gc);
+ free(drw);
+}
+
+Fnt *
+drw_font_create(Display *dpy, const char *fontname) {
+ Fnt *font;
+ char *def, **missing;
+ int n;
+
+ font = (Fnt *)calloc(1, sizeof(Fnt));
+ if(!font)
+ return NULL;
+ font->set = XCreateFontSet(dpy, fontname, &missing, &n, &def);
+ if(missing) {
+ while(n--)
+ fprintf(stderr, "drw: missing fontset: %s\n", missing[n]);
+ XFreeStringList(missing);
+ }
+ if(font->set) {
+ XFontStruct **xfonts;
+ char **font_names;
+ XExtentsOfFontSet(font->set);
+ n = XFontsOfFontSet(font->set, &xfonts, &font_names);
+ while(n--) {
+ font->ascent = MAX(font->ascent, (*xfonts)->ascent);
+ font->descent = MAX(font->descent,(*xfonts)->descent);
+ xfonts++;
+ }
+ }
+ else {
+ if(!(font->xfont = XLoadQueryFont(dpy, fontname))
+ && !(font->xfont = XLoadQueryFont(dpy, "fixed")))
+ die("error, cannot load font: '%s'\n", fontname);
+ font->ascent = font->xfont->ascent;
+ font->descent = font->xfont->descent;
+ }
+ font->h = font->ascent + font->descent;
+ return font;
+}
+
+void
+drw_font_free(Display *dpy, Fnt *font) {
+ if(!font)
+ return;
+ if(font->set)
+ XFreeFontSet(dpy, font->set);
+ else
+ XFreeFont(dpy, font->xfont);
+ free(font);
+}
+
+Clr *
+drw_clr_create(Drw *drw, const char *clrname) {
+ Clr *clr;
+ Colormap cmap;
+ XColor color;
+
+ if(!drw)
+ return NULL;
+ clr = (Clr *)calloc(1, sizeof(Clr));
+ if(!clr)
+ return NULL;
+ cmap = DefaultColormap(drw->dpy, drw->screen);
+ if(!XAllocNamedColor(drw->dpy, cmap, clrname, &color, &color))
+ die("error, cannot allocate color '%s'\n", clrname);
+ clr->rgb = color.pixel;
+ return clr;
+}
+
+void
+drw_clr_free(Clr *clr) {
+ free(clr);
+}
+
+void
+drw_setfont(Drw *drw, Fnt *font) {
+ if(drw)
+ drw->font = font;
+}
+
+void
+drw_setscheme(Drw *drw, ClrScheme *scheme) {
+ if(drw && scheme)
+ drw->scheme = scheme;
+}
+
+void
+drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) {
+ int dx;
+
+ if(!drw || !drw->font || !drw->scheme)
+ return;
+ XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->rgb : drw->scheme->fg->rgb);
+ dx = (drw->font->ascent + drw->font->descent + 2) / 4;
+ if(filled)
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x+1, y+1, dx+1, dx+1);
+ else if(empty)
+ XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x+1, y+1, dx, dx);
+}
+
+void
+drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert) {
+ char buf[256];
+ int i, tx, ty, th, len, olen;
+ Extnts tex;
+
+ if(!drw || !drw->scheme)
+ return;
+ XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->fg->rgb : drw->scheme->bg->rgb);
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+ if(!text || !drw->font)
+ return;
+ olen = strlen(text);
+ drw_font_getexts(drw->font, text, olen, &tex);
+ th = drw->font->ascent + drw->font->descent;
+ ty = y + (h / 2) - (th / 2) + drw->font->ascent;
+ tx = x + (h / 2);
+ /* shorten text if necessary */
+ for(len = MIN(olen, sizeof buf); len && (tex.w > w - tex.h || w < tex.h); len--)
+ drw_font_getexts(drw->font, text, len, &tex);
+ if(!len)
+ return;
+ memcpy(buf, text, len);
+ if(len < olen)
+ for(i = len; i && i > len - 3; buf[--i] = '.');
+ XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->rgb : drw->scheme->fg->rgb);
+ if(drw->font->set)
+ XmbDrawString(drw->dpy, drw->drawable, drw->font->set, drw->gc, tx, ty, buf, len);
+ else
+ XDrawString(drw->dpy, drw->drawable, drw->gc, tx, ty, buf, len);
+}
+
+void
+drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) {
+ if(!drw)
+ return;
+ XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
+ XSync(drw->dpy, False);
+}
+
+
+void
+drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) {
+ XRectangle r;
+
+ if(!font || !text)
+ return;
+ if(font->set) {
+ XmbTextExtents(font->set, text, len, NULL, &r);
+ tex->w = r.width;
+ tex->h = r.height;
+ }
+ else {
+ tex->h = font->ascent + font->descent;
+ tex->w = XTextWidth(font->xfont, text, len);
+ }
+}
+
+unsigned int
+drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) {
+ Extnts tex;
+
+ if(!font)
+ return -1;
+ drw_font_getexts(font, text, len, &tex);
+ return tex.w;
+}
diff --git a/drw.h b/drw.h
new file mode 100644
index 0000000..e77a49c
--- /dev/null
+++ b/drw.h
_AT_@ -0,0 +1,61 @@
+/* See LICENSE file for copyright and license details. */
+
+typedef struct {
+ unsigned long rgb;
+} Clr;
+
+typedef struct {
+ int ascent;
+ int descent;
+ unsigned int h;
+ XFontSet set;
+ XFontStruct *xfont;
+} Fnt;
+
+typedef struct {
+ Clr *fg;
+ Clr *bg;
+ Clr *border;
+} ClrScheme;
+
+typedef struct {
+ unsigned int w, h;
+ Display *dpy;
+ int screen;
+ Window root;
+ Drawable drawable;
+ GC gc;
+ ClrScheme *scheme;
+ Fnt *font;
+} Drw;
+
+typedef struct {
+ unsigned int w;
+ unsigned int h;
+} Extnts;
+
+/* Drawable abstraction */
+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
+void drw_resize(Drw *drw, unsigned int w, unsigned int h);
+void drw_free(Drw *drw);
+
+/* Fnt abstraction */
+Fnt *drw_font_create(Display *dpy, const char *fontname);
+void drw_font_free(Display *dpy, Fnt *font);
+void drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *extnts);
+unsigned int drw_font_getexts_width(Fnt *font, const char *text, unsigned int len);
+
+/* Colour abstraction */
+Clr *drw_clr_create(Drw *drw, const char *clrname);
+void drw_clr_free(Clr *clr);
+
+/* Drawing context manipulation */
+void drw_setfont(Drw *drw, Fnt *font);
+void drw_setscheme(Drw *drw, ClrScheme *scheme);
+
+/* Drawing functions */
+void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert);
+void drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert);
+
+/* Map functions */
+void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
diff --git a/tabbed.c b/tabbed.c
index 93a213a..3ef5968 100644
--- a/tabbed.c
+++ b/tabbed.c
_AT_@ -17,6 +17,7 @@
#include <X11/XKBlib.h>
#include "arg.h"
+#include "drw.h"
/* XEMBED messages */
#define XEMBED_EMBEDDED_NOTIFY 0
_AT_@ -44,9 +45,9 @@
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define LENGTH(x) (sizeof((x)) / sizeof(*(x)))
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask))
-#define TEXTW(x) (textnw(x, strlen(x)) + dc.font.height)
+#define TEXTW(X) (drw_font_getexts_width(drw->font, X, strlen(X)) + drw->font->h)
-enum { ColFG, ColBG, ColLast }; /* color */
+enum { SchemeNorm, SchemeSel, SchemeLast }; /* color schemes */
enum { WMProtocols, WMDelete, WMName, WMState, WMFullscreen,
XEmbed, WMSelectTab, WMLast }; /* default atoms */
_AT_@ -62,21 +63,6 @@ typedef struct {
const Arg arg;
} Key;
-typedef struct {
- int x, y, w, h;
- unsigned long norm[ColLast];
- unsigned long sel[ColLast];
- Drawable drawable;
- GC gc;
- struct {
- int ascent;
- int descent;
- int height;
- XFontSet set;
- XFontStruct *xfont;
- } font;
-} DC; /* draw context */
-
typedef struct Client {
char name[256];
Window win;
_AT_@ -95,7 +81,6 @@ static void createnotify(const XEvent *e);
static void destroynotify(const XEvent *e);
static void die(const char *errstr, ...);
static void drawbar(void);
-static void drawtext(const char *text, unsigned long col[ColLast]);
static void *emallocz(size_t size);
static void *erealloc(void *o, size_t size);
static void expose(const XEvent *e);
_AT_@ -105,10 +90,8 @@ static void focusonce(const Arg *arg);
static void fullscreen(const Arg *arg);
static char* getatom(int a);
static int getclient(Window w);
-static unsigned long getcolor(const char *colstr);
static int getfirsttab(void);
static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
-static void initfont(const char *fontstr);
static Bool isprotodel(int c);
static void keypress(const XEvent *e);
static void killclient(const Arg *arg);
_AT_@ -125,7 +108,6 @@ static void setup(void);
static void setcmd(int argc, char *argv[], int);
static void sigchld(int unused);
static void spawn(const Arg *arg);
-static int textnw(const char *text, unsigned int len);
static void unmanage(int c);
static void updatenumlockmask(void);
static void updatetitle(int c);
_AT_@ -152,7 +134,9 @@ static unsigned int numlockmask = 0;
static Bool running = True, nextfocus, doinitspawn = True,
fillagain = False, closelastclient = False;
static Display *dpy;
-static DC dc;
+static Drw* drw;
+static Fnt* fnt;
+static ClrScheme scheme[SchemeLast];
static Atom wmatom[WMLast];
static Window root, win;
static Client **clients = NULL;
_AT_@ -219,14 +203,13 @@ cleanup(void) {
free(clients);
clients = NULL;
- if(dc.font.set) {
- XFreeFontSet(dpy, dc.font.set);
- } else {
- XFreeFont(dpy, dc.font.xfont);
- }
+ drw_font_free(dpy, fnt);
+ drw_clr_free(scheme[SchemeNorm].bg);
+ drw_clr_free(scheme[SchemeNorm].fg);
+ drw_clr_free(scheme[SchemeSel].bg);
+ drw_clr_free(scheme[SchemeSel].fg);
+ drw_free(drw);
- XFreePixmap(dpy, dc.drawable);
- XFreeGC(dpy, dc.gc);
XDestroyWindow(dpy, win);
XSync(dpy, False);
free(cmd);
_AT_@ -249,9 +232,7 @@ configurenotify(const XEvent *e) {
if(ev->window == win && (ev->width != ww || ev->height != wh)) {
ww = ev->width;
wh = ev->height;
- XFreePixmap(dpy, dc.drawable);
- dc.drawable = XCreatePixmap(dpy, root, ww, wh,
- DefaultDepth(dpy, screen));
+ drw_resize(drw, ww, bh);
if(sel > -1)
resize(sel, ww, wh - bh);
XSync(dpy, False);
_AT_@ -305,16 +286,13 @@ die(const char *errstr, ...) {
void
drawbar(void) {
- unsigned long *col;
- int c, fc, width, n = 0;
+ int c, fc, width, n = 0, xoff = 0, draww = 0;
char *name = NULL;
if(nclients == 0) {
- dc.x = 0;
- dc.w = ww;
XFetchName(dpy, win, &name);
- drawtext(name ? name : "", dc.norm);
- XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, ww, bh, 0, 0);
+ drw_text(drw, 0, /* y */ 0, ww, bh, name ? name : "", False);
+ XCopyArea(dpy, drw->drawable, win, drw->gc, 0, 0, ww, bh, 0, 0);
XSync(dpy, False);
return;
_AT_@ -327,76 +305,40 @@ drawbar(void) {
n = nclients - fc;
if((n * tabwidth) > width) {
- dc.w = TEXTW(after);
- dc.x = width - dc.w;
- drawtext(after, dc.sel);
- width -= dc.w;
+ draww = TEXTW(after);
+ drw_setscheme(drw, &scheme[SchemeSel]);
+ drw_text(drw, width - draww, /* y */ 0, draww, bh, after, False);
+ width -= draww;
}
- dc.x = 0;
if(fc > 0) {
- dc.w = TEXTW(before);
- drawtext(before, dc.sel);
- dc.x += dc.w;
- width -= dc.w;
+ draww = TEXTW(before);
+ drw_setscheme(drw, &scheme[SchemeSel]);
+ drw_text(drw, 0, /* y */ 0, draww, bh, before, False);
+ xoff = draww;
+ width -= draww;
}
- for(c = (fc > 0)? fc : 0; c < nclients && dc.x < width; c++) {
- dc.w = tabwidth;
+ for(c = (fc > 0)? fc : 0; c < nclients && xoff < width; c++) {
+ draww = tabwidth;
if(c == sel) {
- col = dc.sel;
+ drw_setscheme(drw, &scheme[SchemeSel]);
if((n * tabwidth) > width) {
- dc.w += width % tabwidth;
+ draww += width % tabwidth;
} else {
- dc.w = width - (n - 1) * tabwidth;
+ draww = width - (n - 1) * tabwidth;
}
} else {
- col = dc.norm;
+ drw_setscheme(drw, &scheme[SchemeNorm]);
}
- drawtext(clients[c]->name, col);
- dc.x += dc.w;
- clients[c]->tabx = dc.x;
+ drw_text(drw, xoff, /* y */ 0, draww, bh, clients[c]->name, False);
+ xoff += draww;
+ clients[c]->tabx = xoff;
}
- XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, ww, bh, 0, 0);
+ XCopyArea(dpy, drw->drawable, win, drw->gc, 0, 0, ww, bh, 0, 0);
XSync(dpy, False);
}
-void
-drawtext(const char *text, unsigned long col[ColLast]) {
- int i, x, y, h, len, olen;
- char buf[256];
- XRectangle r = { dc.x, dc.y, dc.w, dc.h };
-
- XSetForeground(dpy, dc.gc, col[ColBG]);
- XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
- if(!text)
- return;
-
- olen = strlen(text);
- h = dc.font.ascent + dc.font.descent;
- y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
- x = dc.x + (h / 2);
-
- /* shorten text if necessary */
- for(len = MIN(olen, sizeof(buf));
- len && textnw(text, len) > dc.w - h; len--);
- if(!len)
- return;
-
- memcpy(buf, text, len);
- if(len < olen) {
- for(i = len; i && i > len - 3; buf[--i] = '.');
- }
-
- XSetForeground(dpy, dc.gc, col[ColFG]);
- if(dc.font.set) {
- XmbDrawString(dpy, dc.drawable, dc.font.set,
- dc.gc, x, y, buf, len);
- } else {
- XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
- }
-}
-
void *
emallocz(size_t size) {
void *p;
_AT_@ -524,17 +466,6 @@ getclient(Window w) {
return -1;
}
-unsigned long
-getcolor(const char *colstr) {
- Colormap cmap = DefaultColormap(dpy, screen);
- XColor color;
-
- if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
- die("tabbed: cannot allocate color '%s'\n", colstr);
-
- return color.pixel;
-}
-
int
getfirsttab(void) {
int c, n, fc;
_AT_@ -583,46 +514,6 @@ gettextprop(Window w, Atom atom, char *text, unsigned int size) {
return True;
}
-void
-initfont(const char *fontstr) {
- char *def, **missing, **font_names;
- int i, n;
- XFontStruct **xfonts;
-
- missing = NULL;
- if(dc.font.set)
- XFreeFontSet(dpy, dc.font.set);
-
- dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
- if(missing) {
- while(n--)
- fprintf(stderr, "tabbed: missing fontset: %s\n", missing[n]);
- XFreeStringList(missing);
- }
-
- if(dc.font.set) {
- dc.font.ascent = dc.font.descent = 0;
- n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
- for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
- dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent);
- dc.font.descent = MAX(dc.font.descent,(*xfonts)->descent);
- xfonts++;
- }
- } else {
- if(dc.font.xfont)
- XFreeFont(dpy, dc.font.xfont);
- dc.font.xfont = NULL;
- if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr))
- && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) {
- die("tabbed: cannot load font: '%s'\n", fontstr);
- }
-
- dc.font.ascent = dc.font.xfont->ascent;
- dc.font.descent = dc.font.xfont->descent;
- }
- dc.font.height = dc.font.ascent + dc.font.descent;
-}
-
Bool
isprotodel(int c) {
int i, n;
_AT_@ -919,8 +810,8 @@ setup(void) {
/* init screen */
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
- initfont(font);
- bh = dc.h = dc.font.height + 2;
+ fnt = drw_font_create(dpy, font);
+ bh = fnt->h + 2;
/* init atoms */
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
_AT_@ -965,18 +856,16 @@ setup(void) {
wy = dh + wy - wh - 1;
}
- dc.norm[ColBG] = getcolor(normbgcolor);
- dc.norm[ColFG] = getcolor(normfgcolor);
- dc.sel[ColBG] = getcolor(selbgcolor);
- dc.sel[ColFG] = getcolor(selfgcolor);
- dc.drawable = XCreatePixmap(dpy, root, ww, wh,
- DefaultDepth(dpy, screen));
- dc.gc = XCreateGC(dpy, root, 0, 0);
- if(!dc.font.set)
- XSetFont(dpy, dc.gc, dc.font.xfont->fid);
+ drw = drw_create(dpy, screen, root, ww, bh);
+ drw_setfont(drw, fnt);
+
+ scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor);
+ scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor);
+ scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor);
+ scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor);
win = XCreateSimpleWindow(dpy, root, wx, wy, ww, wh, 0,
- dc.norm[ColFG], dc.norm[ColBG]);
+ scheme[SchemeNorm].fg->rgb, scheme[SchemeNorm].bg->rgb);
XMapRaised(dpy, win);
XSelectInput(dpy, win, SubstructureNotifyMask|FocusChangeMask|
ButtonPressMask|ExposureMask|KeyPressMask|PropertyChangeMask|
_AT_@ -1038,19 +927,6 @@ spawn(const Arg *arg) {
}
}
-int
-textnw(const char *text, unsigned int len) {
- XRectangle r;
-
- if(dc.font.set) {
- XmbTextExtents(dc.font.set, text, len, NULL, &r);
-
- return r.width;
- }
-
- return XTextWidth(dc.font.xfont, text, len);
-}
-
void
unmanage(int c) {
if(c < 0 || c >= nclients) {
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..51acd1a
--- /dev/null
+++ b/util.c
_AT_@ -0,0 +1,17 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+void
+die(const char *errstr, ...) {
+ va_list ap;
+
+ va_start(ap, errstr);
+ vfprintf(stderr, errstr, ap);
+ va_end(ap);
+ exit(EXIT_FAILURE);
+}
+
diff --git a/util.h b/util.h
new file mode 100644
index 0000000..033700c
--- /dev/null
+++ b/util.h
_AT_@ -0,0 +1,6 @@
+/* See LICENSE file for copyright and license details. */
+
+#define MAX(A, B) ((A) > (B) ? (A) : (B))
+#define MIN(A, B) ((A) < (B) ? (A) : (B))
+
+void die(const char *errstr, ...);
--
1.8.5.3
--Bn2rw/3z4jIqBvZU--
Received on Mon Sep 17 2001 - 00:00:00 CEST
This archive was generated by hypermail 2.3.0 : Wed Jan 22 2014 - 17:00:04 CET