]> Sergey Matveev's repositories - st.git/blobdiff - x.c
Optimisations
[st.git] / x.c
diff --git a/x.c b/x.c
index cd96575be257240b094888f9ca2bbdaaa0e3792a..6cf403dc755fa1d0c9abf28b923d021a67937e6a 100644 (file)
--- a/x.c
+++ b/x.c
@@ -253,6 +253,7 @@ static char *opt_name  = NULL;
 static char *opt_title = NULL;
 
 static uint buttons; /* bit field of pressed buttons */
+static int cursorblinks = 0;
 
 void
 clipcopy(const Arg *dummy)
@@ -818,7 +819,7 @@ xloadcols(void)
 int
 xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b)
 {
-       if (!BETWEEN(x, 0, dc.collen))
+       if (!BETWEEN(x, 0, dc.collen - 1))
                return 1;
 
        *r = dc.col[x].color.red >> 8;
@@ -833,7 +834,7 @@ xsetcolorname(int x, const char *name)
 {
        Color ncolor;
 
-       if (!BETWEEN(x, 0, dc.collen))
+       if (!BETWEEN(x, 0, dc.collen - 1))
                return 1;
 
        if (!xloadcolor(x, name, &ncolor))
@@ -1196,24 +1197,6 @@ xinit(int cols, int rows)
                                               ximinstantiate, NULL);
        }
 
-       /* white cursor, black outline */
-       cursor = XCreateFontCursor(xw.dpy, mouseshape);
-       XDefineCursor(xw.dpy, xw.win, cursor);
-
-       if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) {
-               xmousefg.red   = 0xffff;
-               xmousefg.green = 0xffff;
-               xmousefg.blue  = 0xffff;
-       }
-
-       if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) {
-               xmousebg.red   = 0x0000;
-               xmousebg.green = 0x0000;
-               xmousebg.blue  = 0x0000;
-       }
-
-       XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg);
-
        xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
        xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
        xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False);
@@ -1381,12 +1364,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
        XRenderColor colfg, colbg;
        XRectangle r;
 
-       /* Fallback on color display for attributes not supported by the font */
-       if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) {
-               if (dc.ibfont.badslant || dc.ibfont.badweight)
-                       base.fg = defaultattr;
-       } else if ((base.mode & ATTR_ITALIC && dc.ifont.badslant) ||
-           (base.mode & ATTR_BOLD && dc.bfont.badweight)) {
+       if (base.mode & ATTR_ITALIC) {
                base.fg = defaultattr;
        }
 
@@ -1493,12 +1471,12 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
 
        /* Render underline and strikethrough. */
        if (base.mode & ATTR_UNDERLINE) {
-               XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
+               XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1,
                                width, 1);
        }
 
        if (base.mode & ATTR_STRUCK) {
-               XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
+               XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3,
                                width, 1);
        }
 
@@ -1558,16 +1536,19 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
        /* draw the new one */
        if (IS_SET(MODE_FOCUSED)) {
                switch (win.cursor) {
-               case 7: /* st extension */
-                       g.u = 0x2603; /* snowman (U+2603) */
+               case 0: /* Blinking block */
+               case 1: /* Blinking block (default) */
+                       if (IS_SET(MODE_BLINK))
+                               break;
                        /* FALLTHROUGH */
-               case 0: /* Blinking Block */
-               case 1: /* Blinking Block (Default) */
-               case 2: /* Steady Block */
+               case 2: /* Steady block */
                        xdrawglyph(g, cx, cy);
                        break;
-               case 3: /* Blinking Underline */
-               case 4: /* Steady Underline */
+               case 3: /* Blinking underline */
+                       if (IS_SET(MODE_BLINK))
+                               break;
+                       /* FALLTHROUGH */
+               case 4: /* Steady underline */
                        XftDrawRect(xw.draw, &drawcol,
                                        borderpx + cx * win.cw,
                                        borderpx + (cy + 1) * win.ch - \
@@ -1575,12 +1556,23 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
                                        win.cw, cursorthickness);
                        break;
                case 5: /* Blinking bar */
+                       if (IS_SET(MODE_BLINK))
+                               break;
+                       /* FALLTHROUGH */
                case 6: /* Steady bar */
                        XftDrawRect(xw.draw, &drawcol,
                                        borderpx + cx * win.cw,
                                        borderpx + cy * win.ch,
                                        cursorthickness, win.ch);
                        break;
+               case 7: /* Blinking st cursor */
+                       if (IS_SET(MODE_BLINK))
+                               break;
+                       /* FALLTHROUGH */
+               case 8: /* Steady st cursor */
+                       g.u = 0x2603; /* snowman (U+2603) */
+                       xdrawglyph(g, cx, cy);
+                       break;
                }
        } else {
                XftDrawRect(xw.draw, &drawcol,
@@ -1617,6 +1609,9 @@ xseticontitle(char *p)
        XTextProperty prop;
        DEFAULT(p, opt_title);
 
+       if (p[0] == '\0')
+               p = opt_title;
+
        if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
                                        &prop) != Success)
                return;
@@ -1631,6 +1626,9 @@ xsettitle(char *p)
        XTextProperty prop;
        DEFAULT(p, opt_title);
 
+       if (p[0] == '\0')
+               p = opt_title;
+
        if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
                                        &prop) != Success)
                return;
@@ -1737,9 +1735,12 @@ xsetmode(int set, unsigned int flags)
 int
 xsetcursor(int cursor)
 {
-       if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */
+       if (!BETWEEN(cursor, 0, 8)) /* 7-8: st extensions */
                return 1;
        win.cursor = cursor;
+       cursorblinks = win.cursor == 0 || win.cursor == 1 ||
+                      win.cursor == 3 || win.cursor == 5 ||
+                      win.cursor == 7;
        return 0;
 }
 
@@ -1833,7 +1834,7 @@ void
 kpress(XEvent *ev)
 {
        XKeyEvent *e = &ev->xkey;
-       KeySym ksym;
+       KeySym ksym = NoSymbol;
        char buf[64], *customkey;
        int len;
        Rune c;
@@ -1843,10 +1844,13 @@ kpress(XEvent *ev)
        if (IS_SET(MODE_KBDLOCK))
                return;
 
-       if (xw.ime.xic)
+       if (xw.ime.xic) {
                len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
-       else
+               if (status == XBufferOverflow)
+                       return;
+       } else {
                len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
+       }
        /* 1. shortcuts */
        for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
                if (ksym == bp->keysym && match(bp->mod, e->state)) {
@@ -1983,6 +1987,10 @@ run(void)
                if (FD_ISSET(ttyfd, &rfd) || xev) {
                        if (!drawing) {
                                trigger = now;
+                               if (IS_SET(MODE_BLINK)) {
+                                       win.mode ^= MODE_BLINK;
+                               }
+                               lastblink = now;
                                drawing = 1;
                        }
                        timeout = (maxlatency - TIMEDIFF(now, trigger)) \
@@ -1993,7 +2001,7 @@ run(void)
 
                /* idle detected or maxlatency exhausted -> draw */
                timeout = -1;
-               if (blinktimeout && tattrset(ATTR_BLINK)) {
+               if (blinktimeout && (cursorblinks || tattrset(ATTR_BLINK))) {
                        timeout = blinktimeout - TIMEDIFF(now, lastblink);
                        if (timeout <= 0) {
                                if (-timeout > blinktimeout) /* start visible */