Ver Fonte

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

Christoph Lohmann há 12 anos atrás
pai
commit
71b09ec4f1
3 ficheiros alterados com 128 adições e 76 exclusões
  1. 14 0
      config.def.h
  2. 2 2
      config.mk
  3. 112 74
      st.c

+ 14 - 0
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
+

+ 2 - 2
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

+ 112 - 74
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)
@@ -2694,6 +2724,14 @@ resize(XEvent *e) {
 	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
 run(void) {
 	XEvent ev;