st

fork of suckless's simple terminal
Index Commits Files Refs README LICENSE
commit 88d8293fb4ba150a5f19d58d133b5db93d9dcfa5
parent 05c66cb37d9ff278a3e0c45682c4b5e7945deb42
Author: Devin J. Pohly <djpohly@gmail.com>
Date:   Sat, 24 Feb 2018 14:53:23 -0600

Move win-agnostic parts of draw/drawregion to st.c

Introduces three functions to encapsulate X-specific behavior:
 * xdrawline: draws a portion of a single line (used by drawregion)
 * xbegindraw: called to prepare for drawing (will be useful for e.g.
   Wayland) and returns true if drawing should happen
 * xfinishdraw: called to finish drawing (used by draw)

Signed-off-by: Devin J. Pohly <djpohly@gmail.com>

Diffstat:
Mst.c | 25+++++++++++++++++++++++++
Mst.h | 1+
Mwin.h | 7++++---
Mx.c | 79+++++++++++++++++++++++++++++++++++--------------------------------------------
4 files changed, 65 insertions(+), 47 deletions(-)
diff --git a/st.c b/st.c
@@ -166,6 +166,8 @@ static int32_t tdefcolor(int *, int *, int);
 static void tdeftran(char);
 static void tstrsequence(uchar);
 
+static void drawregion(int, int, int, int);
+
 static void selscroll(int, int);
 static void selsnap(int *, int *, int);
 
@@ -2527,6 +2529,29 @@ resettitle(void)
 }
 
 void
+drawregion(int x1, int y1, int x2, int y2)
+{
+    int y;
+    for (y = y1; y < y2; y++) {
+        if (!term.dirty[y])
+            continue;
+
+        term.dirty[y] = 0;
+        xdrawline(term.line[y], x1, y, x2);
+    }
+}
+
+void
+draw(void)
+{
+    if (!xstartdraw())
+        return;
+    drawregion(0, 0, term.col, term.row);
+    xdrawcursor();
+    xfinishdraw();
+}
+
+void
 redraw(void)
 {
     tfulldirt();
diff --git a/st.h b/st.h
@@ -131,6 +131,7 @@ typedef union {
 
 void die(const char *, ...);
 void redraw(void);
+void draw(void);
 
 void iso14755(const Arg *);
 void printscreen(const Arg *);
diff --git a/win.h b/win.h
@@ -23,12 +23,12 @@ enum win_mode {
                       |MODE_MOUSEMANY,
 };
 
-void draw(void);
-void drawregion(int, int, int, int);
-
 void xbell(void);
 void xclipcopy(void);
+void xdrawcursor(void);
+void xdrawline(Line, int, int, int);
 void xhints(void);
+void xfinishdraw(void);
 void xloadcols(void);
 int xsetcolorname(int, const char *);
 void xsettitle(char *);
@@ -36,3 +36,4 @@ int xsetcursor(int);
 void xsetmode(int, unsigned int);
 void xsetpointermotion(int);
 void xsetsel(char *);
+int xstartdraw(void);
diff --git a/x.c b/x.c
@@ -129,7 +129,6 @@ static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int)
 static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
 static void xdrawglyph(Glyph, int, int);
 static void xclear(int, int, int, int);
-static void xdrawcursor(void);
 static int xgeommasktogravity(int);
 static void xinit(void);
 static void cresize(int, int);
@@ -1512,59 +1511,51 @@ xsettitle(char *p)
     XFree(prop.value);
 }
 
-void
-draw(void)
+int
+xstartdraw(void)
 {
-    drawregion(0, 0, term.col, term.row);
-    XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w,
-            win.h, 0, 0);
-    XSetForeground(xw.dpy, dc.gc,
-            dc.col[IS_SET(MODE_REVERSE)?
-                defaultfg : defaultbg].pixel);
+    return IS_SET(MODE_VISIBLE);
 }
 
 void
-drawregion(int x1, int y1, int x2, int y2)
+xdrawline(Line line, int x1, int y1, int x2)
 {
-    int i, x, y, ox, numspecs;
+    int i, x, ox, numspecs;
     Glyph base, new;
-    XftGlyphFontSpec *specs;
+    XftGlyphFontSpec *specs = xw.specbuf;
 
-    if (!(IS_SET(MODE_VISIBLE)))
-        return;
-
-    for (y = y1; y < y2; y++) {
-        if (!term.dirty[y])
+    numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
+    i = ox = 0;
+    for (x = x1; x < x2 && i < numspecs; x++) {
+        new = line[x];
+        if (new.mode == ATTR_WDUMMY)
             continue;
-
-        term.dirty[y] = 0;
-
-        specs = xw.specbuf;
-        numspecs = xmakeglyphfontspecs(specs, &term.line[y][x1], x2 - x1, x1, y);
-
-        i = ox = 0;
-        for (x = x1; x < x2 && i < numspecs; x++) {
-            new = term.line[y][x];
-            if (new.mode == ATTR_WDUMMY)
-                continue;
-            if (selected(x, y))
-                new.mode ^= ATTR_REVERSE;
-            if (i > 0 && ATTRCMP(base, new)) {
-                xdrawglyphfontspecs(specs, base, i, ox, y);
-                specs += i;
-                numspecs -= i;
-                i = 0;
-            }
-            if (i == 0) {
-                ox = x;
-                base = new;
-            }
-            i++;
+        if (selected(x, y1))
+            new.mode ^= ATTR_REVERSE;
+        if (i > 0 && ATTRCMP(base, new)) {
+            xdrawglyphfontspecs(specs, base, i, ox, y1);
+            specs += i;
+            numspecs -= i;
+            i = 0;
+        }
+        if (i == 0) {
+            ox = x;
+            base = new;
         }
-        if (i > 0)
-            xdrawglyphfontspecs(specs, base, i, ox, y);
+        i++;
     }
-    xdrawcursor();
+    if (i > 0)
+        xdrawglyphfontspecs(specs, base, i, ox, y1);
+}
+
+void
+xfinishdraw(void)
+{
+    XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w,
+            win.h, 0, 0);
+    XSetForeground(xw.dpy, dc.gc,
+            dc.col[IS_SET(MODE_REVERSE)?
+                defaultfg : defaultbg].pixel);
 }
 
 void