diff options
| author | zachir <zachir@librem.one> | 2023-02-20 01:52:58 -0600 | 
|---|---|---|
| committer | zachir <zachir@librem.one> | 2023-02-20 01:52:58 -0600 | 
| commit | e37e594a2a75e965c353dd541385208d03f2b4bc (patch) | |
| tree | 59126c7bb6dff97bc76a13b8e82fc78034cc16e2 /x.c | |
| parent | 6cafedb4b171c53bea640d7850988526b3b64c20 (diff) | |
add alpha anysize bold-is-not-bright boxdraw_v2 charoffsets clipboard and focus patches
Diffstat (limited to 'x.c')
| -rw-r--r-- | x.c | 158 | 
1 files changed, 103 insertions, 55 deletions
@@ -81,6 +81,7 @@ typedef XftGlyphFontSpec GlyphFontSpec;  typedef struct {  	int tw, th; /* tty width and height */  	int w, h; /* window width and height */ +	int hborderpx, vborderpx;  	int ch; /* char height */  	int cw; /* char width  */  	int mode; /* window state/mode flags */ @@ -105,6 +106,7 @@ typedef struct {  	XSetWindowAttributes attrs;  	int scr;  	int isfixed; /* is fixed geometry? */ +	int depth; /* bit depth */  	int l, t; /* left and top offset */  	int gm; /* geometry mask */  } XWindow; @@ -243,6 +245,7 @@ static char *usedfont = NULL;  static double usedfontsize = 0;  static double defaultfontsize = 0; +static char *opt_alpha = NULL;  static char *opt_class = NULL;  static char **opt_cmd  = NULL;  static char *opt_embed = NULL; @@ -252,6 +255,8 @@ static char *opt_line  = NULL;  static char *opt_name  = NULL;  static char *opt_title = NULL; +static int focused = 0; +  static uint buttons; /* bit field of pressed buttons */  void @@ -331,7 +336,7 @@ ttysend(const Arg *arg)  int  evcol(XEvent *e)  { -	int x = e->xbutton.x - borderpx; +	int x = e->xbutton.x - win.hborderpx;  	LIMIT(x, 0, win.tw - 1);  	return x / win.cw;  } @@ -339,7 +344,7 @@ evcol(XEvent *e)  int  evrow(XEvent *e)  { -	int y = e->xbutton.y - borderpx; +	int y = e->xbutton.y - win.vborderpx;  	LIMIT(y, 0, win.th - 1);  	return y / win.ch;  } @@ -686,6 +691,7 @@ setsel(char *str, Time t)  	XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);  	if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)  		selclear(); +	clipcopy(NULL);  }  void @@ -739,6 +745,9 @@ cresize(int width, int height)  	col = MAX(1, col);  	row = MAX(1, row); +	win.hborderpx = (win.w - col * win.cw) / 2; +	win.vborderpx = (win.h - row * win.ch) / 2; +  	tresize(col, row);  	xresize(col, row);  	ttyresize(win.tw, win.th); @@ -752,7 +761,7 @@ xresize(int col, int row)  	XFreePixmap(xw.dpy, xw.buf);  	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, -			DefaultDepth(xw.dpy, xw.scr)); +			xw.depth);  	XftDrawChange(xw.draw, xw.buf);  	xclear(0, 0, win.w, win.h); @@ -791,27 +800,37 @@ xloadcolor(int i, const char *name, Color *ncolor)  }  void +xloadalpha(void) +{ +	float const usedAlpha = focused ? alpha : alphaUnfocused; +	if (opt_alpha) alpha = strtof(opt_alpha, NULL); +	dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * usedAlpha); +	dc.col[defaultbg].pixel &= 0x00FFFFFF; +	dc.col[defaultbg].pixel |= (unsigned char)(0xff * usedAlpha) << 24; +} + +void  xloadcols(void)  { -	int i;  	static int loaded;  	Color *cp; -	if (loaded) { -		for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp) -			XftColorFree(xw.dpy, xw.vis, xw.cmap, cp); -	} else { -		dc.collen = MAX(LEN(colorname), 256); -		dc.col = xmalloc(dc.collen * sizeof(Color)); +	if (!loaded) { +		dc.collen = 1 + (defaultbg = MAX(LEN(colorname), 256)); +		dc.col = xmalloc((dc.collen) * sizeof(Color));  	} -	for (i = 0; i < dc.collen; i++) +	for (int i = 0; i+1 < dc.collen; ++i)  		if (!xloadcolor(i, NULL, &dc.col[i])) {  			if (colorname[i])  				die("could not allocate color '%s'\n", colorname[i]);  			else  				die("could not allocate color %d\n", i);  		} +	if (dc.collen) // cannot die, as the color is already loaded. +		xloadcolor(focused ?bg :bgUnfocused, NULL, &dc.col[defaultbg]); + +	xloadalpha();  	loaded = 1;  } @@ -869,8 +888,8 @@ xhints(void)  	sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize;  	sizeh->height = win.h;  	sizeh->width = win.w; -	sizeh->height_inc = win.ch; -	sizeh->width_inc = win.cw; +	sizeh->height_inc = 1; +	sizeh->width_inc = 1;  	sizeh->base_height = 2 * borderpx;  	sizeh->base_width = 2 * borderpx;  	sizeh->min_height = win.ch + 2 * borderpx; @@ -1134,11 +1153,23 @@ xinit(int cols, int rows)  	Window parent;  	pid_t thispid = getpid();  	XColor xmousefg, xmousebg; +	XWindowAttributes attr; +	XVisualInfo vis;  	if (!(xw.dpy = XOpenDisplay(NULL)))  		die("can't open display\n");  	xw.scr = XDefaultScreen(xw.dpy); -	xw.vis = XDefaultVisual(xw.dpy, xw.scr); + +	if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) { +		parent = XRootWindow(xw.dpy, xw.scr); +		xw.depth = 32; +	} else { +		XGetWindowAttributes(xw.dpy, parent, &attr); +		xw.depth = attr.depth; +	} + +	XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis); +	xw.vis = vis.visual;  	/* font */  	if (!FcInit()) @@ -1148,12 +1179,12 @@ xinit(int cols, int rows)  	xloadfonts(usedfont, 0);  	/* colors */ -	xw.cmap = XDefaultColormap(xw.dpy, xw.scr); +	xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None);  	xloadcols();  	/* adjust fixed window geometry */ -	win.w = 2 * borderpx + cols * win.cw; -	win.h = 2 * borderpx + rows * win.ch; +	win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw; +	win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch;  	if (xw.gm & XNegative)  		xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2;  	if (xw.gm & YNegative) @@ -1168,19 +1199,15 @@ xinit(int cols, int rows)  		| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;  	xw.attrs.colormap = xw.cmap; -	if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) -		parent = XRootWindow(xw.dpy, xw.scr);  	xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, -			win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, +			win.w, win.h, 0, xw.depth, InputOutput,  			xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity  			| CWEventMask | CWColormap, &xw.attrs);  	memset(&gcvalues, 0, sizeof(gcvalues));  	gcvalues.graphics_exposures = False; -	dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, -			&gcvalues); -	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, -			DefaultDepth(xw.dpy, xw.scr)); +	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); +	dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues);  	XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);  	XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); @@ -1237,12 +1264,14 @@ xinit(int cols, int rows)  	xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0);  	if (xsel.xtarget == None)  		xsel.xtarget = XA_STRING; + +	boxdraw_xinit(xw.dpy, xw.cmap, xw.draw, xw.vis);  }  int  xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)  { -	float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; +	float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp;  	ushort mode, prevmode = USHRT_MAX;  	Font *font = &dc.font;  	int frcflags = FRC_NORMAL; @@ -1283,13 +1312,18 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x  			yp = winy + font->ascent;  		} -		/* Lookup character index with default font. */ -		glyphidx = XftCharIndex(xw.dpy, font->match, rune); +		if (mode & ATTR_BOXDRAW) { +			/* minor shoehorning: boxdraw uses only this ushort */ +			glyphidx = boxdrawindex(&glyphs[i]); +		} else { +			/* Lookup character index with default font. */ +			glyphidx = XftCharIndex(xw.dpy, font->match, rune); +		}  		if (glyphidx) {  			specs[numspecs].font = font->match;  			specs[numspecs].glyph = glyphidx; -			specs[numspecs].x = (short)xp; -			specs[numspecs].y = (short)yp; +			specs[numspecs].x = (short)xp + cxoffset; +			specs[numspecs].y = (short)yp + cyoffset;  			xp += runewidth;  			numspecs++;  			continue; @@ -1375,7 +1409,7 @@ void  xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)  {  	int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); -	int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, +	int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch,  	    width = charlen * win.cw;  	Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;  	XRenderColor colfg, colbg; @@ -1412,10 +1446,6 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i  		bg = &dc.col[base.bg];  	} -	/* Change basic system colors [0-7] to bright system colors [8-15] */ -	if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) -		fg = &dc.col[base.fg + 8]; -  	if (IS_SET(MODE_REVERSE)) {  		if (fg == &dc.col[defaultfg]) {  			fg = &dc.col[defaultbg]; @@ -1465,17 +1495,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i  	/* Intelligent cleaning up of the borders. */  	if (x == 0) { -		xclear(0, (y == 0)? 0 : winy, borderpx, +		xclear(0, (y == 0)? 0 : winy, win.hborderpx,  			winy + win.ch + -			((winy + win.ch >= borderpx + win.th)? win.h : 0)); +			((winy + win.ch >= win.vborderpx + win.th)? win.h : 0));  	} -	if (winx + width >= borderpx + win.tw) { +	if (winx + width >= win.hborderpx + win.tw) {  		xclear(winx + width, (y == 0)? 0 : winy, win.w, -			((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); +			((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch)));  	}  	if (y == 0) -		xclear(winx, 0, winx + width, borderpx); -	if (winy + win.ch >= borderpx + win.th) +		xclear(winx, 0, winx + width, win.vborderpx); +	if (winy + win.ch >= win.vborderpx + win.th)  		xclear(winx, winy + win.ch, winx + width, win.h);  	/* Clean up the region we want to draw to. */ @@ -1488,8 +1518,12 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i  	r.width = width;  	XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1); -	/* Render the glyphs. */ -	XftDrawGlyphFontSpec(xw.draw, fg, specs, len); +	if (base.mode & ATTR_BOXDRAW) { +		drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len); +	} else { +		/* Render the glyphs. */ +		XftDrawGlyphFontSpec(xw.draw, fg, specs, len); +	}  	/* Render underline and strikethrough. */  	if (base.mode & ATTR_UNDERLINE) { @@ -1532,7 +1566,7 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)  	/*  	 * Select the right color for the right mode.  	 */ -	g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE; +	g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE|ATTR_BOXDRAW;  	if (IS_SET(MODE_REVERSE)) {  		g.mode |= ATTR_REVERSE; @@ -1569,35 +1603,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)  		case 3: /* Blinking Underline */  		case 4: /* Steady Underline */  			XftDrawRect(xw.draw, &drawcol, -					borderpx + cx * win.cw, -					borderpx + (cy + 1) * win.ch - \ +					win.hborderpx + cx * win.cw, +					win.vborderpx + (cy + 1) * win.ch - \  						cursorthickness,  					win.cw, cursorthickness);  			break;  		case 5: /* Blinking bar */  		case 6: /* Steady bar */  			XftDrawRect(xw.draw, &drawcol, -					borderpx + cx * win.cw, -					borderpx + cy * win.ch, +					win.hborderpx + cx * win.cw, +					win.vborderpx + cy * win.ch,  					cursorthickness, win.ch);  			break;  		}  	} else {  		XftDrawRect(xw.draw, &drawcol, -				borderpx + cx * win.cw, -				borderpx + cy * win.ch, +				win.hborderpx + cx * win.cw, +				win.vborderpx + cy * win.ch,  				win.cw - 1, 1);  		XftDrawRect(xw.draw, &drawcol, -				borderpx + cx * win.cw, -				borderpx + cy * win.ch, +				win.hborderpx + cx * win.cw, +				win.vborderpx + cy * win.ch,  				1, win.ch - 1);  		XftDrawRect(xw.draw, &drawcol, -				borderpx + (cx + 1) * win.cw - 1, -				borderpx + cy * win.ch, +				win.hborderpx + (cx + 1) * win.cw - 1, +				win.vborderpx + cy * win.ch,  				1, win.ch - 1);  		XftDrawRect(xw.draw, &drawcol, -				borderpx + cx * win.cw, -				borderpx + (cy + 1) * win.ch - 1, +				win.hborderpx + cx * win.cw, +				win.vborderpx + (cy + 1) * win.ch - 1,  				win.cw, 1);  	}  } @@ -1777,12 +1811,22 @@ focus(XEvent *ev)  		xseturgency(0);  		if (IS_SET(MODE_FOCUS))  			ttywrite("\033[I", 3, 0); +		if (!focused) { +			focused = 1; +			xloadcols(); +			tfulldirt(); +		}  	} else {  		if (xw.ime.xic)  			XUnsetICFocus(xw.ime.xic);  		win.mode &= ~MODE_FOCUSED;  		if (IS_SET(MODE_FOCUS))  			ttywrite("\033[O", 3, 0); +		if (focused) { +			focused = 0; +			xloadcols(); +			tfulldirt(); +		}  	}  } @@ -2035,6 +2079,9 @@ main(int argc, char *argv[])  	case 'a':  		allowaltscreen = 0;  		break; +	case 'A': +		opt_alpha = EARGF(usage()); +		break;  	case 'c':  		opt_class = EARGF(usage());  		break; @@ -2086,6 +2133,7 @@ run:  	XSetLocaleModifiers("");  	cols = MAX(cols, 1);  	rows = MAX(rows, 1); +	defaultbg = MAX(LEN(colorname), 256);  	tnew(cols, rows);  	xinit(cols, rows);  	xsetenv();  | 
