st-visualbell2-basic-2018-10-16-30ec9a3.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
st-visualbell2-basic-2018-10-16-30ec9a3.diff (5437B)
---
1 From bcc850d57fb4cb6941008fb2808d4d0d373aa5f8 Mon Sep 17 00:00:00 2001
2 From: "Avi Halachmi (:avih)" <avihpit@yahoo.com>
3 Date: Mon, 15 Oct 2018 01:06:01 +0300
4 Subject: [PATCH] [vbell2] add visual bell with two rendering modes
5
6 - Inverse the whole terminal - "standard" visual-bell, a bit jarring.
7 - Inverse outer (border) cells - much less jarring, yet plenty visible.
8
9 Note: blink used a timeout of 1us after drawing, probably to
10 re-calculate the timeout without being affected by draw speed. This was
11 changed to 1ms for code simplicity, and should be inconsequential.
12 ---
13 config.def.h | 11 ++++++++
14 st.c | 1 -
15 st.h | 1 +
16 x.c | 77 +++++++++++++++++++++++++++++++++++++++-------------
17 4 files changed, 70 insertions(+), 20 deletions(-)
18
19 diff --git a/config.def.h b/config.def.h
20 index 823e79f..0915ce5 100644
21 --- a/config.def.h
22 +++ b/config.def.h
23 @@ -62,6 +62,17 @@ static unsigned int cursorthickness = 2;
24 */
25 static int bellvolume = 0;
26
27 +/*
28 + * visual-bell timeout (set to 0 to disable visual-bell).
29 + */
30 +static int vbelltimeout = 0;
31 +/*
32 + * visual bell mode when enabled:
33 + * 1: Inverse whole screen
34 + * 2: Inverse outer (border) cells
35 + */
36 +static int vbellmode = 1;
37 +
38 /* default TERM value */
39 char *termname = "st-256color";
40
41 diff --git a/st.c b/st.c
42 index 46cf2da..1229479 100644
43 --- a/st.c
44 +++ b/st.c
45 @@ -193,7 +193,6 @@ static void tsetscroll(int, int);
46 static void tswapscreen(void);
47 static void tsetmode(int, int, int *, int);
48 static int twrite(const char *, int, int);
49 -static void tfulldirt(void);
50 static void tcontrolcode(uchar );
51 static void tdectest(char );
52 static void tdefutf8(char);
53 diff --git a/st.h b/st.h
54 index 38c61c4..619d716 100644
55 --- a/st.h
56 +++ b/st.h
57 @@ -89,6 +89,7 @@ int tattrset(int);
58 void tnew(int, int);
59 void tresize(int, int);
60 void tsetdirtattr(int);
61 +void tfulldirt();
62 void ttyhangup(void);
63 int ttynew(char *, char *, char *, char **);
64 size_t ttyread(void);
65 diff --git a/x.c b/x.c
66 index 00cb6b1..7e66c6d 100644
67 --- a/x.c
68 +++ b/x.c
69 @@ -82,6 +82,8 @@ typedef struct {
70 int cw; /* char width */
71 int mode; /* window state/mode flags */
72 int cursor; /* cursor style */
73 + int vbellset; /* 1 during visual bell, 0 otherwise */
74 + struct timespec lastvbell;
75 } TermWindow;
76
77 typedef struct {
78 @@ -173,6 +175,9 @@ static void mousereport(XEvent *);
79 static char *kmap(KeySym, uint);
80 static int match(uint, uint);
81
82 +static void vbellbegin();
83 +static int isvbellcell(int x, int y);
84 +
85 static void run(void);
86 static void usage(void);
87
88 @@ -1528,6 +1533,8 @@ xdrawline(Line line, int x1, int y1, int x2)
89 continue;
90 if (selected(x, y1))
91 new.mode ^= ATTR_REVERSE;
92 + if (win.vbellset && isvbellcell(x, y1))
93 + new.mode ^= ATTR_REVERSE;
94 if (i > 0 && ATTRCMP(base, new)) {
95 xdrawglyphfontspecs(specs, base, i, ox, y1);
96 specs += i;
97 @@ -1610,6 +1617,28 @@ xseturgency(int add)
98 XFree(h);
99 }
100
101 +int
102 +isvbellcell(int x, int y)
103 +{
104 + if (vbellmode == 1)
105 + return 1;
106 + if (vbellmode == 2)
107 + return y == 0 || y == win.th / win.ch - 1 ||
108 + x == 0 || x == win.tw / win.cw - 1;
109 + return 0;
110 +}
111 +
112 +void
113 +vbellbegin() {
114 + clock_gettime(CLOCK_MONOTONIC, &win.lastvbell);
115 + if (win.vbellset) /* already visible, just extend win.lastvbell */
116 + return;
117 + win.vbellset = 1;
118 + tfulldirt();
119 + draw();
120 + XFlush(xw.dpy);
121 +}
122 +
123 void
124 xbell(void)
125 {
126 @@ -1617,6 +1646,8 @@ xbell(void)
127 xseturgency(1);
128 if (bellvolume)
129 XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL);
130 + if (vbelltimeout)
131 + vbellbegin();
132 }
133
134 void
135 @@ -1770,7 +1801,7 @@ run(void)
136 int xfd = XConnectionNumber(xw.dpy), xev, blinkset = 0, dodraw = 0;
137 int ttyfd;
138 struct timespec drawtimeout, *tv = NULL, now, last, lastblink;
139 - long deltatime;
140 + long deltatime, to_ms, remain;
141
142 /* Waiting for window mapping */
143 do {
144 @@ -1822,11 +1853,28 @@ run(void)
145 tv = &drawtimeout;
146
147 dodraw = 0;
148 - if (blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) {
149 - tsetdirtattr(ATTR_BLINK);
150 - win.mode ^= MODE_BLINK;
151 - lastblink = now;
152 - dodraw = 1;
153 + to_ms = -1; /* timeout in ms, indefinite if negative */
154 + if (blinkset) {
155 + remain = blinktimeout - TIMEDIFF(now, lastblink);
156 + if (remain <= 0) {
157 + dodraw = 1;
158 + remain = 1; /* draw, wait 1ms, and re-calc */
159 + tsetdirtattr(ATTR_BLINK);
160 + win.mode ^= MODE_BLINK;
161 + lastblink = now;
162 + }
163 + to_ms = remain;
164 + }
165 + if (win.vbellset) {
166 + remain = vbelltimeout - TIMEDIFF(now, win.lastvbell);
167 + if (remain <= 0) {
168 + dodraw = 1;
169 + remain = -1; /* draw (clear), and that's it */
170 + tfulldirt();
171 + win.vbellset = 0;
172 + }
173 + if (remain >= 0 && (to_ms < 0 || remain < to_ms))
174 + to_ms = remain;
175 }
176 deltatime = TIMEDIFF(now, last);
177 if (deltatime > 1000 / (xev ? xfps : actionfps)) {
178 @@ -1849,19 +1897,10 @@ run(void)
179 if (xev && !FD_ISSET(xfd, &rfd))
180 xev--;
181 if (!FD_ISSET(ttyfd, &rfd) && !FD_ISSET(xfd, &rfd)) {
182 - if (blinkset) {
183 - if (TIMEDIFF(now, lastblink) \
184 - > blinktimeout) {
185 - drawtimeout.tv_nsec = 1000;
186 - } else {
187 - drawtimeout.tv_nsec = (1E6 * \
188 - (blinktimeout - \
189 - TIMEDIFF(now,
190 - lastblink)));
191 - }
192 - drawtimeout.tv_sec = \
193 - drawtimeout.tv_nsec / 1E9;
194 - drawtimeout.tv_nsec %= (long)1E9;
195 + if (to_ms >= 0) {
196 + static const long k = 1E3, m = 1E6;
197 + drawtimeout.tv_sec = to_ms / k;
198 + drawtimeout.tv_nsec = (to_ms % k) * m;
199 } else {
200 tv = NULL;
201 }
202 --
203 2.19.1
204