import new drw and util from libsl. - sent - simple plaintext presentation tool | |
git clone git://git.suckless.org/sent | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 27a904c1dd40d185dd5123ca354f6080e853ec92 | |
parent 268d1968ea951b3eb2d1411a9e0d7c0fcb23217b | |
Author: Markus Teich <[email protected]> | |
Date: Sat, 21 May 2016 21:39:58 +0200 | |
import new drw and util from libsl. | |
Diffstat: | |
M config.def.h | 6 ++++-- | |
M drw.c | 310 ++++++++++++++++-------------… | |
M drw.h | 28 ++++++++++------------------ | |
M sent.c | 85 ++++++++++++-----------------… | |
M util.c | 24 ++++++++++++++++++++---- | |
M util.h | 3 ++- | |
6 files changed, 227 insertions(+), 229 deletions(-) | |
--- | |
diff --git a/config.def.h b/config.def.h | |
@@ -8,8 +8,10 @@ static char *fontfallbacks[] = { | |
#define NUMFONTSCALES 42 | |
#define FONTSZ(x) ((int)(10.0 * powf(1.1288, (x)))) /* x in [0, NUMFONTSCALES-… | |
-static const char *fgcol = "#000000"; | |
-static const char *bgcol = "#FFFFFF"; | |
+static const char *colors[] = { | |
+ "#000000", /* foreground color */ | |
+ "#FFFFFF", /* background color */ | |
+}; | |
static const float linespacing = 1.4; | |
diff --git a/drw.c b/drw.c | |
@@ -9,9 +9,7 @@ | |
#include "util.h" | |
#define UTF_INVALID 0xFFFD | |
-#define UTF_SIZ 4 | |
- | |
-static void drw_xfont_free(Fnt *font); | |
+#define UTF_SIZ 4 | |
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF… | |
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF… | |
@@ -19,50 +17,54 @@ static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0… | |
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FF… | |
static long | |
-utf8decodebyte(const char c, size_t *i) { | |
- for(*i = 0; *i < (UTF_SIZ + 1); ++(*i)) | |
- if(((unsigned char)c & utfmask[*i]) == utfbyte[*i]) | |
+utf8decodebyte(const char c, size_t *i) | |
+{ | |
+ for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) | |
+ if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) | |
return (unsigned char)c & ~utfmask[*i]; | |
return 0; | |
} | |
static size_t | |
-utf8validate(long *u, size_t i) { | |
- if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) | |
+utf8validate(long *u, size_t i) | |
+{ | |
+ if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) | |
*u = UTF_INVALID; | |
- for(i = 1; *u > utfmax[i]; ++i) | |
+ for (i = 1; *u > utfmax[i]; ++i) | |
; | |
return i; | |
} | |
static size_t | |
-utf8decode(const char *c, long *u, size_t clen) { | |
+utf8decode(const char *c, long *u, size_t clen) | |
+{ | |
size_t i, j, len, type; | |
long udecoded; | |
*u = UTF_INVALID; | |
- if(!clen) | |
+ if (!clen) | |
return 0; | |
udecoded = utf8decodebyte(c[0], &len); | |
- if(!BETWEEN(len, 1, UTF_SIZ)) | |
+ if (!BETWEEN(len, 1, UTF_SIZ)) | |
return 1; | |
- for(i = 1, j = 1; i < clen && j < len; ++i, ++j) { | |
+ for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { | |
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); | |
- if(type != 0) | |
+ if (type) | |
return j; | |
} | |
- if(j < len) | |
+ if (j < len) | |
return 0; | |
*u = udecoded; | |
utf8validate(u, len); | |
+ | |
return len; | |
} | |
Drw * | |
-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int… | |
- Drw *drw = (Drw *)calloc(1, sizeof(Drw)); | |
- if(!drw) | |
- return NULL; | |
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int… | |
+{ | |
+ Drw *drw = ecalloc(1, sizeof(Drw)); | |
+ | |
drw->dpy = dpy; | |
drw->screen = screen; | |
drw->root = root; | |
@@ -71,22 +73,26 @@ drw_create(Display *dpy, int screen, Window root, unsigned … | |
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, scree… | |
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) | |
+drw_resize(Drw *drw, unsigned int w, unsigned int h) | |
+{ | |
+ if (!drw) | |
return; | |
+ | |
drw->w = w; | |
drw->h = h; | |
- if(drw->drawable != 0) | |
+ if (drw->drawable) | |
XFreePixmap(drw->dpy, drw->drawable); | |
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(… | |
} | |
void | |
-drw_free(Drw *drw) { | |
+drw_free(Drw *drw) | |
+{ | |
XFreePixmap(drw->dpy, drw->drawable); | |
XFreeGC(drw->dpy, drw->gc); | |
free(drw); | |
@@ -96,119 +102,123 @@ drw_free(Drw *drw) { | |
* drw_fontset_create instead. | |
*/ | |
static Fnt * | |
-drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { | |
+xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) | |
+{ | |
Fnt *font; | |
- | |
- if (!(fontname || fontpattern)) | |
- die("No font specified.\n"); | |
- | |
- if (!(font = (Fnt *)calloc(1, sizeof(Fnt)))) | |
- return NULL; | |
+ XftFont *xfont = NULL; | |
+ FcPattern *pattern = NULL; | |
if (fontname) { | |
/* Using the pattern found at font->xfont->pattern does not yi… | |
* same substitution results as using the pattern returned by | |
* FcNameParse; using the latter results in the desired fallba… | |
- * behaviour whereas the former just results in | |
- * missing-character-rectangles being drawn, at least with som… | |
- */ | |
- if (!(font->xfont = XftFontOpenName(drw->dpy, drw->screen, fon… | |
- !(font->pattern = FcNameParse((const FcChar8 *) fontname))… | |
- if (font->xfont) { | |
- XftFontClose(drw->dpy, font->xfont); | |
- font->xfont = NULL; | |
- } | |
- fprintf(stderr, "error, cannot load font: '%s'\n", fon… | |
+ * behaviour whereas the former just results in missing-charac… | |
+ * rectangles being drawn, at least with some fonts. */ | |
+ if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname)… | |
+ fprintf(stderr, "error, cannot load font from name: '%… | |
+ return NULL; | |
+ } | |
+ if (!(pattern = FcNameParse((FcChar8 *) fontname))) { | |
+ fprintf(stderr, "error, cannot parse font name to patt… | |
+ XftFontClose(drw->dpy, xfont); | |
+ return NULL; | |
} | |
} else if (fontpattern) { | |
- if (!(font->xfont = XftFontOpenPattern(drw->dpy, fontpattern))… | |
- fprintf(stderr, "error, cannot load font pattern.\n"); | |
- } else { | |
- font->pattern = NULL; | |
+ if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { | |
+ fprintf(stderr, "error, cannot load font from pattern.… | |
+ return NULL; | |
} | |
+ } else { | |
+ die("no font specified.\n"); | |
} | |
- if (!font->xfont) { | |
- free(font); | |
- return NULL; | |
- } | |
- | |
- font->ascent = font->xfont->ascent; | |
- font->descent = font->xfont->descent; | |
- font->h = font->ascent + font->descent; | |
+ font = ecalloc(1, sizeof(Fnt)); | |
+ font->xfont = xfont; | |
+ font->pattern = pattern; | |
+ font->h = xfont->ascent + xfont->descent; | |
font->dpy = drw->dpy; | |
+ | |
return font; | |
} | |
-void | |
-drw_xfont_free(Fnt *font) { | |
- if(!font) | |
+static void | |
+xfont_free(Fnt *font) | |
+{ | |
+ if (!font) | |
return; | |
- if(font->pattern) | |
+ if (font->pattern) | |
FcPatternDestroy(font->pattern); | |
XftFontClose(font->dpy, font->xfont); | |
free(font); | |
} | |
Fnt* | |
-drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) { | |
- Fnt *ret = NULL; | |
- Fnt *cur = NULL; | |
- ssize_t i; | |
- for (i = fontcount - 1; i >= 0; i--) { | |
- if ((cur = drw_font_xcreate(drw, fonts[i], NULL))) { | |
+drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) | |
+{ | |
+ Fnt *cur, *ret = NULL; | |
+ size_t i; | |
+ | |
+ if (!drw || !fonts) | |
+ return NULL; | |
+ | |
+ for (i = 1; i <= fontcount; i++) { | |
+ if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { | |
cur->next = ret; | |
ret = cur; | |
} | |
} | |
- return ret; | |
+ return (drw->fonts = ret); | |
} | |
void | |
-drw_fontset_free(Fnt *font) { | |
- Fnt *nf = font; | |
- | |
- while ((font = nf)) { | |
- nf = font->next; | |
- drw_xfont_free(font); | |
+drw_fontset_free(Fnt *font) | |
+{ | |
+ if (font) { | |
+ drw_fontset_free(font->next); | |
+ xfont_free(font); | |
} | |
} | |
-Scm * | |
-drw_scm_create(Drw *drw, const char *fgname, const char *bgname) { | |
- Scm *scm; | |
- Colormap cmap; | |
- Visual *vis; | |
- | |
- if (!drw || !(scm = (Scm *)calloc(1, sizeof(Scm)))) | |
- return NULL; | |
+void | |
+drw_clr_create(Drw *drw, Clr *dest, const char *clrname) | |
+{ | |
+ if (!drw || !dest || !clrname) | |
+ return; | |
- cmap = DefaultColormap(drw->dpy, drw->screen); | |
- vis = DefaultVisual(drw->dpy, drw->screen); | |
- if (!XftColorAllocName(drw->dpy, vis, cmap, fgname, &scm->fg.rgb)) | |
- die("error, cannot allocate color '%s'\n", fgname); | |
- if (!XftColorAllocName(drw->dpy, vis, cmap, bgname, &scm->bg.rgb)) | |
- die("error, cannot allocate color '%s'\n", bgname); | |
- scm->fg.pix = scm->fg.rgb.pixel; | |
- scm->bg.pix = scm->bg.rgb.pixel; | |
- return scm; | |
+ if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), | |
+ DefaultColormap(drw->dpy, drw->screen), | |
+ clrname, dest)) | |
+ die("error, cannot allocate color '%s'\n", clrname); | |
} | |
-void | |
-drw_scm_free(Scm *scm) { | |
- if (scm) | |
- free(scm); | |
+/* Wrapper to create color schemes. The caller has to call free(3) on the | |
+ * returned color scheme when done using it. */ | |
+Clr * | |
+drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) | |
+{ | |
+ size_t i; | |
+ Clr *ret; | |
+ | |
+ /* need at least two colors for a scheme */ | |
+ if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, siz… | |
+ return NULL; | |
+ | |
+ for (i = 0; i < clrcount; i++) | |
+ drw_clr_create(drw, &ret[i], clrnames[i]); | |
+ return ret; | |
} | |
void | |
-drw_setfontset(Drw *drw, Fnt *set) { | |
+drw_setfontset(Drw *drw, Fnt *set) | |
+{ | |
if (drw) | |
drw->fonts = set; | |
} | |
void | |
-drw_setscheme(Drw *drw, Scm *scm) { | |
- if (drw && scm) | |
+drw_setscheme(Drw *drw, Clr *scm) | |
+{ | |
+ if (drw) | |
drw->scheme = scm; | |
} | |
@@ -217,24 +227,23 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned… | |
{ | |
if (!drw || !drw->scheme) | |
return; | |
- XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg.pix : drw->… | |
+ XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : … | |
if (filled) | |
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | |
else | |
- XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | |
+ XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, … | |
} | |
int | |
-drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *t… | |
+drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int … | |
+{ | |
char buf[1024]; | |
- int tx, ty, th; | |
- unsigned int ew = 0; | |
- Colormap cmap; | |
- Visual *vis; | |
- XftDraw *d; | |
+ int ty; | |
+ unsigned int ew; | |
+ XftDraw *d = NULL; | |
Fnt *usedfont, *curfont, *nextfont; | |
size_t i, len; | |
- int utf8strlen, utf8charlen, render; | |
+ int utf8strlen, utf8charlen, render = x || y || w || h; | |
long utf8codepoint = 0; | |
const char *utf8str; | |
FcCharSet *fccharset; | |
@@ -243,23 +252,19 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned… | |
XftResult result; | |
int charexists = 0; | |
- if (!(render = x || y || w || h)) { | |
- w = ~w; | |
- } | |
- | |
- if (!drw || !drw->scheme) { | |
+ if (!drw || (render && !drw->scheme) || !text || !drw->fonts) | |
return 0; | |
- } else if (render) { | |
- XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->fg.pix… | |
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | |
- } | |
- if (!text || !drw->fonts) { | |
- return 0; | |
- } else if (render) { | |
- cmap = DefaultColormap(drw->dpy, drw->screen); | |
- vis = DefaultVisual(drw->dpy, drw->screen); | |
- d = XftDrawCreate(drw->dpy, drw->drawable, vis, cmap); | |
+ if (!render) { | |
+ w = ~w; | |
+ } else { | |
+ XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg :… | |
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | |
+ d = XftDrawCreate(drw->dpy, drw->drawable, | |
+ DefaultVisual(drw->dpy, drw->screen), | |
+ DefaultColormap(drw->dpy, drw->screen)); | |
+ x += lpad; | |
+ w -= lpad; | |
} | |
usedfont = drw->fonts; | |
@@ -282,32 +287,30 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned… | |
} | |
} | |
- if (!charexists || nextfont) { | |
+ if (!charexists || nextfont) | |
break; | |
- } else { | |
+ else | |
charexists = 0; | |
- } | |
} | |
if (utf8strlen) { | |
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, N… | |
/* shorten text if necessary */ | |
- for(len = MIN(utf8strlen, (sizeof buf) - 1); len && (e… | |
+ for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew… | |
drw_font_getexts(usedfont, utf8str, len, &ew, … | |
if (len) { | |
memcpy(buf, utf8str, len); | |
buf[len] = '\0'; | |
- if(len < utf8strlen) | |
- for(i = len; i && i > len - 3; buf[--i… | |
+ if (len < utf8strlen) | |
+ for (i = len; i && i > len - 3; buf[--… | |
+ ; /* NOP */ | |
if (render) { | |
- th = usedfont->ascent + usedfont->desc… | |
- ty = y + (h / 2) - (th / 2) + usedfont… | |
- tx = x + (h / 2); | |
- XftDrawStringUtf8(d, invert ? &drw->sc… | |
+ ty = y + (h - usedfont->h) / 2 + usedf… | |
+ XftDrawStringUtf8(d, &drw->scheme[inve… | |
+ usedfont->xfont, x, … | |
} | |
- | |
x += ew; | |
w -= ew; | |
} | |
@@ -320,18 +323,15 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned… | |
usedfont = nextfont; | |
} else { | |
/* Regardless of whether or not a fallback font is fou… | |
- * character must be drawn. | |
- */ | |
+ * character must be drawn. */ | |
charexists = 1; | |
fccharset = FcCharSetCreate(); | |
FcCharSetAddChar(fccharset, utf8codepoint); | |
if (!drw->fonts->pattern) { | |
- /* Refer to the comment in drw_font_xcreate fo… | |
- * information. | |
- */ | |
- die("The first font in the cache must be loade… | |
+ /* Refer to the comment in xfont_create for mo… | |
+ die("the first font in the cache must be loade… | |
} | |
fcpattern = FcPatternDuplicate(drw->fonts->pattern); | |
@@ -346,47 +346,50 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned… | |
FcPatternDestroy(fcpattern); | |
if (match) { | |
- usedfont = drw_font_xcreate(drw, NULL, match); | |
+ usedfont = xfont_create(drw, NULL, match); | |
if (usedfont && XftCharExists(drw->dpy, usedfo… | |
for (curfont = drw->fonts; curfont->ne… | |
- ; /* just find the end of the … | |
+ ; /* NOP */ | |
curfont->next = usedfont; | |
} else { | |
- drw_xfont_free(usedfont); | |
+ xfont_free(usedfont); | |
usedfont = drw->fonts; | |
} | |
} | |
} | |
} | |
- | |
- if (render) { | |
+ if (d) | |
XftDrawDestroy(d); | |
- } | |
- return x; | |
+ return x + (render ? w : 0); | |
} | |
void | |
-drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) { | |
- if(!drw) | |
+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); | |
} | |
unsigned int | |
-drw_fontset_getwidth(Drw *drw, const char *text) { | |
+drw_fontset_getwidth(Drw *drw, const char *text) | |
+{ | |
if (!drw || !drw->fonts || !text) | |
return 0; | |
- return drw_text(drw, 0, 0, 0, 0, text, 0); | |
+ return drw_text(drw, 0, 0, 0, 0, 0, text, 0); | |
} | |
void | |
-drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *… | |
+drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *… | |
+{ | |
XGlyphInfo ext; | |
- if(!font || !text) | |
+ if (!font || !text) | |
return; | |
+ | |
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext… | |
if (w) | |
*w = ext.xOff; | |
@@ -395,19 +398,24 @@ drw_font_getexts(Fnt *font, const char *text, unsigned in… | |
} | |
Cur * | |
-drw_cur_create(Drw *drw, int shape) { | |
+drw_cur_create(Drw *drw, int shape) | |
+{ | |
Cur *cur; | |
- if(!drw || !(cur = (Cur *)calloc(1, sizeof(Cur)))) | |
+ if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) | |
return NULL; | |
+ | |
cur->cursor = XCreateFontCursor(drw->dpy, shape); | |
+ | |
return cur; | |
} | |
void | |
-drw_cur_free(Drw *drw, Cur *cursor) { | |
- if(!drw || !cursor) | |
+drw_cur_free(Drw *drw, Cur *cursor) | |
+{ | |
+ if (!cursor) | |
return; | |
+ | |
XFreeCursor(drw->dpy, cursor->cursor); | |
free(cursor); | |
} | |
diff --git a/drw.h b/drw.h | |
@@ -1,27 +1,19 @@ | |
/* See LICENSE file for copyright and license details. */ | |
-#define DRW_FONT_CACHE_SIZE 32 | |
typedef struct { | |
Cursor cursor; | |
} Cur; | |
-typedef struct Fnt Fnt; | |
-struct Fnt { | |
+typedef struct Fnt { | |
Display *dpy; | |
- int ascent; | |
- int descent; | |
unsigned int h; | |
XftFont *xfont; | |
FcPattern *pattern; | |
- Fnt *next; | |
-}; | |
+ struct Fnt *next; | |
+} Fnt; | |
-typedef struct { | |
- struct { | |
- unsigned long pix; | |
- XftColor rgb; | |
- } fg, bg; | |
-} Scm; | |
+enum { ColFg, ColBg }; /* Clr scheme index */ | |
+typedef XftColor Clr; | |
typedef struct { | |
unsigned int w, h; | |
@@ -30,7 +22,7 @@ typedef struct { | |
Window root; | |
Drawable drawable; | |
GC gc; | |
- Scm *scheme; | |
+ Clr *scheme; | |
Fnt *fonts; | |
} Drw; | |
@@ -46,8 +38,8 @@ unsigned int drw_fontset_getwidth(Drw *drw, const char *text); | |
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned … | |
/* Colorscheme abstraction */ | |
-Scm *drw_scm_create(Drw *drw, const char *fgname, const char *bgname); | |
-void drw_scm_free(Scm *scm); | |
+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); | |
+Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); | |
/* Cursor abstraction */ | |
Cur *drw_cur_create(Drw *drw, int shape); | |
@@ -55,11 +47,11 @@ void drw_cur_free(Drw *drw, Cur *cursor); | |
/* Drawing context manipulation */ | |
void drw_setfontset(Drw *drw, Fnt *set); | |
-void drw_setscheme(Drw *drw, Scm *scm); | |
+void drw_setscheme(Drw *drw, Clr *scm); | |
/* Drawing functions */ | |
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int fill… | |
-int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const cha… | |
+int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned … | |
/* Map functions */ | |
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int … | |
diff --git a/sent.c b/sent.c | |
@@ -20,6 +20,7 @@ | |
#include <X11/Xft/Xft.h> | |
#include "arg.h" | |
+#include "util.h" | |
#include "drw.h" | |
char *argv0; | |
@@ -96,7 +97,6 @@ static void ffdraw(Image *img); | |
static void getfontsize(Slide *s, unsigned int *width, unsigned int *height); | |
static void cleanup(); | |
-static void die(const char *, ...); | |
static void load(FILE *fp); | |
static void advance(const Arg *arg); | |
static void quit(const Arg *arg); | |
@@ -123,7 +123,7 @@ static int idx = 0; | |
static int slidecount = 0; | |
static XWindow xw; | |
static Drw *d = NULL; | |
-static Scm *sc; | |
+static Clr *sc; | |
static Fnt *fonts[NUMFONTSCALES]; | |
static int running = 1; | |
@@ -141,18 +141,18 @@ filter(int fd, const char *cmd) | |
int fds[2]; | |
if (pipe(fds) < 0) | |
- die("Unable to create pipe:"); | |
+ die("sent: Unable to create pipe:"); | |
switch (fork()) { | |
case -1: | |
- die("Unable to fork:"); | |
+ die("sent: Unable to fork:"); | |
case 0: | |
dup2(fd, 0); | |
dup2(fds[1], 1); | |
close(fds[0]); | |
close(fds[1]); | |
execlp("sh", "sh", "-c", cmd, (char *)0); | |
- die("execlp sh -c '%s':", cmd); | |
+ die("sent: execlp sh -c '%s':", cmd); | |
} | |
close(fds[1]); | |
return fds[0]; | |
@@ -182,13 +182,13 @@ ffopen(char *filename) | |
return NULL; | |
if ((fd = open(filename, O_RDONLY)) < 0) { | |
- die("Unable to open file %s:", filename); | |
+ die("sent: Unable to open file %s:", filename); | |
} | |
tmpfd = fd; | |
fd = filter(fd, bin); | |
if (fd < 0) | |
- die("Unable to filter %s:", filename); | |
+ die("sent: Unable to filter %s:", filename); | |
close(tmpfd); | |
if (read(fd, hdr, 16) != 16) | |
@@ -231,26 +231,26 @@ ffread(Image *img) | |
free(img->buf); | |
/* internally the image is stored in 888 format */ | |
if (!(img->buf = malloc(3 * img->bufwidth * img->bufheight))) | |
- die("Unable to malloc buffer for image."); | |
+ die("sent: Unable to malloc buffer for image.\n"); | |
/* scratch buffer to read row by row */ | |
rowlen = img->bufwidth * 2 * strlen("RGBA"); | |
row = malloc(rowlen); | |
if (!row) { | |
- die("Unable to malloc buffer for image row."); | |
+ die("sent: Unable to malloc buffer for image row.\n"); | |
} | |
/* extract window background color channels for transparency */ | |
- bg_r = (sc->bg.pix >> 16) % 256; | |
- bg_g = (sc->bg.pix >> 8) % 256; | |
- bg_b = (sc->bg.pix >> 0) % 256; | |
+ bg_r = (sc[ColBg].pixel >> 16) % 256; | |
+ bg_g = (sc[ColBg].pixel >> 8) % 256; | |
+ bg_b = (sc[ColBg].pixel >> 0) % 256; | |
for (off = 0, y = 0; y < img->bufheight; y++) { | |
nbytes = 0; | |
while (nbytes < rowlen) { | |
count = read(img->fd, (char *)row + nbytes, rowlen - n… | |
if (count < 0) | |
- die("Unable to read from pipe:"); | |
+ die("sent: Unable to read from pipe:"); | |
nbytes += count; | |
} | |
for (x = 0; x < rowlen / 2; x += 4) { | |
@@ -284,17 +284,17 @@ ffprepare(Image *img) | |
height = img->bufheight * xw.uw / img->bufwidth; | |
if (depth < 24) | |
- die("Display depths <24 not supported."); | |
+ die("sent: Display depths <24 not supported.\n"); | |
if (!(img->ximg = XCreateImage(xw.dpy, CopyFromParent, depth, ZPixmap,… | |
NULL, width, height, 32, 0))) | |
- die("Unable to create XImage."); | |
+ die("sent: Unable to create XImage.\n"); | |
if (!(img->ximg->data = malloc(img->ximg->bytes_per_line * height))) | |
- die("Unable to alloc data section for XImage."); | |
+ die("sent: Unable to alloc data section for XImage.\n"); | |
if (!XInitImage(img->ximg)) | |
- die("Unable to init XImage."); | |
+ die("sent: Unable to init XImage.\n"); | |
ffscale(img); | |
img->state |= SCALED; | |
@@ -364,7 +364,6 @@ getfontsize(Slide *s, unsigned int *width, unsigned int *he… | |
*width = curw; | |
} | |
*height = fonts[j]->h * lfac; | |
- *width += fonts[j]->h; | |
} | |
void | |
@@ -374,7 +373,7 @@ cleanup() | |
for (i = 0; i < NUMFONTSCALES; i++) | |
drw_fontset_free(fonts[i]); | |
- drw_scm_free(sc); | |
+ free(sc); | |
drw_free(d); | |
XDestroyWindow(xw.dpy, xw.win); | |
@@ -394,27 +393,6 @@ cleanup() | |
} | |
void | |
-die(const char *fmt, ...) | |
-{ | |
- va_list ap; | |
- | |
- fputs("sent: ", stderr); | |
- | |
- va_start(ap, fmt); | |
- vfprintf(stderr, fmt, ap); | |
- va_end(ap); | |
- | |
- if (fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':') { | |
- fputc(' ', stderr); | |
- perror(NULL); | |
- } else { | |
- fputc('\n', stderr); | |
- } | |
- | |
- exit(1); | |
-} | |
- | |
-void | |
load(FILE *fp) | |
{ | |
static size_t size = 0; | |
@@ -433,7 +411,7 @@ load(FILE *fp) | |
if ((slidecount+1) * sizeof(*slides) >= size) | |
if (!(slides = realloc(slides, (size += BUFSIZ)))) | |
- die("Unable to realloc %u bytes:", size); | |
+ die("sent: Unable to realloc %u bytes:", size); | |
/* read one slide */ | |
maxlines = 0; | |
@@ -446,12 +424,12 @@ load(FILE *fp) | |
if (s->linecount >= maxlines) { | |
maxlines = 2 * s->linecount + 1; | |
if (!(s->lines = realloc(s->lines, maxlines * … | |
- die("Unable to realloc %u bytes:", max… | |
+ die("sent: Unable to realloc %u bytes:… | |
} | |
blen = strlen(buf); | |
if (!(s->lines[s->linecount] = strdup(buf))) | |
- die("Unable to strdup:"); | |
+ die("sent: Unable to strdup:"); | |
if (s->lines[s->linecount][blen-1] == '\n') | |
s->lines[s->linecount][blen-1] = '\0'; | |
@@ -543,6 +521,7 @@ xdraw() | |
(xw.h - height) / 2 + i * linespacing * d->fo… | |
width, | |
d->fonts->h, | |
+ 0, | |
slides[idx].lines[i], | |
0); | |
drw_map(d, xw.win, 0, 0, xw.w, xw.h); | |
@@ -564,7 +543,7 @@ xhints() | |
XSizeHints *sizeh = NULL; | |
if (!(sizeh = XAllocSizeHints())) | |
- die("Unable to alloc size hints."); | |
+ die("sent: Unable to alloc size hints.\n"); | |
sizeh->flags = PSize; | |
sizeh->height = xw.h; | |
@@ -580,7 +559,7 @@ xinit() | |
XTextProperty prop; | |
if (!(xw.dpy = XOpenDisplay(NULL))) | |
- die("Unable to open display."); | |
+ die("sent: Unable to open display.\n"); | |
xw.scr = XDefaultScreen(xw.dpy); | |
xw.vis = XDefaultVisual(xw.dpy, xw.scr); | |
resize(DisplayWidth(xw.dpy, xw.scr), DisplayHeight(xw.dpy, xw.scr)); | |
@@ -599,10 +578,10 @@ xinit() | |
XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); | |
if (!(d = drw_create(xw.dpy, xw.scr, xw.win, xw.w, xw.h))) | |
- die("Unable to create drawing context."); | |
- sc = drw_scm_create(d, fgcol, bgcol); | |
+ die("sent: Unable to create drawing context.\n"); | |
+ sc = drw_scm_create(d, colors, 2); | |
drw_setscheme(d, sc); | |
- XSetWindowBackground(xw.dpy, xw.win, sc->bg.pix); | |
+ XSetWindowBackground(xw.dpy, xw.win, sc[ColBg].pixel); | |
xloadfonts(); | |
@@ -623,16 +602,16 @@ xloadfonts() | |
for (j = 0; j < LEN(fontfallbacks); j++) { | |
if (!(fstrs[j] = malloc(MAXFONTSTRLEN))) | |
- die("Unable to malloc fstrs."); | |
+ die("sent: Unable to malloc fstrs.\n"); | |
} | |
for (i = 0; i < NUMFONTSCALES; i++) { | |
for (j = 0; j < LEN(fontfallbacks); j++) { | |
if (MAXFONTSTRLEN < snprintf(fstrs[j], MAXFONTSTRLEN, … | |
- die("Font string too long."); | |
+ die("sent: Font string too long.\n"); | |
} | |
if (!(fonts[i] = drw_fontset_create(d, (const char**)fstrs, LE… | |
- die("Unable to load any font for size %d.", FONTSZ(i)); | |
+ die("sent: Unable to load any font for size %d.\n", FO… | |
} | |
for (j = 0; j < LEN(fontfallbacks); j++) | |
@@ -689,7 +668,7 @@ void | |
usage() | |
{ | |
die("sent " VERSION " (c) 2014-2015 [email protected]\n" \ | |
- "usage: sent [FILE]", argv0); | |
+ "usage: sent [FILE]\n", argv0); | |
} | |
int | |
@@ -706,7 +685,7 @@ main(int argc, char *argv[]) | |
if (!argv[0] || !strcmp(argv[0], "-")) | |
fp = stdin; | |
else if (!(fp = fopen(argv[0], "r"))) | |
- die("Unable to open '%s' for reading:", argv[0]); | |
+ die("sent: Unable to open '%s' for reading:", argv[0]); | |
load(fp); | |
fclose(fp); | |
diff --git a/util.c b/util.c | |
@@ -2,16 +2,32 @@ | |
#include <stdarg.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
+#include <string.h> | |
#include "util.h" | |
+void * | |
+ecalloc(size_t nmemb, size_t size) | |
+{ | |
+ void *p; | |
+ | |
+ if (!(p = calloc(nmemb, size))) | |
+ perror(NULL); | |
+ return p; | |
+} | |
+ | |
void | |
-die(const char *errstr, ...) { | |
+die(const char *fmt, ...) { | |
va_list ap; | |
- va_start(ap, errstr); | |
- vfprintf(stderr, errstr, ap); | |
+ va_start(ap, fmt); | |
+ vfprintf(stderr, fmt, ap); | |
va_end(ap); | |
+ | |
+ if (fmt[0] && fmt[strlen(fmt)-1] == ':') { | |
+ fputc(' ', stderr); | |
+ perror(NULL); | |
+ } | |
+ | |
exit(1); | |
} | |
- | |
diff --git a/util.h b/util.h | |
@@ -4,4 +4,5 @@ | |
#define MIN(A, B) ((A) < (B) ? (A) : (B)) | |
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) | |
-void die(const char *errstr, ...); | |
+void die(const char *fmt, ...); | |
+void *ecalloc(size_t nmemb, size_t size); |