Re: [hackers][ubase][tput] tput(1)
2016-05-22 18:00 GMT-03:00 Lucas Vuotto: > Hello FRIGN, > > the patch is for ubase, not sbase, which, by definitio, is ugly :D > > Anyway, what you say may still hold true. The patch could be smaller if we > only deal with clear, init and reset parameters, as stated by POSIX. This > come by my mind, but after asking in #suckless, just got an answer from ??, > telling my to go full ncurses tput (which reminds me, it > ?? is Christoph Lohmann > only deals with string capabilities now -- will fix if it gets merged). > > As for the line count, I don't think it's possibly to make any library > dealing with terminfo smaller by a significant amount (say, 10% less > lines). Take in account that the library must provide a parser for a > context-free grammar. > > Aside, maybe tput is too much for ubase. It's listed in the TODO, but I > don't know if it's really needed. > > Concluding, I sent the patch so you can judge if it's worthless to merge > or no. It wasn't wasted time, because it helped me to find bugs in my > library :D > > Cheers. > > > -- lv. > > > > 2016-05-22 16:08 GMT-03:00 FRIGN : > > On Sun, 22 May 2016 16:01:43 -0300 > > Lucas Gabriel Vuotto wrote: > > > > Hey Lucas, > > > >> attached you will find two patches, one implementing a basic library > for dealing > >> with terminfo capabilities and another implementing the tput command > using that > >> library. The library itself is part of a bigger library from me, damned > [0], for > >> TUI creation. > > > >> 9 files changed, 2179 insertions(+), 3 deletions(-) > > > > :O > > > > definitely too much man. > > > > If we look at sbase, it has the following SLOC-count: > > > > Totals grouped by language (dominant language first): > > ansic:18805 (97.57%) > > awk:255 (1.32%) > > sh: 213 (1.11%) > > > > do you really think it's a good idea to increase its size > > by roughly 10% to accomodate one single command? > > > > Cheers > > > > FRIGN > > > > -- > > FRIGN > > > >
Re: [hackers][ubase][tput] tput(1)
Hello FRIGN, the patch is for ubase, not sbase, which, by definitio, is ugly :D Anyway, what you say may still hold true. The patch could be smaller if we only deal with clear, init and reset parameters, as stated by POSIX. This come by my mind, but after asking in #suckless, just got an answer from ??, telling my to go full ncurses tput (which reminds me, it only deals with string capabilities now -- will fix if it gets merged). As for the line count, I don't think it's possibly to make any library dealing with terminfo smaller by a significant amount (say, 10% less lines). Take in account that the library must provide a parser for a context-free grammar. Aside, maybe tput is too much for ubase. It's listed in the TODO, but I don't know if it's really needed. Concluding, I sent the patch so you can judge if it's worthless to merge or no. It wasn't wasted time, because it helped me to find bugs in my library :D Cheers. -- lv. 2016-05-22 16:08 GMT-03:00 FRIGN: > On Sun, 22 May 2016 16:01:43 -0300 > Lucas Gabriel Vuotto wrote: > > Hey Lucas, > >> attached you will find two patches, one implementing a basic library for dealing >> with terminfo capabilities and another implementing the tput command using that >> library. The library itself is part of a bigger library from me, damned [0], for >> TUI creation. > >> 9 files changed, 2179 insertions(+), 3 deletions(-) > > :O > > definitely too much man. > > If we look at sbase, it has the following SLOC-count: > > Totals grouped by language (dominant language first): > ansic:18805 (97.57%) > awk:255 (1.32%) > sh: 213 (1.11%) > > do you really think it's a good idea to increase its size > by roughly 10% to accomodate one single command? > > Cheers > > FRIGN > > -- > FRIGN >
[hackers] [sent] import new drw and util from libsl.
--- config.def.h | 6 +- drw.c| 326 ++- drw.h| 28 ++--- sent.c | 85 ++-- util.c | 24 - util.h | 3 +- 6 files changed, 235 insertions(+), 237 deletions(-) diff --git a/config.def.h b/config.def.h index 92d577c..023f8cd 100644 --- 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-1] */ -static const char *fgcol = "#00"; -static const char *bgcol = "#FF"; +static const char *colors[] = { + "#00", /* foreground color */ + "#FF", /* background color */ +}; static const float linespacing = 1.4; diff --git a/drw.c b/drw.c index be30400..987e53b 100644 --- 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, 0xF0}; static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; @@ -19,50 +17,54 @@ static const long utfmin[UTF_SIZ + 1] = { 0,0, 0x80, 0x800, 0x1 static const long utfmax[UTF_SIZ + 1] = {0x10, 0x7F, 0x7FF, 0x, 0x10}; 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], ); - 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], ); - 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 h) { - Drw *drw = (Drw *)calloc(1, sizeof(Drw)); - if(!drw) - return NULL; +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +{ + 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 int w, unsigned int 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) +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(drw->dpy, drw->screen)); } 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 yield the
[hackers] [dmenu] import new drw from libsl and minor fixes.
- extract drawitem function (code deduplication) - fix bug where inputw was not correctly calculated from the widest item, but just from the one with the longest strlen() which is not the same. - minor code style fixes (indentation, useless line breaks) --- config.def.h | 12 +-- dmenu.c | 142 +++-- drw.c| 253 --- drw.h| 63 ++- util.h | 4 +- 5 files changed, 232 insertions(+), 242 deletions(-) diff --git a/config.def.h b/config.def.h index dcffd38..5ac2af8 100644 --- a/config.def.h +++ b/config.def.h @@ -7,12 +7,12 @@ static const char *fonts[] = { "monospace:size=10" }; static const char *prompt = NULL; /* -p option; prompt to the left of input field */ -static const char *normbgcolor = "#22"; /* -nb option; normal background */ -static const char *normfgcolor = "#bb"; /* -nf option; normal foreground */ -static const char *selbgcolor = "#005577"; /* -sb option; selected background */ -static const char *selfgcolor = "#ee"; /* -sf option; selected foreground */ -static const char *outbgcolor = "#00"; -static const char *outfgcolor = "#00"; +static const char *colors[][2] = { +/* fg bg */ + { "#bb", "#22" }, /* normal */ + { "#ee", "#005577" }, /* selected */ + { "#00", "#00" }, /* out */ +}; /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ static unsigned int lines = 0; diff --git a/dmenu.c b/dmenu.c index e0c2f80..f802553 100644 --- a/dmenu.c +++ b/dmenu.c @@ -22,8 +22,7 @@ #define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) #define LENGTH(X) (sizeof X / sizeof X[0]) -#define TEXTNW(X,N) (drw_font_getexts_width(drw->fonts[0], (X), (N))) -#define TEXTW(X) (drw_text(drw, 0, 0, 0, 0, (X), 0) + drw->fonts[0]->h) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) /* enums */ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ @@ -37,7 +36,8 @@ struct item { static char text[BUFSIZ] = ""; static int bh, mw, mh; static int sw, sh; /* X display screen geometry width, height */ -static int inputw, promptw; +static int inputw = 0, promptw; +static int lrpad; /* sum of left and right padding */ static size_t cursor; static struct item *items = NULL; static struct item *matches, *matchend; @@ -49,8 +49,8 @@ static Display *dpy; static Window root, win; static XIC xic; -static ClrScheme scheme[SchemeLast]; static Drw *drw; +static Scm scheme[SchemeLast]; #include "config.h" @@ -81,10 +81,10 @@ calcoffsets(void) n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); /* calculate which items will begin the next page and previous page */ for (i = 0, next = curr; next; next = next->right) - if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n) + if ((i += (lines > 0) ? bh : TEXTW(next->text)) > n) break; for (i = 0, prev = curr; prev && prev->left; prev = prev->left) - if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n) + if ((i += (lines > 0) ? bh : TEXTW(prev->left->text)) > n) break; } @@ -94,10 +94,8 @@ cleanup(void) size_t i; XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < SchemeLast; i++) { - drw_clr_free(scheme[i].bg); - drw_clr_free(scheme[i].fg); - } + for (i = 0; i < SchemeLast; i++) + free(scheme[i]); drw_free(drw); XSync(dpy, False); XCloseDisplay(dpy); @@ -114,70 +112,63 @@ cistrstr(const char *s, const char *sub) return NULL; } +static int +drawitem(struct item *item, int x, int y, int w) +{ + if (item == sel) + drw_setscheme(drw, scheme[SchemeSel]); + else if (item->out) + drw_setscheme(drw, scheme[SchemeOut]); + else + drw_setscheme(drw, scheme[SchemeNorm]); + + return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); +} + static void drawmenu(void) { - int curpos; + unsigned int curpos; struct item *item; - int x = 0, y = 0, h = bh, w; + int x = 0, y = 0, w; - drw_setscheme(drw, [SchemeNorm]); - drw_rect(drw, 0, 0, mw, mh, 1, 1, 1); + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, 0, 0, mw, mh, 1, 1); if (prompt && *prompt) { - drw_setscheme(drw, [SchemeSel]); - drw_text(drw, x, 0, promptw, bh, prompt, 0); - x += promptw; +
[hackers] [dwm] import new drw from libsl and minor fixes.
- better scaling for occupied tag squares. - draw statusline first to omitt some complicated calculations. --- config.def.h | 24 +++--- drw.c| 253 --- drw.h| 63 ++- dwm.c| 85 +--- util.h | 4 +- 5 files changed, 215 insertions(+), 214 deletions(-) diff --git a/config.def.h b/config.def.h index 7054c06..13ea4b9 100644 --- a/config.def.h +++ b/config.def.h @@ -1,20 +1,22 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -static const char *fonts[] = { - "monospace:size=10" -}; -static const char dmenufont[] = "monospace:size=10"; -static const char normbordercolor[] = "#44"; -static const char normbgcolor[] = "#22"; -static const char normfgcolor[] = "#bb"; -static const char selbordercolor[] = "#005577"; -static const char selbgcolor[] = "#005577"; -static const char selfgcolor[] = "#ee"; static const unsigned int borderpx = 1;/* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ static const int showbar= 1;/* 0 means no bar */ static const int topbar = 1;/* 0 means bottom bar */ +static const char *fonts[] = { "monospace:size=10" }; +static const char dmenufont[] = "monospace:size=10"; +static const char col_gray1[] = "#22"; +static const char col_gray2[] = "#44"; +static const char col_gray3[] = "#bb"; +static const char col_gray4[] = "#ee"; +static const char col_cyan[]= "#005577"; +static const char *colors[][3] = { + /* fgbg border */ + { col_gray3, col_gray1, col_gray2}, /* normal */ + { col_gray4, col_cyan, col_cyan }, /* selected */ +}; /* tagging */ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; @@ -54,7 +56,7 @@ static const Layout layouts[] = { /* commands */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ -static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; static const char *termcmd[] = { "st", NULL }; static Key keys[] = { diff --git a/drw.c b/drw.c index f49200b..987e53b 100644 --- a/drw.c +++ b/drw.c @@ -63,9 +63,8 @@ utf8decode(const char *c, long *u, size_t clen) Drw * drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) { - Drw *drw; + Drw *drw = ecalloc(1, sizeof(Drw)); - drw = ecalloc(1, sizeof(Drw)); drw->dpy = dpy; drw->screen = screen; drw->root = root; @@ -73,7 +72,6 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h drw->h = h; drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); drw->gc = XCreateGC(dpy, root, 0, NULL); - drw->fontcount = 0; XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); return drw; @@ -82,6 +80,9 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h void drw_resize(Drw *drw, unsigned int w, unsigned int h) { + if (!drw) + return; + drw->w = w; drw->h = h; if (drw->drawable) @@ -92,44 +93,39 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) void drw_free(Drw *drw) { - size_t i; - - for (i = 0; i < drw->fontcount; i++) - drw_font_free(drw->fonts[i]); XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); free(drw); } /* This function is an implementation detail. Library users should use - * drw_font_create instead. + * 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; XftFont *xfont = NULL; FcPattern *pattern = NULL; if (fontname) { - /* Using the pattern found at font->xfont->pattern does not yield same -* the same substitution results as using the pattern returned by + /* Using the pattern found at font->xfont->pattern does not yield the +* same substitution results as using the pattern returned by * FcNameParse; using the latter results in the desired fallback -* behaviour whereas the former just results in -* missing-character-rectangles being drawn, at least with some fonts. -*/ +* behaviour whereas the former just results in
[hackers] [PATCH 8/8] drw: fixup drw_text
- add optional left padding parameter which is ignored on non-render calls where just the width of the text is calculated. - add /* NOP */ comments to empty loop bodies. --- drw.c | 30 +++--- drw.h | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drw.c b/drw.c index 80383c9..987e53b 100644 --- a/drw.c +++ b/drw.c @@ -235,10 +235,10 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int } int -drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert) +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) { char buf[1024]; - int tx, ty, th; + int ty; unsigned int ew; XftDraw *d = NULL; Fnt *usedfont, *curfont, *nextfont; @@ -258,12 +258,13 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex if (!render) { w = ~w; } else { - XSetForeground(drw->dpy, drw->gc, invert ? - drw->scheme[ColFg].pixel : drw->scheme[ColBg].pixel); + XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); 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; @@ -295,20 +296,20 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex if (utf8strlen) { drw_font_getexts(usedfont, utf8str, utf8strlen, , NULL); /* shorten text if necessary */ - for (len = MIN(utf8strlen, (sizeof buf) - 1); len && (ew > w - usedfont->h || w < usedfont->h); len--) + for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) drw_font_getexts(usedfont, utf8str, len, , NULL); if (len) { memcpy(buf, utf8str, len); buf[len] = '\0'; if (len < utf8strlen) - for (i = len; i && i > len - 3; buf[--i] = '.'); + for (i = len; i && i > len - 3; buf[--i] = '.') + ; /* NOP */ if (render) { - th = usedfont->h; - ty = y + (h - th) / 2 + usedfont->xfont->ascent; - tx = x + (h / 2); - XftDrawStringUtf8(d, invert ? >scheme[ColBg] : >scheme[ColFg], usedfont->xfont, tx, ty, (XftChar8 *)buf, len); + ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; + XftDrawStringUtf8(d, >scheme[invert ? ColBg : ColFg], + usedfont->xfont, x, ty, (XftChar8 *)buf, len); } x += ew; w -= ew; @@ -322,8 +323,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex usedfont = nextfont; } else { /* Regardless of whether or not a fallback font is found, the -* character must be drawn. -*/ +* character must be drawn. */ charexists = 1; fccharset = FcCharSetCreate(); @@ -349,7 +349,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex usedfont = xfont_create(drw, NULL, match); if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { for (curfont = drw->fonts; curfont->next; curfont = curfont->next) - ; /* just find the end of the linked list */ + ; /* NOP */ curfont->next = usedfont; } else { xfont_free(usedfont); @@ -361,7 +361,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex if (d) XftDrawDestroy(d); - return x; + return x + (render ? w : 0); } void @@ -379,7 +379,7 @@ drw_fontset_getwidth(Drw *drw, const char *text) { if
[hackers] [PATCH 7/8] drw: misc fixes
--- drw.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drw.c b/drw.c index 0adf33e..80383c9 100644 --- a/drw.c +++ b/drw.c @@ -63,9 +63,8 @@ utf8decode(const char *c, long *u, size_t clen) Drw * drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) { - Drw *drw; + Drw *drw = ecalloc(1, sizeof(Drw)); - drw = ecalloc(1, sizeof(Drw)); drw->dpy = dpy; drw->screen = screen; drw->root = root; @@ -81,6 +80,9 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h void drw_resize(Drw *drw, unsigned int w, unsigned int h) { + if (!drw) + return; + drw->w = w; drw->h = h; if (drw->drawable) @@ -365,6 +367,9 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex 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); } @@ -397,7 +402,9 @@ drw_cur_create(Drw *drw, int shape) { Cur *cur; - cur = ecalloc(1, sizeof(Cur)); + if (!drw || !(cur = ecalloc(1, sizeof(Cur + return NULL; + cur->cursor = XCreateFontCursor(drw->dpy, shape); return cur; @@ -408,6 +415,7 @@ drw_cur_free(Drw *drw, Cur *cursor) { if (!cursor) return; + XFreeCursor(drw->dpy, cursor->cursor); free(cursor); } -- 2.7.3
[hackers] [PATCH 6/8] drw: fixup font handling
- replace static sized fontcache array with dynamic linked list (sent needs that). - remove `drw_` prefix from static helper functions. - distinguish different error cases in internal xfont_create. - remove ascent and descent members from struct Fnt since they are seldomly used and can still be accessed within the xfont member. - remove exported function to load a single font, use the drw_fontset_create function instead. - add drw_fontset_getwidth function to calculate width of a string rendered with the selected fontset. - clarify variable name in drw_text (curfont -> usedfont). curfont is only used as loop index now. - fix bug where first font in set was used to calculate truncation width instead of currently used fallback font. --- drw.c | 147 +++--- drw.h | 17 2 files changed, 86 insertions(+), 78 deletions(-) diff --git a/drw.c b/drw.c index 88d4eac..0adf33e 100644 --- a/drw.c +++ b/drw.c @@ -73,7 +73,6 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h drw->h = h; drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); drw->gc = XCreateGC(dpy, root, 0, NULL); - drw->fontcount = 0; XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); return drw; @@ -92,44 +91,39 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) void drw_free(Drw *drw) { - size_t i; - - for (i = 0; i < drw->fontcount; i++) - drw_font_free(drw->fonts[i]); XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); free(drw); } /* This function is an implementation detail. Library users should use - * drw_font_create instead. + * 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; XftFont *xfont = NULL; FcPattern *pattern = NULL; if (fontname) { - /* Using the pattern found at font->xfont->pattern does not yield same -* the same substitution results as using the pattern returned by + /* Using the pattern found at font->xfont->pattern does not yield the +* same substitution results as using the pattern returned by * FcNameParse; using the latter results in the desired fallback -* behaviour whereas the former just results in -* missing-character-rectangles being drawn, at least with some fonts. -*/ +* behaviour whereas the former just results in missing-character +* rectangles being drawn, at least with some fonts. */ if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { - fprintf(stderr, "error, cannot load font: '%s'\n", fontname); + fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); return NULL; } if (!(pattern = FcNameParse((FcChar8 *) fontname))) { - fprintf(stderr, "error, cannot load font: '%s'\n", fontname); + fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); XftFontClose(drw->dpy, xfont); return NULL; } } else if (fontpattern) { if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { - fprintf(stderr, "error, cannot load font pattern.\n"); + fprintf(stderr, "error, cannot load font from pattern.\n"); return NULL; } } else { @@ -139,37 +133,14 @@ drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) font = ecalloc(1, sizeof(Fnt)); font->xfont = xfont; font->pattern = pattern; - font->ascent = xfont->ascent; - font->descent = xfont->descent; - font->h = font->ascent + font->descent; + font->h = xfont->ascent + xfont->descent; font->dpy = drw->dpy; return font; } -Fnt* -drw_font_create(Drw *drw, const char *fontname) -{ - return drw_font_xcreate(drw, fontname, NULL); -} - -void -drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) -{ - size_t i; - Fnt *font; - - for (i = 0; i < fontcount; i++) { - if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { - die("font cache exhausted.\n"); - } else if ((font = drw_font_xcreate(drw, fonts[i], NULL))) { - drw->fonts[drw->fontcount++] = font; - } - } -} - -void -drw_font_free(Fnt *font) +static void +xfont_free(Fnt *font) { if (!font) return; @@
[hackers] [PATCH 5/8] drw: fixup drw_rect function
- drw_rect was just setting the color when filled == empty == 0. If you don't want to draw a rectangle, you should not call drw_rect. - parameters w and h now also specify the result exactly. --- drw.c | 10 +- drw.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drw.c b/drw.c index e56cb47..88d4eac 100644 --- a/drw.c +++ b/drw.c @@ -216,15 +216,15 @@ drw_setscheme(Drw *drw, Scm scm) } void -drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) +drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) { - if (!drw->scheme) + if (!drw || !drw->scheme) return; XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); if (filled) - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w + 1, h + 1); - else if (empty) - XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + else + XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); } int diff --git a/drw.h b/drw.h index 61633d9..8ce6bc5 100644 --- a/drw.h +++ b/drw.h @@ -53,7 +53,7 @@ void drw_setfont(Drw *drw, Fnt *font); void drw_setscheme(Drw *drw, Scm scm); /* 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_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert); /* Map functions */ -- 2.7.3
[hackers] [PATCH 4/8] drw: simplify color schemes
- Use simple XftColor type instead of Clr struct => No need for drw_clr_free function. - Replace ClrScheme struct with simple array of XftColor items `Scm`. - Add Enum with ColFg and ColBg for indexing Scm type variables. - Remove border color, since drw.c does never use it. dwm can still use it by creating a 3 element Scm. --- drw.c | 47 --- drw.h | 22 +++--- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/drw.c b/drw.c index ac27cdc..e56cb47 100644 --- a/drw.c +++ b/drw.c @@ -179,31 +179,40 @@ drw_font_free(Fnt *font) free(font); } -Clr * -drw_clr_create(Drw *drw, const char *clrname) +void +drw_clr_create(Drw *drw, XftColor *dest, const char *clrname) { - Clr *clr; + if (!drw || !dest || !clrname) + return; - clr = ecalloc(1, sizeof(Clr)); if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), DefaultColormap(drw->dpy, drw->screen), - clrname, >rgb)) + clrname, dest)) die("error, cannot allocate color '%s'\n", clrname); - clr->pix = clr->rgb.pixel; - - return clr; } -void -drw_clr_free(Clr *clr) +/* Wrapper to create color schemes. The caller has to call free(3) on the + * returned color scheme when done using it. */ +Scm +drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) { - free(clr); + size_t i; + Scm ret; + + /* need at least two colors for a scheme */ + if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor + return NULL; + + for (i = 0; i < clrcount; i++) + drw_clr_create(drw, [i], clrnames[i]); + return ret; } void -drw_setscheme(Drw *drw, ClrScheme *scheme) +drw_setscheme(Drw *drw, Scm scm) { - drw->scheme = scheme; + if (drw) + drw->scheme = scm; } void @@ -211,7 +220,7 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int { if (!drw->scheme) return; - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->pix : drw->scheme->fg->pix); + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); if (filled) XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w + 1, h + 1); else if (empty) @@ -227,7 +236,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex XftDraw *d = NULL; Fnt *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; @@ -236,14 +245,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex XftResult result; int charexists = 0; - if (!drw->scheme || !drw->fontcount) + if ((render && !drw->scheme) || !drw->fontcount) return 0; - if (!(render = x || y || w || h)) { + if (!render) { w = ~w; } else { XSetForeground(drw->dpy, drw->gc, invert ? - drw->scheme->fg->pix : drw->scheme->bg->pix); + drw->scheme[ColFg].pixel : drw->scheme[ColBg].pixel); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); d = XftDrawCreate(drw->dpy, drw->drawable, DefaultVisual(drw->dpy, drw->screen), @@ -292,7 +301,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex th = curfont->ascent + curfont->descent; ty = y + (h / 2) - (th / 2) + curfont->ascent; tx = x + (h / 2); - XftDrawStringUtf8(d, invert ? >scheme->bg->rgb : >scheme->fg->rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len); + XftDrawStringUtf8(d, invert ? >scheme[ColBg] : >scheme[ColFg], curfont->xfont, tx, ty, (XftChar8 *)buf, len); } x += ew; w -= ew; diff --git a/drw.h b/drw.h index 28f7c61..61633d9 100644 --- a/drw.h +++ b/drw.h @@ -2,11 +2,6 @@ #define DRW_FONT_CACHE_SIZE 32 typedef struct { - unsigned long pix; - XftColor rgb; -} Clr; - -typedef struct { Cursor cursor; } Cur; @@ -19,11 +14,8 @@ typedef struct { FcPattern *pattern; } Fnt; -typedef struct { - Clr *fg; - Clr *bg; - Clr *border; -} ClrScheme; +enum { ColFg, ColBg, ColCount }; /* Scm index */ +typedef XftColor *Scm; typedef struct {
[hackers] [PATCH 3/8] drw: simplify font_getexts
The struct Extnts was pointless. With the new interface there is also no need to have an extra function which just extracts the width. --- drw.c | 33 ++--- drw.h | 8 +--- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/drw.c b/drw.c index f49200b..ac27cdc 100644 --- a/drw.c +++ b/drw.c @@ -223,7 +223,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex { char buf[1024]; int tx, ty, th; - Extnts tex; + unsigned int ew; XftDraw *d = NULL; Fnt *curfont, *nextfont; size_t i, len; @@ -277,10 +277,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex } if (utf8strlen) { - drw_font_getexts(curfont, utf8str, utf8strlen, ); + drw_font_getexts(curfont, utf8str, utf8strlen, , NULL); /* shorten text if necessary */ - for (len = MIN(utf8strlen, (sizeof buf) - 1); len && (tex.w > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--) - drw_font_getexts(curfont, utf8str, len, ); + for (len = MIN(utf8strlen, (sizeof buf) - 1); len && (ew > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--) + drw_font_getexts(curfont, utf8str, len, , NULL); if (len) { memcpy(buf, utf8str, len); @@ -294,8 +294,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex tx = x + (h / 2); XftDrawStringUtf8(d, invert ? >scheme->bg->rgb : >scheme->fg->rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len); } - x += tex.w; - w -= tex.w; + x += ew; + w -= ew; } } @@ -358,23 +358,18 @@ drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) } void -drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) +drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) { XGlyphInfo ext; + if (!font || !text) + return; + XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, ); - tex->h = font->h; - tex->w = ext.xOff; -} - -unsigned int -drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) -{ - Extnts tex; - - drw_font_getexts(font, text, len, ); - - return tex.w; + if (w) + *w = ext.xOff; + if (h) + *h = font->h; } Cur * diff --git a/drw.h b/drw.h index 536171b..28f7c61 100644 --- a/drw.h +++ b/drw.h @@ -37,11 +37,6 @@ typedef struct { Fnt *fonts[DRW_FONT_CACHE_SIZE]; } 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); @@ -51,8 +46,7 @@ void drw_free(Drw *drw); Fnt *drw_font_create(Drw *drw, const char *fontname); void drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount); void drw_font_free(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); +void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); /* Colour abstraction */ Clr *drw_clr_create(Drw *drw, const char *clrname); -- 2.7.3
Re: [hackers][ubase][tput] tput(1)
On Sun, 22 May 2016 16:01:43 -0300 Lucas Gabriel Vuottowrote: Hey Lucas, > attached you will find two patches, one implementing a basic library for > dealing > with terminfo capabilities and another implementing the tput command using > that > library. The library itself is part of a bigger library from me, damned [0], > for > TUI creation. > 9 files changed, 2179 insertions(+), 3 deletions(-) :O definitely too much man. If we look at sbase, it has the following SLOC-count: Totals grouped by language (dominant language first): ansic:18805 (97.57%) awk:255 (1.32%) sh: 213 (1.11%) do you really think it's a good idea to increase its size by roughly 10% to accomodate one single command? Cheers FRIGN -- FRIGN
[hackers] [PATCH 1/2] Import libterminfo
Modified source from https://gitlab.com/lv/damned.git Signed-off-by: Lucas Gabriel Vuotto--- Makefile | 24 +- libterminfo/Makefile | 10 + libterminfo/mkcaps.h.awk | 22 + libterminfo/mkcapsutil.h.awk | 42 ++ libterminfo/ncurses-5.9/Caps | 1258 ++ libterminfo/terminfo.c | 178 ++ libterminfo/tparse.c | 614 + terminfo.h | 32 ++ util.h |2 + 9 files changed, 2179 insertions(+), 3 deletions(-) create mode 100644 libterminfo/Makefile create mode 100644 libterminfo/mkcaps.h.awk create mode 100644 libterminfo/mkcapsutil.h.awk create mode 100644 libterminfo/ncurses-5.9/Caps create mode 100644 libterminfo/terminfo.c create mode 100644 libterminfo/tparse.c create mode 100644 terminfo.h diff --git a/Makefile b/Makefile index 453607c..c639d69 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ HDR = \ queue.h \ reboot.h \ rtc.h\ + terminfo.h \ text.h \ util.h @@ -34,7 +35,16 @@ LIBUTILSRC = \ libutil/strtonum.c \ libutil/tty.c -LIB = $(LIBUTIL) +LIBTERMINFO = libterminfo.a +LIBTERMINFOSRC = \ + libterminfo/terminfo.c \ + libterminfo/tparse.c +LIBTERMINFOGENHDR = \ + libterminfo/damned-caps.h \ + libterminfo/damned-capsutil.h \ + libterminfo/capstbl.h + +LIB = $(LIBTERMINFO) $(LIBUTIL) BIN = \ chvt \ @@ -144,7 +154,8 @@ MAN8 = \ umount.8 LIBUTILOBJ = $(LIBUTILSRC:.c=.o) -OBJ = $(BIN:=.o) $(LIBUTILOBJ) +LIBTERMINFOOBJ = $(LIBTERMINFOSRC:.c=.o) +OBJ = $(BIN:=.o) $(LIBUTILOBJ) $(LIBTERMINFOOBJ) SRC = $(BIN:=.c) all: $(BIN) @@ -166,6 +177,13 @@ $(LIBUTIL): $(LIBUTILOBJ) $(AR) rc $@ $? $(RANLIB) $@ +$(LIBTERMINFOGENHDR): + cd libterminfo && $(MAKE) $(MAKEFLAGS) + +$(LIBTERMINFO): $(LIBTERMINFOGENHDR) $(LIBTERMINFOOBJ) + $(AR) rc $@ $? + $(RANLIB) $@ + install: all mkdir -p $(DESTDIR)$(PREFIX)/bin cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin @@ -221,7 +239,7 @@ ubase-box-install: ubase-box cd $(DESTDIR)$(MANPREFIX)/man8 && chmod 644 $(MAN8) clean: - rm -f $(BIN) $(OBJ) $(LIB) ubase-box ubase-$(VERSION).tar.gz + rm -f $(BIN) $(OBJ) $(LIB) $(LIBTERMINFOGENHDR) ubase-box ubase-$(VERSION).tar.gz .PHONY: all install uninstall dist ubase-box ubase-box-install clean diff --git a/libterminfo/Makefile b/libterminfo/Makefile new file mode 100644 index 000..0fff6ab --- /dev/null +++ b/libterminfo/Makefile @@ -0,0 +1,10 @@ +all: damned-caps.h damned-capsutil.h + +damned-caps.h: mkcaps.h.awk + rm -f $@ + awk -f $< -v caps=1 ncurses-5.9/Caps >>$@ + awk -f $< -v caps=0 ncurses-5.9/Caps >>$@ + +damned-capsutil.h: mkcapsutil.h.awk + rm -f $@ + awk -f $< ncurses-5.9/Caps >$@ diff --git a/libterminfo/mkcaps.h.awk b/libterminfo/mkcaps.h.awk new file mode 100644 index 000..77d1bde --- /dev/null +++ b/libterminfo/mkcaps.h.awk @@ -0,0 +1,22 @@ +#!/usr/bin/env awk + +BEGIN { + print "typedef enum {" +} + +/^# %%-STOP-HERE-%%$/ { exit } +/^#/ { next } +caps { + print "\tTI_" $2 "," +} +!caps && $1 != $2 { + print "\tTI_" $1 " = TI_" $2 "," +} + +END { + if (caps) { + print "} Capname;" + } else { + print "} Capvarname;" + } +} diff --git a/libterminfo/mkcapsutil.h.awk b/libterminfo/mkcapsutil.h.awk new file mode 100644 index 000..0d75205 --- /dev/null +++ b/libterminfo/mkcapsutil.h.awk @@ -0,0 +1,42 @@ +#!/usr/bin/env awk + +BEGIN { + fbool = "" + lbool = "" + fnum = "" + lnum = "" + fstr = "" + lstr = "" +} + +/^# %%-STOP-HERE-%%$/ { exit } +/^#/ { next } +{ + if ($3 == "bool") { + if (fbool == "") { + fbool = $2 + print "#define FIRSTBOOL TI_" fbool + } + lbool = $2 + } + if ($3 == "num") { + if (fnum == "") { + fnum = $2 + print "#define LASTBOOL TI_" lbool + print "#define FIRSTNUM TI_" fnum + } + lnum = $2 + } + if ($3 == "str") { + if (fstr == "") { + fstr = $2 + print "#define LASTNUM TI_" lnum + print "#define FIRSTSTR TI_" fstr + } + lstr = $2 + } +} + +END { + print "#define LASTSTR TI_" lstr +} diff --git a/libterminfo/ncurses-5.9/Caps b/libterminfo/ncurses-5.9/Caps new file mode 100644 index 000..f9a8ebd --- /dev/null +++ b/libterminfo/ncurses-5.9/Caps @@ -0,0 +1,1258 @@ +## +# Copyright (c) 1998-2006,2010 Free Software
[hackers][ubase][tput] tput(1)
Hello suckless, attached you will find two patches, one implementing a basic library for dealing with terminfo capabilities and another implementing the tput command using that library. The library itself is part of a bigger library from me, damned [0], for TUI creation. The library is work in progress, so it can be a little sucky or bloated at times (after all, the terminal's world sucks), plus it may have some bugs. Found a lot implementing tput and there are already plans for doing some things better. Any feedback or suggestions are welcome. It lacks a manpage. I might do one in the following weeks, but if there is any candidate to do it, he/she will be welcome. Hope it's useful for you guys, keep rockin'. Cheers. -- [0]: https://gitlab.com/lv/damned.git -- lv.
[hackers] [PATCH 2/2] Add tput(1)
Signed-off-by: Lucas Gabriel Vuotto--- Makefile| 1 + TODO| 2 +- libterminfo/Makefile| 6 +- libterminfo/mkcapstbl.h.awk | 19 +++ tput.c | 134 5 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 libterminfo/mkcapstbl.h.awk create mode 100644 tput.c diff --git a/Makefile b/Makefile index c639d69..54b02ad 100644 --- a/Makefile +++ b/Makefile @@ -91,6 +91,7 @@ BIN = \ swapon\ switch_root \ sysctl\ + tput \ truncate \ umount\ unshare \ diff --git a/TODO b/TODO index 21f5c20..3ef3e31 100644 --- a/TODO +++ b/TODO @@ -26,7 +26,6 @@ setcap tabs taskset top -tput vmstat Misc @@ -34,3 +33,4 @@ Misc Beautify passwd(1). last(1) manpage. +tput(1) manpage. diff --git a/libterminfo/Makefile b/libterminfo/Makefile index 0fff6ab..ad55688 100644 --- a/libterminfo/Makefile +++ b/libterminfo/Makefile @@ -1,4 +1,4 @@ -all: damned-caps.h damned-capsutil.h +all: damned-caps.h damned-capsutil.h capstbl.h damned-caps.h: mkcaps.h.awk rm -f $@ @@ -8,3 +8,7 @@ damned-caps.h: mkcaps.h.awk damned-capsutil.h: mkcapsutil.h.awk rm -f $@ awk -f $< ncurses-5.9/Caps >$@ + +capstbl.h: mkcapstbl.h.awk + rm -f $@ + awk -f $< ncurses-5.9/Caps >$@ diff --git a/libterminfo/mkcapstbl.h.awk b/libterminfo/mkcapstbl.h.awk new file mode 100644 index 000..57925ca --- /dev/null +++ b/libterminfo/mkcapstbl.h.awk @@ -0,0 +1,19 @@ +#!/usr/bin/env awk + +BEGIN { + print "static struct {" + print "\tconst char *name;" + print "\tconst char *varname;" + print "\tCapname cn;" + print "} tbl[] = {" +} + +/^# %%-STOP-HERE-%%$/ { exit } +/^#/ { next } +{ + print "\t{ \"" $2 "\", \"" $1 "\", TI_" $2 " }," +} + +END { + print "};" +} diff --git a/tput.c b/tput.c new file mode 100644 index 000..21e96de --- /dev/null +++ b/tput.c @@ -0,0 +1,134 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include + +#include "terminfo.h" +#include "util.h" + +/* needs libterminfo/caps.h, included from terminfo.h */ +#include "libterminfo/capstbl.h" + +static char *dummyargs[] = { NULL }; +static char *params[9]; + +static int +docap(int cap, char **p) +{ + char *o; + size_t l; + int i, r = 0; + + for (i = 0; p[i]; i++) + params[i] = p[i]; + for (; i < 9; i++); + params[i] = NULL; + + o = tparse(cap, + params[0], params[1], params[2], + params[3], params[4], params[5], + params[6], params[7], params[8]); + if (!o) + return -2; + l = strlen(o); + if (fwrite(o, sizeof(char), l, stdout) != l) + r = -1; + free(o); + + return r; +} + +static void +doclear(void) +{ + docap(TI_clear, dummyargs); +} + +static void +doinit(void) +{ + /* TODO: do something about iprog and if */ + docap(TI_is1, dummyargs); + docap(TI_is2, dummyargs); + docap(TI_mgc, dummyargs); + docap(TI_smgl, dummyargs); + docap(TI_smgr, dummyargs); + docap(TI_tbc, dummyargs); + docap(TI_hts, dummyargs); + docap(TI_is3, dummyargs); +} + +static void +doreset(void) +{ + if (docap(TI_rs1, dummyargs) < 0) + docap(TI_is1, dummyargs); + if (docap(TI_rs2, dummyargs) < 0) + docap(TI_is2, dummyargs); + docap(TI_mgc, dummyargs); + docap(TI_smgl, dummyargs); + docap(TI_smgr, dummyargs); + docap(TI_tbc, dummyargs); + docap(TI_hts, dummyargs); + if (docap(TI_rs3, dummyargs) < 0) + docap(TI_is3, dummyargs); +} + +static void +usage(void) +{ + eprintf("usage: %s [-T term] [capargs...]\n", argv0); +} + + +int +main(int argc, char *argv[]) +{ + char *term = NULL; + int cap = -1, i; + + ARGBEGIN { + case 'T': + term = EARGF(usage()); + if (setenv("TERM", term, 1) < 0) + eprintf("couldn't change terminal type\n", argv0); + break; + default: + usage(); + } ARGEND; + + if (argc == 0) + usage(); + + if (setupterminfo() < 0) + enprintf(3, "couldn't init terminfo\n"); + + if (!strcmp("clear", *argv)) { + doclear(); + return 0; + } else if (!strcmp("init", *argv)) { + doinit(); + return 0; + } else if (!strcmp("reset", *argv)) { + doreset(); + return 0; + } + + for (i = 0; i < LEN(tbl) && cap < 0; i++) { + if (!strcmp(tbl[i].name, *argv) || !strcmp(tbl[i].varname, *argv)) +