st

Simple Terminal from suckless utilities
git clone git://git.thepablogq.xyz/st
Log | Files | Refs | README | LICENSE

commit 71b09ec4f172da9a89be2add54b5b94da8af3bea
parent 6d4e525ed95fbddc38be441394a02dc9233b157d
Author: Christoph Lohmann <20h@r-36.net>
Date:   Sun, 28 Oct 2012 13:25:53 +0100

Adding a more flexible fontstring handling, shortcuts and a zoom function.

Diffstat:
Mconfig.def.h | 14++++++++++++++
Mconfig.mk | 4++--
Mst.c | 186+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
3 files changed, 128 insertions(+), 76 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -1,4 +1,8 @@ +/* + * Do not include the »pixelsize« parameter in your font definition. It is + * used to calculate zooming. + */ #define FONT "Liberation Mono:pixelsize=12:antialias=false:autohint=false" /* Space in pixels around the terminal buffer */ @@ -73,6 +77,15 @@ static Key key[] = { { XK_F12, XK_NO_MOD, "\033[24~" }, }; +/* Internal shortcuts. */ +#define MODKEY Mod1Mask + +static Shortcut shortcuts[] = { + /* modifier key function argument */ + { MODKEY|ShiftMask, XK_Prior, xzoom, {.i = +1} }, + { MODKEY|ShiftMask, XK_Next, xzoom, {.i = -1} }, +}; + /* Set TERM to this */ #define TNAME "st-256color" @@ -81,3 +94,4 @@ static Key key[] = { #define TRIPLECLICK_TIMEOUT (2*DOUBLECLICK_TIMEOUT) #define TAB 8 + diff --git a/config.mk b/config.mk @@ -16,8 +16,8 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext -lXft -lfontconfig # flags CPPFLAGS = -DVERSION=\"${VERSION}\" -CFLAGS += -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} -LDFLAGS += -s ${LIBS} +CFLAGS += -g -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} +LDFLAGS += -g ${LIBS} # compiler and linker CC ?= cc diff --git a/st.c b/st.c @@ -60,6 +60,8 @@ #define REDRAW_TIMEOUT (80*1000) /* 80 ms */ +/* macros */ +#define CLEANMASK(mask) (mask & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) #define SERRNO strerror(errno) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) < (b) ? (b) : (a)) @@ -238,6 +240,24 @@ typedef struct { struct timeval tclick2; } Selection; +typedef union { + int i; + unsigned int ui; + float f; + const void *v; +} Arg; + +typedef struct { + unsigned int mod; + KeySym keysym; + void (*func)(const Arg *); + const Arg arg; +} Shortcut; + +/* function definitions used in config.h */ +static void xzoom(const Arg *); + +/* Config.h for applying patches and the configuration. */ #include "config.h" /* Font structure */ @@ -321,6 +341,7 @@ static void unmap(XEvent *); static char *kmap(KeySym, uint); static void kpress(XEvent *); static void cmessage(XEvent *); +static void cresize(int width, int height); static void resize(XEvent *); static void focus(XEvent *); static void brelease(XEvent *); @@ -345,7 +366,6 @@ static ssize_t xwrite(int, char *, size_t); static void *xmalloc(size_t); static void *xrealloc(void *, size_t); static void *xcalloc(size_t nmemb, size_t size); -static char *smstrcat(char *, ...); static void (*handler[LASTEvent])(XEvent *) = { [KeyPress] = kpress, @@ -381,6 +401,8 @@ static char *opt_embed = NULL; static char *opt_class = NULL; static char *opt_font = NULL; +static char *usedfont = NULL; +static int usedfontsize = 0; ssize_t xwrite(int fd, char *s, size_t len) { @@ -424,44 +446,6 @@ xcalloc(size_t nmemb, size_t size) { return p; } -char * -smstrcat(char *src, ...) -{ - va_list fmtargs; - char *ret, *p, *v; - int len, slen, flen; - - len = slen = strlen(src); - - va_start(fmtargs, src); - for(;;) { - v = va_arg(fmtargs, char *); - if(v == NULL) - break; - len += strlen(v); - } - va_end(fmtargs); - - p = ret = xmalloc(len+1); - memmove(p, src, slen); - p += slen; - - va_start(fmtargs, src); - for(;;) { - v = va_arg(fmtargs, char *); - if(v == NULL) - break; - flen = strlen(v); - memmove(p, v, flen); - p += flen; - } - va_end(fmtargs); - - ret[len] = '\0'; - - return ret; -} - int utf8decode(char *s, long *u) { uchar c; @@ -2107,7 +2091,8 @@ tresize(int col, int row) { *bp = 1; } /* update terminal size */ - term.col = col, term.row = row; + term.col = col; + term.row = row; /* make use of the LIMIT in tmoveto */ tmoveto(term.c.x, term.c.y); /* reset scrolling region */ @@ -2207,22 +2192,17 @@ xhints(void) { XFree(sizeh); } -void -xinitfont(Font *f, char *fontstr) { - FcPattern *pattern, *match; +int +xloadfont(Font *f, FcPattern *pattern) { + FcPattern *match; FcResult result; - pattern = FcNameParse((FcChar8 *)fontstr); - if(!pattern) - die("st: can't open font %s\n", fontstr); - match = XftFontMatch(xw.dpy, xw.scr, pattern, &result); - FcPatternDestroy(pattern); if(!match) - die("st: can't open font %s\n", fontstr); + return 1; if(!(f->xft_set = XftFontOpenPattern(xw.dpy, match))) { FcPatternDestroy(match); - die("st: can't open font %s.\n", fontstr); + return 1; } f->ascent = f->xft_set->ascent; @@ -2232,27 +2212,68 @@ xinitfont(Font *f, char *fontstr) { f->height = f->xft_set->height; f->width = f->lbearing + f->rbearing; + + return 0; } void -initfonts(char *fontstr) { - char *fstr; +xloadfonts(char *fontstr, int fontsize) { + FcPattern *pattern; + FcResult result; + double fontval; + + pattern = FcNameParse((FcChar8 *)fontstr); + if(!pattern) + die("st: can't open font %s\n", fontstr); + + if(fontsize > 0) { + FcPatternDel(pattern, FC_PIXEL_SIZE); + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize); + usedfontsize = fontsize; + } else { + result = FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval); + if(result == FcResultMatch) { + usedfontsize = (int)fontval; + } else { + /* + * Default font size is 12, if none given. This is to + * have a known usedfontsize value. + */ + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12); + usedfontsize = 12; + } + } - xinitfont(&dc.font, fontstr); + if(xloadfont(&dc.font, pattern)) + die("st: can't open font %s\n", fontstr); + + /* Setting character width and height. */ xw.cw = dc.font.width; xw.ch = dc.font.height; - fstr = smstrcat(fontstr, ":weight=bold", NULL); - xinitfont(&dc.bfont, fstr); - free(fstr); + FcPatternDel(pattern, FC_WEIGHT); + FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); + if(xloadfont(&dc.bfont, pattern)) + die("st: can't open font %s\n", fontstr); - fstr = smstrcat(fontstr, ":slant=italic,oblique", NULL); - xinitfont(&dc.ifont, fstr); - free(fstr); + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); + if(xloadfont(&dc.ibfont, pattern)) + die("st: can't open font %s\n", fontstr); - fstr = smstrcat(fontstr, ":weight=bold:slant=italic,oblique", NULL); - xinitfont(&dc.ibfont, fstr); - free(fstr); + FcPatternDel(pattern, FC_WEIGHT); + if(xloadfont(&dc.ifont, pattern)) + die("st: can't open font %s\n", fontstr); + + FcPatternDestroy(pattern); +} + +void +xzoom(const Arg *arg) +{ + xloadfonts(usedfont, usedfontsize + arg->i); + cresize(0, 0); + draw(); } void @@ -2268,7 +2289,8 @@ xinit(void) { xw.vis = XDefaultVisual(xw.dpy, xw.scr); /* font */ - initfonts((opt_font != NULL)? opt_font : FONT); + usedfont = (opt_font == NULL)? FONT : opt_font; + xloadfonts(usedfont, 0); /* colors */ xw.cmap = XDefaultColormap(xw.dpy, xw.scr); @@ -2604,11 +2626,8 @@ void kpress(XEvent *ev) { XKeyEvent *e = &ev->xkey; KeySym ksym; - char buf[32]; - char *customkey; - int len; - int meta; - int shift; + char buf[32], *customkey; + int len, meta, shift, i; Status status; if (IS_SET(MODE_KBDLOCK)) @@ -2618,7 +2637,17 @@ kpress(XEvent *ev) { shift = e->state & ShiftMask; len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status); - /* 1. custom keys from config.h */ + /* 1. shortcuts */ + for(i = 0; i < LEN(shortcuts); i++) { + if((ksym == shortcuts[i].keysym) + && (CLEANMASK(shortcuts[i].mod) == \ + CLEANMASK(e->state)) + && shortcuts[i].func) { + shortcuts[i].func(&(shortcuts[i].arg)); + } + } + + /* 2. custom keys from config.h */ if((customkey = kmap(ksym, e->state))) { ttywrite(customkey, strlen(customkey)); /* 2. hardcoded (overrides X lookup) */ @@ -2676,14 +2705,15 @@ cmessage(XEvent *e) { } void -resize(XEvent *e) { +cresize(int width, int height) +{ int col, row; - if(e->xconfigure.width == xw.w && e->xconfigure.height == xw.h) - return; + if(width != 0) + xw.w = width; + if(height != 0) + xw.h = height; - xw.w = e->xconfigure.width; - xw.h = e->xconfigure.height; col = (xw.w - 2*BORDER) / xw.cw; row = (xw.h - 2*BORDER) / xw.ch; if(col == term.col && row == term.row) @@ -2695,6 +2725,14 @@ resize(XEvent *e) { } void +resize(XEvent *e) { + if(e->xconfigure.width == xw.w && e->xconfigure.height == xw.h) + return; + + cresize(e->xconfigure.width, e->xconfigure.height); +} + +void run(void) { XEvent ev; fd_set rfd;