From b40ce8559698d1442ced6e537fb18091f1343fb8 Mon Sep 17 00:00:00 2001 From: xAlpharax <42233094+xAlpharax@users.noreply.github.com> Date: Mon, 14 Aug 2023 01:37:39 +0300 Subject: Complete migration and clean installation. Up to date with the upstream and the latest patches. Personal configuration merged. Changes to be committed: modified: Makefile new file: boxdraw.c new file: boxdraw.o new file: boxdraw_data.h modified: config.def.h new file: config.def.h.orig new file: config.def.h.rej new file: config.h modified: config.mk new file: patches/st-alpha-20220206-0.8.5.diff new file: patches/st-anysize-20220718-baa9357.diff new file: patches/st-boxdraw_v2-0.8.5.diff new file: patches/st-clipboard-0.8.3.diff new file: patches/st-copyurl-multiline-20230406-211964d.diff new file: patches/st-font2-0.8.5.diff new file: patches/st-scrollback-20210507-4536f46.diff new file: patches/st-scrollback-mouse-20220127-2c5edf2-after-scrollback.diff modified: st.c new file: st.c.orig new file: st.c.rej modified: st.h new file: st.h.orig new file: st.h.rej new file: st.o modified: x.c new file: x.c.orig new file: x.o --- x.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 178 insertions(+), 41 deletions(-) (limited to 'x.c') diff --git a/x.c b/x.c index aa09997..16b7bda 100644 --- a/x.c +++ b/x.c @@ -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; @@ -157,6 +159,8 @@ static void xhints(void); static int xloadcolor(int, const char *, Color *); static int xloadfont(Font *, FcPattern *); static void xloadfonts(const char *, double); +static int xloadsparefont(FcPattern *, int); +static void xloadsparefonts(void); static void xunloadfont(Font *); static void xunloadfonts(void); static void xsetenv(void); @@ -243,6 +247,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; @@ -306,6 +311,7 @@ zoomabs(const Arg *arg) { xunloadfonts(); xloadfonts(usedfont, arg->f); + xloadsparefonts(); cresize(0, 0); redraw(); xhints(); @@ -331,7 +337,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 +345,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 +692,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 +746,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 +762,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); @@ -812,6 +822,13 @@ xloadcols(void) else die("could not allocate color %d\n", i); } + + /* set alpha value of bg color */ + if (opt_alpha) + alpha = strtof(opt_alpha, NULL); + dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); + dc.col[defaultbg].pixel &= 0x00FFFFFF; + dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; loaded = 1; } @@ -869,8 +886,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; @@ -1050,6 +1067,101 @@ xloadfonts(const char *fontstr, double fontsize) FcPatternDestroy(pattern); } +int +xloadsparefont(FcPattern *pattern, int flags) +{ + FcPattern *match; + FcResult result; + + match = FcFontMatch(NULL, pattern, &result); + if (!match) { + return 1; + } + + if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) { + FcPatternDestroy(match); + return 1; + } + + frc[frclen].flags = flags; + /* Believe U+0000 glyph will present in each default font */ + frc[frclen].unicodep = 0; + frclen++; + + return 0; +} + +void +xloadsparefonts(void) +{ + FcPattern *pattern; + double sizeshift, fontval; + int fc; + char **fp; + + if (frclen != 0) + die("can't embed spare fonts. cache isn't empty"); + + /* Calculate count of spare fonts */ + fc = sizeof(font2) / sizeof(*font2); + if (fc == 0) + return; + + /* Allocate memory for cache entries. */ + if (frccap < 4 * fc) { + frccap += 4 * fc - frccap; + frc = xrealloc(frc, frccap * sizeof(Fontcache)); + } + + for (fp = font2; fp - font2 < fc; ++fp) { + + if (**fp == '-') + pattern = XftXlfdParse(*fp, False, False); + else + pattern = FcNameParse((FcChar8 *)*fp); + + if (!pattern) + die("can't open spare font %s\n", *fp); + + if (defaultfontsize > 0) { + sizeshift = usedfontsize - defaultfontsize; + if (sizeshift != 0 && + FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == + FcResultMatch) { + fontval += sizeshift; + FcPatternDel(pattern, FC_PIXEL_SIZE); + FcPatternDel(pattern, FC_SIZE); + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval); + } + } + + FcPatternAddBool(pattern, FC_SCALABLE, 1); + + FcConfigSubstitute(NULL, pattern, FcMatchPattern); + XftDefaultSubstitute(xw.dpy, xw.scr, pattern); + + if (xloadsparefont(pattern, FRC_NORMAL)) + die("can't open spare font %s\n", *fp); + + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); + if (xloadsparefont(pattern, FRC_ITALIC)) + die("can't open spare font %s\n", *fp); + + FcPatternDel(pattern, FC_WEIGHT); + FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); + if (xloadsparefont(pattern, FRC_ITALICBOLD)) + die("can't open spare font %s\n", *fp); + + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); + if (xloadsparefont(pattern, FRC_BOLD)) + die("can't open spare font %s\n", *fp); + + FcPatternDestroy(pattern); + } +} + void xunloadfont(Font *f) { @@ -1134,11 +1246,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()) @@ -1147,13 +1271,16 @@ xinit(int cols, int rows) usedfont = (opt_font == NULL)? font : opt_font; xloadfonts(usedfont, 0); + /* spare fonts */ + xloadsparefonts(); + /* 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 +1295,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 +1360,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,8 +1408,13 @@ 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; @@ -1375,7 +1505,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; @@ -1465,17 +1595,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 +1618,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 +1666,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 +1703,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); } } @@ -2038,6 +2172,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; -- cgit v1.2.3