aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Lohmann <20h@r-36.net>2012-10-28 13:25:53 +0100
committerChristoph Lohmann <20h@r-36.net>2012-10-28 13:25:53 +0100
commit53eda6d525899b661a961c97a9e9801ffb583cdb (patch)
treedcaf4aedf7d7b21afdf989de3a392b1b75e361ad
parent91804d72273e18ab9f4022f3dc1cc7d90eb3fea0 (diff)
downloadst-patched-53eda6d525899b661a961c97a9e9801ffb583cdb.tar.bz2
st-patched-53eda6d525899b661a961c97a9e9801ffb583cdb.tar.xz
st-patched-53eda6d525899b661a961c97a9e9801ffb583cdb.zip
Adding a more flexible fontstring handling, shortcuts and a zoom function.
-rw-r--r--config.def.h14
-rw-r--r--config.mk4
-rw-r--r--st.c186
3 files changed, 128 insertions, 76 deletions
diff --git a/config.def.h b/config.def.h
index 5c4c518..67b1316 100644
--- a/config.def.h
+++ b/config.def.h
@@ -1,4 +1,8 @@
1 1
2/*
3 * Do not include the »pixelsize« parameter in your font definition. It is
4 * used to calculate zooming.
5 */
2#define FONT "Liberation Mono:pixelsize=12:antialias=false:autohint=false" 6#define FONT "Liberation Mono:pixelsize=12:antialias=false:autohint=false"
3 7
4/* Space in pixels around the terminal buffer */ 8/* Space in pixels around the terminal buffer */
@@ -73,6 +77,15 @@ static Key key[] = {
73 { XK_F12, XK_NO_MOD, "\033[24~" }, 77 { XK_F12, XK_NO_MOD, "\033[24~" },
74}; 78};
75 79
80/* Internal shortcuts. */
81#define MODKEY Mod1Mask
82
83static Shortcut shortcuts[] = {
84 /* modifier key function argument */
85 { MODKEY|ShiftMask, XK_Prior, xzoom, {.i = +1} },
86 { MODKEY|ShiftMask, XK_Next, xzoom, {.i = -1} },
87};
88
76/* Set TERM to this */ 89/* Set TERM to this */
77#define TNAME "st-256color" 90#define TNAME "st-256color"
78 91
@@ -81,3 +94,4 @@ static Key key[] = {
81#define TRIPLECLICK_TIMEOUT (2*DOUBLECLICK_TIMEOUT) 94#define TRIPLECLICK_TIMEOUT (2*DOUBLECLICK_TIMEOUT)
82 95
83#define TAB 8 96#define TAB 8
97
diff --git a/config.mk b/config.mk
index 3cd714f..e45fc2d 100644
--- a/config.mk
+++ b/config.mk
@@ -16,8 +16,8 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext -lXft -lfontconfig
16 16
17# flags 17# flags
18CPPFLAGS = -DVERSION=\"${VERSION}\" 18CPPFLAGS = -DVERSION=\"${VERSION}\"
19CFLAGS += -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} 19CFLAGS += -g -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
20LDFLAGS += -s ${LIBS} 20LDFLAGS += -g ${LIBS}
21 21
22# compiler and linker 22# compiler and linker
23CC ?= cc 23CC ?= cc
diff --git a/st.c b/st.c
index f54e4d5..5703e96 100644
--- a/st.c
+++ b/st.c
@@ -60,6 +60,8 @@
60 60
61#define REDRAW_TIMEOUT (80*1000) /* 80 ms */ 61#define REDRAW_TIMEOUT (80*1000) /* 80 ms */
62 62
63/* macros */
64#define CLEANMASK(mask) (mask & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
63#define SERRNO strerror(errno) 65#define SERRNO strerror(errno)
64#define MIN(a, b) ((a) < (b) ? (a) : (b)) 66#define MIN(a, b) ((a) < (b) ? (a) : (b))
65#define MAX(a, b) ((a) < (b) ? (b) : (a)) 67#define MAX(a, b) ((a) < (b) ? (b) : (a))
@@ -238,6 +240,24 @@ typedef struct {
238 struct timeval tclick2; 240 struct timeval tclick2;
239} Selection; 241} Selection;
240 242
243typedef union {
244 int i;
245 unsigned int ui;
246 float f;
247 const void *v;
248} Arg;
249
250typedef struct {
251 unsigned int mod;
252 KeySym keysym;
253 void (*func)(const Arg *);
254 const Arg arg;
255} Shortcut;
256
257/* function definitions used in config.h */
258static void xzoom(const Arg *);
259
260/* Config.h for applying patches and the configuration. */
241#include "config.h" 261#include "config.h"
242 262
243/* Font structure */ 263/* Font structure */
@@ -321,6 +341,7 @@ static void unmap(XEvent *);
321static char *kmap(KeySym, uint); 341static char *kmap(KeySym, uint);
322static void kpress(XEvent *); 342static void kpress(XEvent *);
323static void cmessage(XEvent *); 343static void cmessage(XEvent *);
344static void cresize(int width, int height);
324static void resize(XEvent *); 345static void resize(XEvent *);
325static void focus(XEvent *); 346static void focus(XEvent *);
326static void brelease(XEvent *); 347static void brelease(XEvent *);
@@ -345,7 +366,6 @@ static ssize_t xwrite(int, char *, size_t);
345static void *xmalloc(size_t); 366static void *xmalloc(size_t);
346static void *xrealloc(void *, size_t); 367static void *xrealloc(void *, size_t);
347static void *xcalloc(size_t nmemb, size_t size); 368static void *xcalloc(size_t nmemb, size_t size);
348static char *smstrcat(char *, ...);
349 369
350static void (*handler[LASTEvent])(XEvent *) = { 370static void (*handler[LASTEvent])(XEvent *) = {
351 [KeyPress] = kpress, 371 [KeyPress] = kpress,
@@ -381,6 +401,8 @@ static char *opt_embed = NULL;
381static char *opt_class = NULL; 401static char *opt_class = NULL;
382static char *opt_font = NULL; 402static char *opt_font = NULL;
383 403
404static char *usedfont = NULL;
405static int usedfontsize = 0;
384 406
385ssize_t 407ssize_t
386xwrite(int fd, char *s, size_t len) { 408xwrite(int fd, char *s, size_t len) {
@@ -424,44 +446,6 @@ xcalloc(size_t nmemb, size_t size) {
424 return p; 446 return p;
425} 447}
426 448
427char *
428smstrcat(char *src, ...)
429{
430 va_list fmtargs;
431 char *ret, *p, *v;
432 int len, slen, flen;
433
434 len = slen = strlen(src);
435
436 va_start(fmtargs, src);
437 for(;;) {
438 v = va_arg(fmtargs, char *);
439 if(v == NULL)
440 break;
441 len += strlen(v);
442 }
443 va_end(fmtargs);
444
445 p = ret = xmalloc(len+1);
446 memmove(p, src, slen);
447 p += slen;
448
449 va_start(fmtargs, src);
450 for(;;) {
451 v = va_arg(fmtargs, char *);
452 if(v == NULL)
453 break;
454 flen = strlen(v);
455 memmove(p, v, flen);
456 p += flen;
457 }
458 va_end(fmtargs);
459
460 ret[len] = '\0';
461
462 return ret;
463}
464
465int 449int
466utf8decode(char *s, long *u) { 450utf8decode(char *s, long *u) {
467 uchar c; 451 uchar c;
@@ -2107,7 +2091,8 @@ tresize(int col, int row) {
2107 *bp = 1; 2091 *bp = 1;
2108 } 2092 }
2109 /* update terminal size */ 2093 /* update terminal size */
2110 term.col = col, term.row = row; 2094 term.col = col;
2095 term.row = row;
2111 /* make use of the LIMIT in tmoveto */ 2096 /* make use of the LIMIT in tmoveto */
2112 tmoveto(term.c.x, term.c.y); 2097 tmoveto(term.c.x, term.c.y);
2113 /* reset scrolling region */ 2098 /* reset scrolling region */
@@ -2207,22 +2192,17 @@ xhints(void) {
2207 XFree(sizeh); 2192 XFree(sizeh);
2208} 2193}
2209 2194
2210void 2195int
2211xinitfont(Font *f, char *fontstr) { 2196xloadfont(Font *f, FcPattern *pattern) {
2212 FcPattern *pattern, *match; 2197 FcPattern *match;
2213 FcResult result; 2198 FcResult result;
2214 2199
2215 pattern = FcNameParse((FcChar8 *)fontstr);
2216 if(!pattern)
2217 die("st: can't open font %s\n", fontstr);
2218
2219 match = XftFontMatch(xw.dpy, xw.scr, pattern, &result); 2200 match = XftFontMatch(xw.dpy, xw.scr, pattern, &result);
2220 FcPatternDestroy(pattern);
2221 if(!match) 2201 if(!match)
2222 die("st: can't open font %s\n", fontstr); 2202 return 1;
2223 if(!(f->xft_set = XftFontOpenPattern(xw.dpy, match))) { 2203 if(!(f->xft_set = XftFontOpenPattern(xw.dpy, match))) {
2224 FcPatternDestroy(match); 2204 FcPatternDestroy(match);
2225 die("st: can't open font %s.\n", fontstr); 2205 return 1;
2226 } 2206 }
2227 2207
2228 f->ascent = f->xft_set->ascent; 2208 f->ascent = f->xft_set->ascent;
@@ -2232,27 +2212,68 @@ xinitfont(Font *f, char *fontstr) {
2232 2212
2233 f->height = f->xft_set->height; 2213 f->height = f->xft_set->height;
2234 f->width = f->lbearing + f->rbearing; 2214 f->width = f->lbearing + f->rbearing;
2215
2216 return 0;
2235} 2217}
2236 2218
2237void 2219void
2238initfonts(char *fontstr) { 2220xloadfonts(char *fontstr, int fontsize) {
2239 char *fstr; 2221 FcPattern *pattern;
2222 FcResult result;
2223 double fontval;
2224
2225 pattern = FcNameParse((FcChar8 *)fontstr);
2226 if(!pattern)
2227 die("st: can't open font %s\n", fontstr);
2228
2229 if(fontsize > 0) {
2230 FcPatternDel(pattern, FC_PIXEL_SIZE);
2231 FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize);
2232 usedfontsize = fontsize;
2233 } else {
2234 result = FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval);
2235 if(result == FcResultMatch) {
2236 usedfontsize = (int)fontval;
2237 } else {
2238 /*
2239 * Default font size is 12, if none given. This is to
2240 * have a known usedfontsize value.
2241 */
2242 FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12);
2243 usedfontsize = 12;
2244 }
2245 }
2240 2246
2241 xinitfont(&dc.font, fontstr); 2247 if(xloadfont(&dc.font, pattern))
2248 die("st: can't open font %s\n", fontstr);
2249
2250 /* Setting character width and height. */
2242 xw.cw = dc.font.width; 2251 xw.cw = dc.font.width;
2243 xw.ch = dc.font.height; 2252 xw.ch = dc.font.height;
2244 2253
2245 fstr = smstrcat(fontstr, ":weight=bold", NULL); 2254 FcPatternDel(pattern, FC_WEIGHT);
2246 xinitfont(&dc.bfont, fstr); 2255 FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
2247 free(fstr); 2256 if(xloadfont(&dc.bfont, pattern))
2257 die("st: can't open font %s\n", fontstr);
2248 2258
2249 fstr = smstrcat(fontstr, ":slant=italic,oblique", NULL); 2259 FcPatternDel(pattern, FC_SLANT);
2250 xinitfont(&dc.ifont, fstr); 2260 FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
2251 free(fstr); 2261 if(xloadfont(&dc.ibfont, pattern))
2262 die("st: can't open font %s\n", fontstr);
2252 2263
2253 fstr = smstrcat(fontstr, ":weight=bold:slant=italic,oblique", NULL); 2264 FcPatternDel(pattern, FC_WEIGHT);
2254 xinitfont(&dc.ibfont, fstr); 2265 if(xloadfont(&dc.ifont, pattern))
2255 free(fstr); 2266 die("st: can't open font %s\n", fontstr);
2267
2268 FcPatternDestroy(pattern);
2269}
2270
2271void
2272xzoom(const Arg *arg)
2273{
2274 xloadfonts(usedfont, usedfontsize + arg->i);
2275 cresize(0, 0);
2276 draw();
2256} 2277}
2257 2278
2258void 2279void
@@ -2268,7 +2289,8 @@ xinit(void) {
2268 xw.vis = XDefaultVisual(xw.dpy, xw.scr); 2289 xw.vis = XDefaultVisual(xw.dpy, xw.scr);
2269 2290
2270 /* font */ 2291 /* font */
2271 initfonts((opt_font != NULL)? opt_font : FONT); 2292 usedfont = (opt_font == NULL)? FONT : opt_font;
2293 xloadfonts(usedfont, 0);
2272 2294
2273 /* colors */ 2295 /* colors */
2274 xw.cmap = XDefaultColormap(xw.dpy, xw.scr); 2296 xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
@@ -2604,11 +2626,8 @@ void
2604kpress(XEvent *ev) { 2626kpress(XEvent *ev) {
2605 XKeyEvent *e = &ev->xkey; 2627 XKeyEvent *e = &ev->xkey;
2606 KeySym ksym; 2628 KeySym ksym;
2607 char buf[32]; 2629 char buf[32], *customkey;
2608 char *customkey; 2630 int len, meta, shift, i;
2609 int len;
2610 int meta;
2611 int shift;
2612 Status status; 2631 Status status;
2613 2632
2614 if (IS_SET(MODE_KBDLOCK)) 2633 if (IS_SET(MODE_KBDLOCK))
@@ -2618,7 +2637,17 @@ kpress(XEvent *ev) {
2618 shift = e->state & ShiftMask; 2637 shift = e->state & ShiftMask;
2619 len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status); 2638 len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status);
2620 2639
2621 /* 1. custom keys from config.h */ 2640 /* 1. shortcuts */
2641 for(i = 0; i < LEN(shortcuts); i++) {
2642 if((ksym == shortcuts[i].keysym)
2643 && (CLEANMASK(shortcuts[i].mod) == \
2644 CLEANMASK(e->state))
2645 && shortcuts[i].func) {
2646 shortcuts[i].func(&(shortcuts[i].arg));
2647 }
2648 }
2649
2650 /* 2. custom keys from config.h */
2622 if((customkey = kmap(ksym, e->state))) { 2651 if((customkey = kmap(ksym, e->state))) {
2623 ttywrite(customkey, strlen(customkey)); 2652 ttywrite(customkey, strlen(customkey));
2624 /* 2. hardcoded (overrides X lookup) */ 2653 /* 2. hardcoded (overrides X lookup) */
@@ -2676,14 +2705,15 @@ cmessage(XEvent *e) {
2676} 2705}
2677 2706
2678void 2707void
2679resize(XEvent *e) { 2708cresize(int width, int height)
2709{
2680 int col, row; 2710 int col, row;
2681 2711
2682 if(e->xconfigure.width == xw.w && e->xconfigure.height == xw.h) 2712 if(width != 0)
2683 return; 2713 xw.w = width;
2714 if(height != 0)
2715 xw.h = height;
2684 2716
2685 xw.w = e->xconfigure.width;
2686 xw.h = e->xconfigure.height;
2687 col = (xw.w - 2*BORDER) / xw.cw; 2717 col = (xw.w - 2*BORDER) / xw.cw;
2688 row = (xw.h - 2*BORDER) / xw.ch; 2718 row = (xw.h - 2*BORDER) / xw.ch;
2689 if(col == term.col && row == term.row) 2719 if(col == term.col && row == term.row)
@@ -2695,6 +2725,14 @@ resize(XEvent *e) {
2695} 2725}
2696 2726
2697void 2727void
2728resize(XEvent *e) {
2729 if(e->xconfigure.width == xw.w && e->xconfigure.height == xw.h)
2730 return;
2731
2732 cresize(e->xconfigure.width, e->xconfigure.height);
2733}
2734
2735void
2698run(void) { 2736run(void) {
2699 XEvent ev; 2737 XEvent ev;
2700 fd_set rfd; 2738 fd_set rfd;