Code formatting + st refactoring.
This commit is contained in:
parent
b5878fc205
commit
e15f7fb669
28 changed files with 5853 additions and 6321 deletions
|
@ -30,7 +30,7 @@ extern char *argv0;
|
|||
switch (argc_)
|
||||
|
||||
#define ARGEND }\
|
||||
}
|
||||
}
|
||||
|
||||
#define ARGC() argc_
|
||||
|
||||
|
|
|
@ -58,14 +58,14 @@ static Clr *scheme[SchemeLast];
|
|||
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
|
||||
static char *(*fstrstr)(const char *, const char *) = strstr;
|
||||
|
||||
static unsigned int
|
||||
static unsigned int
|
||||
textw_clamp(const char *str, unsigned int n)
|
||||
{
|
||||
unsigned int w = drw_fontset_getwidth_clamp(drw, str, n) + lrpad;
|
||||
return MIN(w, n);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
appenditem(struct item *item, struct item **list, struct item **last)
|
||||
{
|
||||
if (*last)
|
||||
|
@ -78,7 +78,7 @@ appenditem(struct item *item, struct item **list, struct item **last)
|
|||
*last = item;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
calcoffsets(void)
|
||||
{
|
||||
int i, n;
|
||||
|
@ -96,7 +96,7 @@ calcoffsets(void)
|
|||
break;
|
||||
}
|
||||
|
||||
static int
|
||||
static int
|
||||
max_textw(void)
|
||||
{
|
||||
int len = 0;
|
||||
|
@ -105,7 +105,7 @@ max_textw(void)
|
|||
return len;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -121,7 +121,7 @@ cleanup(void)
|
|||
XCloseDisplay(dpy);
|
||||
}
|
||||
|
||||
static char *
|
||||
static char *
|
||||
cistrstr(const char *h, const char *n)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -139,7 +139,7 @@ cistrstr(const char *h, const char *n)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static int
|
||||
drawitem(struct item *item, int x, int y, int w)
|
||||
{
|
||||
if (item == sel)
|
||||
|
@ -152,7 +152,7 @@ drawitem(struct item *item, int x, int y, int w)
|
|||
return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
drawmenu(void)
|
||||
{
|
||||
unsigned int curpos;
|
||||
|
@ -201,7 +201,7 @@ drawmenu(void)
|
|||
drw_map(drw, win, 0, 0, mw, mh);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
grabfocus(void)
|
||||
{
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
|
||||
|
@ -218,7 +218,7 @@ grabfocus(void)
|
|||
die("cannot grab focus");
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
grabkeyboard(void)
|
||||
{
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
|
||||
|
@ -236,7 +236,7 @@ grabkeyboard(void)
|
|||
die("cannot grab keyboard");
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
match(void)
|
||||
{
|
||||
static char **tokv = NULL;
|
||||
|
@ -290,7 +290,7 @@ match(void)
|
|||
calcoffsets();
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
insert(const char *str, ssize_t n)
|
||||
{
|
||||
if (strlen(text) + n > sizeof text - 1)
|
||||
|
@ -303,7 +303,7 @@ insert(const char *str, ssize_t n)
|
|||
match();
|
||||
}
|
||||
|
||||
static size_t
|
||||
static size_t
|
||||
nextrune(int inc)
|
||||
{
|
||||
ssize_t n;
|
||||
|
@ -314,7 +314,7 @@ nextrune(int inc)
|
|||
return n;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
movewordedge(int dir)
|
||||
{
|
||||
if (dir < 0) { /* move cursor to the start of the word*/
|
||||
|
@ -330,7 +330,7 @@ movewordedge(int dir)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
keypress(XKeyEvent *ev)
|
||||
{
|
||||
char buf[32];
|
||||
|
@ -537,7 +537,7 @@ draw:
|
|||
drawmenu();
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
paste(void)
|
||||
{
|
||||
char *p, *q;
|
||||
|
@ -555,7 +555,7 @@ paste(void)
|
|||
drawmenu();
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
readstdin(void)
|
||||
{
|
||||
char buf[sizeof text], *p;
|
||||
|
@ -577,7 +577,7 @@ readstdin(void)
|
|||
lines = MIN(lines, i);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
run(void)
|
||||
{
|
||||
XEvent ev;
|
||||
|
@ -615,7 +615,7 @@ run(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
setup(void)
|
||||
{
|
||||
int x, y, i, j;
|
||||
|
@ -735,7 +735,7 @@ setup(void)
|
|||
drawmenu();
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
|
||||
|
@ -743,7 +743,7 @@ usage(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
XWindowAttributes wa;
|
||||
|
|
|
@ -16,7 +16,7 @@ static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}
|
|||
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
|
||||
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
|
||||
|
||||
static long
|
||||
static long
|
||||
utf8decodebyte(const char c, size_t *i)
|
||||
{
|
||||
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
|
||||
|
@ -25,7 +25,7 @@ utf8decodebyte(const char c, size_t *i)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
static size_t
|
||||
utf8validate(long *u, size_t i)
|
||||
{
|
||||
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
|
||||
|
@ -35,7 +35,7 @@ utf8validate(long *u, size_t i)
|
|||
return i;
|
||||
}
|
||||
|
||||
static size_t
|
||||
static size_t
|
||||
utf8decode(const char *c, long *u, size_t clen)
|
||||
{
|
||||
size_t i, j, len, type;
|
||||
|
@ -60,7 +60,7 @@ utf8decode(const char *c, long *u, size_t clen)
|
|||
return len;
|
||||
}
|
||||
|
||||
Drw *
|
||||
Drw *
|
||||
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
|
||||
{
|
||||
Drw *drw = ecalloc(1, sizeof(Drw));
|
||||
|
@ -77,7 +77,7 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
|
|||
return drw;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
drw_resize(Drw *drw, unsigned int w, unsigned int h)
|
||||
{
|
||||
if (!drw)
|
||||
|
@ -90,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
|
|||
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
drw_free(Drw *drw)
|
||||
{
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
|
@ -102,7 +102,7 @@ drw_free(Drw *drw)
|
|||
/* This function is an implementation detail. Library users should use
|
||||
* drw_fontset_create instead.
|
||||
*/
|
||||
static Fnt *
|
||||
static Fnt *
|
||||
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
|
||||
{
|
||||
Fnt *font;
|
||||
|
@ -142,7 +142,7 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
|
|||
return font;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
xfont_free(Fnt *font)
|
||||
{
|
||||
if (!font)
|
||||
|
@ -153,7 +153,7 @@ xfont_free(Fnt *font)
|
|||
free(font);
|
||||
}
|
||||
|
||||
Fnt*
|
||||
Fnt*
|
||||
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
|
||||
{
|
||||
Fnt *cur, *ret = NULL;
|
||||
|
@ -171,7 +171,7 @@ drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
|
|||
return (drw->fonts = ret);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
drw_fontset_free(Fnt *font)
|
||||
{
|
||||
if (font) {
|
||||
|
@ -180,7 +180,7 @@ drw_fontset_free(Fnt *font)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||
{
|
||||
if (!drw || !dest || !clrname)
|
||||
|
@ -194,7 +194,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
|||
|
||||
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||
* returned color scheme when done using it. */
|
||||
Clr *
|
||||
Clr *
|
||||
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -209,21 +209,21 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
drw_setfontset(Drw *drw, Fnt *set)
|
||||
{
|
||||
if (drw)
|
||||
drw->fonts = set;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
drw_setscheme(Drw *drw, Clr *scm)
|
||||
{
|
||||
if (drw)
|
||||
drw->scheme = scm;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
|
||||
{
|
||||
if (!drw || !drw->scheme)
|
||||
|
@ -235,7 +235,7 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
|
|||
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
|
||||
{
|
||||
int i, ty, ellipsis_x = 0;
|
||||
|
@ -385,7 +385,7 @@ no_match:
|
|||
return x + (render ? w : 0);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
|
||||
{
|
||||
if (!drw)
|
||||
|
@ -395,7 +395,7 @@ drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
|
|||
XSync(drw->dpy, False);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
unsigned int
|
||||
drw_fontset_getwidth(Drw *drw, const char *text)
|
||||
{
|
||||
if (!drw || !drw->fonts || !text)
|
||||
|
@ -403,7 +403,7 @@ drw_fontset_getwidth(Drw *drw, const char *text)
|
|||
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
unsigned int
|
||||
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
|
||||
{
|
||||
unsigned int tmp = 0;
|
||||
|
@ -412,7 +412,7 @@ drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
|
|||
return MIN(n, tmp);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
|
||||
{
|
||||
XGlyphInfo ext;
|
||||
|
@ -427,7 +427,7 @@ drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w,
|
|||
*h = font->h;
|
||||
}
|
||||
|
||||
Cur *
|
||||
Cur *
|
||||
drw_cur_create(Drw *drw, int shape)
|
||||
{
|
||||
Cur *cur;
|
||||
|
@ -440,7 +440,7 @@ drw_cur_create(Drw *drw, int shape)
|
|||
return cur;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
drw_cur_free(Drw *drw, Cur *cursor)
|
||||
{
|
||||
if (!cursor)
|
||||
|
|
|
@ -20,7 +20,7 @@ static int match = 0;
|
|||
static int flag[26];
|
||||
static struct stat old, new;
|
||||
|
||||
static void
|
||||
static void
|
||||
test(const char *path, const char *name)
|
||||
{
|
||||
struct stat st, ln;
|
||||
|
@ -48,7 +48,7 @@ test(const char *path, const char *name)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] "
|
||||
|
@ -56,7 +56,7 @@ usage(void)
|
|||
exit(2); /* like test(1) return > 1 on error */
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct dirent *d;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "util.h"
|
||||
|
||||
void *
|
||||
void *
|
||||
ecalloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
|
|
@ -29,7 +29,7 @@ extern char *argv0;
|
|||
argc_ = argv[0][0];\
|
||||
switch (argc_)
|
||||
|
||||
/* Handles obsolete -NUM syntax */
|
||||
/* Handles obsolete -NUM syntax */
|
||||
#define ARGNUM case '0':\
|
||||
case '1':\
|
||||
case '2':\
|
||||
|
@ -42,7 +42,7 @@ extern char *argv0;
|
|||
case '9'
|
||||
|
||||
#define ARGEND }\
|
||||
}
|
||||
}
|
||||
|
||||
#define ARGC() argc_
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
__attribute__((weak)) void
|
||||
__attribute__((weak)) void
|
||||
__explicit_bzero_hook(void *buf, size_t len)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
explicit_bzero(void *buf, size_t len)
|
||||
{
|
||||
memset(buf, 0, len);
|
||||
|
|
|
@ -57,7 +57,7 @@ struct xrandr {
|
|||
int errbase;
|
||||
};
|
||||
|
||||
static void
|
||||
static void
|
||||
die(const char *errstr, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
@ -72,7 +72,7 @@ die(const char *errstr, ...)
|
|||
#include <fcntl.h>
|
||||
#include <linux/oom.h>
|
||||
|
||||
static void
|
||||
static void
|
||||
dontkillme(void)
|
||||
{
|
||||
FILE *f;
|
||||
|
@ -94,7 +94,7 @@ dontkillme(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
static const char *
|
||||
gethash(void)
|
||||
{
|
||||
const char *hash;
|
||||
|
@ -135,7 +135,7 @@ gethash(void)
|
|||
return hash;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
resizerectangles(struct lock *lock)
|
||||
{
|
||||
int i;
|
||||
|
@ -150,7 +150,7 @@ resizerectangles(struct lock *lock)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
drawlogo(Display *dpy, struct lock *lock, int color)
|
||||
{
|
||||
XSetForeground(dpy, lock->gc, lock->colors[BACKGROUND]);
|
||||
|
@ -161,7 +161,7 @@ drawlogo(Display *dpy, struct lock *lock, int color)
|
|||
XSync(dpy, False);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
|
||||
const char *hash)
|
||||
{
|
||||
|
@ -253,7 +253,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
|
|||
}
|
||||
}
|
||||
|
||||
static struct lock *
|
||||
static struct lock *
|
||||
lockscreen(Display *dpy, struct xrandr *rr, int screen)
|
||||
{
|
||||
char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
@ -357,7 +357,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
die("usage: slock [-v] [cmd [arg ...]]\n");
|
||||
|
|
250
_suckless/st/FAQ
250
_suckless/st/FAQ
|
@ -1,250 +0,0 @@
|
|||
## Why does st not handle utmp entries?
|
||||
|
||||
Use the excellent tool of [utmp](https://git.suckless.org/utmp/) for this task.
|
||||
|
||||
|
||||
## Some _random program_ complains that st is unknown/not recognised/unsupported/whatever!
|
||||
|
||||
It means that st doesn’t have any terminfo entry on your system. Chances are
|
||||
you did not `make install`. If you just want to test it without installing it,
|
||||
you can manually run `tic -sx st.info`.
|
||||
|
||||
|
||||
## Nothing works, and nothing is said about an unknown terminal!
|
||||
|
||||
* Some programs just assume they’re running in xterm i.e. they don’t rely on
|
||||
terminfo. What you see is the current state of the “xterm compliance”.
|
||||
* Some programs don’t complain about the lacking st description and default to
|
||||
another terminal. In that case see the question about terminfo.
|
||||
|
||||
|
||||
## How do I scroll back up?
|
||||
|
||||
* Using a terminal multiplexer.
|
||||
* `st -e tmux` using C-b [
|
||||
* `st -e screen` using C-a ESC
|
||||
* Using the excellent tool of [scroll](https://git.suckless.org/scroll/).
|
||||
* Using the scrollback [patch](https://st.suckless.org/patches/scrollback/).
|
||||
|
||||
|
||||
## I would like to have utmp and/or scroll functionality by default
|
||||
|
||||
You can add the absolute path of both programs in your config.h file. You only
|
||||
have to modify the value of utmp and scroll variables.
|
||||
|
||||
|
||||
## Why doesn't the Del key work in some programs?
|
||||
|
||||
Taken from the terminfo manpage:
|
||||
|
||||
If the terminal has a keypad that transmits codes when the keys
|
||||
are pressed, this information can be given. Note that it is not
|
||||
possible to handle terminals where the keypad only works in
|
||||
local (this applies, for example, to the unshifted HP 2621 keys).
|
||||
If the keypad can be set to transmit or not transmit, give these
|
||||
codes as smkx and rmkx. Otherwise the keypad is assumed to
|
||||
always transmit.
|
||||
|
||||
In the st case smkx=E[?1hE= and rmkx=E[?1lE>, so it is mandatory that
|
||||
applications which want to test against keypad keys send these
|
||||
sequences.
|
||||
|
||||
But buggy applications (like bash and irssi, for example) don't do this. A fast
|
||||
solution for them is to use the following command:
|
||||
|
||||
$ printf '\033[?1h\033=' >/dev/tty
|
||||
|
||||
or
|
||||
$ tput smkx
|
||||
|
||||
In the case of bash, readline is used. Readline has a different note in its
|
||||
manpage about this issue:
|
||||
|
||||
enable-keypad (Off)
|
||||
When set to On, readline will try to enable the
|
||||
application keypad when it is called. Some systems
|
||||
need this to enable arrow keys.
|
||||
|
||||
Adding this option to your .inputrc will fix the keypad problem for all
|
||||
applications using readline.
|
||||
|
||||
If you are using zsh, then read the zsh FAQ
|
||||
<http://zsh.sourceforge.net/FAQ/zshfaq03.html#l25>:
|
||||
|
||||
It should be noted that the O / [ confusion can occur with other keys
|
||||
such as Home and End. Some systems let you query the key sequences
|
||||
sent by these keys from the system's terminal database, terminfo.
|
||||
Unfortunately, the key sequences given there typically apply to the
|
||||
mode that is not the one zsh uses by default (it's the "application"
|
||||
mode rather than the "raw" mode). Explaining the use of terminfo is
|
||||
outside of the scope of this FAQ, but if you wish to use the key
|
||||
sequences given there you can tell the line editor to turn on
|
||||
"application" mode when it starts and turn it off when it stops:
|
||||
|
||||
function zle-line-init () { echoti smkx }
|
||||
function zle-line-finish () { echoti rmkx }
|
||||
zle -N zle-line-init
|
||||
zle -N zle-line-finish
|
||||
|
||||
Putting these lines into your .zshrc will fix the problems.
|
||||
|
||||
|
||||
## How can I use meta in 8bit mode?
|
||||
|
||||
St supports meta in 8bit mode, but the default terminfo entry doesn't
|
||||
use this capability. If you want it, you have to use the 'st-meta' value
|
||||
in TERM.
|
||||
|
||||
|
||||
## I cannot compile st in OpenBSD
|
||||
|
||||
OpenBSD lacks librt, despite it being mandatory in POSIX
|
||||
<http://pubs.opengroup.org/onlinepubs/9699919799/utilities/c99.html#tag_20_11_13>.
|
||||
If you want to compile st for OpenBSD you have to remove -lrt from config.mk, and
|
||||
st will compile without any loss of functionality, because all the functions are
|
||||
included in libc on this platform.
|
||||
|
||||
|
||||
## The Backspace Case
|
||||
|
||||
St is emulating the Linux way of handling backspace being delete and delete being
|
||||
backspace.
|
||||
|
||||
This is an issue that was discussed in suckless mailing list
|
||||
<https://lists.suckless.org/dev/1404/20697.html>. Here is why some old grumpy
|
||||
terminal users wants its backspace to be how he feels it:
|
||||
|
||||
Well, I am going to comment why I want to change the behaviour
|
||||
of this key. When ASCII was defined in 1968, communication
|
||||
with computers was done using punched cards, or hardcopy
|
||||
terminals (basically a typewriter machine connected with the
|
||||
computer using a serial port). ASCII defines DELETE as 7F,
|
||||
because, in punched-card terms, it means all the holes of the
|
||||
card punched; it is thus a kind of 'physical delete'. In the
|
||||
same way, the BACKSPACE key was a non-destructive backspace,
|
||||
as on a typewriter. So, if you wanted to delete a character,
|
||||
you had to BACKSPACE and then DELETE. Another use of BACKSPACE
|
||||
was to type accented characters, for example 'a BACKSPACE `'.
|
||||
The VT100 had no BACKSPACE key; it was generated using the
|
||||
CONTROL key as another control character (CONTROL key sets to
|
||||
0 b7 b6 b5, so it converts H (code 0x48) into BACKSPACE (code
|
||||
0x08)), but it had a DELETE key in a similar position where
|
||||
the BACKSPACE key is located today on common PC keyboards.
|
||||
All the terminal emulators emulated the difference between
|
||||
these keys correctly: the backspace key generated a BACKSPACE
|
||||
(^H) and delete key generated a DELETE (^?).
|
||||
|
||||
But a problem arose when Linus Torvalds wrote Linux. Unlike
|
||||
earlier terminals, the Linux virtual terminal (the terminal
|
||||
emulator integrated in the kernel) returned a DELETE when
|
||||
backspace was pressed, due to the VT100 having a DELETE key in
|
||||
the same position. This created a lot of problems (see [1]
|
||||
and [2]). Since Linux has become the king, a lot of terminal
|
||||
emulators today generate a DELETE when the backspace key is
|
||||
pressed in order to avoid problems with Linux. The result is
|
||||
that the only way of generating a BACKSPACE on these systems
|
||||
is by using CONTROL + H. (I also think that emacs had an
|
||||
important point here because the CONTROL + H prefix is used
|
||||
in emacs in some commands (help commands).)
|
||||
|
||||
From point of view of the kernel, you can change the key
|
||||
for deleting a previous character with stty erase. When you
|
||||
connect a real terminal into a machine you describe the type
|
||||
of terminal, so getty configures the correct value of stty
|
||||
erase for this terminal. In the case of terminal emulators,
|
||||
however, you don't have any getty that can set the correct
|
||||
value of stty erase, so you always get the default value.
|
||||
For this reason, it is necessary to add 'stty erase ^H' to your
|
||||
profile if you have changed the value of the backspace key.
|
||||
Of course, another solution is for st itself to modify the
|
||||
value of stty erase. I usually have the inverse problem:
|
||||
when I connect to non-Unix machines, I have to press CONTROL +
|
||||
h to get a BACKSPACE. The inverse problem occurs when a user
|
||||
connects to my Unix machines from a different system with a
|
||||
correct backspace key.
|
||||
|
||||
[1] http://www.ibb.net/~anne/keyboard.html
|
||||
[2] http://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-5.html
|
||||
|
||||
|
||||
## But I really want the old grumpy behaviour of my terminal
|
||||
|
||||
Apply [1].
|
||||
|
||||
[1] https://st.suckless.org/patches/delkey
|
||||
|
||||
|
||||
## Why do images not work in st using the w3m image hack?
|
||||
|
||||
w3mimg uses a hack that draws an image on top of the terminal emulator Drawable
|
||||
window. The hack relies on the terminal to use a single buffer to draw its
|
||||
contents directly.
|
||||
|
||||
st uses double-buffered drawing so the image is quickly replaced and may show a
|
||||
short flicker effect.
|
||||
|
||||
Below is a patch example to change st double-buffering to a single Drawable
|
||||
buffer.
|
||||
|
||||
diff --git a/x.c b/x.c
|
||||
--- a/x.c
|
||||
+++ b/x.c
|
||||
@@ -732,10 +732,6 @@ xresize(int col, int row)
|
||||
win.tw = col * win.cw;
|
||||
win.th = row * win.ch;
|
||||
|
||||
- XFreePixmap(xw.dpy, xw.buf);
|
||||
- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
||||
- DefaultDepth(xw.dpy, xw.scr));
|
||||
- XftDrawChange(xw.draw, xw.buf);
|
||||
xclear(0, 0, win.w, win.h);
|
||||
|
||||
/* resize to new width */
|
||||
@@ -1148,8 +1144,7 @@ xinit(int cols, int rows)
|
||||
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 = xw.win;
|
||||
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
|
||||
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
||||
|
||||
@@ -1632,8 +1627,6 @@ xdrawline(Line line, int x1, int y1, int x2)
|
||||
void
|
||||
xfinishdraw(void)
|
||||
{
|
||||
- XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w,
|
||||
- win.h, 0, 0);
|
||||
XSetForeground(xw.dpy, dc.gc,
|
||||
dc.col[IS_SET(MODE_REVERSE)?
|
||||
defaultfg : defaultbg].pixel);
|
||||
|
||||
|
||||
## BadLength X error in Xft when trying to render emoji
|
||||
|
||||
Xft makes st crash when rendering color emojis with the following error:
|
||||
|
||||
"X Error of failed request: BadLength (poly request too large or internal Xlib length error)"
|
||||
Major opcode of failed request: 139 (RENDER)
|
||||
Minor opcode of failed request: 20 (RenderAddGlyphs)
|
||||
Serial number of failed request: 1595
|
||||
Current serial number in output stream: 1818"
|
||||
|
||||
This is a known bug in Xft (not st) which happens on some platforms and
|
||||
combination of particular fonts and fontconfig settings.
|
||||
|
||||
See also:
|
||||
https://gitlab.freedesktop.org/xorg/lib/libxft/issues/6
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=107534
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1498269
|
||||
|
||||
The solution is to remove color emoji fonts or disable this in the fontconfig
|
||||
XML configuration. As an ugly workaround (which may work only on newer
|
||||
fontconfig versions (FC_COLOR)), the following code can be used to mask color
|
||||
fonts:
|
||||
|
||||
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
|
||||
|
||||
Please don't bother reporting this bug to st, but notify the upstream Xft
|
||||
developers about fixing this bug.
|
|
@ -1,17 +0,0 @@
|
|||
A STATEMENT ON LEGACY SUPPORT
|
||||
|
||||
In the terminal world there is much cruft that comes from old and unsup‐
|
||||
ported terminals that inherit incompatible modes and escape sequences
|
||||
which noone is able to know, except when he/she comes from that time and
|
||||
developed a graphical vt100 emulator at that time.
|
||||
|
||||
One goal of st is to only support what is really needed. When you en‐
|
||||
counter a sequence which you really need, implement it. But while you
|
||||
are at it, do not add the other cruft you might encounter while sneek‐
|
||||
ing at other terminal emulators. History has bloated them and there is
|
||||
no real evidence that most of the sequences are used today.
|
||||
|
||||
|
||||
Christoph Lohmann <20h@r-36.net>
|
||||
2012-09-13T07:00:36.081271045+02:00
|
||||
|
34
_suckless/st/LICENSE
Normal file
34
_suckless/st/LICENSE
Normal file
|
@ -0,0 +1,34 @@
|
|||
MIT/X Consortium License
|
||||
|
||||
© 2014-2022 Hiltjo Posthuma <hiltjo at codemadness dot org>
|
||||
© 2018 Devin J. Pohly <djpohly at gmail dot com>
|
||||
© 2014-2017 Quentin Rameau <quinq at fifth dot space>
|
||||
© 2009-2012 Aurélien APTEL <aurelien dot aptel at gmail dot com>
|
||||
© 2008-2017 Anselm R Garbe <garbeam at gmail dot com>
|
||||
© 2012-2017 Roberto E. Vargas Caballero <k0ga at shike2 dot com>
|
||||
© 2012-2016 Christoph Lohmann <20h at r-36 dot net>
|
||||
© 2013 Eon S. Jeon <esjeon at hyunmu dot am>
|
||||
© 2013 Alexander Sedov <alex0player at gmail dot com>
|
||||
© 2013 Mark Edgar <medgar123 at gmail dot com>
|
||||
© 2013-2014 Eric Pruitt <eric.pruitt at gmail dot com>
|
||||
© 2013 Michael Forney <mforney at mforney dot org>
|
||||
© 2013-2014 Markus Teich <markus dot teich at stusta dot mhn dot de>
|
||||
© 2014-2015 Laslo Hunhold <dev at frign dot de>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
These patches from suckless.org were applied from the newest versions, in order:
|
||||
|
||||
1. `st-w3m-0.8.3.diff`
|
||||
1. `st-font2-20190416-ba72400.diff`
|
||||
1. `st-scrollback-0.8.4.diff`
|
||||
1. `st-hidecursor-0.8.3.diff`
|
||||
1. `st-scrollback-0.8.5.diff`
|
||||
1. `st-externalpipe-0.8.4.diff`
|
||||
1. `fix-wide-glyphs.diff (local, see _patches/)`
|
||||
1. `st-glyph-wide-support-20220411-ef05519.diff`
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
vt emulation
|
||||
------------
|
||||
|
||||
* double-height support
|
||||
|
||||
code & interface
|
||||
----------------
|
||||
|
||||
* add a simple way to do multiplexing
|
||||
|
||||
drawing
|
||||
-------
|
||||
* add diacritics support to xdraws()
|
||||
* switch to a suckless font drawing library
|
||||
* make the font cache simpler
|
||||
* add better support for brightening of the upper colors
|
||||
|
||||
bugs
|
||||
----
|
||||
|
||||
* fix shift up/down (shift selection in emacs)
|
||||
* remove DEC test sequence when appropriate
|
||||
|
||||
misc
|
||||
----
|
||||
|
||||
$ grep -nE 'XXX|TODO' st.c
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
diff --git a/st.h b/st.h
|
||||
index a25605c..96b285c 100644
|
||||
--- a/st.h
|
||||
+++ b/st.h
|
||||
@@ -36,6 +36,12 @@ enum glyph_attribute {
|
||||
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
|
||||
};
|
||||
|
||||
+enum drawing_mode {
|
||||
+ DRAW_NONE = 0,
|
||||
+ DRAW_BG = 1 << 0,
|
||||
+ DRAW_FG = 1 << 1,
|
||||
+};
|
||||
+
|
||||
enum selection_mode {
|
||||
SEL_IDLE = 0,
|
||||
SEL_EMPTY = 1,
|
||||
diff --git a/x.c b/x.c
|
||||
index 12008ef..b668c83 100644
|
||||
--- a/x.c
|
||||
+++ b/x.c
|
||||
@@ -142,7 +142,7 @@ typedef struct {
|
||||
|
||||
static inline ushort sixd_to_16bit(int);
|
||||
static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int);
|
||||
-static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
|
||||
+static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int);
|
||||
static void xdrawglyph(Glyph, int, int);
|
||||
static void xclear(int, int, int, int);
|
||||
static int xgeommasktogravity(int);
|
||||
@@ -1457,14 +1457,13 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
||||
}
|
||||
|
||||
void
|
||||
-xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
|
||||
+xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y, int dmode)
|
||||
{
|
||||
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
|
||||
int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
|
||||
width = charlen * win.cw;
|
||||
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
|
||||
XRenderColor colfg, colbg;
|
||||
- XRectangle r;
|
||||
|
||||
/* Fallback on color display for attributes not supported by the font */
|
||||
if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) {
|
||||
@@ -1548,47 +1547,47 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
|
||||
if (base.mode & ATTR_INVISIBLE)
|
||||
fg = bg;
|
||||
|
||||
- /* Intelligent cleaning up of the borders. */
|
||||
- if (x == 0) {
|
||||
- xclear(0, (y == 0)? 0 : winy, borderpx,
|
||||
- winy + win.ch +
|
||||
- ((winy + win.ch >= borderpx + win.th)? win.h : 0));
|
||||
- }
|
||||
- if (winx + width >= borderpx + win.tw) {
|
||||
- xclear(winx + width, (y == 0)? 0 : winy, win.w,
|
||||
- ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch)));
|
||||
- }
|
||||
- if (y == 0)
|
||||
- xclear(winx, 0, winx + width, borderpx);
|
||||
- if (winy + win.ch >= borderpx + win.th)
|
||||
- xclear(winx, winy + win.ch, winx + width, win.h);
|
||||
-
|
||||
- /* Clean up the region we want to draw to. */
|
||||
- XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
|
||||
-
|
||||
- /* Set the clip region because Xft is sometimes dirty. */
|
||||
- r.x = 0;
|
||||
- r.y = 0;
|
||||
- r.height = win.ch;
|
||||
- r.width = width;
|
||||
- XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
|
||||
-
|
||||
- /* Render the glyphs. */
|
||||
- XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
|
||||
-
|
||||
- /* Render underline and strikethrough. */
|
||||
- if (base.mode & ATTR_UNDERLINE) {
|
||||
- XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
|
||||
- width, 1);
|
||||
- }
|
||||
+ if (dmode & DRAW_BG) {
|
||||
+ /* Intelligent cleaning up of the borders. */
|
||||
+ if (x == 0) {
|
||||
+ xclear(0, (y == 0)? 0 : winy, borderpx,
|
||||
+ winy + win.ch +
|
||||
+ ((winy + win.ch >= borderpx + win.th)? win.h : 0));
|
||||
+ }
|
||||
+ if (winx + width >= borderpx + win.tw) {
|
||||
+ xclear(winx + width, (y == 0)? 0 : winy, win.w,
|
||||
+ ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch)));
|
||||
+ }
|
||||
+ if (y == 0)
|
||||
+ xclear(winx, 0, winx + width, borderpx);
|
||||
+ if (winy + win.ch >= borderpx + win.th)
|
||||
+ xclear(winx, winy + win.ch, winx + width, win.h);
|
||||
|
||||
- if (base.mode & ATTR_STRUCK) {
|
||||
- XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
|
||||
- width, 1);
|
||||
+ /* Fill the background */
|
||||
+ XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
|
||||
}
|
||||
|
||||
- /* Reset clip to none. */
|
||||
- XftDrawSetClip(xw.draw, 0);
|
||||
+ if (dmode & DRAW_FG) {
|
||||
+/*
|
||||
+ if (base.mode & ATTR_BOXDRAW) {
|
||||
+ drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len);
|
||||
+ } else {
|
||||
+*/
|
||||
+ /* Render the glyphs. */
|
||||
+ XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
|
||||
+// }
|
||||
+
|
||||
+ /* Render underline and strikethrough. */
|
||||
+ if (base.mode & ATTR_UNDERLINE) {
|
||||
+ XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
|
||||
+ width, 1);
|
||||
+ }
|
||||
+
|
||||
+ if (base.mode & ATTR_STRUCK) {
|
||||
+ XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
|
||||
+ width, 1);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1598,7 +1597,7 @@ xdrawglyph(Glyph g, int x, int y)
|
||||
XftGlyphFontSpec spec;
|
||||
|
||||
numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
|
||||
- xdrawglyphfontspecs(&spec, g, numspecs, x, y);
|
||||
+ xdrawglyphfontspecs(&spec, g, numspecs, x, y, DRAW_BG | DRAW_FG);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1735,32 +1734,39 @@ xstartdraw(void)
|
||||
void
|
||||
xdrawline(Line line, int x1, int y1, int x2)
|
||||
{
|
||||
- int i, x, ox, numspecs;
|
||||
+ int i, x, ox, numspecs, numspecs_cached;
|
||||
Glyph base, new;
|
||||
- XftGlyphFontSpec *specs = xw.specbuf;
|
||||
-
|
||||
- numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
|
||||
- i = ox = 0;
|
||||
- for (x = x1; x < x2 && i < numspecs; x++) {
|
||||
- new = line[x];
|
||||
- if (new.mode == ATTR_WDUMMY)
|
||||
- continue;
|
||||
- if (selected(x, y1))
|
||||
- new.mode ^= ATTR_REVERSE;
|
||||
- if (i > 0 && ATTRCMP(base, new)) {
|
||||
- xdrawglyphfontspecs(specs, base, i, ox, y1);
|
||||
- specs += i;
|
||||
- numspecs -= i;
|
||||
- i = 0;
|
||||
- }
|
||||
- if (i == 0) {
|
||||
- ox = x;
|
||||
- base = new;
|
||||
+ XftGlyphFontSpec *specs;
|
||||
+
|
||||
+ numspecs_cached = xmakeglyphfontspecs(xw.specbuf, &line[x1], x2 - x1, x1, y1);
|
||||
+
|
||||
+ /* Draw line in 2 passes: background and foreground. This way wide glyphs
|
||||
+ won't get truncated (#223) */
|
||||
+ for (int dmode = DRAW_BG; dmode <= DRAW_FG; dmode <<= 1) {
|
||||
+ specs = xw.specbuf;
|
||||
+ numspecs = numspecs_cached;
|
||||
+ i = ox = 0;
|
||||
+ for (x = x1; x < x2 && i < numspecs; x++) {
|
||||
+ new = line[x];
|
||||
+ if (new.mode == ATTR_WDUMMY)
|
||||
+ continue;
|
||||
+ if (selected(x, y1))
|
||||
+ new.mode ^= ATTR_REVERSE;
|
||||
+ if (i > 0 && ATTRCMP(base, new)) {
|
||||
+ xdrawglyphfontspecs(specs, base, i, ox, y1, dmode);
|
||||
+ specs += i;
|
||||
+ numspecs -= i;
|
||||
+ i = 0;
|
||||
+ }
|
||||
+ if (i == 0) {
|
||||
+ ox = x;
|
||||
+ base = new;
|
||||
+ }
|
||||
+ i++;
|
||||
}
|
||||
- i++;
|
||||
+ if (i > 0)
|
||||
+ xdrawglyphfontspecs(specs, base, i, ox, y1, dmode);
|
||||
}
|
||||
- if (i > 0)
|
||||
- xdrawglyphfontspecs(specs, base, i, ox, y1);
|
||||
}
|
||||
|
||||
void
|
|
@ -31,7 +31,7 @@ extern char *argv0;
|
|||
switch (argc_)
|
||||
|
||||
#define ARGEND }\
|
||||
}
|
||||
}
|
||||
|
||||
#define ARGC() argc_
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
|
||||
/* Spare fonts */
|
||||
static char *font2[] = {
|
||||
/* "Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true", */
|
||||
/* "Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true", */
|
||||
/* "Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true", */
|
||||
"Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true",
|
||||
};
|
||||
|
||||
static int borderpx = 2;
|
||||
|
@ -477,6 +477,6 @@ static uint selmasks[] = {
|
|||
* of single wide characters.
|
||||
*/
|
||||
static char ascii_printable[] =
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
|
|
|
@ -187,7 +187,6 @@ static MouseShortcut mshortcuts[] = {
|
|||
#define MODKEY ControlMask
|
||||
#define SHTKEY (ControlMask|ShiftMask)
|
||||
|
||||
//static char *openurlcmd[] = { "/bin/sh", "-c", "st-url -o", "externalpipe", NULL };
|
||||
static char *openurlcmd[] = {"/bin/sh", "-c", "xurls | dmenu -c -l 20 -i | xargs -r $BROWSER",
|
||||
"externalpipe", NULL};
|
||||
|
||||
|
@ -470,6 +469,6 @@ static uint selmasks[] = {
|
|||
* of single wide characters.
|
||||
*/
|
||||
static char ascii_printable[] =
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
|
|
|
@ -30,6 +30,7 @@ STLDFLAGS = $(LIBS) $(LDFLAGS)
|
|||
#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \
|
||||
# `$(PKG_CONFIG) --libs fontconfig` \
|
||||
# `$(PKG_CONFIG) --libs freetype2`
|
||||
#MANPREFIX = ${PREFIX}/man
|
||||
|
||||
# compiler and linker
|
||||
# CC = c99
|
||||
|
|
|
@ -21,11 +21,11 @@
|
|||
#include "win.h"
|
||||
|
||||
#if defined(__linux)
|
||||
#include <pty.h>
|
||||
#include <pty.h>
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
|
||||
#include <util.h>
|
||||
#include <util.h>
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
#include <libutil.h>
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
|
||||
/* Arbitrary sizes */
|
||||
|
@ -168,6 +168,7 @@ static void csidump(void);
|
|||
static void csihandle(void);
|
||||
static void csiparse(void);
|
||||
static void csireset(void);
|
||||
static void osc_color_response(int, int, int);
|
||||
static int eschandle(uchar);
|
||||
static void strdump(void);
|
||||
static void strhandle(void);
|
||||
|
@ -238,7 +239,7 @@ static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
|
|||
static const Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
|
||||
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)
|
||||
{
|
||||
size_t aux = len;
|
||||
|
@ -255,7 +256,7 @@ xwrite(int fd, const char *s, size_t len)
|
|||
return aux;
|
||||
}
|
||||
|
||||
void *
|
||||
void *
|
||||
xmalloc(size_t len)
|
||||
{
|
||||
void *p;
|
||||
|
@ -266,7 +267,7 @@ xmalloc(size_t len)
|
|||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
void *
|
||||
xrealloc(void *p, size_t len)
|
||||
{
|
||||
if ((p = realloc(p, len)) == NULL)
|
||||
|
@ -275,7 +276,7 @@ xrealloc(void *p, size_t len)
|
|||
return p;
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
xstrdup(const char *s)
|
||||
{
|
||||
char *p;
|
||||
|
@ -286,7 +287,7 @@ xstrdup(const char *s)
|
|||
return p;
|
||||
}
|
||||
|
||||
size_t
|
||||
size_t
|
||||
utf8decode(const char *c, Rune *u, size_t clen)
|
||||
{
|
||||
size_t i, j, len, type;
|
||||
|
@ -311,7 +312,7 @@ utf8decode(const char *c, Rune *u, size_t clen)
|
|||
return len;
|
||||
}
|
||||
|
||||
Rune
|
||||
Rune
|
||||
utf8decodebyte(char c, size_t *i)
|
||||
{
|
||||
for (*i = 0; *i < LEN(utfmask); ++(*i))
|
||||
|
@ -321,7 +322,7 @@ utf8decodebyte(char c, size_t *i)
|
|||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
size_t
|
||||
utf8encode(Rune u, char *c)
|
||||
{
|
||||
size_t len, i;
|
||||
|
@ -339,13 +340,13 @@ utf8encode(Rune u, char *c)
|
|||
return len;
|
||||
}
|
||||
|
||||
char
|
||||
char
|
||||
utf8encodebyte(Rune u, size_t i)
|
||||
{
|
||||
return utfbyte[i] | (u & ~utfmask[i]);
|
||||
}
|
||||
|
||||
size_t
|
||||
size_t
|
||||
utf8validate(Rune *u, size_t i)
|
||||
{
|
||||
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
|
||||
|
@ -356,34 +357,26 @@ utf8validate(Rune *u, size_t 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)
|
||||
{
|
||||
while (**src && !isprint(**src))
|
||||
while (**src && !isprint((unsigned char)**src))
|
||||
(*src)++;
|
||||
return **src ? *((*src)++) : '='; /* emulate padding if string ends */
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
base64dec(const char *src)
|
||||
{
|
||||
size_t in_len = strlen(src);
|
||||
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)
|
||||
in_len += 4 - (in_len % 4);
|
||||
|
@ -410,7 +403,7 @@ base64dec(const char *src)
|
|||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
selinit(void)
|
||||
{
|
||||
sel.mode = SEL_IDLE;
|
||||
|
@ -418,7 +411,7 @@ selinit(void)
|
|||
sel.ob.x = -1;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
tlinelen(int y)
|
||||
{
|
||||
int i = term.col;
|
||||
|
@ -432,7 +425,7 @@ tlinelen(int y)
|
|||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
selstart(int col, int row, int snap)
|
||||
{
|
||||
selclear();
|
||||
|
@ -449,7 +442,7 @@ selstart(int col, int row, int snap)
|
|||
tsetdirt(sel.nb.y, sel.ne.y);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
selextend(int col, int row, int type, int done)
|
||||
{
|
||||
int oldey, oldex, oldsby, oldsey, oldtype;
|
||||
|
@ -478,7 +471,7 @@ selextend(int col, int row, int type, int done)
|
|||
sel.mode = done ? SEL_IDLE : SEL_READY;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
selnormalize(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -506,7 +499,7 @@ selnormalize(void)
|
|||
sel.ne.x = term.col - 1;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
selected(int x, int y)
|
||||
{
|
||||
if (sel.mode == SEL_EMPTY || sel.ob.x == -1 ||
|
||||
|
@ -522,7 +515,7 @@ selected(int x, int y)
|
|||
&& (y != sel.ne.y || x <= sel.ne.x);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
selsnap(int *x, int *y, int direction)
|
||||
{
|
||||
int newx, newy, xt, yt;
|
||||
|
@ -595,7 +588,7 @@ selsnap(int *x, int *y, int direction)
|
|||
}
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
getsel(void)
|
||||
{
|
||||
char *str, *ptr;
|
||||
|
@ -650,7 +643,7 @@ getsel(void)
|
|||
return str;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
selclear(void)
|
||||
{
|
||||
if (sel.ob.x == -1)
|
||||
|
@ -660,7 +653,7 @@ selclear(void)
|
|||
tsetdirt(sel.nb.y, sel.ne.y);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
die(const char *errstr, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
@ -671,7 +664,7 @@ die(const char *errstr, ...)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
execsh(char *cmd, char **args)
|
||||
{
|
||||
char *sh, *prog, *arg;
|
||||
|
@ -723,7 +716,7 @@ execsh(char *cmd, char **args)
|
|||
_exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
sigchld(int a)
|
||||
{
|
||||
int stat;
|
||||
|
@ -748,7 +741,7 @@ sigchld(int a)
|
|||
_exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
stty(char **args)
|
||||
{
|
||||
char cmd[_POSIX_ARG_MAX], **p, *q, *s;
|
||||
|
@ -772,7 +765,7 @@ stty(char **args)
|
|||
perror("Couldn't call stty");
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
ttynew(const char *line, char *cmd, const char *out, char **args)
|
||||
{
|
||||
int m, s;
|
||||
|
@ -834,7 +827,7 @@ ttynew(const char *line, char *cmd, const char *out, char **args)
|
|||
return cmdfd;
|
||||
}
|
||||
|
||||
size_t
|
||||
size_t
|
||||
ttyread(void)
|
||||
{
|
||||
static char buf[BUFSIZ];
|
||||
|
@ -860,7 +853,7 @@ ttyread(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
ttywrite(const char *s, size_t n, int may_echo)
|
||||
{
|
||||
const char *next;
|
||||
|
@ -891,7 +884,7 @@ ttywrite(const char *s, size_t n, int may_echo)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
ttywriteraw(const char *s, size_t n)
|
||||
{
|
||||
fd_set wfd, rfd;
|
||||
|
@ -948,7 +941,7 @@ write_error:
|
|||
die("write error on tty: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
ttyresize(int tw, int th)
|
||||
{
|
||||
struct winsize w;
|
||||
|
@ -961,14 +954,14 @@ ttyresize(int tw, int th)
|
|||
fprintf(stderr, "Couldn't set window size: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
ttyhangup()
|
||||
{
|
||||
/* Send SIGHUP to shell */
|
||||
kill(pid, SIGHUP);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
tattrset(int attr)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -983,7 +976,7 @@ tattrset(int attr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tsetdirt(int top, int bot)
|
||||
{
|
||||
int i;
|
||||
|
@ -995,7 +988,7 @@ tsetdirt(int top, int bot)
|
|||
term.dirty[i] = 1;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tsetdirtattr(int attr)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -1010,13 +1003,13 @@ tsetdirtattr(int attr)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tfulldirt(void)
|
||||
{
|
||||
tsetdirt(0, term.row-1);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tcursor(int mode)
|
||||
{
|
||||
static TCursor c[2];
|
||||
|
@ -1030,7 +1023,7 @@ tcursor(int mode)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
treset(void)
|
||||
{
|
||||
uint i;
|
||||
|
@ -1058,7 +1051,7 @@ treset(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tnew(int col, int row)
|
||||
{
|
||||
term = (Term){ .c = { .attr = { .fg = defaultfg, .bg = defaultbg } } };
|
||||
|
@ -1066,7 +1059,7 @@ tnew(int col, int row)
|
|||
treset();
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tswapscreen(void)
|
||||
{
|
||||
Line *tmp = term.line;
|
||||
|
@ -1077,7 +1070,7 @@ tswapscreen(void)
|
|||
tfulldirt();
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
kscrolldown(const Arg* a)
|
||||
{
|
||||
int n = a->i;
|
||||
|
@ -1095,7 +1088,7 @@ kscrolldown(const Arg* a)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
kscrollup(const Arg* a)
|
||||
{
|
||||
int n = a->i;
|
||||
|
@ -1110,14 +1103,13 @@ kscrollup(const Arg* a)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tscrolldown(int orig, int n, int copyhist)
|
||||
{
|
||||
int i;
|
||||
Line temp;
|
||||
|
||||
LIMIT(n, 0, term.bot-orig+1);
|
||||
|
||||
if (copyhist) {
|
||||
term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE;
|
||||
temp = term.hist[term.histi];
|
||||
|
@ -1125,6 +1117,7 @@ tscrolldown(int orig, int n, int copyhist)
|
|||
term.line[term.bot] = temp;
|
||||
}
|
||||
|
||||
|
||||
tsetdirt(orig, term.bot-n);
|
||||
tclearregion(0, term.bot-n+1, term.col-1, term.bot);
|
||||
|
||||
|
@ -1138,7 +1131,7 @@ tscrolldown(int orig, int n, int copyhist)
|
|||
selscroll(orig, n);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tscrollup(int orig, int n, int copyhist)
|
||||
{
|
||||
int i;
|
||||
|
@ -1169,7 +1162,7 @@ tscrollup(int orig, int n, int copyhist)
|
|||
selscroll(orig, -n);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
selscroll(int orig, int n)
|
||||
{
|
||||
if (sel.ob.x == -1)
|
||||
|
@ -1189,7 +1182,7 @@ selscroll(int orig, int n)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tnewline(int first_col)
|
||||
{
|
||||
int y = term.c.y;
|
||||
|
@ -1202,7 +1195,7 @@ tnewline(int first_col)
|
|||
tmoveto(first_col ? 0 : term.c.x, y);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
csiparse(void)
|
||||
{
|
||||
char *p = csiescseq.buf, *np;
|
||||
|
@ -1233,13 +1226,13 @@ csiparse(void)
|
|||
}
|
||||
|
||||
/* for absolute user moves, when decom is set */
|
||||
void
|
||||
void
|
||||
tmoveato(int x, int y)
|
||||
{
|
||||
tmoveto(x, y + ((term.c.state & CURSOR_ORIGIN) ? term.top: 0));
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tmoveto(int x, int y)
|
||||
{
|
||||
int miny, maxy;
|
||||
|
@ -1256,7 +1249,7 @@ tmoveto(int x, int y)
|
|||
term.c.y = LIMIT(y, miny, maxy);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tsetchar(Rune u, const Glyph *attr, int x, int y)
|
||||
{
|
||||
static const char *vt100_0[62] = { /* 0x41 - 0x7e */
|
||||
|
@ -1292,7 +1285,7 @@ tsetchar(Rune u, const Glyph *attr, int x, int y)
|
|||
term.line[y][x].u = u;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tclearregion(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
int x, y, temp;
|
||||
|
@ -1322,7 +1315,7 @@ tclearregion(int x1, int y1, int x2, int y2)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tdeletechar(int n)
|
||||
{
|
||||
int dst, src, size;
|
||||
|
@ -1339,7 +1332,7 @@ tdeletechar(int n)
|
|||
tclearregion(term.col-n, term.c.y, term.col-1, term.c.y);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tinsertblank(int n)
|
||||
{
|
||||
int dst, src, size;
|
||||
|
@ -1356,21 +1349,21 @@ tinsertblank(int n)
|
|||
tclearregion(src, term.c.y, dst - 1, term.c.y);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tinsertblankline(int n)
|
||||
{
|
||||
if (BETWEEN(term.c.y, term.top, term.bot))
|
||||
tscrolldown(term.c.y, n, 0);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tdeleteline(int n)
|
||||
{
|
||||
if (BETWEEN(term.c.y, term.top, term.bot))
|
||||
tscrollup(term.c.y, n, 0);
|
||||
}
|
||||
|
||||
int32_t
|
||||
int32_t
|
||||
tdefcolor(const int *attr, int *npar, int l)
|
||||
{
|
||||
int32_t idx = -1;
|
||||
|
@ -1420,7 +1413,7 @@ tdefcolor(const int *attr, int *npar, int l)
|
|||
return idx;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tsetattr(const int *attr, int l)
|
||||
{
|
||||
int i;
|
||||
|
@ -1522,7 +1515,7 @@ tsetattr(const int *attr, int l)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tsetscroll(int t, int b)
|
||||
{
|
||||
int temp;
|
||||
|
@ -1538,7 +1531,7 @@ tsetscroll(int t, int b)
|
|||
term.bot = b;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tsetmode(int priv, int set, const int *args, int narg)
|
||||
{
|
||||
int alt; const int *lim;
|
||||
|
@ -1668,7 +1661,7 @@ tsetmode(int priv, int set, const int *args, int narg)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
csihandle(void)
|
||||
{
|
||||
char buf[40];
|
||||
|
@ -1676,7 +1669,7 @@ csihandle(void)
|
|||
|
||||
switch (csiescseq.mode[0]) {
|
||||
default:
|
||||
unknown:
|
||||
unknown:
|
||||
fprintf(stderr, "erresc: unknown csi ");
|
||||
csidump();
|
||||
/* die(""); */
|
||||
|
@ -1880,7 +1873,7 @@ csihandle(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
csidump(void)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -1904,53 +1897,47 @@ csidump(void)
|
|||
putc('\n', stderr);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
csireset(void)
|
||||
{
|
||||
memset(&csiescseq, 0, sizeof(csiescseq));
|
||||
}
|
||||
|
||||
void
|
||||
osc4_color_response(int num)
|
||||
void
|
||||
osc_color_response(int num, int index, int is_osc4)
|
||||
{
|
||||
int n;
|
||||
char buf[32];
|
||||
unsigned char r, g, b;
|
||||
|
||||
if (xgetcolor(num, &r, &g, &b)) {
|
||||
fprintf(stderr, "erresc: failed to fetch osc4 color %d\n", num);
|
||||
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]4;%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
|
||||
num, r, r, g, g, b, b);
|
||||
|
||||
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
|
||||
osc_color_response(int index, int num)
|
||||
{
|
||||
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
|
||||
strhandle(void)
|
||||
{
|
||||
char *p = NULL, *dec;
|
||||
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);
|
||||
strparse();
|
||||
|
@ -1985,43 +1972,22 @@ strhandle(void)
|
|||
}
|
||||
return;
|
||||
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
|
||||
redraw();
|
||||
return;
|
||||
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
|
||||
redraw();
|
||||
return;
|
||||
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(defaultcs, 12);
|
||||
else if (xsetcolorname(defaultcs, p))
|
||||
fprintf(stderr, "erresc: invalid cursor color: %s\n", p);
|
||||
else
|
||||
redraw();
|
||||
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 */
|
||||
if (narg < 3)
|
||||
|
@ -2031,9 +1997,9 @@ strhandle(void)
|
|||
case 104: /* color reset */
|
||||
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
|
||||
|
||||
if (p && !strcmp(p, "?"))
|
||||
osc4_color_response(j);
|
||||
else if (xsetcolorname(j, p)) {
|
||||
if (p && !strcmp(p, "?")) {
|
||||
osc_color_response(j, 0, 1);
|
||||
} else if (xsetcolorname(j, p)) {
|
||||
if (par == 104 && narg <= 1)
|
||||
return; /* color reset without parameter */
|
||||
fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
|
||||
|
@ -2043,7 +2009,7 @@ strhandle(void)
|
|||
* TODO if defaultbg color is changed, borders
|
||||
* are dirty
|
||||
*/
|
||||
redraw();
|
||||
tfulldirt();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -2061,7 +2027,7 @@ strhandle(void)
|
|||
strdump();
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
strparse(void)
|
||||
{
|
||||
int c;
|
||||
|
@ -2083,7 +2049,7 @@ strparse(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
externalpipe(const Arg *arg)
|
||||
{
|
||||
int to[2];
|
||||
|
@ -2136,7 +2102,7 @@ externalpipe(const Arg *arg)
|
|||
signal(SIGPIPE, oldsigpipe);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
strdump(void)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -2163,7 +2129,7 @@ strdump(void)
|
|||
fprintf(stderr, "ESC\\\n");
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
strreset(void)
|
||||
{
|
||||
strescseq = (STREscape){
|
||||
|
@ -2172,14 +2138,14 @@ strreset(void)
|
|||
};
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
sendbreak(const Arg *arg)
|
||||
{
|
||||
if (tcsendbreak(cmdfd, 0))
|
||||
perror("Error sending break");
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tprinter(char *s, size_t len)
|
||||
{
|
||||
if (iofd != -1 && xwrite(iofd, s, len) < 0) {
|
||||
|
@ -2189,25 +2155,25 @@ tprinter(char *s, size_t len)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
toggleprinter(const Arg *arg)
|
||||
{
|
||||
term.mode ^= MODE_PRINT;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
printscreen(const Arg *arg)
|
||||
{
|
||||
tdump();
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
printsel(const Arg *arg)
|
||||
{
|
||||
tdumpsel();
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tdumpsel(void)
|
||||
{
|
||||
char *ptr;
|
||||
|
@ -2218,7 +2184,7 @@ tdumpsel(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tdumpline(int n)
|
||||
{
|
||||
char buf[UTF_SIZ];
|
||||
|
@ -2233,7 +2199,7 @@ tdumpline(int n)
|
|||
tprinter("\n", 1);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tdump(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -2242,7 +2208,7 @@ tdump(void)
|
|||
tdumpline(i);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tputtab(int n)
|
||||
{
|
||||
uint x = term.c.x;
|
||||
|
@ -2259,7 +2225,7 @@ tputtab(int n)
|
|||
term.c.x = LIMIT(x, 0, term.col-1);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tdefutf8(char ascii)
|
||||
{
|
||||
if (ascii == 'G')
|
||||
|
@ -2268,7 +2234,7 @@ tdefutf8(char ascii)
|
|||
term.mode &= ~MODE_UTF8;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tdeftran(char ascii)
|
||||
{
|
||||
static char cs[] = "0B";
|
||||
|
@ -2282,7 +2248,7 @@ tdeftran(char ascii)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tdectest(char c)
|
||||
{
|
||||
int x, y;
|
||||
|
@ -2295,7 +2261,7 @@ tdectest(char c)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tstrsequence(uchar c)
|
||||
{
|
||||
switch (c) {
|
||||
|
@ -2317,7 +2283,7 @@ tstrsequence(uchar c)
|
|||
term.esc |= ESC_STR;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tcontrolcode(uchar ascii)
|
||||
{
|
||||
switch (ascii) {
|
||||
|
@ -2418,7 +2384,7 @@ tcontrolcode(uchar ascii)
|
|||
* returns 1 when the sequence is finished and it hasn't to read
|
||||
* more characters for this sequence, otherwise 0
|
||||
*/
|
||||
int
|
||||
int
|
||||
eschandle(uchar ascii)
|
||||
{
|
||||
switch (ascii) {
|
||||
|
@ -2501,7 +2467,7 @@ eschandle(uchar ascii)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tputc(Rune u)
|
||||
{
|
||||
char c[UTF_SIZ];
|
||||
|
@ -2643,7 +2609,7 @@ check_control_code:
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
twrite(const char *buf, int buflen, int show_ctrl)
|
||||
{
|
||||
int charsize;
|
||||
|
@ -2675,7 +2641,7 @@ twrite(const char *buf, int buflen, int show_ctrl)
|
|||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
tresize(int col, int row)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -2765,13 +2731,13 @@ tresize(int col, int row)
|
|||
term.c = c;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
resettitle(void)
|
||||
{
|
||||
xsettitle(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
drawregion(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
int y;
|
||||
|
@ -2785,7 +2751,7 @@ drawregion(int x1, int y1, int x2, int y2)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
draw(void)
|
||||
{
|
||||
int cx = term.c.x, ocx = term.ocx, ocy = term.ocy;
|
||||
|
@ -2812,7 +2778,7 @@ draw(void)
|
|||
xximspot(term.ocx, term.ocy);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
redraw(void)
|
||||
{
|
||||
tfulldirt();
|
||||
|
|
|
@ -87,9 +87,9 @@ void die(const char *, ...);
|
|||
void redraw(void);
|
||||
void draw(void);
|
||||
|
||||
void externalpipe(const Arg *);
|
||||
void kscrolldown(const Arg *);
|
||||
void kscrollup(const Arg *);
|
||||
void externalpipe(const Arg *);
|
||||
void printscreen(const Arg *);
|
||||
void printsel(const Arg *);
|
||||
void sendbreak(const Arg *);
|
||||
|
@ -120,8 +120,6 @@ void *xmalloc(size_t);
|
|||
void *xrealloc(void *, size_t);
|
||||
char *xstrdup(const char *);
|
||||
|
||||
int xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b);
|
||||
|
||||
/* config.h globals */
|
||||
extern char *utmp;
|
||||
extern char *scroll;
|
||||
|
|
|
@ -30,6 +30,7 @@ void xdrawline(Line, int, int, int);
|
|||
void xfinishdraw(void);
|
||||
void xloadcols(void);
|
||||
int xsetcolorname(int, const char *);
|
||||
int xgetcolor(int, unsigned char *, unsigned char *, unsigned char *);
|
||||
void xseticontitle(char *);
|
||||
void xsettitle(char *);
|
||||
int xsetcursor(int);
|
||||
|
|
278
_suckless/st/x.c
278
_suckless/st/x.c
|
@ -103,6 +103,11 @@ typedef struct {
|
|||
Draw draw;
|
||||
Visual *vis;
|
||||
XSetWindowAttributes attrs;
|
||||
/* Here, we use the term *pointer* to differentiate the cursor
|
||||
* one sees when hovering the mouse over the terminal from, e.g.,
|
||||
* a green rectangle where text would be entered. */
|
||||
Cursor vpointer, bpointer; /* visible and hidden pointers */
|
||||
int pointerisvisible;
|
||||
int scr;
|
||||
int isfixed; /* is fixed geometry? */
|
||||
int l, t; /* left and top offset */
|
||||
|
@ -203,13 +208,13 @@ static void (*handler[LASTEvent])(XEvent *) = {
|
|||
[MotionNotify] = bmotion,
|
||||
[ButtonPress] = bpress,
|
||||
[ButtonRelease] = brelease,
|
||||
/*
|
||||
/*
|
||||
* Uncomment if you want the selection to disappear when you select something
|
||||
* different in another window.
|
||||
*/
|
||||
/* [SelectionClear] = selclear_, */
|
||||
/* [SelectionClear] = selclear_, */
|
||||
[SelectionNotify] = selnotify,
|
||||
/*
|
||||
/*
|
||||
* PropertyNotify is only turned on when there is some INCR transfer happening
|
||||
* for the selection retrieval.
|
||||
*/
|
||||
|
@ -254,9 +259,9 @@ static char *opt_line = NULL;
|
|||
static char *opt_name = NULL;
|
||||
static char *opt_title = NULL;
|
||||
|
||||
static int oldbutton = 3; /* button event on startup: 3 = release */
|
||||
static uint buttons; /* bit field of pressed buttons */
|
||||
|
||||
void
|
||||
void
|
||||
clipcopy(const Arg *dummy)
|
||||
{
|
||||
Atom clipboard;
|
||||
|
@ -271,7 +276,7 @@ clipcopy(const Arg *dummy)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
clippaste(const Arg *dummy)
|
||||
{
|
||||
Atom clipboard;
|
||||
|
@ -281,20 +286,20 @@ clippaste(const Arg *dummy)
|
|||
xw.win, CurrentTime);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
selpaste(const Arg *dummy)
|
||||
{
|
||||
XConvertSelection(xw.dpy, XA_PRIMARY, xsel.xtarget, XA_PRIMARY,
|
||||
xw.win, CurrentTime);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
numlock(const Arg *dummy)
|
||||
{
|
||||
win.mode ^= MODE_NUMLOCK;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
zoom(const Arg *arg)
|
||||
{
|
||||
Arg larg;
|
||||
|
@ -303,7 +308,7 @@ zoom(const Arg *arg)
|
|||
zoomabs(&larg);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
zoomabs(const Arg *arg)
|
||||
{
|
||||
xunloadfonts();
|
||||
|
@ -314,7 +319,7 @@ zoomabs(const Arg *arg)
|
|||
xhints();
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
zoomreset(const Arg *arg)
|
||||
{
|
||||
Arg larg;
|
||||
|
@ -325,13 +330,13 @@ zoomreset(const Arg *arg)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
ttysend(const Arg *arg)
|
||||
{
|
||||
ttywrite(arg->s, strlen(arg->s), 1);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
evcol(XEvent *e)
|
||||
{
|
||||
int x = e->xbutton.x - borderpx;
|
||||
|
@ -339,7 +344,7 @@ evcol(XEvent *e)
|
|||
return x / win.cw;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
evrow(XEvent *e)
|
||||
{
|
||||
int y = e->xbutton.y - borderpx;
|
||||
|
@ -347,7 +352,7 @@ evrow(XEvent *e)
|
|||
return y / win.ch;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
mousesel(XEvent *e, int done)
|
||||
{
|
||||
int type, seltype = SEL_REGULAR;
|
||||
|
@ -364,64 +369,71 @@ mousesel(XEvent *e, int done)
|
|||
setsel(getsel(), e->xbutton.time);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
mousereport(XEvent *e)
|
||||
{
|
||||
int len, x = evcol(e), y = evrow(e),
|
||||
button = e->xbutton.button, state = e->xbutton.state;
|
||||
int len, btn, code;
|
||||
int x = evcol(e), y = evrow(e);
|
||||
int state = e->xbutton.state;
|
||||
char buf[40];
|
||||
static int ox, oy;
|
||||
|
||||
/* from urxvt */
|
||||
if (e->xbutton.type == MotionNotify) {
|
||||
if (e->type == MotionNotify) {
|
||||
if (x == ox && y == oy)
|
||||
return;
|
||||
if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY))
|
||||
return;
|
||||
/* MOUSE_MOTION: no reporting if no button is pressed */
|
||||
if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3)
|
||||
/* MODE_MOUSEMOTION: no reporting if no button is pressed */
|
||||
if (IS_SET(MODE_MOUSEMOTION) && buttons == 0)
|
||||
return;
|
||||
|
||||
button = oldbutton + 32;
|
||||
ox = x;
|
||||
oy = y;
|
||||
/* Set btn to lowest-numbered pressed button, or 12 if no
|
||||
* buttons are pressed. */
|
||||
for (btn = 1; btn <= 11 && !(buttons & (1<<(btn-1))); btn++)
|
||||
;
|
||||
code = 32;
|
||||
} else {
|
||||
if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) {
|
||||
button = 3;
|
||||
} else {
|
||||
button -= Button1;
|
||||
if (button >= 7)
|
||||
button += 128 - 7;
|
||||
else if (button >= 3)
|
||||
button += 64 - 3;
|
||||
}
|
||||
if (e->xbutton.type == ButtonPress) {
|
||||
oldbutton = button;
|
||||
ox = x;
|
||||
oy = y;
|
||||
} else if (e->xbutton.type == ButtonRelease) {
|
||||
oldbutton = 3;
|
||||
btn = e->xbutton.button;
|
||||
/* Only buttons 1 through 11 can be encoded */
|
||||
if (btn < 1 || btn > 11)
|
||||
return;
|
||||
if (e->type == ButtonRelease) {
|
||||
/* MODE_MOUSEX10: no button release reporting */
|
||||
if (IS_SET(MODE_MOUSEX10))
|
||||
return;
|
||||
if (button == 64 || button == 65)
|
||||
/* Don't send release events for the scroll wheel */
|
||||
if (btn == 4 || btn == 5)
|
||||
return;
|
||||
}
|
||||
code = 0;
|
||||
}
|
||||
|
||||
ox = x;
|
||||
oy = y;
|
||||
|
||||
/* Encode btn into code. If no button is pressed for a motion event in
|
||||
* MODE_MOUSEMANY, then encode it as a release. */
|
||||
if ((!IS_SET(MODE_MOUSESGR) && e->type == ButtonRelease) || btn == 12)
|
||||
code += 3;
|
||||
else if (btn >= 8)
|
||||
code += 128 + btn - 8;
|
||||
else if (btn >= 4)
|
||||
code += 64 + btn - 4;
|
||||
else
|
||||
code += btn - 1;
|
||||
|
||||
if (!IS_SET(MODE_MOUSEX10)) {
|
||||
button += ((state & ShiftMask ) ? 4 : 0)
|
||||
+ ((state & Mod4Mask ) ? 8 : 0)
|
||||
code += ((state & ShiftMask ) ? 4 : 0)
|
||||
+ ((state & Mod1Mask ) ? 8 : 0) /* meta key: alt */
|
||||
+ ((state & ControlMask) ? 16 : 0);
|
||||
}
|
||||
|
||||
if (IS_SET(MODE_MOUSESGR)) {
|
||||
len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c",
|
||||
button, x+1, y+1,
|
||||
e->xbutton.type == ButtonRelease ? 'm' : 'M');
|
||||
code, x+1, y+1,
|
||||
e->type == ButtonRelease ? 'm' : 'M');
|
||||
} else if (x < 223 && y < 223) {
|
||||
len = snprintf(buf, sizeof(buf), "\033[M%c%c%c",
|
||||
32+button, 32+x+1, 32+y+1);
|
||||
32+code, 32+x+1, 32+y+1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -429,7 +441,7 @@ mousereport(XEvent *e)
|
|||
ttywrite(buf, len, 0);
|
||||
}
|
||||
|
||||
uint
|
||||
uint
|
||||
buttonmask(uint button)
|
||||
{
|
||||
return button == Button1 ? Button1Mask
|
||||
|
@ -440,7 +452,7 @@ buttonmask(uint button)
|
|||
: 0;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
mouseaction(XEvent *e, uint release)
|
||||
{
|
||||
MouseShortcut *ms;
|
||||
|
@ -461,12 +473,16 @@ mouseaction(XEvent *e, uint release)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
bpress(XEvent *e)
|
||||
{
|
||||
int btn = e->xbutton.button;
|
||||
struct timespec now;
|
||||
int snap;
|
||||
|
||||
if (1 <= btn && btn <= 11)
|
||||
buttons |= 1 << (btn-1);
|
||||
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||
mousereport(e);
|
||||
return;
|
||||
|
@ -475,7 +491,7 @@ bpress(XEvent *e)
|
|||
if (mouseaction(e, 0))
|
||||
return;
|
||||
|
||||
if (e->xbutton.button == Button1) {
|
||||
if (btn == Button1) {
|
||||
/*
|
||||
* If the user clicks below predefined timeouts specific
|
||||
* snapping behaviour is exposed.
|
||||
|
@ -495,7 +511,7 @@ bpress(XEvent *e)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
propnotify(XEvent *e)
|
||||
{
|
||||
XPropertyEvent *xpev;
|
||||
|
@ -509,7 +525,7 @@ propnotify(XEvent *e)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
selnotify(XEvent *e)
|
||||
{
|
||||
ulong nitems, ofs, rem;
|
||||
|
@ -596,19 +612,19 @@ selnotify(XEvent *e)
|
|||
XDeleteProperty(xw.dpy, xw.win, (int)property);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xclipcopy(void)
|
||||
{
|
||||
clipcopy(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
selclear_(XEvent *e)
|
||||
{
|
||||
selclear();
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
selrequest(XEvent *e)
|
||||
{
|
||||
XSelectionRequestEvent *xsre;
|
||||
|
@ -666,7 +682,7 @@ selrequest(XEvent *e)
|
|||
fprintf(stderr, "Error sending SelectionNotify event\n");
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
setsel(char *str, Time t)
|
||||
{
|
||||
if (!str)
|
||||
|
@ -680,15 +696,20 @@ setsel(char *str, Time t)
|
|||
selclear();
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xsetsel(char *str)
|
||||
{
|
||||
setsel(str, CurrentTime);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
brelease(XEvent *e)
|
||||
{
|
||||
int btn = e->xbutton.button;
|
||||
|
||||
if (1 <= btn && btn <= 11)
|
||||
buttons &= ~(1 << (btn-1));
|
||||
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||
mousereport(e);
|
||||
return;
|
||||
|
@ -696,13 +717,20 @@ brelease(XEvent *e)
|
|||
|
||||
if (mouseaction(e, 1))
|
||||
return;
|
||||
if (e->xbutton.button == Button1)
|
||||
if (btn == Button1)
|
||||
mousesel(e, 1);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
bmotion(XEvent *e)
|
||||
{
|
||||
if (!xw.pointerisvisible) {
|
||||
XDefineCursor(xw.dpy, xw.win, xw.vpointer);
|
||||
xw.pointerisvisible = 1;
|
||||
if (!IS_SET(MODE_MOUSEMANY))
|
||||
xsetpointermotion(0);
|
||||
}
|
||||
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||
mousereport(e);
|
||||
return;
|
||||
|
@ -711,7 +739,7 @@ bmotion(XEvent *e)
|
|||
mousesel(e, 0);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
cresize(int width, int height)
|
||||
{
|
||||
int col, row;
|
||||
|
@ -731,7 +759,7 @@ cresize(int width, int height)
|
|||
ttyresize(win.tw, win.th);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xresize(int col, int row)
|
||||
{
|
||||
win.tw = col * win.cw;
|
||||
|
@ -747,13 +775,13 @@ xresize(int col, int row)
|
|||
xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec));
|
||||
}
|
||||
|
||||
ushort
|
||||
ushort
|
||||
sixd_to_16bit(int x)
|
||||
{
|
||||
return x == 0 ? 0 : 0x3737 + 0x2828 * x;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
xloadcolor(int i, const char *name, Color *ncolor)
|
||||
{
|
||||
XRenderColor color = { .alpha = 0xffff };
|
||||
|
@ -777,7 +805,7 @@ xloadcolor(int i, const char *name, Color *ncolor)
|
|||
return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xloadcols(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -802,7 +830,7 @@ xloadcols(void)
|
|||
loaded = 1;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b)
|
||||
{
|
||||
if (!BETWEEN(x, 0, dc.collen))
|
||||
|
@ -815,7 +843,7 @@ xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
xsetcolorname(int x, const char *name)
|
||||
{
|
||||
Color ncolor;
|
||||
|
@ -835,7 +863,7 @@ xsetcolorname(int x, const char *name)
|
|||
/*
|
||||
* Absolute coordinates.
|
||||
*/
|
||||
void
|
||||
void
|
||||
xclear(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
XftDrawRect(xw.draw,
|
||||
|
@ -843,7 +871,7 @@ xclear(int x1, int y1, int x2, int y2)
|
|||
x1, y1, x2-x1, y2-y1);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xhints(void)
|
||||
{
|
||||
XClassHint class = {opt_name ? opt_name : termname,
|
||||
|
@ -879,7 +907,7 @@ xhints(void)
|
|||
XFree(sizeh);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
xgeommasktogravity(int mask)
|
||||
{
|
||||
switch (mask & (XNegative|YNegative)) {
|
||||
|
@ -894,7 +922,7 @@ xgeommasktogravity(int mask)
|
|||
return SouthEastGravity;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
xloadfont(Font *f, FcPattern *pattern)
|
||||
{
|
||||
FcPattern *configured;
|
||||
|
@ -967,7 +995,7 @@ xloadfont(Font *f, FcPattern *pattern)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xloadfonts(const char *fontstr, double fontsize)
|
||||
{
|
||||
FcPattern *pattern;
|
||||
|
@ -1037,7 +1065,7 @@ xloadfonts(const char *fontstr, double fontsize)
|
|||
FcPatternDestroy(pattern);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
xloadsparefont(FcPattern *pattern, int flags)
|
||||
{
|
||||
FcPattern *match;
|
||||
|
@ -1061,7 +1089,7 @@ xloadsparefont(FcPattern *pattern, int flags)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xloadsparefonts(void)
|
||||
{
|
||||
FcPattern *pattern;
|
||||
|
@ -1132,7 +1160,7 @@ xloadsparefonts(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xunloadfont(Font *f)
|
||||
{
|
||||
XftFontClose(xw.dpy, f->match);
|
||||
|
@ -1141,7 +1169,7 @@ xunloadfont(Font *f)
|
|||
FcFontSetDestroy(f->set);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xunloadfonts(void)
|
||||
{
|
||||
/* Free the loaded fonts in the font cache. */
|
||||
|
@ -1154,7 +1182,7 @@ xunloadfonts(void)
|
|||
xunloadfont(&dc.ibfont);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
ximopen(Display *dpy)
|
||||
{
|
||||
XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy };
|
||||
|
@ -1184,7 +1212,7 @@ ximopen(Display *dpy)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
ximinstantiate(Display *dpy, XPointer client, XPointer call)
|
||||
{
|
||||
if (ximopen(dpy))
|
||||
|
@ -1192,7 +1220,7 @@ ximinstantiate(Display *dpy, XPointer client, XPointer call)
|
|||
ximinstantiate, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
ximdestroy(XIM xim, XPointer client, XPointer call)
|
||||
{
|
||||
xw.ime.xim = NULL;
|
||||
|
@ -1201,21 +1229,21 @@ ximdestroy(XIM xim, XPointer client, XPointer call)
|
|||
XFree(xw.ime.spotlist);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
xicdestroy(XIC xim, XPointer client, XPointer call)
|
||||
{
|
||||
xw.ime.xic = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xinit(int cols, int rows)
|
||||
{
|
||||
XGCValues gcvalues;
|
||||
Cursor cursor;
|
||||
Window parent;
|
||||
pid_t thispid = getpid();
|
||||
XColor xmousefg, xmousebg;
|
||||
Pixmap blankpm;
|
||||
|
||||
if (!(xw.dpy = XOpenDisplay(NULL)))
|
||||
die("can't open display\n");
|
||||
|
@ -1282,8 +1310,9 @@ xinit(int cols, int rows)
|
|||
}
|
||||
|
||||
/* white cursor, black outline */
|
||||
cursor = XCreateFontCursor(xw.dpy, mouseshape);
|
||||
XDefineCursor(xw.dpy, xw.win, cursor);
|
||||
xw.pointerisvisible = 1;
|
||||
xw.vpointer = XCreateFontCursor(xw.dpy, mouseshape);
|
||||
XDefineCursor(xw.dpy, xw.win, xw.vpointer);
|
||||
|
||||
if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) {
|
||||
xmousefg.red = 0xffff;
|
||||
|
@ -1297,7 +1326,10 @@ xinit(int cols, int rows)
|
|||
xmousebg.blue = 0x0000;
|
||||
}
|
||||
|
||||
XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg);
|
||||
XRecolorCursor(xw.dpy, xw.vpointer, &xmousefg, &xmousebg);
|
||||
blankpm = XCreateBitmapFromData(xw.dpy, xw.win, &(char){0}, 1, 1);
|
||||
xw.bpointer = XCreatePixmapCursor(xw.dpy, blankpm, blankpm,
|
||||
&xmousefg, &xmousebg, 0, 0);
|
||||
|
||||
xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
|
||||
xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
|
||||
|
@ -1324,7 +1356,7 @@ xinit(int cols, int rows)
|
|||
xsel.xtarget = XA_STRING;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
|
||||
{
|
||||
float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
|
||||
|
@ -1456,7 +1488,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
|||
return numspecs;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y, int dmode)
|
||||
{
|
||||
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
|
||||
|
@ -1464,6 +1496,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
|
|||
width = charlen * win.cw;
|
||||
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
|
||||
XRenderColor colfg, colbg;
|
||||
XRectangle r;
|
||||
|
||||
/* Fallback on color display for attributes not supported by the font */
|
||||
if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) {
|
||||
|
@ -1562,20 +1595,13 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
|
|||
xclear(winx, 0, winx + width, borderpx);
|
||||
if (winy + win.ch >= borderpx + win.th)
|
||||
xclear(winx, winy + win.ch, winx + width, win.h);
|
||||
|
||||
/* Fill the background */
|
||||
XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
|
||||
}
|
||||
|
||||
if (dmode & DRAW_FG) {
|
||||
/*
|
||||
if (base.mode & ATTR_BOXDRAW) {
|
||||
drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len);
|
||||
} else {
|
||||
*/
|
||||
/* Render the glyphs. */
|
||||
XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
|
||||
// }
|
||||
|
||||
/* Render underline and strikethrough. */
|
||||
if (base.mode & ATTR_UNDERLINE) {
|
||||
|
@ -1590,7 +1616,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xdrawglyph(Glyph g, int x, int y)
|
||||
{
|
||||
int numspecs;
|
||||
|
@ -1600,7 +1626,7 @@ xdrawglyph(Glyph g, int x, int y)
|
|||
xdrawglyphfontspecs(&spec, g, numspecs, x, y, DRAW_BG | DRAW_FG);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
|
||||
{
|
||||
Color drawcol;
|
||||
|
@ -1686,7 +1712,7 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xsetenv(void)
|
||||
{
|
||||
char buf[sizeof(long) * 8 + 1];
|
||||
|
@ -1695,7 +1721,7 @@ xsetenv(void)
|
|||
setenv("WINDOWID", buf, 1);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xseticontitle(char *p)
|
||||
{
|
||||
XTextProperty prop;
|
||||
|
@ -1709,7 +1735,7 @@ xseticontitle(char *p)
|
|||
XFree(prop.value);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xsettitle(char *p)
|
||||
{
|
||||
XTextProperty prop;
|
||||
|
@ -1723,15 +1749,13 @@ xsettitle(char *p)
|
|||
XFree(prop.value);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
xstartdraw(void)
|
||||
{
|
||||
if (IS_SET(MODE_VISIBLE))
|
||||
XCopyArea(xw.dpy, xw.win, xw.buf, dc.gc, 0, 0, win.w, win.h, 0, 0);
|
||||
return IS_SET(MODE_VISIBLE);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xdrawline(Line line, int x1, int y1, int x2)
|
||||
{
|
||||
int i, x, ox, numspecs, numspecs_cached;
|
||||
|
@ -1769,7 +1793,7 @@ xdrawline(Line line, int x1, int y1, int x2)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xfinishdraw(void)
|
||||
{
|
||||
XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w,
|
||||
|
@ -1779,7 +1803,7 @@ xfinishdraw(void)
|
|||
defaultfg : defaultbg].pixel);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xximspot(int x, int y)
|
||||
{
|
||||
if (xw.ime.xic == NULL)
|
||||
|
@ -1791,13 +1815,13 @@ xximspot(int x, int y)
|
|||
XSetICValues(xw.ime.xic, XNPreeditAttributes, xw.ime.spotlist, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
expose(XEvent *ev)
|
||||
{
|
||||
redraw();
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
visibility(XEvent *ev)
|
||||
{
|
||||
XVisibilityEvent *e = &ev->xvisibility;
|
||||
|
@ -1805,20 +1829,22 @@ visibility(XEvent *ev)
|
|||
MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
unmap(XEvent *ev)
|
||||
{
|
||||
win.mode &= ~MODE_VISIBLE;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xsetpointermotion(int set)
|
||||
{
|
||||
if (!set && !xw.pointerisvisible)
|
||||
return;
|
||||
MODBIT(xw.attrs.event_mask, set, PointerMotionMask);
|
||||
XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xsetmode(int set, unsigned int flags)
|
||||
{
|
||||
int mode = win.mode;
|
||||
|
@ -1827,7 +1853,7 @@ xsetmode(int set, unsigned int flags)
|
|||
redraw();
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
xsetcursor(int cursor)
|
||||
{
|
||||
if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */
|
||||
|
@ -1836,7 +1862,7 @@ xsetcursor(int cursor)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xseturgency(int add)
|
||||
{
|
||||
XWMHints *h = XGetWMHints(xw.dpy, xw.win);
|
||||
|
@ -1846,7 +1872,7 @@ xseturgency(int add)
|
|||
XFree(h);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xbell(void)
|
||||
{
|
||||
if (!(IS_SET(MODE_FOCUSED)))
|
||||
|
@ -1855,7 +1881,7 @@ xbell(void)
|
|||
XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
focus(XEvent *ev)
|
||||
{
|
||||
XFocusChangeEvent *e = &ev->xfocus;
|
||||
|
@ -1879,13 +1905,13 @@ focus(XEvent *ev)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
match(uint mask, uint state)
|
||||
{
|
||||
return mask == XK_ANY_MOD || mask == (state & ~ignoremod);
|
||||
}
|
||||
|
||||
char*
|
||||
char*
|
||||
kmap(KeySym k, uint state)
|
||||
{
|
||||
Key *kp;
|
||||
|
@ -1922,7 +1948,7 @@ kmap(KeySym k, uint state)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
kpress(XEvent *ev)
|
||||
{
|
||||
XKeyEvent *e = &ev->xkey;
|
||||
|
@ -1933,6 +1959,12 @@ kpress(XEvent *ev)
|
|||
Status status;
|
||||
Shortcut *bp;
|
||||
|
||||
if (xw.pointerisvisible) {
|
||||
XDefineCursor(xw.dpy, xw.win, xw.bpointer);
|
||||
xsetpointermotion(1);
|
||||
xw.pointerisvisible = 0;
|
||||
}
|
||||
|
||||
if (IS_SET(MODE_KBDLOCK))
|
||||
return;
|
||||
|
||||
|
@ -1972,7 +2004,7 @@ kpress(XEvent *ev)
|
|||
ttywrite(buf, len, 1);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
cmessage(XEvent *e)
|
||||
{
|
||||
/*
|
||||
|
@ -1992,7 +2024,7 @@ cmessage(XEvent *e)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
resize(XEvent *e)
|
||||
{
|
||||
if (e->xconfigure.width == win.w && e->xconfigure.height == win.h)
|
||||
|
@ -2001,7 +2033,7 @@ resize(XEvent *e)
|
|||
cresize(e->xconfigure.width, e->xconfigure.height);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
run(void)
|
||||
{
|
||||
XEvent ev;
|
||||
|
@ -2104,7 +2136,7 @@ run(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]"
|
||||
|
@ -2117,7 +2149,7 @@ usage(void)
|
|||
" [stty_args ...]\n", argv0, argv0);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
xw.l = xw.t = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue