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