diff options
author | ZachIR <zachir@librem.one> | 2025-07-08 20:39:57 -0500 |
---|---|---|
committer | ZachIR <zachir@librem.one> | 2025-07-08 20:39:57 -0500 |
commit | 38d2f7ba589e8ee0ee5ded7915952ed094e3a51a (patch) | |
tree | b98c891bcd03dcbc6a9ebae038d154a472febe8a /x.c | |
parent | 8cda47f8e8b2db37f5c69b4cdb748ac31a2e6e23 (diff) |
Start from scratch on version 0.9.2
Diffstat (limited to 'x.c')
-rw-r--r-- | x.c | 1110 |
1 files changed, 87 insertions, 1023 deletions
@@ -4,7 +4,6 @@ #include <limits.h> #include <locale.h> #include <signal.h> -#include <stdlib.h> #include <sys/select.h> #include <time.h> #include <unistd.h> @@ -15,8 +14,6 @@ #include <X11/keysym.h> #include <X11/Xft/Xft.h> #include <X11/XKBlib.h> -#include <X11/Xresource.h> -#include <X11/extensions/Xrandr.h> char *argv0; #include "arg.h" @@ -37,7 +34,6 @@ typedef struct { void (*func)(const Arg *); const Arg arg; uint release; - int altscrn; /* 0: don't care, -1: not alt screen, 1: alt screen */ } MouseShortcut; typedef struct { @@ -49,40 +45,6 @@ typedef struct { signed char appcursor; /* application cursor */ } Key; -/* Undercurl slope types */ -enum undercurl_slope_type { - UNDERCURL_SLOPE_ASCENDING = 0, - UNDERCURL_SLOPE_TOP_CAP = 1, - UNDERCURL_SLOPE_DESCENDING = 2, - UNDERCURL_SLOPE_BOTTOM_CAP = 3 -}; - -typedef struct { - const char *name; - float defaultfontsize; -} MonitorConfig; - -typedef struct { - Atom name; - int x, y, w, h; - float defaultfontsize, usedfontsize; -} MonitorInfo; - -static void refreshxrandr(const Arg *dummy); - -/* Xresources preferences */ -enum resource_type { - STRING = 0, - INTEGER = 1, - FLOAT = 2 -}; - -typedef struct { - char *name; - enum resource_type type; - void *dst; -} ResourcePref; - /* X modifiers */ #define XK_ANY_MOD UINT_MAX #define XK_NO_MOD 0 @@ -101,9 +63,6 @@ static void ttysend(const Arg *); /* config.h for applying patches and the configuration. */ #include "config.h" -/* size of title stack */ -#define TITLESTACKSIZE 8 - /* XEMBED messages */ #define XEMBED_FOCUS_IN 4 #define XEMBED_FOCUS_OUT 5 @@ -122,7 +81,6 @@ 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 */ @@ -135,7 +93,7 @@ typedef struct { Window win; Drawable buf; GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ - Atom xembed, wmdeletewin, netwmname, netwmicon, netwmiconname, netwmpid; + Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid; struct { XIM xim; XIC xic; @@ -145,14 +103,8 @@ typedef struct { Draw draw; Visual *vis; XSetWindowAttributes attrs; - /* Here, we use the term *pointer* to differentiate the cursor - * one sees when hovering the mouse over the terminal from, e.g., - * a green rectangle where text would be entered. */ - Cursor vpointer, bpointer; /* visible and hidden pointers */ - int pointerisvisible; int scr; int isfixed; /* is fixed geometry? */ - int depth; /* bit depth */ int l, t; /* left and top offset */ int gm; /* geometry mask */ } XWindow; @@ -205,8 +157,6 @@ 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); @@ -265,18 +215,11 @@ static void (*handler[LASTEvent])(XEvent *) = { [SelectionRequest] = selrequest, }; -static double defaultrelfontsize = 0; -static MonitorInfo *monitors_info = NULL; -static int monitors_num = 0; -static int prev_mindex = -1; - /* Globals */ static DC dc; static XWindow xw; static XSelection xsel; static TermWindow win; -static int tstki; /* title stack index */ -static char *titlestack[TITLESTACKSIZE]; /* title stack */ /* Font Ring Cache */ enum { @@ -300,7 +243,6 @@ 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; @@ -310,8 +252,6 @@ 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 @@ -366,7 +306,6 @@ zoomabs(const Arg *arg) { xunloadfonts(); xloadfonts(usedfont, arg->f); - xloadsparefonts(); cresize(0, 0); redraw(); xhints(); @@ -392,7 +331,7 @@ ttysend(const Arg *arg) int evcol(XEvent *e) { - int x = e->xbutton.x - win.hborderpx; + int x = e->xbutton.x - borderpx; LIMIT(x, 0, win.tw - 1); return x / win.cw; } @@ -400,7 +339,7 @@ evcol(XEvent *e) int evrow(XEvent *e) { - int y = e->xbutton.y - win.vborderpx; + int y = e->xbutton.y - borderpx; LIMIT(y, 0, win.th - 1); return y / win.ch; } @@ -516,7 +455,6 @@ mouseaction(XEvent *e, uint release) for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { if (ms->release == release && ms->button == e->xbutton.button && - (!ms->altscrn || (ms->altscrn == (tisaltscr() ? 1 : -1))) && (match(ms->mod, state) || /* exact or forced */ match(ms->mod, state & ~forcemousemod))) { ms->func(&(ms->arg)); @@ -748,7 +686,6 @@ 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 @@ -779,13 +716,6 @@ brelease(XEvent *e) void bmotion(XEvent *e) { - if (!xw.pointerisvisible) { - XDefineCursor(xw.dpy, xw.win, xw.vpointer); - xw.pointerisvisible = 1; - if (!IS_SET(MODE_MOUSEMANY)) - xsetpointermotion(0); - } - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { mousereport(e); return; @@ -809,9 +739,6 @@ cresize(int width, int height) col = MAX(1, col); row = MAX(1, row); - win.hborderpx = center_text ? (win.w - col * win.cw) / 2 : 0; // (win.w - col * win.cw) / 2 - win.vborderpx = center_text ? (win.h - row * win.ch) / 2 : 0; // (win.h - row * win.ch) / 2 - tresize(col, row); xresize(col, row); ttyresize(win.tw, win.th); @@ -825,7 +752,7 @@ xresize(int col, int row) XFreePixmap(xw.dpy, xw.buf); xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, - xw.depth); + DefaultDepth(xw.dpy, xw.scr)); XftDrawChange(xw.draw, xw.buf); xclear(0, 0, win.w, win.h); @@ -864,44 +791,34 @@ 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) { - dc.collen = 1 + (defaultbg = MAX(LEN(colorname), 256)); - dc.col = xmalloc((dc.collen) * sizeof(Color)); + 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)); } - for (int i = 0; i+1 < dc.collen; ++i) + for (i = 0; i < 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; } 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; @@ -916,7 +833,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)) @@ -942,8 +859,8 @@ xclear(int x1, int y1, int x2, int y2) void xhints(void) { - XClassHint class = {opt_name ? opt_name : "st", - opt_class ? opt_class : "St"}; + XClassHint class = {opt_name ? opt_name : termname, + opt_class ? opt_class : termname}; XWMHints wm = {.flags = InputHint, .input = 1}; XSizeHints *sizeh; @@ -952,8 +869,8 @@ xhints(void) sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; sizeh->height = win.h; sizeh->width = win.w; - sizeh->height_inc = 1; - sizeh->width_inc = 1; + sizeh->height_inc = win.ch; + sizeh->width_inc = win.cw; sizeh->base_height = 2 * borderpx; sizeh->base_width = 2 * borderpx; sizeh->min_height = win.ch + 2 * borderpx; @@ -1115,8 +1032,6 @@ xloadfonts(const char *fontstr, double fontsize) win.cw = ceilf(dc.font.width * cwscale); win.ch = ceilf(dc.font.height * chscale); - borderpx = ceilf(((float)borderperc / 100) * win.cw); - FcPatternDel(pattern, FC_SLANT); FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); if (xloadfont(&dc.ifont, pattern)) @@ -1135,101 +1050,6 @@ 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) { @@ -1314,40 +1134,26 @@ xinit(int cols, int rows) Window parent; pid_t thispid = getpid(); XColor xmousefg, xmousebg; - Pixmap blankpm; - XWindowAttributes attr; - XVisualInfo vis; + if (!(xw.dpy = XOpenDisplay(NULL))) + die("can't open display\n"); xw.scr = XDefaultScreen(xw.dpy); - - 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; + xw.vis = XDefaultVisual(xw.dpy, xw.scr); /* font */ if (!FcInit()) die("could not init fontconfig.\n"); usedfont = (opt_font == NULL)? font : opt_font; - xloadfonts(usedfont, defaultfontsize); - - /* spare fonts */ - xloadsparefonts(); + xloadfonts(usedfont, 0); /* colors */ - xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); + xw.cmap = XDefaultColormap(xw.dpy, xw.scr); xloadcols(); /* adjust fixed window geometry */ - win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw; - win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch; + win.w = 2 * borderpx + cols * win.cw; + win.h = 2 * borderpx + rows * win.ch; if (xw.gm & XNegative) xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; if (xw.gm & YNegative) @@ -1362,15 +1168,19 @@ 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, xw.depth, InputOutput, + win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask | CWColormap, &xw.attrs); memset(&gcvalues, 0, sizeof(gcvalues)); gcvalues.graphics_exposures = False; - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); - dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues); + dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, + &gcvalues); + xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, + DefaultDepth(xw.dpy, xw.scr)); XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); @@ -1387,9 +1197,8 @@ xinit(int cols, int rows) } /* white cursor, black outline */ - xw.pointerisvisible = 1; - xw.vpointer = XCreateFontCursor(xw.dpy, mouseshape); - XDefineCursor(xw.dpy, xw.win, xw.vpointer); + cursor = XCreateFontCursor(xw.dpy, mouseshape); + XDefineCursor(xw.dpy, xw.win, cursor); if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { xmousefg.red = 0xffff; @@ -1403,10 +1212,7 @@ xinit(int cols, int rows) xmousebg.blue = 0x0000; } - XRecolorCursor(xw.dpy, xw.vpointer, &xmousefg, &xmousebg); - blankpm = XCreateBitmapFromData(xw.dpy, xw.win, &(char){0}, 1, 1); - xw.bpointer = XCreatePixmapCursor(xw.dpy, blankpm, blankpm, - &xmousefg, &xmousebg, 0, 0); + XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg); xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); @@ -1414,41 +1220,6 @@ xinit(int cols, int rows) xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False); XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); - /* use a png-image to set _NET_WM_ICON */ - FILE* file = fopen(ICON, "r"); - if (file) { - /* load image in rgba-format */ - const gdImagePtr icon_rgba = gdImageCreateFromPng(file); - fclose(file); - /* declare icon-variable which will store the image in argb-format */ - const int width = gdImageSX(icon_rgba); - const int height = gdImageSY(icon_rgba); - const int icon_n = width * height + 2; - long icon_argb[icon_n]; - /* set width and height of the icon */ - int i = 0; - icon_argb[i++] = width; - icon_argb[i++] = height; - /* rgba -> argb */ - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - const int pixel_rgba = gdImageGetPixel(icon_rgba, x, y); - unsigned char *pixel_argb = (unsigned char *) &icon_argb[i++]; - pixel_argb[0] = gdImageBlue(icon_rgba, pixel_rgba); - pixel_argb[1] = gdImageGreen(icon_rgba, pixel_rgba); - pixel_argb[2] = gdImageRed(icon_rgba, pixel_rgba); - /* scale alpha from 0-127 to 0-255 */ - const unsigned char alpha = 127 - gdImageAlpha(icon_rgba, pixel_rgba); - pixel_argb[3] = alpha == 127 ? 255 : alpha * 2; - } - } - gdImageDestroy(icon_rgba); - /* set _NET_WM_ICON */ - xw.netwmicon = XInternAtom(xw.dpy, "_NET_WM_ICON", False); - XChangeProperty(xw.dpy, xw.win, xw.netwmicon, XA_CARDINAL, 32, - PropModeReplace, (uchar *) icon_argb, icon_n); - } - xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, PropModeReplace, (uchar *)&thispid, 1); @@ -1466,14 +1237,12 @@ 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 = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp; + float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; ushort mode, prevmode = USHRT_MAX; Font *font = &dc.font; int frcflags = FRC_NORMAL; @@ -1514,18 +1283,13 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x yp = winy + font->ascent; } - 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); - } + /* 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 + cxoffset; - specs[numspecs].y = (short)yp + cyoffset; + specs[numspecs].x = (short)xp; + specs[numspecs].y = (short)yp; xp += runewidth; numspecs++; continue; @@ -1607,56 +1371,11 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x return numspecs; } -static int isSlopeRising (int x, int iPoint, int waveWidth) -{ - // . . . . - // / \ / \ / \ / \ - // / \ / \ / \ / \ - // . . . . . - - // Find absolute `x` of point - x += iPoint * (waveWidth/2); - - // Find index of absolute wave - int absSlope = x / ((float)waveWidth/2); - - return (absSlope % 2); -} - -static int getSlope (int x, int iPoint, int waveWidth) -{ - // Sizes: Caps are half width of slopes - // 1_2 1_2 1_2 1_2 - // / \ / \ / \ / \ - // / \ / \ / \ / \ - // 0 3_0 3_0 3_0 3_ - // <2-> <1> <---6----> - - // Find type of first point - int firstType; - x -= (x / waveWidth) * waveWidth; - if (x < (waveWidth * (2.f/6.f))) - firstType = UNDERCURL_SLOPE_ASCENDING; - else if (x < (waveWidth * (3.f/6.f))) - firstType = UNDERCURL_SLOPE_TOP_CAP; - else if (x < (waveWidth * (5.f/6.f))) - firstType = UNDERCURL_SLOPE_DESCENDING; - else - firstType = UNDERCURL_SLOPE_BOTTOM_CAP; - - // Find type of given point - int pointType = (iPoint % 4); - pointType += firstType; - pointType %= 4; - - return pointType; -} - void xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) { int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); - int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, + int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, width = charlen * win.cw; Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; XRenderColor colfg, colbg; @@ -1693,6 +1412,10 @@ 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]; @@ -1742,17 +1465,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, win.hborderpx, + xclear(0, (y == 0)? 0 : winy, borderpx, winy + win.ch + - ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0)); + ((winy + win.ch >= borderpx + win.th)? win.h : 0)); } - if (winx + width >= win.hborderpx + win.tw) { + if (winx + width >= borderpx + win.tw) { xclear(winx + width, (y == 0)? 0 : winy, win.w, - ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch))); + ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); } if (y == 0) - xclear(winx, 0, winx + width, win.vborderpx); - if (winy + win.ch >= win.vborderpx + win.th) + xclear(winx, 0, winx + width, borderpx); + if (winy + win.ch >= borderpx + win.th) xclear(winx, winy + win.ch, winx + width, win.h); /* Clean up the region we want to draw to. */ @@ -1765,367 +1488,13 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i r.width = width; XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1); - 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 the glyphs. */ + XftDrawGlyphFontSpec(xw.draw, fg, specs, len); /* Render underline and strikethrough. */ if (base.mode & ATTR_UNDERLINE) { - // Underline Color - const int widthThreshold = 28; // +1 width every widthThreshold px of font - int wlw = (win.ch / widthThreshold) + 1; // Wave Line Width - int linecolor; - if ((base.ucolor[0] >= 0) && - !(base.mode & ATTR_BLINK && win.mode & MODE_BLINK) && - !(base.mode & ATTR_INVISIBLE) - ) { - // Special color for underline - // Index - if (base.ucolor[1] < 0) { - linecolor = dc.col[base.ucolor[0]].pixel; - } - // RGB - else { - XColor lcolor; - lcolor.red = base.ucolor[0] * 257; - lcolor.green = base.ucolor[1] * 257; - lcolor.blue = base.ucolor[2] * 257; - lcolor.flags = DoRed | DoGreen | DoBlue; - XAllocColor(xw.dpy, xw.cmap, &lcolor); - linecolor = lcolor.pixel; - } - } else { - // Foreground color for underline - linecolor = fg->pixel; - } - - XGCValues ugcv = { - .foreground = linecolor, - .line_width = wlw, - .line_style = LineSolid, - .cap_style = CapNotLast - }; - - GC ugc = XCreateGC(xw.dpy, XftDrawDrawable(xw.draw), - GCForeground | GCLineWidth | GCLineStyle | GCCapStyle, - &ugcv); - - // Underline Style - if (base.ustyle != 3) { - //XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, width, 1); - XFillRectangle(xw.dpy, XftDrawDrawable(xw.draw), ugc, winx, - winy + dc.font.ascent + 1, width, wlw); - } else if (base.ustyle == 3) { - int ww = win.cw;//width; - int wh = dc.font.descent - wlw/2 - 1;//r.height/7; - int wx = winx; - int wy = winy + win.ch - dc.font.descent; - -#if UNDERCURL_STYLE == UNDERCURL_CURLY - // Draw waves - int narcs = charlen * 2 + 1; - XArc *arcs = xmalloc(sizeof(XArc) * narcs); - - int i = 0; - for (i = 0; i < charlen-1; i++) { - arcs[i*2] = (XArc) { - .x = wx + win.cw * i + ww / 4, - .y = wy, - .width = win.cw / 2, - .height = wh, - .angle1 = 0, - .angle2 = 180 * 64 - }; - arcs[i*2+1] = (XArc) { - .x = wx + win.cw * i + ww * 0.75, - .y = wy, - .width = win.cw/2, - .height = wh, - .angle1 = 180 * 64, - .angle2 = 180 * 64 - }; - } - // Last wave - arcs[i*2] = (XArc) {wx + ww * i + ww / 4, wy, ww / 2, wh, - 0, 180 * 64 }; - // Last wave tail - arcs[i*2+1] = (XArc) {wx + ww * i + ww * 0.75, wy, ceil(ww / 2.), - wh, 180 * 64, 90 * 64}; - // First wave tail - i++; - arcs[i*2] = (XArc) {wx - ww/4 - 1, wy, ceil(ww / 2.), wh, 270 * 64, - 90 * 64 }; - - XDrawArcs(xw.dpy, XftDrawDrawable(xw.draw), ugc, arcs, narcs); - - free(arcs); -#elif UNDERCURL_STYLE == UNDERCURL_SPIKY - // Make the underline corridor larger - /* - wy -= wh; - */ - wh *= 2; - - // Set the angle of the slope to 45° - ww = wh; - - // Position of wave is independent of word, it's absolute - wx = (wx / (ww/2)) * (ww/2); - - int marginStart = winx - wx; - - // Calculate number of points with floating precision - float n = width; // Width of word in pixels - n = (n / ww) * 2; // Number of slopes (/ or \) - n += 2; // Add two last points - int npoints = n; // Convert to int - - // Total length of underline - float waveLength = 0; - - if (npoints >= 3) { - // We add an aditional slot in case we use a bonus point - XPoint *points = xmalloc(sizeof(XPoint) * (npoints + 1)); - - // First point (Starts with the word bounds) - points[0] = (XPoint) { - .x = wx + marginStart, - .y = (isSlopeRising(wx, 0, ww)) - ? (wy - marginStart + ww/2.f) - : (wy + marginStart) - }; - - // Second point (Goes back to the absolute point coordinates) - points[1] = (XPoint) { - .x = (ww/2.f) - marginStart, - .y = (isSlopeRising(wx, 1, ww)) - ? (ww/2.f - marginStart) - : (-ww/2.f + marginStart) - }; - waveLength += (ww/2.f) - marginStart; - - // The rest of the points - for (int i = 2; i < npoints-1; i++) { - points[i] = (XPoint) { - .x = ww/2, - .y = (isSlopeRising(wx, i, ww)) - ? wh/2 - : -wh/2 - }; - waveLength += ww/2; - } - - // Last point - points[npoints-1] = (XPoint) { - .x = ww/2, - .y = (isSlopeRising(wx, npoints-1, ww)) - ? wh/2 - : -wh/2 - }; - waveLength += ww/2; - - // End - if (waveLength < width) { // Add a bonus point? - int marginEnd = width - waveLength; - points[npoints] = (XPoint) { - .x = marginEnd, - .y = (isSlopeRising(wx, npoints, ww)) - ? (marginEnd) - : (-marginEnd) - }; - - npoints++; - } else if (waveLength > width) { // Is last point too far? - int marginEnd = waveLength - width; - points[npoints-1].x -= marginEnd; - if (isSlopeRising(wx, npoints-1, ww)) - points[npoints-1].y -= (marginEnd); - else - points[npoints-1].y += (marginEnd); - } - - // Draw the lines - XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points, npoints, - CoordModePrevious); - - // Draw a second underline with an offset of 1 pixel - if ( ((win.ch / (widthThreshold/2)) % 2)) { - points[0].x++; - - XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points, - npoints, CoordModePrevious); - } - - // Free resources - free(points); - } -#else // UNDERCURL_CAPPED - // Cap is half of wave width - float capRatio = 0.5f; - - // Make the underline corridor larger - wh *= 2; - - // Set the angle of the slope to 45° - ww = wh; - ww *= 1 + capRatio; // Add a bit of width for the cap - - // Position of wave is independent of word, it's absolute - wx = (wx / ww) * ww; - - float marginStart; - switch(getSlope(winx, 0, ww)) { - case UNDERCURL_SLOPE_ASCENDING: - marginStart = winx - wx; - break; - case UNDERCURL_SLOPE_TOP_CAP: - marginStart = winx - (wx + (ww * (2.f/6.f))); - break; - case UNDERCURL_SLOPE_DESCENDING: - marginStart = winx - (wx + (ww * (3.f/6.f))); - break; - case UNDERCURL_SLOPE_BOTTOM_CAP: - marginStart = winx - (wx + (ww * (5.f/6.f))); - break; - } - - // Calculate number of points with floating precision - float n = width; // Width of word in pixels - // ._. - n = (n / ww) * 4; // Number of points (./ \.) - n += 2; // Add two last points - int npoints = n; // Convert to int - - // Position of the pen to draw the lines - float penX = 0; - float penY = 0; - - if (npoints >= 3) { - XPoint *points = xmalloc(sizeof(XPoint) * (npoints + 1)); - - // First point (Starts with the word bounds) - penX = winx; - switch (getSlope(winx, 0, ww)) { - case UNDERCURL_SLOPE_ASCENDING: - penY = wy + wh/2.f - marginStart; - break; - case UNDERCURL_SLOPE_TOP_CAP: - penY = wy; - break; - case UNDERCURL_SLOPE_DESCENDING: - penY = wy + marginStart; - break; - case UNDERCURL_SLOPE_BOTTOM_CAP: - penY = wy + wh/2.f; - break; - } - points[0].x = penX; - points[0].y = penY; - - // Second point (Goes back to the absolute point coordinates) - switch (getSlope(winx, 1, ww)) { - case UNDERCURL_SLOPE_ASCENDING: - penX += ww * (1.f/6.f) - marginStart; - penY += 0; - break; - case UNDERCURL_SLOPE_TOP_CAP: - penX += ww * (2.f/6.f) - marginStart; - penY += -wh/2.f + marginStart; - break; - case UNDERCURL_SLOPE_DESCENDING: - penX += ww * (1.f/6.f) - marginStart; - penY += 0; - break; - case UNDERCURL_SLOPE_BOTTOM_CAP: - penX += ww * (2.f/6.f) - marginStart; - penY += -marginStart + wh/2.f; - break; - } - points[1].x = penX; - points[1].y = penY; - - // The rest of the points - for (int i = 2; i < npoints; i++) { - switch (getSlope(winx, i, ww)) { - case UNDERCURL_SLOPE_ASCENDING: - case UNDERCURL_SLOPE_DESCENDING: - penX += ww * (1.f/6.f); - penY += 0; - break; - case UNDERCURL_SLOPE_TOP_CAP: - penX += ww * (2.f/6.f); - penY += -wh / 2.f; - break; - case UNDERCURL_SLOPE_BOTTOM_CAP: - penX += ww * (2.f/6.f); - penY += wh / 2.f; - break; - } - points[i].x = penX; - points[i].y = penY; - } - - // End - float waveLength = penX - winx; - if (waveLength < width) { // Add a bonus point? - int marginEnd = width - waveLength; - penX += marginEnd; - switch(getSlope(winx, npoints, ww)) { - case UNDERCURL_SLOPE_ASCENDING: - case UNDERCURL_SLOPE_DESCENDING: - //penY += 0; - break; - case UNDERCURL_SLOPE_TOP_CAP: - penY += -marginEnd; - break; - case UNDERCURL_SLOPE_BOTTOM_CAP: - penY += marginEnd; - break; - } - - points[npoints].x = penX; - points[npoints].y = penY; - - npoints++; - } else if (waveLength > width) { // Is last point too far? - int marginEnd = waveLength - width; - points[npoints-1].x -= marginEnd; - switch(getSlope(winx, npoints-1, ww)) { - case UNDERCURL_SLOPE_TOP_CAP: - points[npoints-1].y += marginEnd; - break; - case UNDERCURL_SLOPE_BOTTOM_CAP: - points[npoints-1].y -= marginEnd; - break; - default: - break; - } - } - - // Draw the lines - XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points, npoints, - CoordModeOrigin); - - // Draw a second underline with an offset of 1 pixel - if ( ((win.ch / (widthThreshold/2)) % 2)) { - for (int i = 0; i < npoints; i++) - points[i].x++; - - XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points, - npoints, CoordModeOrigin); - } - - // Free resources - free(points); - } -#endif - } - - XFreeGC(xw.dpy, ugc); - + XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1, + width, 1); } if (base.mode & ATTR_STRUCK) { @@ -2151,7 +1520,6 @@ void xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) { Color drawcol; - XRenderColor colbg; /* remove the old cursor */ if (selected(ox, oy)) @@ -2164,7 +1532,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|ATTR_BOXDRAW; + g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE; if (IS_SET(MODE_REVERSE)) { g.mode |= ATTR_REVERSE; @@ -2180,21 +1548,11 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) if (selected(cx, cy)) { g.fg = defaultfg; g.bg = defaultrcs; - } else if (!(og.mode & ATTR_REVERSE)) { - unsigned long col = g.bg; - g.bg = g.fg; - g.fg = col; - } - - if (IS_TRUECOL(g.bg)) { - colbg.alpha = 0xffff; - colbg.red = TRUERED(g.bg); - colbg.green = TRUEGREEN(g.bg); - colbg.blue = TRUEBLUE(g.bg); - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &drawcol); } else { - drawcol = dc.col[g.bg]; + g.fg = defaultbg; + g.bg = defaultcs; } + drawcol = dc.col[g.bg]; } /* draw the new one */ @@ -2211,35 +1569,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, - win.hborderpx + cx * win.cw, - win.vborderpx + (cy + 1) * win.ch - \ + borderpx + cx * win.cw, + borderpx + (cy + 1) * win.ch - \ cursorthickness, win.cw, cursorthickness); break; case 5: /* Blinking bar */ case 6: /* Steady bar */ XftDrawRect(xw.draw, &drawcol, - win.hborderpx + cx * win.cw, - win.vborderpx + cy * win.ch, + borderpx + cx * win.cw, + borderpx + cy * win.ch, cursorthickness, win.ch); break; } } else { XftDrawRect(xw.draw, &drawcol, - win.hborderpx + cx * win.cw, - win.vborderpx + cy * win.ch, + borderpx + cx * win.cw, + borderpx + cy * win.ch, win.cw - 1, 1); XftDrawRect(xw.draw, &drawcol, - win.hborderpx + cx * win.cw, - win.vborderpx + cy * win.ch, + borderpx + cx * win.cw, + borderpx + cy * win.ch, 1, win.ch - 1); XftDrawRect(xw.draw, &drawcol, - win.hborderpx + (cx + 1) * win.cw - 1, - win.vborderpx + cy * win.ch, + borderpx + (cx + 1) * win.cw - 1, + borderpx + cy * win.ch, 1, win.ch - 1); XftDrawRect(xw.draw, &drawcol, - win.hborderpx + cx * win.cw, - win.vborderpx + (cy + 1) * win.ch - 1, + borderpx + cx * win.cw, + borderpx + (cy + 1) * win.ch - 1, win.cw, 1); } } @@ -2259,6 +1617,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; @@ -2268,30 +1629,13 @@ xseticontitle(char *p) } void -xfreetitlestack(void) +xsettitle(char *p) { - for (int i = 0; i < LEN(titlestack); i++) { - free(titlestack[i]); - titlestack[i] = NULL; - } -} + XTextProperty prop; + DEFAULT(p, opt_title); -void -xsettitle(char *p, int pop) -{ - XTextProperty prop; - - free(titlestack[tstki]); - if (pop) { - titlestack[tstki] = NULL; - tstki = (tstki - 1 + TITLESTACKSIZE) % TITLESTACKSIZE; - p = titlestack[tstki] ? titlestack[tstki] : opt_title; - } else if (p) { - titlestack[tstki] = xstrdup(p); - } else { - titlestack[tstki] = NULL; + if (p[0] == '\0') p = opt_title; - } if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, &prop) != Success) @@ -2301,16 +1645,6 @@ xsettitle(char *p, int pop) XFree(prop.value); } -void -xpushtitle(void) -{ - int tstkin = (tstki + 1) % TITLESTACKSIZE; - - free(titlestack[tstkin]); - titlestack[tstkin] = titlestack[tstki] ? xstrdup(titlestack[tstki]) : NULL; - tstki = tstkin; -} - int xstartdraw(void) { @@ -2393,8 +1727,6 @@ unmap(XEvent *ev) void xsetpointermotion(int set) { - if (!set && !xw.pointerisvisible) - return; MODBIT(xw.attrs.event_mask, set, PointerMotionMask); XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); } @@ -2427,144 +1759,6 @@ xseturgency(int add) XFree(h); } -static void -cachemonitorinfo() -{ - int prev_num = monitors_num; - MonitorInfo *prev_info = monitors_info; - XRRMonitorInfo *xmonitors = XRRGetMonitors(xw.dpy, XRootWindow(xw.dpy, xw.scr), 1, &monitors_num); - if (!monitors_num) - die("xrandr found no monitors"); - - monitors_info = xmalloc(monitors_num * sizeof(MonitorInfo)); - - for (int i = 0; i < monitors_num; ++i) { - XRRMonitorInfo *xm = &xmonitors[i]; - MonitorInfo *m = &monitors_info[i]; - - m->name = xm->name; - m->x = xm->x; - m->y = xm->y; - m->w = xm->width; - m->h = xm->height; - - float px_mm = ((float)m->w / xm->mwidth + (float)m->h / xm->mheight) / 2; - float px_pt = 25.4 * px_mm / 72; - m->defaultfontsize = defaultrelfontsize * px_pt; - - // Override defaultfontsize (dpi) by user config - char *name = XGetAtomName(xw.dpy, xm->name); - for (int j = 0; j < LEN(monitors_config); ++j) - if (!strcmp(name, monitors_config[j].name)) { - m->defaultfontsize = monitors_config[j].defaultfontsize; - if (m->defaultfontsize < 0) - m->defaultfontsize *= -px_pt; - break; - } - // fprintf(stderr, "%s: %fpx, %f\n", name, m->defaultfontsize, m->usedfontsize); - XFree(name); - - // Restore usedfontsize (zoom) after re-cache for monitors with the same name - m->usedfontsize = m->defaultfontsize; - for (int j = 0; j < prev_num; ++j) - if (prev_info[j].name == m->name) { - m->usedfontsize = prev_info[j].usedfontsize; - break; - } - } - - XRRFreeMonitors(xmonitors); - free(prev_info); -} - -static int -getmonitorindex_threshold(int w, int h, int x, int y) -{ - int mindex = -1; - float fontsize = 0; - int thresholdarea = winmovethreshold * w * h; - - for (int i = 0; i < monitors_num; ++i) { - MonitorInfo *m = &monitors_info[i]; - int overlap_w = MAX(0, MIN(x + w, m->x + m->w) - MAX(x, m->x)); - int overlap_h = MAX(0, MIN(y + h, m->y + m->h) - MAX(y, m->y)); - int area = overlap_w * overlap_h; - // Choose monitor with largest dpi (defaultfontsize) - // from all "mirrored"/overlapped (e.g. projector) - if (area >= thresholdarea && fontsize < m->defaultfontsize) { - fontsize = m->defaultfontsize; - mindex = i; - } - } - return mindex; -} - -static int -getmonitorindex_nearest(int w, int h, int x, int y) -{ - int mindex = -1; - float fontsize = 0; - int overlaparea = 0; - - for (int i = 0; i < monitors_num; ++i) { - MonitorInfo *m = &monitors_info[i]; - int overlap_w = MAX(0, MIN(x + w, m->x + m->w) - MAX(x, m->x)); - int overlap_h = MAX(0, MIN(y + h, m->y + m->h) - MAX(y, m->y)); - int area = overlap_w * overlap_h; - // Choose monitor with largest overlapping area - // e.g. when "st" is initially spawned in-between monitors - if (area > overlaparea) { - overlaparea = area; - mindex = i; - } - } - return mindex; -} - -static void -adjustmonitorfontsize(int mindex) -{ - if (mindex < 0 || prev_mindex == mindex) - return; - // Save zoom of current monitor before switching - if (prev_mindex >= 0) - monitors_info[prev_mindex].usedfontsize = usedfontsize; - - defaultfontsize = monitors_info[mindex].defaultfontsize; - // fprintf(stderr, "Crossing: %fpx\n", defaultfontsize); - - // NOTE: do nothing if font size differs by less than 1% - double fontsize = monitors_info[mindex].usedfontsize; - double delta = 0.01 * usedfontsize; - if (!BETWEEN(fontsize - usedfontsize, -delta, delta)) { - // fprintf(stderr, "Adjusted: %fpx\n", fontsize); - xunloadfonts(); - xloadfonts(usedfont, fontsize); - } - prev_mindex = mindex; -} - -void -refreshxrandr(const Arg *dummy) -{ - // Reset index to detect change of window association on "xrandr ... --primary" - // otherwise: zoom won't be saved on switching and new font size won't be loaded - // CRIT!!! event from xrandr may place another monitor into same index - if (prev_mindex >= 0) - monitors_info[prev_mindex].usedfontsize = usedfontsize; - prev_mindex = -1; - - XWindowAttributes xattr = {0}; - cachemonitorinfo(); - XGetWindowAttributes(xw.dpy, xw.win, &xattr); - - int mindex = getmonitorindex_threshold(xattr.width, xattr.height, xattr.x, xattr.y); - if (mindex < 0) - mindex = getmonitorindex_nearest(xattr.width, xattr.height, xattr.x, xattr.y); - adjustmonitorfontsize(mindex); -} - - void xbell(void) { @@ -2589,22 +1783,12 @@ 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(); - } } } @@ -2655,26 +1839,23 @@ void kpress(XEvent *ev) { XKeyEvent *e = &ev->xkey; - KeySym ksym; + KeySym ksym = NoSymbol; char buf[64], *customkey; int len; Rune c; Status status; Shortcut *bp; - if (xw.pointerisvisible) { - XDefineCursor(xw.dpy, xw.win, xw.bpointer); - xsetpointermotion(1); - xw.pointerisvisible = 0; - } - 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)) { @@ -2730,23 +1911,12 @@ cmessage(XEvent *e) void resize(XEvent *e) { - // BAD: no resize on monitor plug/unplug/reconfigure -- until window itself is kept in the same place - // NOTE: no resize event on zoomabs() - // fprintf(stderr, "Resize: %dx%d+%d+%d\n", - // e->xconfigure.width, e->xconfigure.height, e->xconfigure.x, e->xconfigure.y); - - adjustmonitorfontsize(getmonitorindex_threshold( - e->xconfigure.width, e->xconfigure.height, e->xconfigure.x, e->xconfigure.y)); - if (e->xconfigure.width == win.w && e->xconfigure.height == win.h) return; cresize(e->xconfigure.width, e->xconfigure.height); } -int tinsync(uint); -int ttyread_pending(); - void run(void) { @@ -2773,22 +1943,6 @@ run(void) } } while (ev.type != MapNotify); - int rr_event_base, rr_error_base, rr_major, rr_minor; - if (!XRRQueryExtension (xw.dpy, &rr_event_base, &rr_error_base) || - !XRRQueryVersion (xw.dpy, &rr_major, &rr_minor) || - rr_major < 1 || (rr_major == 1 && rr_minor < 5)) - { - die("RandR 1.5 extension isn't available\n"); - } - XRRSelectInput(xw.dpy, xw.win, RRCrtcChangeNotifyMask); - - // WARN: can query actual window size/pos only after window is mapped and its width/height are adjusted by WM - // * x/y are WM-dependent and can't be determined beforehand anyway - // * defaultfontsize isn't available until font is loaded and actual Fc*() size queried - // BAD: fonts on startup are always reloaded -- how to specify their size beforehand ? - FcPatternGetDouble(dc.font.match->pattern, FC_SIZE, 0, &defaultrelfontsize); - refreshxrandr(0); - ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd); cresize(w, h); @@ -2797,7 +1951,7 @@ run(void) FD_SET(ttyfd, &rfd); FD_SET(xfd, &rfd); - if (XPending(xw.dpy) || ttyread_pending()) + if (XPending(xw.dpy)) timeout = 0; /* existing events might not set xfd */ seltv.tv_sec = timeout / 1E3; @@ -2811,8 +1965,7 @@ run(void) } clock_gettime(CLOCK_MONOTONIC, &now); - int ttyin = FD_ISSET(ttyfd, &rfd) || ttyread_pending(); - if (ttyin) + if (FD_ISSET(ttyfd, &rfd)) ttyread(); xev = 0; @@ -2821,16 +1974,6 @@ run(void) XNextEvent(xw.dpy, &ev); if (XFilterEvent(&ev, None)) continue; - if (LASTEvent <= ev.type) { - if (rr_event_base + RRNotify == ev.type && - RRNotify_CrtcChange == ((XRRNotifyEvent *)&ev)->subtype) - { - XRRUpdateConfiguration(&ev); - // fprintf(stderr, "Monitor change: %d > %d\n", rr_event_base, LASTEvent); - refreshxrandr(0); - } - continue; - } if (handler[ev.type]) (handler[ev.type])(&ev); } @@ -2846,7 +1989,7 @@ run(void) * maximum latency intervals during `cat huge.txt`, and perfect * sync with periodic updates from animations/key-repeats/etc. */ - if (ttyin || xev) { + if (FD_ISSET(ttyfd, &rfd) || xev) { if (!drawing) { trigger = now; drawing = 1; @@ -2857,18 +2000,6 @@ run(void) continue; /* we have time, try to find idle */ } - if (tinsync(su_timeout)) { - /* - * on synchronized-update draw-suspension: don't reset - * drawing so that we draw ASAP once we can (just after - * ESU). it won't be too soon because we already can - * draw now but we skip. we set timeout > 0 to draw on - * SU-timeout even without new content. - */ - timeout = minlatency; - continue; - } - /* idle detected or maxlatency exhausted -> draw */ timeout = -1; if (blinktimeout && tattrset(ATTR_BLINK)) { @@ -2889,59 +2020,6 @@ run(void) } } -int -resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst) -{ - char **sdst = dst; - int *idst = dst; - float *fdst = dst; - - char fullname[256]; - char fullclass[256]; - char *type; - XrmValue ret; - - snprintf(fullname, sizeof(fullname), "%s.%s", - opt_name ? opt_name : "st", name); - snprintf(fullclass, sizeof(fullclass), "%s.%s", - opt_class ? opt_class : "St", name); - fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0'; - - XrmGetResource(db, fullname, fullclass, &type, &ret); - if (ret.addr == NULL || strncmp("String", type, 64)) - return 1; - - switch (rtype) { - case STRING: - *sdst = ret.addr; - break; - case INTEGER: - *idst = strtoul(ret.addr, NULL, 10); - break; - case FLOAT: - *fdst = strtof(ret.addr, NULL); - break; - } - return 0; -} - -void -config_init(void) -{ - char *resm; - XrmDatabase db; - ResourcePref *p; - - XrmInitialize(); - resm = XResourceManagerString(xw.dpy); - if (!resm) - return; - - db = XrmGetStringDatabase(resm); - for (p = resources; p < resources + LEN(resources); p++) - resource_load(db, p->name, p->type, p->dst); -} - void usage(void) { @@ -2966,9 +2044,6 @@ main(int argc, char *argv[]) case 'a': allowaltscreen = 0; break; - case 'A': - opt_alpha = EARGF(usage()); - break; case 'c': opt_class = EARGF(usage()); break; @@ -3005,11 +2080,6 @@ main(int argc, char *argv[]) case 'v': die("%s " VERSION "\n", argv0); break; - case 'z': - defaultfontsize = strtod(EARGF(usage()), NULL); - if (!(defaultfontsize > 0)) - usage(); - break; default: usage(); } ARGEND; @@ -3023,14 +2093,8 @@ run: setlocale(LC_CTYPE, ""); XSetLocaleModifiers(""); - - if(!(xw.dpy = XOpenDisplay(NULL))) - die("Can't open display\n"); - - config_init(); cols = MAX(cols, 1); rows = MAX(rows, 1); - defaultbg = MAX(LEN(colorname), 256); tnew(cols, rows); xinit(cols, rows); xsetenv(); |