~petersanchez/st

88d8293fb4ba150a5f19d58d133b5db93d9dcfa5 — Devin J. Pohly 6 years ago 05c66cb
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>
4 files changed, 65 insertions(+), 47 deletions(-)

M st.c
M st.h
M win.h
M x.c
M st.c => st.c +25 -0
@@ 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();

M st.h => st.h +1 -0
@@ 131,6 131,7 @@ typedef union {

void die(const char *, ...);
void redraw(void);
void draw(void);

void iso14755(const Arg *);
void printscreen(const Arg *);

M win.h => win.h +4 -3
@@ 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);

M x.c => x.c +35 -44
@@ 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