summaryrefslogtreecommitdiff
path: root/x.c
diff options
context:
space:
mode:
Diffstat (limited to 'x.c')
-rw-r--r--x.c1110
1 files changed, 87 insertions, 1023 deletions
diff --git a/x.c b/x.c
index 8cbf815..bd23686 100644
--- a/x.c
+++ b/x.c
@@ -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();