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

This commit is contained in:
Christoph Lohmann 2012-10-28 13:25:53 +01:00
parent 6d4e525ed9
commit 71b09ec4f1
3 changed files with 128 additions and 76 deletions

View file

@ -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" #define FONT "Liberation Mono:pixelsize=12:antialias=false:autohint=false"
/* Space in pixels around the terminal buffer */ /* Space in pixels around the terminal buffer */
@ -73,6 +77,15 @@ static Key key[] = {
{ XK_F12, XK_NO_MOD, "\033[24~" }, { 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 */ /* Set TERM to this */
#define TNAME "st-256color" #define TNAME "st-256color"
@ -81,3 +94,4 @@ static Key key[] = {
#define TRIPLECLICK_TIMEOUT (2*DOUBLECLICK_TIMEOUT) #define TRIPLECLICK_TIMEOUT (2*DOUBLECLICK_TIMEOUT)
#define TAB 8 #define TAB 8

View file

@ -16,8 +16,8 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext -lXft -lfontconfig
# flags # flags
CPPFLAGS = -DVERSION=\"${VERSION}\" CPPFLAGS = -DVERSION=\"${VERSION}\"
CFLAGS += -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} CFLAGS += -g -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
LDFLAGS += -s ${LIBS} LDFLAGS += -g ${LIBS}
# compiler and linker # compiler and linker
CC ?= cc CC ?= cc

186
st.c
View file

@ -60,6 +60,8 @@
#define REDRAW_TIMEOUT (80*1000) /* 80 ms */ #define REDRAW_TIMEOUT (80*1000) /* 80 ms */
/* macros */
#define CLEANMASK(mask) (mask & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
#define SERRNO strerror(errno) #define SERRNO strerror(errno)
#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) < (b) ? (b) : (a)) #define MAX(a, b) ((a) < (b) ? (b) : (a))
@ -238,6 +240,24 @@ typedef struct {
struct timeval tclick2; struct timeval tclick2;
} Selection; } 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" #include "config.h"
/* Font structure */ /* Font structure */
@ -321,6 +341,7 @@ static void unmap(XEvent *);
static char *kmap(KeySym, uint); static char *kmap(KeySym, uint);
static void kpress(XEvent *); static void kpress(XEvent *);
static void cmessage(XEvent *); static void cmessage(XEvent *);
static void cresize(int width, int height);
static void resize(XEvent *); static void resize(XEvent *);
static void focus(XEvent *); static void focus(XEvent *);
static void brelease(XEvent *); static void brelease(XEvent *);
@ -345,7 +366,6 @@ static ssize_t xwrite(int, char *, size_t);
static void *xmalloc(size_t); static void *xmalloc(size_t);
static void *xrealloc(void *, size_t); static void *xrealloc(void *, size_t);
static void *xcalloc(size_t nmemb, size_t size); static void *xcalloc(size_t nmemb, size_t size);
static char *smstrcat(char *, ...);
static void (*handler[LASTEvent])(XEvent *) = { static void (*handler[LASTEvent])(XEvent *) = {
[KeyPress] = kpress, [KeyPress] = kpress,
@ -381,6 +401,8 @@ static char *opt_embed = NULL;
static char *opt_class = NULL; static char *opt_class = NULL;
static char *opt_font = NULL; static char *opt_font = NULL;
static char *usedfont = NULL;
static int usedfontsize = 0;
ssize_t ssize_t
xwrite(int fd, char *s, size_t len) { xwrite(int fd, char *s, size_t len) {
@ -424,44 +446,6 @@ xcalloc(size_t nmemb, size_t size) {
return p; 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 int
utf8decode(char *s, long *u) { utf8decode(char *s, long *u) {
uchar c; uchar c;
@ -2107,7 +2091,8 @@ tresize(int col, int row) {
*bp = 1; *bp = 1;
} }
/* update terminal size */ /* update terminal size */
term.col = col, term.row = row; term.col = col;
term.row = row;
/* make use of the LIMIT in tmoveto */ /* make use of the LIMIT in tmoveto */
tmoveto(term.c.x, term.c.y); tmoveto(term.c.x, term.c.y);
/* reset scrolling region */ /* reset scrolling region */
@ -2207,22 +2192,17 @@ xhints(void) {
XFree(sizeh); XFree(sizeh);
} }
void int
xinitfont(Font *f, char *fontstr) { xloadfont(Font *f, FcPattern *pattern) {
FcPattern *pattern, *match; FcPattern *match;
FcResult result; 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); match = XftFontMatch(xw.dpy, xw.scr, pattern, &result);
FcPatternDestroy(pattern);
if(!match) if(!match)
die("st: can't open font %s\n", fontstr); return 1;
if(!(f->xft_set = XftFontOpenPattern(xw.dpy, match))) { if(!(f->xft_set = XftFontOpenPattern(xw.dpy, match))) {
FcPatternDestroy(match); FcPatternDestroy(match);
die("st: can't open font %s.\n", fontstr); return 1;
} }
f->ascent = f->xft_set->ascent; f->ascent = f->xft_set->ascent;
@ -2232,27 +2212,68 @@ xinitfont(Font *f, char *fontstr) {
f->height = f->xft_set->height; f->height = f->xft_set->height;
f->width = f->lbearing + f->rbearing; f->width = f->lbearing + f->rbearing;
return 0;
} }
void void
initfonts(char *fontstr) { xloadfonts(char *fontstr, int fontsize) {
char *fstr; FcPattern *pattern;
FcResult result;
double fontval;
xinitfont(&dc.font, fontstr); 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;
}
}
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.cw = dc.font.width;
xw.ch = dc.font.height; xw.ch = dc.font.height;
fstr = smstrcat(fontstr, ":weight=bold", NULL); FcPatternDel(pattern, FC_WEIGHT);
xinitfont(&dc.bfont, fstr); FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
free(fstr); if(xloadfont(&dc.bfont, pattern))
die("st: can't open font %s\n", fontstr);
fstr = smstrcat(fontstr, ":slant=italic,oblique", NULL); FcPatternDel(pattern, FC_SLANT);
xinitfont(&dc.ifont, fstr); FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
free(fstr); if(xloadfont(&dc.ibfont, pattern))
die("st: can't open font %s\n", fontstr);
fstr = smstrcat(fontstr, ":weight=bold:slant=italic,oblique", NULL); FcPatternDel(pattern, FC_WEIGHT);
xinitfont(&dc.ibfont, fstr); if(xloadfont(&dc.ifont, pattern))
free(fstr); 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 void
@ -2268,7 +2289,8 @@ xinit(void) {
xw.vis = XDefaultVisual(xw.dpy, xw.scr); xw.vis = XDefaultVisual(xw.dpy, xw.scr);
/* font */ /* font */
initfonts((opt_font != NULL)? opt_font : FONT); usedfont = (opt_font == NULL)? FONT : opt_font;
xloadfonts(usedfont, 0);
/* colors */ /* colors */
xw.cmap = XDefaultColormap(xw.dpy, xw.scr); xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
@ -2604,11 +2626,8 @@ void
kpress(XEvent *ev) { kpress(XEvent *ev) {
XKeyEvent *e = &ev->xkey; XKeyEvent *e = &ev->xkey;
KeySym ksym; KeySym ksym;
char buf[32]; char buf[32], *customkey;
char *customkey; int len, meta, shift, i;
int len;
int meta;
int shift;
Status status; Status status;
if (IS_SET(MODE_KBDLOCK)) if (IS_SET(MODE_KBDLOCK))
@ -2618,7 +2637,17 @@ kpress(XEvent *ev) {
shift = e->state & ShiftMask; shift = e->state & ShiftMask;
len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status); 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))) { if((customkey = kmap(ksym, e->state))) {
ttywrite(customkey, strlen(customkey)); ttywrite(customkey, strlen(customkey));
/* 2. hardcoded (overrides X lookup) */ /* 2. hardcoded (overrides X lookup) */
@ -2676,14 +2705,15 @@ cmessage(XEvent *e) {
} }
void void
resize(XEvent *e) { cresize(int width, int height)
{
int col, row; int col, row;
if(e->xconfigure.width == xw.w && e->xconfigure.height == xw.h) if(width != 0)
return; 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; col = (xw.w - 2*BORDER) / xw.cw;
row = (xw.h - 2*BORDER) / xw.ch; row = (xw.h - 2*BORDER) / xw.ch;
if(col == term.col && row == term.row) if(col == term.col && row == term.row)
@ -2694,6 +2724,14 @@ resize(XEvent *e) {
ttyresize(); ttyresize();
} }
void
resize(XEvent *e) {
if(e->xconfigure.width == xw.w && e->xconfigure.height == xw.h)
return;
cresize(e->xconfigure.width, e->xconfigure.height);
}
void void
run(void) { run(void) {
XEvent ev; XEvent ev;