diff options
Diffstat (limited to 'x.c')
| -rw-r--r-- | x.c | 54 |
1 files changed, 54 insertions, 0 deletions
| @@ -1674,6 +1674,43 @@ xsettitle(char *p) | |||
| 1674 | XFree(prop.value); | 1674 | XFree(prop.value); |
| 1675 | } | 1675 | } |
| 1676 | 1676 | ||
| 1677 | |||
| 1678 | static int vbellset = 0; /* 1 during visual bell, 0 otherwise */ | ||
| 1679 | static struct timespec lastvbell = {0}; | ||
| 1680 | |||
| 1681 | static int | ||
| 1682 | isvbellcell(int x, int y) | ||
| 1683 | { | ||
| 1684 | int right = win.tw / win.cw - 1, bottom = win.th / win.ch - 1; | ||
| 1685 | return vbellmode == 0 && (VBCELL); /* logic defined at config.h */ | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | static void | ||
| 1689 | vbellbegin() { | ||
| 1690 | clock_gettime(CLOCK_MONOTONIC, &lastvbell); | ||
| 1691 | if (vbellset) | ||
| 1692 | return; | ||
| 1693 | vbellset = 1; | ||
| 1694 | redraw(); | ||
| 1695 | XFlush(xw.dpy); | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | static void | ||
| 1699 | xfillcircle(int x, int y, int r, uint color_ix) | ||
| 1700 | { | ||
| 1701 | XSetForeground(xw.dpy, dc.gc, dc.col[color_ix].pixel); | ||
| 1702 | XFillArc(xw.dpy, xw.buf, dc.gc, x - r, y - r, r * 2, r * 2, 0, 360*64); | ||
| 1703 | } | ||
| 1704 | |||
| 1705 | static void | ||
| 1706 | xdrawvbell() { | ||
| 1707 | int r = round(vbellradius * (vbellradius > 0 ? win.w : -win.cw)); | ||
| 1708 | int x = borderpx + r + vbellx * (win.tw - 2 * r); | ||
| 1709 | int y = borderpx + r + vbelly * (win.th - 2 * r); | ||
| 1710 | xfillcircle(x, y, r, vbellcolor_outline); | ||
| 1711 | xfillcircle(x, y, r / 1.2, vbellcolor); /* 1.2 - an artistic choice */ | ||
| 1712 | } | ||
| 1713 | |||
| 1677 | int | 1714 | int |
| 1678 | xstartdraw(void) | 1715 | xstartdraw(void) |
| 1679 | { | 1716 | { |
| @@ -1695,6 +1732,8 @@ xdrawline(Line line, int x1, int y1, int x2) | |||
| 1695 | continue; | 1732 | continue; |
| 1696 | if (selected(x, y1)) | 1733 | if (selected(x, y1)) |
| 1697 | new.mode ^= ATTR_REVERSE; | 1734 | new.mode ^= ATTR_REVERSE; |
| 1735 | if (vbellset && isvbellcell(x, y1)) | ||
| 1736 | new.mode ^= ATTR_REVERSE; | ||
| 1698 | if (i > 0 && ATTRCMP(base, new)) { | 1737 | if (i > 0 && ATTRCMP(base, new)) { |
| 1699 | xdrawglyphfontspecs(specs, base, i, ox, y1); | 1738 | xdrawglyphfontspecs(specs, base, i, ox, y1); |
| 1700 | specs += i; | 1739 | specs += i; |
| @@ -1714,6 +1753,9 @@ xdrawline(Line line, int x1, int y1, int x2) | |||
| 1714 | void | 1753 | void |
| 1715 | xfinishdraw(void) | 1754 | xfinishdraw(void) |
| 1716 | { | 1755 | { |
| 1756 | if (vbellset && vbellmode == 1) | ||
| 1757 | xdrawvbell(); | ||
| 1758 | |||
| 1717 | XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, | 1759 | XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, |
| 1718 | win.h, 0, 0); | 1760 | win.h, 0, 0); |
| 1719 | XSetForeground(xw.dpy, dc.gc, | 1761 | XSetForeground(xw.dpy, dc.gc, |
| @@ -1798,6 +1840,8 @@ xbell(void) | |||
| 1798 | xseturgency(1); | 1840 | xseturgency(1); |
| 1799 | if (bellvolume) | 1841 | if (bellvolume) |
| 1800 | XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); | 1842 | XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); |
| 1843 | if (vbelltimeout) | ||
| 1844 | vbellbegin(); | ||
| 1801 | } | 1845 | } |
| 1802 | 1846 | ||
| 1803 | void | 1847 | void |
| @@ -2062,6 +2106,16 @@ run(void) | |||
| 2062 | } | 2106 | } |
| 2063 | } | 2107 | } |
| 2064 | 2108 | ||
| 2109 | if (vbellset) { | ||
| 2110 | double remain = vbelltimeout - TIMEDIFF(now, lastvbell); | ||
| 2111 | if (remain <= 0) { | ||
| 2112 | vbellset = 0; | ||
| 2113 | redraw(); | ||
| 2114 | } else if (timeout < 0 || remain < timeout) { | ||
| 2115 | timeout = remain; | ||
| 2116 | } | ||
| 2117 | } | ||
| 2118 | |||
| 2065 | draw(); | 2119 | draw(); |
| 2066 | XFlush(xw.dpy); | 2120 | XFlush(xw.dpy); |
| 2067 | drawing = 0; | 2121 | drawing = 0; |
