Oh, I guess the mailing list manager swallowed the subscribe message
---

Hello

The render- patches are independent of each other, but depend on the
first reorder-and-extend.

Move default-rows-cols to config is completely independent, and makes
sense on its own.

The fast-blink support involves a bit of mucking about in the main
loop, and is a bit more debatable. I'm not entirely happy with it, but
it does separate things a bit. It also makes independent windows blink
synchronously, which makes me slightly less crazy.


cheers
aes
From 313012a5e28bedd9aa8c7e23fa0b8f09c4f3a3ab Mon Sep 17 00:00:00 2001
From: Anders Eurenius <a...@spotify.com>
Date: Sat, 21 Jun 2014 20:29:36 +0200
Subject: [PATCH 1/6] Reorder and extend glyph attributes

---
 st.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 14 deletions(-)

diff --git a/st.c b/st.c
index 26053b0..4ffb3df 100644
--- a/st.c
+++ b/st.c
@@ -90,15 +90,19 @@ char *argv0;
 #define VT102ID "\033[?6c"
 
 enum glyph_attribute {
-	ATTR_NULL      = 0,
-	ATTR_REVERSE   = 1,
-	ATTR_UNDERLINE = 2,
-	ATTR_BOLD      = 4,
-	ATTR_ITALIC    = 8,
+        ATTR_NULL      = 0,
+	ATTR_BOLD      = 1,
+	ATTR_FAINT     = 2,
+	ATTR_ITALIC    = 4,
+	ATTR_UNDERLINE = 8,
 	ATTR_BLINK     = 16,
-	ATTR_WRAP      = 32,
-	ATTR_WIDE      = 64,
-	ATTR_WDUMMY    = 128,
+	ATTR_FASTBLINK = 32,
+	ATTR_REVERSE   = 64,
+	ATTR_INVISIBLE = 128,
+	ATTR_STRUCK    = 256,
+	ATTR_WRAP      = 512,
+	ATTR_WIDE      = 1024,
+	ATTR_WDUMMY    = 2048,
 };
 
 enum cursor_movement {
@@ -1682,15 +1686,25 @@ tsetattr(int *attr, int l) {
 	for(i = 0; i < l; i++) {
 		switch(attr[i]) {
 		case 0:
-			term.c.attr.mode &= ~(ATTR_REVERSE | ATTR_UNDERLINE \
-					| ATTR_BOLD | ATTR_ITALIC \
-					| ATTR_BLINK);
+			term.c.attr.mode &= ~(
+				ATTR_BOLD       |
+				ATTR_FAINT      |
+				ATTR_ITALIC     |
+				ATTR_UNDERLINE  |
+				ATTR_BLINK      |
+				ATTR_FASTBLINK  |
+				ATTR_REVERSE    |
+				ATTR_INVISIBLE  |
+				ATTR_STRUCK     );
 			term.c.attr.fg = defaultfg;
 			term.c.attr.bg = defaultbg;
 			break;
 		case 1:
 			term.c.attr.mode |= ATTR_BOLD;
 			break;
+		case 2:
+			term.c.attr.mode |= ATTR_FAINT;
+			break;
 		case 3:
 			term.c.attr.mode |= ATTR_ITALIC;
 			break;
@@ -1698,16 +1712,26 @@ tsetattr(int *attr, int l) {
 			term.c.attr.mode |= ATTR_UNDERLINE;
 			break;
 		case 5: /* slow blink */
-		case 6: /* rapid blink */
 			term.c.attr.mode |= ATTR_BLINK;
 			break;
+		case 6: /* rapid blink */
+			term.c.attr.mode |= ATTR_FASTBLINK;
+			break;
 		case 7:
 			term.c.attr.mode |= ATTR_REVERSE;
 			break;
+		case 8:
+			term.c.attr.mode |= ATTR_INVISIBLE;
+			break;
+		case 9:
+			term.c.attr.mode |= ATTR_STRUCK;
+			break;
 		case 21:
-		case 22:
 			term.c.attr.mode &= ~ATTR_BOLD;
 			break;
+		case 22:
+			term.c.attr.mode &= ~ATTR_FAINT;
+			break;
 		case 23:
 			term.c.attr.mode &= ~ATTR_ITALIC;
 			break;
@@ -1715,12 +1739,20 @@ tsetattr(int *attr, int l) {
 			term.c.attr.mode &= ~ATTR_UNDERLINE;
 			break;
 		case 25:
-		case 26:
 			term.c.attr.mode &= ~ATTR_BLINK;
 			break;
+		case 26:
+			term.c.attr.mode &= ~ATTR_FASTBLINK;
+			break;
 		case 27:
 			term.c.attr.mode &= ~ATTR_REVERSE;
 			break;
+		case 28:
+			term.c.attr.mode &= ~ATTR_INVISIBLE;
+			break;
+		case 29:
+			term.c.attr.mode &= ~ATTR_STRUCK;
+			break;
 		case 38:
 			if ((idx = tdefcolor(attr, &i, l)) >= 0)
 				term.c.attr.fg = idx;
-- 
2.0.0

From 06d67617e79ec6e4a63635c65654a76658136973 Mon Sep 17 00:00:00 2001
From: Anders Eurenius <a...@spotify.com>
Date: Sat, 21 Jun 2014 20:30:22 +0200
Subject: [PATCH 2/6] Render invisible attribute

---
 st.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/st.c b/st.c
index 4ffb3df..2083d42 100644
--- a/st.c
+++ b/st.c
@@ -3236,6 +3236,9 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
 	if(base.mode & ATTR_BLINK && term.mode & MODE_BLINK)
 		fg = bg;
 
+	if(base.mode & ATTR_INVISIBLE)
+		fg = bg;
+
 	/* Intelligent cleaning up of the borders. */
 	if(x == 0) {
 		xclear(0, (y == 0)? 0 : winy, borderpx,
-- 
2.0.0

From 47feca0fe1e719dabd67a4e8691372493d38074b Mon Sep 17 00:00:00 2001
From: Anders Eurenius <a...@spotify.com>
Date: Sat, 21 Jun 2014 20:32:34 +0200
Subject: [PATCH 3/6] Render struck-out attribute

---
 st.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/st.c b/st.c
index 2083d42..dcbc4cb 100644
--- a/st.c
+++ b/st.c
@@ -3383,6 +3383,11 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
 				width, 1);
 	}
 
+	if(base.mode & ATTR_STRUCK) {
+		XftDrawRect(xw.draw, fg, winx, winy + 2 * font->ascent / 3,
+				width, 1);
+	}
+
 	/* Reset clip to none. */
 	XftDrawSetClip(xw.draw, 0);
 }
-- 
2.0.0

From 0caf4828c9ecace69322ebf87b37c91310b27f43 Mon Sep 17 00:00:00 2001
From: Anders Eurenius <a...@spotify.com>
Date: Sun, 22 Jun 2014 00:10:59 +0200
Subject: [PATCH 4/6] Render faint attribute

---
 st.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/st.c b/st.c
index dcbc4cb..40dcdf3 100644
--- a/st.c
+++ b/st.c
@@ -3189,7 +3189,7 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
 		 * change basic system colors [0-7]
 		 * to bright system colors [8-15]
 		 */
-		if(BETWEEN(base.fg, 0, 7))
+		if(BETWEEN(base.fg, 0, 7) && !(base.mode & ATTR_FAINT))
 			fg = &dc.col[base.fg + 8];
 
 		if(base.mode & ATTR_ITALIC) {
@@ -3233,6 +3233,14 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
 		bg = temp;
 	}
 
+	if(base.mode & ATTR_FAINT && !(base.mode & ATTR_BOLD)) {
+		colfg.red = fg->color.red / 2;
+		colfg.green = fg->color.green / 2;
+		colfg.blue = fg->color.blue / 2;
+		XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg);
+		fg = &revfg;
+	}
+
 	if(base.mode & ATTR_BLINK && term.mode & MODE_BLINK)
 		fg = bg;
 
-- 
2.0.0

From 8192b6f0f6f68dff2016022003406ba2f0d69aeb Mon Sep 17 00:00:00 2001
From: Anders Eurenius <a...@spotify.com>
Date: Sat, 21 Jun 2014 20:34:11 +0200
Subject: [PATCH 5/6] Move default rows, cols to config.def.h

---
 config.def.h | 2 ++
 st.c         | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/config.def.h b/config.def.h
index fadcfa0..68c2051 100644
--- a/config.def.h
+++ b/config.def.h
@@ -6,6 +6,8 @@
  * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
  */
 static char font[] = "Liberation Mono:pixelsize=12:antialias=false:autohint=false";
+static int default_cols = 80;
+static int default_rows = 24;
 static int borderpx = 2;
 static char shell[] = "/bin/sh";
 
diff --git a/st.c b/st.c
index 40dcdf3..1621352 100644
--- a/st.c
+++ b/st.c
@@ -3862,7 +3862,8 @@ usage(void) {
 int
 main(int argc, char *argv[]) {
 	char *titles;
-	uint cols = 80, rows = 24;
+	uint cols = default_cols;
+	uint rows = default_rows;
 
 	xw.l = xw.t = 0;
 	xw.isfixed = False;
-- 
2.0.0

From 7482a4bf5f58274f7f0c032b91c18c673375b277 Mon Sep 17 00:00:00 2001
From: Anders Eurenius <a...@spotify.com>
Date: Sun, 22 Jun 2014 16:02:06 +0200
Subject: [PATCH 6/6] Refactor mainloop, add fast blink support

---
 st.c | 136 ++++++++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 86 insertions(+), 50 deletions(-)

diff --git a/st.c b/st.c
index 1621352..f256528 100644
--- a/st.c
+++ b/st.c
@@ -3244,6 +3244,9 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
 	if(base.mode & ATTR_BLINK && term.mode & MODE_BLINK)
 		fg = bg;
 
+	if(base.mode & ATTR_FASTBLINK && term.mode & MODE_FBLINK)
+		fg = bg;
+
 	if(base.mode & ATTR_INVISIBLE)
 		fg = bg;
 
@@ -3752,12 +3755,10 @@ resize(XEvent *e) {
 }
 
 void
-run(void) {
+init(void)
+{
 	XEvent ev;
 	int w = xw.w, h = xw.h;
-	fd_set rfd;
-	int xfd = XConnectionNumber(xw.dpy), xev, blinkset = 0, dodraw = 0;
-	struct timeval drawtimeout, *tv = NULL, now, last, lastblink;
 
 	/* Waiting for window mapping */
 	while(1) {
@@ -3772,32 +3773,75 @@ run(void) {
 
 	ttynew();
 	cresize(w, h);
+}
+
+const int xev_activity = 1;
+const int cmd_activity = 2;
+
+int do_select(struct timeval *tv)
+{
+	int xfd = XConnectionNumber(xw.dpy);
+	fd_set rfd;
+
+	FD_ZERO(&rfd);
+	FD_SET(cmdfd, &rfd);
+	FD_SET(xfd, &rfd);
+
+	while(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, tv) < 0) {
+		if(errno == EINTR)
+			continue;
+		die("select failed: %s\n", strerror(errno));
+	}
+
+	return (FD_ISSET(xfd, &rfd)? xev_activity: 0) |
+		(FD_ISSET(cmdfd, &rfd)? cmd_activity: 0);
+}
+
+int
+setblinks(struct timeval *now)
+{
+	unsigned long long int t = now->tv_sec * 1000 + now->tv_usec / 1000;
+	int blink, fblink, change = 0;
+
+	blink = (t / blinktimeout) & 1;
+	if(!!(term.mode & MODE_BLINK) != blink)
+		change = 1;
+
+	fblink = (t / (blinktimeout / 4)) & 1;
+	if(!!(term.mode & MODE_FBLINK) != fblink)
+		change = 1;
+
+	MODBIT(term.mode, blink, MODE_BLINK);
+	MODBIT(term.mode, fblink, MODE_FBLINK);
+
+	return change;
+}
+
+void
+run(void) {
+	XEvent ev;
+	int s, xev, blinkset = 0, dodraw = 0;
+	struct timeval drawtimeout, *tv = NULL, now, last;
+
+	init();
 
 	gettimeofday(&last, NULL);
-	lastblink = last;
+	xev = actionfps;
 
-	for(xev = actionfps;;) {
+	for(;;) {
 		long deltatime;
 
-		FD_ZERO(&rfd);
-		FD_SET(cmdfd, &rfd);
-		FD_SET(xfd, &rfd);
+		s = do_select(tv);
 
-		if(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, tv) < 0) {
-			if(errno == EINTR)
-				continue;
-			die("select failed: %s\n", strerror(errno));
-		}
-		if(FD_ISSET(cmdfd, &rfd)) {
+		if(s & cmd_activity) {
 			ttyread();
 			if(blinktimeout) {
-				blinkset = tattrset(ATTR_BLINK);
-				if(!blinkset)
-					MODBIT(term.mode, 0, MODE_BLINK);
+				blinkset = tattrset(ATTR_BLINK) |
+					tattrset(ATTR_FASTBLINK);
 			}
 		}
 
-		if(FD_ISSET(xfd, &rfd))
+		if(s & xev_activity)
 			xev = actionfps;
 
 		gettimeofday(&now, NULL);
@@ -3806,10 +3850,9 @@ run(void) {
 		tv = &drawtimeout;
 
 		dodraw = 0;
-		if(blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) {
+		if(blinktimeout && blinkset && setblinks(&now)) {
 			tsetdirtattr(ATTR_BLINK);
-			term.mode ^= MODE_BLINK;
-			lastblink = now;
+			tsetdirtattr(ATTR_FASTBLINK);
 			dodraw = 1;
 		}
 		deltatime = TIMEDIFF(now, last);
@@ -3819,35 +3862,28 @@ run(void) {
 			last = now;
 		}
 
-		if(dodraw) {
-			while(XPending(xw.dpy)) {
-				XNextEvent(xw.dpy, &ev);
-				if(XFilterEvent(&ev, None))
-					continue;
-				if(handler[ev.type])
-					(handler[ev.type])(&ev);
-			}
+		if(!dodraw)
+			continue;
 
-			draw();
-			XFlush(xw.dpy);
-
-			if(xev && !FD_ISSET(xfd, &rfd))
-				xev--;
-			if(!FD_ISSET(cmdfd, &rfd) && !FD_ISSET(xfd, &rfd)) {
-				if(blinkset) {
-					if(TIMEDIFF(now, lastblink) \
-							> blinktimeout) {
-						drawtimeout.tv_usec = 1;
-					} else {
-						drawtimeout.tv_usec = (1000 * \
-							(blinktimeout - \
-							TIMEDIFF(now,
-								lastblink)));
-					}
-				} else {
-					tv = NULL;
-				}
-			}
+		while(XPending(xw.dpy)) {
+			XNextEvent(xw.dpy, &ev);
+			if(XFilterEvent(&ev, None))
+				continue;
+			if(handler[ev.type])
+				(handler[ev.type])(&ev);
+		}
+
+		draw();
+		XFlush(xw.dpy);
+
+		if(xev && !(s & xev_activity))
+			xev--;
+		if(blinkset) {
+			drawtimeout.tv_sec = 0;
+			drawtimeout.tv_usec = blinktimeout / 2;
+			tv = &drawtimeout;
+		} else {
+			tv = NULL;
 		}
 	}
 }
-- 
2.0.0

Reply via email to