aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2020-05-30 16:12:43 +0200
committerMarvin Borner2020-05-30 16:12:43 +0200
commit96cde026875d0cb74274ff509a082c7131ba74ab (patch)
tree915f42e07cdb2fe90f5d46c294eb8ad612f55feb
parentfd7cd8ecce2f5cfa7530e3954c2a6669ec282a67 (diff)
Synced upstream of terminal
-rw-r--r--.repos/st/.Xdefaults124
-rw-r--r--.repos/st/.gitignore4
-rw-r--r--.repos/st/.travis.yml11
-rw-r--r--.repos/st/Makefile8
-rw-r--r--.repos/st/README.md4
-rw-r--r--.repos/st/boxdraw.c194
-rw-r--r--.repos/st/boxdraw_data.h214
-rw-r--r--.repos/st/config.h43
-rw-r--r--.repos/st/config.mk4
-rwxr-xr-x.repos/st/st-copyout1
-rwxr-xr-x.repos/st/st-urlhandler15
-rw-r--r--.repos/st/st.c22
-rw-r--r--.repos/st/st.h11
-rw-r--r--.repos/st/st.info4
-rw-r--r--.repos/st/win.h1
-rw-r--r--.repos/st/x.c154
16 files changed, 581 insertions, 233 deletions
diff --git a/.repos/st/.Xdefaults b/.repos/st/.Xdefaults
deleted file mode 100644
index 05b5e2e..0000000
--- a/.repos/st/.Xdefaults
+++ /dev/null
@@ -1,124 +0,0 @@
-!! Transparency (0-1):
-st.alpha: 0.92
-
-!! Set a default font and font size as below:
-st.font: Monospace-11;
-
-! st.termname: st-256color
-! st.borderpx: 2
-
-!! Set the background, foreground and cursor colors as below:
-*.background: #282828
-*.foreground: white
-*.cursorColor: white
-
-/* !! gruvbox: */
-/* *.color0: #1d2021 */
-/* *.color1: #cc241d */
-/* *.color2: #98971a */
-/* *.color3: #d79921 */
-/* *.color4: #458588 */
-/* *.color5: #b16286 */
-/* *.color6: #689d6a */
-/* *.color7: #a89984 */
-/* *.color8: #928374 */
-/* *.color9: #fb4934 */
-/* *.color10: #b8bb26 */
-/* *.color11: #fabd2f */
-/* *.color12: #83a598 */
-/* *.color13: #d3869b */
-/* *.color14: #8ec07c */
-/* *.color15: #ebdbb2 */
-
-/* !! gruvbox light: */
-/* *.color0: #fbf1c7 */
-/* *.color1: #cc241d */
-/* *.color2: #98971a */
-/* *.color3: #d79921 */
-/* *.color4: #458588 */
-/* *.color5: #b16286 */
-/* *.color6: #689d6a */
-/* *.color7: #7c6f64 */
-/* *.color8: #928374 */
-/* *.color9: #9d0006 */
-/* *.color10: #79740e */
-/* *.color11: #b57614 */
-/* *.color12: #076678 */
-/* *.color13: #8f3f71 */
-/* *.color14: #427b58 */
-/* *.color15: #3c3836 */
-
-/* !! brogrammer: */
-/* *.foreground: #d6dbe5 */
-/* *.background: #131313 */
-/* *.color0: #1f1f1f */
-/* *.color8: #d6dbe5 */
-/* *.color1: #f81118 */
-/* *.color9: #de352e */
-/* *.color2: #2dc55e */
-/* *.color10: #1dd361 */
-/* *.color3: #ecba0f */
-/* *.color11: #f3bd09 */
-/* *.color4: #2a84d2 */
-/* *.color12: #1081d6 */
-/* *.color5: #4e5ab7 */
-/* *.color13: #5350b9 */
-/* *.color6: #1081d6 */
-/* *.color14: #0f7ddb */
-/* *.color7: #d6dbe5 */
-/* *.color15: #ffffff */
-/* *.colorBD: #d6dbe5 */
-
-/* ! base16 */
-/* *.color0: #181818 */
-/* *.color1: #ab4642 */
-/* *.color2: #a1b56c */
-/* *.color3: #f7ca88 */
-/* *.color4: #7cafc2 */
-/* *.color5: #ba8baf */
-/* *.color6: #86c1b9 */
-/* *.color7: #d8d8d8 */
-/* *.color8: #585858 */
-/* *.color9: #ab4642 */
-/* *.color10: #a1b56c */
-/* *.color11: #f7ca88 */
-/* *.color12: #7cafc2 */
-/* *.color13: #ba8baf */
-/* *.color14: #86c1b9 */
-/* *.color15: #f8f8f8 */
-
-/* !! solarized */
-/* *.color0: #073642 */
-/* *.color1: #dc322f */
-/* *.color2: #859900 */
-/* *.color3: #b58900 */
-/* *.color4: #268bd2 */
-/* *.color5: #d33682 */
-/* *.color6: #2aa198 */
-/* *.color7: #eee8d5 */
-/* *.color9: #cb4b16 */
-/* *.color8: #fdf6e3 */
-/* *.color10: #586e75 */
-/* *.color11: #657b83 */
-/* *.color12: #839496 */
-/* *.color13: #6c71c4 */
-/* *.color14: #93a1a1 */
-/* *.color15: #fdf6e3 */
-
-/* !! xterm */
-/* *.color0: #000000 */
-/* *.color1: #cd0000 */
-/* *.color2: #00cd00 */
-/* *.color3: #cdcd00 */
-/* *.color4: #0000cd */
-/* *.color5: #cd00cd */
-/* *.color6: #00cdcd */
-/* *.color7: #e5e5e5 */
-/* *.color8: #4d4d4d */
-/* *.color9: #ff0000 */
-/* *.color10: #00ff00 */
-/* *.color11: #ffff00 */
-/* *.color12: #0000ff */
-/* *.color13: #ff00ff */
-/* *.color14: #00ffff */
-/* *.color15: #aabac8 */
diff --git a/.repos/st/.gitignore b/.repos/st/.gitignore
index 18c21b0..732bca7 100644
--- a/.repos/st/.gitignore
+++ b/.repos/st/.gitignore
@@ -1,5 +1,5 @@
st
-st.o
-x.o
+*.o
pkg/
*.pkg.tar.xz
+patches
diff --git a/.repos/st/.travis.yml b/.repos/st/.travis.yml
deleted file mode 100644
index dfc38d4..0000000
--- a/.repos/st/.travis.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-language: c
-compiler:
- - gcc
-script: make
-notifications:
- webhooks:
- urls:
- - https://webhooks.gitter.im/e/ec51097009f538278ab8
- on_success: change
- on_failure: always
-
diff --git a/.repos/st/Makefile b/.repos/st/Makefile
index a836907..2e05e4b 100644
--- a/.repos/st/Makefile
+++ b/.repos/st/Makefile
@@ -4,7 +4,7 @@
include config.mk
-SRC = st.c x.c
+SRC = st.c x.c boxdraw.c
OBJ = $(SRC:.c=.o)
all: options st
@@ -23,6 +23,7 @@ config.h:
st.o: config.h st.h win.h
x.o: arg.h config.h st.h win.h
+boxdraw.o: config.h st.h boxdraw_data.h
$(OBJ): config.h config.mk
@@ -30,7 +31,7 @@ st: $(OBJ)
$(CC) -o $@ $(OBJ) $(STLDFLAGS)
clean:
- rm -f st $(OBJ) st-$(VERSION).tar.gz
+ rm -f st $(OBJ) st-$(VERSION).tar.gz *.o *.orig *.rej
dist: clean
mkdir -p st-$(VERSION)
@@ -44,8 +45,10 @@ install: st
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f st $(DESTDIR)$(PREFIX)/bin
cp -f st-copyout $(DESTDIR)$(PREFIX)/bin
+ cp -f st-urlhandler $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/st
chmod 755 $(DESTDIR)$(PREFIX)/bin/st-copyout
+ chmod 755 $(DESTDIR)$(PREFIX)/bin/st-urlhandler
mkdir -p $(DESTDIR)$(MANPREFIX)/man1
sed "s/VERSION/$(VERSION)/g" < st.1 > $(DESTDIR)$(MANPREFIX)/man1/st.1
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1
@@ -55,6 +58,7 @@ install: st
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/st
rm -f $(DESTDIR)$(PREFIX)/bin/st-copyout
+ rm -f $(DESTDIR)$(PREFIX)/bin/st-urlhandler
rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1
.PHONY: all options clean dist install uninstall
diff --git a/.repos/st/README.md b/.repos/st/README.md
index 466c366..811f446 100644
--- a/.repos/st/README.md
+++ b/.repos/st/README.md
@@ -17,7 +17,7 @@ The [suckless terminal (st)](https://st.suckless.org/) with some additional feat
## Pretty stuff
-+ Compatibility with `Xresources` and `pywal` for dynamic colors. The `Xdefaults` file shows a usage example.
++ Compatibility with `Xresources` and `pywal` for dynamic colors.
+ Default [gruvbox](https://github.com/morhetz/gruvbox) colors otherwise.
+ Transparency/alpha, which is also adjustable from your `Xresources`.
+ Default font is system "mono" at 14pt, meaning the font will match your system font.
@@ -43,7 +43,7 @@ Obviously, `make` is required to build. `fontconfig` is required for the default
On OpenBSD, be sure to edit `config.mk` first and remove `-lrt` from the `$LIBS` before compiling.
-Be sure to have a composite manager (`xcompmgr`, `compton`, etc.) running if you want transparency.
+Be sure to have a composite manager (`xcompmgr`, `picom`, etc.) running if you want transparency.
## How to configure dynamically with Xresources
diff --git a/.repos/st/boxdraw.c b/.repos/st/boxdraw.c
new file mode 100644
index 0000000..28a92d0
--- /dev/null
+++ b/.repos/st/boxdraw.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih
+ * MIT/X Consortium License
+ */
+
+#include <X11/Xft/Xft.h>
+#include "st.h"
+#include "boxdraw_data.h"
+
+/* Rounded non-negative integers division of n / d */
+#define DIV(n, d) (((n) + (d) / 2) / (d))
+
+static Display *xdpy;
+static Colormap xcmap;
+static XftDraw *xd;
+static Visual *xvis;
+
+static void drawbox(int, int, int, int, XftColor *, XftColor *, ushort);
+static void drawboxlines(int, int, int, int, XftColor *, ushort);
+
+/* public API */
+
+void
+boxdraw_xinit(Display *dpy, Colormap cmap, XftDraw *draw, Visual *vis)
+{
+ xdpy = dpy; xcmap = cmap; xd = draw, xvis = vis;
+}
+
+int
+isboxdraw(Rune u)
+{
+ Rune block = u & ~0xff;
+ return (boxdraw && block == 0x2500 && boxdata[(uint8_t)u]) ||
+ (boxdraw_braille && block == 0x2800);
+}
+
+/* the "index" is actually the entire shape data encoded as ushort */
+ushort
+boxdrawindex(const Glyph *g)
+{
+ if (boxdraw_braille && (g->u & ~0xff) == 0x2800)
+ return BRL | (uint8_t)g->u;
+ if (boxdraw_bold && (g->mode & ATTR_BOLD))
+ return BDB | boxdata[(uint8_t)g->u];
+ return boxdata[(uint8_t)g->u];
+}
+
+void
+drawboxes(int x, int y, int cw, int ch, XftColor *fg, XftColor *bg,
+ const XftGlyphFontSpec *specs, int len)
+{
+ for ( ; len-- > 0; x += cw, specs++)
+ drawbox(x, y, cw, ch, fg, bg, (ushort)specs->glyph);
+}
+
+/* implementation */
+
+void
+drawbox(int x, int y, int w, int h, XftColor *fg, XftColor *bg, ushort bd)
+{
+ ushort cat = bd & ~(BDB | 0xff); /* mask out bold and data */
+ if (bd & (BDL | BDA)) {
+ /* lines (light/double/heavy/arcs) */
+ drawboxlines(x, y, w, h, fg, bd);
+
+ } else if (cat == BBD) {
+ /* lower (8-X)/8 block */
+ int d = DIV((uint8_t)bd * h, 8);
+ XftDrawRect(xd, fg, x, y + d, w, h - d);
+
+ } else if (cat == BBU) {
+ /* upper X/8 block */
+ XftDrawRect(xd, fg, x, y, w, DIV((uint8_t)bd * h, 8));
+
+ } else if (cat == BBL) {
+ /* left X/8 block */
+ XftDrawRect(xd, fg, x, y, DIV((uint8_t)bd * w, 8), h);
+
+ } else if (cat == BBR) {
+ /* right (8-X)/8 block */
+ int d = DIV((uint8_t)bd * w, 8);
+ XftDrawRect(xd, fg, x + d, y, w - d, h);
+
+ } else if (cat == BBQ) {
+ /* Quadrants */
+ int w2 = DIV(w, 2), h2 = DIV(h, 2);
+ if (bd & TL)
+ XftDrawRect(xd, fg, x, y, w2, h2);
+ if (bd & TR)
+ XftDrawRect(xd, fg, x + w2, y, w - w2, h2);
+ if (bd & BL)
+ XftDrawRect(xd, fg, x, y + h2, w2, h - h2);
+ if (bd & BR)
+ XftDrawRect(xd, fg, x + w2, y + h2, w - w2, h - h2);
+
+ } else if (bd & BBS) {
+ /* Shades - data is 1/2/3 for 25%/50%/75% alpha, respectively */
+ int d = (uint8_t)bd;
+ XftColor xfc;
+ XRenderColor xrc = { .alpha = 0xffff };
+
+ xrc.red = DIV(fg->color.red * d + bg->color.red * (4 - d), 4);
+ xrc.green = DIV(fg->color.green * d + bg->color.green * (4 - d), 4);
+ xrc.blue = DIV(fg->color.blue * d + bg->color.blue * (4 - d), 4);
+
+ XftColorAllocValue(xdpy, xvis, xcmap, &xrc, &xfc);
+ XftDrawRect(xd, &xfc, x, y, w, h);
+ XftColorFree(xdpy, xvis, xcmap, &xfc);
+
+ } else if (cat == BRL) {
+ /* braille, each data bit corresponds to one dot at 2x4 grid */
+ int w1 = DIV(w, 2);
+ int h1 = DIV(h, 4), h2 = DIV(h, 2), h3 = DIV(3 * h, 4);
+
+ if (bd & 1) XftDrawRect(xd, fg, x, y, w1, h1);
+ if (bd & 2) XftDrawRect(xd, fg, x, y + h1, w1, h2 - h1);
+ if (bd & 4) XftDrawRect(xd, fg, x, y + h2, w1, h3 - h2);
+ if (bd & 8) XftDrawRect(xd, fg, x + w1, y, w - w1, h1);
+ if (bd & 16) XftDrawRect(xd, fg, x + w1, y + h1, w - w1, h2 - h1);
+ if (bd & 32) XftDrawRect(xd, fg, x + w1, y + h2, w - w1, h3 - h2);
+ if (bd & 64) XftDrawRect(xd, fg, x, y + h3, w1, h - h3);
+ if (bd & 128) XftDrawRect(xd, fg, x + w1, y + h3, w - w1, h - h3);
+
+ }
+}
+
+void
+drawboxlines(int x, int y, int w, int h, XftColor *fg, ushort bd)
+{
+ /* s: stem thickness. width/8 roughly matches underscore thickness. */
+ /* We draw bold as 1.5 * normal-stem and at least 1px thicker. */
+ /* doubles draw at least 3px, even when w or h < 3. bold needs 6px. */
+ int mwh = MIN(w, h);
+ int base_s = MAX(1, DIV(mwh, 8));
+ int bold = (bd & BDB) && mwh >= 6; /* possibly ignore boldness */
+ int s = bold ? MAX(base_s + 1, DIV(3 * base_s, 2)) : base_s;
+ int w2 = DIV(w - s, 2), h2 = DIV(h - s, 2);
+ /* the s-by-s square (x + w2, y + h2, s, s) is the center texel. */
+ /* The base length (per direction till edge) includes this square. */
+
+ int light = bd & (LL | LU | LR | LD);
+ int double_ = bd & (DL | DU | DR | DD);
+
+ if (light) {
+ /* d: additional (negative) length to not-draw the center */
+ /* texel - at arcs and avoid drawing inside (some) doubles */
+ int arc = bd & BDA;
+ int multi_light = light & (light - 1);
+ int multi_double = double_ & (double_ - 1);
+ /* light crosses double only at DH+LV, DV+LH (ref. shapes) */
+ int d = arc || (multi_double && !multi_light) ? -s : 0;
+
+ if (bd & LL)
+ XftDrawRect(xd, fg, x, y + h2, w2 + s + d, s);
+ if (bd & LU)
+ XftDrawRect(xd, fg, x + w2, y, s, h2 + s + d);
+ if (bd & LR)
+ XftDrawRect(xd, fg, x + w2 - d, y + h2, w - w2 + d, s);
+ if (bd & LD)
+ XftDrawRect(xd, fg, x + w2, y + h2 - d, s, h - h2 + d);
+ }
+
+ /* double lines - also align with light to form heavy when combined */
+ if (double_) {
+ /*
+ * going clockwise, for each double-ray: p is additional length
+ * to the single-ray nearer to the previous direction, and n to
+ * the next. p and n adjust from the base length to lengths
+ * which consider other doubles - shorter to avoid intersections
+ * (p, n), or longer to draw the far-corner texel (n).
+ */
+ int dl = bd & DL, du = bd & DU, dr = bd & DR, dd = bd & DD;
+ if (dl) {
+ int p = dd ? -s : 0, n = du ? -s : dd ? s : 0;
+ XftDrawRect(xd, fg, x, y + h2 + s, w2 + s + p, s);
+ XftDrawRect(xd, fg, x, y + h2 - s, w2 + s + n, s);
+ }
+ if (du) {
+ int p = dl ? -s : 0, n = dr ? -s : dl ? s : 0;
+ XftDrawRect(xd, fg, x + w2 - s, y, s, h2 + s + p);
+ XftDrawRect(xd, fg, x + w2 + s, y, s, h2 + s + n);
+ }
+ if (dr) {
+ int p = du ? -s : 0, n = dd ? -s : du ? s : 0;
+ XftDrawRect(xd, fg, x + w2 - p, y + h2 - s, w - w2 + p, s);
+ XftDrawRect(xd, fg, x + w2 - n, y + h2 + s, w - w2 + n, s);
+ }
+ if (dd) {
+ int p = dr ? -s : 0, n = dl ? -s : dr ? s : 0;
+ XftDrawRect(xd, fg, x + w2 + s, y + h2 - p, s, h - h2 + p);
+ XftDrawRect(xd, fg, x + w2 - s, y + h2 - n, s, h - h2 + n);
+ }
+ }
+}
diff --git a/.repos/st/boxdraw_data.h b/.repos/st/boxdraw_data.h
new file mode 100644
index 0000000..7890500
--- /dev/null
+++ b/.repos/st/boxdraw_data.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih
+ * MIT/X Consortium License
+ */
+
+/*
+ * U+25XX codepoints data
+ *
+ * References:
+ * http://www.unicode.org/charts/PDF/U2500.pdf
+ * http://www.unicode.org/charts/PDF/U2580.pdf
+ *
+ * Test page:
+ * https://github.com/GNOME/vte/blob/master/doc/boxes.txt
+ */
+
+/* Each shape is encoded as 16-bits. Higher bits are category, lower are data */
+/* Categories (mutually exclusive except BDB): */
+/* For convenience, BDL/BDA/BBS/BDB are 1 bit each, the rest are enums */
+#define BDL (1<<8) /* Box Draw Lines (light/double/heavy) */
+#define BDA (1<<9) /* Box Draw Arc (light) */
+
+#define BBD (1<<10) /* Box Block Down (lower) X/8 */
+#define BBL (2<<10) /* Box Block Left X/8 */
+#define BBU (3<<10) /* Box Block Upper X/8 */
+#define BBR (4<<10) /* Box Block Right X/8 */
+#define BBQ (5<<10) /* Box Block Quadrants */
+#define BRL (6<<10) /* Box Braille (data is lower byte of U28XX) */
+
+#define BBS (1<<14) /* Box Block Shades */
+#define BDB (1<<15) /* Box Draw is Bold */
+
+/* (BDL/BDA) Light/Double/Heavy x Left/Up/Right/Down/Horizontal/Vertical */
+/* Heavy is light+double (literally drawing light+double align to form heavy) */
+#define LL (1<<0)
+#define LU (1<<1)
+#define LR (1<<2)
+#define LD (1<<3)
+#define LH (LL+LR)
+#define LV (LU+LD)
+
+#define DL (1<<4)
+#define DU (1<<5)
+#define DR (1<<6)
+#define DD (1<<7)
+#define DH (DL+DR)
+#define DV (DU+DD)
+
+#define HL (LL+DL)
+#define HU (LU+DU)
+#define HR (LR+DR)
+#define HD (LD+DD)
+#define HH (HL+HR)
+#define HV (HU+HD)
+
+/* (BBQ) Quadrants Top/Bottom x Left/Right */
+#define TL (1<<0)
+#define TR (1<<1)
+#define BL (1<<2)
+#define BR (1<<3)
+
+/* Data for U+2500 - U+259F except dashes/diagonals */
+static const unsigned short boxdata[256] = {
+ /* light lines */
+ [0x00] = BDL + LH, /* light horizontal */
+ [0x02] = BDL + LV, /* light vertical */
+ [0x0c] = BDL + LD + LR, /* light down and right */
+ [0x10] = BDL + LD + LL, /* light down and left */
+ [0x14] = BDL + LU + LR, /* light up and right */
+ [0x18] = BDL + LU + LL, /* light up and left */
+ [0x1c] = BDL + LV + LR, /* light vertical and right */
+ [0x24] = BDL + LV + LL, /* light vertical and left */
+ [0x2c] = BDL + LH + LD, /* light horizontal and down */
+ [0x34] = BDL + LH + LU, /* light horizontal and up */
+ [0x3c] = BDL + LV + LH, /* light vertical and horizontal */
+ [0x74] = BDL + LL, /* light left */
+ [0x75] = BDL + LU, /* light up */
+ [0x76] = BDL + LR, /* light right */
+ [0x77] = BDL + LD, /* light down */
+
+ /* heavy [+light] lines */
+ [0x01] = BDL + HH,
+ [0x03] = BDL + HV,
+ [0x0d] = BDL + HR + LD,
+ [0x0e] = BDL + HD + LR,
+ [0x0f] = BDL + HD + HR,
+ [0x11] = BDL + HL + LD,
+ [0x12] = BDL + HD + LL,
+ [0x13] = BDL + HD + HL,
+ [0x15] = BDL + HR + LU,
+ [0x16] = BDL + HU + LR,
+ [0x17] = BDL + HU + HR,
+ [0x19] = BDL + HL + LU,
+ [0x1a] = BDL + HU + LL,
+ [0x1b] = BDL + HU + HL,
+ [0x1d] = BDL + HR + LV,
+ [0x1e] = BDL + HU + LD + LR,
+ [0x1f] = BDL + HD + LR + LU,
+ [0x20] = BDL + HV + LR,
+ [0x21] = BDL + HU + HR + LD,
+ [0x22] = BDL + HD + HR + LU,
+ [0x23] = BDL + HV + HR,
+ [0x25] = BDL + HL + LV,
+ [0x26] = BDL + HU + LD + LL,
+ [0x27] = BDL + HD + LU + LL,
+ [0x28] = BDL + HV + LL,
+ [0x29] = BDL + HU + HL + LD,
+ [0x2a] = BDL + HD + HL + LU,
+ [0x2b] = BDL + HV + HL,
+ [0x2d] = BDL + HL + LD + LR,
+ [0x2e] = BDL + HR + LL + LD,
+ [0x2f] = BDL + HH + LD,
+ [0x30] = BDL + HD + LH,
+ [0x31] = BDL + HD + HL + LR,
+ [0x32] = BDL + HR + HD + LL,
+ [0x33] = BDL + HH + HD,
+ [0x35] = BDL + HL + LU + LR,
+ [0x36] = BDL + HR + LU + LL,
+ [0x37] = BDL + HH + LU,
+ [0x38] = BDL + HU + LH,
+ [0x39] = BDL + HU + HL + LR,
+ [0x3a] = BDL + HU + HR + LL,
+ [0x3b] = BDL + HH + HU,
+ [0x3d] = BDL + HL + LV + LR,
+ [0x3e] = BDL + HR + LV + LL,
+ [0x3f] = BDL + HH + LV,
+ [0x40] = BDL + HU + LH + LD,
+ [0x41] = BDL + HD + LH + LU,
+ [0x42] = BDL + HV + LH,
+ [0x43] = BDL + HU + HL + LD + LR,
+ [0x44] = BDL + HU + HR + LD + LL,
+ [0x45] = BDL + HD + HL + LU + LR,
+ [0x46] = BDL + HD + HR + LU + LL,
+ [0x47] = BDL + HH + HU + LD,
+ [0x48] = BDL + HH + HD + LU,
+ [0x49] = BDL + HV + HL + LR,
+ [0x4a] = BDL + HV + HR + LL,
+ [0x4b] = BDL + HV + HH,
+ [0x78] = BDL + HL,
+ [0x79] = BDL + HU,
+ [0x7a] = BDL + HR,
+ [0x7b] = BDL + HD,
+ [0x7c] = BDL + HR + LL,
+ [0x7d] = BDL + HD + LU,
+ [0x7e] = BDL + HL + LR,
+ [0x7f] = BDL + HU + LD,
+
+ /* double [+light] lines */
+ [0x50] = BDL + DH,
+ [0x51] = BDL + DV,
+ [0x52] = BDL + DR + LD,
+ [0x53] = BDL + DD + LR,
+ [0x54] = BDL + DR + DD,
+ [0x55] = BDL + DL + LD,
+ [0x56] = BDL + DD + LL,
+ [0x57] = BDL + DL + DD,
+ [0x58] = BDL + DR + LU,
+ [0x59] = BDL + DU + LR,
+ [0x5a] = BDL + DU + DR,
+ [0x5b] = BDL + DL + LU,
+ [0x5c] = BDL + DU + LL,
+ [0x5d] = BDL + DL + DU,
+ [0x5e] = BDL + DR + LV,
+ [0x5f] = BDL + DV + LR,
+ [0x60] = BDL + DV + DR,
+ [0x61] = BDL + DL + LV,
+ [0x62] = BDL + DV + LL,
+ [0x63] = BDL + DV + DL,
+ [0x64] = BDL + DH + LD,
+ [0x65] = BDL + DD + LH,
+ [0x66] = BDL + DD + DH,
+ [0x67] = BDL + DH + LU,
+ [0x68] = BDL + DU + LH,
+ [0x69] = BDL + DH + DU,
+ [0x6a] = BDL + DH + LV,
+ [0x6b] = BDL + DV + LH,
+ [0x6c] = BDL + DH + DV,
+
+ /* (light) arcs */
+ [0x6d] = BDA + LD + LR,
+ [0x6e] = BDA + LD + LL,
+ [0x6f] = BDA + LU + LL,
+ [0x70] = BDA + LU + LR,
+
+ /* Lower (Down) X/8 block (data is 8 - X) */
+ [0x81] = BBD + 7, [0x82] = BBD + 6, [0x83] = BBD + 5, [0x84] = BBD + 4,
+ [0x85] = BBD + 3, [0x86] = BBD + 2, [0x87] = BBD + 1, [0x88] = BBD + 0,
+
+ /* Left X/8 block (data is X) */
+ [0x89] = BBL + 7, [0x8a] = BBL + 6, [0x8b] = BBL + 5, [0x8c] = BBL + 4,
+ [0x8d] = BBL + 3, [0x8e] = BBL + 2, [0x8f] = BBL + 1,
+
+ /* upper 1/2 (4/8), 1/8 block (X), right 1/2, 1/8 block (8-X) */
+ [0x80] = BBU + 4, [0x94] = BBU + 1,
+ [0x90] = BBR + 4, [0x95] = BBR + 7,
+
+ /* Quadrants */
+ [0x96] = BBQ + BL,
+ [0x97] = BBQ + BR,
+ [0x98] = BBQ + TL,
+ [0x99] = BBQ + TL + BL + BR,
+ [0x9a] = BBQ + TL + BR,
+ [0x9b] = BBQ + TL + TR + BL,
+ [0x9c] = BBQ + TL + TR + BR,
+ [0x9d] = BBQ + TR,
+ [0x9e] = BBQ + BL + TR,
+ [0x9f] = BBQ + BL + TR + BR,
+
+ /* Shades, data is an alpha value in 25% units (1/4, 1/2, 3/4) */
+ [0x91] = BBS + 1, [0x92] = BBS + 2, [0x93] = BBS + 3,
+
+ /* U+2504 - U+250B, U+254C - U+254F: unsupported (dashes) */
+ /* U+2571 - U+2573: unsupported (diagonals) */
+};
diff --git a/.repos/st/config.h b/.repos/st/config.h
index bb36f5c..b4283bd 100644
--- a/.repos/st/config.h
+++ b/.repos/st/config.h
@@ -42,9 +42,14 @@ static unsigned int tripleclicktimeout = 600;
/* alt screens */
int allowaltscreen = 1;
-/* frames per second st should at maximum draw to the screen */
-static unsigned int xfps = 120;
-static unsigned int actionfps = 30;
+/*
+ * draw latency range in ms - from new content/keypress/etc until drawing.
+ * within this range, st draws when content stops arriving (idle). mostly it's
+ * near minlatency, but it waits longer for slow updates to avoid partial draw.
+ * low minlatency will tear/flicker more, as it can "detect" idle too early.
+ */
+static double minlatency = 8;
+static double maxlatency = 33;
/*
* blinking timeout (set to 0 to disable blinking) for the terminal blinking
@@ -65,6 +70,18 @@ int ximspot_update_interval = 1000;
static unsigned int cursorthickness = 2;
/*
+ * 1: render most of the lines/blocks characters without using the font for
+ * perfect alignment between cells (U2500 - U259F except dashes/diagonals).
+ * Bold affects lines thickness if boxdraw_bold is not 0. Italic is ignored.
+ * 0: disable (render all U25XX glyphs normally from the font).
+ */
+const int boxdraw = 1;
+const int boxdraw_bold = 1;
+
+/* braille (U28XX): 1: render as adjacent "pixels", 0: use font */
+const int boxdraw_braille = 1;
+
+/*
* bell volume. It must be a value between -100 and 100. Use 0 for disabling
* it
*/
@@ -91,7 +108,7 @@ char *termname = "st-256color";
unsigned int tabspaces = 8;
/* bg opacity */
-float alpha = 0.92;
+float alpha = 0.8;
/* Terminal colors (16 first used in escape sequence) */
static const char *colorname[] = {
@@ -119,15 +136,14 @@ static const char *colorname[] = {
"#eaeaea", /* 259 -> fg */
};
-
/*
* Default colors (colorname index)
* foreground, background, cursor, reverse cursor
*/
unsigned int defaultfg = 259;
unsigned int defaultbg = 258;
-static unsigned int defaultcs = 256;
-static unsigned int defaultrcs = 257;
+unsigned int defaultcs = 256;
+unsigned int defaultrcs = 257;
/*
* Default shape of cursor
@@ -185,8 +201,6 @@ ResourcePref resources[] = {
{ "cursorColor", STRING, &colorname[256] },
{ "termname", STRING, &termname },
{ "shell", STRING, &shell },
- { "xfps", INTEGER, &xfps },
- { "actionfps", INTEGER, &actionfps },
{ "blinktimeout", INTEGER, &blinktimeout },
{ "bellvolume", INTEGER, &bellvolume },
{ "tabspaces", INTEGER, &tabspaces },
@@ -221,12 +235,10 @@ MouseKey mkeys[] = {
{ Button5, TERMMOD, zoom, {.f = -1} },
};
-static char *openurlcmd[] = { "/bin/sh", "-c",
- "sed 's/.*│//g' | tr -d '\n' | grep -aEo '(((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./&%?$#=_-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)'| uniq | sed 's/^www./http:\\/\\/www\\./g' | dmenu -i -p 'Follow which url?' -l 10 | xargs -r xdg-open",
- "externalpipe", NULL };
+static char *openurlcmd[] = { "/bin/sh", "-c", "st-urlhandler", "externalpipe", NULL };
static char *copyurlcmd[] = { "/bin/sh", "-c",
- "sed 's/.*│//g' | tr -d '\n' | grep -aEo '(((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./&%?$#=_-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)' | uniq | sed 's/^www./http:\\/\\/www\\./g' | dmenu -i -p 'Copy which url?' -l 10 | tr -d '\n' | xclip -selection clipboard",
+ "tmp=$(sed 's/.*│//g' | tr -d '\n' | grep -aEo '(((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./@$&%?$#=_-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)' | uniq | sed 's/^www./http:\\/\\/www\\./g' ); IFS=; [ ! -z $tmp ] && echo $tmp | dmenu -i -p 'Copy which url?' -l 10 | tr -d '\n' | xclip -selection clipboard",
"externalpipe", NULL };
static char *copyoutput[] = { "/bin/sh", "-c", "st-copyout", "externalpipe", NULL };
@@ -240,10 +252,9 @@ static Shortcut shortcuts[] = {
{ TERMMOD, XK_Prior, zoom, {.f = +1} },
{ TERMMOD, XK_Next, zoom, {.f = -1} },
{ MODKEY, XK_Home, zoomreset, {.f = 0} },
+ { MODKEY, XK_c, clipcopy, {.i = 0} },
{ ShiftMask, XK_Insert, clippaste, {.i = 0} },
- { MODKEY, XK_c, clipcopy, {.i = 0} },
- { MODKEY, XK_v, clippaste, {.i = 0} },
- { MODKEY, XK_p, selpaste, {.i = 0} },
+ { MODKEY, XK_v, clippaste, {.i = 0} },
{ XK_ANY_MOD, Button2, selpaste, {.i = 0} },
{ MODKEY, XK_Num_Lock, numlock, {.i = 0} },
{ MODKEY, XK_Control_L, iso14755, {.i = 0} },
diff --git a/.repos/st/config.mk b/.repos/st/config.mk
index eba98c3..1635264 100644
--- a/.repos/st/config.mk
+++ b/.repos/st/config.mk
@@ -10,6 +10,10 @@ MANPREFIX = $(PREFIX)/share/man
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
+# include X11 in Ubuntu
+# X11INC = /usr/include/X11R6
+# X11LIB = /usr/lib/X11R6
+
PKG_CONFIG = pkg-config
# includes and libs
diff --git a/.repos/st/st-copyout b/.repos/st/st-copyout
index 8eafc58..0d19e5a 100755
--- a/.repos/st/st-copyout
+++ b/.repos/st/st-copyout
@@ -6,6 +6,7 @@
tmpfile=$(mktemp /tmp/st-cmd-output.XXXXXX)
trap 'rm "$tmpfile"' 0 1 15
sed -n "w $tmpfile"
+sed -i 's/\x0//g' "$tmpfile"
ps1="$(grep "\S" "$tmpfile" | tail -n 1 | sed 's/^\s*//' | cut -d' ' -f1)"
chosen="$(grep -F "$ps1" "$tmpfile" | sed '$ d' | tac | dmenu -p "Copy which command's output?" -i -l 10 | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
eps1="$(echo "$ps1" | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
diff --git a/.repos/st/st-urlhandler b/.repos/st/st-urlhandler
new file mode 100755
index 0000000..d44bb99
--- /dev/null
+++ b/.repos/st/st-urlhandler
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+urlregex="(((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./@$&%?$#=_-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)"
+
+# First remove linebreaks and mutt sidebars:
+urls="$(sed 's/.*│//g' | tr -d '\n' |
+ grep -aEo "$urlregex" | # grep only urls as defined above.
+ uniq | # Ignore neighboring duplicates.
+ sed 's/^www./http:\/\/www\./g')"
+
+[ -z "$urls" ] && exit
+
+chosen="$(echo "$urls" | dmenu -i -p 'Follow which url?' -l 10)"
+
+setsid xdg-open "$chosen" >/dev/null 2>&1 &
diff --git a/.repos/st/st.c b/.repos/st/st.c
index e4df60c..0e5e3f5 100644
--- a/.repos/st/st.c
+++ b/.repos/st/st.c
@@ -1295,6 +1295,9 @@ tsetchar(Rune u, Glyph *attr, int x, int y)
term.dirty[y] = 1;
term.line[y][x] = *attr;
term.line[y][x].u = u;
+
+ if (isboxdraw(u))
+ term.line[y][x].mode |= ATTR_BOXDRAW;
}
void
@@ -1940,12 +1943,23 @@ strhandle(void)
}
return;
case 4: /* color set */
- if (narg < 3)
+ case 10: /* foreground set */
+ case 11: /* background set */
+ case 12: /* cursor color */
+ if ((par == 4 && narg < 3) || narg < 2)
break;
- p = strescseq.args[2];
+ p = strescseq.args[((par == 4) ? 2 : 1)];
/* FALLTHROUGH */
case 104: /* color reset, here p = NULL */
- j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
+ if (par == 10)
+ j = defaultfg;
+ else if (par == 11)
+ j = defaultbg;
+ else if (par == 12)
+ j = defaultcs;
+ else
+ j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
+
if (xsetcolorname(j, p)) {
if (par == 104 && narg <= 1)
return; /* color reset without parameter */
@@ -1956,6 +1970,8 @@ strhandle(void)
* TODO if defaultbg color is changed, borders
* are dirty
*/
+ if (j == defaultbg)
+ xclearwin();
redraw();
}
return;
diff --git a/.repos/st/st.h b/.repos/st/st.h
index 4504a30..33cc5d4 100644
--- a/.repos/st/st.h
+++ b/.repos/st/st.h
@@ -33,6 +33,7 @@ enum glyph_attribute {
ATTR_WRAP = 1 << 8,
ATTR_WIDE = 1 << 9,
ATTR_WDUMMY = 1 << 10,
+ ATTR_BOXDRAW = 1 << 11,
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
};
@@ -121,6 +122,14 @@ void *xmalloc(size_t);
void *xrealloc(void *, size_t);
char *xstrdup(char *);
+int isboxdraw(Rune);
+ushort boxdrawindex(const Glyph *);
+#ifdef XFT_VERSION
+/* only exposed to x.c, otherwise we'll need Xft.h for the types */
+void boxdraw_xinit(Display *, Colormap, XftDraw *, Visual *);
+void drawboxes(int, int, int, int, XftColor *, XftColor *, const XftGlyphFontSpec *, int);
+#endif
+
/* config.h globals */
extern char *utmp;
extern char *stty_args;
@@ -131,6 +140,8 @@ extern char *termname;
extern unsigned int tabspaces;
extern unsigned int defaultfg;
extern unsigned int defaultbg;
+extern unsigned int defaultcs;
+extern const int boxdraw, boxdraw_bold, boxdraw_braille;
extern float alpha;
extern MouseKey mkeys[];
extern int ximspot_update_interval;
diff --git a/.repos/st/st.info b/.repos/st/st.info
index 52fc617..78ffd30 100644
--- a/.repos/st/st.info
+++ b/.repos/st/st.info
@@ -189,10 +189,10 @@ st| simpleterm,
rmxx=\E[29m,
smxx=\E[9m,
# tmux extensions, see TERMINFO EXTENSIONS in tmux(1)
- Se,
- Ss,
Tc,
Ms=\E]52;%p1%s;%p2%s\007,
+ Se=\E[2 q,
+ Ss=\E[%p1%d q,
st-256color| simpleterm with 256 colors,
use=st,
diff --git a/.repos/st/win.h b/.repos/st/win.h
index a6ef1b9..d7b4980 100644
--- a/.repos/st/win.h
+++ b/.repos/st/win.h
@@ -37,3 +37,4 @@ void xsetpointermotion(int);
void xsetsel(char *);
int xstartdraw(void);
void xximspot(int, int);
+void xclearwin(void);
diff --git a/.repos/st/x.c b/.repos/st/x.c
index c09392b..55f4a61 100644
--- a/.repos/st/x.c
+++ b/.repos/st/x.c
@@ -661,8 +661,6 @@ setsel(char *str, Time t)
XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
selclear();
-
- clipcopy(NULL);
}
void
@@ -680,7 +678,7 @@ brelease(XEvent *e)
}
if (e->xbutton.button == Button2)
- clippaste(NULL);
+ selpaste(NULL);
else if (e->xbutton.button == Button1)
mousesel(e, 1);
}
@@ -816,6 +814,8 @@ xsetcolorname(int x, const char *name)
XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]);
dc.col[x] = ncolor;
+ if (x == defaultbg)
+ dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha);
return 0;
}
@@ -832,6 +832,13 @@ xclear(int x1, int y1, int x2, int y2)
}
void
+xclearwin(void)
+{
+ xclear(0, 0, win.w, win.h);
+}
+
+
+void
xhints(void)
{
XClassHint class = {opt_name ? opt_name : "st",
@@ -1296,6 +1303,8 @@ xinit(int cols, int rows)
xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0);
if (xsel.xtarget == None)
xsel.xtarget = XA_STRING;
+
+ boxdraw_xinit(xw.dpy, xw.cmap, xw.draw, xw.vis);
}
int
@@ -1342,8 +1351,13 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
yp = winy + font->ascent + win.cyo;
}
- /* Lookup character index with default font. */
- glyphidx = XftCharIndex(xw.dpy, font->match, rune);
+ if (mode & ATTR_BOXDRAW) {
+ /* minor shoehorning: boxdraw uses only this ushort */
+ glyphidx = boxdrawindex(&glyphs[i]);
+ } else {
+ /* Lookup character index with default font. */
+ glyphidx = XftCharIndex(xw.dpy, font->match, rune);
+ }
if (glyphidx) {
specs[numspecs].font = font->match;
specs[numspecs].glyph = glyphidx;
@@ -1543,8 +1557,12 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
r.width = width;
XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
- /* Render the glyphs. */
- XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
+ if (base.mode & ATTR_BOXDRAW) {
+ drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len);
+ } else {
+ /* Render the glyphs. */
+ XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
+ }
/* Render underline and strikethrough. */
if (base.mode & ATTR_UNDERLINE) {
@@ -1587,7 +1605,7 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
/*
* Select the right color for the right mode.
*/
- g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE;
+ g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE|ATTR_BOXDRAW;
if (IS_SET(MODE_REVERSE)) {
g.mode |= ATTR_REVERSE;
@@ -1947,10 +1965,9 @@ run(void)
XEvent ev;
int w = win.w, h = win.h;
fd_set rfd;
- int xfd = XConnectionNumber(xw.dpy), xev, blinkset = 0, dodraw = 0;
- int ttyfd;
- struct timespec drawtimeout, *tv = NULL, now, last, lastblink;
- long deltatime;
+ int xfd = XConnectionNumber(xw.dpy), ttyfd, xev, drawing;
+ struct timespec seltv, *tv, now, lastblink, trigger;
+ double timeout;
/* Waiting for window mapping */
do {
@@ -1971,82 +1988,77 @@ run(void)
ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd);
cresize(w, h);
- clock_gettime(CLOCK_MONOTONIC, &last);
- lastblink = last;
-
- for (xev = actionfps;;) {
+ for (timeout = -1, drawing = 0, lastblink = (struct timespec){0};;) {
FD_ZERO(&rfd);
FD_SET(ttyfd, &rfd);
FD_SET(xfd, &rfd);
+ if (XPending(xw.dpy))
+ timeout = 0; /* existing events might not set xfd */
+
+ seltv.tv_sec = timeout / 1E3;
+ seltv.tv_nsec = 1E6 * (timeout - 1E3 * seltv.tv_sec);
+ tv = timeout >= 0 ? &seltv : NULL;
+
if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) {
if (errno == EINTR)
continue;
die("select failed: %s\n", strerror(errno));
}
- if (FD_ISSET(ttyfd, &rfd)) {
- ttyread();
- if (blinktimeout) {
- blinkset = tattrset(ATTR_BLINK);
- if (!blinkset)
- MODBIT(win.mode, 0, MODE_BLINK);
- }
- }
+ clock_gettime(CLOCK_MONOTONIC, &now);
- if (FD_ISSET(xfd, &rfd))
- xev = actionfps;
+ if (FD_ISSET(ttyfd, &rfd))
+ ttyread();
- clock_gettime(CLOCK_MONOTONIC, &now);
- drawtimeout.tv_sec = 0;
- drawtimeout.tv_nsec = (1000 * 1E6)/ xfps;
- tv = &drawtimeout;
-
- dodraw = 0;
- if (blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) {
- tsetdirtattr(ATTR_BLINK);
- win.mode ^= MODE_BLINK;
- lastblink = now;
- dodraw = 1;
- }
- deltatime = TIMEDIFF(now, last);
- if (deltatime > 1000 / (xev ? xfps : actionfps)) {
- dodraw = 1;
- last = now;
+ xev = 0;
+ while (XPending(xw.dpy)) {
+ xev = 1;
+ XNextEvent(xw.dpy, &ev);
+ if (XFilterEvent(&ev, None))
+ continue;
+ if (handler[ev.type])
+ (handler[ev.type])(&ev);
}
- if (dodraw) {
- while (XPending(xw.dpy)) {
- XNextEvent(xw.dpy, &ev);
- if (XFilterEvent(&ev, None))
- continue;
- if (handler[ev.type])
- (handler[ev.type])(&ev);
+ /*
+ * To reduce flicker and tearing, when new content or event
+ * triggers drawing, we first wait a bit to ensure we got
+ * everything, and if nothing new arrives - we draw.
+ * We start with trying to wait minlatency ms. If more content
+ * arrives sooner, we retry with shorter and shorter preiods,
+ * and eventually draw even without idle after maxlatency ms.
+ * Typically this results in low latency while interacting,
+ * maximum latency intervals during `cat huge.txt`, and perfect
+ * sync with periodic updates from animations/key-repeats/etc.
+ */
+ if (FD_ISSET(ttyfd, &rfd) || xev) {
+ if (!drawing) {
+ trigger = now;
+ drawing = 1;
}
+ timeout = (maxlatency - TIMEDIFF(now, trigger)) \
+ / maxlatency * minlatency;
+ if (timeout > 0)
+ continue; /* we have time, try to find idle */
+ }
- draw();
- XFlush(xw.dpy);
-
- if (xev && !FD_ISSET(xfd, &rfd))
- xev--;
- if (!FD_ISSET(ttyfd, &rfd) && !FD_ISSET(xfd, &rfd)) {
- if (blinkset) {
- if (TIMEDIFF(now, lastblink) \
- > blinktimeout) {
- drawtimeout.tv_nsec = 1000;
- } else {
- drawtimeout.tv_nsec = (1E6 * \
- (blinktimeout - \
- TIMEDIFF(now,
- lastblink)));
- }
- drawtimeout.tv_sec = \
- drawtimeout.tv_nsec / 1E9;
- drawtimeout.tv_nsec %= (long)1E9;
- } else {
- tv = NULL;
- }
+ /* idle detected or maxlatency exhausted -> draw */
+ timeout = -1;
+ if (blinktimeout && tattrset(ATTR_BLINK)) {
+ timeout = blinktimeout - TIMEDIFF(now, lastblink);
+ if (timeout <= 0) {
+ if (-timeout > blinktimeout) /* start visible */
+ win.mode |= MODE_BLINK;
+ win.mode ^= MODE_BLINK;
+ tsetdirtattr(ATTR_BLINK);
+ lastblink = now;
+ timeout = blinktimeout;
}
}
+
+ draw();
+ XFlush(xw.dpy);
+ drawing = 0;
}
}