patched undercurl
parent
52fea633a1
commit
79381aad47
@ -0,0 +1,153 @@
|
|||||||
|
From a3cdd0753bf578cd4e6db7c6507481f3b5c38aea Mon Sep 17 00:00:00 2001
|
||||||
|
From: Steve Ward <planet36@gmail.com>
|
||||||
|
Date: Tue, 16 Nov 2021 14:15:06 -0500
|
||||||
|
Subject: [PATCH] Allow blinking cursor
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 19 +++++++++++++------
|
||||||
|
x.c | 47 +++++++++++++++++++++++++++++++++++------------
|
||||||
|
2 files changed, 48 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 6f05dce..1a5fed0 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -133,13 +133,20 @@ static unsigned int defaultcs = 256;
|
||||||
|
static unsigned int defaultrcs = 257;
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Default shape of cursor
|
||||||
|
- * 2: Block ("█")
|
||||||
|
- * 4: Underline ("_")
|
||||||
|
- * 6: Bar ("|")
|
||||||
|
- * 7: Snowman ("☃")
|
||||||
|
+ * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
|
||||||
|
+ * Default style of cursor
|
||||||
|
+ * 0: blinking block
|
||||||
|
+ * 1: blinking block (default)
|
||||||
|
+ * 2: steady block ("█")
|
||||||
|
+ * 3: blinking underline
|
||||||
|
+ * 4: steady underline ("_")
|
||||||
|
+ * 5: blinking bar
|
||||||
|
+ * 6: steady bar ("|")
|
||||||
|
+ * 7: blinking st cursor
|
||||||
|
+ * 8: steady st cursor
|
||||||
|
*/
|
||||||
|
-static unsigned int cursorshape = 2;
|
||||||
|
+static unsigned int cursorstyle = 1;
|
||||||
|
+static Rune stcursor = 0x2603; /* snowman ("☃") */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default columns and rows numbers
|
||||||
|
diff --git a/x.c b/x.c
|
||||||
|
index 89786b8..7d2447d 100644
|
||||||
|
--- a/x.c
|
||||||
|
+++ b/x.c
|
||||||
|
@@ -253,6 +253,7 @@ static char *opt_name = NULL;
|
||||||
|
static char *opt_title = NULL;
|
||||||
|
|
||||||
|
static int oldbutton = 3; /* button event on startup: 3 = release */
|
||||||
|
+static int cursorblinks = 0;
|
||||||
|
|
||||||
|
void
|
||||||
|
clipcopy(const Arg *dummy)
|
||||||
|
@@ -1529,29 +1530,44 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
|
||||||
|
/* draw the new one */
|
||||||
|
if (IS_SET(MODE_FOCUSED)) {
|
||||||
|
switch (win.cursor) {
|
||||||
|
- case 7: /* st extension */
|
||||||
|
- g.u = 0x2603; /* snowman (U+2603) */
|
||||||
|
+ default:
|
||||||
|
+ case 0: /* blinking block */
|
||||||
|
+ case 1: /* blinking block (default) */
|
||||||
|
+ if (IS_SET(MODE_BLINK))
|
||||||
|
+ break;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
- case 0: /* Blinking Block */
|
||||||
|
- case 1: /* Blinking Block (Default) */
|
||||||
|
- case 2: /* Steady Block */
|
||||||
|
+ case 2: /* steady block */
|
||||||
|
xdrawglyph(g, cx, cy);
|
||||||
|
break;
|
||||||
|
- case 3: /* Blinking Underline */
|
||||||
|
- case 4: /* Steady Underline */
|
||||||
|
+ case 3: /* blinking underline */
|
||||||
|
+ if (IS_SET(MODE_BLINK))
|
||||||
|
+ break;
|
||||||
|
+ /* FALLTHROUGH */
|
||||||
|
+ case 4: /* steady underline */
|
||||||
|
XftDrawRect(xw.draw, &drawcol,
|
||||||
|
borderpx + cx * win.cw,
|
||||||
|
borderpx + (cy + 1) * win.ch - \
|
||||||
|
cursorthickness,
|
||||||
|
win.cw, cursorthickness);
|
||||||
|
break;
|
||||||
|
- case 5: /* Blinking bar */
|
||||||
|
- case 6: /* Steady bar */
|
||||||
|
+ case 5: /* blinking bar */
|
||||||
|
+ if (IS_SET(MODE_BLINK))
|
||||||
|
+ break;
|
||||||
|
+ /* FALLTHROUGH */
|
||||||
|
+ case 6: /* steady bar */
|
||||||
|
XftDrawRect(xw.draw, &drawcol,
|
||||||
|
borderpx + cx * win.cw,
|
||||||
|
borderpx + cy * win.ch,
|
||||||
|
cursorthickness, win.ch);
|
||||||
|
break;
|
||||||
|
+ case 7: /* blinking st cursor */
|
||||||
|
+ if (IS_SET(MODE_BLINK))
|
||||||
|
+ break;
|
||||||
|
+ /* FALLTHROUGH */
|
||||||
|
+ case 8: /* steady st cursor */
|
||||||
|
+ g.u = stcursor;
|
||||||
|
+ xdrawglyph(g, cx, cy);
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
XftDrawRect(xw.draw, &drawcol,
|
||||||
|
@@ -1708,9 +1724,12 @@ xsetmode(int set, unsigned int flags)
|
||||||
|
int
|
||||||
|
xsetcursor(int cursor)
|
||||||
|
{
|
||||||
|
- if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */
|
||||||
|
+ if (!BETWEEN(cursor, 0, 8)) /* 7-8: st extensions */
|
||||||
|
return 1;
|
||||||
|
win.cursor = cursor;
|
||||||
|
+ cursorblinks = win.cursor == 0 || win.cursor == 1 ||
|
||||||
|
+ win.cursor == 3 || win.cursor == 5 ||
|
||||||
|
+ win.cursor == 7;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1954,6 +1973,10 @@ run(void)
|
||||||
|
if (FD_ISSET(ttyfd, &rfd) || xev) {
|
||||||
|
if (!drawing) {
|
||||||
|
trigger = now;
|
||||||
|
+ if (IS_SET(MODE_BLINK)) {
|
||||||
|
+ win.mode ^= MODE_BLINK;
|
||||||
|
+ }
|
||||||
|
+ lastblink = now;
|
||||||
|
drawing = 1;
|
||||||
|
}
|
||||||
|
timeout = (maxlatency - TIMEDIFF(now, trigger)) \
|
||||||
|
@@ -1964,7 +1987,7 @@ run(void)
|
||||||
|
|
||||||
|
/* idle detected or maxlatency exhausted -> draw */
|
||||||
|
timeout = -1;
|
||||||
|
- if (blinktimeout && tattrset(ATTR_BLINK)) {
|
||||||
|
+ if (blinktimeout && (cursorblinks || tattrset(ATTR_BLINK))) {
|
||||||
|
timeout = blinktimeout - TIMEDIFF(now, lastblink);
|
||||||
|
if (timeout <= 0) {
|
||||||
|
if (-timeout > blinktimeout) /* start visible */
|
||||||
|
@@ -2000,7 +2023,7 @@ main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
xw.l = xw.t = 0;
|
||||||
|
xw.isfixed = False;
|
||||||
|
- xsetcursor(cursorshape);
|
||||||
|
+ xsetcursor(cursorstyle);
|
||||||
|
|
||||||
|
ARGBEGIN {
|
||||||
|
case 'a':
|
||||||
|
--
|
||||||
|
2.34.0
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
diff --git a/x.c b/x.c
|
||||||
|
index e5f1737..5cabd60 100644
|
||||||
|
--- a/x.c
|
||||||
|
+++ b/x.c
|
||||||
|
@@ -673,6 +673,7 @@ setsel(char *str, Time t)
|
||||||
|
XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
|
||||||
|
if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
|
||||||
|
selclear();
|
||||||
|
+ clipcopy(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
@ -0,0 +1,271 @@
|
|||||||
|
From 10fa2b6aebceb3a12219ef25376297b063638bd9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julius Huelsmann <juliusHuelsmann@gmail.com>
|
||||||
|
Date: Fri, 31 Jul 2020 10:13:35 +0200
|
||||||
|
Subject: [PATCH] patch: focus
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 5 ++++
|
||||||
|
config.mk | 2 +-
|
||||||
|
st.c | 1 -
|
||||||
|
st.h | 2 ++
|
||||||
|
x.c | 72 +++++++++++++++++++++++++++++++++++++++-------------
|
||||||
|
5 files changed, 62 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 0895a1f..577d1f1 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -84,6 +84,9 @@ char *termname = "st-256color";
|
||||||
|
*/
|
||||||
|
unsigned int tabspaces = 8;
|
||||||
|
|
||||||
|
+/* bg opacity */
|
||||||
|
+float alpha = 0.8, alphaUnfocused = 0.6;
|
||||||
|
+
|
||||||
|
/* Terminal colors (16 first used in escape sequence) */
|
||||||
|
static const char *colorname[] = {
|
||||||
|
/* 8 normal colors */
|
||||||
|
@@ -111,6 +114,7 @@ static const char *colorname[] = {
|
||||||
|
/* more colors can be added after 255 to use with DefaultXX */
|
||||||
|
"#cccccc",
|
||||||
|
"#555555",
|
||||||
|
+ "black",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -122,6 +126,7 @@ unsigned int defaultfg = 7;
|
||||||
|
unsigned int defaultbg = 0;
|
||||||
|
static unsigned int defaultcs = 256;
|
||||||
|
static unsigned int defaultrcs = 257;
|
||||||
|
+unsigned int bg = 17, bgUnfocused = 16;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default shape of cursor
|
||||||
|
diff --git a/config.mk b/config.mk
|
||||||
|
index beafc35..ddc65ae 100644
|
||||||
|
--- a/config.mk
|
||||||
|
+++ b/config.mk
|
||||||
|
@@ -16,7 +16,7 @@ PKG_CONFIG = pkg-config
|
||||||
|
INCS = -I$(X11INC) \
|
||||||
|
`$(PKG_CONFIG) --cflags fontconfig` \
|
||||||
|
`$(PKG_CONFIG) --cflags freetype2`
|
||||||
|
-LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
|
||||||
|
+LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\
|
||||||
|
`$(PKG_CONFIG) --libs fontconfig` \
|
||||||
|
`$(PKG_CONFIG) --libs freetype2`
|
||||||
|
|
||||||
|
diff --git a/st.c b/st.c
|
||||||
|
index 0ce6ac2..c7f40c8 100644
|
||||||
|
--- a/st.c
|
||||||
|
+++ b/st.c
|
||||||
|
@@ -194,7 +194,6 @@ static void tsetscroll(int, int);
|
||||||
|
static void tswapscreen(void);
|
||||||
|
static void tsetmode(int, int, int *, int);
|
||||||
|
static int twrite(const char *, int, int);
|
||||||
|
-static void tfulldirt(void);
|
||||||
|
static void tcontrolcode(uchar );
|
||||||
|
static void tdectest(char );
|
||||||
|
static void tdefutf8(char);
|
||||||
|
diff --git a/st.h b/st.h
|
||||||
|
index d978458..44cb3fd 100644
|
||||||
|
--- a/st.h
|
||||||
|
+++ b/st.h
|
||||||
|
@@ -79,6 +79,7 @@ typedef union {
|
||||||
|
|
||||||
|
void die(const char *, ...);
|
||||||
|
void redraw(void);
|
||||||
|
+void tfulldirt(void);
|
||||||
|
void draw(void);
|
||||||
|
|
||||||
|
void printscreen(const Arg *);
|
||||||
|
@@ -122,3 +123,4 @@ extern char *termname;
|
||||||
|
extern unsigned int tabspaces;
|
||||||
|
extern unsigned int defaultfg;
|
||||||
|
extern unsigned int defaultbg;
|
||||||
|
+extern float alpha, alphaUnfocused;
|
||||||
|
diff --git a/x.c b/x.c
|
||||||
|
index e5f1737..a2e820f 100644
|
||||||
|
--- a/x.c
|
||||||
|
+++ b/x.c
|
||||||
|
@@ -105,6 +105,7 @@ typedef struct {
|
||||||
|
XSetWindowAttributes attrs;
|
||||||
|
int scr;
|
||||||
|
int isfixed; /* is fixed geometry? */
|
||||||
|
+ int depth; /* bit depth */
|
||||||
|
int l, t; /* left and top offset */
|
||||||
|
int gm; /* geometry mask */
|
||||||
|
} XWindow;
|
||||||
|
@@ -243,6 +244,7 @@ static char *usedfont = NULL;
|
||||||
|
static double usedfontsize = 0;
|
||||||
|
static double defaultfontsize = 0;
|
||||||
|
|
||||||
|
+static char *opt_alpha = NULL;
|
||||||
|
static char *opt_class = NULL;
|
||||||
|
static char **opt_cmd = NULL;
|
||||||
|
static char *opt_embed = NULL;
|
||||||
|
@@ -252,6 +254,8 @@ static char *opt_line = NULL;
|
||||||
|
static char *opt_name = NULL;
|
||||||
|
static char *opt_title = NULL;
|
||||||
|
|
||||||
|
+static int focused = 0;
|
||||||
|
+
|
||||||
|
static int oldbutton = 3; /* button event on startup: 3 = release */
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -734,7 +738,7 @@ xresize(int col, int row)
|
||||||
|
|
||||||
|
XFreePixmap(xw.dpy, xw.buf);
|
||||||
|
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
||||||
|
- DefaultDepth(xw.dpy, xw.scr));
|
||||||
|
+ xw.depth);
|
||||||
|
XftDrawChange(xw.draw, xw.buf);
|
||||||
|
xclear(0, 0, win.w, win.h);
|
||||||
|
|
||||||
|
@@ -772,28 +776,38 @@ xloadcolor(int i, const char *name, Color *ncolor)
|
||||||
|
return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+xloadalpha(void)
|
||||||
|
+{
|
||||||
|
+ float const usedAlpha = focused ? alpha : alphaUnfocused;
|
||||||
|
+ if (opt_alpha) alpha = strtof(opt_alpha, NULL);
|
||||||
|
+ dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * usedAlpha);
|
||||||
|
+ dc.col[defaultbg].pixel &= 0x00FFFFFF;
|
||||||
|
+ dc.col[defaultbg].pixel |= (unsigned char)(0xff * usedAlpha) << 24;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
xloadcols(void)
|
||||||
|
{
|
||||||
|
- int i;
|
||||||
|
static int loaded;
|
||||||
|
Color *cp;
|
||||||
|
|
||||||
|
- if (loaded) {
|
||||||
|
- for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
|
||||||
|
- XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
|
||||||
|
- } else {
|
||||||
|
- dc.collen = MAX(LEN(colorname), 256);
|
||||||
|
- dc.col = xmalloc(dc.collen * sizeof(Color));
|
||||||
|
+ if (!loaded) {
|
||||||
|
+ dc.collen = 1 + (defaultbg = MAX(LEN(colorname), 256));
|
||||||
|
+ dc.col = xmalloc((dc.collen) * sizeof(Color));
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (i = 0; i < dc.collen; i++)
|
||||||
|
+ for (int i = 0; i+1 < dc.collen; ++i)
|
||||||
|
if (!xloadcolor(i, NULL, &dc.col[i])) {
|
||||||
|
if (colorname[i])
|
||||||
|
die("could not allocate color '%s'\n", colorname[i]);
|
||||||
|
else
|
||||||
|
die("could not allocate color %d\n", i);
|
||||||
|
}
|
||||||
|
+ if (dc.collen) // cannot die, as the color is already loaded.
|
||||||
|
+ xloadcolor(focused ?bg :bgUnfocused, NULL, &dc.col[defaultbg]);
|
||||||
|
+
|
||||||
|
+ xloadalpha();
|
||||||
|
loaded = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1103,11 +1117,23 @@ xinit(int cols, int rows)
|
||||||
|
Window parent;
|
||||||
|
pid_t thispid = getpid();
|
||||||
|
XColor xmousefg, xmousebg;
|
||||||
|
+ XWindowAttributes attr;
|
||||||
|
+ XVisualInfo vis;
|
||||||
|
|
||||||
|
if (!(xw.dpy = XOpenDisplay(NULL)))
|
||||||
|
die("can't open display\n");
|
||||||
|
xw.scr = XDefaultScreen(xw.dpy);
|
||||||
|
- xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
||||||
|
+
|
||||||
|
+ if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) {
|
||||||
|
+ parent = XRootWindow(xw.dpy, xw.scr);
|
||||||
|
+ xw.depth = 32;
|
||||||
|
+ } else {
|
||||||
|
+ XGetWindowAttributes(xw.dpy, parent, &attr);
|
||||||
|
+ xw.depth = attr.depth;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis);
|
||||||
|
+ xw.vis = vis.visual;
|
||||||
|
|
||||||
|
/* font */
|
||||||
|
if (!FcInit())
|
||||||
|
@@ -1117,7 +1143,7 @@ xinit(int cols, int rows)
|
||||||
|
xloadfonts(usedfont, 0);
|
||||||
|
|
||||||
|
/* colors */
|
||||||
|
- xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
|
||||||
|
+ xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None);
|
||||||
|
xloadcols();
|
||||||
|
|
||||||
|
/* adjust fixed window geometry */
|
||||||
|
@@ -1137,19 +1163,15 @@ xinit(int cols, int rows)
|
||||||
|
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
|
||||||
|
xw.attrs.colormap = xw.cmap;
|
||||||
|
|
||||||
|
- if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
|
||||||
|
- parent = XRootWindow(xw.dpy, xw.scr);
|
||||||
|
xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
|
||||||
|
- win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
|
||||||
|
+ win.w, win.h, 0, xw.depth, InputOutput,
|
||||||
|
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
|
||||||
|
| CWEventMask | CWColormap, &xw.attrs);
|
||||||
|
|
||||||
|
memset(&gcvalues, 0, sizeof(gcvalues));
|
||||||
|
gcvalues.graphics_exposures = False;
|
||||||
|
- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
|
||||||
|
- &gcvalues);
|
||||||
|
- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
||||||
|
- DefaultDepth(xw.dpy, xw.scr));
|
||||||
|
+ xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth);
|
||||||
|
+ dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues);
|
||||||
|
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
|
||||||
|
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
||||||
|
|
||||||
|
@@ -1730,12 +1752,22 @@ focus(XEvent *ev)
|
||||||
|
xseturgency(0);
|
||||||
|
if (IS_SET(MODE_FOCUS))
|
||||||
|
ttywrite("\033[I", 3, 0);
|
||||||
|
+ if (!focused) {
|
||||||
|
+ focused = 1;
|
||||||
|
+ xloadcols();
|
||||||
|
+ tfulldirt();
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
if (xw.ime.xic)
|
||||||
|
XUnsetICFocus(xw.ime.xic);
|
||||||
|
win.mode &= ~MODE_FOCUSED;
|
||||||
|
if (IS_SET(MODE_FOCUS))
|
||||||
|
ttywrite("\033[O", 3, 0);
|
||||||
|
+ if (focused) {
|
||||||
|
+ focused = 0;
|
||||||
|
+ xloadcols();
|
||||||
|
+ tfulldirt();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1994,6 +2026,9 @@ main(int argc, char *argv[])
|
||||||
|
case 'a':
|
||||||
|
allowaltscreen = 0;
|
||||||
|
break;
|
||||||
|
+ case 'A':
|
||||||
|
+ opt_alpha = EARGF(usage());
|
||||||
|
+ break;
|
||||||
|
case 'c':
|
||||||
|
opt_class = EARGF(usage());
|
||||||
|
break;
|
||||||
|
@@ -2045,6 +2080,7 @@ run:
|
||||||
|
XSetLocaleModifiers("");
|
||||||
|
cols = MAX(cols, 1);
|
||||||
|
rows = MAX(rows, 1);
|
||||||
|
+ defaultbg = MAX(LEN(colorname), 256);
|
||||||
|
tnew(cols, rows);
|
||||||
|
xinit(cols, rows);
|
||||||
|
xsetenv();
|
||||||
|
--
|
||||||
|
2.28.0
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
diff a/st.c b/st.c (rejected hunks)
|
|
||||||
@@ -159,6 +161,7 @@ static void ttywriteraw(const char *, size_t);
|
|
||||||
|
|
||||||
static void csidump(void);
|
|
||||||
static void csihandle(void);
|
|
||||||
+static void readcolonargs(char **, int, int[][CAR_PER_ARG]);
|
|
||||||
static void csiparse(void);
|
|
||||||
static void csireset(void);
|
|
||||||
static int eschandle(uchar);
|
|
@ -1,361 +0,0 @@
|
|||||||
diff a/x.c b/x.c (rejected hunks)
|
|
||||||
@@ -1461,8 +1514,357 @@ 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 + dc.font.ascent + 1,
|
|
||||||
- width, 1);
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (base.mode & ATTR_STRUCK) {
|
|
Loading…
Reference in New Issue