Compare commits
11 Commits
ef0551932f
...
feat/xreso
Author | SHA1 | Date | |
---|---|---|---|
4bb9184a41 | |||
1478e0d6ed | |||
211964d56e | |||
f17abd25b3 | |||
7e8050cc62 | |||
e5e959835b | |||
68d1ad9b54 | |||
0008519903 | |||
72fd32736a | |||
baa9357e96 | |||
8629d9a1da |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.o
|
||||||
|
*.orig
|
3
FAQ
3
FAQ
@ -248,3 +248,6 @@ fonts:
|
|||||||
|
|
||||||
Please don't bother reporting this bug to st, but notify the upstream Xft
|
Please don't bother reporting this bug to st, but notify the upstream Xft
|
||||||
developers about fixing this bug.
|
developers about fixing this bug.
|
||||||
|
|
||||||
|
As of 2022-09-05 this now seems to be finally fixed in libXft 2.3.5:
|
||||||
|
https://gitlab.freedesktop.org/xorg/lib/libxft/-/blob/libXft-2.3.5/NEWS
|
||||||
|
36
config.def.h
36
config.def.h
@ -170,6 +170,42 @@ static unsigned int defaultattr = 11;
|
|||||||
*/
|
*/
|
||||||
static uint forcemousemod = ShiftMask;
|
static uint forcemousemod = ShiftMask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Xresources preferences to load at startup
|
||||||
|
*/
|
||||||
|
ResourcePref resources[] = {
|
||||||
|
{ "font", STRING, &font },
|
||||||
|
{ "color0", STRING, &colorname[0] },
|
||||||
|
{ "color1", STRING, &colorname[1] },
|
||||||
|
{ "color2", STRING, &colorname[2] },
|
||||||
|
{ "color3", STRING, &colorname[3] },
|
||||||
|
{ "color4", STRING, &colorname[4] },
|
||||||
|
{ "color5", STRING, &colorname[5] },
|
||||||
|
{ "color6", STRING, &colorname[6] },
|
||||||
|
{ "color7", STRING, &colorname[7] },
|
||||||
|
{ "color8", STRING, &colorname[8] },
|
||||||
|
{ "color9", STRING, &colorname[9] },
|
||||||
|
{ "color10", STRING, &colorname[10] },
|
||||||
|
{ "color11", STRING, &colorname[11] },
|
||||||
|
{ "color12", STRING, &colorname[12] },
|
||||||
|
{ "color13", STRING, &colorname[13] },
|
||||||
|
{ "color14", STRING, &colorname[14] },
|
||||||
|
{ "color15", STRING, &colorname[15] },
|
||||||
|
{ "background", STRING, &colorname[256] },
|
||||||
|
{ "foreground", STRING, &colorname[257] },
|
||||||
|
{ "cursorColor", STRING, &colorname[258] },
|
||||||
|
{ "termname", STRING, &termname },
|
||||||
|
{ "shell", STRING, &shell },
|
||||||
|
{ "minlatency", INTEGER, &minlatency },
|
||||||
|
{ "maxlatency", INTEGER, &maxlatency },
|
||||||
|
{ "blinktimeout", INTEGER, &blinktimeout },
|
||||||
|
{ "bellvolume", INTEGER, &bellvolume },
|
||||||
|
{ "tabspaces", INTEGER, &tabspaces },
|
||||||
|
{ "borderpx", INTEGER, &borderpx },
|
||||||
|
{ "cwscale", FLOAT, &cwscale },
|
||||||
|
{ "chscale", FLOAT, &chscale },
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal mouse shortcuts.
|
* Internal mouse shortcuts.
|
||||||
* Beware that overloading Button1 will disable the selection.
|
* Beware that overloading Button1 will disable the selection.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# st version
|
# st version
|
||||||
VERSION = 0.8.5
|
VERSION = 0.9
|
||||||
|
|
||||||
# Customize below to fit your system
|
# Customize below to fit your system
|
||||||
|
|
||||||
@ -30,6 +30,7 @@ STLDFLAGS = $(LIBS) $(LDFLAGS)
|
|||||||
#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \
|
#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \
|
||||||
# `$(PKG_CONFIG) --libs fontconfig` \
|
# `$(PKG_CONFIG) --libs fontconfig` \
|
||||||
# `$(PKG_CONFIG) --libs freetype2`
|
# `$(PKG_CONFIG) --libs freetype2`
|
||||||
|
#MANPREFIX = ${PREFIX}/man
|
||||||
|
|
||||||
# compiler and linker
|
# compiler and linker
|
||||||
# CC = c99
|
# CC = c99
|
||||||
|
110
st.c
110
st.c
@ -161,6 +161,7 @@ static void csidump(void);
|
|||||||
static void csihandle(void);
|
static void csihandle(void);
|
||||||
static void csiparse(void);
|
static void csiparse(void);
|
||||||
static void csireset(void);
|
static void csireset(void);
|
||||||
|
static void osc_color_response(int, int, int);
|
||||||
static int eschandle(uchar);
|
static int eschandle(uchar);
|
||||||
static void strdump(void);
|
static void strdump(void);
|
||||||
static void strhandle(void);
|
static void strhandle(void);
|
||||||
@ -938,7 +939,7 @@ ttyresize(int tw, int th)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ttyhangup()
|
ttyhangup(void)
|
||||||
{
|
{
|
||||||
/* Send SIGHUP to shell */
|
/* Send SIGHUP to shell */
|
||||||
kill(pid, SIGHUP);
|
kill(pid, SIGHUP);
|
||||||
@ -1768,11 +1769,18 @@ csihandle(void)
|
|||||||
case 'm': /* SGR -- Terminal attribute (color) */
|
case 'm': /* SGR -- Terminal attribute (color) */
|
||||||
tsetattr(csiescseq.arg, csiescseq.narg);
|
tsetattr(csiescseq.arg, csiescseq.narg);
|
||||||
break;
|
break;
|
||||||
case 'n': /* DSR – Device Status Report (cursor position) */
|
case 'n': /* DSR -- Device Status Report */
|
||||||
if (csiescseq.arg[0] == 6) {
|
switch (csiescseq.arg[0]) {
|
||||||
|
case 5: /* Status Report "OK" `0n` */
|
||||||
|
ttywrite("\033[0n", sizeof("\033[0n") - 1, 0);
|
||||||
|
break;
|
||||||
|
case 6: /* Report Cursor Position (CPR) "<row>;<column>R" */
|
||||||
len = snprintf(buf, sizeof(buf), "\033[%i;%iR",
|
len = snprintf(buf, sizeof(buf), "\033[%i;%iR",
|
||||||
term.c.y+1, term.c.x+1);
|
term.c.y+1, term.c.x+1);
|
||||||
ttywrite(buf, len, 0);
|
ttywrite(buf, len, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto unknown;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'r': /* DECSTBM -- Set Scrolling Region */
|
case 'r': /* DECSTBM -- Set Scrolling Region */
|
||||||
@ -1835,39 +1843,28 @@ csireset(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
osc4_color_response(int num)
|
osc_color_response(int num, int index, int is_osc4)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
unsigned char r, g, b;
|
unsigned char r, g, b;
|
||||||
|
|
||||||
if (xgetcolor(num, &r, &g, &b)) {
|
if (xgetcolor(is_osc4 ? num : index, &r, &g, &b)) {
|
||||||
fprintf(stderr, "erresc: failed to fetch osc4 color %d\n", num);
|
fprintf(stderr, "erresc: failed to fetch %s color %d\n",
|
||||||
|
is_osc4 ? "osc4" : "osc",
|
||||||
|
is_osc4 ? num : index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = snprintf(buf, sizeof buf, "\033]4;%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
|
n = snprintf(buf, sizeof buf, "\033]%s%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
|
||||||
num, r, r, g, g, b, b);
|
is_osc4 ? "4;" : "", num, r, r, g, g, b, b);
|
||||||
|
if (n < 0 || n >= sizeof(buf)) {
|
||||||
ttywrite(buf, n, 1);
|
fprintf(stderr, "error: %s while printing %s response\n",
|
||||||
}
|
n < 0 ? "snprintf failed" : "truncation occurred",
|
||||||
|
is_osc4 ? "osc4" : "osc");
|
||||||
void
|
} else {
|
||||||
osc_color_response(int index, int num)
|
ttywrite(buf, n, 1);
|
||||||
{
|
|
||||||
int n;
|
|
||||||
char buf[32];
|
|
||||||
unsigned char r, g, b;
|
|
||||||
|
|
||||||
if (xgetcolor(index, &r, &g, &b)) {
|
|
||||||
fprintf(stderr, "erresc: failed to fetch osc color %d\n", index);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n = snprintf(buf, sizeof buf, "\033]%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
|
|
||||||
num, r, r, g, g, b, b);
|
|
||||||
|
|
||||||
ttywrite(buf, n, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1875,6 +1872,11 @@ strhandle(void)
|
|||||||
{
|
{
|
||||||
char *p = NULL, *dec;
|
char *p = NULL, *dec;
|
||||||
int j, narg, par;
|
int j, narg, par;
|
||||||
|
const struct { int idx; char *str; } osc_table[] = {
|
||||||
|
{ defaultfg, "foreground" },
|
||||||
|
{ defaultbg, "background" },
|
||||||
|
{ defaultcs, "cursor" }
|
||||||
|
};
|
||||||
|
|
||||||
term.esc &= ~(ESC_STR_END|ESC_STR);
|
term.esc &= ~(ESC_STR_END|ESC_STR);
|
||||||
strparse();
|
strparse();
|
||||||
@ -1909,43 +1911,22 @@ strhandle(void)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 10:
|
case 10:
|
||||||
if (narg < 2)
|
|
||||||
break;
|
|
||||||
|
|
||||||
p = strescseq.args[1];
|
|
||||||
|
|
||||||
if (!strcmp(p, "?"))
|
|
||||||
osc_color_response(defaultfg, 10);
|
|
||||||
else if (xsetcolorname(defaultfg, p))
|
|
||||||
fprintf(stderr, "erresc: invalid foreground color: %s\n", p);
|
|
||||||
else
|
|
||||||
tfulldirt();
|
|
||||||
return;
|
|
||||||
case 11:
|
case 11:
|
||||||
if (narg < 2)
|
|
||||||
break;
|
|
||||||
|
|
||||||
p = strescseq.args[1];
|
|
||||||
|
|
||||||
if (!strcmp(p, "?"))
|
|
||||||
osc_color_response(defaultbg, 11);
|
|
||||||
else if (xsetcolorname(defaultbg, p))
|
|
||||||
fprintf(stderr, "erresc: invalid background color: %s\n", p);
|
|
||||||
else
|
|
||||||
tfulldirt();
|
|
||||||
return;
|
|
||||||
case 12:
|
case 12:
|
||||||
if (narg < 2)
|
if (narg < 2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
p = strescseq.args[1];
|
p = strescseq.args[1];
|
||||||
|
if ((j = par - 10) < 0 || j >= LEN(osc_table))
|
||||||
|
break; /* shouldn't be possible */
|
||||||
|
|
||||||
if (!strcmp(p, "?"))
|
if (!strcmp(p, "?")) {
|
||||||
osc_color_response(defaultcs, 12);
|
osc_color_response(par, osc_table[j].idx, 0);
|
||||||
else if (xsetcolorname(defaultcs, p))
|
} else if (xsetcolorname(osc_table[j].idx, p)) {
|
||||||
fprintf(stderr, "erresc: invalid cursor color: %s\n", p);
|
fprintf(stderr, "erresc: invalid %s color: %s\n",
|
||||||
else
|
osc_table[j].str, p);
|
||||||
|
} else {
|
||||||
tfulldirt();
|
tfulldirt();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case 4: /* color set */
|
case 4: /* color set */
|
||||||
if (narg < 3)
|
if (narg < 3)
|
||||||
@ -1955,11 +1936,13 @@ strhandle(void)
|
|||||||
case 104: /* color reset */
|
case 104: /* color reset */
|
||||||
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
|
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
|
||||||
|
|
||||||
if (p && !strcmp(p, "?"))
|
if (p && !strcmp(p, "?")) {
|
||||||
osc4_color_response(j);
|
osc_color_response(j, 0, 1);
|
||||||
else if (xsetcolorname(j, p)) {
|
} else if (xsetcolorname(j, p)) {
|
||||||
if (par == 104 && narg <= 1)
|
if (par == 104 && narg <= 1) {
|
||||||
|
xloadcols();
|
||||||
return; /* color reset without parameter */
|
return; /* color reset without parameter */
|
||||||
|
}
|
||||||
fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
|
fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
|
||||||
j, p ? p : "(null)");
|
j, p ? p : "(null)");
|
||||||
} else {
|
} else {
|
||||||
@ -2439,6 +2422,9 @@ check_control_code:
|
|||||||
* they must not cause conflicts with sequences.
|
* they must not cause conflicts with sequences.
|
||||||
*/
|
*/
|
||||||
if (control) {
|
if (control) {
|
||||||
|
/* in UTF-8 mode ignore handling C1 control characters */
|
||||||
|
if (IS_SET(MODE_UTF8) && ISCONTROLC1(u))
|
||||||
|
return;
|
||||||
tcontrolcode(u);
|
tcontrolcode(u);
|
||||||
/*
|
/*
|
||||||
* control codes are not shown ever
|
* control codes are not shown ever
|
||||||
|
2
st.h
2
st.h
@ -111,8 +111,6 @@ void *xmalloc(size_t);
|
|||||||
void *xrealloc(void *, size_t);
|
void *xrealloc(void *, size_t);
|
||||||
char *xstrdup(const char *);
|
char *xstrdup(const char *);
|
||||||
|
|
||||||
int xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b);
|
|
||||||
|
|
||||||
/* config.h globals */
|
/* config.h globals */
|
||||||
extern char *utmp;
|
extern char *utmp;
|
||||||
extern char *scroll;
|
extern char *scroll;
|
||||||
|
1
win.h
1
win.h
@ -30,6 +30,7 @@ void xdrawline(Line, int, int, int);
|
|||||||
void xfinishdraw(void);
|
void xfinishdraw(void);
|
||||||
void xloadcols(void);
|
void xloadcols(void);
|
||||||
int xsetcolorname(int, const char *);
|
int xsetcolorname(int, const char *);
|
||||||
|
int xgetcolor(int, unsigned char *, unsigned char *, unsigned char *);
|
||||||
void xseticontitle(char *);
|
void xseticontitle(char *);
|
||||||
void xsettitle(char *);
|
void xsettitle(char *);
|
||||||
int xsetcursor(int);
|
int xsetcursor(int);
|
||||||
|
87
x.c
87
x.c
@ -14,6 +14,7 @@
|
|||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <X11/Xft/Xft.h>
|
#include <X11/Xft/Xft.h>
|
||||||
#include <X11/XKBlib.h>
|
#include <X11/XKBlib.h>
|
||||||
|
#include <X11/Xresource.h>
|
||||||
|
|
||||||
char *argv0;
|
char *argv0;
|
||||||
#include "arg.h"
|
#include "arg.h"
|
||||||
@ -45,6 +46,19 @@ typedef struct {
|
|||||||
signed char appcursor; /* application cursor */
|
signed char appcursor; /* application cursor */
|
||||||
} Key;
|
} 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 */
|
/* X modifiers */
|
||||||
#define XK_ANY_MOD UINT_MAX
|
#define XK_ANY_MOD UINT_MAX
|
||||||
#define XK_NO_MOD 0
|
#define XK_NO_MOD 0
|
||||||
@ -859,8 +873,8 @@ xclear(int x1, int y1, int x2, int y2)
|
|||||||
void
|
void
|
||||||
xhints(void)
|
xhints(void)
|
||||||
{
|
{
|
||||||
XClassHint class = {opt_name ? opt_name : termname,
|
XClassHint class = {opt_name ? opt_name : "st",
|
||||||
opt_class ? opt_class : termname};
|
opt_class ? opt_class : "St"};
|
||||||
XWMHints wm = {.flags = InputHint, .input = 1};
|
XWMHints wm = {.flags = InputHint, .input = 1};
|
||||||
XSizeHints *sizeh;
|
XSizeHints *sizeh;
|
||||||
|
|
||||||
@ -1135,8 +1149,6 @@ xinit(int cols, int rows)
|
|||||||
pid_t thispid = getpid();
|
pid_t thispid = getpid();
|
||||||
XColor xmousefg, xmousebg;
|
XColor xmousefg, xmousebg;
|
||||||
|
|
||||||
if (!(xw.dpy = XOpenDisplay(NULL)))
|
|
||||||
die("can't open display\n");
|
|
||||||
xw.scr = XDefaultScreen(xw.dpy);
|
xw.scr = XDefaultScreen(xw.dpy);
|
||||||
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
||||||
|
|
||||||
@ -1833,7 +1845,7 @@ void
|
|||||||
kpress(XEvent *ev)
|
kpress(XEvent *ev)
|
||||||
{
|
{
|
||||||
XKeyEvent *e = &ev->xkey;
|
XKeyEvent *e = &ev->xkey;
|
||||||
KeySym ksym;
|
KeySym ksym = NoSymbol;
|
||||||
char buf[64], *customkey;
|
char buf[64], *customkey;
|
||||||
int len;
|
int len;
|
||||||
Rune c;
|
Rune c;
|
||||||
@ -1843,10 +1855,13 @@ kpress(XEvent *ev)
|
|||||||
if (IS_SET(MODE_KBDLOCK))
|
if (IS_SET(MODE_KBDLOCK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (xw.ime.xic)
|
if (xw.ime.xic) {
|
||||||
len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
|
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);
|
len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
|
||||||
|
}
|
||||||
/* 1. shortcuts */
|
/* 1. shortcuts */
|
||||||
for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
|
for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
|
||||||
if (ksym == bp->keysym && match(bp->mod, e->state)) {
|
if (ksym == bp->keysym && match(bp->mod, e->state)) {
|
||||||
@ -2011,6 +2026,59 @@ 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
|
void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
@ -2084,6 +2152,11 @@ run:
|
|||||||
|
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
XSetLocaleModifiers("");
|
XSetLocaleModifiers("");
|
||||||
|
|
||||||
|
if(!(xw.dpy = XOpenDisplay(NULL)))
|
||||||
|
die("Can't open display\n");
|
||||||
|
|
||||||
|
config_init();
|
||||||
cols = MAX(cols, 1);
|
cols = MAX(cols, 1);
|
||||||
rows = MAX(rows, 1);
|
rows = MAX(rows, 1);
|
||||||
tnew(cols, rows);
|
tnew(cols, rows);
|
||||||
|
Reference in New Issue
Block a user