mirror of git://git.suckless.org/st
Adding a more flexible fontstring handling, shortcuts and a zoom function.
This commit is contained in:
parent
6d4e525ed9
commit
71b09ec4f1
14
config.def.h
14
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"
|
#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
|
||||||
|
|
||||||
|
|
|
@ -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
186
st.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue