From 3cd91894ec91a0de7aa71d62949ba3381e600afd Mon Sep 17 00:00:00 2001 From: yusufaktepe Date: Wed, 8 May 2019 04:05:57 +0300 Subject: [PATCH] Updated st to 0.8.2 Updated to latest git (20190414.f1546cf) & updated patches. Changes: . Upstream fixes. . Alpha: Opacity value is now typed in float (0-1). Also "-A" cmd option added as alternative opacity changing method. . Clipboard: middle click pastes from clipboard. . Organized shortcuts. --- .Xdefaults | 7 +- Makefile | 2 +- PKGBUILD | 10 +-- README.md | 6 +- config.h | 53 +++++++------- config.mk | 25 ++++--- st.1 | 2 +- st.c | 81 ++++++++++------------ st.h | 14 ++-- win.h | 5 +- x.c | 199 +++++++++++++++++++++++++---------------------------- 11 files changed, 198 insertions(+), 206 deletions(-) diff --git a/.Xdefaults b/.Xdefaults index b1aee67..b4322ee 100644 --- a/.Xdefaults +++ b/.Xdefaults @@ -1,9 +1,12 @@ -!! Transparency (0-255): -st.alpha: 240 +!! Transparency (0-1): +st.alpha: 0.92 !! Set a default font and font size as below: st.font: Monospace-11; +! st.termname: st-256color +! st.borderpx: 2 + /* !! gruvbox: */ /* *.color0: #1d2021 */ /* *.color1: #cc241d */ diff --git a/Makefile b/Makefile index 0b3cecd..470ac86 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ config.h: $(CC) $(STCFLAGS) -c $< st.o: config.h st.h win.h -x.o: arg.h st.h win.h +x.o: arg.h config.h st.h win.h $(OBJ): config.h config.mk diff --git a/PKGBUILD b/PKGBUILD index 959a2e9..ebafe00 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -2,9 +2,10 @@ pkgname=st-luke-git _pkgname=st -_pkgver=0.8.1 -pkgver=0.8.1.r1046.1cd0b79 +_pkgver=0.8.2 +pkgver=0.8.2.r1059.51ac1b9 pkgrel=1 +epoch=1 pkgdesc="Luke's simple (suckless) terminal with vim-bindings, transparency, xresources, etc. " url='https://github.com/LukeSmithxyz/st' arch=('i686' 'x86_64') @@ -21,12 +22,12 @@ conflicts=("${_pkgname}") pkgver() { cd "${_pkgname}" - printf "${_pkgver}.r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" + printf "%s.r%s.%s" "${_pkgver}" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" } prepare() { cd $srcdir/${_pkgname} - # skip terminfo which conflicts with nsurses + # skip terminfo which conflicts with ncurses sed -i '/tic /d' Makefile } @@ -40,4 +41,5 @@ package() { make PREFIX=/usr DESTDIR="${pkgdir}" install install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" install -Dm644 README.md "${pkgdir}/usr/share/doc/${pkgname}/README.md" + install -Dm644 .Xdefaults "${pkgdir}/usr/share/doc/${pkgname}/Xdefaults.example" } diff --git a/README.md b/README.md index 0c9b374..b1ddc09 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ The [suckless terminal (st)](https://st.suckless.org/) with some additional feat + Alt-PageUp and Alt-PageDown will do the same. + Vertcenter + Scrollback -+ updated to latest version 0.8.1 ++ updated to latest version 0.8.2 The following additional bindings were added before I forked this: @@ -51,12 +51,12 @@ For example, you can define your desired fonts, transparency or colors: ``` *.font: Liberation Mono:pixelsize=12:antialias=true:autohint=true; -*.alpha: 150 +*.alpha: 0.9 *.color0: #111 ... ``` -The `alpha` value (for transparency) goes from `0` (transparent) to `255` +The `alpha` value (for transparency) goes from `0` (transparent) to `1` (opaque). ### Colors diff --git a/config.h b/config.h index 12f0316..be9a952 100644 --- a/config.h +++ b/config.h @@ -30,9 +30,9 @@ static float chscale = 1.0; /* * word delimiter string * - * More advanced example: " `'\"()[]{}" + * More advanced example: L" `'\"()[]{}" */ -char *worddelimiters = " "; +wchar_t *worddelimiters = L" "; /* selection timeouts (in milliseconds) */ static unsigned int doubleclicktimeout = 300; @@ -83,8 +83,9 @@ char *termname = "st-256color"; unsigned int tabspaces = 8; /* bg opacity */ -unsigned int alpha = 0xed; +float alpha = 0.92; +/* Terminal colors (16 first used in escape sequence) */ static const char *colorname[] = { "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */ "#cc241d", @@ -170,6 +171,7 @@ ResourcePref resources[] = { { "color15", STRING, &colorname[15] }, { "background", STRING, &colorname[256] }, { "foreground", STRING, &colorname[257] }, + { "cursorColor", STRING, &colorname[258] }, { "termname", STRING, &termname }, { "shell", STRING, &shell }, { "xfps", INTEGER, &xfps }, @@ -177,10 +179,10 @@ ResourcePref resources[] = { { "blinktimeout", INTEGER, &blinktimeout }, { "bellvolume", INTEGER, &bellvolume }, { "tabspaces", INTEGER, &tabspaces }, + { "borderpx", INTEGER, &borderpx }, { "cwscale", FLOAT, &cwscale }, { "chscale", FLOAT, &chscale }, - { "alpha", INTEGER, &alpha }, - { "border", INTEGER, &borderpx }, + { "alpha", FLOAT, &alpha }, }; /* @@ -195,6 +197,7 @@ static MouseShortcut mshortcuts[] = { /* Internal keyboard shortcuts. */ #define MODKEY Mod1Mask +#define TERMMOD (Mod1Mask|ShiftMask) MouseKey mkeys[] = { /* button mask function argument */ @@ -202,8 +205,8 @@ MouseKey mkeys[] = { { Button5, ShiftMask, kscrolldown, {.i = 1} }, { Button4, MODKEY, kscrollup, {.i = 1} }, { Button5, MODKEY, kscrolldown, {.i = 1} }, - { Button4, MODKEY|ShiftMask, zoom, {.f = +1} }, - { Button5, MODKEY|ShiftMask, zoom, {.f = -1} }, + { Button4, TERMMOD, zoom, {.f = +1} }, + { Button5, TERMMOD, zoom, {.f = -1} }, }; static char *openurlcmd[] = { "/bin/sh", "-c", @@ -220,33 +223,33 @@ static Shortcut shortcuts[] = { { ControlMask, XK_Print, toggleprinter, {.i = 0} }, { ShiftMask, XK_Print, printscreen, {.i = 0} }, { XK_ANY_MOD, XK_Print, printsel, {.i = 0} }, - { MODKEY|ShiftMask, XK_Prior, zoom, {.f = +1} }, - { MODKEY|ShiftMask, XK_Next, zoom, {.f = -1} }, - { MODKEY, XK_Home, zoomreset, {.f = 0} }, + { TERMMOD, XK_Prior, zoom, {.f = +1} }, + { TERMMOD, XK_Next, zoom, {.f = -1} }, + { MODKEY, XK_Home, zoomreset, {.f = 0} }, { ShiftMask, XK_Insert, clippaste, {.i = 0} }, { MODKEY, XK_c, clipcopy, {.i = 0} }, { MODKEY, XK_v, clippaste, {.i = 0} }, { MODKEY, XK_p, selpaste, {.i = 0} }, - { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, + { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, { MODKEY, XK_Control_L, iso14755, {.i = 0} }, { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, { MODKEY, XK_Page_Up, kscrollup, {.i = -1} }, { MODKEY, XK_Page_Down, kscrolldown, {.i = -1} }, - { MODKEY, XK_k, kscrollup, {.i = 1} }, - { MODKEY, XK_j, kscrolldown, {.i = 1} }, - { MODKEY, XK_Up, kscrollup, {.i = 1} }, - { MODKEY, XK_Down, kscrolldown, {.i = 1} }, - { MODKEY, XK_u, kscrollup, {.i = -1} }, - { MODKEY, XK_d, kscrolldown, {.i = -1} }, - { MODKEY|ShiftMask, XK_Up, zoom, {.f = +1} }, - { MODKEY|ShiftMask, XK_Down, zoom, {.f = -1} }, - { MODKEY|ShiftMask, XK_K, zoom, {.f = +1} }, - { MODKEY|ShiftMask, XK_J, zoom, {.f = -1} }, - { MODKEY|ShiftMask, XK_U, zoom, {.f = +2} }, - { MODKEY|ShiftMask, XK_D, zoom, {.f = -2} }, - { MODKEY, XK_l, externalpipe, { .v = openurlcmd } }, - { MODKEY, XK_y, externalpipe, { .v = copyurlcmd } }, + { MODKEY, XK_k, kscrollup, {.i = 1} }, + { MODKEY, XK_j, kscrolldown, {.i = 1} }, + { MODKEY, XK_Up, kscrollup, {.i = 1} }, + { MODKEY, XK_Down, kscrolldown, {.i = 1} }, + { MODKEY, XK_u, kscrollup, {.i = -1} }, + { MODKEY, XK_d, kscrolldown, {.i = -1} }, + { TERMMOD, XK_Up, zoom, {.f = +1} }, + { TERMMOD, XK_Down, zoom, {.f = -1} }, + { TERMMOD, XK_K, zoom, {.f = +1} }, + { TERMMOD, XK_J, zoom, {.f = -1} }, + { TERMMOD, XK_U, zoom, {.f = +2} }, + { TERMMOD, XK_D, zoom, {.f = -2} }, + { MODKEY, XK_l, externalpipe, {.v = openurlcmd } }, + { MODKEY, XK_y, externalpipe, {.v = copyurlcmd } }, }; /* diff --git a/config.mk b/config.mk index d801515..eba98c3 100644 --- a/config.mk +++ b/config.mk @@ -1,5 +1,5 @@ # st version -VERSION = 0.8.1 +VERSION = 0.8.2 # Customize below to fit your system @@ -10,19 +10,26 @@ 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` -LIBS = -L${X11LIB} -lm -lrt -lX11 -lutil -lXft -lXrender \ - `pkg-config --libs fontconfig` \ - `pkg-config --libs freetype2` + `$(PKG_CONFIG) --cflags fontconfig` \ + `$(PKG_CONFIG) --cflags freetype2` +LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender \ + `$(PKG_CONFIG) --libs fontconfig` \ + `$(PKG_CONFIG) --libs freetype2` # flags -CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -STCFLAGS = $(INCS) $(CPPFLAGS) $(CFLAGS) +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` + # compiler and linker # CC = c99 - diff --git a/st.1 b/st.1 index 6d1a128..97cafc7 100644 --- a/st.1 +++ b/st.1 @@ -169,7 +169,7 @@ Print the full screen to the Print the selection to the .I iofile. .TP -.B Ctrl-Shift-i +.B Alt-Ctrl Launch dmenu to enter a unicode codepoint and send the corresponding glyph to st. .SH CUSTOMIZATION diff --git a/st.c b/st.c index 9fd04bd..bcb3444 100644 --- a/st.c +++ b/st.c @@ -35,6 +35,7 @@ #define ESC_ARG_SIZ 16 #define STR_BUF_SIZ ESC_BUF_SIZ #define STR_ARG_SIZ ESC_ARG_SIZ +#define HISTSIZE 2000 /* macros */ #define IS_SET(flag) ((term.mode & (flag)) != 0) @@ -42,7 +43,10 @@ #define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177') #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) -#define ISDELIM(u) (utf8strchr(worddelimiters, u) != NULL) +#define ISDELIM(u) (u && wcschr(worddelimiters, u)) +#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - \ + term.scr + HISTSIZE + 1) % HISTSIZE] : \ + term.line[(y) - term.scr]) /* constants */ #define ISO14755CMD "dmenu -w \"$WINDOWID\" -p codepoint: 0) memmove(buf, buf + written, buflen); - if (term.scr > 0 && term.scr < HISTSIZE-1) - term.scr++; - return ret; } @@ -1096,7 +1088,6 @@ kscrollup(const Arg* a) } } - void tscrolldown(int orig, int n, int copyhist) { @@ -1139,6 +1130,9 @@ tscrollup(int orig, int n, int copyhist) term.line[orig] = temp; } + if (term.scr > 0 && term.scr < HISTSIZE) + term.scr = MIN(term.scr + n, HISTSIZE-1); + tclearregion(0, orig, term.col-1, orig+n-1); tsetdirt(orig+n, term.bot); @@ -1627,6 +1621,7 @@ tsetmode(int priv, int set, int *args, int narg) case 1015: /* urxvt mangled mouse mode; incompatible and can be mistaken for other control codes. */ + break; default: fprintf(stderr, "erresc: unknown private set/reset mode %d\n", @@ -1898,7 +1893,7 @@ csireset(void) void strhandle(void) { - char *p = NULL; + char *p = NULL, *dec; int j, narg, par; term.esc &= ~(ESC_STR_END|ESC_STR); @@ -1916,8 +1911,6 @@ strhandle(void) return; case 52: if (narg > 2) { - char *dec; - dec = base64dec(strescseq.args[2]); if (dec) { xsetsel(dec); @@ -1935,7 +1928,10 @@ strhandle(void) case 104: /* color reset, here p = NULL */ j = (narg > 1) ? atoi(strescseq.args[1]) : -1; if (xsetcolorname(j, p)) { - fprintf(stderr, "erresc: invalid color %s\n", p); + if (par == 104 && narg <= 1) + return; /* color reset without parameter */ + fprintf(stderr, "erresc: invalid color j=%d, p=%s\n", + j, p ? p : "(null)"); } else { /* * TODO if defaultbg color is changed, borders @@ -2462,7 +2458,6 @@ tputc(Rune u) goto check_control_code; } - if (IS_SET(MODE_SIXEL)) { /* TODO: implement sixel mode */ return; @@ -2647,7 +2642,7 @@ tresize(int col, int row) } } - /* resize each r w to new width, zero-pad if needed */ + /* resize each row to new width, zero-pad if needed */ for (i = 0; i < minrow; i++) { term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph)); term.alt[i] = xrealloc(term.alt[i], col * sizeof(Glyph)); @@ -2725,12 +2720,12 @@ draw(void) cx--; drawregion(0, 0, term.col, term.row); - if (term.scr == 0) { + if (term.scr == 0) xdrawcursor(cx, term.c.y, term.line[term.c.y][cx], term.ocx, term.ocy, term.line[term.ocy][term.ocx]); - } term.ocx = cx, term.ocy = term.c.y; xfinishdraw(); + xximspot(term.ocx, term.ocy); } void diff --git a/st.h b/st.h index 01cad23..94ce5c3 100644 --- a/st.h +++ b/st.h @@ -3,9 +3,6 @@ #include #include -/* Arbitrary size */ -#define HISTSIZE 2000 - /* macros */ #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) < (b) ? (b) : (a)) @@ -22,8 +19,6 @@ #define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) #define IS_TRUECOL(x) (1 << 24 & (x)) -#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - term.scr \ - + HISTSIZE + 1) % HISTSIZE] : term.line[(y) - term.scr]) enum glyph_attribute { ATTR_NULL = 0, @@ -94,6 +89,8 @@ void draw(void); void externalpipe(const Arg *); void iso14755(const Arg *); +void kscrolldown(const Arg *); +void kscrollup(const Arg *); void printscreen(const Arg *); void printsel(const Arg *); void sendbreak(const Arg *); @@ -124,18 +121,15 @@ void *xmalloc(size_t); void *xrealloc(void *, size_t); char *xstrdup(char *); -void kscrolldown(const Arg *); -void kscrollup(const Arg *); - /* config.h globals */ extern char *utmp; extern char *stty_args; extern char *vtiden; -extern char *worddelimiters; +extern wchar_t *worddelimiters; extern int allowaltscreen; extern char *termname; extern unsigned int tabspaces; -extern unsigned int alpha; extern unsigned int defaultfg; extern unsigned int defaultbg; +extern float alpha; extern MouseKey mkeys[]; diff --git a/win.h b/win.h index d277477..a6ef1b9 100644 --- a/win.h +++ b/win.h @@ -23,10 +23,6 @@ enum win_mode { |MODE_MOUSEMANY, }; -/* alpha */ -#define OPAQUE 0Xff -#define USE_ARGB (alpha != OPAQUE && opt_embed == NULL) - void xbell(void); void xclipcopy(void); void xdrawcursor(int, int, Glyph, int, int, Glyph); @@ -40,3 +36,4 @@ void xsetmode(int, unsigned int); void xsetpointermotion(int); void xsetsel(char *); int xstartdraw(void); +void xximspot(int, int); diff --git a/x.c b/x.c index da5084b..cc2df91 100644 --- a/x.c +++ b/x.c @@ -155,6 +155,9 @@ static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); static void xdrawglyph(Glyph, int, int); static void xclear(int, int, int, int); static int xgeommasktogravity(int); +static void ximopen(Display *); +static void ximinstantiate(Display *, XPointer, XPointer); +static void ximdestroy(XIM, XPointer, XPointer); static void xinit(int, int); static void cresize(int, int); static void xresize(int, int); @@ -239,12 +242,14 @@ typedef struct { } Fontcache; /* Fontcache is an array now. A new font will be appended to the array. */ -static Fontcache frc[16]; +static Fontcache *frc = NULL; static int frclen = 0; +static int frccap = 0; 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; @@ -653,7 +658,7 @@ setsel(char *str, Time t) if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) selclear(); - xclipcopy(); + clipcopy(NULL); } void @@ -671,7 +676,7 @@ brelease(XEvent *e) } if (e->xbutton.button == Button2) - selpaste(NULL); + clippaste(NULL); else if (e->xbutton.button == Button1) mousesel(e, 1); } @@ -771,17 +776,17 @@ xloadcols(void) for (i = 0; i < dc.collen; i++) if (!xloadcolor(i, NULL, &dc.col[i])) { if (colorname[i]) - die("Could not allocate color '%s'\n", colorname[i]); + die("could not allocate color '%s'\n", colorname[i]); else - die("Could not allocate color %d\n", i); + die("could not allocate color %d\n", i); } /* set alpha value of bg color */ - if (USE_ARGB) { - dc.col[defaultbg].color.alpha = (0xffff * alpha) / OPAQUE; - dc.col[defaultbg].pixel &= 0x00111111; - dc.col[defaultbg].pixel |= alpha << 24; - } + 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; } @@ -793,7 +798,6 @@ xsetcolorname(int x, const char *name) if (!BETWEEN(x, 0, dc.collen)) return 1; - if (!xloadcolor(x, name, &ncolor)) return 1; @@ -803,17 +807,6 @@ xsetcolorname(int x, const char *name) return 0; } -void -xtermclear(int col1, int row1, int col2, int row2) -{ - XftDrawRect(xw.draw, - &dc.col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg], - borderpx + col1 * win.cw, - borderpx + row1 * win.ch, - (col2-col1+1) * win.cw, - (row2-row1+1) * win.ch); -} - /* * Absolute coordinates. */ @@ -918,7 +911,7 @@ xloadfont(Font *f, FcPattern *pattern) if ((XftPatternGetInteger(f->match->pattern, "slant", 0, &haveattr) != XftResultMatch) || haveattr < wantattr) { f->badslant = 1; - fputs("st: font slant does not match\n", stderr); + fputs("font slant does not match\n", stderr); } } @@ -927,7 +920,7 @@ xloadfont(Font *f, FcPattern *pattern) if ((XftPatternGetInteger(f->match->pattern, "weight", 0, &haveattr) != XftResultMatch) || haveattr != wantattr) { f->badweight = 1; - fputs("st: font weight does not match\n", stderr); + fputs("font weight does not match\n", stderr); } } @@ -955,14 +948,13 @@ xloadfonts(char *fontstr, double fontsize) FcPattern *pattern; double fontval; - if (fontstr[0] == '-') { + if (fontstr[0] == '-') pattern = XftXlfdParse(fontstr, False, False); - } else { + else pattern = FcNameParse((FcChar8 *)fontstr); - } if (!pattern) - die("st: can't open font %s\n", fontstr); + die("can't open font %s\n", fontstr); if (fontsize > 1) { FcPatternDel(pattern, FC_PIXEL_SIZE); @@ -988,7 +980,7 @@ xloadfonts(char *fontstr, double fontsize) } if (xloadfont(&dc.font, pattern)) - die("st: can't open font %s\n", fontstr); + die("can't open font %s\n", fontstr); if (usedfontsize < 0) { FcPatternGetDouble(dc.font.match->pattern, @@ -1006,17 +998,17 @@ xloadfonts(char *fontstr, double fontsize) FcPatternDel(pattern, FC_SLANT); FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); if (xloadfont(&dc.ifont, pattern)) - die("st: can't open font %s\n", fontstr); + die("can't open font %s\n", fontstr); FcPatternDel(pattern, FC_WEIGHT); FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); if (xloadfont(&dc.ibfont, pattern)) - die("st: can't open font %s\n", fontstr); + die("can't open font %s\n", fontstr); FcPatternDel(pattern, FC_SLANT); FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); if (xloadfont(&dc.bfont, pattern)) - die("st: can't open font %s\n", fontstr); + die("can't open font %s\n", fontstr); FcPatternDestroy(pattern); } @@ -1043,6 +1035,43 @@ xunloadfonts(void) xunloadfont(&dc.ibfont); } +void +ximopen(Display *dpy) +{ + XIMCallback destroy = { .client_data = NULL, .callback = ximdestroy }; + + if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { + XSetLocaleModifiers("@im=local"); + if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { + XSetLocaleModifiers("@im="); + if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) + die("XOpenIM failed. Could not open input device.\n"); + } + } + if (XSetIMValues(xw.xim, XNDestroyCallback, &destroy, NULL) != NULL) + die("XSetIMValues failed. Could not set input method value.\n"); + xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, xw.win, XNFocusWindow, xw.win, NULL); + if (xw.xic == NULL) + die("XCreateIC failed. Could not obtain input method.\n"); +} + +void +ximinstantiate(Display *dpy, XPointer client, XPointer call) +{ + ximopen(dpy); + XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, + ximinstantiate, NULL); +} + +void +ximdestroy(XIM xim, XPointer client, XPointer call) +{ + xw.xim = NULL; + XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, + ximinstantiate, NULL); +} + void xinit(int cols, int rows) { @@ -1051,56 +1080,31 @@ xinit(int cols, int rows) Window parent; pid_t thispid = getpid(); XColor xmousefg, xmousebg; + XWindowAttributes attr; + XVisualInfo vis; xw.scr = XDefaultScreen(xw.dpy); - xw.depth = (USE_ARGB) ? 32: XDefaultDepth(xw.dpy, xw.scr); - if (!USE_ARGB) - xw.vis = XDefaultVisual(xw.dpy, xw.scr); - else { - XVisualInfo *vis; - XRenderPictFormat *fmt; - int nvi; - int i; - XVisualInfo tpl = { - .screen = xw.scr, - .depth = 32, - .class = TrueColor - }; - - vis = XGetVisualInfo(xw.dpy, - VisualScreenMask | VisualDepthMask | VisualClassMask, - &tpl, &nvi); - xw.vis = NULL; - for (i = 0; i < nvi; i++) { - fmt = XRenderFindVisualFormat(xw.dpy, vis[i].visual); - if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { - xw.vis = vis[i].visual; - break; - } - } - - XFree(vis); - - if (!xw.vis) { - fprintf(stderr, "Couldn't find ARGB visual.\n"); - exit(1); - } + 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()) - die("Could not init fontconfig.\n"); + die("could not init fontconfig.\n"); usedfont = (opt_font == NULL)? font : opt_font; xloadfonts(usedfont, 0); /* colors */ - if (!USE_ARGB) - xw.cmap = XDefaultColormap(xw.dpy, xw.scr); - else - xw.cmap = XCreateColormap(xw.dpy, XRootWindow(xw.dpy, xw.scr), - xw.vis, None); + xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); xloadcols(); /* adjust fixed window geometry */ @@ -1115,13 +1119,11 @@ xinit(int cols, int rows) xw.attrs.background_pixel = dc.col[defaultbg].pixel; xw.attrs.border_pixel = dc.col[defaultbg].pixel; xw.attrs.bit_gravity = NorthWestGravity; - xw.attrs.event_mask = FocusChangeMask | KeyPressMask + xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | ExposureMask | VisibilityChangeMask | StructureNotifyMask | 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, xw.depth, InputOutput, xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity @@ -1130,8 +1132,7 @@ xinit(int cols, int rows) memset(&gcvalues, 0, sizeof(gcvalues)); gcvalues.graphics_exposures = False; xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); - dc.gc = XCreateGC(xw.dpy, (USE_ARGB) ? xw.buf: parent, - GCGraphicsExposures, &gcvalues); + 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); @@ -1142,22 +1143,7 @@ xinit(int cols, int rows) xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); /* input methods */ - if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { - XSetLocaleModifiers("@im=local"); - if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { - XSetLocaleModifiers("@im="); - if ((xw.xim = XOpenIM(xw.dpy, - NULL, NULL, NULL)) == NULL) { - die("XOpenIM failed. Could not open input" - " device.\n"); - } - } - } - xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing - | XIMStatusNothing, XNClientWindow, xw.win, - XNFocusWindow, xw.win, NULL); - if (xw.xic == NULL) - die("XCreateIC failed. Could not obtain input method.\n"); + ximopen(xw.dpy); /* white cursor, black outline */ cursor = XCreateFontCursor(xw.dpy, mouseshape); @@ -1299,13 +1285,10 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x fontpattern = FcFontSetMatch(0, fcsets, 1, fcpattern, &fcres); - /* - * Overwrite or create the new cache entry. - */ - if (frclen >= LEN(frc)) { - frclen = LEN(frc) - 1; - XftFontClose(xw.dpy, frc[frclen].font); - frc[frclen].unicodep = 0; + /* Allocate memory for the new cache entry. */ + if (frclen >= frccap) { + frccap += 16; + frc = xrealloc(frc, frccap * sizeof(Fontcache)); } frc[frclen].font = XftFontOpenPattern(xw.dpy, @@ -1377,10 +1360,6 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i bg = &dc.col[base.bg]; } - /* Change basic system colors [0-7] to bright system colors [8-15] */ - if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) - fg = &dc.col[base.fg]; - if (IS_SET(MODE_REVERSE)) { if (fg == &dc.col[defaultfg]) { fg = &dc.col[defaultbg]; @@ -1635,6 +1614,16 @@ xfinishdraw(void) defaultfg : defaultbg].pixel); } +void +xximspot(int x, int y) +{ + XPoint spot = { borderpx + x * win.cw, borderpx + (y + 1) * win.ch }; + XVaNestedList attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL); + + XSetICValues(xw.xic, XNPreeditAttributes, attr, NULL); + XFree(attr); +} + void expose(XEvent *ev) { @@ -1812,7 +1801,6 @@ kpress(XEvent *ev) ttywrite(buf, len, 1); } - void cmessage(XEvent *e) { @@ -2028,6 +2016,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; @@ -2062,7 +2053,7 @@ main(int argc, char *argv[]) opt_embed = EARGF(usage()); break; case 'v': - die("%s " VERSION " (c) 2010-2016 st engineers\n", argv0); + die("%s " VERSION "\n", argv0); break; default: usage();