diff --git a/config.def.h b/config.def.h index 2cd740a..ccf3ab8 100644 --- a/config.def.h +++ b/config.def.h @@ -73,6 +73,20 @@ static unsigned int cursorthickness = 2; */ static int bellvolume = 0; +/* visual bell duration (in milliseconds) */ +static unsigned int bellduration = 150; + +/* + * visual bell colors + * + * Formulas from normal colors to bell colors. + * Bell colors are clipped between 0x0000 and 0xffff. + */ +#define BELLR(color) (color.red * 0.9 + 0xffff * 0.1) +#define BELLG(color) (color.green * 0.9 + 0xffff * 0.1) +#define BELLB(color) (color.blue * 0.9 + 0xffff * 0.1) +#define BELLA(color) (color.alpha - 0x0500) + /* default TERM value */ char *termname = "st-256color"; diff --git a/x.c b/x.c index bd23686..30db597 100644 --- a/x.c +++ b/x.c @@ -135,6 +135,8 @@ typedef struct { /* Drawing Context */ typedef struct { Color *col; + Color *normalcol; + Color *bellcol; size_t collen; Font font, bfont, ifont, ibfont; GC gc; @@ -155,6 +157,8 @@ static void cresize(int, int); static void xresize(int, int); static void xhints(void); static int xloadcolor(int, const char *, Color *); +static void xnormalcols(void); +static void xbellcols(void); static int xloadfont(Font *, FcPattern *); static void xloadfonts(const char *, double); static void xunloadfont(Font *); @@ -220,6 +224,7 @@ static DC dc; static XWindow xw; static XSelection xsel; static TermWindow win; +struct timespec lastbell; /* Font Ring Cache */ enum { @@ -795,18 +800,33 @@ xloadcols(void) { int i; static int loaded; - Color *cp; if (loaded) { - for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp) - XftColorFree(xw.dpy, xw.vis, xw.cmap, cp); + for (i = 0; i < dc.collen; i++) { + XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.normalcol[i]); + XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.bellcol[i]); + } } else { dc.collen = MAX(LEN(colorname), 256); - dc.col = xmalloc(dc.collen * sizeof(Color)); + dc.normalcol = xmalloc(dc.collen * sizeof(Color)); + dc.bellcol = xmalloc(dc.collen * sizeof(Color)); + dc.col = dc.normalcol; } + xnormalcols(); + xbellcols(); + + loaded = 1; +} + +void +xnormalcols(void) +{ + int i; + static int loaded; + for (i = 0; i < dc.collen; i++) - if (!xloadcolor(i, NULL, &dc.col[i])) { + if (!xloadcolor(i, NULL, &dc.normalcol[i])) { if (colorname[i]) die("could not allocate color '%s'\n", colorname[i]); else @@ -815,6 +835,22 @@ xloadcols(void) loaded = 1; } +void +xbellcols(void) +{ + int i; + XRenderColor bc; + + for (i = 0; i < dc.collen; i++) { + bc.red = MAX(0, MIN(0xffff, BELLR(dc.normalcol[i].color))); + bc.green = MAX(0, MIN(0xffff, BELLG(dc.normalcol[i].color))); + bc.blue = MAX(0, MIN(0xffff, BELLB(dc.normalcol[i].color))); + bc.alpha = MAX(0, MIN(0xffff, BELLA(dc.normalcol[i].color))); + XftColorAllocValue(xw.dpy, xw.vis, + xw.cmap, &bc, &dc.bellcol[i]); + } +} + int xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b) { @@ -1766,6 +1802,10 @@ xbell(void) xseturgency(1); if (bellvolume) XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); + + clock_gettime(CLOCK_MONOTONIC, &lastbell); + dc.col = dc.bellcol; + redraw(); } void @@ -1925,7 +1965,7 @@ run(void) fd_set rfd; int xfd = XConnectionNumber(xw.dpy), ttyfd, xev, drawing; struct timespec seltv, *tv, now, lastblink, trigger; - double timeout; + double timeout, bellremain; /* Waiting for window mapping */ do { @@ -2014,6 +2054,17 @@ run(void) } } + /* bell */ + if (dc.col == dc.bellcol) { + bellremain = bellduration - TIMEDIFF(now, lastbell); + if (bellremain < 0) { + dc.col = dc.normalcol; + redraw(); + } else if (timeout < 0 || bellremain < timeout) { + timeout = bellremain; + } + } + draw(); XFlush(xw.dpy); drawing = 0;