init
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
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
|
||||
|
||||
Executable
+34
@@ -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.
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
# st - simple terminal
|
||||
# See LICENSE file for copyright and license details.
|
||||
.POSIX:
|
||||
|
||||
include config.mk
|
||||
|
||||
SRC = st.c x.c hb.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
all: st
|
||||
|
||||
config.h:
|
||||
cp config.def.h config.h
|
||||
|
||||
.c.o:
|
||||
$(CC) $(STCFLAGS) -c $<
|
||||
|
||||
st.o: config.h st.h win.h
|
||||
x.o: arg.h config.h st.h win.h hb.h
|
||||
hb.o: st.h
|
||||
|
||||
$(OBJ): config.h config.mk
|
||||
|
||||
st: $(OBJ)
|
||||
$(CC) -o $@ $(OBJ) $(STLDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f st $(OBJ) st-$(VERSION).tar.gz
|
||||
|
||||
dist: clean
|
||||
mkdir -p st-$(VERSION)
|
||||
cp -R FAQ LEGACY TODO LICENSE Makefile README config.mk\
|
||||
config.def.h st.info st.1 arg.h st.h win.h $(SRC)\
|
||||
st-$(VERSION)
|
||||
tar -cf - st-$(VERSION) | gzip > st-$(VERSION).tar.gz
|
||||
rm -rf st-$(VERSION)
|
||||
|
||||
install: st
|
||||
mkdir -p $(DESTDIR)$(PREFIX)/bin
|
||||
cp -f st $(DESTDIR)$(PREFIX)/bin
|
||||
chmod 755 $(DESTDIR)$(PREFIX)/bin/st
|
||||
mkdir -p $(DESTDIR)$(MANPREFIX)/man1
|
||||
sed "s/VERSION/$(VERSION)/g" < st.1 > $(DESTDIR)$(MANPREFIX)/man1/st.1
|
||||
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1
|
||||
tic -sx st.info
|
||||
@echo Please see the README file regarding the terminfo entry of st.
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/st
|
||||
rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1
|
||||
|
||||
.PHONY: all clean dist install uninstall
|
||||
@@ -0,0 +1,34 @@
|
||||
st - simple terminal
|
||||
--------------------
|
||||
st is a simple terminal emulator for X which sucks less.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
In order to build st you need the Xlib header files.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
Edit config.mk to match your local setup (st is installed into
|
||||
the /usr/local namespace by default).
|
||||
|
||||
Afterwards enter the following command to build and install st (if
|
||||
necessary as root):
|
||||
|
||||
make clean install
|
||||
|
||||
|
||||
Running st
|
||||
----------
|
||||
If you did not install st with make clean install, you must compile
|
||||
the st terminfo entry with the following command:
|
||||
|
||||
tic -sx st.info
|
||||
|
||||
See the man page for additional details.
|
||||
|
||||
Credits
|
||||
-------
|
||||
Based on Aurélien APTEL <aurelien dot aptel at gmail dot com> bt source code.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
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
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copy me if you can.
|
||||
* by 20h
|
||||
*/
|
||||
|
||||
#ifndef ARG_H__
|
||||
#define ARG_H__
|
||||
|
||||
extern char *argv0;
|
||||
|
||||
/* use main(int argc, char *argv[]) */
|
||||
#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
|
||||
argv[0] && argv[0][0] == '-'\
|
||||
&& argv[0][1];\
|
||||
argc--, argv++) {\
|
||||
char argc_;\
|
||||
char **argv_;\
|
||||
int brk_;\
|
||||
if (argv[0][1] == '-' && argv[0][2] == '\0') {\
|
||||
argv++;\
|
||||
argc--;\
|
||||
break;\
|
||||
}\
|
||||
int i_;\
|
||||
for (i_ = 1, brk_ = 0, argv_ = argv;\
|
||||
argv[0][i_] && !brk_;\
|
||||
i_++) {\
|
||||
if (argv_ != argv)\
|
||||
break;\
|
||||
argc_ = argv[0][i_];\
|
||||
switch (argc_)
|
||||
|
||||
#define ARGEND }\
|
||||
}
|
||||
|
||||
#define ARGC() argc_
|
||||
|
||||
#define EARGF(x) ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\
|
||||
((x), abort(), (char *)0) :\
|
||||
(brk_ = 1, (argv[0][i_+1] != '\0')?\
|
||||
(&argv[0][i_+1]) :\
|
||||
(argc--, argv++, argv[0])))
|
||||
|
||||
#define ARGF() ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\
|
||||
(char *)0 :\
|
||||
(brk_ = 1, (argv[0][i_+1] != '\0')?\
|
||||
(&argv[0][i_+1]) :\
|
||||
(argc--, argv++, argv[0])))
|
||||
|
||||
#endif
|
||||
Executable
+194
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih
|
||||
* MIT/X Consortium License
|
||||
*/
|
||||
|
||||
#include <X11/Xft/Xft.h>
|
||||
#include "st.h"
|
||||
#include "boxdraw_data.h"
|
||||
|
||||
/* Rounded non-negative integers division of n / d */
|
||||
#define DIV(n, d) (((n) + (d) / 2) / (d))
|
||||
|
||||
static Display *xdpy;
|
||||
static Colormap xcmap;
|
||||
static XftDraw *xd;
|
||||
static Visual *xvis;
|
||||
|
||||
static void drawbox(int, int, int, int, XftColor *, XftColor *, ushort);
|
||||
static void drawboxlines(int, int, int, int, XftColor *, ushort);
|
||||
|
||||
/* public API */
|
||||
|
||||
void
|
||||
boxdraw_xinit(Display *dpy, Colormap cmap, XftDraw *draw, Visual *vis)
|
||||
{
|
||||
xdpy = dpy; xcmap = cmap; xd = draw, xvis = vis;
|
||||
}
|
||||
|
||||
int
|
||||
isboxdraw(Rune u)
|
||||
{
|
||||
Rune block = u & ~0xff;
|
||||
return (boxdraw && block == 0x2500 && boxdata[(uint8_t)u]) ||
|
||||
(boxdraw_braille && block == 0x2800);
|
||||
}
|
||||
|
||||
/* the "index" is actually the entire shape data encoded as ushort */
|
||||
ushort
|
||||
boxdrawindex(const Glyph *g)
|
||||
{
|
||||
if (boxdraw_braille && (g->u & ~0xff) == 0x2800)
|
||||
return BRL | (uint8_t)g->u;
|
||||
if (boxdraw_bold && (g->mode & ATTR_BOLD))
|
||||
return BDB | boxdata[(uint8_t)g->u];
|
||||
return boxdata[(uint8_t)g->u];
|
||||
}
|
||||
|
||||
void
|
||||
drawboxes(int x, int y, int cw, int ch, XftColor *fg, XftColor *bg,
|
||||
const XftGlyphFontSpec *specs, int len)
|
||||
{
|
||||
for ( ; len-- > 0; x += cw, specs++)
|
||||
drawbox(x, y, cw, ch, fg, bg, (ushort)specs->glyph);
|
||||
}
|
||||
|
||||
/* implementation */
|
||||
|
||||
void
|
||||
drawbox(int x, int y, int w, int h, XftColor *fg, XftColor *bg, ushort bd)
|
||||
{
|
||||
ushort cat = bd & ~(BDB | 0xff); /* mask out bold and data */
|
||||
if (bd & (BDL | BDA)) {
|
||||
/* lines (light/double/heavy/arcs) */
|
||||
drawboxlines(x, y, w, h, fg, bd);
|
||||
|
||||
} else if (cat == BBD) {
|
||||
/* lower (8-X)/8 block */
|
||||
int d = DIV((uint8_t)bd * h, 8);
|
||||
XftDrawRect(xd, fg, x, y + d, w, h - d);
|
||||
|
||||
} else if (cat == BBU) {
|
||||
/* upper X/8 block */
|
||||
XftDrawRect(xd, fg, x, y, w, DIV((uint8_t)bd * h, 8));
|
||||
|
||||
} else if (cat == BBL) {
|
||||
/* left X/8 block */
|
||||
XftDrawRect(xd, fg, x, y, DIV((uint8_t)bd * w, 8), h);
|
||||
|
||||
} else if (cat == BBR) {
|
||||
/* right (8-X)/8 block */
|
||||
int d = DIV((uint8_t)bd * w, 8);
|
||||
XftDrawRect(xd, fg, x + d, y, w - d, h);
|
||||
|
||||
} else if (cat == BBQ) {
|
||||
/* Quadrants */
|
||||
int w2 = DIV(w, 2), h2 = DIV(h, 2);
|
||||
if (bd & TL)
|
||||
XftDrawRect(xd, fg, x, y, w2, h2);
|
||||
if (bd & TR)
|
||||
XftDrawRect(xd, fg, x + w2, y, w - w2, h2);
|
||||
if (bd & BL)
|
||||
XftDrawRect(xd, fg, x, y + h2, w2, h - h2);
|
||||
if (bd & BR)
|
||||
XftDrawRect(xd, fg, x + w2, y + h2, w - w2, h - h2);
|
||||
|
||||
} else if (bd & BBS) {
|
||||
/* Shades - data is 1/2/3 for 25%/50%/75% alpha, respectively */
|
||||
int d = (uint8_t)bd;
|
||||
XftColor xfc;
|
||||
XRenderColor xrc = { .alpha = 0xffff };
|
||||
|
||||
xrc.red = DIV(fg->color.red * d + bg->color.red * (4 - d), 4);
|
||||
xrc.green = DIV(fg->color.green * d + bg->color.green * (4 - d), 4);
|
||||
xrc.blue = DIV(fg->color.blue * d + bg->color.blue * (4 - d), 4);
|
||||
|
||||
XftColorAllocValue(xdpy, xvis, xcmap, &xrc, &xfc);
|
||||
XftDrawRect(xd, &xfc, x, y, w, h);
|
||||
XftColorFree(xdpy, xvis, xcmap, &xfc);
|
||||
|
||||
} else if (cat == BRL) {
|
||||
/* braille, each data bit corresponds to one dot at 2x4 grid */
|
||||
int w1 = DIV(w, 2);
|
||||
int h1 = DIV(h, 4), h2 = DIV(h, 2), h3 = DIV(3 * h, 4);
|
||||
|
||||
if (bd & 1) XftDrawRect(xd, fg, x, y, w1, h1);
|
||||
if (bd & 2) XftDrawRect(xd, fg, x, y + h1, w1, h2 - h1);
|
||||
if (bd & 4) XftDrawRect(xd, fg, x, y + h2, w1, h3 - h2);
|
||||
if (bd & 8) XftDrawRect(xd, fg, x + w1, y, w - w1, h1);
|
||||
if (bd & 16) XftDrawRect(xd, fg, x + w1, y + h1, w - w1, h2 - h1);
|
||||
if (bd & 32) XftDrawRect(xd, fg, x + w1, y + h2, w - w1, h3 - h2);
|
||||
if (bd & 64) XftDrawRect(xd, fg, x, y + h3, w1, h - h3);
|
||||
if (bd & 128) XftDrawRect(xd, fg, x + w1, y + h3, w - w1, h - h3);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drawboxlines(int x, int y, int w, int h, XftColor *fg, ushort bd)
|
||||
{
|
||||
/* s: stem thickness. width/8 roughly matches underscore thickness. */
|
||||
/* We draw bold as 1.5 * normal-stem and at least 1px thicker. */
|
||||
/* doubles draw at least 3px, even when w or h < 3. bold needs 6px. */
|
||||
int mwh = MIN(w, h);
|
||||
int base_s = MAX(1, DIV(mwh, 8));
|
||||
int bold = (bd & BDB) && mwh >= 6; /* possibly ignore boldness */
|
||||
int s = bold ? MAX(base_s + 1, DIV(3 * base_s, 2)) : base_s;
|
||||
int w2 = DIV(w - s, 2), h2 = DIV(h - s, 2);
|
||||
/* the s-by-s square (x + w2, y + h2, s, s) is the center texel. */
|
||||
/* The base length (per direction till edge) includes this square. */
|
||||
|
||||
int light = bd & (LL | LU | LR | LD);
|
||||
int double_ = bd & (DL | DU | DR | DD);
|
||||
|
||||
if (light) {
|
||||
/* d: additional (negative) length to not-draw the center */
|
||||
/* texel - at arcs and avoid drawing inside (some) doubles */
|
||||
int arc = bd & BDA;
|
||||
int multi_light = light & (light - 1);
|
||||
int multi_double = double_ & (double_ - 1);
|
||||
/* light crosses double only at DH+LV, DV+LH (ref. shapes) */
|
||||
int d = arc || (multi_double && !multi_light) ? -s : 0;
|
||||
|
||||
if (bd & LL)
|
||||
XftDrawRect(xd, fg, x, y + h2, w2 + s + d, s);
|
||||
if (bd & LU)
|
||||
XftDrawRect(xd, fg, x + w2, y, s, h2 + s + d);
|
||||
if (bd & LR)
|
||||
XftDrawRect(xd, fg, x + w2 - d, y + h2, w - w2 + d, s);
|
||||
if (bd & LD)
|
||||
XftDrawRect(xd, fg, x + w2, y + h2 - d, s, h - h2 + d);
|
||||
}
|
||||
|
||||
/* double lines - also align with light to form heavy when combined */
|
||||
if (double_) {
|
||||
/*
|
||||
* going clockwise, for each double-ray: p is additional length
|
||||
* to the single-ray nearer to the previous direction, and n to
|
||||
* the next. p and n adjust from the base length to lengths
|
||||
* which consider other doubles - shorter to avoid intersections
|
||||
* (p, n), or longer to draw the far-corner texel (n).
|
||||
*/
|
||||
int dl = bd & DL, du = bd & DU, dr = bd & DR, dd = bd & DD;
|
||||
if (dl) {
|
||||
int p = dd ? -s : 0, n = du ? -s : dd ? s : 0;
|
||||
XftDrawRect(xd, fg, x, y + h2 + s, w2 + s + p, s);
|
||||
XftDrawRect(xd, fg, x, y + h2 - s, w2 + s + n, s);
|
||||
}
|
||||
if (du) {
|
||||
int p = dl ? -s : 0, n = dr ? -s : dl ? s : 0;
|
||||
XftDrawRect(xd, fg, x + w2 - s, y, s, h2 + s + p);
|
||||
XftDrawRect(xd, fg, x + w2 + s, y, s, h2 + s + n);
|
||||
}
|
||||
if (dr) {
|
||||
int p = du ? -s : 0, n = dd ? -s : du ? s : 0;
|
||||
XftDrawRect(xd, fg, x + w2 - p, y + h2 - s, w - w2 + p, s);
|
||||
XftDrawRect(xd, fg, x + w2 - n, y + h2 + s, w - w2 + n, s);
|
||||
}
|
||||
if (dd) {
|
||||
int p = dr ? -s : 0, n = dl ? -s : dr ? s : 0;
|
||||
XftDrawRect(xd, fg, x + w2 + s, y + h2 - p, s, h - h2 + p);
|
||||
XftDrawRect(xd, fg, x + w2 - s, y + h2 - n, s, h - h2 + n);
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+214
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih
|
||||
* MIT/X Consortium License
|
||||
*/
|
||||
|
||||
/*
|
||||
* U+25XX codepoints data
|
||||
*
|
||||
* References:
|
||||
* http://www.unicode.org/charts/PDF/U2500.pdf
|
||||
* http://www.unicode.org/charts/PDF/U2580.pdf
|
||||
*
|
||||
* Test page:
|
||||
* https://github.com/GNOME/vte/blob/master/doc/boxes.txt
|
||||
*/
|
||||
|
||||
/* Each shape is encoded as 16-bits. Higher bits are category, lower are data */
|
||||
/* Categories (mutually exclusive except BDB): */
|
||||
/* For convenience, BDL/BDA/BBS/BDB are 1 bit each, the rest are enums */
|
||||
#define BDL (1<<8) /* Box Draw Lines (light/double/heavy) */
|
||||
#define BDA (1<<9) /* Box Draw Arc (light) */
|
||||
|
||||
#define BBD (1<<10) /* Box Block Down (lower) X/8 */
|
||||
#define BBL (2<<10) /* Box Block Left X/8 */
|
||||
#define BBU (3<<10) /* Box Block Upper X/8 */
|
||||
#define BBR (4<<10) /* Box Block Right X/8 */
|
||||
#define BBQ (5<<10) /* Box Block Quadrants */
|
||||
#define BRL (6<<10) /* Box Braille (data is lower byte of U28XX) */
|
||||
|
||||
#define BBS (1<<14) /* Box Block Shades */
|
||||
#define BDB (1<<15) /* Box Draw is Bold */
|
||||
|
||||
/* (BDL/BDA) Light/Double/Heavy x Left/Up/Right/Down/Horizontal/Vertical */
|
||||
/* Heavy is light+double (literally drawing light+double align to form heavy) */
|
||||
#define LL (1<<0)
|
||||
#define LU (1<<1)
|
||||
#define LR (1<<2)
|
||||
#define LD (1<<3)
|
||||
#define LH (LL+LR)
|
||||
#define LV (LU+LD)
|
||||
|
||||
#define DL (1<<4)
|
||||
#define DU (1<<5)
|
||||
#define DR (1<<6)
|
||||
#define DD (1<<7)
|
||||
#define DH (DL+DR)
|
||||
#define DV (DU+DD)
|
||||
|
||||
#define HL (LL+DL)
|
||||
#define HU (LU+DU)
|
||||
#define HR (LR+DR)
|
||||
#define HD (LD+DD)
|
||||
#define HH (HL+HR)
|
||||
#define HV (HU+HD)
|
||||
|
||||
/* (BBQ) Quadrants Top/Bottom x Left/Right */
|
||||
#define TL (1<<0)
|
||||
#define TR (1<<1)
|
||||
#define BL (1<<2)
|
||||
#define BR (1<<3)
|
||||
|
||||
/* Data for U+2500 - U+259F except dashes/diagonals */
|
||||
static const unsigned short boxdata[256] = {
|
||||
/* light lines */
|
||||
[0x00] = BDL + LH, /* light horizontal */
|
||||
[0x02] = BDL + LV, /* light vertical */
|
||||
[0x0c] = BDL + LD + LR, /* light down and right */
|
||||
[0x10] = BDL + LD + LL, /* light down and left */
|
||||
[0x14] = BDL + LU + LR, /* light up and right */
|
||||
[0x18] = BDL + LU + LL, /* light up and left */
|
||||
[0x1c] = BDL + LV + LR, /* light vertical and right */
|
||||
[0x24] = BDL + LV + LL, /* light vertical and left */
|
||||
[0x2c] = BDL + LH + LD, /* light horizontal and down */
|
||||
[0x34] = BDL + LH + LU, /* light horizontal and up */
|
||||
[0x3c] = BDL + LV + LH, /* light vertical and horizontal */
|
||||
[0x74] = BDL + LL, /* light left */
|
||||
[0x75] = BDL + LU, /* light up */
|
||||
[0x76] = BDL + LR, /* light right */
|
||||
[0x77] = BDL + LD, /* light down */
|
||||
|
||||
/* heavy [+light] lines */
|
||||
[0x01] = BDL + HH,
|
||||
[0x03] = BDL + HV,
|
||||
[0x0d] = BDL + HR + LD,
|
||||
[0x0e] = BDL + HD + LR,
|
||||
[0x0f] = BDL + HD + HR,
|
||||
[0x11] = BDL + HL + LD,
|
||||
[0x12] = BDL + HD + LL,
|
||||
[0x13] = BDL + HD + HL,
|
||||
[0x15] = BDL + HR + LU,
|
||||
[0x16] = BDL + HU + LR,
|
||||
[0x17] = BDL + HU + HR,
|
||||
[0x19] = BDL + HL + LU,
|
||||
[0x1a] = BDL + HU + LL,
|
||||
[0x1b] = BDL + HU + HL,
|
||||
[0x1d] = BDL + HR + LV,
|
||||
[0x1e] = BDL + HU + LD + LR,
|
||||
[0x1f] = BDL + HD + LR + LU,
|
||||
[0x20] = BDL + HV + LR,
|
||||
[0x21] = BDL + HU + HR + LD,
|
||||
[0x22] = BDL + HD + HR + LU,
|
||||
[0x23] = BDL + HV + HR,
|
||||
[0x25] = BDL + HL + LV,
|
||||
[0x26] = BDL + HU + LD + LL,
|
||||
[0x27] = BDL + HD + LU + LL,
|
||||
[0x28] = BDL + HV + LL,
|
||||
[0x29] = BDL + HU + HL + LD,
|
||||
[0x2a] = BDL + HD + HL + LU,
|
||||
[0x2b] = BDL + HV + HL,
|
||||
[0x2d] = BDL + HL + LD + LR,
|
||||
[0x2e] = BDL + HR + LL + LD,
|
||||
[0x2f] = BDL + HH + LD,
|
||||
[0x30] = BDL + HD + LH,
|
||||
[0x31] = BDL + HD + HL + LR,
|
||||
[0x32] = BDL + HR + HD + LL,
|
||||
[0x33] = BDL + HH + HD,
|
||||
[0x35] = BDL + HL + LU + LR,
|
||||
[0x36] = BDL + HR + LU + LL,
|
||||
[0x37] = BDL + HH + LU,
|
||||
[0x38] = BDL + HU + LH,
|
||||
[0x39] = BDL + HU + HL + LR,
|
||||
[0x3a] = BDL + HU + HR + LL,
|
||||
[0x3b] = BDL + HH + HU,
|
||||
[0x3d] = BDL + HL + LV + LR,
|
||||
[0x3e] = BDL + HR + LV + LL,
|
||||
[0x3f] = BDL + HH + LV,
|
||||
[0x40] = BDL + HU + LH + LD,
|
||||
[0x41] = BDL + HD + LH + LU,
|
||||
[0x42] = BDL + HV + LH,
|
||||
[0x43] = BDL + HU + HL + LD + LR,
|
||||
[0x44] = BDL + HU + HR + LD + LL,
|
||||
[0x45] = BDL + HD + HL + LU + LR,
|
||||
[0x46] = BDL + HD + HR + LU + LL,
|
||||
[0x47] = BDL + HH + HU + LD,
|
||||
[0x48] = BDL + HH + HD + LU,
|
||||
[0x49] = BDL + HV + HL + LR,
|
||||
[0x4a] = BDL + HV + HR + LL,
|
||||
[0x4b] = BDL + HV + HH,
|
||||
[0x78] = BDL + HL,
|
||||
[0x79] = BDL + HU,
|
||||
[0x7a] = BDL + HR,
|
||||
[0x7b] = BDL + HD,
|
||||
[0x7c] = BDL + HR + LL,
|
||||
[0x7d] = BDL + HD + LU,
|
||||
[0x7e] = BDL + HL + LR,
|
||||
[0x7f] = BDL + HU + LD,
|
||||
|
||||
/* double [+light] lines */
|
||||
[0x50] = BDL + DH,
|
||||
[0x51] = BDL + DV,
|
||||
[0x52] = BDL + DR + LD,
|
||||
[0x53] = BDL + DD + LR,
|
||||
[0x54] = BDL + DR + DD,
|
||||
[0x55] = BDL + DL + LD,
|
||||
[0x56] = BDL + DD + LL,
|
||||
[0x57] = BDL + DL + DD,
|
||||
[0x58] = BDL + DR + LU,
|
||||
[0x59] = BDL + DU + LR,
|
||||
[0x5a] = BDL + DU + DR,
|
||||
[0x5b] = BDL + DL + LU,
|
||||
[0x5c] = BDL + DU + LL,
|
||||
[0x5d] = BDL + DL + DU,
|
||||
[0x5e] = BDL + DR + LV,
|
||||
[0x5f] = BDL + DV + LR,
|
||||
[0x60] = BDL + DV + DR,
|
||||
[0x61] = BDL + DL + LV,
|
||||
[0x62] = BDL + DV + LL,
|
||||
[0x63] = BDL + DV + DL,
|
||||
[0x64] = BDL + DH + LD,
|
||||
[0x65] = BDL + DD + LH,
|
||||
[0x66] = BDL + DD + DH,
|
||||
[0x67] = BDL + DH + LU,
|
||||
[0x68] = BDL + DU + LH,
|
||||
[0x69] = BDL + DH + DU,
|
||||
[0x6a] = BDL + DH + LV,
|
||||
[0x6b] = BDL + DV + LH,
|
||||
[0x6c] = BDL + DH + DV,
|
||||
|
||||
/* (light) arcs */
|
||||
[0x6d] = BDA + LD + LR,
|
||||
[0x6e] = BDA + LD + LL,
|
||||
[0x6f] = BDA + LU + LL,
|
||||
[0x70] = BDA + LU + LR,
|
||||
|
||||
/* Lower (Down) X/8 block (data is 8 - X) */
|
||||
[0x81] = BBD + 7, [0x82] = BBD + 6, [0x83] = BBD + 5, [0x84] = BBD + 4,
|
||||
[0x85] = BBD + 3, [0x86] = BBD + 2, [0x87] = BBD + 1, [0x88] = BBD + 0,
|
||||
|
||||
/* Left X/8 block (data is X) */
|
||||
[0x89] = BBL + 7, [0x8a] = BBL + 6, [0x8b] = BBL + 5, [0x8c] = BBL + 4,
|
||||
[0x8d] = BBL + 3, [0x8e] = BBL + 2, [0x8f] = BBL + 1,
|
||||
|
||||
/* upper 1/2 (4/8), 1/8 block (X), right 1/2, 1/8 block (8-X) */
|
||||
[0x80] = BBU + 4, [0x94] = BBU + 1,
|
||||
[0x90] = BBR + 4, [0x95] = BBR + 7,
|
||||
|
||||
/* Quadrants */
|
||||
[0x96] = BBQ + BL,
|
||||
[0x97] = BBQ + BR,
|
||||
[0x98] = BBQ + TL,
|
||||
[0x99] = BBQ + TL + BL + BR,
|
||||
[0x9a] = BBQ + TL + BR,
|
||||
[0x9b] = BBQ + TL + TR + BL,
|
||||
[0x9c] = BBQ + TL + TR + BR,
|
||||
[0x9d] = BBQ + TR,
|
||||
[0x9e] = BBQ + BL + TR,
|
||||
[0x9f] = BBQ + BL + TR + BR,
|
||||
|
||||
/* Shades, data is an alpha value in 25% units (1/4, 1/2, 3/4) */
|
||||
[0x91] = BBS + 1, [0x92] = BBS + 2, [0x93] = BBS + 3,
|
||||
|
||||
/* U+2504 - U+250B, U+254C - U+254F: unsupported (dashes) */
|
||||
/* U+2571 - U+2573: unsupported (diagonals) */
|
||||
};
|
||||
Executable
+517
@@ -0,0 +1,517 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
/*
|
||||
* appearance
|
||||
*
|
||||
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||
*/
|
||||
static const char *font = "CaskaydiaMonoNerdFontMono-Bold:size=14:style=Bold";
|
||||
/* Spare fonts */
|
||||
|
||||
static char *font2[] = {
|
||||
"CaskaydiaMonoNerdFontMono-Bold:pixelsize=12:antialias=true:autohint=true"};
|
||||
static int borderpx = 6;
|
||||
|
||||
/* How to align the content in the window when the size of the terminal
|
||||
* doesn't perfectly match the size of the window. The values are percentages.
|
||||
* 50 means center, 0 means flush left/top, 100 means flush right/bottom.
|
||||
*/
|
||||
static int anysize_halign = 50;
|
||||
static int anysize_valign = 50;
|
||||
|
||||
/*
|
||||
* What program is execed by st depends of these precedence rules:
|
||||
* 1: program passed with -e
|
||||
* 2: scroll and/or utmp
|
||||
* 3: SHELL environment variable
|
||||
* 4: value of shell in /etc/passwd
|
||||
* 5: value of shell in config.h
|
||||
*/
|
||||
static char *shell = "/bin/sh";
|
||||
char *utmp = NULL;
|
||||
/* scroll program: to enable use a string like "scroll" */
|
||||
char *scroll = NULL;
|
||||
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
|
||||
|
||||
/* identification sequence returned in DA and DECID */
|
||||
/* By default, use the same one as kitty. */
|
||||
|
||||
char *vtiden = "\033[?62c";
|
||||
//char *vtiden = "\x1b[?62;4c";
|
||||
|
||||
/* Kerning / character bounding-box multipliers */
|
||||
static float cwscale = 1;
|
||||
static float chscale = 1;
|
||||
|
||||
/*
|
||||
* word delimiter string
|
||||
*
|
||||
* More advanced example: L" `'\"()[]{}"
|
||||
*/
|
||||
wchar_t *worddelimiters = L" ";
|
||||
|
||||
/* selection timeouts (in milliseconds) */
|
||||
static unsigned int doubleclicktimeout = 300;
|
||||
static unsigned int tripleclicktimeout = 600;
|
||||
|
||||
/* alt screens */
|
||||
int allowaltscreen = 1;
|
||||
|
||||
/* allow certain non-interactive (insecure) window operations such as:
|
||||
setting the clipboard text */
|
||||
int allowwindowops = 0;
|
||||
|
||||
/*
|
||||
* draw latency range in ms - from new content/keypress/etc until drawing.
|
||||
* within this range, st draws when content stops arriving (idle). mostly it's
|
||||
* near minlatency, but it waits longer for slow updates to avoid partial draw.
|
||||
* low minlatency will tear/flicker more, as it can "detect" idle too early.
|
||||
*/
|
||||
static double minlatency = 1;
|
||||
static double maxlatency = 10;
|
||||
|
||||
/*
|
||||
* blinking timeout (set to 0 to disable blinking) for the terminal blinking
|
||||
* attribute.
|
||||
*/
|
||||
static unsigned int blinktimeout = 100;
|
||||
|
||||
/*
|
||||
* thickness of underline and bar cursors
|
||||
*/
|
||||
static unsigned int cursorthickness = 2;
|
||||
|
||||
/*
|
||||
* 1: render most of the lines/blocks characters without using the font for
|
||||
* perfect alignment between cells (U2500 - U259F except dashes/diagonals).
|
||||
* Bold affects lines thickness if boxdraw_bold is not 0. Italic is ignored.
|
||||
* 0: disable (render all U25XX glyphs normally from the font).
|
||||
*/
|
||||
const int boxdraw = 1;
|
||||
const int boxdraw_bold = 1;
|
||||
|
||||
/* braille (U28XX): 1: render as adjacent "pixels", 0: use font */
|
||||
const int boxdraw_braille = 0;
|
||||
|
||||
/*
|
||||
* bell volume. It must be a value between -100 and 100. Use 0 for disabling
|
||||
* it
|
||||
*/
|
||||
static int bellvolume = 0;
|
||||
|
||||
/* default TERM value */
|
||||
char *termname = "st";
|
||||
|
||||
/*
|
||||
* spaces per tab
|
||||
*
|
||||
* When you are changing this value, don't forget to adapt the »it« value in
|
||||
* the st.info and appropriately install the st.info in the environment where
|
||||
* you use this st version.
|
||||
*
|
||||
* it#$tabspaces,
|
||||
*
|
||||
* Secondly make sure your kernel is not expanding tabs. When running `stty
|
||||
* -a` »tab0« should appear. You can tell the terminal to not expand tabs by
|
||||
* running following command:
|
||||
*
|
||||
* stty tabs
|
||||
*/
|
||||
unsigned int tabspaces = 8;
|
||||
|
||||
/* Terminal colors (16 first used in escape sequence) */
|
||||
static const char *colorname[] = {
|
||||
/* 8 normal colors */
|
||||
"black", "red3", "green3", "yellow3", "blue2", "magenta3", "cyan3",
|
||||
"gray90",
|
||||
|
||||
/* 8 bright colors */
|
||||
"gray50", "red", "green", "yellow", "#5c5cff", "magenta", "cyan", "white",
|
||||
|
||||
[255] = 0,
|
||||
|
||||
/* more colors can be added after 255 to use with DefaultXX */
|
||||
"#cccccc", "#555555", "gray90", /* default foreground colour */
|
||||
"black", /* default background colour */
|
||||
};
|
||||
|
||||
/*
|
||||
* Default colors (colorname index)
|
||||
* foreground, background, cursor, reverse cursor
|
||||
*/
|
||||
unsigned int defaultfg = 258;
|
||||
unsigned int defaultbg = 259;
|
||||
unsigned int defaultcs = 256;
|
||||
static unsigned int defaultrcs = 257;
|
||||
|
||||
/*
|
||||
* Default shape of cursor
|
||||
* 2: Block ("█")
|
||||
* 4: Underline ("_")
|
||||
* 6: Bar ("|")
|
||||
* 7: Snowman ("☃")
|
||||
*/
|
||||
static unsigned int cursorshape = 2;
|
||||
|
||||
/*
|
||||
* Default columns and rows numbers
|
||||
*/
|
||||
|
||||
static unsigned int cols = 80;
|
||||
static unsigned int rows = 24;
|
||||
|
||||
/*
|
||||
* Default colour and shape of the mouse cursor
|
||||
*/
|
||||
static unsigned int mouseshape = XC_xterm;
|
||||
static unsigned int mousefg = 7;
|
||||
static unsigned int mousebg = 0;
|
||||
|
||||
/*
|
||||
* Color used to display font attributes when fontconfig selected a font which
|
||||
* doesn't match the ones requested.
|
||||
*/
|
||||
static unsigned int defaultattr = 11;
|
||||
|
||||
/*
|
||||
* Graphics configuration
|
||||
*/
|
||||
|
||||
/// The template for the cache directory.
|
||||
const char graphics_cache_dir_template[] = "/tmp/st-images-XXXXXX";
|
||||
/// The max size of a single image file, in bytes.
|
||||
unsigned graphics_max_single_image_file_size = 20 * 1024 * 1024;
|
||||
/// The max size of the cache, in bytes.
|
||||
unsigned graphics_total_file_cache_size = 300 * 1024 * 1024;
|
||||
/// The max ram size of an image or placement, in bytes.
|
||||
unsigned graphics_max_single_image_ram_size = 100 * 1024 * 1024;
|
||||
/// The max total size of all images loaded into RAM.
|
||||
unsigned graphics_max_total_ram_size = 300 * 1024 * 1024;
|
||||
/// The max total number of image placements and images.
|
||||
unsigned graphics_max_total_placements = 4096;
|
||||
/// The ratio by which limits can be exceeded. This is to reduce the frequency
|
||||
/// of image removal.
|
||||
double graphics_excess_tolerance_ratio = 0.05;
|
||||
/// The minimum delay between redraws caused by animations, in milliseconds.
|
||||
unsigned graphics_animation_min_delay = 20;
|
||||
|
||||
/*
|
||||
* Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
|
||||
* Note that if you want to use ShiftMask with selmasks, set this to an other
|
||||
* modifier, set to 0 to not use it.
|
||||
*/
|
||||
static uint forcemousemod = ShiftMask;
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
#define MODKEY Mod1Mask
|
||||
#define TERMMOD (ControlMask | ShiftMask)
|
||||
|
||||
/*
|
||||
* Internal mouse shortcuts.
|
||||
* Beware that overloading Button1 will disable the selection.
|
||||
*/
|
||||
static MouseShortcut mshortcuts[] = {
|
||||
/* mask button function argument release */
|
||||
{TERMMOD, Button3, previewimage, {.s = "feh"}},
|
||||
{TERMMOD, Button2, showimageinfo, {}, 1},
|
||||
{XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1},
|
||||
{ShiftMask, Button4, kscrollup, {.i = 1}},
|
||||
{ShiftMask, Button5, kscrolldown, {.i = 1}},
|
||||
{ShiftMask, Button4, ttysend, {.s = "\033[5;2~"}},
|
||||
{XK_ANY_MOD, Button4, ttysend, {.s = "\031"}},
|
||||
{ShiftMask, Button5, ttysend, {.s = "\033[6;2~"}},
|
||||
{XK_ANY_MOD, Button5, ttysend, {.s = "\005"}},
|
||||
};
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
|
||||
static Shortcut shortcuts[] = {
|
||||
/* mask keysym function argument */
|
||||
{TERMMOD, XK_F1, togglegrdebug, {.i = 0}},
|
||||
{TERMMOD, XK_F6, dumpgrstate, {.i = 0}},
|
||||
{TERMMOD, XK_F7, unloadimages, {.i = 0}},
|
||||
{TERMMOD, XK_F8, toggleimages, {.i = 0}},
|
||||
{XK_ANY_MOD, XK_Break, sendbreak, {.i = 0}},
|
||||
{ControlMask, XK_Print, toggleprinter, {.i = 0}},
|
||||
{ShiftMask, XK_Print, printscreen, {.i = 0}},
|
||||
{XK_ANY_MOD, XK_Print, printsel, {.i = 0}},
|
||||
{TERMMOD, XK_C, clipcopy, {.i = 0}},
|
||||
{TERMMOD, XK_V, clippaste, {.i = 0}},
|
||||
{TERMMOD, XK_Y, selpaste, {.i = 0}},
|
||||
{ShiftMask, XK_Page_Up, kscrollup, {.i = -1}},
|
||||
{ShiftMask, XK_Page_Down, kscrolldown, {.i = -1}},
|
||||
{ShiftMask, XK_Insert, selpaste, {.i = 0}},
|
||||
{TERMMOD, XK_Num_Lock, numlock, {.i = 0}},
|
||||
{TERMMOD, XK_plus, zoom, {.f = +1}},
|
||||
{TERMMOD, XK_underscore, zoom, {.f = -1}},
|
||||
{TERMMOD, XK_equal, zoomreset, {0}},
|
||||
};
|
||||
|
||||
/*
|
||||
* Special keys (change & recompile st.info accordingly)
|
||||
*
|
||||
* Mask value:
|
||||
* * Use XK_ANY_MOD to match the key no matter modifiers state
|
||||
* * Use XK_NO_MOD to match the key alone (no modifiers)
|
||||
* appkey value:
|
||||
* * 0: no value
|
||||
* * > 0: keypad application mode enabled
|
||||
* * = 2: term.numlock = 1
|
||||
* * < 0: keypad application mode disabled
|
||||
* appcursor value:
|
||||
* * 0: no value
|
||||
* * > 0: cursor application mode enabled
|
||||
* * < 0: cursor application mode disabled
|
||||
*
|
||||
* Be careful with the order of the definitions because st searches in
|
||||
* this table sequentially, so any XK_ANY_MOD must be in the last
|
||||
* position for a key.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
|
||||
* to be mapped below, add them to this array.
|
||||
*/
|
||||
static KeySym mappedkeys[] = {-1};
|
||||
|
||||
/*
|
||||
* State bits to ignore when matching key or button events. By default,
|
||||
* numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
|
||||
*/
|
||||
static uint ignoremod = Mod2Mask | XK_SWITCH_MOD;
|
||||
|
||||
/*
|
||||
* This is the huge key array which defines all compatibility to the Linux
|
||||
* world. Please decide about changes wisely.
|
||||
*/
|
||||
static Key key[] = {
|
||||
/* keysym mask string appkey appcursor */
|
||||
{XK_KP_Home, ShiftMask, "\033[2J", 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[1~", 0, +1},
|
||||
{XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
|
||||
{XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
|
||||
{XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
|
||||
{XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
|
||||
{XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
|
||||
{XK_KP_End, ControlMask, "\033[J", -1, 0},
|
||||
{XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{XK_KP_End, ShiftMask, "\033[K", -1, 0},
|
||||
{XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{XK_KP_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{XK_KP_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
|
||||
{XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
|
||||
{XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
|
||||
{XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
|
||||
{XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
|
||||
{XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
|
||||
{XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
|
||||
{XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
|
||||
{XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
|
||||
{XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
|
||||
{XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
|
||||
{XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
|
||||
{XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
|
||||
{XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
|
||||
{XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
|
||||
{XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
|
||||
{XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
|
||||
{XK_Up, ShiftMask, "\033[1;2A", 0, 0},
|
||||
{XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
|
||||
{XK_Up, ShiftMask | Mod1Mask, "\033[1;4A", 0, 0},
|
||||
{XK_Up, ControlMask, "\033[1;5A", 0, 0},
|
||||
{XK_Up, ShiftMask | ControlMask, "\033[1;6A", 0, 0},
|
||||
{XK_Up, ControlMask | Mod1Mask, "\033[1;7A", 0, 0},
|
||||
{XK_Up, ShiftMask | ControlMask | Mod1Mask, "\033[1;8A", 0, 0},
|
||||
{XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{XK_Down, ShiftMask, "\033[1;2B", 0, 0},
|
||||
{XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
|
||||
{XK_Down, ShiftMask | Mod1Mask, "\033[1;4B", 0, 0},
|
||||
{XK_Down, ControlMask, "\033[1;5B", 0, 0},
|
||||
{XK_Down, ShiftMask | ControlMask, "\033[1;6B", 0, 0},
|
||||
{XK_Down, ControlMask | Mod1Mask, "\033[1;7B", 0, 0},
|
||||
{XK_Down, ShiftMask | ControlMask | Mod1Mask, "\033[1;8B", 0, 0},
|
||||
{XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{XK_Left, ShiftMask, "\033[1;2D", 0, 0},
|
||||
{XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
|
||||
{XK_Left, ShiftMask | Mod1Mask, "\033[1;4D", 0, 0},
|
||||
{XK_Left, ControlMask, "\033[1;5D", 0, 0},
|
||||
{XK_Left, ShiftMask | ControlMask, "\033[1;6D", 0, 0},
|
||||
{XK_Left, ControlMask | Mod1Mask, "\033[1;7D", 0, 0},
|
||||
{XK_Left, ShiftMask | ControlMask | Mod1Mask, "\033[1;8D", 0, 0},
|
||||
{XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{XK_Right, ShiftMask, "\033[1;2C", 0, 0},
|
||||
{XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
|
||||
{XK_Right, ShiftMask | Mod1Mask, "\033[1;4C", 0, 0},
|
||||
{XK_Right, ControlMask, "\033[1;5C", 0, 0},
|
||||
{XK_Right, ShiftMask | ControlMask, "\033[1;6C", 0, 0},
|
||||
{XK_Right, ControlMask | Mod1Mask, "\033[1;7C", 0, 0},
|
||||
{XK_Right, ShiftMask | ControlMask | Mod1Mask, "\033[1;8C", 0, 0},
|
||||
{XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
|
||||
{XK_Return, Mod1Mask, "\033\r", 0, 0},
|
||||
{XK_Return, XK_ANY_MOD, "\r", 0, 0},
|
||||
{XK_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{XK_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{XK_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{XK_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{XK_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{XK_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
|
||||
{XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
|
||||
{XK_Home, ShiftMask, "\033[2J", 0, -1},
|
||||
{XK_Home, ShiftMask, "\033[1;2H", 0, +1},
|
||||
{XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
||||
{XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
||||
{XK_End, ControlMask, "\033[J", -1, 0},
|
||||
{XK_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{XK_End, ShiftMask, "\033[K", -1, 0},
|
||||
{XK_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{XK_Prior, ControlMask, "\033[5;5~", 0, 0},
|
||||
{XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{XK_Next, ControlMask, "\033[6;5~", 0, 0},
|
||||
{XK_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{XK_F1, XK_NO_MOD, "\033OP", 0, 0},
|
||||
{XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
|
||||
{XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
|
||||
{XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
|
||||
{XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
|
||||
{XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
|
||||
{XK_F2, XK_NO_MOD, "\033OQ", 0, 0},
|
||||
{XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
|
||||
{XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
|
||||
{XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
|
||||
{XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
|
||||
{XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
|
||||
{XK_F3, XK_NO_MOD, "\033OR", 0, 0},
|
||||
{XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
|
||||
{XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
|
||||
{XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
|
||||
{XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
|
||||
{XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
|
||||
{XK_F4, XK_NO_MOD, "\033OS", 0, 0},
|
||||
{XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
|
||||
{XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
|
||||
{XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
|
||||
{XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
|
||||
{XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
|
||||
{XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
|
||||
{XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
|
||||
{XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
|
||||
{XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
|
||||
{XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
|
||||
{XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
|
||||
{XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
|
||||
{XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
|
||||
{XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
|
||||
{XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
|
||||
{XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
|
||||
{XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
|
||||
{XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
|
||||
{XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
|
||||
{XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
|
||||
{XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
|
||||
{XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
|
||||
{XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
|
||||
{XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
|
||||
{XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
|
||||
{XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
|
||||
{XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
|
||||
{XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
|
||||
{XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
|
||||
{XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
|
||||
{XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
|
||||
{XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
|
||||
{XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
|
||||
{XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
|
||||
{XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
|
||||
{XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
|
||||
{XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
|
||||
{XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
|
||||
{XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
|
||||
{XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
|
||||
{XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
|
||||
{XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
|
||||
{XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
|
||||
{XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
|
||||
{XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
|
||||
{XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
|
||||
{XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
|
||||
{XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
|
||||
{XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
|
||||
{XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
|
||||
{XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
|
||||
{XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
|
||||
{XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
|
||||
{XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
|
||||
{XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
|
||||
{XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
|
||||
{XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
|
||||
{XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
|
||||
{XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
|
||||
{XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
|
||||
{XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
|
||||
{XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
|
||||
{XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
|
||||
{XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
|
||||
{XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
|
||||
{XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
|
||||
{XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
|
||||
};
|
||||
|
||||
/*
|
||||
* Selection types' masks.
|
||||
* Use the same masks as usual.
|
||||
* Button1Mask is always unset, to make masks match between ButtonPress.
|
||||
* ButtonRelease and MotionNotify.
|
||||
* If no match is found, regular selection is used.
|
||||
*/
|
||||
static uint selmasks[] = {
|
||||
[SEL_RECTANGULAR] = Mod1Mask,
|
||||
};
|
||||
|
||||
/*
|
||||
* Printable characters in ASCII, used to estimate the advance width
|
||||
* of single wide characters.
|
||||
*/
|
||||
static char ascii_printable[] = " !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
Executable
+336
@@ -0,0 +1,336 @@
|
||||
static char *font =
|
||||
"JetBrainsMono Nerd Font:size=11:antialias=true:autohint=true";
|
||||
static int borderpx = 2;
|
||||
|
||||
static char *shell = "/bin/sh";
|
||||
char *utmp = NULL;
|
||||
char *scroll = NULL;
|
||||
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
|
||||
|
||||
char *vtiden = "\033[?6c";
|
||||
|
||||
static float cwscale = 0.95;
|
||||
static float chscale = 0.95;
|
||||
|
||||
wchar_t *worddelimiters = L" ";
|
||||
|
||||
static unsigned int doubleclicktimeout = 300;
|
||||
static unsigned int tripleclicktimeout = 600;
|
||||
|
||||
int allowaltscreen = 1;
|
||||
|
||||
int allowwindowops = 0;
|
||||
|
||||
static double minlatency = 2;
|
||||
static double maxlatency = 33;
|
||||
|
||||
static unsigned int blinktimeout = 800;
|
||||
|
||||
static unsigned int cursorthickness = 2;
|
||||
|
||||
static int bellvolume = 0;
|
||||
|
||||
char *termname = "xterm";
|
||||
|
||||
unsigned int tabspaces = 8;
|
||||
|
||||
float alpha = 0.95;
|
||||
float alpha_def;
|
||||
|
||||
static const char *colorname[] = {
|
||||
"#e7d8b1", "#F38BA8", "#A6E3A1", "#F9E2AF", "#89B4FA", "#F5C2E7", "#94E2D5",
|
||||
"#CDD6F4", "#6C7086", "#F38BA8", "#A6E3A1", "#F9E2AF", "#89B4FA", "#F5C2E7",
|
||||
"#94E2D5", "#ECEFFF", [255] = 0, "#CDD6F4", "#1E1E2E",
|
||||
};
|
||||
|
||||
unsigned int defaultfg = 256;
|
||||
unsigned int defaultbg = 257;
|
||||
unsigned int defaultcs = 256;
|
||||
static unsigned int defaultrcs = 257;
|
||||
|
||||
/*
|
||||
* Default shape of cursor
|
||||
* 2: Block ("█")
|
||||
* 4: Underline ("_")
|
||||
* 6: Pipe ("|")
|
||||
* 7: Snowman ("☃")
|
||||
*/
|
||||
static unsigned int cursorshape = 2;
|
||||
|
||||
static unsigned int cols = 160;
|
||||
static unsigned int rows = 40;
|
||||
|
||||
static unsigned int mouseshape = XC_xterm;
|
||||
static unsigned int mousefg = 7;
|
||||
static unsigned int mousebg = 0;
|
||||
|
||||
static unsigned int defaultattr = 11;
|
||||
|
||||
static uint forcemousemod = ShiftMask;
|
||||
|
||||
static MouseShortcut mshortcuts[] = {
|
||||
/* mask button function argument release */
|
||||
{XK_NO_MOD, Button4, kscrollup, {.i = 1}},
|
||||
{XK_NO_MOD, Button5, kscrolldown, {.i = 1}},
|
||||
{XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1},
|
||||
{ShiftMask, Button4, ttysend, {.s = "\033[5;2~"}},
|
||||
{XK_ANY_MOD, Button4, ttysend, {.s = "\031"}},
|
||||
{ShiftMask, Button5, ttysend, {.s = "\033[6;2~"}},
|
||||
{XK_ANY_MOD, Button5, ttysend, {.s = "\005"}},
|
||||
};
|
||||
|
||||
#define MODKEY Mod1Mask
|
||||
#define TERMMOD (Mod1Mask | ShiftMask)
|
||||
|
||||
static Shortcut shortcuts[] = {
|
||||
{XK_ANY_MOD, XK_Break, sendbreak, {.i = 0}},
|
||||
{ControlMask, XK_Print, toggleprinter, {.i = 0}},
|
||||
{ShiftMask, XK_Print, printscreen, {.i = 0}},
|
||||
{XK_ANY_MOD, XK_Print, printsel, {.i = 0}},
|
||||
{ControlMask, XK_equal, zoom, {.f = +1}},
|
||||
{ControlMask, XK_minus, zoom, {.f = -1}},
|
||||
{TERMMOD, XK_Home, zoomreset, {.f = 0}},
|
||||
{MODKEY, XK_c, clipcopy, {.i = 0}},
|
||||
{MODKEY, XK_v, clippaste, {.i = 0}},
|
||||
{TERMMOD, XK_Y, selpaste, {.i = 0}},
|
||||
{ShiftMask, XK_Insert, selpaste, {.i = 0}},
|
||||
{TERMMOD, XK_Num_Lock, numlock, {.i = 0}},
|
||||
{MODKEY, XK_k, kscrollup, {.i = 1}},
|
||||
{MODKEY, XK_j, kscrolldown, {.i = 1}},
|
||||
};
|
||||
|
||||
static KeySym mappedkeys[] = {-1};
|
||||
|
||||
static uint ignoremod = Mod2Mask | XK_SWITCH_MOD;
|
||||
|
||||
static Key key[] = {
|
||||
/* keysym mask string appkey appcursor */
|
||||
{XK_KP_Home, ShiftMask, "\033[2J", 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[1~", 0, +1},
|
||||
{XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
|
||||
{XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
|
||||
{XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
|
||||
{XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
|
||||
{XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
|
||||
{XK_KP_End, ControlMask, "\033[J", -1, 0},
|
||||
{XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{XK_KP_End, ShiftMask, "\033[K", -1, 0},
|
||||
{XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{XK_KP_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{XK_KP_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
|
||||
{XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
|
||||
{XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
|
||||
{XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
|
||||
{XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
|
||||
{XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
|
||||
{XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
|
||||
{XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
|
||||
{XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
|
||||
{XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
|
||||
{XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
|
||||
{XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
|
||||
{XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
|
||||
{XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
|
||||
{XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
|
||||
{XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
|
||||
{XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
|
||||
{XK_Up, ShiftMask, "\033[1;2A", 0, 0},
|
||||
{XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
|
||||
{XK_Up, ShiftMask | Mod1Mask, "\033[1;4A", 0, 0},
|
||||
{XK_Up, ControlMask, "\033[1;5A", 0, 0},
|
||||
{XK_Up, ShiftMask | ControlMask, "\033[1;6A", 0, 0},
|
||||
{XK_Up, ControlMask | Mod1Mask, "\033[1;7A", 0, 0},
|
||||
{XK_Up, ShiftMask | ControlMask | Mod1Mask, "\033[1;8A", 0, 0},
|
||||
{XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{XK_Down, ShiftMask, "\033[1;2B", 0, 0},
|
||||
{XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
|
||||
{XK_Down, ShiftMask | Mod1Mask, "\033[1;4B", 0, 0},
|
||||
{XK_Down, ControlMask, "\033[1;5B", 0, 0},
|
||||
{XK_Down, ShiftMask | ControlMask, "\033[1;6B", 0, 0},
|
||||
{XK_Down, ControlMask | Mod1Mask, "\033[1;7B", 0, 0},
|
||||
{XK_Down, ShiftMask | ControlMask | Mod1Mask, "\033[1;8B", 0, 0},
|
||||
{XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{XK_Left, ShiftMask, "\033[1;2D", 0, 0},
|
||||
{XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
|
||||
{XK_Left, ShiftMask | Mod1Mask, "\033[1;4D", 0, 0},
|
||||
{XK_Left, ControlMask, "\033[1;5D", 0, 0},
|
||||
{XK_Left, ShiftMask | ControlMask, "\033[1;6D", 0, 0},
|
||||
{XK_Left, ControlMask | Mod1Mask, "\033[1;7D", 0, 0},
|
||||
{XK_Left, ShiftMask | ControlMask | Mod1Mask, "\033[1;8D", 0, 0},
|
||||
{XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{XK_Right, ShiftMask, "\033[1;2C", 0, 0},
|
||||
{XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
|
||||
{XK_Right, ShiftMask | Mod1Mask, "\033[1;4C", 0, 0},
|
||||
{XK_Right, ControlMask, "\033[1;5C", 0, 0},
|
||||
{XK_Right, ShiftMask | ControlMask, "\033[1;6C", 0, 0},
|
||||
{XK_Right, ControlMask | Mod1Mask, "\033[1;7C", 0, 0},
|
||||
{XK_Right, ShiftMask | ControlMask | Mod1Mask, "\033[1;8C", 0, 0},
|
||||
{XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
|
||||
{XK_Return, Mod1Mask, "\033\r", 0, 0},
|
||||
{XK_Return, XK_ANY_MOD, "\r", 0, 0},
|
||||
{XK_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{XK_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{XK_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{XK_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{XK_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{XK_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
|
||||
{XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
|
||||
{XK_Home, ShiftMask, "\033[2J", 0, -1},
|
||||
{XK_Home, ShiftMask, "\033[1;2H", 0, +1},
|
||||
{XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
||||
{XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
||||
{XK_End, ControlMask, "\033[J", -1, 0},
|
||||
{XK_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{XK_End, ShiftMask, "\033[K", -1, 0},
|
||||
{XK_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{XK_Prior, ControlMask, "\033[5;5~", 0, 0},
|
||||
{XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{XK_Next, ControlMask, "\033[6;5~", 0, 0},
|
||||
{XK_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{XK_F1, XK_NO_MOD, "\033OP", 0, 0},
|
||||
{XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
|
||||
{XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
|
||||
{XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
|
||||
{XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
|
||||
{XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
|
||||
{XK_F2, XK_NO_MOD, "\033OQ", 0, 0},
|
||||
{XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
|
||||
{XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
|
||||
{XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
|
||||
{XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
|
||||
{XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
|
||||
{XK_F3, XK_NO_MOD, "\033OR", 0, 0},
|
||||
{XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
|
||||
{XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
|
||||
{XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
|
||||
{XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
|
||||
{XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
|
||||
{XK_F4, XK_NO_MOD, "\033OS", 0, 0},
|
||||
{XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
|
||||
{XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
|
||||
{XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
|
||||
{XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
|
||||
{XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
|
||||
{XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
|
||||
{XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
|
||||
{XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
|
||||
{XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
|
||||
{XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
|
||||
{XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
|
||||
{XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
|
||||
{XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
|
||||
{XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
|
||||
{XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
|
||||
{XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
|
||||
{XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
|
||||
{XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
|
||||
{XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
|
||||
{XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
|
||||
{XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
|
||||
{XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
|
||||
{XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
|
||||
{XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
|
||||
{XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
|
||||
{XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
|
||||
{XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
|
||||
{XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
|
||||
{XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
|
||||
{XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
|
||||
{XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
|
||||
{XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
|
||||
{XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
|
||||
{XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
|
||||
{XK_F16, XK_NO_MOD, "\033[23~", 0, 0},
|
||||
{XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
|
||||
{XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
|
||||
{XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
|
||||
{XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
|
||||
{XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
|
||||
{XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
|
||||
{XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
|
||||
{XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
|
||||
{XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
|
||||
{XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
|
||||
{XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
|
||||
{XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
|
||||
{XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
|
||||
{XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
|
||||
{XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
|
||||
{XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
|
||||
{XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
|
||||
{XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
|
||||
{XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
|
||||
{XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
|
||||
{XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
|
||||
{XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
|
||||
{XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
|
||||
{XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
|
||||
{XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
|
||||
{XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
|
||||
{XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
|
||||
{XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
|
||||
{XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
|
||||
{XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
|
||||
{XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
|
||||
{XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
|
||||
};
|
||||
|
||||
/*
|
||||
* Selection types' masks.
|
||||
* Use the same masks as usual.
|
||||
* Button1Mask is always unset, to make masks match between ButtonPress.
|
||||
* ButtonRelease and MotionNotify.
|
||||
* If no match is found, regular selection is used.
|
||||
*/
|
||||
static uint selmasks[] = {
|
||||
[SEL_RECTANGULAR] = Mod1Mask,
|
||||
};
|
||||
|
||||
/*
|
||||
* Printable characters in ASCII, used to estimate the advance width
|
||||
* of single wide characters.
|
||||
*/
|
||||
static char ascii_printable[] = " !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
Executable
+486
@@ -0,0 +1,486 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
/*
|
||||
* appearance
|
||||
*
|
||||
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||
*/
|
||||
static char *font = "Terminus-9:antialias=true:autohint=true";
|
||||
static int borderpx = 2;
|
||||
|
||||
/*
|
||||
* What program is execed by st depends of these precedence rules:
|
||||
* 1: program passed with -e
|
||||
* 2: scroll and/or utmp
|
||||
* 3: SHELL environment variable
|
||||
* 4: value of shell in /etc/passwd
|
||||
* 5: value of shell in config.h
|
||||
*/
|
||||
static char *shell = "/bin/sh";
|
||||
char *utmp = NULL;
|
||||
/* scroll program: to enable use a string like "scroll" */
|
||||
char *scroll = NULL;
|
||||
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
|
||||
|
||||
/* identification sequence returned in DA and DECID */
|
||||
char *vtiden = "\033[?6c";
|
||||
|
||||
/* Kerning / character bounding-box multipliers */
|
||||
static float cwscale = 1.0;
|
||||
static float chscale = 1.0;
|
||||
|
||||
/*
|
||||
* word delimiter string
|
||||
*
|
||||
* More advanced example: L" `'\"()[]{}"
|
||||
*/
|
||||
wchar_t *worddelimiters = L" ";
|
||||
|
||||
/* selection timeouts (in milliseconds) */
|
||||
static unsigned int doubleclicktimeout = 300;
|
||||
static unsigned int tripleclicktimeout = 600;
|
||||
|
||||
/* alt screens */
|
||||
int allowaltscreen = 1;
|
||||
|
||||
/* allow certain non-interactive (insecure) window operations such as:
|
||||
setting the clipboard text */
|
||||
int allowwindowops = 0;
|
||||
|
||||
/*
|
||||
* draw latency range in ms - from new content/keypress/etc until drawing.
|
||||
* within this range, st draws when content stops arriving (idle). mostly it's
|
||||
* near minlatency, but it waits longer for slow updates to avoid partial draw.
|
||||
* low minlatency will tear/flicker more, as it can "detect" idle too early.
|
||||
*/
|
||||
static double minlatency = 2;
|
||||
static double maxlatency = 33;
|
||||
|
||||
/*
|
||||
* blinking timeout (set to 0 to disable blinking) for the terminal blinking
|
||||
* attribute.
|
||||
*/
|
||||
static unsigned int blinktimeout = 800;
|
||||
|
||||
/*
|
||||
* thickness of underline and bar cursors
|
||||
*/
|
||||
static unsigned int cursorthickness = 2;
|
||||
|
||||
/*
|
||||
* bell volume. It must be a value between -100 and 100. Use 0 for disabling
|
||||
* it
|
||||
*/
|
||||
static int bellvolume = 0;
|
||||
|
||||
/* default TERM value */
|
||||
char *termname = "st-256color";
|
||||
|
||||
/*
|
||||
* spaces per tab
|
||||
*
|
||||
* When you are changing this value, don't forget to adapt the »it« value in
|
||||
* the st.info and appropriately install the st.info in the environment where
|
||||
* you use this st version.
|
||||
*
|
||||
* it#$tabspaces,
|
||||
*
|
||||
* Secondly make sure your kernel is not expanding tabs. When running `stty
|
||||
* -a` »tab0« should appear. You can tell the terminal to not expand tabs by
|
||||
* running following command:
|
||||
*
|
||||
* stty tabs
|
||||
*/
|
||||
unsigned int tabspaces = 8;
|
||||
|
||||
/* bg opacity */
|
||||
float alpha = 0.8;
|
||||
|
||||
/* Background opacity */
|
||||
float alpha_def;
|
||||
|
||||
/* Terminal colors (16 first used in escape sequence) */
|
||||
static const char *colorname[] = {
|
||||
|
||||
/* 8 normal colors */
|
||||
"#0a0a0a", /* black */
|
||||
"#44516d", /* red */
|
||||
"#c95d38", /* green */
|
||||
"#de9e68", /* yellow */
|
||||
"#8b7675", /* blue */
|
||||
"#7e5f8c", /* magenta */
|
||||
"#8c82c2", /* cyan */
|
||||
"#eff7d0", /* white */
|
||||
|
||||
/* 8 bright colors */
|
||||
"#181818", /* black */
|
||||
"#7d87a1", /* red */
|
||||
"#e9673c", /* green */
|
||||
"#e0b18b", /* yellow */
|
||||
"#b9a192", /* blue */
|
||||
"#9a7ebd", /* magenta */
|
||||
"#bccce2", /* cyan */
|
||||
"#ffffff", /* white */
|
||||
|
||||
[255] = 0,
|
||||
|
||||
/* more colors can be added after 255 to use with DefaultXX */
|
||||
"#gray90", /* default foreground colour */
|
||||
"#black", /* default background colour */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Default colors (colorname index)
|
||||
* foreground, background, cursor, reverse cursor
|
||||
*/
|
||||
unsigned int defaultfg = 256;
|
||||
unsigned int defaultbg = 257;
|
||||
unsigned int defaultcs = 256;
|
||||
static unsigned int defaultrcs = 257;
|
||||
|
||||
/*
|
||||
* Default shape of cursor
|
||||
* 2: Block ("█")
|
||||
* 4: Underline ("_")
|
||||
* 6: Bar ("|")
|
||||
* 7: Snowman ("☃")
|
||||
*/
|
||||
static unsigned int cursorshape = 6;
|
||||
|
||||
/*
|
||||
* Default columns and rows numbers
|
||||
*/
|
||||
|
||||
static unsigned int cols = 80;
|
||||
static unsigned int rows = 24;
|
||||
|
||||
/*
|
||||
* Default colour and shape of the mouse cursor
|
||||
*/
|
||||
static unsigned int mouseshape = XC_xterm;
|
||||
static unsigned int mousefg = 7;
|
||||
static unsigned int mousebg = 0;
|
||||
|
||||
/*
|
||||
* Color used to display font attributes when fontconfig selected a font which
|
||||
* doesn't match the ones requested.
|
||||
*/
|
||||
static unsigned int defaultattr = 11;
|
||||
|
||||
/*
|
||||
* Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
|
||||
* Note that if you want to use ShiftMask with selmasks, set this to an other
|
||||
* modifier, set to 0 to not use it.
|
||||
*/
|
||||
static uint forcemousemod = ShiftMask;
|
||||
|
||||
/*
|
||||
* Internal mouse shortcuts.
|
||||
* Beware that overloading Button1 will disable the selection.
|
||||
*/
|
||||
static MouseShortcut mshortcuts[] = {
|
||||
/* mask button function argument release */
|
||||
{ XK_NO_MOD, Button4, kscrollup, {.i = 1} },
|
||||
{ XK_NO_MOD, Button5, kscrolldown, {.i = 1} },
|
||||
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
||||
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
|
||||
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
|
||||
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
|
||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
|
||||
};
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
#define MODKEY Mod1Mask
|
||||
#define TERMMOD (Mod1Mask|ShiftMask)
|
||||
|
||||
static Shortcut shortcuts[] = {
|
||||
/* mask keysym function argument */
|
||||
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
|
||||
{ ControlMask, XK_Print, toggleprinter, {.i = 0} },
|
||||
{ ShiftMask, XK_Print, printscreen, {.i = 0} },
|
||||
{ XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
|
||||
{ ControlMask, XK_j, zoom, {.f = +1} },
|
||||
{ ControlMask, XK_minus, zoom, {.f = -1} },
|
||||
{ TERMMOD, XK_Home, zoomreset, {.f = 0} },
|
||||
{ MODKEY, XK_c, clipcopy, {.i = 0} },
|
||||
{ MODKEY, XK_v, clippaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
|
||||
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
|
||||
{ MODKEY, XK_k, kscrollup, {.i = 1} },
|
||||
{ MODKEY, XK_j, kscrolldown, {.i = 1} },
|
||||
{ MODKEY, XK_a, chgalpha, {.f = -1} },
|
||||
{ MODKEY, XK_s, chgalpha, {.f = +1} },
|
||||
{ MODKEY, XK_d, chgalpha, {.f = 0} },
|
||||
};
|
||||
|
||||
/*
|
||||
* Special keys (change & recompile st.info accordingly)
|
||||
*
|
||||
* Mask value:
|
||||
* * Use XK_ANY_MOD to match the key no matter modifiers state
|
||||
* * Use XK_NO_MOD to match the key alone (no modifiers)
|
||||
* appkey value:
|
||||
* * 0: no value
|
||||
* * > 0: keypad application mode enabled
|
||||
* * = 2: term.numlock = 1
|
||||
* * < 0: keypad application mode disabled
|
||||
* appcursor value:
|
||||
* * 0: no value
|
||||
* * > 0: cursor application mode enabled
|
||||
* * < 0: cursor application mode disabled
|
||||
*
|
||||
* Be careful with the order of the definitions because st searches in
|
||||
* this table sequentially, so any XK_ANY_MOD must be in the last
|
||||
* position for a key.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
|
||||
* to be mapped below, add them to this array.
|
||||
*/
|
||||
static KeySym mappedkeys[] = { -1 };
|
||||
|
||||
/*
|
||||
* State bits to ignore when matching key or button events. By default,
|
||||
* numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
|
||||
*/
|
||||
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
|
||||
|
||||
/*
|
||||
* This is the huge key array which defines all compatibility to the Linux
|
||||
* world. Please decide about changes wisely.
|
||||
*/
|
||||
static Key key[] = {
|
||||
/* keysym mask string appkey appcursor */
|
||||
{ XK_KP_Home, ShiftMask, "\033[2J", 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[1~", 0, +1},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{ XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{ XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{ XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
|
||||
{ XK_KP_End, ControlMask, "\033[J", -1, 0},
|
||||
{ XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{ XK_KP_End, ShiftMask, "\033[K", -1, 0},
|
||||
{ XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{ XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{ XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{ XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{ XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{ XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{ XK_KP_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{ XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{ XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{ XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{ XK_KP_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{ XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{ XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{ XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{ XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{ XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{ XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
|
||||
{ XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
|
||||
{ XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
|
||||
{ XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
|
||||
{ XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
|
||||
{ XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
|
||||
{ XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
|
||||
{ XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
|
||||
{ XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
|
||||
{ XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
|
||||
{ XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
|
||||
{ XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
|
||||
{ XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
|
||||
{ XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
|
||||
{ XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
|
||||
{ XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
|
||||
{ XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
|
||||
{ XK_Up, ShiftMask, "\033[1;2A", 0, 0},
|
||||
{ XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
|
||||
{ XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0},
|
||||
{ XK_Up, ControlMask, "\033[1;5A", 0, 0},
|
||||
{ XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0},
|
||||
{ XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0},
|
||||
{ XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0},
|
||||
{ XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{ XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{ XK_Down, ShiftMask, "\033[1;2B", 0, 0},
|
||||
{ XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
|
||||
{ XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0},
|
||||
{ XK_Down, ControlMask, "\033[1;5B", 0, 0},
|
||||
{ XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0},
|
||||
{ XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0},
|
||||
{ XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0},
|
||||
{ XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{ XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{ XK_Left, ShiftMask, "\033[1;2D", 0, 0},
|
||||
{ XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
|
||||
{ XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0},
|
||||
{ XK_Left, ControlMask, "\033[1;5D", 0, 0},
|
||||
{ XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0},
|
||||
{ XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0},
|
||||
{ XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0},
|
||||
{ XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{ XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{ XK_Right, ShiftMask, "\033[1;2C", 0, 0},
|
||||
{ XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
|
||||
{ XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0},
|
||||
{ XK_Right, ControlMask, "\033[1;5C", 0, 0},
|
||||
{ XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0},
|
||||
{ XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0},
|
||||
{ XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0},
|
||||
{ XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{ XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{ XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
|
||||
{ XK_Return, Mod1Mask, "\033\r", 0, 0},
|
||||
{ XK_Return, XK_ANY_MOD, "\r", 0, 0},
|
||||
{ XK_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{ XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{ XK_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{ XK_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{ XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{ XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{ XK_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{ XK_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{ XK_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{ XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{ XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{ XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{ XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
|
||||
{ XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
|
||||
{ XK_Home, ShiftMask, "\033[2J", 0, -1},
|
||||
{ XK_Home, ShiftMask, "\033[1;2H", 0, +1},
|
||||
{ XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
||||
{ XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
||||
{ XK_End, ControlMask, "\033[J", -1, 0},
|
||||
{ XK_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{ XK_End, ShiftMask, "\033[K", -1, 0},
|
||||
{ XK_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{ XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{ XK_Prior, ControlMask, "\033[5;5~", 0, 0},
|
||||
{ XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{ XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{ XK_Next, ControlMask, "\033[6;5~", 0, 0},
|
||||
{ XK_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{ XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{ XK_F1, XK_NO_MOD, "\033OP" , 0, 0},
|
||||
{ XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
|
||||
{ XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
|
||||
{ XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
|
||||
{ XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
|
||||
{ XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
|
||||
{ XK_F2, XK_NO_MOD, "\033OQ" , 0, 0},
|
||||
{ XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
|
||||
{ XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
|
||||
{ XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
|
||||
{ XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
|
||||
{ XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
|
||||
{ XK_F3, XK_NO_MOD, "\033OR" , 0, 0},
|
||||
{ XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
|
||||
{ XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
|
||||
{ XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
|
||||
{ XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
|
||||
{ XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
|
||||
{ XK_F4, XK_NO_MOD, "\033OS" , 0, 0},
|
||||
{ XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
|
||||
{ XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
|
||||
{ XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
|
||||
{ XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
|
||||
{ XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
|
||||
{ XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
|
||||
{ XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
|
||||
{ XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
|
||||
{ XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
|
||||
{ XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
|
||||
{ XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
|
||||
{ XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
|
||||
{ XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
|
||||
{ XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
|
||||
{ XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
|
||||
{ XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
|
||||
{ XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
|
||||
{ XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
|
||||
{ XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
|
||||
{ XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
|
||||
{ XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
|
||||
{ XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
|
||||
{ XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
|
||||
{ XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
|
||||
{ XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
|
||||
{ XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
|
||||
{ XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
|
||||
{ XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
|
||||
{ XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
|
||||
{ XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
|
||||
{ XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
|
||||
{ XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
|
||||
{ XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
|
||||
{ XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
|
||||
{ XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
|
||||
{ XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
|
||||
{ XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
|
||||
{ XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
|
||||
{ XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
|
||||
{ XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
|
||||
{ XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
|
||||
{ XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
|
||||
{ XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
|
||||
{ XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
|
||||
{ XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
|
||||
{ XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
|
||||
{ XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
|
||||
{ XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
|
||||
{ XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
|
||||
{ XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
|
||||
{ XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
|
||||
{ XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
|
||||
{ XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
|
||||
{ XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
|
||||
{ XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
|
||||
{ XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
|
||||
{ XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
|
||||
{ XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
|
||||
{ XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
|
||||
{ XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
|
||||
{ XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
|
||||
{ XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
|
||||
{ XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
|
||||
{ XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
|
||||
{ XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
|
||||
{ XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
|
||||
{ XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
|
||||
};
|
||||
|
||||
/*
|
||||
* Selection types' masks.
|
||||
* Use the same masks as usual.
|
||||
* Button1Mask is always unset, to make masks match between ButtonPress.
|
||||
* ButtonRelease and MotionNotify.
|
||||
* If no match is found, regular selection is used.
|
||||
*/
|
||||
static uint selmasks[] = {
|
||||
[SEL_RECTANGULAR] = Mod1Mask,
|
||||
};
|
||||
|
||||
/*
|
||||
* Printable characters in ASCII, used to estimate the advance width
|
||||
* of single wide characters.
|
||||
*/
|
||||
static char ascii_printable[] =
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
Executable
+486
@@ -0,0 +1,486 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
/*
|
||||
* appearance
|
||||
*
|
||||
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||
*/
|
||||
static char *font = "Terminus-9:antialias=true:autohint=true";
|
||||
static int borderpx = 2;
|
||||
|
||||
/*
|
||||
* What program is execed by st depends of these precedence rules:
|
||||
* 1: program passed with -e
|
||||
* 2: scroll and/or utmp
|
||||
* 3: SHELL environment variable
|
||||
* 4: value of shell in /etc/passwd
|
||||
* 5: value of shell in config.h
|
||||
*/
|
||||
static char *shell = "/bin/sh";
|
||||
char *utmp = NULL;
|
||||
/* scroll program: to enable use a string like "scroll" */
|
||||
char *scroll = NULL;
|
||||
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
|
||||
|
||||
/* identification sequence returned in DA and DECID */
|
||||
char *vtiden = "\033[?6c";
|
||||
|
||||
/* Kerning / character bounding-box multipliers */
|
||||
static float cwscale = 1.0;
|
||||
static float chscale = 1.0;
|
||||
|
||||
/*
|
||||
* word delimiter string
|
||||
*
|
||||
* More advanced example: L" `'\"()[]{}"
|
||||
*/
|
||||
wchar_t *worddelimiters = L" ";
|
||||
|
||||
/* selection timeouts (in milliseconds) */
|
||||
static unsigned int doubleclicktimeout = 300;
|
||||
static unsigned int tripleclicktimeout = 600;
|
||||
|
||||
/* alt screens */
|
||||
int allowaltscreen = 1;
|
||||
|
||||
/* allow certain non-interactive (insecure) window operations such as:
|
||||
setting the clipboard text */
|
||||
int allowwindowops = 0;
|
||||
|
||||
/*
|
||||
* draw latency range in ms - from new content/keypress/etc until drawing.
|
||||
* within this range, st draws when content stops arriving (idle). mostly it's
|
||||
* near minlatency, but it waits longer for slow updates to avoid partial draw.
|
||||
* low minlatency will tear/flicker more, as it can "detect" idle too early.
|
||||
*/
|
||||
static double minlatency = 2;
|
||||
static double maxlatency = 33;
|
||||
|
||||
/*
|
||||
* blinking timeout (set to 0 to disable blinking) for the terminal blinking
|
||||
* attribute.
|
||||
*/
|
||||
static unsigned int blinktimeout = 800;
|
||||
|
||||
/*
|
||||
* thickness of underline and bar cursors
|
||||
*/
|
||||
static unsigned int cursorthickness = 2;
|
||||
|
||||
/*
|
||||
* bell volume. It must be a value between -100 and 100. Use 0 for disabling
|
||||
* it
|
||||
*/
|
||||
static int bellvolume = 0;
|
||||
|
||||
/* default TERM value */
|
||||
char *termname = "st-256color";
|
||||
|
||||
/*
|
||||
* spaces per tab
|
||||
*
|
||||
* When you are changing this value, don't forget to adapt the »it« value in
|
||||
* the st.info and appropriately install the st.info in the environment where
|
||||
* you use this st version.
|
||||
*
|
||||
* it#$tabspaces,
|
||||
*
|
||||
* Secondly make sure your kernel is not expanding tabs. When running `stty
|
||||
* -a` »tab0« should appear. You can tell the terminal to not expand tabs by
|
||||
* running following command:
|
||||
*
|
||||
* stty tabs
|
||||
*/
|
||||
unsigned int tabspaces = 8;
|
||||
|
||||
/* bg opacity */
|
||||
float alpha = 0.8;
|
||||
|
||||
/* Background opacity */
|
||||
float alpha_def;
|
||||
|
||||
/* Terminal colors (16 first used in escape sequence) */
|
||||
static const char *colorname[] = {
|
||||
|
||||
/* 8 normal colors */
|
||||
"#0a0a0a", /* black */
|
||||
"#44516d", /* red */
|
||||
"#c95d38", /* green */
|
||||
"#de9e68", /* yellow */
|
||||
"#8b7675", /* blue */
|
||||
"#7e5f8c", /* magenta */
|
||||
"#8c82c2", /* cyan */
|
||||
"#eff7d0", /* white */
|
||||
|
||||
/* 8 bright colors */
|
||||
"#181818", /* black */
|
||||
"#7d87a1", /* red */
|
||||
"#e9673c", /* green */
|
||||
"#e0b18b", /* yellow */
|
||||
"#b9a192", /* blue */
|
||||
"#9a7ebd", /* magenta */
|
||||
"#bccce2", /* cyan */
|
||||
"#ffffff", /* white */
|
||||
|
||||
[255] = 0,
|
||||
|
||||
/* more colors can be added after 255 to use with DefaultXX */
|
||||
"gray90", /* default foreground colour */
|
||||
"black", /* default background colour */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Default colors (colorname index)
|
||||
* foreground, background, cursor, reverse cursor
|
||||
*/
|
||||
unsigned int defaultfg = 256;
|
||||
unsigned int defaultbg = 257;
|
||||
unsigned int defaultcs = 256;
|
||||
static unsigned int defaultrcs = 257;
|
||||
|
||||
/*
|
||||
* Default shape of cursor
|
||||
* 2: Block ("█")
|
||||
* 4: Underline ("_")
|
||||
* 6: Bar ("|")
|
||||
* 7: Snowman ("☃")
|
||||
*/
|
||||
static unsigned int cursorshape = 6;
|
||||
|
||||
/*
|
||||
* Default columns and rows numbers
|
||||
*/
|
||||
|
||||
static unsigned int cols = 80;
|
||||
static unsigned int rows = 24;
|
||||
|
||||
/*
|
||||
* Default colour and shape of the mouse cursor
|
||||
*/
|
||||
static unsigned int mouseshape = XC_xterm;
|
||||
static unsigned int mousefg = 7;
|
||||
static unsigned int mousebg = 0;
|
||||
|
||||
/*
|
||||
* Color used to display font attributes when fontconfig selected a font which
|
||||
* doesn't match the ones requested.
|
||||
*/
|
||||
static unsigned int defaultattr = 11;
|
||||
|
||||
/*
|
||||
* Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
|
||||
* Note that if you want to use ShiftMask with selmasks, set this to an other
|
||||
* modifier, set to 0 to not use it.
|
||||
*/
|
||||
static uint forcemousemod = ShiftMask;
|
||||
|
||||
/*
|
||||
* Internal mouse shortcuts.
|
||||
* Beware that overloading Button1 will disable the selection.
|
||||
*/
|
||||
static MouseShortcut mshortcuts[] = {
|
||||
/* mask button function argument release */
|
||||
{ XK_NO_MOD, Button4, kscrollup, {.i = 1} },
|
||||
{ XK_NO_MOD, Button5, kscrolldown, {.i = 1} },
|
||||
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
||||
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
|
||||
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
|
||||
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
|
||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
|
||||
};
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
#define MODKEY Mod1Mask
|
||||
#define TERMMOD (Mod1Mask|ShiftMask)
|
||||
|
||||
static Shortcut shortcuts[] = {
|
||||
/* mask keysym function argument */
|
||||
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
|
||||
{ ControlMask, XK_Print, toggleprinter, {.i = 0} },
|
||||
{ ShiftMask, XK_Print, printscreen, {.i = 0} },
|
||||
{ XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
|
||||
{ ControlMask, XK_equal, zoom, {.f = +1} },
|
||||
{ ControlMask, XK_minus, zoom, {.f = -1} },
|
||||
{ TERMMOD, XK_Home, zoomreset, {.f = 0} },
|
||||
{ MODKEY, XK_c, clipcopy, {.i = 0} },
|
||||
{ MODKEY, XK_v, clippaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
|
||||
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
|
||||
{ ControlMask, XK_k, kscrollup, {.i = 1} },
|
||||
{ ControlMask, XK_j, kscrolldown, {.i = 1} },
|
||||
{ MODKEY, XK_a, chgalpha, {.f = -1} },
|
||||
{ MODKEY, XK_s, chgalpha, {.f = +1} },
|
||||
{ MODKEY, XK_d, chgalpha, {.f = 0} },
|
||||
};
|
||||
|
||||
/*
|
||||
* Special keys (change & recompile st.info accordingly)
|
||||
*
|
||||
* Mask value:
|
||||
* * Use XK_ANY_MOD to match the key no matter modifiers state
|
||||
* * Use XK_NO_MOD to match the key alone (no modifiers)
|
||||
* appkey value:
|
||||
* * 0: no value
|
||||
* * > 0: keypad application mode enabled
|
||||
* * = 2: term.numlock = 1
|
||||
* * < 0: keypad application mode disabled
|
||||
* appcursor value:
|
||||
* * 0: no value
|
||||
* * > 0: cursor application mode enabled
|
||||
* * < 0: cursor application mode disabled
|
||||
*
|
||||
* Be careful with the order of the definitions because st searches in
|
||||
* this table sequentially, so any XK_ANY_MOD must be in the last
|
||||
* position for a key.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
|
||||
* to be mapped below, add them to this array.
|
||||
*/
|
||||
static KeySym mappedkeys[] = { -1 };
|
||||
|
||||
/*
|
||||
* State bits to ignore when matching key or button events. By default,
|
||||
* numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
|
||||
*/
|
||||
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
|
||||
|
||||
/*
|
||||
* This is the huge key array which defines all compatibility to the Linux
|
||||
* world. Please decide about changes wisely.
|
||||
*/
|
||||
static Key key[] = {
|
||||
/* keysym mask string appkey appcursor */
|
||||
{ XK_KP_Home, ShiftMask, "\033[2J", 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[1~", 0, +1},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{ XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{ XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{ XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
|
||||
{ XK_KP_End, ControlMask, "\033[J", -1, 0},
|
||||
{ XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{ XK_KP_End, ShiftMask, "\033[K", -1, 0},
|
||||
{ XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{ XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{ XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{ XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{ XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{ XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{ XK_KP_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{ XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{ XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{ XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{ XK_KP_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{ XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{ XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{ XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{ XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{ XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{ XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
|
||||
{ XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
|
||||
{ XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
|
||||
{ XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
|
||||
{ XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
|
||||
{ XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
|
||||
{ XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
|
||||
{ XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
|
||||
{ XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
|
||||
{ XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
|
||||
{ XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
|
||||
{ XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
|
||||
{ XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
|
||||
{ XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
|
||||
{ XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
|
||||
{ XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
|
||||
{ XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
|
||||
{ XK_Up, ShiftMask, "\033[1;2A", 0, 0},
|
||||
{ XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
|
||||
{ XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0},
|
||||
{ XK_Up, ControlMask, "\033[1;5A", 0, 0},
|
||||
{ XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0},
|
||||
{ XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0},
|
||||
{ XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0},
|
||||
{ XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{ XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{ XK_Down, ShiftMask, "\033[1;2B", 0, 0},
|
||||
{ XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
|
||||
{ XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0},
|
||||
{ XK_Down, ControlMask, "\033[1;5B", 0, 0},
|
||||
{ XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0},
|
||||
{ XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0},
|
||||
{ XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0},
|
||||
{ XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{ XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{ XK_Left, ShiftMask, "\033[1;2D", 0, 0},
|
||||
{ XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
|
||||
{ XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0},
|
||||
{ XK_Left, ControlMask, "\033[1;5D", 0, 0},
|
||||
{ XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0},
|
||||
{ XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0},
|
||||
{ XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0},
|
||||
{ XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{ XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{ XK_Right, ShiftMask, "\033[1;2C", 0, 0},
|
||||
{ XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
|
||||
{ XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0},
|
||||
{ XK_Right, ControlMask, "\033[1;5C", 0, 0},
|
||||
{ XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0},
|
||||
{ XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0},
|
||||
{ XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0},
|
||||
{ XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{ XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{ XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
|
||||
{ XK_Return, Mod1Mask, "\033\r", 0, 0},
|
||||
{ XK_Return, XK_ANY_MOD, "\r", 0, 0},
|
||||
{ XK_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{ XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{ XK_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{ XK_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{ XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{ XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{ XK_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{ XK_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{ XK_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{ XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{ XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{ XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{ XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
|
||||
{ XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
|
||||
{ XK_Home, ShiftMask, "\033[2J", 0, -1},
|
||||
{ XK_Home, ShiftMask, "\033[1;2H", 0, +1},
|
||||
{ XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
||||
{ XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
||||
{ XK_End, ControlMask, "\033[J", -1, 0},
|
||||
{ XK_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{ XK_End, ShiftMask, "\033[K", -1, 0},
|
||||
{ XK_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{ XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{ XK_Prior, ControlMask, "\033[5;5~", 0, 0},
|
||||
{ XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{ XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{ XK_Next, ControlMask, "\033[6;5~", 0, 0},
|
||||
{ XK_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{ XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{ XK_F1, XK_NO_MOD, "\033OP" , 0, 0},
|
||||
{ XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
|
||||
{ XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
|
||||
{ XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
|
||||
{ XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
|
||||
{ XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
|
||||
{ XK_F2, XK_NO_MOD, "\033OQ" , 0, 0},
|
||||
{ XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
|
||||
{ XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
|
||||
{ XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
|
||||
{ XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
|
||||
{ XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
|
||||
{ XK_F3, XK_NO_MOD, "\033OR" , 0, 0},
|
||||
{ XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
|
||||
{ XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
|
||||
{ XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
|
||||
{ XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
|
||||
{ XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
|
||||
{ XK_F4, XK_NO_MOD, "\033OS" , 0, 0},
|
||||
{ XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
|
||||
{ XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
|
||||
{ XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
|
||||
{ XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
|
||||
{ XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
|
||||
{ XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
|
||||
{ XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
|
||||
{ XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
|
||||
{ XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
|
||||
{ XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
|
||||
{ XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
|
||||
{ XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
|
||||
{ XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
|
||||
{ XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
|
||||
{ XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
|
||||
{ XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
|
||||
{ XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
|
||||
{ XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
|
||||
{ XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
|
||||
{ XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
|
||||
{ XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
|
||||
{ XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
|
||||
{ XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
|
||||
{ XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
|
||||
{ XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
|
||||
{ XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
|
||||
{ XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
|
||||
{ XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
|
||||
{ XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
|
||||
{ XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
|
||||
{ XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
|
||||
{ XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
|
||||
{ XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
|
||||
{ XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
|
||||
{ XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
|
||||
{ XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
|
||||
{ XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
|
||||
{ XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
|
||||
{ XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
|
||||
{ XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
|
||||
{ XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
|
||||
{ XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
|
||||
{ XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
|
||||
{ XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
|
||||
{ XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
|
||||
{ XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
|
||||
{ XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
|
||||
{ XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
|
||||
{ XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
|
||||
{ XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
|
||||
{ XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
|
||||
{ XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
|
||||
{ XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
|
||||
{ XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
|
||||
{ XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
|
||||
{ XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
|
||||
{ XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
|
||||
{ XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
|
||||
{ XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
|
||||
{ XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
|
||||
{ XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
|
||||
{ XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
|
||||
{ XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
|
||||
{ XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
|
||||
{ XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
|
||||
{ XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
|
||||
{ XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
|
||||
};
|
||||
|
||||
/*
|
||||
* Selection types' masks.
|
||||
* Use the same masks as usual.
|
||||
* Button1Mask is always unset, to make masks match between ButtonPress.
|
||||
* ButtonRelease and MotionNotify.
|
||||
* If no match is found, regular selection is used.
|
||||
*/
|
||||
static uint selmasks[] = {
|
||||
[SEL_RECTANGULAR] = Mod1Mask,
|
||||
};
|
||||
|
||||
/*
|
||||
* Printable characters in ASCII, used to estimate the advance width
|
||||
* of single wide characters.
|
||||
*/
|
||||
static char ascii_printable[] =
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
Executable
+486
@@ -0,0 +1,486 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
/*
|
||||
* appearance
|
||||
*
|
||||
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||
*/
|
||||
static char *font = "Terminus-9:antialias=true:autohint=true";
|
||||
static int borderpx = 2;
|
||||
|
||||
/*
|
||||
* What program is execed by st depends of these precedence rules:
|
||||
* 1: program passed with -e
|
||||
* 2: scroll and/or utmp
|
||||
* 3: SHELL environment variable
|
||||
* 4: value of shell in /etc/passwd
|
||||
* 5: value of shell in config.h
|
||||
*/
|
||||
static char *shell = "/bin/sh";
|
||||
char *utmp = NULL;
|
||||
/* scroll program: to enable use a string like "scroll" */
|
||||
char *scroll = NULL;
|
||||
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
|
||||
|
||||
/* identification sequence returned in DA and DECID */
|
||||
char *vtiden = "\033[?6c";
|
||||
|
||||
/* Kerning / character bounding-box multipliers */
|
||||
static float cwscale = 1.0;
|
||||
static float chscale = 1.0;
|
||||
|
||||
/*
|
||||
* word delimiter string
|
||||
*
|
||||
* More advanced example: L" `'\"()[]{}"
|
||||
*/
|
||||
wchar_t *worddelimiters = L" ";
|
||||
|
||||
/* selection timeouts (in milliseconds) */
|
||||
static unsigned int doubleclicktimeout = 300;
|
||||
static unsigned int tripleclicktimeout = 600;
|
||||
|
||||
/* alt screens */
|
||||
int allowaltscreen = 1;
|
||||
|
||||
/* allow certain non-interactive (insecure) window operations such as:
|
||||
setting the clipboard text */
|
||||
int allowwindowops = 0;
|
||||
|
||||
/*
|
||||
* draw latency range in ms - from new content/keypress/etc until drawing.
|
||||
* within this range, st draws when content stops arriving (idle). mostly it's
|
||||
* near minlatency, but it waits longer for slow updates to avoid partial draw.
|
||||
* low minlatency will tear/flicker more, as it can "detect" idle too early.
|
||||
*/
|
||||
static double minlatency = 2;
|
||||
static double maxlatency = 33;
|
||||
|
||||
/*
|
||||
* blinking timeout (set to 0 to disable blinking) for the terminal blinking
|
||||
* attribute.
|
||||
*/
|
||||
static unsigned int blinktimeout = 800;
|
||||
|
||||
/*
|
||||
* thickness of underline and bar cursors
|
||||
*/
|
||||
static unsigned int cursorthickness = 2;
|
||||
|
||||
/*
|
||||
* bell volume. It must be a value between -100 and 100. Use 0 for disabling
|
||||
* it
|
||||
*/
|
||||
static int bellvolume = 0;
|
||||
|
||||
/* default TERM value */
|
||||
char *termname = "st-256color";
|
||||
|
||||
/*
|
||||
* spaces per tab
|
||||
*
|
||||
* When you are changing this value, don't forget to adapt the »it« value in
|
||||
* the st.info and appropriately install the st.info in the environment where
|
||||
* you use this st version.
|
||||
*
|
||||
* it#$tabspaces,
|
||||
*
|
||||
* Secondly make sure your kernel is not expanding tabs. When running `stty
|
||||
* -a` »tab0« should appear. You can tell the terminal to not expand tabs by
|
||||
* running following command:
|
||||
*
|
||||
* stty tabs
|
||||
*/
|
||||
unsigned int tabspaces = 8;
|
||||
|
||||
/* bg opacity */
|
||||
float alpha = 0.8;
|
||||
|
||||
/* Background opacity */
|
||||
float alpha_def;
|
||||
|
||||
/* Terminal colors (16 first used in escape sequence) */
|
||||
static const char *colorname[] = {
|
||||
|
||||
/* 8 normal colors */
|
||||
"#0a0a0a", /* black */
|
||||
"#44516d", /* red */
|
||||
"#c95d38", /* green */
|
||||
"#de9e68", /* yellow */
|
||||
"#8b7675", /* blue */
|
||||
"#7e5f8c", /* magenta */
|
||||
"#8c82c2", /* cyan */
|
||||
"#eff7d0", /* white */
|
||||
|
||||
/* 8 bright colors */
|
||||
"#181818", /* black */
|
||||
"#7d87a1", /* red */
|
||||
"#e9673c", /* green */
|
||||
"#e0b18b", /* yellow */
|
||||
"#b9a192", /* blue */
|
||||
"#9a7ebd", /* magenta */
|
||||
"#bccce2", /* cyan */
|
||||
"#ffffff", /* white */
|
||||
|
||||
[255] = 0,
|
||||
|
||||
/* more colors can be added after 255 to use with DefaultXX */
|
||||
"gray90", /* default foreground colour */
|
||||
"black", /* default background colour */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Default colors (colorname index)
|
||||
* foreground, background, cursor, reverse cursor
|
||||
*/
|
||||
unsigned int defaultfg = 256;
|
||||
unsigned int defaultbg = 257;
|
||||
unsigned int defaultcs = 256;
|
||||
static unsigned int defaultrcs = 257;
|
||||
|
||||
/*
|
||||
* Default shape of cursor
|
||||
* 2: Block ("█")
|
||||
* 4: Underline ("_")
|
||||
* 6: Bar ("|")
|
||||
* 7: Snowman ("☃")
|
||||
*/
|
||||
static unsigned int cursorshape = 6;
|
||||
|
||||
/*
|
||||
* Default columns and rows numbers
|
||||
*/
|
||||
|
||||
static unsigned int cols = 80;
|
||||
static unsigned int rows = 24;
|
||||
|
||||
/*
|
||||
* Default colour and shape of the mouse cursor
|
||||
*/
|
||||
static unsigned int mouseshape = XC_xterm;
|
||||
static unsigned int mousefg = 7;
|
||||
static unsigned int mousebg = 0;
|
||||
|
||||
/*
|
||||
* Color used to display font attributes when fontconfig selected a font which
|
||||
* doesn't match the ones requested.
|
||||
*/
|
||||
static unsigned int defaultattr = 11;
|
||||
|
||||
/*
|
||||
* Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
|
||||
* Note that if you want to use ShiftMask with selmasks, set this to an other
|
||||
* modifier, set to 0 to not use it.
|
||||
*/
|
||||
static uint forcemousemod = ShiftMask;
|
||||
|
||||
/*
|
||||
* Internal mouse shortcuts.
|
||||
* Beware that overloading Button1 will disable the selection.
|
||||
*/
|
||||
static MouseShortcut mshortcuts[] = {
|
||||
/* mask button function argument release */
|
||||
{ XK_NO_MOD, Button4, kscrollup, {.i = 1} },
|
||||
{ XK_NO_MOD, Button5, kscrolldown, {.i = 1} },
|
||||
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
||||
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
|
||||
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
|
||||
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
|
||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
|
||||
};
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
#define MODKEY Mod1Mask
|
||||
#define TERMMOD (Mod1Mask|ShiftMask)
|
||||
|
||||
static Shortcut shortcuts[] = {
|
||||
/* mask keysym function argument */
|
||||
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
|
||||
{ ControlMask, XK_Print, toggleprinter, {.i = 0} },
|
||||
{ ShiftMask, XK_Print, printscreen, {.i = 0} },
|
||||
{ XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
|
||||
{ ControlMask, XK_equal, zoom, {.f = +1} },
|
||||
{ ControlMask, XK_minus, zoom, {.f = -1} },
|
||||
{ TERMMOD, XK_Home, zoomreset, {.f = 0} },
|
||||
{ ControlMask|Shift, XK_c, clipcopy, {.i = 0} },
|
||||
{ MODKEY, XK_v, clippaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
|
||||
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
|
||||
{ ControlMask, XK_k, kscrollup, {.i = 1} },
|
||||
{ ControlMask, XK_j, kscrolldown, {.i = 1} },
|
||||
{ MODKEY, XK_a, chgalpha, {.f = -1} },
|
||||
{ MODKEY, XK_s, chgalpha, {.f = +1} },
|
||||
{ MODKEY, XK_d, chgalpha, {.f = 0} },
|
||||
};
|
||||
|
||||
/*
|
||||
* Special keys (change & recompile st.info accordingly)
|
||||
*
|
||||
* Mask value:
|
||||
* * Use XK_ANY_MOD to match the key no matter modifiers state
|
||||
* * Use XK_NO_MOD to match the key alone (no modifiers)
|
||||
* appkey value:
|
||||
* * 0: no value
|
||||
* * > 0: keypad application mode enabled
|
||||
* * = 2: term.numlock = 1
|
||||
* * < 0: keypad application mode disabled
|
||||
* appcursor value:
|
||||
* * 0: no value
|
||||
* * > 0: cursor application mode enabled
|
||||
* * < 0: cursor application mode disabled
|
||||
*
|
||||
* Be careful with the order of the definitions because st searches in
|
||||
* this table sequentially, so any XK_ANY_MOD must be in the last
|
||||
* position for a key.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
|
||||
* to be mapped below, add them to this array.
|
||||
*/
|
||||
static KeySym mappedkeys[] = { -1 };
|
||||
|
||||
/*
|
||||
* State bits to ignore when matching key or button events. By default,
|
||||
* numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
|
||||
*/
|
||||
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
|
||||
|
||||
/*
|
||||
* This is the huge key array which defines all compatibility to the Linux
|
||||
* world. Please decide about changes wisely.
|
||||
*/
|
||||
static Key key[] = {
|
||||
/* keysym mask string appkey appcursor */
|
||||
{ XK_KP_Home, ShiftMask, "\033[2J", 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[1~", 0, +1},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{ XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{ XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{ XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
|
||||
{ XK_KP_End, ControlMask, "\033[J", -1, 0},
|
||||
{ XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{ XK_KP_End, ShiftMask, "\033[K", -1, 0},
|
||||
{ XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{ XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{ XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{ XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{ XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{ XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{ XK_KP_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{ XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{ XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{ XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{ XK_KP_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{ XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{ XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{ XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{ XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{ XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{ XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
|
||||
{ XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
|
||||
{ XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
|
||||
{ XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
|
||||
{ XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
|
||||
{ XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
|
||||
{ XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
|
||||
{ XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
|
||||
{ XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
|
||||
{ XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
|
||||
{ XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
|
||||
{ XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
|
||||
{ XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
|
||||
{ XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
|
||||
{ XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
|
||||
{ XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
|
||||
{ XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
|
||||
{ XK_Up, ShiftMask, "\033[1;2A", 0, 0},
|
||||
{ XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
|
||||
{ XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0},
|
||||
{ XK_Up, ControlMask, "\033[1;5A", 0, 0},
|
||||
{ XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0},
|
||||
{ XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0},
|
||||
{ XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0},
|
||||
{ XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{ XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{ XK_Down, ShiftMask, "\033[1;2B", 0, 0},
|
||||
{ XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
|
||||
{ XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0},
|
||||
{ XK_Down, ControlMask, "\033[1;5B", 0, 0},
|
||||
{ XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0},
|
||||
{ XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0},
|
||||
{ XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0},
|
||||
{ XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{ XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{ XK_Left, ShiftMask, "\033[1;2D", 0, 0},
|
||||
{ XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
|
||||
{ XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0},
|
||||
{ XK_Left, ControlMask, "\033[1;5D", 0, 0},
|
||||
{ XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0},
|
||||
{ XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0},
|
||||
{ XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0},
|
||||
{ XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{ XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{ XK_Right, ShiftMask, "\033[1;2C", 0, 0},
|
||||
{ XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
|
||||
{ XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0},
|
||||
{ XK_Right, ControlMask, "\033[1;5C", 0, 0},
|
||||
{ XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0},
|
||||
{ XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0},
|
||||
{ XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0},
|
||||
{ XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{ XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{ XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
|
||||
{ XK_Return, Mod1Mask, "\033\r", 0, 0},
|
||||
{ XK_Return, XK_ANY_MOD, "\r", 0, 0},
|
||||
{ XK_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{ XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{ XK_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{ XK_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{ XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{ XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{ XK_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{ XK_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{ XK_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{ XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{ XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{ XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{ XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
|
||||
{ XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
|
||||
{ XK_Home, ShiftMask, "\033[2J", 0, -1},
|
||||
{ XK_Home, ShiftMask, "\033[1;2H", 0, +1},
|
||||
{ XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
||||
{ XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
||||
{ XK_End, ControlMask, "\033[J", -1, 0},
|
||||
{ XK_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{ XK_End, ShiftMask, "\033[K", -1, 0},
|
||||
{ XK_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{ XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{ XK_Prior, ControlMask, "\033[5;5~", 0, 0},
|
||||
{ XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{ XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{ XK_Next, ControlMask, "\033[6;5~", 0, 0},
|
||||
{ XK_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{ XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{ XK_F1, XK_NO_MOD, "\033OP" , 0, 0},
|
||||
{ XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
|
||||
{ XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
|
||||
{ XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
|
||||
{ XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
|
||||
{ XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
|
||||
{ XK_F2, XK_NO_MOD, "\033OQ" , 0, 0},
|
||||
{ XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
|
||||
{ XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
|
||||
{ XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
|
||||
{ XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
|
||||
{ XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
|
||||
{ XK_F3, XK_NO_MOD, "\033OR" , 0, 0},
|
||||
{ XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
|
||||
{ XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
|
||||
{ XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
|
||||
{ XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
|
||||
{ XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
|
||||
{ XK_F4, XK_NO_MOD, "\033OS" , 0, 0},
|
||||
{ XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
|
||||
{ XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
|
||||
{ XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
|
||||
{ XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
|
||||
{ XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
|
||||
{ XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
|
||||
{ XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
|
||||
{ XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
|
||||
{ XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
|
||||
{ XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
|
||||
{ XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
|
||||
{ XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
|
||||
{ XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
|
||||
{ XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
|
||||
{ XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
|
||||
{ XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
|
||||
{ XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
|
||||
{ XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
|
||||
{ XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
|
||||
{ XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
|
||||
{ XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
|
||||
{ XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
|
||||
{ XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
|
||||
{ XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
|
||||
{ XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
|
||||
{ XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
|
||||
{ XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
|
||||
{ XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
|
||||
{ XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
|
||||
{ XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
|
||||
{ XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
|
||||
{ XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
|
||||
{ XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
|
||||
{ XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
|
||||
{ XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
|
||||
{ XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
|
||||
{ XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
|
||||
{ XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
|
||||
{ XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
|
||||
{ XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
|
||||
{ XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
|
||||
{ XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
|
||||
{ XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
|
||||
{ XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
|
||||
{ XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
|
||||
{ XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
|
||||
{ XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
|
||||
{ XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
|
||||
{ XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
|
||||
{ XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
|
||||
{ XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
|
||||
{ XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
|
||||
{ XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
|
||||
{ XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
|
||||
{ XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
|
||||
{ XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
|
||||
{ XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
|
||||
{ XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
|
||||
{ XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
|
||||
{ XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
|
||||
{ XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
|
||||
{ XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
|
||||
{ XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
|
||||
{ XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
|
||||
{ XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
|
||||
{ XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
|
||||
{ XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
|
||||
};
|
||||
|
||||
/*
|
||||
* Selection types' masks.
|
||||
* Use the same masks as usual.
|
||||
* Button1Mask is always unset, to make masks match between ButtonPress.
|
||||
* ButtonRelease and MotionNotify.
|
||||
* If no match is found, regular selection is used.
|
||||
*/
|
||||
static uint selmasks[] = {
|
||||
[SEL_RECTANGULAR] = Mod1Mask,
|
||||
};
|
||||
|
||||
/*
|
||||
* Printable characters in ASCII, used to estimate the advance width
|
||||
* of single wide characters.
|
||||
*/
|
||||
static char ascii_printable[] =
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
Executable
+486
@@ -0,0 +1,486 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
/*
|
||||
* appearance
|
||||
*
|
||||
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||
*/
|
||||
static char *font = "Terminus-9:antialias=true:autohint=true";
|
||||
static int borderpx = 2;
|
||||
|
||||
/*
|
||||
* What program is execed by st depends of these precedence rules:
|
||||
* 1: program passed with -e
|
||||
* 2: scroll and/or utmp
|
||||
* 3: SHELL environment variable
|
||||
* 4: value of shell in /etc/passwd
|
||||
* 5: value of shell in config.h
|
||||
*/
|
||||
static char *shell = "/bin/sh";
|
||||
char *utmp = NULL;
|
||||
/* scroll program: to enable use a string like "scroll" */
|
||||
char *scroll = NULL;
|
||||
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
|
||||
|
||||
/* identification sequence returned in DA and DECID */
|
||||
char *vtiden = "\033[?6c";
|
||||
|
||||
/* Kerning / character bounding-box multipliers */
|
||||
static float cwscale = 1.0;
|
||||
static float chscale = 1.0;
|
||||
|
||||
/*
|
||||
* word delimiter string
|
||||
*
|
||||
* More advanced example: L" `'\"()[]{}"
|
||||
*/
|
||||
wchar_t *worddelimiters = L" ";
|
||||
|
||||
/* selection timeouts (in milliseconds) */
|
||||
static unsigned int doubleclicktimeout = 300;
|
||||
static unsigned int tripleclicktimeout = 600;
|
||||
|
||||
/* alt screens */
|
||||
int allowaltscreen = 1;
|
||||
|
||||
/* allow certain non-interactive (insecure) window operations such as:
|
||||
setting the clipboard text */
|
||||
int allowwindowops = 0;
|
||||
|
||||
/*
|
||||
* draw latency range in ms - from new content/keypress/etc until drawing.
|
||||
* within this range, st draws when content stops arriving (idle). mostly it's
|
||||
* near minlatency, but it waits longer for slow updates to avoid partial draw.
|
||||
* low minlatency will tear/flicker more, as it can "detect" idle too early.
|
||||
*/
|
||||
static double minlatency = 2;
|
||||
static double maxlatency = 33;
|
||||
|
||||
/*
|
||||
* blinking timeout (set to 0 to disable blinking) for the terminal blinking
|
||||
* attribute.
|
||||
*/
|
||||
static unsigned int blinktimeout = 800;
|
||||
|
||||
/*
|
||||
* thickness of underline and bar cursors
|
||||
*/
|
||||
static unsigned int cursorthickness = 2;
|
||||
|
||||
/*
|
||||
* bell volume. It must be a value between -100 and 100. Use 0 for disabling
|
||||
* it
|
||||
*/
|
||||
static int bellvolume = 0;
|
||||
|
||||
/* default TERM value */
|
||||
char *termname = "st-256color";
|
||||
|
||||
/*
|
||||
* spaces per tab
|
||||
*
|
||||
* When you are changing this value, don't forget to adapt the »it« value in
|
||||
* the st.info and appropriately install the st.info in the environment where
|
||||
* you use this st version.
|
||||
*
|
||||
* it#$tabspaces,
|
||||
*
|
||||
* Secondly make sure your kernel is not expanding tabs. When running `stty
|
||||
* -a` »tab0« should appear. You can tell the terminal to not expand tabs by
|
||||
* running following command:
|
||||
*
|
||||
* stty tabs
|
||||
*/
|
||||
unsigned int tabspaces = 8;
|
||||
|
||||
/* bg opacity */
|
||||
float alpha = 0.8;
|
||||
|
||||
/* Background opacity */
|
||||
float alpha_def;
|
||||
|
||||
/* Terminal colors (16 first used in escape sequence) */
|
||||
static const char *colorname[] = {
|
||||
|
||||
/* 8 normal colors */
|
||||
"#333e21", /* black */
|
||||
"#757849", /* red */
|
||||
"#FF432A", /* green */
|
||||
"#c83e72", /* yellow */
|
||||
"#448C2C", /* blue */
|
||||
"#7d5f5f", /* magenta */
|
||||
"#bd8c77", /* cyan */
|
||||
"#efdceb", /* white */
|
||||
|
||||
/* 8 bright colors */
|
||||
"#686e50", /* black */
|
||||
"#A6AA6A", /* red */
|
||||
"#fa6d5a", /* green */
|
||||
"#d3658e", /* yellow */
|
||||
"#80BD6C", /* blue */
|
||||
"#B38887", /* magenta */
|
||||
"#f0bfaa", /* cyan */
|
||||
"#ffffff", /* white */
|
||||
|
||||
[255] = 0,
|
||||
|
||||
/* more colors can be added after 255 to use with DefaultXX */
|
||||
"gray90", /* default foreground colour */
|
||||
"black", /* default background colour */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Default colors (colorname index)
|
||||
* foreground, background, cursor, reverse cursor
|
||||
*/
|
||||
unsigned int defaultfg = 256;
|
||||
unsigned int defaultbg = 257;
|
||||
unsigned int defaultcs = 256;
|
||||
static unsigned int defaultrcs = 257;
|
||||
|
||||
/*
|
||||
* Default shape of cursor
|
||||
* 2: Block ("█")
|
||||
* 4: Underline ("_")
|
||||
* 6: Bar ("|")
|
||||
* 7: Snowman ("☃")
|
||||
*/
|
||||
static unsigned int cursorshape = 6;
|
||||
|
||||
/*
|
||||
* Default columns and rows numbers
|
||||
*/
|
||||
|
||||
static unsigned int cols = 80;
|
||||
static unsigned int rows = 24;
|
||||
|
||||
/*
|
||||
* Default colour and shape of the mouse cursor
|
||||
*/
|
||||
static unsigned int mouseshape = XC_xterm;
|
||||
static unsigned int mousefg = 7;
|
||||
static unsigned int mousebg = 0;
|
||||
|
||||
/*
|
||||
* Color used to display font attributes when fontconfig selected a font which
|
||||
* doesn't match the ones requested.
|
||||
*/
|
||||
static unsigned int defaultattr = 11;
|
||||
|
||||
/*
|
||||
* Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
|
||||
* Note that if you want to use ShiftMask with selmasks, set this to an other
|
||||
* modifier, set to 0 to not use it.
|
||||
*/
|
||||
static uint forcemousemod = ShiftMask;
|
||||
|
||||
/*
|
||||
* Internal mouse shortcuts.
|
||||
* Beware that overloading Button1 will disable the selection.
|
||||
*/
|
||||
static MouseShortcut mshortcuts[] = {
|
||||
/* mask button function argument release */
|
||||
{ XK_NO_MOD, Button4, kscrollup, {.i = 1} },
|
||||
{ XK_NO_MOD, Button5, kscrolldown, {.i = 1} },
|
||||
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
||||
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
|
||||
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
|
||||
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
|
||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
|
||||
};
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
#define MODKEY Mod1Mask
|
||||
#define TERMMOD (Mod1Mask|ShiftMask)
|
||||
|
||||
static Shortcut shortcuts[] = {
|
||||
/* mask keysym function argument */
|
||||
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
|
||||
{ ControlMask, XK_Print, toggleprinter, {.i = 0} },
|
||||
{ ShiftMask, XK_Print, printscreen, {.i = 0} },
|
||||
{ XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
|
||||
{ ControlMask, XK_equal, zoom, {.f = +1} },
|
||||
{ ControlMask, XK_minus, zoom, {.f = -1} },
|
||||
{ TERMMOD, XK_Home, zoomreset, {.f = 0} },
|
||||
{ MODKEY, XK_c, clipcopy, {.i = 0} },
|
||||
{ MODKEY, XK_v, clippaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
|
||||
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
|
||||
{ ShiftMask, XK_k, kscrollup, {.i = 1} },
|
||||
{ ShiftMask, XK_j, kscrolldown, {.i = 1} },
|
||||
{ MODKEY, XK_a, chgalpha, {.f = -1} },
|
||||
{ MODKEY, XK_s, chgalpha, {.f = +1} },
|
||||
{ MODKEY, XK_d, chgalpha, {.f = 0} },
|
||||
};
|
||||
|
||||
/*
|
||||
* Special keys (change & recompile st.info accordingly)
|
||||
*
|
||||
* Mask value:
|
||||
* * Use XK_ANY_MOD to match the key no matter modifiers state
|
||||
* * Use XK_NO_MOD to match the key alone (no modifiers)
|
||||
* appkey value:
|
||||
* * 0: no value
|
||||
* * > 0: keypad application mode enabled
|
||||
* * = 2: term.numlock = 1
|
||||
* * < 0: keypad application mode disabled
|
||||
* appcursor value:
|
||||
* * 0: no value
|
||||
* * > 0: cursor application mode enabled
|
||||
* * < 0: cursor application mode disabled
|
||||
*
|
||||
* Be careful with the order of the definitions because st searches in
|
||||
* this table sequentially, so any XK_ANY_MOD must be in the last
|
||||
* position for a key.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
|
||||
* to be mapped below, add them to this array.
|
||||
*/
|
||||
static KeySym mappedkeys[] = { -1 };
|
||||
|
||||
/*
|
||||
* State bits to ignore when matching key or button events. By default,
|
||||
* numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
|
||||
*/
|
||||
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
|
||||
|
||||
/*
|
||||
* This is the huge key array which defines all compatibility to the Linux
|
||||
* world. Please decide about changes wisely.
|
||||
*/
|
||||
static Key key[] = {
|
||||
/* keysym mask string appkey appcursor */
|
||||
{ XK_KP_Home, ShiftMask, "\033[2J", 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[1~", 0, +1},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{ XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{ XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{ XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{ XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{ XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{ XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{ XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
|
||||
{ XK_KP_End, ControlMask, "\033[J", -1, 0},
|
||||
{ XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{ XK_KP_End, ShiftMask, "\033[K", -1, 0},
|
||||
{ XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{ XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{ XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{ XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{ XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{ XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{ XK_KP_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{ XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{ XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{ XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{ XK_KP_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{ XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{ XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{ XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{ XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{ XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{ XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
|
||||
{ XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
|
||||
{ XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
|
||||
{ XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
|
||||
{ XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
|
||||
{ XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
|
||||
{ XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
|
||||
{ XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
|
||||
{ XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
|
||||
{ XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
|
||||
{ XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
|
||||
{ XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
|
||||
{ XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
|
||||
{ XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
|
||||
{ XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
|
||||
{ XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
|
||||
{ XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
|
||||
{ XK_Up, ShiftMask, "\033[1;2A", 0, 0},
|
||||
{ XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
|
||||
{ XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0},
|
||||
{ XK_Up, ControlMask, "\033[1;5A", 0, 0},
|
||||
{ XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0},
|
||||
{ XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0},
|
||||
{ XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0},
|
||||
{ XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||
{ XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||
{ XK_Down, ShiftMask, "\033[1;2B", 0, 0},
|
||||
{ XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
|
||||
{ XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0},
|
||||
{ XK_Down, ControlMask, "\033[1;5B", 0, 0},
|
||||
{ XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0},
|
||||
{ XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0},
|
||||
{ XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0},
|
||||
{ XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||
{ XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||
{ XK_Left, ShiftMask, "\033[1;2D", 0, 0},
|
||||
{ XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
|
||||
{ XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0},
|
||||
{ XK_Left, ControlMask, "\033[1;5D", 0, 0},
|
||||
{ XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0},
|
||||
{ XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0},
|
||||
{ XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0},
|
||||
{ XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||
{ XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||
{ XK_Right, ShiftMask, "\033[1;2C", 0, 0},
|
||||
{ XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
|
||||
{ XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0},
|
||||
{ XK_Right, ControlMask, "\033[1;5C", 0, 0},
|
||||
{ XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0},
|
||||
{ XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0},
|
||||
{ XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0},
|
||||
{ XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||
{ XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||
{ XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
|
||||
{ XK_Return, Mod1Mask, "\033\r", 0, 0},
|
||||
{ XK_Return, XK_ANY_MOD, "\r", 0, 0},
|
||||
{ XK_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||
{ XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||
{ XK_Insert, ControlMask, "\033[L", -1, 0},
|
||||
{ XK_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||
{ XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||
{ XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||
{ XK_Delete, ControlMask, "\033[M", -1, 0},
|
||||
{ XK_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||
{ XK_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||
{ XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||
{ XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||
{ XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||
{ XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
|
||||
{ XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
|
||||
{ XK_Home, ShiftMask, "\033[2J", 0, -1},
|
||||
{ XK_Home, ShiftMask, "\033[1;2H", 0, +1},
|
||||
{ XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
||||
{ XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
||||
{ XK_End, ControlMask, "\033[J", -1, 0},
|
||||
{ XK_End, ControlMask, "\033[1;5F", +1, 0},
|
||||
{ XK_End, ShiftMask, "\033[K", -1, 0},
|
||||
{ XK_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||
{ XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||
{ XK_Prior, ControlMask, "\033[5;5~", 0, 0},
|
||||
{ XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||
{ XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||
{ XK_Next, ControlMask, "\033[6;5~", 0, 0},
|
||||
{ XK_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||
{ XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||
{ XK_F1, XK_NO_MOD, "\033OP" , 0, 0},
|
||||
{ XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
|
||||
{ XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
|
||||
{ XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
|
||||
{ XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
|
||||
{ XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
|
||||
{ XK_F2, XK_NO_MOD, "\033OQ" , 0, 0},
|
||||
{ XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
|
||||
{ XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
|
||||
{ XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
|
||||
{ XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
|
||||
{ XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
|
||||
{ XK_F3, XK_NO_MOD, "\033OR" , 0, 0},
|
||||
{ XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
|
||||
{ XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
|
||||
{ XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
|
||||
{ XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
|
||||
{ XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
|
||||
{ XK_F4, XK_NO_MOD, "\033OS" , 0, 0},
|
||||
{ XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
|
||||
{ XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
|
||||
{ XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
|
||||
{ XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
|
||||
{ XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
|
||||
{ XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
|
||||
{ XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
|
||||
{ XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
|
||||
{ XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
|
||||
{ XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
|
||||
{ XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
|
||||
{ XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
|
||||
{ XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
|
||||
{ XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
|
||||
{ XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
|
||||
{ XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
|
||||
{ XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
|
||||
{ XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
|
||||
{ XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
|
||||
{ XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
|
||||
{ XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
|
||||
{ XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
|
||||
{ XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
|
||||
{ XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
|
||||
{ XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
|
||||
{ XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
|
||||
{ XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
|
||||
{ XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
|
||||
{ XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
|
||||
{ XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
|
||||
{ XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
|
||||
{ XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
|
||||
{ XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
|
||||
{ XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
|
||||
{ XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
|
||||
{ XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
|
||||
{ XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
|
||||
{ XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
|
||||
{ XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
|
||||
{ XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
|
||||
{ XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
|
||||
{ XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
|
||||
{ XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
|
||||
{ XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
|
||||
{ XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
|
||||
{ XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
|
||||
{ XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
|
||||
{ XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
|
||||
{ XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
|
||||
{ XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
|
||||
{ XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
|
||||
{ XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
|
||||
{ XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
|
||||
{ XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
|
||||
{ XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
|
||||
{ XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
|
||||
{ XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
|
||||
{ XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
|
||||
{ XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
|
||||
{ XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
|
||||
{ XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
|
||||
{ XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
|
||||
{ XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
|
||||
{ XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
|
||||
{ XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
|
||||
{ XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
|
||||
{ XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
|
||||
};
|
||||
|
||||
/*
|
||||
* Selection types' masks.
|
||||
* Use the same masks as usual.
|
||||
* Button1Mask is always unset, to make masks match between ButtonPress.
|
||||
* ButtonRelease and MotionNotify.
|
||||
* If no match is found, regular selection is used.
|
||||
*/
|
||||
static uint selmasks[] = {
|
||||
[SEL_RECTANGULAR] = Mod1Mask,
|
||||
};
|
||||
|
||||
/*
|
||||
* Printable characters in ASCII, used to estimate the advance width
|
||||
* of single wide characters.
|
||||
*/
|
||||
static char ascii_printable[] =
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
# st version
|
||||
VERSION = 0.9.2
|
||||
|
||||
# Customize below to fit your system
|
||||
|
||||
# paths
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = $(PREFIX)/share/man
|
||||
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
|
||||
PKG_CONFIG = pkg-config
|
||||
|
||||
# includes and libs
|
||||
INCS = -I$(X11INC) \
|
||||
`$(PKG_CONFIG) --cflags fontconfig` \
|
||||
`$(PKG_CONFIG) --cflags freetype2` \
|
||||
`$(PKG_CONFIG) --cflags harfbuzz`
|
||||
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender \
|
||||
`$(PKG_CONFIG) --libs fontconfig` \
|
||||
`$(PKG_CONFIG) --libs freetype2` \
|
||||
`$(PKG_CONFIG) --libs harfbuzz`
|
||||
|
||||
# flags
|
||||
STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600
|
||||
STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS)
|
||||
STLDFLAGS = $(LIBS) $(LDFLAGS)
|
||||
|
||||
# OpenBSD:
|
||||
#CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -D_BSD_SOURCE
|
||||
#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \
|
||||
# `$(PKG_CONFIG) --libs fontconfig` \
|
||||
# `$(PKG_CONFIG) --libs freetype2`
|
||||
#MANPREFIX = ${PREFIX}/man
|
||||
|
||||
# compiler and linker
|
||||
CC = gcc
|
||||
Executable
+3812
File diff suppressed because it is too large
Load Diff
Executable
+107
@@ -0,0 +1,107 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
/// Initialize the graphics module.
|
||||
void gr_init(Display *disp, Visual *vis, Colormap cm);
|
||||
/// Deinitialize the graphics module.
|
||||
void gr_deinit();
|
||||
|
||||
/// Add an image rectangle to a list if rectangles to draw. This function may
|
||||
/// actually draw some rectangles, or it may wait till more rectangles are
|
||||
/// appended. Must be called between `gr_start_drawing` and `gr_finish_drawing`.
|
||||
/// - `img_start_col..img_end_col` and `img_start_row..img_end_row` define the
|
||||
/// part of the image to draw (row/col indices are zero-based, ends are
|
||||
/// excluded).
|
||||
/// - `x_col` and `y_row` are the coordinates of the top-left corner of the
|
||||
/// image in the terminal grid.
|
||||
/// - `x_pix` and `y_pix` are the same but in pixels.
|
||||
/// - `reverse` indicates whether colors should be inverted.
|
||||
void gr_append_imagerect(Drawable buf, uint32_t image_id, uint32_t placement_id,
|
||||
int img_start_col, int img_end_col, int img_start_row,
|
||||
int img_end_row, int x_col, int y_row, int x_pix,
|
||||
int y_pix, int cw, int ch, int reverse);
|
||||
/// Prepare for image drawing. `cw` and `ch` are dimensions of the cell.
|
||||
void gr_start_drawing(Drawable buf, int cw, int ch);
|
||||
/// Finish image drawing. This functions will draw all the rectangles left to
|
||||
/// draw.
|
||||
void gr_finish_drawing(Drawable buf);
|
||||
/// Mark rows containing animations as dirty if it's time to redraw them. Must
|
||||
/// be called right after `gr_start_drawing`.
|
||||
void gr_mark_dirty_animations(int *dirty, int rows);
|
||||
|
||||
/// Parse and execute a graphics command. `buf` must start with 'G' and contain
|
||||
/// at least `len + 1` characters (including '\0'). Returns 1 on success.
|
||||
/// Additional informations is returned through `graphics_command_result`.
|
||||
int gr_parse_command(char *buf, size_t len);
|
||||
|
||||
/// Executes `command` with the name of the file corresponding to `image_id` as
|
||||
/// the argument. Executes xmessage with an error message on failure.
|
||||
void gr_preview_image(uint32_t image_id, const char *command);
|
||||
|
||||
/// Executes `<st> -e less <file>` where <file> is the name of a temporary file
|
||||
/// containing the information about an image and placement, and <st> is
|
||||
/// specified with `st_executable`.
|
||||
void gr_show_image_info(uint32_t image_id, uint32_t placement_id,
|
||||
uint32_t imgcol, uint32_t imgrow,
|
||||
char is_classic_placeholder, int32_t diacritic_count,
|
||||
char *st_executable);
|
||||
|
||||
/// Dumps the internal state (images and placements) to stderr.
|
||||
void gr_dump_state();
|
||||
|
||||
/// Unloads images to reduce RAM usage.
|
||||
void gr_unload_images_to_reduce_ram();
|
||||
|
||||
/// Executes `callback` for each image cell. `callback` may return 1 to erase
|
||||
/// the cell or 0 to keep it. This function is implemented in `st.c`.
|
||||
void gr_for_each_image_cell(int (*callback)(void *data, uint32_t image_id,
|
||||
uint32_t placement_id, int col,
|
||||
int row, char is_classic),
|
||||
void *data);
|
||||
|
||||
/// Marks all the rows containing the image with `image_id` as dirty.
|
||||
void gr_schedule_image_redraw_by_id(uint32_t image_id);
|
||||
|
||||
typedef enum {
|
||||
GRAPHICS_DEBUG_NONE = 0,
|
||||
GRAPHICS_DEBUG_LOG = 1,
|
||||
GRAPHICS_DEBUG_LOG_AND_BOXES = 2,
|
||||
} GraphicsDebugMode;
|
||||
|
||||
/// Print additional information, draw bounding bounding boxes, etc.
|
||||
extern GraphicsDebugMode graphics_debug_mode;
|
||||
|
||||
/// Whether to display images or just draw bounding boxes.
|
||||
extern char graphics_display_images;
|
||||
|
||||
/// The time in milliseconds until the next redraw to update animations.
|
||||
/// INT_MAX means no redraw is needed. Populated by `gr_finish_drawing`.
|
||||
extern int graphics_next_redraw_delay;
|
||||
|
||||
#define MAX_GRAPHICS_RESPONSE_LEN 256
|
||||
|
||||
/// A structure representing the result of a graphics command.
|
||||
typedef struct {
|
||||
/// Indicates if the terminal needs to be redrawn.
|
||||
char redraw;
|
||||
/// The response of the command that should be sent back to the client
|
||||
/// (may be empty if the quiet flag is set).
|
||||
char response[MAX_GRAPHICS_RESPONSE_LEN];
|
||||
/// Whether there was an error executing this command (not very useful,
|
||||
/// the response must be sent back anyway).
|
||||
char error;
|
||||
/// Whether the terminal has to create a placeholder for a non-virtual
|
||||
/// placement.
|
||||
char create_placeholder;
|
||||
/// The placeholder that needs to be created.
|
||||
struct {
|
||||
uint32_t rows, columns;
|
||||
uint32_t image_id, placement_id;
|
||||
char do_not_move_cursor;
|
||||
} placeholder;
|
||||
} GraphicsCommandResult;
|
||||
|
||||
/// The result of a graphics command.
|
||||
extern GraphicsCommandResult graphics_command_result;
|
||||
@@ -0,0 +1,125 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <hb.h>
|
||||
#include <hb-ft.h>
|
||||
|
||||
#include "st.h"
|
||||
#include "hb.h"
|
||||
|
||||
#define FEATURE(c1,c2,c3,c4) { .tag = HB_TAG(c1,c2,c3,c4), .value = 1, .start = HB_FEATURE_GLOBAL_START, .end = HB_FEATURE_GLOBAL_END }
|
||||
#define BUFFER_STEP 256
|
||||
|
||||
hb_font_t *hbfindfont(XftFont *match);
|
||||
|
||||
typedef struct {
|
||||
XftFont *match;
|
||||
hb_font_t *font;
|
||||
} HbFontMatch;
|
||||
|
||||
typedef struct {
|
||||
size_t capacity;
|
||||
HbFontMatch *fonts;
|
||||
} HbFontCache;
|
||||
|
||||
static HbFontCache hbfontcache = { 0, NULL };
|
||||
|
||||
typedef struct {
|
||||
size_t capacity;
|
||||
Rune *runes;
|
||||
} RuneBuffer;
|
||||
|
||||
static RuneBuffer hbrunebuffer = { 0, NULL };
|
||||
|
||||
/*
|
||||
* Poplulate the array with a list of font features, wrapped in FEATURE macro,
|
||||
* e. g.
|
||||
* FEATURE('c', 'a', 'l', 't'), FEATURE('d', 'l', 'i', 'g')
|
||||
*/
|
||||
hb_feature_t features[] = {0};
|
||||
|
||||
void
|
||||
hbunloadfonts()
|
||||
{
|
||||
for (int i = 0; i < hbfontcache.capacity; i++) {
|
||||
hb_font_destroy(hbfontcache.fonts[i].font);
|
||||
XftUnlockFace(hbfontcache.fonts[i].match);
|
||||
}
|
||||
|
||||
if (hbfontcache.fonts != NULL) {
|
||||
free(hbfontcache.fonts);
|
||||
hbfontcache.fonts = NULL;
|
||||
}
|
||||
hbfontcache.capacity = 0;
|
||||
}
|
||||
|
||||
hb_font_t *
|
||||
hbfindfont(XftFont *match)
|
||||
{
|
||||
for (int i = 0; i < hbfontcache.capacity; i++) {
|
||||
if (hbfontcache.fonts[i].match == match)
|
||||
return hbfontcache.fonts[i].font;
|
||||
}
|
||||
|
||||
/* Font not found in cache, caching it now. */
|
||||
hbfontcache.fonts = realloc(hbfontcache.fonts, sizeof(HbFontMatch) * (hbfontcache.capacity + 1));
|
||||
FT_Face face = XftLockFace(match);
|
||||
hb_font_t *font = hb_ft_font_create(face, NULL);
|
||||
if (font == NULL)
|
||||
die("Failed to load Harfbuzz font.");
|
||||
|
||||
hbfontcache.fonts[hbfontcache.capacity].match = match;
|
||||
hbfontcache.fonts[hbfontcache.capacity].font = font;
|
||||
hbfontcache.capacity += 1;
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
void hbtransform(HbTransformData *data, XftFont *xfont, const Glyph *glyphs, int start, int length) {
|
||||
ushort mode = USHRT_MAX;
|
||||
unsigned int glyph_count;
|
||||
int rune_idx, glyph_idx, end = start + length;
|
||||
|
||||
hb_font_t *font = hbfindfont(xfont);
|
||||
if (font == NULL)
|
||||
return;
|
||||
|
||||
hb_buffer_t *buffer = hb_buffer_create();
|
||||
hb_buffer_set_direction(buffer, HB_DIRECTION_LTR);
|
||||
hb_buffer_set_cluster_level(buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
|
||||
|
||||
/* Resize the buffer if required length is larger. */
|
||||
if (hbrunebuffer.capacity < length) {
|
||||
hbrunebuffer.capacity = (length / BUFFER_STEP + 1) * BUFFER_STEP;
|
||||
hbrunebuffer.runes = realloc(hbrunebuffer.runes, hbrunebuffer.capacity * sizeof(Rune));
|
||||
}
|
||||
|
||||
/* Fill buffer with codepoints. */
|
||||
for (rune_idx = 0, glyph_idx = start; glyph_idx < end; glyph_idx++, rune_idx++) {
|
||||
hbrunebuffer.runes[rune_idx] = glyphs[glyph_idx].u;
|
||||
mode = glyphs[glyph_idx].mode;
|
||||
if (mode & ATTR_WDUMMY)
|
||||
hbrunebuffer.runes[rune_idx] = 0x0020;
|
||||
}
|
||||
hb_buffer_add_codepoints(buffer, hbrunebuffer.runes, length, 0, length);
|
||||
|
||||
/* Shape the segment. */
|
||||
hb_shape(font, buffer, features, sizeof(features)/sizeof(hb_feature_t));
|
||||
|
||||
/* Get new glyph info. */
|
||||
hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, &glyph_count);
|
||||
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(buffer, &glyph_count);
|
||||
|
||||
/* Fill the output. */
|
||||
data->buffer = buffer;
|
||||
data->glyphs = info;
|
||||
data->positions = pos;
|
||||
data->count = glyph_count;
|
||||
}
|
||||
|
||||
void hbcleanup(HbTransformData *data) {
|
||||
hb_buffer_destroy(data->buffer);
|
||||
memset(data, 0, sizeof(HbTransformData));
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#include <X11/Xft/Xft.h>
|
||||
#include <hb.h>
|
||||
#include <hb-ft.h>
|
||||
|
||||
typedef struct {
|
||||
hb_buffer_t *buffer;
|
||||
hb_glyph_info_t *glyphs;
|
||||
hb_glyph_position_t *positions;
|
||||
unsigned int count;
|
||||
} HbTransformData;
|
||||
|
||||
void hbunloadfonts();
|
||||
void hbtransform(HbTransformData *, XftFont *, const Glyph *, int, int);
|
||||
void hbcleanup(HbTransformData *);
|
||||
Executable
+800
@@ -0,0 +1,800 @@
|
||||
#!/bin/sh
|
||||
|
||||
# vim: shiftwidth=4
|
||||
|
||||
script_name="$(basename "$0")"
|
||||
|
||||
short_help="Usage: $script_name [OPTIONS] <image_file>
|
||||
|
||||
This is a script to display images in the terminal using the kitty graphics
|
||||
protocol with Unicode placeholders. It is very basic, please use something else
|
||||
if you have alternatives.
|
||||
|
||||
Options:
|
||||
-h Show this help.
|
||||
-s SCALE The scale of the image, may be floating point.
|
||||
-c N, --cols N The number of columns.
|
||||
-r N, --rows N The number of rows.
|
||||
--max-cols N The maximum number of columns.
|
||||
--max-rows N The maximum number of rows.
|
||||
--cell-size WxH The cell size in pixels.
|
||||
-m METHOD The uploading method, may be 'file', 'direct' or 'auto'.
|
||||
--speed SPEED The multiplier for the animation speed (float).
|
||||
"
|
||||
|
||||
# Exit the script on keyboard interrupt
|
||||
trap "echo 'icat-mini was interrupted' >&2; exit 1" INT
|
||||
|
||||
cols=""
|
||||
rows=""
|
||||
file=""
|
||||
tty="/dev/tty"
|
||||
uploading_method="auto"
|
||||
cell_size=""
|
||||
scale=1
|
||||
max_cols=""
|
||||
max_rows=""
|
||||
speed=""
|
||||
|
||||
# Parse the command line.
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-c|--columns|--cols)
|
||||
cols="$2"
|
||||
shift 2
|
||||
;;
|
||||
-r|--rows|-l|--lines)
|
||||
rows="$2"
|
||||
shift 2
|
||||
;;
|
||||
-s|--scale)
|
||||
scale="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
echo "$short_help"
|
||||
exit 0
|
||||
;;
|
||||
-m|--upload-method|--uploading-method)
|
||||
uploading_method="$2"
|
||||
shift 2
|
||||
;;
|
||||
--cell-size)
|
||||
cell_size="$2"
|
||||
shift 2
|
||||
;;
|
||||
--max-cols)
|
||||
max_cols="$2"
|
||||
shift 2
|
||||
;;
|
||||
--max-rows)
|
||||
max_rows="$2"
|
||||
shift 2
|
||||
;;
|
||||
--speed)
|
||||
speed="$2"
|
||||
shift 2
|
||||
;;
|
||||
--)
|
||||
file="$2"
|
||||
shift 2
|
||||
;;
|
||||
-*)
|
||||
echo "Unknown option: $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
if [ -n "$file" ]; then
|
||||
echo "Multiple image files are not supported: $file and $1" >&2
|
||||
exit 1
|
||||
fi
|
||||
file="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
file="$(realpath "$file")"
|
||||
|
||||
#####################################################################
|
||||
# Adjust the terminal state
|
||||
#####################################################################
|
||||
|
||||
stty_orig="$(stty -g < "$tty")"
|
||||
stty -echo < "$tty"
|
||||
# Disable ctrl-z. Pressing ctrl-z during image uploading may cause some
|
||||
# horrible issues otherwise.
|
||||
stty susp undef < "$tty"
|
||||
stty -icanon < "$tty"
|
||||
|
||||
restore_echo() {
|
||||
[ -n "$stty_orig" ] || return
|
||||
stty $stty_orig < "$tty"
|
||||
}
|
||||
|
||||
trap restore_echo EXIT TERM
|
||||
|
||||
#####################################################################
|
||||
# Detect imagemagick
|
||||
#####################################################################
|
||||
|
||||
# If there is the 'magick' command, use it instead of separate 'convert' and
|
||||
# 'identify' commands.
|
||||
if command -v magick > /dev/null; then
|
||||
identify="magick identify"
|
||||
convert="magick"
|
||||
else
|
||||
identify="identify"
|
||||
convert="convert"
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
# Detect tmux
|
||||
#####################################################################
|
||||
|
||||
# Check if we are inside tmux.
|
||||
inside_tmux=""
|
||||
if [ -n "$TMUX" ]; then
|
||||
case "$TERM" in
|
||||
*tmux*|*screen*)
|
||||
inside_tmux=1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
# Compute the number of rows and columns
|
||||
#####################################################################
|
||||
|
||||
is_pos_int() {
|
||||
if [ -z "$1" ]; then
|
||||
return 1 # false
|
||||
fi
|
||||
if [ -z "$(printf '%s' "$1" | tr -d '[:digit:]')" ]; then
|
||||
if [ "$1" -gt 0 ]; then
|
||||
return 0 # true
|
||||
fi
|
||||
fi
|
||||
return 1 # false
|
||||
}
|
||||
|
||||
if [ -n "$cols" ] || [ -n "$rows" ]; then
|
||||
if [ -n "$max_cols" ] || [ -n "$max_rows" ]; then
|
||||
echo "You can't specify both max-cols/rows and cols/rows" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# Get the max number of cols and rows.
|
||||
[ -n "$max_cols" ] || max_cols="$(tput cols)"
|
||||
[ -n "$max_rows" ] || max_rows="$(tput lines)"
|
||||
if [ "$max_rows" -gt 255 ]; then
|
||||
max_rows=255
|
||||
fi
|
||||
|
||||
python_ioctl_command="import array, fcntl, termios
|
||||
buf = array.array('H', [0, 0, 0, 0])
|
||||
fcntl.ioctl(0, termios.TIOCGWINSZ, buf)
|
||||
print(int(buf[2]/buf[1]), int(buf[3]/buf[0]))"
|
||||
|
||||
# Get the cell size in pixels if either cols or rows are not specified.
|
||||
if [ -z "$cols" ] || [ -z "$rows" ]; then
|
||||
cell_width=""
|
||||
cell_height=""
|
||||
# If the cell size is specified, use it.
|
||||
if [ -n "$cell_size" ]; then
|
||||
cell_width="${cell_size%x*}"
|
||||
cell_height="${cell_size#*x}"
|
||||
if ! is_pos_int "$cell_height" || ! is_pos_int "$cell_width"; then
|
||||
echo "Invalid cell size: $cell_size" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# Otherwise try to use TIOCGWINSZ ioctl via python.
|
||||
if [ -z "$cell_width" ] || [ -z "$cell_height" ]; then
|
||||
cell_size_ioctl="$(python3 -c "$python_ioctl_command" < "$tty" 2> /dev/null)"
|
||||
cell_width="${cell_size_ioctl% *}"
|
||||
cell_height="${cell_size_ioctl#* }"
|
||||
if ! is_pos_int "$cell_height" || ! is_pos_int "$cell_width"; then
|
||||
cell_width=""
|
||||
cell_height=""
|
||||
fi
|
||||
fi
|
||||
# If it didn't work, try to use csi XTWINOPS.
|
||||
if [ -z "$cell_width" ] || [ -z "$cell_height" ]; then
|
||||
if [ -n "$inside_tmux" ]; then
|
||||
printf '\ePtmux;\e\e[16t\e\\' >> "$tty"
|
||||
else
|
||||
printf '\e[16t' >> "$tty"
|
||||
fi
|
||||
# The expected response will look like ^[[6;<height>;<width>t
|
||||
term_response=""
|
||||
while true; do
|
||||
char=$(dd bs=1 count=1 <"$tty" 2>/dev/null)
|
||||
if [ "$char" = "t" ]; then
|
||||
break
|
||||
fi
|
||||
term_response="$term_response$char"
|
||||
done
|
||||
cell_height="$(printf '%s' "$term_response" | cut -d ';' -f 2)"
|
||||
cell_width="$(printf '%s' "$term_response" | cut -d ';' -f 3)"
|
||||
if ! is_pos_int "$cell_height" || ! is_pos_int "$cell_width"; then
|
||||
cell_width=8
|
||||
cell_height=16
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Compute a formula with bc and round to the nearest integer.
|
||||
bc_round() {
|
||||
LC_NUMERIC=C printf '%.0f' "$(printf '%s\n' "scale=2;($1) + 0.5" | bc)"
|
||||
}
|
||||
|
||||
# Compute the number of rows and columns of the image.
|
||||
if [ -z "$cols" ] || [ -z "$rows" ]; then
|
||||
# Get the size of the image and its resolution. If it's an animation, use
|
||||
# the first frame.
|
||||
format_output="$($identify -format '%w %h\n' "$file" | head -1)"
|
||||
img_width="$(printf '%s' "$format_output" | cut -d ' ' -f 1)"
|
||||
img_height="$(printf '%s' "$format_output" | cut -d ' ' -f 2)"
|
||||
if ! is_pos_int "$img_width" || ! is_pos_int "$img_height"; then
|
||||
echo "Couldn't get image size from identify: $format_output" >&2
|
||||
echo >&2
|
||||
exit 1
|
||||
fi
|
||||
opt_cols_expr="(${scale}*${img_width}/${cell_width})"
|
||||
opt_rows_expr="(${scale}*${img_height}/${cell_height})"
|
||||
if [ -z "$cols" ] && [ -z "$rows" ]; then
|
||||
# If columns and rows are not specified, compute the optimal values
|
||||
# using the information about rows and columns per inch.
|
||||
cols="$(bc_round "$opt_cols_expr")"
|
||||
rows="$(bc_round "$opt_rows_expr")"
|
||||
# Make sure that automatically computed rows and columns are within some
|
||||
# sane limits
|
||||
if [ "$cols" -gt "$max_cols" ]; then
|
||||
rows="$(bc_round "$rows * $max_cols / $cols")"
|
||||
cols="$max_cols"
|
||||
fi
|
||||
if [ "$rows" -gt "$max_rows" ]; then
|
||||
cols="$(bc_round "$cols * $max_rows / $rows")"
|
||||
rows="$max_rows"
|
||||
fi
|
||||
elif [ -z "$cols" ]; then
|
||||
# If only one dimension is specified, compute the other one to match the
|
||||
# aspect ratio as close as possible.
|
||||
cols="$(bc_round "${opt_cols_expr}*${rows}/${opt_rows_expr}")"
|
||||
elif [ -z "$rows" ]; then
|
||||
rows="$(bc_round "${opt_rows_expr}*${cols}/${opt_cols_expr}")"
|
||||
fi
|
||||
|
||||
if [ "$cols" -lt 1 ]; then
|
||||
cols=1
|
||||
fi
|
||||
if [ "$rows" -lt 1 ]; then
|
||||
rows=1
|
||||
fi
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
# Generate an image id
|
||||
#####################################################################
|
||||
|
||||
image_id=""
|
||||
while [ -z "$image_id" ]; do
|
||||
image_id="$(shuf -i 16777217-4294967295 -n 1)"
|
||||
# Check that the id requires 24-bit fg colors.
|
||||
if [ "$(expr \( "$image_id" / 256 \) % 65536)" -eq 0 ]; then
|
||||
image_id=""
|
||||
fi
|
||||
done
|
||||
|
||||
#####################################################################
|
||||
# Uploading the image
|
||||
#####################################################################
|
||||
|
||||
# Choose the uploading method
|
||||
if [ "$uploading_method" = "auto" ]; then
|
||||
if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ] || [ -n "$SSH_CONNECTION" ]; then
|
||||
uploading_method="direct"
|
||||
else
|
||||
uploading_method="file"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Functions to emit the start and the end of a graphics command.
|
||||
if [ -n "$inside_tmux" ]; then
|
||||
# If we are in tmux we have to wrap the command in Ptmux.
|
||||
graphics_command_start='\ePtmux;\e\e_G'
|
||||
graphics_command_end='\e\e\\\e\\'
|
||||
else
|
||||
graphics_command_start='\e_G'
|
||||
graphics_command_end='\e\\'
|
||||
fi
|
||||
|
||||
start_gr_command() {
|
||||
printf "$graphics_command_start" >> "$tty"
|
||||
}
|
||||
end_gr_command() {
|
||||
printf "$graphics_command_end" >> "$tty"
|
||||
}
|
||||
|
||||
# Send a graphics command with the correct start and end
|
||||
gr_command() {
|
||||
start_gr_command
|
||||
printf '%s' "$1" >> "$tty"
|
||||
end_gr_command
|
||||
}
|
||||
|
||||
# Send an uploading command. Usage: gr_upload <action> <command> <file>
|
||||
# Where <action> is a part of command that specifies the action, it will be
|
||||
# repeated for every chunk (if the method is direct), and <command> is the rest
|
||||
# of the command that specifies the image parameters. <action> and <command>
|
||||
# must not include the transmission method or ';'.
|
||||
# Example:
|
||||
# gr_upload "a=T,q=2" "U=1,i=${image_id},f=100,c=${cols},r=${rows}" "$file"
|
||||
gr_upload() {
|
||||
arg_action="$1"
|
||||
arg_command="$2"
|
||||
arg_file="$3"
|
||||
if [ "$uploading_method" = "file" ]; then
|
||||
# base64-encode the filename
|
||||
encoded_filename=$(printf '%s' "$arg_file" | base64 -w0)
|
||||
gr_command "${arg_action},${arg_command},t=f;${encoded_filename}"
|
||||
fi
|
||||
if [ "$uploading_method" = "direct" ]; then
|
||||
# Create a temporary directory to store the chunked image.
|
||||
chunkdir="$(mktemp -d)"
|
||||
if [ ! "$chunkdir" ] || [ ! -d "$chunkdir" ]; then
|
||||
echo "Can't create a temp dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
# base64-encode the file and split it into chunks. The size of each
|
||||
# graphics command shouldn't be more than 4096, so we set the size of an
|
||||
# encoded chunk to be 3968, slightly less than that.
|
||||
chunk_size=3968
|
||||
cat "$arg_file" | base64 -w0 | split -b "$chunk_size" - "$chunkdir/chunk_"
|
||||
|
||||
# Issue a command indicating that we want to start data transmission for
|
||||
# a new image.
|
||||
gr_command "${arg_action},${arg_command},t=d,m=1"
|
||||
|
||||
# Transmit chunks.
|
||||
for chunk in "$chunkdir/chunk_"*; do
|
||||
start_gr_command
|
||||
printf '%s' "${arg_action},i=${image_id},m=1;" >> "$tty"
|
||||
cat "$chunk" >> "$tty"
|
||||
end_gr_command
|
||||
rm "$chunk"
|
||||
done
|
||||
|
||||
# Tell the terminal that we are done.
|
||||
gr_command "${arg_action},i=$image_id,m=0"
|
||||
|
||||
# Remove the temporary directory.
|
||||
rmdir "$chunkdir"
|
||||
fi
|
||||
}
|
||||
|
||||
delayed_frame_dir_cleanup() {
|
||||
arg_frame_dir="$1"
|
||||
sleep 2
|
||||
if [ -n "$arg_frame_dir" ]; then
|
||||
for frame in "$arg_frame_dir"/frame_*.png; do
|
||||
rm "$frame"
|
||||
done
|
||||
rmdir "$arg_frame_dir"
|
||||
fi
|
||||
}
|
||||
|
||||
upload_image_and_print_placeholder() {
|
||||
# Check if the file is an animation.
|
||||
frame_count=$($identify -format '%n\n' "$file" | head -n 1)
|
||||
if [ "$frame_count" -gt 1 ]; then
|
||||
# The file is an animation, decompose into frames and upload each frame.
|
||||
frame_dir="$(mktemp -d)"
|
||||
frame_dir="$HOME/temp/frames${frame_dir}"
|
||||
mkdir -p "$frame_dir"
|
||||
if [ ! "$frame_dir" ] || [ ! -d "$frame_dir" ]; then
|
||||
echo "Can't create a temp dir for frames" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Decompose the animation into separate frames.
|
||||
$convert "$file" -coalesce "$frame_dir/frame_%06d.png"
|
||||
|
||||
# Get all frame delays at once, in centiseconds, as a space-separated
|
||||
# string.
|
||||
delays=$($identify -format "%T " "$file")
|
||||
|
||||
frame_number=1
|
||||
for frame in "$frame_dir"/frame_*.png; do
|
||||
# Read the delay for the current frame and convert it from
|
||||
# centiseconds to milliseconds.
|
||||
delay=$(printf '%s' "$delays" | cut -d ' ' -f "$frame_number")
|
||||
delay=$((delay * 10))
|
||||
# If the delay is 0, set it to 100ms.
|
||||
if [ "$delay" -eq 0 ]; then
|
||||
delay=100
|
||||
fi
|
||||
|
||||
if [ -n "$speed" ]; then
|
||||
delay=$(bc_round "$delay / $speed")
|
||||
fi
|
||||
|
||||
if [ "$frame_number" -eq 1 ]; then
|
||||
# Upload the first frame with a=T
|
||||
gr_upload "q=2,a=T" "f=100,U=1,i=${image_id},c=${cols},r=${rows}" "$frame"
|
||||
# Set the delay for the first frame and also play the animation
|
||||
# in loading mode (s=2).
|
||||
gr_command "a=a,v=1,s=2,r=${frame_number},z=${delay},i=${image_id}"
|
||||
# Print the placeholder after the first frame to reduce the wait
|
||||
# time.
|
||||
print_placeholder
|
||||
else
|
||||
# Upload subsequent frames with a=f
|
||||
gr_upload "q=2,a=f" "f=100,i=${image_id},z=${delay}" "$frame"
|
||||
fi
|
||||
|
||||
frame_number=$((frame_number + 1))
|
||||
done
|
||||
|
||||
# Play the animation in loop mode (s=3).
|
||||
gr_command "a=a,v=1,s=3,i=${image_id}"
|
||||
|
||||
# Remove the temporary directory, but do it in the background with a
|
||||
# delay to avoid removing files before they are loaded by the terminal.
|
||||
delayed_frame_dir_cleanup "$frame_dir" 2> /dev/null &
|
||||
else
|
||||
# The file is not an animation, upload it directly
|
||||
gr_upload "q=2,a=T" "U=1,i=${image_id},f=100,c=${cols},r=${rows}" "$file"
|
||||
# Print the placeholder
|
||||
print_placeholder
|
||||
fi
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# Printing the image placeholder
|
||||
#####################################################################
|
||||
|
||||
print_placeholder() {
|
||||
# Each line starts with the escape sequence to set the foreground color to
|
||||
# the image id.
|
||||
blue="$(expr "$image_id" % 256 )"
|
||||
green="$(expr \( "$image_id" / 256 \) % 256 )"
|
||||
red="$(expr \( "$image_id" / 65536 \) % 256 )"
|
||||
line_start="$(printf "\e[38;2;%d;%d;%dm" "$red" "$green" "$blue")"
|
||||
line_end="$(printf "\e[39;m")"
|
||||
|
||||
id4th="$(expr \( "$image_id" / 16777216 \) % 256 )"
|
||||
eval "id_diacritic=\$d${id4th}"
|
||||
|
||||
# Reset the brush state, mostly to reset the underline color.
|
||||
printf "\e[0m"
|
||||
|
||||
# Fill the output with characters representing the image
|
||||
for y in $(seq 0 "$(expr "$rows" - 1)"); do
|
||||
eval "row_diacritic=\$d${y}"
|
||||
printf '%s' "$line_start"
|
||||
for x in $(seq 0 "$(expr "$cols" - 1)"); do
|
||||
eval "col_diacritic=\$d${x}"
|
||||
# Note that when $x is out of bounds, the column diacritic will
|
||||
# be empty, meaning that the column should be guessed by the
|
||||
# terminal.
|
||||
if [ "$x" -ge "$num_diacritics" ]; then
|
||||
printf '%s' "${placeholder}${row_diacritic}"
|
||||
else
|
||||
printf '%s' "${placeholder}${row_diacritic}${col_diacritic}${id_diacritic}"
|
||||
fi
|
||||
done
|
||||
printf '%s\n' "$line_end"
|
||||
done
|
||||
|
||||
printf "\e[0m"
|
||||
}
|
||||
|
||||
d0="̅"
|
||||
d1="̍"
|
||||
d2="̎"
|
||||
d3="̐"
|
||||
d4="̒"
|
||||
d5="̽"
|
||||
d6="̾"
|
||||
d7="̿"
|
||||
d8="͆"
|
||||
d9="͊"
|
||||
d10="͋"
|
||||
d11="͌"
|
||||
d12="͐"
|
||||
d13="͑"
|
||||
d14="͒"
|
||||
d15="͗"
|
||||
d16="͛"
|
||||
d17="ͣ"
|
||||
d18="ͤ"
|
||||
d19="ͥ"
|
||||
d20="ͦ"
|
||||
d21="ͧ"
|
||||
d22="ͨ"
|
||||
d23="ͩ"
|
||||
d24="ͪ"
|
||||
d25="ͫ"
|
||||
d26="ͬ"
|
||||
d27="ͭ"
|
||||
d28="ͮ"
|
||||
d29="ͯ"
|
||||
d30="҃"
|
||||
d31="҄"
|
||||
d32="҅"
|
||||
d33="҆"
|
||||
d34="҇"
|
||||
d35="֒"
|
||||
d36="֓"
|
||||
d37="֔"
|
||||
d38="֕"
|
||||
d39="֗"
|
||||
d40="֘"
|
||||
d41="֙"
|
||||
d42="֜"
|
||||
d43="֝"
|
||||
d44="֞"
|
||||
d45="֟"
|
||||
d46="֠"
|
||||
d47="֡"
|
||||
d48="֨"
|
||||
d49="֩"
|
||||
d50="֫"
|
||||
d51="֬"
|
||||
d52="֯"
|
||||
d53="ׄ"
|
||||
d54="ؐ"
|
||||
d55="ؑ"
|
||||
d56="ؒ"
|
||||
d57="ؓ"
|
||||
d58="ؔ"
|
||||
d59="ؕ"
|
||||
d60="ؖ"
|
||||
d61="ؗ"
|
||||
d62="ٗ"
|
||||
d63="٘"
|
||||
d64="ٙ"
|
||||
d65="ٚ"
|
||||
d66="ٛ"
|
||||
d67="ٝ"
|
||||
d68="ٞ"
|
||||
d69="ۖ"
|
||||
d70="ۗ"
|
||||
d71="ۘ"
|
||||
d72="ۙ"
|
||||
d73="ۚ"
|
||||
d74="ۛ"
|
||||
d75="ۜ"
|
||||
d76="۟"
|
||||
d77="۠"
|
||||
d78="ۡ"
|
||||
d79="ۢ"
|
||||
d80="ۤ"
|
||||
d81="ۧ"
|
||||
d82="ۨ"
|
||||
d83="۫"
|
||||
d84="۬"
|
||||
d85="ܰ"
|
||||
d86="ܲ"
|
||||
d87="ܳ"
|
||||
d88="ܵ"
|
||||
d89="ܶ"
|
||||
d90="ܺ"
|
||||
d91="ܽ"
|
||||
d92="ܿ"
|
||||
d93="݀"
|
||||
d94="݁"
|
||||
d95="݃"
|
||||
d96="݅"
|
||||
d97="݇"
|
||||
d98="݉"
|
||||
d99="݊"
|
||||
d100="߫"
|
||||
d101="߬"
|
||||
d102="߭"
|
||||
d103="߮"
|
||||
d104="߯"
|
||||
d105="߰"
|
||||
d106="߱"
|
||||
d107="߳"
|
||||
d108="ࠖ"
|
||||
d109="ࠗ"
|
||||
d110="࠘"
|
||||
d111="࠙"
|
||||
d112="ࠛ"
|
||||
d113="ࠜ"
|
||||
d114="ࠝ"
|
||||
d115="ࠞ"
|
||||
d116="ࠟ"
|
||||
d117="ࠠ"
|
||||
d118="ࠡ"
|
||||
d119="ࠢ"
|
||||
d120="ࠣ"
|
||||
d121="ࠥ"
|
||||
d122="ࠦ"
|
||||
d123="ࠧ"
|
||||
d124="ࠩ"
|
||||
d125="ࠪ"
|
||||
d126="ࠫ"
|
||||
d127="ࠬ"
|
||||
d128="࠭"
|
||||
d129="॑"
|
||||
d130="॓"
|
||||
d131="॔"
|
||||
d132="ྂ"
|
||||
d133="ྃ"
|
||||
d134="྆"
|
||||
d135="྇"
|
||||
d136="፝"
|
||||
d137="፞"
|
||||
d138="፟"
|
||||
d139="៝"
|
||||
d140="᤺"
|
||||
d141="ᨗ"
|
||||
d142="᩵"
|
||||
d143="᩶"
|
||||
d144="᩷"
|
||||
d145="᩸"
|
||||
d146="᩹"
|
||||
d147="᩺"
|
||||
d148="᩻"
|
||||
d149="᩼"
|
||||
d150="᭫"
|
||||
d151="᭭"
|
||||
d152="᭮"
|
||||
d153="᭯"
|
||||
d154="᭰"
|
||||
d155="᭱"
|
||||
d156="᭲"
|
||||
d157="᭳"
|
||||
d158="᳐"
|
||||
d159="᳑"
|
||||
d160="᳒"
|
||||
d161="᳚"
|
||||
d162="᳛"
|
||||
d163="᳠"
|
||||
d164="᷀"
|
||||
d165="᷁"
|
||||
d166="᷃"
|
||||
d167="᷄"
|
||||
d168="᷅"
|
||||
d169="᷆"
|
||||
d170="᷇"
|
||||
d171="᷈"
|
||||
d172="᷉"
|
||||
d173="᷋"
|
||||
d174="᷌"
|
||||
d175="᷑"
|
||||
d176="᷒"
|
||||
d177="ᷓ"
|
||||
d178="ᷔ"
|
||||
d179="ᷕ"
|
||||
d180="ᷖ"
|
||||
d181="ᷗ"
|
||||
d182="ᷘ"
|
||||
d183="ᷙ"
|
||||
d184="ᷚ"
|
||||
d185="ᷛ"
|
||||
d186="ᷜ"
|
||||
d187="ᷝ"
|
||||
d188="ᷞ"
|
||||
d189="ᷟ"
|
||||
d190="ᷠ"
|
||||
d191="ᷡ"
|
||||
d192="ᷢ"
|
||||
d193="ᷣ"
|
||||
d194="ᷤ"
|
||||
d195="ᷥ"
|
||||
d196="ᷦ"
|
||||
d197="᷾"
|
||||
d198="⃐"
|
||||
d199="⃑"
|
||||
d200="⃔"
|
||||
d201="⃕"
|
||||
d202="⃖"
|
||||
d203="⃗"
|
||||
d204="⃛"
|
||||
d205="⃜"
|
||||
d206="⃡"
|
||||
d207="⃧"
|
||||
d208="⃩"
|
||||
d209="⃰"
|
||||
d210="⳯"
|
||||
d211="⳰"
|
||||
d212="⳱"
|
||||
d213="ⷠ"
|
||||
d214="ⷡ"
|
||||
d215="ⷢ"
|
||||
d216="ⷣ"
|
||||
d217="ⷤ"
|
||||
d218="ⷥ"
|
||||
d219="ⷦ"
|
||||
d220="ⷧ"
|
||||
d221="ⷨ"
|
||||
d222="ⷩ"
|
||||
d223="ⷪ"
|
||||
d224="ⷫ"
|
||||
d225="ⷬ"
|
||||
d226="ⷭ"
|
||||
d227="ⷮ"
|
||||
d228="ⷯ"
|
||||
d229="ⷰ"
|
||||
d230="ⷱ"
|
||||
d231="ⷲ"
|
||||
d232="ⷳ"
|
||||
d233="ⷴ"
|
||||
d234="ⷵ"
|
||||
d235="ⷶ"
|
||||
d236="ⷷ"
|
||||
d237="ⷸ"
|
||||
d238="ⷹ"
|
||||
d239="ⷺ"
|
||||
d240="ⷻ"
|
||||
d241="ⷼ"
|
||||
d242="ⷽ"
|
||||
d243="ⷾ"
|
||||
d244="ⷿ"
|
||||
d245="꙯"
|
||||
d246="꙼"
|
||||
d247="꙽"
|
||||
d248="꛰"
|
||||
d249="꛱"
|
||||
d250="꣠"
|
||||
d251="꣡"
|
||||
d252="꣢"
|
||||
d253="꣣"
|
||||
d254="꣤"
|
||||
d255="꣥"
|
||||
d256="꣦"
|
||||
d257="꣧"
|
||||
d258="꣨"
|
||||
d259="꣩"
|
||||
d260="꣪"
|
||||
d261="꣫"
|
||||
d262="꣬"
|
||||
d263="꣭"
|
||||
d264="꣮"
|
||||
d265="꣯"
|
||||
d266="꣰"
|
||||
d267="꣱"
|
||||
d268="ꪰ"
|
||||
d269="ꪲ"
|
||||
d270="ꪳ"
|
||||
d271="ꪷ"
|
||||
d272="ꪸ"
|
||||
d273="ꪾ"
|
||||
d274="꪿"
|
||||
d275="꫁"
|
||||
d276="︠"
|
||||
d277="︡"
|
||||
d278="︢"
|
||||
d279="︣"
|
||||
d280="︤"
|
||||
d281="︥"
|
||||
d282="︦"
|
||||
d283="𐨏"
|
||||
d284="𐨸"
|
||||
d285="𝆅"
|
||||
d286="𝆆"
|
||||
d287="𝆇"
|
||||
d288="𝆈"
|
||||
d289="𝆉"
|
||||
d290="𝆪"
|
||||
d291="𝆫"
|
||||
d292="𝆬"
|
||||
d293="𝆭"
|
||||
d294="𝉂"
|
||||
d295="𝉃"
|
||||
d296="𝉄"
|
||||
|
||||
num_diacritics="297"
|
||||
|
||||
placeholder=""
|
||||
|
||||
#####################################################################
|
||||
# Upload the image and print the placeholder
|
||||
#####################################################################
|
||||
|
||||
upload_image_and_print_placeholder
|
||||
Executable
+627
@@ -0,0 +1,627 @@
|
||||
/* The MIT License
|
||||
|
||||
Copyright (c) 2008, 2009, 2011 by Attractive Chaos <attractor@live.co.uk>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
An example:
|
||||
|
||||
#include "khash.h"
|
||||
KHASH_MAP_INIT_INT(32, char)
|
||||
int main() {
|
||||
int ret, is_missing;
|
||||
khiter_t k;
|
||||
khash_t(32) *h = kh_init(32);
|
||||
k = kh_put(32, h, 5, &ret);
|
||||
kh_value(h, k) = 10;
|
||||
k = kh_get(32, h, 10);
|
||||
is_missing = (k == kh_end(h));
|
||||
k = kh_get(32, h, 5);
|
||||
kh_del(32, h, k);
|
||||
for (k = kh_begin(h); k != kh_end(h); ++k)
|
||||
if (kh_exist(h, k)) kh_value(h, k) = 1;
|
||||
kh_destroy(32, h);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
2013-05-02 (0.2.8):
|
||||
|
||||
* Use quadratic probing. When the capacity is power of 2, stepping function
|
||||
i*(i+1)/2 guarantees to traverse each bucket. It is better than double
|
||||
hashing on cache performance and is more robust than linear probing.
|
||||
|
||||
In theory, double hashing should be more robust than quadratic probing.
|
||||
However, my implementation is probably not for large hash tables, because
|
||||
the second hash function is closely tied to the first hash function,
|
||||
which reduce the effectiveness of double hashing.
|
||||
|
||||
Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php
|
||||
|
||||
2011-12-29 (0.2.7):
|
||||
|
||||
* Minor code clean up; no actual effect.
|
||||
|
||||
2011-09-16 (0.2.6):
|
||||
|
||||
* The capacity is a power of 2. This seems to dramatically improve the
|
||||
speed for simple keys. Thank Zilong Tan for the suggestion. Reference:
|
||||
|
||||
- http://code.google.com/p/ulib/
|
||||
- http://nothings.org/computer/judy/
|
||||
|
||||
* Allow to optionally use linear probing which usually has better
|
||||
performance for random input. Double hashing is still the default as it
|
||||
is more robust to certain non-random input.
|
||||
|
||||
* Added Wang's integer hash function (not used by default). This hash
|
||||
function is more robust to certain non-random input.
|
||||
|
||||
2011-02-14 (0.2.5):
|
||||
|
||||
* Allow to declare global functions.
|
||||
|
||||
2009-09-26 (0.2.4):
|
||||
|
||||
* Improve portability
|
||||
|
||||
2008-09-19 (0.2.3):
|
||||
|
||||
* Corrected the example
|
||||
* Improved interfaces
|
||||
|
||||
2008-09-11 (0.2.2):
|
||||
|
||||
* Improved speed a little in kh_put()
|
||||
|
||||
2008-09-10 (0.2.1):
|
||||
|
||||
* Added kh_clear()
|
||||
* Fixed a compiling error
|
||||
|
||||
2008-09-02 (0.2.0):
|
||||
|
||||
* Changed to token concatenation which increases flexibility.
|
||||
|
||||
2008-08-31 (0.1.2):
|
||||
|
||||
* Fixed a bug in kh_get(), which has not been tested previously.
|
||||
|
||||
2008-08-31 (0.1.1):
|
||||
|
||||
* Added destructor
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __AC_KHASH_H
|
||||
#define __AC_KHASH_H
|
||||
|
||||
/*!
|
||||
@header
|
||||
|
||||
Generic hash table library.
|
||||
*/
|
||||
|
||||
#define AC_VERSION_KHASH_H "0.2.8"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* compiler specific configuration */
|
||||
|
||||
#if UINT_MAX == 0xffffffffu
|
||||
typedef unsigned int khint32_t;
|
||||
#elif ULONG_MAX == 0xffffffffu
|
||||
typedef unsigned long khint32_t;
|
||||
#endif
|
||||
|
||||
#if ULONG_MAX == ULLONG_MAX
|
||||
typedef unsigned long khint64_t;
|
||||
#else
|
||||
typedef unsigned long long khint64_t;
|
||||
#endif
|
||||
|
||||
#ifndef kh_inline
|
||||
#ifdef _MSC_VER
|
||||
#define kh_inline __inline
|
||||
#else
|
||||
#define kh_inline inline
|
||||
#endif
|
||||
#endif /* kh_inline */
|
||||
|
||||
#ifndef klib_unused
|
||||
#if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3)
|
||||
#define klib_unused __attribute__ ((__unused__))
|
||||
#else
|
||||
#define klib_unused
|
||||
#endif
|
||||
#endif /* klib_unused */
|
||||
|
||||
typedef khint32_t khint_t;
|
||||
typedef khint_t khiter_t;
|
||||
|
||||
#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2)
|
||||
#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1)
|
||||
#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3)
|
||||
#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1)))
|
||||
#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1)))
|
||||
#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1)))
|
||||
#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1))
|
||||
|
||||
#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4)
|
||||
|
||||
#ifndef kroundup32
|
||||
#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
|
||||
#endif
|
||||
|
||||
#ifndef kcalloc
|
||||
#define kcalloc(N,Z) calloc(N,Z)
|
||||
#endif
|
||||
#ifndef kmalloc
|
||||
#define kmalloc(Z) malloc(Z)
|
||||
#endif
|
||||
#ifndef krealloc
|
||||
#define krealloc(P,Z) realloc(P,Z)
|
||||
#endif
|
||||
#ifndef kfree
|
||||
#define kfree(P) free(P)
|
||||
#endif
|
||||
|
||||
static const double __ac_HASH_UPPER = 0.77;
|
||||
|
||||
#define __KHASH_TYPE(name, khkey_t, khval_t) \
|
||||
typedef struct kh_##name##_s { \
|
||||
khint_t n_buckets, size, n_occupied, upper_bound; \
|
||||
khint32_t *flags; \
|
||||
khkey_t *keys; \
|
||||
khval_t *vals; \
|
||||
} kh_##name##_t;
|
||||
|
||||
#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \
|
||||
extern kh_##name##_t *kh_init_##name(void); \
|
||||
extern void kh_destroy_##name(kh_##name##_t *h); \
|
||||
extern void kh_clear_##name(kh_##name##_t *h); \
|
||||
extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \
|
||||
extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \
|
||||
extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \
|
||||
extern void kh_del_##name(kh_##name##_t *h, khint_t x);
|
||||
|
||||
#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
|
||||
SCOPE kh_##name##_t *kh_init_##name(void) { \
|
||||
return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \
|
||||
} \
|
||||
SCOPE void kh_destroy_##name(kh_##name##_t *h) \
|
||||
{ \
|
||||
if (h) { \
|
||||
kfree((void *)h->keys); kfree(h->flags); \
|
||||
kfree((void *)h->vals); \
|
||||
kfree(h); \
|
||||
} \
|
||||
} \
|
||||
SCOPE void kh_clear_##name(kh_##name##_t *h) \
|
||||
{ \
|
||||
if (h && h->flags) { \
|
||||
memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \
|
||||
h->size = h->n_occupied = 0; \
|
||||
} \
|
||||
} \
|
||||
SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
|
||||
{ \
|
||||
if (h->n_buckets) { \
|
||||
khint_t k, i, last, mask, step = 0; \
|
||||
mask = h->n_buckets - 1; \
|
||||
k = __hash_func(key); i = k & mask; \
|
||||
last = i; \
|
||||
while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
|
||||
i = (i + (++step)) & mask; \
|
||||
if (i == last) return h->n_buckets; \
|
||||
} \
|
||||
return __ac_iseither(h->flags, i)? h->n_buckets : i; \
|
||||
} else return 0; \
|
||||
} \
|
||||
SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
|
||||
{ /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \
|
||||
khint32_t *new_flags = 0; \
|
||||
khint_t j = 1; \
|
||||
{ \
|
||||
kroundup32(new_n_buckets); \
|
||||
if (new_n_buckets < 4) new_n_buckets = 4; \
|
||||
if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \
|
||||
else { /* hash table size to be changed (shrink or expand); rehash */ \
|
||||
new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
|
||||
if (!new_flags) return -1; \
|
||||
memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
|
||||
if (h->n_buckets < new_n_buckets) { /* expand */ \
|
||||
khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
|
||||
if (!new_keys) { kfree(new_flags); return -1; } \
|
||||
h->keys = new_keys; \
|
||||
if (kh_is_map) { \
|
||||
khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
|
||||
if (!new_vals) { kfree(new_flags); return -1; } \
|
||||
h->vals = new_vals; \
|
||||
} \
|
||||
} /* otherwise shrink */ \
|
||||
} \
|
||||
} \
|
||||
if (j) { /* rehashing is needed */ \
|
||||
for (j = 0; j != h->n_buckets; ++j) { \
|
||||
if (__ac_iseither(h->flags, j) == 0) { \
|
||||
khkey_t key = h->keys[j]; \
|
||||
khval_t val; \
|
||||
khint_t new_mask; \
|
||||
new_mask = new_n_buckets - 1; \
|
||||
if (kh_is_map) val = h->vals[j]; \
|
||||
__ac_set_isdel_true(h->flags, j); \
|
||||
while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \
|
||||
khint_t k, i, step = 0; \
|
||||
k = __hash_func(key); \
|
||||
i = k & new_mask; \
|
||||
while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \
|
||||
__ac_set_isempty_false(new_flags, i); \
|
||||
if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \
|
||||
{ khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
|
||||
if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \
|
||||
__ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \
|
||||
} else { /* write the element and jump out of the loop */ \
|
||||
h->keys[i] = key; \
|
||||
if (kh_is_map) h->vals[i] = val; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \
|
||||
h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
|
||||
if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
|
||||
} \
|
||||
kfree(h->flags); /* free the working space */ \
|
||||
h->flags = new_flags; \
|
||||
h->n_buckets = new_n_buckets; \
|
||||
h->n_occupied = h->size; \
|
||||
h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \
|
||||
} \
|
||||
return 0; \
|
||||
} \
|
||||
SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
|
||||
{ \
|
||||
khint_t x; \
|
||||
if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \
|
||||
if (h->n_buckets > (h->size<<1)) { \
|
||||
if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \
|
||||
*ret = -1; return h->n_buckets; \
|
||||
} \
|
||||
} else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \
|
||||
*ret = -1; return h->n_buckets; \
|
||||
} \
|
||||
} /* TODO: to implement automatically shrinking; resize() already support shrinking */ \
|
||||
{ \
|
||||
khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \
|
||||
x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \
|
||||
if (__ac_isempty(h->flags, i)) x = i; /* for speed up */ \
|
||||
else { \
|
||||
last = i; \
|
||||
while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
|
||||
if (__ac_isdel(h->flags, i)) site = i; \
|
||||
i = (i + (++step)) & mask; \
|
||||
if (i == last) { x = site; break; } \
|
||||
} \
|
||||
if (x == h->n_buckets) { \
|
||||
if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \
|
||||
else x = i; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (__ac_isempty(h->flags, x)) { /* not present at all */ \
|
||||
h->keys[x] = key; \
|
||||
__ac_set_isboth_false(h->flags, x); \
|
||||
++h->size; ++h->n_occupied; \
|
||||
*ret = 1; \
|
||||
} else if (__ac_isdel(h->flags, x)) { /* deleted */ \
|
||||
h->keys[x] = key; \
|
||||
__ac_set_isboth_false(h->flags, x); \
|
||||
++h->size; \
|
||||
*ret = 2; \
|
||||
} else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \
|
||||
return x; \
|
||||
} \
|
||||
SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \
|
||||
{ \
|
||||
if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \
|
||||
__ac_set_isdel_true(h->flags, x); \
|
||||
--h->size; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define KHASH_DECLARE(name, khkey_t, khval_t) \
|
||||
__KHASH_TYPE(name, khkey_t, khval_t) \
|
||||
__KHASH_PROTOTYPES(name, khkey_t, khval_t)
|
||||
|
||||
#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
|
||||
__KHASH_TYPE(name, khkey_t, khval_t) \
|
||||
__KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
|
||||
|
||||
#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
|
||||
KHASH_INIT2(name, static kh_inline klib_unused, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
|
||||
|
||||
/* --- BEGIN OF HASH FUNCTIONS --- */
|
||||
|
||||
/*! @function
|
||||
@abstract Integer hash function
|
||||
@param key The integer [khint32_t]
|
||||
@return The hash value [khint_t]
|
||||
*/
|
||||
#define kh_int_hash_func(key) (khint32_t)(key)
|
||||
/*! @function
|
||||
@abstract Integer comparison function
|
||||
*/
|
||||
#define kh_int_hash_equal(a, b) ((a) == (b))
|
||||
/*! @function
|
||||
@abstract 64-bit integer hash function
|
||||
@param key The integer [khint64_t]
|
||||
@return The hash value [khint_t]
|
||||
*/
|
||||
#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11)
|
||||
/*! @function
|
||||
@abstract 64-bit integer comparison function
|
||||
*/
|
||||
#define kh_int64_hash_equal(a, b) ((a) == (b))
|
||||
/*! @function
|
||||
@abstract const char* hash function
|
||||
@param s Pointer to a null terminated string
|
||||
@return The hash value
|
||||
*/
|
||||
static kh_inline khint_t __ac_X31_hash_string(const char *s)
|
||||
{
|
||||
khint_t h = (khint_t)*s;
|
||||
if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s;
|
||||
return h;
|
||||
}
|
||||
/*! @function
|
||||
@abstract Another interface to const char* hash function
|
||||
@param key Pointer to a null terminated string [const char*]
|
||||
@return The hash value [khint_t]
|
||||
*/
|
||||
#define kh_str_hash_func(key) __ac_X31_hash_string(key)
|
||||
/*! @function
|
||||
@abstract Const char* comparison function
|
||||
*/
|
||||
#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0)
|
||||
|
||||
static kh_inline khint_t __ac_Wang_hash(khint_t key)
|
||||
{
|
||||
key += ~(key << 15);
|
||||
key ^= (key >> 10);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 6);
|
||||
key += ~(key << 11);
|
||||
key ^= (key >> 16);
|
||||
return key;
|
||||
}
|
||||
#define kh_int_hash_func2(key) __ac_Wang_hash((khint_t)key)
|
||||
|
||||
/* --- END OF HASH FUNCTIONS --- */
|
||||
|
||||
/* Other convenient macros... */
|
||||
|
||||
/*!
|
||||
@abstract Type of the hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
*/
|
||||
#define khash_t(name) kh_##name##_t
|
||||
|
||||
/*! @function
|
||||
@abstract Initiate a hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@return Pointer to the hash table [khash_t(name)*]
|
||||
*/
|
||||
#define kh_init(name) kh_init_##name()
|
||||
|
||||
/*! @function
|
||||
@abstract Destroy a hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
*/
|
||||
#define kh_destroy(name, h) kh_destroy_##name(h)
|
||||
|
||||
/*! @function
|
||||
@abstract Reset a hash table without deallocating memory.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
*/
|
||||
#define kh_clear(name, h) kh_clear_##name(h)
|
||||
|
||||
/*! @function
|
||||
@abstract Resize a hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param s New size [khint_t]
|
||||
*/
|
||||
#define kh_resize(name, h, s) kh_resize_##name(h, s)
|
||||
|
||||
/*! @function
|
||||
@abstract Insert a key to the hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param k Key [type of keys]
|
||||
@param r Extra return code: -1 if the operation failed;
|
||||
0 if the key is present in the hash table;
|
||||
1 if the bucket is empty (never used); 2 if the element in
|
||||
the bucket has been deleted [int*]
|
||||
@return Iterator to the inserted element [khint_t]
|
||||
*/
|
||||
#define kh_put(name, h, k, r) kh_put_##name(h, k, r)
|
||||
|
||||
/*! @function
|
||||
@abstract Retrieve a key from the hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param k Key [type of keys]
|
||||
@return Iterator to the found element, or kh_end(h) if the element is absent [khint_t]
|
||||
*/
|
||||
#define kh_get(name, h, k) kh_get_##name(h, k)
|
||||
|
||||
/*! @function
|
||||
@abstract Remove a key from the hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param k Iterator to the element to be deleted [khint_t]
|
||||
*/
|
||||
#define kh_del(name, h, k) kh_del_##name(h, k)
|
||||
|
||||
/*! @function
|
||||
@abstract Test whether a bucket contains data.
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param x Iterator to the bucket [khint_t]
|
||||
@return 1 if containing data; 0 otherwise [int]
|
||||
*/
|
||||
#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x)))
|
||||
|
||||
/*! @function
|
||||
@abstract Get key given an iterator
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param x Iterator to the bucket [khint_t]
|
||||
@return Key [type of keys]
|
||||
*/
|
||||
#define kh_key(h, x) ((h)->keys[x])
|
||||
|
||||
/*! @function
|
||||
@abstract Get value given an iterator
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param x Iterator to the bucket [khint_t]
|
||||
@return Value [type of values]
|
||||
@discussion For hash sets, calling this results in segfault.
|
||||
*/
|
||||
#define kh_val(h, x) ((h)->vals[x])
|
||||
|
||||
/*! @function
|
||||
@abstract Alias of kh_val()
|
||||
*/
|
||||
#define kh_value(h, x) ((h)->vals[x])
|
||||
|
||||
/*! @function
|
||||
@abstract Get the start iterator
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@return The start iterator [khint_t]
|
||||
*/
|
||||
#define kh_begin(h) (khint_t)(0)
|
||||
|
||||
/*! @function
|
||||
@abstract Get the end iterator
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@return The end iterator [khint_t]
|
||||
*/
|
||||
#define kh_end(h) ((h)->n_buckets)
|
||||
|
||||
/*! @function
|
||||
@abstract Get the number of elements in the hash table
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@return Number of elements in the hash table [khint_t]
|
||||
*/
|
||||
#define kh_size(h) ((h)->size)
|
||||
|
||||
/*! @function
|
||||
@abstract Get the number of buckets in the hash table
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@return Number of buckets in the hash table [khint_t]
|
||||
*/
|
||||
#define kh_n_buckets(h) ((h)->n_buckets)
|
||||
|
||||
/*! @function
|
||||
@abstract Iterate over the entries in the hash table
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param kvar Variable to which key will be assigned
|
||||
@param vvar Variable to which value will be assigned
|
||||
@param code Block of code to execute
|
||||
*/
|
||||
#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \
|
||||
for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
|
||||
if (!kh_exist(h,__i)) continue; \
|
||||
(kvar) = kh_key(h,__i); \
|
||||
(vvar) = kh_val(h,__i); \
|
||||
code; \
|
||||
} }
|
||||
|
||||
/*! @function
|
||||
@abstract Iterate over the values in the hash table
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param vvar Variable to which value will be assigned
|
||||
@param code Block of code to execute
|
||||
*/
|
||||
#define kh_foreach_value(h, vvar, code) { khint_t __i; \
|
||||
for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
|
||||
if (!kh_exist(h,__i)) continue; \
|
||||
(vvar) = kh_val(h,__i); \
|
||||
code; \
|
||||
} }
|
||||
|
||||
/* More convenient interfaces */
|
||||
|
||||
/*! @function
|
||||
@abstract Instantiate a hash set containing integer keys
|
||||
@param name Name of the hash table [symbol]
|
||||
*/
|
||||
#define KHASH_SET_INIT_INT(name) \
|
||||
KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
|
||||
|
||||
/*! @function
|
||||
@abstract Instantiate a hash map containing integer keys
|
||||
@param name Name of the hash table [symbol]
|
||||
@param khval_t Type of values [type]
|
||||
*/
|
||||
#define KHASH_MAP_INIT_INT(name, khval_t) \
|
||||
KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
|
||||
|
||||
/*! @function
|
||||
@abstract Instantiate a hash set containing 64-bit integer keys
|
||||
@param name Name of the hash table [symbol]
|
||||
*/
|
||||
#define KHASH_SET_INIT_INT64(name) \
|
||||
KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
|
||||
|
||||
/*! @function
|
||||
@abstract Instantiate a hash map containing 64-bit integer keys
|
||||
@param name Name of the hash table [symbol]
|
||||
@param khval_t Type of values [type]
|
||||
*/
|
||||
#define KHASH_MAP_INIT_INT64(name, khval_t) \
|
||||
KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
|
||||
|
||||
typedef const char *kh_cstr_t;
|
||||
/*! @function
|
||||
@abstract Instantiate a hash map containing const char* keys
|
||||
@param name Name of the hash table [symbol]
|
||||
*/
|
||||
#define KHASH_SET_INIT_STR(name) \
|
||||
KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal)
|
||||
|
||||
/*! @function
|
||||
@abstract Instantiate a hash map containing const char* keys
|
||||
@param name Name of the hash table [symbol]
|
||||
@param khval_t Type of values [type]
|
||||
*/
|
||||
#define KHASH_MAP_INIT_STR(name, khval_t) \
|
||||
KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
|
||||
|
||||
#endif /* __AC_KHASH_H */
|
||||
@@ -0,0 +1,90 @@
|
||||
/* The MIT License
|
||||
|
||||
Copyright (c) 2008, by Attractive Chaos <attractor@live.co.uk>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
An example:
|
||||
|
||||
#include "kvec.h"
|
||||
int main() {
|
||||
kvec_t(int) array;
|
||||
kv_init(array);
|
||||
kv_push(int, array, 10); // append
|
||||
kv_a(int, array, 20) = 5; // dynamic
|
||||
kv_A(array, 20) = 4; // static
|
||||
kv_destroy(array);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
2008-09-22 (0.1.0):
|
||||
|
||||
* The initial version.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AC_KVEC_H
|
||||
#define AC_KVEC_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
|
||||
|
||||
#define kvec_t(type) struct { size_t n, m; type *a; }
|
||||
#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0)
|
||||
#define kv_destroy(v) free((v).a)
|
||||
#define kv_A(v, i) ((v).a[(i)])
|
||||
#define kv_pop(v) ((v).a[--(v).n])
|
||||
#define kv_size(v) ((v).n)
|
||||
#define kv_max(v) ((v).m)
|
||||
|
||||
#define kv_resize(type, v, s) ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m))
|
||||
|
||||
#define kv_copy(type, v1, v0) do { \
|
||||
if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n); \
|
||||
(v1).n = (v0).n; \
|
||||
memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \
|
||||
} while (0) \
|
||||
|
||||
#define kv_push(type, v, x) do { \
|
||||
if ((v).n == (v).m) { \
|
||||
(v).m = (v).m? (v).m<<1 : 2; \
|
||||
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \
|
||||
} \
|
||||
(v).a[(v).n++] = (x); \
|
||||
} while (0)
|
||||
|
||||
#define kv_pushp(type, v) ((((v).n == (v).m)? \
|
||||
((v).m = ((v).m? (v).m<<1 : 2), \
|
||||
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \
|
||||
: 0), ((v).a + ((v).n++)))
|
||||
|
||||
#define kv_a(type, v, i) (((v).m <= (size_t)(i)? \
|
||||
((v).m = (v).n = (i) + 1, kv_roundup32((v).m), \
|
||||
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \
|
||||
: (v).n <= (size_t)(i)? (v).n = (i) + 1 \
|
||||
: 0), (v).a[(i)])
|
||||
|
||||
#endif
|
||||
Executable
+391
@@ -0,0 +1,391 @@
|
||||
#include <stdint.h>
|
||||
|
||||
uint16_t diacritic_to_num(uint32_t code)
|
||||
{
|
||||
switch (code) {
|
||||
case 0x305:
|
||||
return code - 0x305 + 1;
|
||||
case 0x30d:
|
||||
case 0x30e:
|
||||
return code - 0x30d + 2;
|
||||
case 0x310:
|
||||
return code - 0x310 + 4;
|
||||
case 0x312:
|
||||
return code - 0x312 + 5;
|
||||
case 0x33d:
|
||||
case 0x33e:
|
||||
case 0x33f:
|
||||
return code - 0x33d + 6;
|
||||
case 0x346:
|
||||
return code - 0x346 + 9;
|
||||
case 0x34a:
|
||||
case 0x34b:
|
||||
case 0x34c:
|
||||
return code - 0x34a + 10;
|
||||
case 0x350:
|
||||
case 0x351:
|
||||
case 0x352:
|
||||
return code - 0x350 + 13;
|
||||
case 0x357:
|
||||
return code - 0x357 + 16;
|
||||
case 0x35b:
|
||||
return code - 0x35b + 17;
|
||||
case 0x363:
|
||||
case 0x364:
|
||||
case 0x365:
|
||||
case 0x366:
|
||||
case 0x367:
|
||||
case 0x368:
|
||||
case 0x369:
|
||||
case 0x36a:
|
||||
case 0x36b:
|
||||
case 0x36c:
|
||||
case 0x36d:
|
||||
case 0x36e:
|
||||
case 0x36f:
|
||||
return code - 0x363 + 18;
|
||||
case 0x483:
|
||||
case 0x484:
|
||||
case 0x485:
|
||||
case 0x486:
|
||||
case 0x487:
|
||||
return code - 0x483 + 31;
|
||||
case 0x592:
|
||||
case 0x593:
|
||||
case 0x594:
|
||||
case 0x595:
|
||||
return code - 0x592 + 36;
|
||||
case 0x597:
|
||||
case 0x598:
|
||||
case 0x599:
|
||||
return code - 0x597 + 40;
|
||||
case 0x59c:
|
||||
case 0x59d:
|
||||
case 0x59e:
|
||||
case 0x59f:
|
||||
case 0x5a0:
|
||||
case 0x5a1:
|
||||
return code - 0x59c + 43;
|
||||
case 0x5a8:
|
||||
case 0x5a9:
|
||||
return code - 0x5a8 + 49;
|
||||
case 0x5ab:
|
||||
case 0x5ac:
|
||||
return code - 0x5ab + 51;
|
||||
case 0x5af:
|
||||
return code - 0x5af + 53;
|
||||
case 0x5c4:
|
||||
return code - 0x5c4 + 54;
|
||||
case 0x610:
|
||||
case 0x611:
|
||||
case 0x612:
|
||||
case 0x613:
|
||||
case 0x614:
|
||||
case 0x615:
|
||||
case 0x616:
|
||||
case 0x617:
|
||||
return code - 0x610 + 55;
|
||||
case 0x657:
|
||||
case 0x658:
|
||||
case 0x659:
|
||||
case 0x65a:
|
||||
case 0x65b:
|
||||
return code - 0x657 + 63;
|
||||
case 0x65d:
|
||||
case 0x65e:
|
||||
return code - 0x65d + 68;
|
||||
case 0x6d6:
|
||||
case 0x6d7:
|
||||
case 0x6d8:
|
||||
case 0x6d9:
|
||||
case 0x6da:
|
||||
case 0x6db:
|
||||
case 0x6dc:
|
||||
return code - 0x6d6 + 70;
|
||||
case 0x6df:
|
||||
case 0x6e0:
|
||||
case 0x6e1:
|
||||
case 0x6e2:
|
||||
return code - 0x6df + 77;
|
||||
case 0x6e4:
|
||||
return code - 0x6e4 + 81;
|
||||
case 0x6e7:
|
||||
case 0x6e8:
|
||||
return code - 0x6e7 + 82;
|
||||
case 0x6eb:
|
||||
case 0x6ec:
|
||||
return code - 0x6eb + 84;
|
||||
case 0x730:
|
||||
return code - 0x730 + 86;
|
||||
case 0x732:
|
||||
case 0x733:
|
||||
return code - 0x732 + 87;
|
||||
case 0x735:
|
||||
case 0x736:
|
||||
return code - 0x735 + 89;
|
||||
case 0x73a:
|
||||
return code - 0x73a + 91;
|
||||
case 0x73d:
|
||||
return code - 0x73d + 92;
|
||||
case 0x73f:
|
||||
case 0x740:
|
||||
case 0x741:
|
||||
return code - 0x73f + 93;
|
||||
case 0x743:
|
||||
return code - 0x743 + 96;
|
||||
case 0x745:
|
||||
return code - 0x745 + 97;
|
||||
case 0x747:
|
||||
return code - 0x747 + 98;
|
||||
case 0x749:
|
||||
case 0x74a:
|
||||
return code - 0x749 + 99;
|
||||
case 0x7eb:
|
||||
case 0x7ec:
|
||||
case 0x7ed:
|
||||
case 0x7ee:
|
||||
case 0x7ef:
|
||||
case 0x7f0:
|
||||
case 0x7f1:
|
||||
return code - 0x7eb + 101;
|
||||
case 0x7f3:
|
||||
return code - 0x7f3 + 108;
|
||||
case 0x816:
|
||||
case 0x817:
|
||||
case 0x818:
|
||||
case 0x819:
|
||||
return code - 0x816 + 109;
|
||||
case 0x81b:
|
||||
case 0x81c:
|
||||
case 0x81d:
|
||||
case 0x81e:
|
||||
case 0x81f:
|
||||
case 0x820:
|
||||
case 0x821:
|
||||
case 0x822:
|
||||
case 0x823:
|
||||
return code - 0x81b + 113;
|
||||
case 0x825:
|
||||
case 0x826:
|
||||
case 0x827:
|
||||
return code - 0x825 + 122;
|
||||
case 0x829:
|
||||
case 0x82a:
|
||||
case 0x82b:
|
||||
case 0x82c:
|
||||
case 0x82d:
|
||||
return code - 0x829 + 125;
|
||||
case 0x951:
|
||||
return code - 0x951 + 130;
|
||||
case 0x953:
|
||||
case 0x954:
|
||||
return code - 0x953 + 131;
|
||||
case 0xf82:
|
||||
case 0xf83:
|
||||
return code - 0xf82 + 133;
|
||||
case 0xf86:
|
||||
case 0xf87:
|
||||
return code - 0xf86 + 135;
|
||||
case 0x135d:
|
||||
case 0x135e:
|
||||
case 0x135f:
|
||||
return code - 0x135d + 137;
|
||||
case 0x17dd:
|
||||
return code - 0x17dd + 140;
|
||||
case 0x193a:
|
||||
return code - 0x193a + 141;
|
||||
case 0x1a17:
|
||||
return code - 0x1a17 + 142;
|
||||
case 0x1a75:
|
||||
case 0x1a76:
|
||||
case 0x1a77:
|
||||
case 0x1a78:
|
||||
case 0x1a79:
|
||||
case 0x1a7a:
|
||||
case 0x1a7b:
|
||||
case 0x1a7c:
|
||||
return code - 0x1a75 + 143;
|
||||
case 0x1b6b:
|
||||
return code - 0x1b6b + 151;
|
||||
case 0x1b6d:
|
||||
case 0x1b6e:
|
||||
case 0x1b6f:
|
||||
case 0x1b70:
|
||||
case 0x1b71:
|
||||
case 0x1b72:
|
||||
case 0x1b73:
|
||||
return code - 0x1b6d + 152;
|
||||
case 0x1cd0:
|
||||
case 0x1cd1:
|
||||
case 0x1cd2:
|
||||
return code - 0x1cd0 + 159;
|
||||
case 0x1cda:
|
||||
case 0x1cdb:
|
||||
return code - 0x1cda + 162;
|
||||
case 0x1ce0:
|
||||
return code - 0x1ce0 + 164;
|
||||
case 0x1dc0:
|
||||
case 0x1dc1:
|
||||
return code - 0x1dc0 + 165;
|
||||
case 0x1dc3:
|
||||
case 0x1dc4:
|
||||
case 0x1dc5:
|
||||
case 0x1dc6:
|
||||
case 0x1dc7:
|
||||
case 0x1dc8:
|
||||
case 0x1dc9:
|
||||
return code - 0x1dc3 + 167;
|
||||
case 0x1dcb:
|
||||
case 0x1dcc:
|
||||
return code - 0x1dcb + 174;
|
||||
case 0x1dd1:
|
||||
case 0x1dd2:
|
||||
case 0x1dd3:
|
||||
case 0x1dd4:
|
||||
case 0x1dd5:
|
||||
case 0x1dd6:
|
||||
case 0x1dd7:
|
||||
case 0x1dd8:
|
||||
case 0x1dd9:
|
||||
case 0x1dda:
|
||||
case 0x1ddb:
|
||||
case 0x1ddc:
|
||||
case 0x1ddd:
|
||||
case 0x1dde:
|
||||
case 0x1ddf:
|
||||
case 0x1de0:
|
||||
case 0x1de1:
|
||||
case 0x1de2:
|
||||
case 0x1de3:
|
||||
case 0x1de4:
|
||||
case 0x1de5:
|
||||
case 0x1de6:
|
||||
return code - 0x1dd1 + 176;
|
||||
case 0x1dfe:
|
||||
return code - 0x1dfe + 198;
|
||||
case 0x20d0:
|
||||
case 0x20d1:
|
||||
return code - 0x20d0 + 199;
|
||||
case 0x20d4:
|
||||
case 0x20d5:
|
||||
case 0x20d6:
|
||||
case 0x20d7:
|
||||
return code - 0x20d4 + 201;
|
||||
case 0x20db:
|
||||
case 0x20dc:
|
||||
return code - 0x20db + 205;
|
||||
case 0x20e1:
|
||||
return code - 0x20e1 + 207;
|
||||
case 0x20e7:
|
||||
return code - 0x20e7 + 208;
|
||||
case 0x20e9:
|
||||
return code - 0x20e9 + 209;
|
||||
case 0x20f0:
|
||||
return code - 0x20f0 + 210;
|
||||
case 0x2cef:
|
||||
case 0x2cf0:
|
||||
case 0x2cf1:
|
||||
return code - 0x2cef + 211;
|
||||
case 0x2de0:
|
||||
case 0x2de1:
|
||||
case 0x2de2:
|
||||
case 0x2de3:
|
||||
case 0x2de4:
|
||||
case 0x2de5:
|
||||
case 0x2de6:
|
||||
case 0x2de7:
|
||||
case 0x2de8:
|
||||
case 0x2de9:
|
||||
case 0x2dea:
|
||||
case 0x2deb:
|
||||
case 0x2dec:
|
||||
case 0x2ded:
|
||||
case 0x2dee:
|
||||
case 0x2def:
|
||||
case 0x2df0:
|
||||
case 0x2df1:
|
||||
case 0x2df2:
|
||||
case 0x2df3:
|
||||
case 0x2df4:
|
||||
case 0x2df5:
|
||||
case 0x2df6:
|
||||
case 0x2df7:
|
||||
case 0x2df8:
|
||||
case 0x2df9:
|
||||
case 0x2dfa:
|
||||
case 0x2dfb:
|
||||
case 0x2dfc:
|
||||
case 0x2dfd:
|
||||
case 0x2dfe:
|
||||
case 0x2dff:
|
||||
return code - 0x2de0 + 214;
|
||||
case 0xa66f:
|
||||
return code - 0xa66f + 246;
|
||||
case 0xa67c:
|
||||
case 0xa67d:
|
||||
return code - 0xa67c + 247;
|
||||
case 0xa6f0:
|
||||
case 0xa6f1:
|
||||
return code - 0xa6f0 + 249;
|
||||
case 0xa8e0:
|
||||
case 0xa8e1:
|
||||
case 0xa8e2:
|
||||
case 0xa8e3:
|
||||
case 0xa8e4:
|
||||
case 0xa8e5:
|
||||
case 0xa8e6:
|
||||
case 0xa8e7:
|
||||
case 0xa8e8:
|
||||
case 0xa8e9:
|
||||
case 0xa8ea:
|
||||
case 0xa8eb:
|
||||
case 0xa8ec:
|
||||
case 0xa8ed:
|
||||
case 0xa8ee:
|
||||
case 0xa8ef:
|
||||
case 0xa8f0:
|
||||
case 0xa8f1:
|
||||
return code - 0xa8e0 + 251;
|
||||
case 0xaab0:
|
||||
return code - 0xaab0 + 269;
|
||||
case 0xaab2:
|
||||
case 0xaab3:
|
||||
return code - 0xaab2 + 270;
|
||||
case 0xaab7:
|
||||
case 0xaab8:
|
||||
return code - 0xaab7 + 272;
|
||||
case 0xaabe:
|
||||
case 0xaabf:
|
||||
return code - 0xaabe + 274;
|
||||
case 0xaac1:
|
||||
return code - 0xaac1 + 276;
|
||||
case 0xfe20:
|
||||
case 0xfe21:
|
||||
case 0xfe22:
|
||||
case 0xfe23:
|
||||
case 0xfe24:
|
||||
case 0xfe25:
|
||||
case 0xfe26:
|
||||
return code - 0xfe20 + 277;
|
||||
case 0x10a0f:
|
||||
return code - 0x10a0f + 284;
|
||||
case 0x10a38:
|
||||
return code - 0x10a38 + 285;
|
||||
case 0x1d185:
|
||||
case 0x1d186:
|
||||
case 0x1d187:
|
||||
case 0x1d188:
|
||||
case 0x1d189:
|
||||
return code - 0x1d185 + 286;
|
||||
case 0x1d1aa:
|
||||
case 0x1d1ab:
|
||||
case 0x1d1ac:
|
||||
case 0x1d1ad:
|
||||
return code - 0x1d1aa + 291;
|
||||
case 0x1d242:
|
||||
case 0x1d243:
|
||||
case 0x1d244:
|
||||
return code - 0x1d242 + 295;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
diff --git a/st/config.def.h b/st_patched/config.def.h
|
||||
index 91ab8ca..59fc2a9 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -93,6 +93,10 @@ char *termname = "st-256color";
|
||||
*/
|
||||
unsigned int tabspaces = 8;
|
||||
|
||||
+/* bg opacity */
|
||||
+float alpha = 0.8;
|
||||
+float alpha_def;
|
||||
+
|
||||
/* Terminal colors (16 first used in escape sequence) */
|
||||
static const char *colorname[] = {
|
||||
/* 8 normal colors */
|
||||
@@ -201,6 +205,9 @@ static Shortcut shortcuts[] = {
|
||||
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
|
||||
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
|
||||
+ { MODKEY, XK_bracketleft, chgalpha, {.f = -1} }, /* Decrease opacity */
|
||||
+ { MODKEY|ShiftMask, XK_braceright, chgalpha, {.f = +1} }, /* Increase opacity */
|
||||
+ { MODKEY, XK_bracketright,chgalpha, {.f = 0} }, /* Reset opacity */
|
||||
};
|
||||
|
||||
/*
|
||||
diff --git a/st/st.h b/st_patched/st.h
|
||||
index fd3b0d8..cda8c13 100644
|
||||
--- a/st.h
|
||||
+++ b/st.h
|
||||
@@ -124,3 +124,4 @@ extern unsigned int tabspaces;
|
||||
extern unsigned int defaultfg;
|
||||
extern unsigned int defaultbg;
|
||||
extern unsigned int defaultcs;
|
||||
+extern float alpha, alpha_def;
|
||||
diff --git a/st/config.mk b/st_patched/config.mk
|
||||
index 1e306f8..47c615e 100644
|
||||
--- a/config.mk
|
||||
+++ b/config.mk
|
||||
@@ -16,7 +16,7 @@ PKG_CONFIG = pkg-config
|
||||
INCS = -I$(X11INC) \
|
||||
`$(PKG_CONFIG) --cflags fontconfig` \
|
||||
`$(PKG_CONFIG) --cflags freetype2`
|
||||
-LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
|
||||
+LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\
|
||||
`$(PKG_CONFIG) --libs fontconfig` \
|
||||
`$(PKG_CONFIG) --libs freetype2`
|
||||
|
||||
diff --git a/st/x.c b/st_patched/x.c
|
||||
index aa09997..3b05a55 100644
|
||||
--- a/x.c
|
||||
+++ b/x.c
|
||||
@@ -59,6 +59,7 @@ static void zoom(const Arg *);
|
||||
static void zoomabs(const Arg *);
|
||||
static void zoomreset(const Arg *);
|
||||
static void ttysend(const Arg *);
|
||||
+static void chgalpha(const Arg *);
|
||||
|
||||
/* config.h for applying patches and the configuration. */
|
||||
#include "config.h"
|
||||
@@ -105,6 +106,7 @@ typedef struct {
|
||||
XSetWindowAttributes attrs;
|
||||
int scr;
|
||||
int isfixed; /* is fixed geometry? */
|
||||
+ int depth; /* bit depth */
|
||||
int l, t; /* left and top offset */
|
||||
int gm; /* geometry mask */
|
||||
} XWindow;
|
||||
@@ -243,6 +245,7 @@ static char *usedfont = NULL;
|
||||
static double usedfontsize = 0;
|
||||
static double defaultfontsize = 0;
|
||||
|
||||
+static char *opt_alpha = NULL;
|
||||
static char *opt_class = NULL;
|
||||
static char **opt_cmd = NULL;
|
||||
static char *opt_embed = NULL;
|
||||
@@ -752,7 +755,7 @@ xresize(int col, int row)
|
||||
|
||||
XFreePixmap(xw.dpy, xw.buf);
|
||||
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
||||
- DefaultDepth(xw.dpy, xw.scr));
|
||||
+ xw.depth);
|
||||
XftDrawChange(xw.draw, xw.buf);
|
||||
xclear(0, 0, win.w, win.h);
|
||||
|
||||
@@ -812,6 +815,13 @@ xloadcols(void)
|
||||
else
|
||||
die("could not allocate color %d\n", i);
|
||||
}
|
||||
+
|
||||
+ /* set alpha value of bg color */
|
||||
+ if (opt_alpha)
|
||||
+ alpha = strtof(opt_alpha, NULL);
|
||||
+ dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha);
|
||||
+ dc.col[defaultbg].pixel &= 0x00FFFFFF;
|
||||
+ dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24;
|
||||
loaded = 1;
|
||||
}
|
||||
|
||||
@@ -1134,11 +1144,23 @@ xinit(int cols, int rows)
|
||||
Window parent;
|
||||
pid_t thispid = getpid();
|
||||
XColor xmousefg, xmousebg;
|
||||
+ XWindowAttributes attr;
|
||||
+ XVisualInfo vis;
|
||||
|
||||
if (!(xw.dpy = XOpenDisplay(NULL)))
|
||||
die("can't open display\n");
|
||||
xw.scr = XDefaultScreen(xw.dpy);
|
||||
- xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
||||
+
|
||||
+ if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) {
|
||||
+ parent = XRootWindow(xw.dpy, xw.scr);
|
||||
+ xw.depth = 32;
|
||||
+ } else {
|
||||
+ XGetWindowAttributes(xw.dpy, parent, &attr);
|
||||
+ xw.depth = attr.depth;
|
||||
+ }
|
||||
+
|
||||
+ XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis);
|
||||
+ xw.vis = vis.visual;
|
||||
|
||||
/* font */
|
||||
if (!FcInit())
|
||||
@@ -1147,8 +1169,11 @@ xinit(int cols, int rows)
|
||||
usedfont = (opt_font == NULL)? font : opt_font;
|
||||
xloadfonts(usedfont, 0);
|
||||
|
||||
+ /* Backup default alpha value */
|
||||
+ alpha_def = alpha;
|
||||
+
|
||||
/* colors */
|
||||
- xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
|
||||
+ xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None);
|
||||
xloadcols();
|
||||
|
||||
/* adjust fixed window geometry */
|
||||
@@ -1168,19 +1193,15 @@ xinit(int cols, int rows)
|
||||
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
|
||||
xw.attrs.colormap = xw.cmap;
|
||||
|
||||
- if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
|
||||
- parent = XRootWindow(xw.dpy, xw.scr);
|
||||
xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
|
||||
- win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
|
||||
+ win.w, win.h, 0, xw.depth, InputOutput,
|
||||
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
|
||||
| CWEventMask | CWColormap, &xw.attrs);
|
||||
|
||||
memset(&gcvalues, 0, sizeof(gcvalues));
|
||||
gcvalues.graphics_exposures = False;
|
||||
- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
|
||||
- &gcvalues);
|
||||
- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
||||
- DefaultDepth(xw.dpy, xw.scr));
|
||||
+ xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth);
|
||||
+ dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues);
|
||||
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
|
||||
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
||||
|
||||
@@ -1371,6 +1392,24 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
||||
return numspecs;
|
||||
}
|
||||
|
||||
+void
|
||||
+chgalpha(const Arg *arg)
|
||||
+{
|
||||
+ if (arg->f == -1.0f && alpha >= 0.1f)
|
||||
+ alpha -= 0.1f;
|
||||
+ else if (arg->f == 1.0f && alpha < 1.0f)
|
||||
+ alpha += 0.1f;
|
||||
+ else if (arg->f == 0.0f)
|
||||
+ alpha = alpha_def;
|
||||
+ else
|
||||
+ return;
|
||||
+
|
||||
+ dc.col[defaultbg].color.alpha = (unsigned short)(0xFFFF * alpha);
|
||||
+ /* Required to remove artifacting from borderpx */
|
||||
+ cresize(0, 0);
|
||||
+ redraw();
|
||||
+}
|
||||
+
|
||||
void
|
||||
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
|
||||
{
|
||||
@@ -2038,6 +2077,9 @@ main(int argc, char *argv[])
|
||||
case 'a':
|
||||
allowaltscreen = 0;
|
||||
break;
|
||||
+ case 'A':
|
||||
+ opt_alpha = EARGF(usage());
|
||||
+ break;
|
||||
case 'c':
|
||||
opt_class = EARGF(usage());
|
||||
break;
|
||||
@@ -0,0 +1,177 @@
|
||||
.TH ST 1 st\-VERSION
|
||||
.SH NAME
|
||||
st \- simple terminal (bread's build)
|
||||
.SH SYNOPSIS
|
||||
.B st
|
||||
.RB [ \-aiv ]
|
||||
.RB [ \-c
|
||||
.IR class ]
|
||||
.RB [ \-f
|
||||
.IR font ]
|
||||
.RB [ \-g
|
||||
.IR geometry ]
|
||||
.RB [ \-n
|
||||
.IR name ]
|
||||
.RB [ \-o
|
||||
.IR iofile ]
|
||||
.RB [ \-T
|
||||
.IR title ]
|
||||
.RB [ \-t
|
||||
.IR title ]
|
||||
.RB [ \-l
|
||||
.IR line ]
|
||||
.RB [ \-w
|
||||
.IR windowid ]
|
||||
.RB [[ \-e ]
|
||||
.IR command
|
||||
.RI [ arguments ...]]
|
||||
.PP
|
||||
.B st
|
||||
.RB [ \-aiv ]
|
||||
.RB [ \-c
|
||||
.IR class ]
|
||||
.RB [ \-f
|
||||
.IR font ]
|
||||
.RB [ \-g
|
||||
.IR geometry ]
|
||||
.RB [ \-n
|
||||
.IR name ]
|
||||
.RB [ \-o
|
||||
.IR iofile ]
|
||||
.RB [ \-T
|
||||
.IR title ]
|
||||
.RB [ \-t
|
||||
.IR title ]
|
||||
.RB [ \-w
|
||||
.IR windowid ]
|
||||
.RB \-l
|
||||
.IR line
|
||||
.RI [ stty_args ...]
|
||||
.SH DESCRIPTION
|
||||
.B st
|
||||
is a simple terminal emulator.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-a
|
||||
disable alternate screens in terminal
|
||||
.TP
|
||||
.BI \-c " class"
|
||||
defines the window class (default $TERM).
|
||||
.TP
|
||||
.BI \-f " font"
|
||||
defines the
|
||||
.I font
|
||||
to use when st is run.
|
||||
.TP
|
||||
.BI \-g " geometry"
|
||||
defines the X11 geometry string.
|
||||
The form is [=][<cols>{xX}<rows>][{+-}<xoffset>{+-}<yoffset>]. See
|
||||
.BR XParseGeometry (3)
|
||||
for further details.
|
||||
.TP
|
||||
.B \-i
|
||||
will fixate the position given with the -g option.
|
||||
.TP
|
||||
.BI \-n " name"
|
||||
defines the window instance name (default $TERM).
|
||||
.TP
|
||||
.BI \-o " iofile"
|
||||
writes all the I/O to
|
||||
.I iofile.
|
||||
This feature is useful when recording st sessions. A value of "-" means
|
||||
standard output.
|
||||
.TP
|
||||
.BI \-T " title"
|
||||
defines the window title (default 'st').
|
||||
.TP
|
||||
.BI \-t " title"
|
||||
defines the window title (default 'st').
|
||||
.TP
|
||||
.BI \-w " windowid"
|
||||
embeds st within the window identified by
|
||||
.I windowid
|
||||
.TP
|
||||
.BI \-l " line"
|
||||
use a tty
|
||||
.I line
|
||||
instead of a pseudo terminal.
|
||||
.I line
|
||||
should be a (pseudo-)serial device (e.g. /dev/ttyS0 on Linux for serial port
|
||||
0).
|
||||
When this flag is given
|
||||
remaining arguments are used as flags for
|
||||
.BR stty(1).
|
||||
By default st initializes the serial line to 8 bits, no parity, 1 stop bit
|
||||
and a 38400 baud rate. The speed is set by appending it as last argument
|
||||
(e.g. 'st -l /dev/ttyS0 115200'). Arguments before the last one are
|
||||
.BR stty(1)
|
||||
flags. If you want to set odd parity on 115200 baud use for example 'st -l
|
||||
/dev/ttyS0 parenb parodd 115200'. Set the number of bits by using for
|
||||
example 'st -l /dev/ttyS0 cs7 115200'. See
|
||||
.BR stty(1)
|
||||
for more arguments and cases.
|
||||
.TP
|
||||
.B \-v
|
||||
prints version information to stderr, then exits.
|
||||
.TP
|
||||
.BI \-e " command " [ " arguments " "... ]"
|
||||
st executes
|
||||
.I command
|
||||
instead of the shell. If this is used it
|
||||
.B must be the last option
|
||||
on the command line, as in xterm / rxvt.
|
||||
This option is only intended for compatibility,
|
||||
and all the remaining arguments are used as a command
|
||||
even without it.
|
||||
.SH SHORTCUTS
|
||||
.TP
|
||||
.B Break
|
||||
Send a break in the serial line.
|
||||
Break key is obtained in PC keyboards
|
||||
pressing at the same time control and pause.
|
||||
.TP
|
||||
.B Ctrl-Print Screen
|
||||
Toggle if st should print to the
|
||||
.I iofile.
|
||||
.TP
|
||||
.B Shift-Print Screen
|
||||
Print the full screen to the
|
||||
.I iofile.
|
||||
.TP
|
||||
.B Print Screen
|
||||
Print the selection to the
|
||||
.I iofile.
|
||||
.TP
|
||||
.B Ctrl-Shift-Page Up
|
||||
Increase font size.
|
||||
.TP
|
||||
.B Ctrl-Shift-Page Down
|
||||
Decrease font size.
|
||||
.TP
|
||||
.B Ctrl-Shift-Home
|
||||
Reset to default font size.
|
||||
.TP
|
||||
.B Ctrl-Shift-y
|
||||
Paste from primary selection (middle mouse button).
|
||||
.TP
|
||||
.B Ctrl-Shift-c
|
||||
Copy the selected text to the clipboard selection.
|
||||
.TP
|
||||
.B Ctrl-Shift-v
|
||||
Paste from the clipboard selection.
|
||||
.SH CUSTOMIZATION
|
||||
.B st
|
||||
can be customized by creating a custom config.h and (re)compiling the source
|
||||
code. This keeps it fast, secure and simple.
|
||||
.SH AUTHORS
|
||||
See the LICENSE file for the authors.
|
||||
.SH LICENSE
|
||||
See the LICENSE file for the terms of redistribution.
|
||||
.SH SEE ALSO
|
||||
.BR tabbed (1),
|
||||
.BR utmp (1),
|
||||
.BR stty (1),
|
||||
.BR scroll (1)
|
||||
.SH BUGS
|
||||
See the TODO file in the distribution.
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,130 @@
|
||||
/* See LICENSE for license details. */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* macros */
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a, b) ((a) < (b) ? (b) : (a))
|
||||
#define LEN(a) (sizeof(a) / sizeof(a)[0])
|
||||
#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
|
||||
#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
|
||||
#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
|
||||
#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
|
||||
#define ATTRCMP(a, b) (((a).mode & (~ATTR_WRAP)) != ((b).mode & (~ATTR_WRAP)) || \
|
||||
(a).fg != (b).fg || \
|
||||
(a).bg != (b).bg)
|
||||
#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \
|
||||
(t1.tv_nsec-t2.tv_nsec)/1E6)
|
||||
#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit)))
|
||||
|
||||
#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b))
|
||||
#define IS_TRUECOL(x) (1 << 24 & (x))
|
||||
#define HISTSIZE 2000
|
||||
|
||||
enum glyph_attribute {
|
||||
ATTR_NULL = 0,
|
||||
ATTR_BOLD = 1 << 0,
|
||||
ATTR_FAINT = 1 << 1,
|
||||
ATTR_ITALIC = 1 << 2,
|
||||
ATTR_UNDERLINE = 1 << 3,
|
||||
ATTR_BLINK = 1 << 4,
|
||||
ATTR_REVERSE = 1 << 5,
|
||||
ATTR_INVISIBLE = 1 << 6,
|
||||
ATTR_STRUCK = 1 << 7,
|
||||
ATTR_WRAP = 1 << 8,
|
||||
ATTR_WIDE = 1 << 9,
|
||||
ATTR_WDUMMY = 1 << 10,
|
||||
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
|
||||
};
|
||||
|
||||
enum selection_mode {
|
||||
SEL_IDLE = 0,
|
||||
SEL_EMPTY = 1,
|
||||
SEL_READY = 2
|
||||
};
|
||||
|
||||
enum selection_type {
|
||||
SEL_REGULAR = 1,
|
||||
SEL_RECTANGULAR = 2
|
||||
};
|
||||
|
||||
enum selection_snap {
|
||||
SNAP_WORD = 1,
|
||||
SNAP_LINE = 2
|
||||
};
|
||||
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned short ushort;
|
||||
|
||||
typedef uint_least32_t Rune;
|
||||
|
||||
#define Glyph Glyph_
|
||||
typedef struct {
|
||||
Rune u; /* character code */
|
||||
ushort mode; /* attribute flags */
|
||||
uint32_t fg; /* foreground */
|
||||
uint32_t bg; /* background */
|
||||
} Glyph;
|
||||
|
||||
typedef Glyph *Line;
|
||||
|
||||
typedef union {
|
||||
int i;
|
||||
uint ui;
|
||||
float f;
|
||||
const void *v;
|
||||
const char *s;
|
||||
} Arg;
|
||||
|
||||
void die(const char *, ...);
|
||||
void redraw(void);
|
||||
void draw(void);
|
||||
|
||||
void printscreen(const Arg *);
|
||||
void printsel(const Arg *);
|
||||
void sendbreak(const Arg *);
|
||||
void toggleprinter(const Arg *);
|
||||
|
||||
int tattrset(int);
|
||||
void tnew(int, int);
|
||||
void tresize(int, int);
|
||||
void tsetdirtattr(int);
|
||||
void ttyhangup(void);
|
||||
int ttynew(const char *, char *, const char *, char **);
|
||||
size_t ttyread(void);
|
||||
void ttyresize(int, int);
|
||||
void ttywrite(const char *, size_t, int);
|
||||
|
||||
void resettitle(void);
|
||||
|
||||
void selclear(void);
|
||||
void selinit(void);
|
||||
void selstart(int, int, int);
|
||||
void selextend(int, int, int, int);
|
||||
int selected(int, int);
|
||||
char *getsel(void);
|
||||
|
||||
size_t utf8encode(Rune, char *);
|
||||
|
||||
void *xmalloc(size_t);
|
||||
void *xrealloc(void *, size_t);
|
||||
char *xstrdup(const char *);
|
||||
|
||||
/* config.h globals */
|
||||
extern char *utmp;
|
||||
extern char *scroll;
|
||||
extern char *stty_args;
|
||||
extern char *vtiden;
|
||||
extern wchar_t *worddelimiters;
|
||||
extern int allowaltscreen;
|
||||
extern int allowwindowops;
|
||||
extern char *termname;
|
||||
extern unsigned int tabspaces;
|
||||
extern unsigned int defaultfg;
|
||||
extern unsigned int defaultbg;
|
||||
extern unsigned int defaultcs;
|
||||
extern float alpha;
|
||||
extern float alpha_def;
|
||||
Executable
+243
@@ -0,0 +1,243 @@
|
||||
st-mono| simpleterm monocolor,
|
||||
acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
|
||||
am,
|
||||
bce,
|
||||
bel=^G,
|
||||
blink=\E[5m,
|
||||
bold=\E[1m,
|
||||
cbt=\E[Z,
|
||||
cvvis=\E[?25h,
|
||||
civis=\E[?25l,
|
||||
clear=\E[H\E[2J,
|
||||
cnorm=\E[?12l\E[?25h,
|
||||
colors#2,
|
||||
cols#80,
|
||||
cr=^M,
|
||||
csr=\E[%i%p1%d;%p2%dr,
|
||||
cub=\E[%p1%dD,
|
||||
cub1=^H,
|
||||
cud1=^J,
|
||||
cud=\E[%p1%dB,
|
||||
cuf1=\E[C,
|
||||
cuf=\E[%p1%dC,
|
||||
cup=\E[%i%p1%d;%p2%dH,
|
||||
cuu1=\E[A,
|
||||
cuu=\E[%p1%dA,
|
||||
dch=\E[%p1%dP,
|
||||
dch1=\E[P,
|
||||
dim=\E[2m,
|
||||
dl=\E[%p1%dM,
|
||||
dl1=\E[M,
|
||||
ech=\E[%p1%dX,
|
||||
ed=\E[J,
|
||||
el=\E[K,
|
||||
el1=\E[1K,
|
||||
enacs=\E)0,
|
||||
flash=\E[?5h$<80/>\E[?5l,
|
||||
fsl=^G,
|
||||
home=\E[H,
|
||||
hpa=\E[%i%p1%dG,
|
||||
hs,
|
||||
ht=^I,
|
||||
hts=\EH,
|
||||
ich=\E[%p1%d@,
|
||||
il1=\E[L,
|
||||
il=\E[%p1%dL,
|
||||
ind=^J,
|
||||
indn=\E[%p1%dS,
|
||||
invis=\E[8m,
|
||||
is2=\E[4l\E>\E[?1034l,
|
||||
it#8,
|
||||
kel=\E[1;2F,
|
||||
ked=\E[1;5F,
|
||||
ka1=\E[1~,
|
||||
ka3=\E[5~,
|
||||
kc1=\E[4~,
|
||||
kc3=\E[6~,
|
||||
kbs=\177,
|
||||
kcbt=\E[Z,
|
||||
kb2=\EOu,
|
||||
kcub1=\EOD,
|
||||
kcud1=\EOB,
|
||||
kcuf1=\EOC,
|
||||
kcuu1=\EOA,
|
||||
kDC=\E[3;2~,
|
||||
kent=\EOM,
|
||||
kEND=\E[1;2F,
|
||||
kIC=\E[2;2~,
|
||||
kNXT=\E[6;2~,
|
||||
kPRV=\E[5;2~,
|
||||
kHOM=\E[1;2H,
|
||||
kLFT=\E[1;2D,
|
||||
kRIT=\E[1;2C,
|
||||
kind=\E[1;2B,
|
||||
kri=\E[1;2A,
|
||||
kclr=\E[3;5~,
|
||||
kdl1=\E[3;2~,
|
||||
kdch1=\E[3~,
|
||||
kich1=\E[2~,
|
||||
kend=\E[4~,
|
||||
kf1=\EOP,
|
||||
kf2=\EOQ,
|
||||
kf3=\EOR,
|
||||
kf4=\EOS,
|
||||
kf5=\E[15~,
|
||||
kf6=\E[17~,
|
||||
kf7=\E[18~,
|
||||
kf8=\E[19~,
|
||||
kf9=\E[20~,
|
||||
kf10=\E[21~,
|
||||
kf11=\E[23~,
|
||||
kf12=\E[24~,
|
||||
kf13=\E[1;2P,
|
||||
kf14=\E[1;2Q,
|
||||
kf15=\E[1;2R,
|
||||
kf16=\E[1;2S,
|
||||
kf17=\E[15;2~,
|
||||
kf18=\E[17;2~,
|
||||
kf19=\E[18;2~,
|
||||
kf20=\E[19;2~,
|
||||
kf21=\E[20;2~,
|
||||
kf22=\E[21;2~,
|
||||
kf23=\E[23;2~,
|
||||
kf24=\E[24;2~,
|
||||
kf25=\E[1;5P,
|
||||
kf26=\E[1;5Q,
|
||||
kf27=\E[1;5R,
|
||||
kf28=\E[1;5S,
|
||||
kf29=\E[15;5~,
|
||||
kf30=\E[17;5~,
|
||||
kf31=\E[18;5~,
|
||||
kf32=\E[19;5~,
|
||||
kf33=\E[20;5~,
|
||||
kf34=\E[21;5~,
|
||||
kf35=\E[23;5~,
|
||||
kf36=\E[24;5~,
|
||||
kf37=\E[1;6P,
|
||||
kf38=\E[1;6Q,
|
||||
kf39=\E[1;6R,
|
||||
kf40=\E[1;6S,
|
||||
kf41=\E[15;6~,
|
||||
kf42=\E[17;6~,
|
||||
kf43=\E[18;6~,
|
||||
kf44=\E[19;6~,
|
||||
kf45=\E[20;6~,
|
||||
kf46=\E[21;6~,
|
||||
kf47=\E[23;6~,
|
||||
kf48=\E[24;6~,
|
||||
kf49=\E[1;3P,
|
||||
kf50=\E[1;3Q,
|
||||
kf51=\E[1;3R,
|
||||
kf52=\E[1;3S,
|
||||
kf53=\E[15;3~,
|
||||
kf54=\E[17;3~,
|
||||
kf55=\E[18;3~,
|
||||
kf56=\E[19;3~,
|
||||
kf57=\E[20;3~,
|
||||
kf58=\E[21;3~,
|
||||
kf59=\E[23;3~,
|
||||
kf60=\E[24;3~,
|
||||
kf61=\E[1;4P,
|
||||
kf62=\E[1;4Q,
|
||||
kf63=\E[1;4R,
|
||||
khome=\E[1~,
|
||||
kil1=\E[2;5~,
|
||||
krmir=\E[2;2~,
|
||||
knp=\E[6~,
|
||||
kmous=\E[M,
|
||||
kpp=\E[5~,
|
||||
lines#24,
|
||||
mir,
|
||||
msgr,
|
||||
npc,
|
||||
op=\E[39;49m,
|
||||
pairs#64,
|
||||
mc0=\E[i,
|
||||
mc4=\E[4i,
|
||||
mc5=\E[5i,
|
||||
rc=\E8,
|
||||
rev=\E[7m,
|
||||
ri=\EM,
|
||||
rin=\E[%p1%dT,
|
||||
ritm=\E[23m,
|
||||
rmacs=\E(B,
|
||||
rmcup=\E[?1049l,
|
||||
rmir=\E[4l,
|
||||
rmkx=\E[?1l\E>,
|
||||
rmso=\E[27m,
|
||||
rmul=\E[24m,
|
||||
rs1=\Ec,
|
||||
rs2=\E[4l\E>\E[?1034l,
|
||||
sc=\E7,
|
||||
sitm=\E[3m,
|
||||
sgr0=\E[0m,
|
||||
smacs=\E(0,
|
||||
smcup=\E[?1049h,
|
||||
smir=\E[4h,
|
||||
smkx=\E[?1h\E=,
|
||||
smso=\E[7m,
|
||||
smul=\E[4m,
|
||||
tbc=\E[3g,
|
||||
tsl=\E]0;,
|
||||
xenl,
|
||||
vpa=\E[%i%p1%dd,
|
||||
# XTerm extensions
|
||||
rmxx=\E[29m,
|
||||
smxx=\E[9m,
|
||||
BE=\E[?2004h,
|
||||
BD=\E[?2004l,
|
||||
PS=\E[200~,
|
||||
PE=\E[201~,
|
||||
# disabled rep for now: causes some issues with older ncurses versions.
|
||||
# rep=%p1%c\E[%p2%{1}%-%db,
|
||||
# tmux extensions, see TERMINFO EXTENSIONS in tmux(1)
|
||||
Tc,
|
||||
Ms=\E]52;%p1%s;%p2%s\007,
|
||||
Se=\E[2 q,
|
||||
Ss=\E[%p1%d q,
|
||||
|
||||
st| simpleterm,
|
||||
use=st-mono,
|
||||
colors#8,
|
||||
setab=\E[4%p1%dm,
|
||||
setaf=\E[3%p1%dm,
|
||||
setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
|
||||
setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
|
||||
sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
|
||||
|
||||
st-256color| simpleterm with 256 colors,
|
||||
use=st,
|
||||
ccc,
|
||||
colors#256,
|
||||
oc=\E]104\007,
|
||||
pairs#32767,
|
||||
# Nicked from xterm-256color
|
||||
initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\,
|
||||
setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
|
||||
setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
|
||||
|
||||
st-meta| simpleterm with meta key,
|
||||
use=st,
|
||||
km,
|
||||
rmm=\E[?1034l,
|
||||
smm=\E[?1034h,
|
||||
rs2=\E[4l\E>\E[?1034h,
|
||||
is2=\E[4l\E>\E[?1034h,
|
||||
|
||||
st-meta-256color| simpleterm with meta key and 256 colors,
|
||||
use=st-256color,
|
||||
km,
|
||||
rmm=\E[?1034l,
|
||||
smm=\E[?1034h,
|
||||
rs2=\E[4l\E>\E[?1034h,
|
||||
is2=\E[4l\E>\E[?1034h,
|
||||
|
||||
st-bs| simpleterm with backspace as backspace,
|
||||
use=st,
|
||||
kbs=\010,
|
||||
kdch1=\177,
|
||||
|
||||
st-bs-256color| simpleterm with backspace as backspace and 256colors,
|
||||
use=st-256color,
|
||||
kbs=\010,
|
||||
kdch1=\177,
|
||||
@@ -0,0 +1,41 @@
|
||||
/* See LICENSE for license details. */
|
||||
|
||||
enum win_mode {
|
||||
MODE_VISIBLE = 1 << 0,
|
||||
MODE_FOCUSED = 1 << 1,
|
||||
MODE_APPKEYPAD = 1 << 2,
|
||||
MODE_MOUSEBTN = 1 << 3,
|
||||
MODE_MOUSEMOTION = 1 << 4,
|
||||
MODE_REVERSE = 1 << 5,
|
||||
MODE_KBDLOCK = 1 << 6,
|
||||
MODE_HIDE = 1 << 7,
|
||||
MODE_APPCURSOR = 1 << 8,
|
||||
MODE_MOUSESGR = 1 << 9,
|
||||
MODE_8BIT = 1 << 10,
|
||||
MODE_BLINK = 1 << 11,
|
||||
MODE_FBLINK = 1 << 12,
|
||||
MODE_FOCUS = 1 << 13,
|
||||
MODE_MOUSEX10 = 1 << 14,
|
||||
MODE_MOUSEMANY = 1 << 15,
|
||||
MODE_BRCKTPASTE = 1 << 16,
|
||||
MODE_NUMLOCK = 1 << 17,
|
||||
MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
|
||||
|MODE_MOUSEMANY,
|
||||
};
|
||||
|
||||
void xbell(void);
|
||||
void xclipcopy(void);
|
||||
void xdrawcursor(int, int, Glyph, int, int, Glyph, Line, int);
|
||||
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);
|
||||
void xsetmode(int, unsigned int);
|
||||
void xsetpointermotion(int);
|
||||
void xsetsel(char *);
|
||||
int xstartdraw(void);
|
||||
void xximspot(int, int);
|
||||
Reference in New Issue
Block a user