# st

Unnamed repository; edit this file 'description' to name the repository.

| 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;