Adding a more flexible fontstring handling, shortcuts and a zoom function. - st - Personal fork of st
 (HTM) git clone git://git.drkhsh.at/st.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 71b09ec4f172da9a89be2add54b5b94da8af3bea
 (DIR) parent 6d4e525ed95fbddc38be441394a02dc9233b157d
 (HTM) 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:
         M config.def.h                        |      14 ++++++++++++++
         M config.mk                           |       4 ++--
         M st.c                                |     186 +++++++++++++++++++------------
       
       3 files changed, 128 insertions(+), 76 deletions(-)
       ---
 (DIR) 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
       +
 (DIR) 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
 (DIR) 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;