Update st to version 0.9 (2022-10-25)
This commit is contained in:
parent
2639054bbf
commit
499f8bc1d0
7
FAQ
7
FAQ
|
@ -29,8 +29,8 @@ you can manually run `tic -sx st.info`.
|
||||||
|
|
||||||
## I would like to have utmp and/or scroll functionality by default
|
## I would like to have utmp and/or scroll functionality by default
|
||||||
|
|
||||||
You can add the absolute patch of both programs in your config.h
|
You can add the absolute path of both programs in your config.h file. You only
|
||||||
file. You only have to modify the value of utmp and scroll variables.
|
have to modify the value of utmp and scroll variables.
|
||||||
|
|
||||||
|
|
||||||
## Why doesn't the Del key work in some programs?
|
## Why doesn't the Del key work in some programs?
|
||||||
|
@ -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
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT/X Consortium License
|
MIT/X Consortium License
|
||||||
|
|
||||||
© 2014-2020 Hiltjo Posthuma <hiltjo at codemadness dot org>
|
© 2014-2022 Hiltjo Posthuma <hiltjo at codemadness dot org>
|
||||||
© 2018 Devin J. Pohly <djpohly at gmail dot com>
|
© 2018 Devin J. Pohly <djpohly at gmail dot com>
|
||||||
© 2014-2017 Quentin Rameau <quinq at fifth dot space>
|
© 2014-2017 Quentin Rameau <quinq at fifth dot space>
|
||||||
© 2009-2012 Aurélien APTEL <aurelien dot aptel at gmail dot com>
|
© 2009-2012 Aurélien APTEL <aurelien dot aptel at gmail dot com>
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -30,7 +30,7 @@ st: $(OBJ)
|
||||||
$(CC) -o $@ $(OBJ) $(STLDFLAGS)
|
$(CC) -o $@ $(OBJ) $(STLDFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f st $(OBJ) st-$(VERSION).tar.gz config.h
|
rm -f st $(OBJ) st-$(VERSION).tar.gz
|
||||||
|
|
||||||
dist: clean
|
dist: clean
|
||||||
mkdir -p st-$(VERSION)
|
mkdir -p st-$(VERSION)
|
||||||
|
|
69
config.def.h
69
config.def.h
|
@ -5,15 +5,7 @@
|
||||||
*
|
*
|
||||||
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||||
*/
|
*/
|
||||||
static char *font = "Jetbrains Mono:pixelsize=14:antialias=true:autohint=true";
|
static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
|
||||||
/* Spare fonts */
|
|
||||||
static char *font2[] = {
|
|
||||||
"Droid Sans Mono:style=Regular:pixelsize=14:antialias=true:autohint=true",
|
|
||||||
"Menlo:style=Regular:pixelsize=14:antialias=true:autohint=true",
|
|
||||||
"Inconsolata for Powerline:pixelsize=14:antialias=true:autohint=true",
|
|
||||||
"Hack Nerd Font Mono:pixelsize=14:antialias=true:autohint=true",
|
|
||||||
};
|
|
||||||
|
|
||||||
static int borderpx = 2;
|
static int borderpx = 2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -27,7 +19,7 @@ static int borderpx = 2;
|
||||||
static char *shell = "/bin/sh";
|
static char *shell = "/bin/sh";
|
||||||
char *utmp = NULL;
|
char *utmp = NULL;
|
||||||
/* scroll program: to enable use a string like "scroll" */
|
/* scroll program: to enable use a string like "scroll" */
|
||||||
char *scroll = "scroll";
|
char *scroll = NULL;
|
||||||
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
|
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
|
||||||
|
|
||||||
/* identification sequence returned in DA and DECID */
|
/* identification sequence returned in DA and DECID */
|
||||||
|
@ -101,36 +93,35 @@ char *termname = "st-256color";
|
||||||
*/
|
*/
|
||||||
unsigned int tabspaces = 8;
|
unsigned int tabspaces = 8;
|
||||||
|
|
||||||
/* bg opacity */
|
|
||||||
float alpha = 0.70;
|
|
||||||
|
|
||||||
/* Terminal colors (16 first used in escape sequence) */
|
/* Terminal colors (16 first used in escape sequence) */
|
||||||
static const char *colorname[] = {
|
static const char *colorname[] = {
|
||||||
/* 8 normal colors */
|
/* 8 normal colors */
|
||||||
[0] = "#002b36", /* black */
|
"black",
|
||||||
[1] = "#dc322f", /* red */
|
"red3",
|
||||||
[2] = "#859900", /* green */
|
"green3",
|
||||||
[3] = "#b58900", /* yellow */
|
"yellow3",
|
||||||
[4] = "#268bd2", /* blue */
|
"blue2",
|
||||||
[5] = "#6c71c4", /* magenta */
|
"magenta3",
|
||||||
[6] = "#2aa198", /* cyan */
|
"cyan3",
|
||||||
[7] = "#93a1a1", /* white */
|
"gray90",
|
||||||
|
|
||||||
/* 8 bright colors */
|
/* 8 bright colors */
|
||||||
[8] = "#657b83", /* black */
|
"gray50",
|
||||||
[9] = "#dc322f", /* red */
|
"red",
|
||||||
[10] = "#859900", /* green */
|
"green",
|
||||||
[11] = "#b58900", /* yellow */
|
"yellow",
|
||||||
[12] = "#268bd2", /* blue */
|
"#5c5cff",
|
||||||
[13] = "#6c71c4", /* magenta */
|
"magenta",
|
||||||
[14] = "#2aa198", /* cyan */
|
"cyan",
|
||||||
[15] = "#fdf6e3", /* white */
|
"white",
|
||||||
|
|
||||||
[255] = 0,
|
[255] = 0,
|
||||||
|
|
||||||
/* more colors can be added after 255 to use with DefaultXX */
|
/* more colors can be added after 255 to use with DefaultXX */
|
||||||
"#272727",
|
"#cccccc",
|
||||||
"#ffffff",
|
"#555555",
|
||||||
|
"gray90", /* default foreground colour */
|
||||||
|
"black", /* default background colour */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,9 +129,9 @@ static const char *colorname[] = {
|
||||||
* Default colors (colorname index)
|
* Default colors (colorname index)
|
||||||
* foreground, background, cursor, reverse cursor
|
* foreground, background, cursor, reverse cursor
|
||||||
*/
|
*/
|
||||||
unsigned int defaultfg = 257;
|
unsigned int defaultfg = 258;
|
||||||
unsigned int defaultbg = 256;
|
unsigned int defaultbg = 259;
|
||||||
static unsigned int defaultcs = 257;
|
unsigned int defaultcs = 256;
|
||||||
static unsigned int defaultrcs = 257;
|
static unsigned int defaultrcs = 257;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -210,13 +201,6 @@ static Shortcut shortcuts[] = {
|
||||||
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
|
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
|
||||||
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
|
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
|
||||||
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
|
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
|
||||||
{ MODKEY|ShiftMask, XK_Up, zoom, {.f = +1} },
|
|
||||||
{ MODKEY|ShiftMask, XK_Down, zoom, {.f = -1} },
|
|
||||||
{ MODKEY|ShiftMask, XK_K, zoom, {.f = +1} },
|
|
||||||
{ MODKEY|ShiftMask, XK_J, zoom, {.f = -1} },
|
|
||||||
{ MODKEY|ShiftMask, XK_plus, zoom, {.f = +1} },
|
|
||||||
{ MODKEY|ShiftMask, XK_underscore, zoom, {.f = -1} },
|
|
||||||
{ MODKEY|ShiftMask, XK_parenright, zoomreset, {.f = 0} },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -258,9 +242,6 @@ static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
|
||||||
*/
|
*/
|
||||||
static Key key[] = {
|
static Key key[] = {
|
||||||
/* keysym mask string appkey appcursor */
|
/* keysym mask string appkey appcursor */
|
||||||
{ XK_parenright, Mod1Mask|ShiftMask,"\033[41;6u", 0, 0},
|
|
||||||
{ XK_underscore, Mod1Mask|ShiftMask,"\033[95;4u", 0, 0},
|
|
||||||
{ XK_plus, Mod1Mask|ShiftMask,"\033[43;4u", 0, 0},
|
|
||||||
{ XK_KP_Home, ShiftMask, "\033[2J", 0, -1},
|
{ XK_KP_Home, ShiftMask, "\033[2J", 0, -1},
|
||||||
{ XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1},
|
{ XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1},
|
||||||
{ XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
{ XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# st version
|
# st version
|
||||||
VERSION = 0.8.4
|
VERSION = 0.9
|
||||||
|
|
||||||
# Customize below to fit your system
|
# Customize below to fit your system
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ PKG_CONFIG = pkg-config
|
||||||
INCS = -I$(X11INC) \
|
INCS = -I$(X11INC) \
|
||||||
`$(PKG_CONFIG) --cflags fontconfig` \
|
`$(PKG_CONFIG) --cflags fontconfig` \
|
||||||
`$(PKG_CONFIG) --cflags freetype2`
|
`$(PKG_CONFIG) --cflags freetype2`
|
||||||
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\
|
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
|
||||||
`$(PKG_CONFIG) --libs fontconfig` \
|
`$(PKG_CONFIG) --libs fontconfig` \
|
||||||
`$(PKG_CONFIG) --libs freetype2`
|
`$(PKG_CONFIG) --libs freetype2`
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
143
st.c
143
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);
|
||||||
|
@ -186,18 +187,18 @@ static void tputc(Rune);
|
||||||
static void treset(void);
|
static void treset(void);
|
||||||
static void tscrollup(int, int);
|
static void tscrollup(int, int);
|
||||||
static void tscrolldown(int, int);
|
static void tscrolldown(int, int);
|
||||||
static void tsetattr(int *, int);
|
static void tsetattr(const int *, int);
|
||||||
static void tsetchar(Rune, Glyph *, int, int);
|
static void tsetchar(Rune, const Glyph *, int, int);
|
||||||
static void tsetdirt(int, int);
|
static void tsetdirt(int, int);
|
||||||
static void tsetscroll(int, int);
|
static void tsetscroll(int, int);
|
||||||
static void tswapscreen(void);
|
static void tswapscreen(void);
|
||||||
static void tsetmode(int, int, int *, int);
|
static void tsetmode(int, int, const int *, int);
|
||||||
static int twrite(const char *, int, int);
|
static int twrite(const char *, int, int);
|
||||||
static void tfulldirt(void);
|
static void tfulldirt(void);
|
||||||
static void tcontrolcode(uchar );
|
static void tcontrolcode(uchar );
|
||||||
static void tdectest(char );
|
static void tdectest(char );
|
||||||
static void tdefutf8(char);
|
static void tdefutf8(char);
|
||||||
static int32_t tdefcolor(int *, int *, int);
|
static int32_t tdefcolor(const int *, int *, int);
|
||||||
static void tdeftran(char);
|
static void tdeftran(char);
|
||||||
static void tstrsequence(uchar);
|
static void tstrsequence(uchar);
|
||||||
|
|
||||||
|
@ -226,10 +227,10 @@ static int iofd = 1;
|
||||||
static int cmdfd;
|
static int cmdfd;
|
||||||
static pid_t pid;
|
static pid_t pid;
|
||||||
|
|
||||||
static uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
|
static const uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
|
||||||
static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
|
static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
|
||||||
static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
|
static const Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
|
||||||
static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
|
static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
xwrite(int fd, const char *s, size_t len)
|
xwrite(int fd, const char *s, size_t len)
|
||||||
|
@ -269,12 +270,14 @@ xrealloc(void *p, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
xstrdup(char *s)
|
xstrdup(const char *s)
|
||||||
{
|
{
|
||||||
if ((s = strdup(s)) == NULL)
|
char *p;
|
||||||
|
|
||||||
|
if ((p = strdup(s)) == NULL)
|
||||||
die("strdup: %s\n", strerror(errno));
|
die("strdup: %s\n", strerror(errno));
|
||||||
|
|
||||||
return s;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
|
@ -347,25 +350,10 @@ utf8validate(Rune *u, size_t i)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char base64_digits[] = {
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0,
|
|
||||||
63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, -1, 0, 0, 0, 0, 1,
|
|
||||||
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
|
||||||
22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34,
|
|
||||||
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
char
|
char
|
||||||
base64dec_getc(const char **src)
|
base64dec_getc(const char **src)
|
||||||
{
|
{
|
||||||
while (**src && !isprint(**src))
|
while (**src && !isprint((unsigned char)**src))
|
||||||
(*src)++;
|
(*src)++;
|
||||||
return **src ? *((*src)++) : '='; /* emulate padding if string ends */
|
return **src ? *((*src)++) : '='; /* emulate padding if string ends */
|
||||||
}
|
}
|
||||||
|
@ -375,6 +363,13 @@ base64dec(const char *src)
|
||||||
{
|
{
|
||||||
size_t in_len = strlen(src);
|
size_t in_len = strlen(src);
|
||||||
char *result, *dst;
|
char *result, *dst;
|
||||||
|
static const char base64_digits[256] = {
|
||||||
|
[43] = 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
|
||||||
|
0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
|
||||||
|
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0,
|
||||||
|
0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||||
|
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
|
||||||
|
};
|
||||||
|
|
||||||
if (in_len % 4)
|
if (in_len % 4)
|
||||||
in_len += 4 - (in_len % 4);
|
in_len += 4 - (in_len % 4);
|
||||||
|
@ -518,7 +513,7 @@ selsnap(int *x, int *y, int direction)
|
||||||
{
|
{
|
||||||
int newx, newy, xt, yt;
|
int newx, newy, xt, yt;
|
||||||
int delim, prevdelim;
|
int delim, prevdelim;
|
||||||
Glyph *gp, *prevgp;
|
const Glyph *gp, *prevgp;
|
||||||
|
|
||||||
switch (sel.snap) {
|
switch (sel.snap) {
|
||||||
case SNAP_WORD:
|
case SNAP_WORD:
|
||||||
|
@ -591,7 +586,7 @@ getsel(void)
|
||||||
{
|
{
|
||||||
char *str, *ptr;
|
char *str, *ptr;
|
||||||
int y, bufsize, lastx, linelen;
|
int y, bufsize, lastx, linelen;
|
||||||
Glyph *gp, *last;
|
const Glyph *gp, *last;
|
||||||
|
|
||||||
if (sel.ob.x == -1)
|
if (sel.ob.x == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -758,7 +753,7 @@ stty(char **args)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ttynew(char *line, char *cmd, char *out, char **args)
|
ttynew(const char *line, char *cmd, const char *out, char **args)
|
||||||
{
|
{
|
||||||
int m, s;
|
int m, s;
|
||||||
|
|
||||||
|
@ -791,14 +786,15 @@ ttynew(char *line, char *cmd, char *out, char **args)
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
close(iofd);
|
close(iofd);
|
||||||
|
close(m);
|
||||||
setsid(); /* create a new process group */
|
setsid(); /* create a new process group */
|
||||||
dup2(s, 0);
|
dup2(s, 0);
|
||||||
dup2(s, 1);
|
dup2(s, 1);
|
||||||
dup2(s, 2);
|
dup2(s, 2);
|
||||||
if (ioctl(s, TIOCSCTTY, NULL) < 0)
|
if (ioctl(s, TIOCSCTTY, NULL) < 0)
|
||||||
die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
|
die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
|
||||||
|
if (s > 2)
|
||||||
close(s);
|
close(s);
|
||||||
close(m);
|
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
if (pledge("stdio getpw proc exec", NULL) == -1)
|
if (pledge("stdio getpw proc exec", NULL) == -1)
|
||||||
die("pledge\n");
|
die("pledge\n");
|
||||||
|
@ -943,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);
|
||||||
|
@ -1186,9 +1182,9 @@ tmoveto(int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tsetchar(Rune u, Glyph *attr, int x, int y)
|
tsetchar(Rune u, const Glyph *attr, int x, int y)
|
||||||
{
|
{
|
||||||
static char *vt100_0[62] = { /* 0x41 - 0x7e */
|
static const char *vt100_0[62] = { /* 0x41 - 0x7e */
|
||||||
"↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */
|
"↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, /* H - O */
|
0, 0, 0, 0, 0, 0, 0, 0, /* H - O */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, /* P - W */
|
0, 0, 0, 0, 0, 0, 0, 0, /* P - W */
|
||||||
|
@ -1300,7 +1296,7 @@ tdeleteline(int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
tdefcolor(int *attr, int *npar, int l)
|
tdefcolor(const int *attr, int *npar, int l)
|
||||||
{
|
{
|
||||||
int32_t idx = -1;
|
int32_t idx = -1;
|
||||||
uint r, g, b;
|
uint r, g, b;
|
||||||
|
@ -1350,7 +1346,7 @@ tdefcolor(int *attr, int *npar, int l)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tsetattr(int *attr, int l)
|
tsetattr(const int *attr, int l)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int32_t idx;
|
int32_t idx;
|
||||||
|
@ -1468,9 +1464,9 @@ tsetscroll(int t, int b)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tsetmode(int priv, int set, int *args, int narg)
|
tsetmode(int priv, int set, const int *args, int narg)
|
||||||
{
|
{
|
||||||
int alt, *lim;
|
int alt; const int *lim;
|
||||||
|
|
||||||
for (lim = args + narg; args < lim; ++args) {
|
for (lim = args + narg; args < lim; ++args) {
|
||||||
if (priv) {
|
if (priv) {
|
||||||
|
@ -1839,11 +1835,41 @@ csireset(void)
|
||||||
memset(&csiescseq, 0, sizeof(csiescseq));
|
memset(&csiescseq, 0, sizeof(csiescseq));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
osc_color_response(int num, int index, int is_osc4)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
char buf[32];
|
||||||
|
unsigned char r, g, b;
|
||||||
|
|
||||||
|
if (xgetcolor(is_osc4 ? num : index, &r, &g, &b)) {
|
||||||
|
fprintf(stderr, "erresc: failed to fetch %s color %d\n",
|
||||||
|
is_osc4 ? "osc4" : "osc",
|
||||||
|
is_osc4 ? num : index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = snprintf(buf, sizeof buf, "\033]%s%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
|
||||||
|
is_osc4 ? "4;" : "", num, r, r, g, g, b, b);
|
||||||
|
if (n < 0 || n >= sizeof(buf)) {
|
||||||
|
fprintf(stderr, "error: %s while printing %s response\n",
|
||||||
|
n < 0 ? "snprintf failed" : "truncation occurred",
|
||||||
|
is_osc4 ? "osc4" : "osc");
|
||||||
|
} else {
|
||||||
|
ttywrite(buf, n, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
strhandle(void)
|
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();
|
||||||
|
@ -1853,7 +1879,15 @@ strhandle(void)
|
||||||
case ']': /* OSC -- Operating System Command */
|
case ']': /* OSC -- Operating System Command */
|
||||||
switch (par) {
|
switch (par) {
|
||||||
case 0:
|
case 0:
|
||||||
|
if (narg > 1) {
|
||||||
|
xsettitle(strescseq.args[1]);
|
||||||
|
xseticontitle(strescseq.args[1]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
case 1:
|
case 1:
|
||||||
|
if (narg > 1)
|
||||||
|
xseticontitle(strescseq.args[1]);
|
||||||
|
return;
|
||||||
case 2:
|
case 2:
|
||||||
if (narg > 1)
|
if (narg > 1)
|
||||||
xsettitle(strescseq.args[1]);
|
xsettitle(strescseq.args[1]);
|
||||||
|
@ -1869,14 +1903,35 @@ strhandle(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
if (narg < 2)
|
||||||
|
break;
|
||||||
|
p = strescseq.args[1];
|
||||||
|
if ((j = par - 10) < 0 || j >= LEN(osc_table))
|
||||||
|
break; /* shouldn't be possible */
|
||||||
|
|
||||||
|
if (!strcmp(p, "?")) {
|
||||||
|
osc_color_response(par, osc_table[j].idx, 0);
|
||||||
|
} else if (xsetcolorname(osc_table[j].idx, p)) {
|
||||||
|
fprintf(stderr, "erresc: invalid %s color: %s\n",
|
||||||
|
osc_table[j].str, p);
|
||||||
|
} else {
|
||||||
|
tfulldirt();
|
||||||
|
}
|
||||||
|
return;
|
||||||
case 4: /* color set */
|
case 4: /* color set */
|
||||||
if (narg < 3)
|
if (narg < 3)
|
||||||
break;
|
break;
|
||||||
p = strescseq.args[2];
|
p = strescseq.args[2];
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case 104: /* color reset, here p = NULL */
|
case 104: /* color reset */
|
||||||
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
|
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
|
||||||
if (xsetcolorname(j, p)) {
|
|
||||||
|
if (p && !strcmp(p, "?")) {
|
||||||
|
osc_color_response(j, 0, 1);
|
||||||
|
} else if (xsetcolorname(j, p)) {
|
||||||
if (par == 104 && narg <= 1)
|
if (par == 104 && narg <= 1)
|
||||||
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",
|
||||||
|
@ -1886,7 +1941,7 @@ strhandle(void)
|
||||||
* TODO if defaultbg color is changed, borders
|
* TODO if defaultbg color is changed, borders
|
||||||
* are dirty
|
* are dirty
|
||||||
*/
|
*/
|
||||||
redraw();
|
tfulldirt();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2012,7 +2067,7 @@ void
|
||||||
tdumpline(int n)
|
tdumpline(int n)
|
||||||
{
|
{
|
||||||
char buf[UTF_SIZ];
|
char buf[UTF_SIZ];
|
||||||
Glyph *bp, *end;
|
const Glyph *bp, *end;
|
||||||
|
|
||||||
bp = &term.line[n][0];
|
bp = &term.line[n][0];
|
||||||
end = &bp[MIN(tlinelen(n), term.col) - 1];
|
end = &bp[MIN(tlinelen(n), term.col) - 1];
|
||||||
|
@ -2418,6 +2473,10 @@ check_control_code:
|
||||||
if (width == 2) {
|
if (width == 2) {
|
||||||
gp->mode |= ATTR_WIDE;
|
gp->mode |= ATTR_WIDE;
|
||||||
if (term.c.x+1 < term.col) {
|
if (term.c.x+1 < term.col) {
|
||||||
|
if (gp[1].mode == ATTR_WIDE && term.c.x+2 < term.col) {
|
||||||
|
gp[2].u = ' ';
|
||||||
|
gp[2].mode &= ~ATTR_WDUMMY;
|
||||||
|
}
|
||||||
gp[1].u = '\0';
|
gp[1].u = '\0';
|
||||||
gp[1].mode = ATTR_WDUMMY;
|
gp[1].mode = ATTR_WDUMMY;
|
||||||
}
|
}
|
||||||
|
|
6
st.h
6
st.h
|
@ -91,7 +91,7 @@ void tnew(int, int);
|
||||||
void tresize(int, int);
|
void tresize(int, int);
|
||||||
void tsetdirtattr(int);
|
void tsetdirtattr(int);
|
||||||
void ttyhangup(void);
|
void ttyhangup(void);
|
||||||
int ttynew(char *, char *, char *, char **);
|
int ttynew(const char *, char *, const char *, char **);
|
||||||
size_t ttyread(void);
|
size_t ttyread(void);
|
||||||
void ttyresize(int, int);
|
void ttyresize(int, int);
|
||||||
void ttywrite(const char *, size_t, int);
|
void ttywrite(const char *, size_t, int);
|
||||||
|
@ -109,7 +109,7 @@ size_t utf8encode(Rune, char *);
|
||||||
|
|
||||||
void *xmalloc(size_t);
|
void *xmalloc(size_t);
|
||||||
void *xrealloc(void *, size_t);
|
void *xrealloc(void *, size_t);
|
||||||
char *xstrdup(char *);
|
char *xstrdup(const char *);
|
||||||
|
|
||||||
/* config.h globals */
|
/* config.h globals */
|
||||||
extern char *utmp;
|
extern char *utmp;
|
||||||
|
@ -123,4 +123,4 @@ extern char *termname;
|
||||||
extern unsigned int tabspaces;
|
extern unsigned int tabspaces;
|
||||||
extern unsigned int defaultfg;
|
extern unsigned int defaultfg;
|
||||||
extern unsigned int defaultbg;
|
extern unsigned int defaultbg;
|
||||||
extern float alpha;
|
extern unsigned int defaultcs;
|
||||||
|
|
2
win.h
2
win.h
|
@ -30,6 +30,8 @@ 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 xsettitle(char *);
|
void xsettitle(char *);
|
||||||
int xsetcursor(int);
|
int xsetcursor(int);
|
||||||
void xsetmode(int, unsigned int);
|
void xsetmode(int, unsigned int);
|
||||||
|
|
280
x.c
280
x.c
|
@ -48,7 +48,7 @@ typedef struct {
|
||||||
/* 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
|
||||||
#define XK_SWITCH_MOD (1<<13)
|
#define XK_SWITCH_MOD (1<<13|1<<14)
|
||||||
|
|
||||||
/* function definitions used in config.h */
|
/* function definitions used in config.h */
|
||||||
static void clipcopy(const Arg *);
|
static void clipcopy(const Arg *);
|
||||||
|
@ -93,7 +93,7 @@ typedef struct {
|
||||||
Window win;
|
Window win;
|
||||||
Drawable buf;
|
Drawable buf;
|
||||||
GlyphFontSpec *specbuf; /* font spec buffer used for rendering */
|
GlyphFontSpec *specbuf; /* font spec buffer used for rendering */
|
||||||
Atom xembed, wmdeletewin, netwmname, netwmpid;
|
Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid;
|
||||||
struct {
|
struct {
|
||||||
XIM xim;
|
XIM xim;
|
||||||
XIC xic;
|
XIC xic;
|
||||||
|
@ -105,7 +105,6 @@ typedef struct {
|
||||||
XSetWindowAttributes attrs;
|
XSetWindowAttributes attrs;
|
||||||
int scr;
|
int scr;
|
||||||
int isfixed; /* is fixed geometry? */
|
int isfixed; /* is fixed geometry? */
|
||||||
int depth; /* bit depth */
|
|
||||||
int l, t; /* left and top offset */
|
int l, t; /* left and top offset */
|
||||||
int gm; /* geometry mask */
|
int gm; /* geometry mask */
|
||||||
} XWindow;
|
} XWindow;
|
||||||
|
@ -157,9 +156,7 @@ static void xresize(int, int);
|
||||||
static void xhints(void);
|
static void xhints(void);
|
||||||
static int xloadcolor(int, const char *, Color *);
|
static int xloadcolor(int, const char *, Color *);
|
||||||
static int xloadfont(Font *, FcPattern *);
|
static int xloadfont(Font *, FcPattern *);
|
||||||
static void xloadfonts(char *, double);
|
static void xloadfonts(const char *, double);
|
||||||
static int xloadsparefont(FcPattern *, int);
|
|
||||||
static void xloadsparefonts(void);
|
|
||||||
static void xunloadfont(Font *);
|
static void xunloadfont(Font *);
|
||||||
static void xunloadfonts(void);
|
static void xunloadfonts(void);
|
||||||
static void xsetenv(void);
|
static void xsetenv(void);
|
||||||
|
@ -246,7 +243,6 @@ static char *usedfont = NULL;
|
||||||
static double usedfontsize = 0;
|
static double usedfontsize = 0;
|
||||||
static double defaultfontsize = 0;
|
static double defaultfontsize = 0;
|
||||||
|
|
||||||
static char *opt_alpha = NULL;
|
|
||||||
static char *opt_class = NULL;
|
static char *opt_class = NULL;
|
||||||
static char **opt_cmd = NULL;
|
static char **opt_cmd = NULL;
|
||||||
static char *opt_embed = NULL;
|
static char *opt_embed = NULL;
|
||||||
|
@ -256,7 +252,7 @@ static char *opt_line = NULL;
|
||||||
static char *opt_name = NULL;
|
static char *opt_name = NULL;
|
||||||
static char *opt_title = 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
|
void
|
||||||
clipcopy(const Arg *dummy)
|
clipcopy(const Arg *dummy)
|
||||||
|
@ -310,7 +306,6 @@ zoomabs(const Arg *arg)
|
||||||
{
|
{
|
||||||
xunloadfonts();
|
xunloadfonts();
|
||||||
xloadfonts(usedfont, arg->f);
|
xloadfonts(usedfont, arg->f);
|
||||||
xloadsparefonts();
|
|
||||||
cresize(0, 0);
|
cresize(0, 0);
|
||||||
redraw();
|
redraw();
|
||||||
xhints();
|
xhints();
|
||||||
|
@ -369,59 +364,68 @@ mousesel(XEvent *e, int done)
|
||||||
void
|
void
|
||||||
mousereport(XEvent *e)
|
mousereport(XEvent *e)
|
||||||
{
|
{
|
||||||
int len, x = evcol(e), y = evrow(e),
|
int len, btn, code;
|
||||||
button = e->xbutton.button, state = e->xbutton.state;
|
int x = evcol(e), y = evrow(e);
|
||||||
|
int state = e->xbutton.state;
|
||||||
char buf[40];
|
char buf[40];
|
||||||
static int ox, oy;
|
static int ox, oy;
|
||||||
|
|
||||||
/* from urxvt */
|
if (e->type == MotionNotify) {
|
||||||
if (e->xbutton.type == MotionNotify) {
|
|
||||||
if (x == ox && y == oy)
|
if (x == ox && y == oy)
|
||||||
return;
|
return;
|
||||||
if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY))
|
if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY))
|
||||||
return;
|
return;
|
||||||
/* MOUSE_MOTION: no reporting if no button is pressed */
|
/* MODE_MOUSEMOTION: no reporting if no button is pressed */
|
||||||
if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3)
|
if (IS_SET(MODE_MOUSEMOTION) && buttons == 0)
|
||||||
return;
|
return;
|
||||||
|
/* Set btn to lowest-numbered pressed button, or 12 if no
|
||||||
button = oldbutton + 32;
|
* buttons are pressed. */
|
||||||
ox = x;
|
for (btn = 1; btn <= 11 && !(buttons & (1<<(btn-1))); btn++)
|
||||||
oy = y;
|
;
|
||||||
|
code = 32;
|
||||||
} else {
|
} else {
|
||||||
if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) {
|
btn = e->xbutton.button;
|
||||||
button = 3;
|
/* Only buttons 1 through 11 can be encoded */
|
||||||
} else {
|
if (btn < 1 || btn > 11)
|
||||||
button -= Button1;
|
return;
|
||||||
if (button >= 3)
|
if (e->type == ButtonRelease) {
|
||||||
button += 64 - 3;
|
|
||||||
}
|
|
||||||
if (e->xbutton.type == ButtonPress) {
|
|
||||||
oldbutton = button;
|
|
||||||
ox = x;
|
|
||||||
oy = y;
|
|
||||||
} else if (e->xbutton.type == ButtonRelease) {
|
|
||||||
oldbutton = 3;
|
|
||||||
/* MODE_MOUSEX10: no button release reporting */
|
/* MODE_MOUSEX10: no button release reporting */
|
||||||
if (IS_SET(MODE_MOUSEX10))
|
if (IS_SET(MODE_MOUSEX10))
|
||||||
return;
|
return;
|
||||||
if (button == 64 || button == 65)
|
/* Don't send release events for the scroll wheel */
|
||||||
|
if (btn == 4 || btn == 5)
|
||||||
return;
|
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)) {
|
if (!IS_SET(MODE_MOUSEX10)) {
|
||||||
button += ((state & ShiftMask ) ? 4 : 0)
|
code += ((state & ShiftMask ) ? 4 : 0)
|
||||||
+ ((state & Mod4Mask ) ? 8 : 0)
|
+ ((state & Mod1Mask ) ? 8 : 0) /* meta key: alt */
|
||||||
+ ((state & ControlMask) ? 16 : 0);
|
+ ((state & ControlMask) ? 16 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_SET(MODE_MOUSESGR)) {
|
if (IS_SET(MODE_MOUSESGR)) {
|
||||||
len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c",
|
len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c",
|
||||||
button, x+1, y+1,
|
code, x+1, y+1,
|
||||||
e->xbutton.type == ButtonRelease ? 'm' : 'M');
|
e->type == ButtonRelease ? 'm' : 'M');
|
||||||
} else if (x < 223 && y < 223) {
|
} else if (x < 223 && y < 223) {
|
||||||
len = snprintf(buf, sizeof(buf), "\033[M%c%c%c",
|
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 {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -464,9 +468,13 @@ mouseaction(XEvent *e, uint release)
|
||||||
void
|
void
|
||||||
bpress(XEvent *e)
|
bpress(XEvent *e)
|
||||||
{
|
{
|
||||||
|
int btn = e->xbutton.button;
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
int snap;
|
int snap;
|
||||||
|
|
||||||
|
if (1 <= btn && btn <= 11)
|
||||||
|
buttons |= 1 << (btn-1);
|
||||||
|
|
||||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||||
mousereport(e);
|
mousereport(e);
|
||||||
return;
|
return;
|
||||||
|
@ -475,7 +483,7 @@ bpress(XEvent *e)
|
||||||
if (mouseaction(e, 0))
|
if (mouseaction(e, 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (e->xbutton.button == Button1) {
|
if (btn == Button1) {
|
||||||
/*
|
/*
|
||||||
* If the user clicks below predefined timeouts specific
|
* If the user clicks below predefined timeouts specific
|
||||||
* snapping behaviour is exposed.
|
* snapping behaviour is exposed.
|
||||||
|
@ -678,7 +686,6 @@ setsel(char *str, Time t)
|
||||||
XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
|
XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
|
||||||
if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
|
if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
|
||||||
selclear();
|
selclear();
|
||||||
clipcopy(NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -690,6 +697,11 @@ xsetsel(char *str)
|
||||||
void
|
void
|
||||||
brelease(XEvent *e)
|
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)) {
|
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||||
mousereport(e);
|
mousereport(e);
|
||||||
return;
|
return;
|
||||||
|
@ -697,7 +709,7 @@ brelease(XEvent *e)
|
||||||
|
|
||||||
if (mouseaction(e, 1))
|
if (mouseaction(e, 1))
|
||||||
return;
|
return;
|
||||||
if (e->xbutton.button == Button1)
|
if (btn == Button1)
|
||||||
mousesel(e, 1);
|
mousesel(e, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,7 +752,7 @@ xresize(int col, int row)
|
||||||
|
|
||||||
XFreePixmap(xw.dpy, xw.buf);
|
XFreePixmap(xw.dpy, xw.buf);
|
||||||
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
||||||
xw.depth);
|
DefaultDepth(xw.dpy, xw.scr));
|
||||||
XftDrawChange(xw.draw, xw.buf);
|
XftDrawChange(xw.draw, xw.buf);
|
||||||
xclear(0, 0, win.w, win.h);
|
xclear(0, 0, win.w, win.h);
|
||||||
|
|
||||||
|
@ -800,16 +812,22 @@ xloadcols(void)
|
||||||
else
|
else
|
||||||
die("could not allocate color %d\n", i);
|
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;
|
loaded = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b)
|
||||||
|
{
|
||||||
|
if (!BETWEEN(x, 0, dc.collen))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
*r = dc.col[x].color.red >> 8;
|
||||||
|
*g = dc.col[x].color.green >> 8;
|
||||||
|
*b = dc.col[x].color.blue >> 8;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
xsetcolorname(int x, const char *name)
|
xsetcolorname(int x, const char *name)
|
||||||
{
|
{
|
||||||
|
@ -963,7 +981,7 @@ xloadfont(Font *f, FcPattern *pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xloadfonts(char *fontstr, double fontsize)
|
xloadfonts(const char *fontstr, double fontsize)
|
||||||
{
|
{
|
||||||
FcPattern *pattern;
|
FcPattern *pattern;
|
||||||
double fontval;
|
double fontval;
|
||||||
|
@ -971,7 +989,7 @@ xloadfonts(char *fontstr, double fontsize)
|
||||||
if (fontstr[0] == '-')
|
if (fontstr[0] == '-')
|
||||||
pattern = XftXlfdParse(fontstr, False, False);
|
pattern = XftXlfdParse(fontstr, False, False);
|
||||||
else
|
else
|
||||||
pattern = FcNameParse((FcChar8 *)fontstr);
|
pattern = FcNameParse((const FcChar8 *)fontstr);
|
||||||
|
|
||||||
if (!pattern)
|
if (!pattern)
|
||||||
die("can't open font %s\n", fontstr);
|
die("can't open font %s\n", fontstr);
|
||||||
|
@ -1032,101 +1050,6 @@ xloadfonts(char *fontstr, double fontsize)
|
||||||
FcPatternDestroy(pattern);
|
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
|
void
|
||||||
xunloadfont(Font *f)
|
xunloadfont(Font *f)
|
||||||
{
|
{
|
||||||
|
@ -1211,23 +1134,11 @@ xinit(int cols, int rows)
|
||||||
Window parent;
|
Window parent;
|
||||||
pid_t thispid = getpid();
|
pid_t thispid = getpid();
|
||||||
XColor xmousefg, xmousebg;
|
XColor xmousefg, xmousebg;
|
||||||
XWindowAttributes attr;
|
|
||||||
XVisualInfo vis;
|
|
||||||
|
|
||||||
if (!(xw.dpy = XOpenDisplay(NULL)))
|
if (!(xw.dpy = XOpenDisplay(NULL)))
|
||||||
die("can't open display\n");
|
die("can't open display\n");
|
||||||
xw.scr = XDefaultScreen(xw.dpy);
|
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 */
|
/* font */
|
||||||
if (!FcInit())
|
if (!FcInit())
|
||||||
|
@ -1236,11 +1147,8 @@ xinit(int cols, int rows)
|
||||||
usedfont = (opt_font == NULL)? font : opt_font;
|
usedfont = (opt_font == NULL)? font : opt_font;
|
||||||
xloadfonts(usedfont, 0);
|
xloadfonts(usedfont, 0);
|
||||||
|
|
||||||
/* spare fonts */
|
|
||||||
xloadsparefonts();
|
|
||||||
|
|
||||||
/* colors */
|
/* colors */
|
||||||
xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None);
|
xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
|
||||||
xloadcols();
|
xloadcols();
|
||||||
|
|
||||||
/* adjust fixed window geometry */
|
/* adjust fixed window geometry */
|
||||||
|
@ -1260,15 +1168,19 @@ xinit(int cols, int rows)
|
||||||
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
|
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
|
||||||
xw.attrs.colormap = xw.cmap;
|
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,
|
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
|
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
|
||||||
| CWEventMask | CWColormap, &xw.attrs);
|
| CWEventMask | CWColormap, &xw.attrs);
|
||||||
|
|
||||||
memset(&gcvalues, 0, sizeof(gcvalues));
|
memset(&gcvalues, 0, sizeof(gcvalues));
|
||||||
gcvalues.graphics_exposures = False;
|
gcvalues.graphics_exposures = False;
|
||||||
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth);
|
dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
|
||||||
dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues);
|
&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);
|
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
|
||||||
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
||||||
|
|
||||||
|
@ -1305,6 +1217,7 @@ xinit(int cols, int rows)
|
||||||
xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
|
xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
|
||||||
xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
|
xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
|
||||||
xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False);
|
xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False);
|
||||||
|
xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False);
|
||||||
XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
|
XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
|
||||||
|
|
||||||
xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
|
xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
|
||||||
|
@ -1580,12 +1493,12 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
|
||||||
|
|
||||||
/* Render underline and strikethrough. */
|
/* Render underline and strikethrough. */
|
||||||
if (base.mode & ATTR_UNDERLINE) {
|
if (base.mode & ATTR_UNDERLINE) {
|
||||||
XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
|
XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1,
|
||||||
width, 1);
|
width, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base.mode & ATTR_STRUCK) {
|
if (base.mode & ATTR_STRUCK) {
|
||||||
XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
|
XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3,
|
||||||
width, 1);
|
width, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1698,14 +1611,29 @@ xsetenv(void)
|
||||||
setenv("WINDOWID", buf, 1);
|
setenv("WINDOWID", buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xseticontitle(char *p)
|
||||||
|
{
|
||||||
|
XTextProperty prop;
|
||||||
|
DEFAULT(p, opt_title);
|
||||||
|
|
||||||
|
if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
|
||||||
|
&prop) != Success)
|
||||||
|
return;
|
||||||
|
XSetWMIconName(xw.dpy, xw.win, &prop);
|
||||||
|
XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname);
|
||||||
|
XFree(prop.value);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xsettitle(char *p)
|
xsettitle(char *p)
|
||||||
{
|
{
|
||||||
XTextProperty prop;
|
XTextProperty prop;
|
||||||
DEFAULT(p, opt_title);
|
DEFAULT(p, opt_title);
|
||||||
|
|
||||||
Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
|
if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
|
||||||
&prop);
|
&prop) != Success)
|
||||||
|
return;
|
||||||
XSetWMName(xw.dpy, xw.win, &prop);
|
XSetWMName(xw.dpy, xw.win, &prop);
|
||||||
XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname);
|
XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname);
|
||||||
XFree(prop.value);
|
XFree(prop.value);
|
||||||
|
@ -1905,7 +1833,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;
|
||||||
|
@ -1915,10 +1843,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)) {
|
||||||
|
@ -2107,9 +2038,6 @@ main(int argc, char *argv[])
|
||||||
case 'a':
|
case 'a':
|
||||||
allowaltscreen = 0;
|
allowaltscreen = 0;
|
||||||
break;
|
break;
|
||||||
case 'A':
|
|
||||||
opt_alpha = EARGF(usage());
|
|
||||||
break;
|
|
||||||
case 'c':
|
case 'c':
|
||||||
opt_class = EARGF(usage());
|
opt_class = EARGF(usage());
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue