summaryrefslogtreecommitdiff
path: root/x.c
diff options
context:
space:
mode:
authorzachir <zachir@librem.one>2023-02-20 01:09:42 -0600
committerzachir <zachir@librem.one>2023-02-20 01:09:42 -0600
commitf5878b3ffbef39b69f93f4c18549640372f87077 (patch)
treed421e4824bdbf66ebf89a19b2b26b279f4c6b0e8 /x.c
parent3f9b30ef78af7c80e55d2e9f111212a432544e2e (diff)
initialize branch at st 0.9 upstream
Diffstat (limited to 'x.c')
-rw-r--r--x.c485
1 files changed, 115 insertions, 370 deletions
diff --git a/x.c b/x.c
index 5f8c2b6..2a3bd38 100644
--- a/x.c
+++ b/x.c
@@ -14,14 +14,11 @@
#include <X11/keysym.h>
#include <X11/Xft/Xft.h>
#include <X11/XKBlib.h>
-#include <X11/Xresource.h>
char *argv0;
#include "arg.h"
-#include "icon.h"
#include "st.h"
#include "win.h"
-#include "hb.h"
/* types used in config.h */
typedef struct {
@@ -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,19 +45,6 @@ typedef struct {
signed char appcursor; /* application cursor */
} Key;
-/* 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
@@ -80,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
@@ -101,10 +81,8 @@ 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 cyo; /* char y offset */
int mode; /* window state/mode flags */
int cursor; /* cursor style */
} TermWindow;
@@ -115,7 +93,7 @@ typedef struct {
Window win;
Drawable buf;
GlyphFontSpec *specbuf; /* font spec buffer used for rendering */
- Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmicon, netwmpid;
+ Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid;
struct {
XIM xim;
XIC xic;
@@ -125,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;
@@ -185,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);
@@ -208,6 +178,7 @@ static void bpress(XEvent *);
static void bmotion(XEvent *);
static void propnotify(XEvent *);
static void selnotify(XEvent *);
+static void selclear_(XEvent *);
static void selrequest(XEvent *);
static void setsel(char *, Time);
static void mousesel(XEvent *, int);
@@ -249,8 +220,6 @@ 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 {
@@ -274,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;
@@ -284,7 +252,7 @@ static char *opt_line = NULL;
static char *opt_name = NULL;
static char *opt_title = NULL;
-static int oldbutton = 3; /* button event on startup: 3 = release */
+static uint buttons; /* bit field of pressed buttons */
void
clipcopy(const Arg *dummy)
@@ -338,7 +306,6 @@ zoomabs(const Arg *arg)
{
xunloadfonts();
xloadfonts(usedfont, arg->f);
- xloadsparefonts();
cresize(0, 0);
redraw();
xhints();
@@ -364,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;
}
@@ -372,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;
}
@@ -397,61 +364,68 @@ mousesel(XEvent *e, int done)
void
mousereport(XEvent *e)
{
- int len, x = evcol(e), y = evrow(e),
- button = e->xbutton.button, state = e->xbutton.state;
+ int len, btn, code;
+ int x = evcol(e), y = evrow(e);
+ int state = e->xbutton.state;
char buf[40];
static int ox, oy;
- /* from urxvt */
- if (e->xbutton.type == MotionNotify) {
+ if (e->type == MotionNotify) {
if (x == ox && y == oy)
return;
if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY))
return;
- /* MOUSE_MOTION: no reporting if no button is pressed */
- if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3)
+ /* MODE_MOUSEMOTION: no reporting if no button is pressed */
+ if (IS_SET(MODE_MOUSEMOTION) && buttons == 0)
return;
-
- button = oldbutton + 32;
- ox = x;
- oy = y;
+ /* Set btn to lowest-numbered pressed button, or 12 if no
+ * buttons are pressed. */
+ for (btn = 1; btn <= 11 && !(buttons & (1<<(btn-1))); btn++)
+ ;
+ code = 32;
} else {
- if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) {
- button = 3;
- } else {
- button -= Button1;
- if (button >= 7)
- button += 128 - 7;
- else if (button >= 3)
- button += 64 - 3;
- }
- if (e->xbutton.type == ButtonPress) {
- oldbutton = button;
- ox = x;
- oy = y;
- } else if (e->xbutton.type == ButtonRelease) {
- oldbutton = 3;
+ btn = e->xbutton.button;
+ /* Only buttons 1 through 11 can be encoded */
+ if (btn < 1 || btn > 11)
+ return;
+ if (e->type == ButtonRelease) {
/* MODE_MOUSEX10: no button release reporting */
if (IS_SET(MODE_MOUSEX10))
return;
- if (button == 64 || button == 65)
+ /* Don't send release events for the scroll wheel */
+ if (btn == 4 || btn == 5)
return;
}
+ code = 0;
}
+ ox = x;
+ oy = y;
+
+ /* Encode btn into code. If no button is pressed for a motion event in
+ * MODE_MOUSEMANY, then encode it as a release. */
+ if ((!IS_SET(MODE_MOUSESGR) && e->type == ButtonRelease) || btn == 12)
+ code += 3;
+ else if (btn >= 8)
+ code += 128 + btn - 8;
+ else if (btn >= 4)
+ code += 64 + btn - 4;
+ else
+ code += btn - 1;
+
if (!IS_SET(MODE_MOUSEX10)) {
- button += ((state & ShiftMask ) ? 4 : 0)
- + ((state & Mod4Mask ) ? 8 : 0)
- + ((state & ControlMask) ? 16 : 0);
+ code += ((state & ShiftMask ) ? 4 : 0)
+ + ((state & Mod1Mask ) ? 8 : 0) /* meta key: alt */
+ + ((state & ControlMask) ? 16 : 0);
}
if (IS_SET(MODE_MOUSESGR)) {
len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c",
- button, x+1, y+1,
- e->xbutton.type == ButtonRelease ? 'm' : 'M');
+ code, x+1, y+1,
+ e->type == ButtonRelease ? 'm' : 'M');
} else if (x < 223 && y < 223) {
len = snprintf(buf, sizeof(buf), "\033[M%c%c%c",
- 32+button, 32+x+1, 32+y+1);
+ 32+code, 32+x+1, 32+y+1);
} else {
return;
}
@@ -481,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));
@@ -495,9 +468,13 @@ mouseaction(XEvent *e, uint release)
void
bpress(XEvent *e)
{
+ int btn = e->xbutton.button;
struct timespec now;
int snap;
+ if (1 <= btn && btn <= 11)
+ buttons |= 1 << (btn-1);
+
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
mousereport(e);
return;
@@ -506,7 +483,7 @@ bpress(XEvent *e)
if (mouseaction(e, 0))
return;
- if (e->xbutton.button == Button1) {
+ if (btn == Button1) {
/*
* If the user clicks below predefined timeouts specific
* snapping behaviour is exposed.
@@ -634,6 +611,12 @@ xclipcopy(void)
}
void
+selclear_(XEvent *e)
+{
+ selclear();
+}
+
+void
selrequest(XEvent *e)
{
XSelectionRequestEvent *xsre;
@@ -703,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
@@ -715,6 +697,11 @@ xsetsel(char *str)
void
brelease(XEvent *e)
{
+ int btn = e->xbutton.button;
+
+ if (1 <= btn && btn <= 11)
+ buttons &= ~(1 << (btn-1));
+
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
mousereport(e);
return;
@@ -722,20 +709,13 @@ brelease(XEvent *e)
if (mouseaction(e, 1))
return;
- if (e->xbutton.button == Button1)
+ if (btn == Button1)
mousesel(e, 1);
}
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;
@@ -759,9 +739,6 @@ 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);
@@ -775,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);
@@ -835,13 +812,6 @@ 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;
}
@@ -887,16 +857,10 @@ xclear(int x1, int y1, int x2, int y2)
}
void
-xclearwin(void)
-{
- xclear(0, 0, win.w, win.h);
-}
-
-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;
@@ -905,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;
@@ -1067,7 +1031,6 @@ xloadfonts(const char *fontstr, double fontsize)
/* Setting character width and height. */
win.cw = ceilf(dc.font.width * cwscale);
win.ch = ceilf(dc.font.height * chscale);
- win.cyo = ceilf(dc.font.height * (chscale - 1) / 2);
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
@@ -1087,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)
{
@@ -1194,9 +1062,6 @@ xunloadfont(Font *f)
void
xunloadfonts(void)
{
- /* Clear Harfbuzz font cache. */
- hbunloadfonts();
-
/* Free the loaded fonts in the font cache. */
while (frclen > 0)
XftFontClose(xw.dpy, frc[--frclen].font);
@@ -1265,25 +1130,15 @@ void
xinit(int cols, int rows)
{
XGCValues gcvalues;
+ Cursor cursor;
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())
@@ -1292,16 +1147,13 @@ xinit(int cols, int rows)
usedfont = (opt_font == NULL)? font : opt_font;
xloadfonts(usedfont, 0);
- /* spare fonts */
- xloadsparefonts();
-
/* 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)
@@ -1316,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);
@@ -1341,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;
@@ -1357,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, &mousebg, 0, 0);
+ XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg);
xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
@@ -1368,10 +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);
- xw.netwmicon = XInternAtom(xw.dpy, "_NET_WM_ICON", False);
- XChangeProperty(xw.dpy, xw.win, xw.netwmicon, XA_CARDINAL, 32,
- PropModeReplace, (uchar *)&icon, LEN(icon));
-
xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32,
PropModeReplace, (uchar *)&thispid, 1);
@@ -1394,7 +1242,7 @@ xinit(int cols, int rows)
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;
@@ -1407,13 +1255,13 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
FcCharSet *fccharset;
int i, f, numspecs = 0;
- for (i = 0, xp = winx, yp = winy + font->ascent + win.cyo; i < len; ++i) {
+ for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
/* Fetch rune and mode for current glyph. */
rune = glyphs[i].u;
mode = glyphs[i].mode;
/* Skip dummy wide-character spacing. */
- if (mode & ATTR_WDUMMY)
+ if (mode == ATTR_WDUMMY)
continue;
/* Determine font for glyph if different from previous glyph. */
@@ -1432,7 +1280,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
font = &dc.bfont;
frcflags = FRC_BOLD;
}
- yp = winy + font->ascent + win.cyo;
+ yp = winy + font->ascent;
}
/* Lookup character index with default font. */
@@ -1520,9 +1368,6 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
numspecs++;
}
- /* Harfbuzz transformation for ligatures. */
- hbtransform(specs, glyphs, len, x, y);
-
return numspecs;
}
@@ -1530,7 +1375,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 = 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;
@@ -1620,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.vborderpx,
+ 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. */
@@ -1648,12 +1493,12 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
/* Render underline and strikethrough. */
if (base.mode & ATTR_UNDERLINE) {
- XftDrawRect(xw.draw, fg, winx, winy + win.cyo + dc.font.ascent + 1,
+ XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1,
width, 1);
}
if (base.mode & ATTR_STRUCK) {
- XftDrawRect(xw.draw, fg, winx, winy + win.cyo + 2 * dc.font.ascent / 3,
+ XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3,
width, 1);
}
@@ -1672,17 +1517,14 @@ xdrawglyph(Glyph g, int x, int y)
}
void
-xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int len)
+xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
{
Color drawcol;
/* remove the old cursor */
if (selected(ox, oy))
og.mode ^= ATTR_REVERSE;
-
- /* Redraw the line where cursor was previously.
- * It will restore the ligatures broken by the cursor. */
- xdrawline(line, 0, oy, len);
+ xdrawglyph(og, ox, oy);
if (IS_SET(MODE_HIDE))
return;
@@ -1727,35 +1569,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int le
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);
}
}
@@ -1783,51 +1625,23 @@ xseticontitle(char *p)
XFree(prop.value);
}
-void xfreetitlestack(void)
-{
- for (int i = 0; i < LEN(titlestack); i++) {
- free(titlestack[i]);
- titlestack[i] = NULL;
- }
-}
-
void
-xsettitle(char *p, int pop)
+xsettitle(char *p)
{
XTextProperty prop;
+ DEFAULT(p, opt_title);
- 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;
- p = opt_title;
- }
-
- Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, &prop);
+ if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
+ &prop) != Success)
+ return;
XSetWMName(xw.dpy, xw.win, &prop);
XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname);
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)
{
- if (IS_SET(MODE_VISIBLE))
- XCopyArea(xw.dpy, xw.win, xw.buf, dc.gc, 0, 0, win.w, win.h, 0, 0);
return IS_SET(MODE_VISIBLE);
}
@@ -1907,8 +1721,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);
}
@@ -2028,12 +1840,6 @@ kpress(XEvent *ev)
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;
@@ -2205,59 +2011,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)
{
@@ -2282,9 +2035,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;
@@ -2334,11 +2084,6 @@ 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);
tnew(cols, rows);