aboutsummaryrefslogtreecommitdiff
path: root/st
diff options
context:
space:
mode:
authorKumar Damani <damani.kumar@gmail.com>2019-12-09 00:13:52 +0000
committerKumar Damani <damani.kumar@gmail.com>2019-12-09 00:13:52 +0000
commit63ad7837556192589799261cdccc28ee3002b36e (patch)
tree34523192bcac71533d895653bd413455dbaf7e71 /st
parentbad72a6710ac3a8d78c98327d9b9f7e987751862 (diff)
updated mutt and st
Diffstat (limited to 'st')
-rw-r--r--st/st/.Xdefaults124
-rw-r--r--st/st/.gitignore5
-rw-r--r--st/st/FAQ167
-rw-r--r--st/st/LEGACY17
-rw-r--r--st/st/Makefile5
-rw-r--r--st/st/PKGBUILD45
-rw-r--r--st/st/README.md85
-rw-r--r--st/st/TODO28
-rw-r--r--st/st/config.h131
-rw-r--r--st/st/config.mk27
-rw-r--r--st/st/solarized-alpha-toggle.patch20
-rwxr-xr-xst/st/stbin104768 -> 115616 bytes
-rwxr-xr-xst/st/st-copyout12
-rw-r--r--st/st/st.154
-rw-r--r--st/st/st.c164
-rw-r--r--st/st/st.h15
-rw-r--r--st/st/win.h5
-rw-r--r--st/st/x.c464
18 files changed, 847 insertions, 521 deletions
diff --git a/st/st/.Xdefaults b/st/st/.Xdefaults
new file mode 100644
index 0000000..05b5e2e
--- /dev/null
+++ b/st/st/.Xdefaults
@@ -0,0 +1,124 @@
+!! 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
+
+!! Set the background, foreground and cursor colors as below:
+*.background: #282828
+*.foreground: white
+*.cursorColor: white
+
+/* !! gruvbox: */
+/* *.color0: #1d2021 */
+/* *.color1: #cc241d */
+/* *.color2: #98971a */
+/* *.color3: #d79921 */
+/* *.color4: #458588 */
+/* *.color5: #b16286 */
+/* *.color6: #689d6a */
+/* *.color7: #a89984 */
+/* *.color8: #928374 */
+/* *.color9: #fb4934 */
+/* *.color10: #b8bb26 */
+/* *.color11: #fabd2f */
+/* *.color12: #83a598 */
+/* *.color13: #d3869b */
+/* *.color14: #8ec07c */
+/* *.color15: #ebdbb2 */
+
+/* !! gruvbox light: */
+/* *.color0: #fbf1c7 */
+/* *.color1: #cc241d */
+/* *.color2: #98971a */
+/* *.color3: #d79921 */
+/* *.color4: #458588 */
+/* *.color5: #b16286 */
+/* *.color6: #689d6a */
+/* *.color7: #7c6f64 */
+/* *.color8: #928374 */
+/* *.color9: #9d0006 */
+/* *.color10: #79740e */
+/* *.color11: #b57614 */
+/* *.color12: #076678 */
+/* *.color13: #8f3f71 */
+/* *.color14: #427b58 */
+/* *.color15: #3c3836 */
+
+/* !! brogrammer: */
+/* *.foreground: #d6dbe5 */
+/* *.background: #131313 */
+/* *.color0: #1f1f1f */
+/* *.color8: #d6dbe5 */
+/* *.color1: #f81118 */
+/* *.color9: #de352e */
+/* *.color2: #2dc55e */
+/* *.color10: #1dd361 */
+/* *.color3: #ecba0f */
+/* *.color11: #f3bd09 */
+/* *.color4: #2a84d2 */
+/* *.color12: #1081d6 */
+/* *.color5: #4e5ab7 */
+/* *.color13: #5350b9 */
+/* *.color6: #1081d6 */
+/* *.color14: #0f7ddb */
+/* *.color7: #d6dbe5 */
+/* *.color15: #ffffff */
+/* *.colorBD: #d6dbe5 */
+
+/* ! base16 */
+/* *.color0: #181818 */
+/* *.color1: #ab4642 */
+/* *.color2: #a1b56c */
+/* *.color3: #f7ca88 */
+/* *.color4: #7cafc2 */
+/* *.color5: #ba8baf */
+/* *.color6: #86c1b9 */
+/* *.color7: #d8d8d8 */
+/* *.color8: #585858 */
+/* *.color9: #ab4642 */
+/* *.color10: #a1b56c */
+/* *.color11: #f7ca88 */
+/* *.color12: #7cafc2 */
+/* *.color13: #ba8baf */
+/* *.color14: #86c1b9 */
+/* *.color15: #f8f8f8 */
+
+/* !! solarized */
+/* *.color0: #073642 */
+/* *.color1: #dc322f */
+/* *.color2: #859900 */
+/* *.color3: #b58900 */
+/* *.color4: #268bd2 */
+/* *.color5: #d33682 */
+/* *.color6: #2aa198 */
+/* *.color7: #eee8d5 */
+/* *.color9: #cb4b16 */
+/* *.color8: #fdf6e3 */
+/* *.color10: #586e75 */
+/* *.color11: #657b83 */
+/* *.color12: #839496 */
+/* *.color13: #6c71c4 */
+/* *.color14: #93a1a1 */
+/* *.color15: #fdf6e3 */
+
+/* !! xterm */
+/* *.color0: #000000 */
+/* *.color1: #cd0000 */
+/* *.color2: #00cd00 */
+/* *.color3: #cdcd00 */
+/* *.color4: #0000cd */
+/* *.color5: #cd00cd */
+/* *.color6: #00cdcd */
+/* *.color7: #e5e5e5 */
+/* *.color8: #4d4d4d */
+/* *.color9: #ff0000 */
+/* *.color10: #00ff00 */
+/* *.color11: #ffff00 */
+/* *.color12: #0000ff */
+/* *.color13: #ff00ff */
+/* *.color14: #00ffff */
+/* *.color15: #aabac8 */
diff --git a/st/st/.gitignore b/st/st/.gitignore
new file mode 100644
index 0000000..18c21b0
--- /dev/null
+++ b/st/st/.gitignore
@@ -0,0 +1,5 @@
+st
+st.o
+x.o
+pkg/
+*.pkg.tar.xz
diff --git a/st/st/FAQ b/st/st/FAQ
deleted file mode 100644
index 921c493..0000000
--- a/st/st/FAQ
+++ /dev/null
@@ -1,167 +0,0 @@
-## Why does st not handle utmp entries?
-
-Use the excellent tool of [utmp](http://git.suckless.org/utmp/) for this task.
-
-## Some _random program_ complains that st is unknown/not recognised/unsupported/whatever!
-
-It means that st doesn’t have any terminfo entry on your system. Chances are
-you did not `make install`. If you just want to test it without installing it,
-you can manually run `tic -sx st.info`.
-
-## Nothing works, and nothing is said about an unknown terminal!
-
-* Some programs just assume they’re running in xterm i.e. they don’t rely on
- terminfo. What you see is the current state of the “xterm compliance”.
-* Some programs don’t complain about the lacking st description and default to
- another terminal. In that case see the question about terminfo.
-
-## I get some weird glitches/visual bug on _random program_!
-
-Try launching it with a different TERM: $ TERM=xterm myapp. toe(1) will give
-you a list of available terminals, but you’ll most likely switch between xterm,
-st or st-256color. The default value for TERM can be changed in config.h
-(TNAME).
-
-## How do I scroll back up?
-
-Using a terminal multiplexer.
-
-* `st -e tmux` using C-b [
-* `st -e screen` using C-a ESC
-
-## Why doesn't the Del key work in some programs?
-
-Taken from the terminfo manpage:
-
- If the terminal has a keypad that transmits codes when the keys
- are pressed, this information can be given. Note that it is not
- possible to handle terminals where the keypad only works in
- local (this applies, for example, to the unshifted HP 2621 keys).
- If the keypad can be set to transmit or not transmit, give these
- codes as smkx and rmkx. Otherwise the keypad is assumed to
- always transmit.
-
-In the st case smkx=E[?1hE= and rmkx=E[?1lE>, so it is mandatory that
-applications which want to test against keypad keys send these
-sequences.
-
-But buggy applications (like bash and irssi, for example) don't do this. A fast
-solution for them is to use the following command:
-
- $ printf '\033[?1h\033=' >/dev/tty
-
-or
- $ tput smkx
-
-In the case of bash, readline is used. Readline has a different note in its
-manpage about this issue:
-
- enable-keypad (Off)
- When set to On, readline will try to enable the
- application keypad when it is called. Some systems
- need this to enable arrow keys.
-
-Adding this option to your .inputrc will fix the keypad problem for all
-applications using readline.
-
-If you are using zsh, then read the zsh FAQ
-<http://zsh.sourceforge.net/FAQ/zshfaq03.html#l25>:
-
- It should be noted that the O / [ confusion can occur with other keys
- such as Home and End. Some systems let you query the key sequences
- sent by these keys from the system's terminal database, terminfo.
- Unfortunately, the key sequences given there typically apply to the
- mode that is not the one zsh uses by default (it's the "application"
- mode rather than the "raw" mode). Explaining the use of terminfo is
- outside of the scope of this FAQ, but if you wish to use the key
- sequences given there you can tell the line editor to turn on
- "application" mode when it starts and turn it off when it stops:
-
- function zle-line-init () { echoti smkx }
- function zle-line-finish () { echoti rmkx }
- zle -N zle-line-init
- zle -N zle-line-finish
-
-Putting these lines into your .zshrc will fix the problems.
-
-## How can I use meta in 8bit mode?
-
-St supports meta in 8bit mode, but the default terminfo entry doesn't
-use this capability. If you want it, you have to use the 'st-meta' value
-in TERM.
-
-## I cannot compile st in OpenBSD
-
-OpenBSD lacks librt, despite it being mandatory in POSIX
-<http://pubs.opengroup.org/onlinepubs/9699919799/utilities/c99.html#tag_20_11_13>.
-If you want to compile st for OpenBSD you have to remove -lrt from config.mk, and
-st will compile without any loss of functionality, because all the functions are
-included in libc on this platform.
-
-## The Backspace Case
-
-St is emulating the Linux way of handling backspace being delete and delete being
-backspace.
-
-This is an issue that was discussed in suckless mailing list
-<http://lists.suckless.org/dev/1404/20697.html>. Here is why some old grumpy
-terminal users wants its backspace to be how he feels it:
-
- Well, I am going to comment why I want to change the behaviour
- of this key. When ASCII was defined in 1968, communication
- with computers was done using punched cards, or hardcopy
- terminals (basically a typewriter machine connected with the
- computer using a serial port). ASCII defines DELETE as 7F,
- because, in punched-card terms, it means all the holes of the
- card punched; it is thus a kind of 'physical delete'. In the
- same way, the BACKSPACE key was a non-destructive backspace,
- as on a typewriter. So, if you wanted to delete a character,
- you had to BACKSPACE and then DELETE. Another use of BACKSPACE
- was to type accented characters, for example 'a BACKSPACE `'.
- The VT100 had no BACKSPACE key; it was generated using the
- CONTROL key as another control character (CONTROL key sets to
- 0 b7 b6 b5, so it converts H (code 0x48) into BACKSPACE (code
- 0x08)), but it had a DELETE key in a similar position where
- the BACKSPACE key is located today on common PC keyboards.
- All the terminal emulators emulated the difference between
- these keys correctly: the backspace key generated a BACKSPACE
- (^H) and delete key generated a DELETE (^?).
-
- But a problem arose when Linus Torvalds wrote Linux. Unlike
- earlier terminals, the Linux virtual terminal (the terminal
- emulator integrated in the kernel) returned a DELETE when
- backspace was pressed, due to the VT100 having a DELETE key in
- the same position. This created a lot of problems (see [1]
- and [2]). Since Linux has become the king, a lot of terminal
- emulators today generate a DELETE when the backspace key is
- pressed in order to avoid problems with Linux. The result is
- that the only way of generating a BACKSPACE on these systems
- is by using CONTROL + H. (I also think that emacs had an
- important point here because the CONTROL + H prefix is used
- in emacs in some commands (help commands).)
-
- From point of view of the kernel, you can change the key
- for deleting a previous character with stty erase. When you
- connect a real terminal into a machine you describe the type
- of terminal, so getty configures the correct value of stty
- erase for this terminal. In the case of terminal emulators,
- however, you don't have any getty that can set the correct
- value of stty erase, so you always get the default value.
- For this reason, it is necessary to add 'stty erase ^H' to your
- profile if you have changed the value of the backspace key.
- Of course, another solution is for st itself to modify the
- value of stty erase. I usually have the inverse problem:
- when I connect to non-Unix machines, I have to press CONTROL +
- h to get a BACKSPACE. The inverse problem occurs when a user
- connects to my Unix machines from a different system with a
- correct backspace key.
-
- [1] http://www.ibb.net/~anne/keyboard.html
- [2] http://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-5.html
-
-## But I really want the old grumpy behaviour of my terminal
-
-Apply [1].
-
-[1] http://st.suckless.org/patches/delkey
-
diff --git a/st/st/LEGACY b/st/st/LEGACY
deleted file mode 100644
index bf28b1e..0000000
--- a/st/st/LEGACY
+++ /dev/null
@@ -1,17 +0,0 @@
-A STATEMENT ON LEGACY SUPPORT
-
-In the terminal world there is much cruft that comes from old and unsup‐
-ported terminals that inherit incompatible modes and escape sequences
-which noone is able to know, except when he/she comes from that time and
-developed a graphical vt100 emulator at that time.
-
-One goal of st is to only support what is really needed. When you en‐
-counter a sequence which you really need, implement it. But while you
-are at it, do not add the other cruft you might encounter while sneek‐
-ing at other terminal emulators. History has bloated them and there is
-no real evidence that most of the sequences are used today.
-
-
-Christoph Lohmann <20h@r-36.net>
-2012-09-13T07:00:36.081271045+02:00
-
diff --git a/st/st/Makefile b/st/st/Makefile
index 0b3cecd..a836907 100644
--- a/st/st/Makefile
+++ b/st/st/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
@@ -43,7 +43,9 @@ dist: clean
install: st
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f st $(DESTDIR)$(PREFIX)/bin
+ cp -f st-copyout $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/st
+ chmod 755 $(DESTDIR)$(PREFIX)/bin/st-copyout
mkdir -p $(DESTDIR)$(MANPREFIX)/man1
sed "s/VERSION/$(VERSION)/g" < st.1 > $(DESTDIR)$(MANPREFIX)/man1/st.1
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1
@@ -52,6 +54,7 @@ install: st
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/st
+ rm -f $(DESTDIR)$(PREFIX)/bin/st-copyout
rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1
.PHONY: all options clean dist install uninstall
diff --git a/st/st/PKGBUILD b/st/st/PKGBUILD
new file mode 100644
index 0000000..98a057d
--- /dev/null
+++ b/st/st/PKGBUILD
@@ -0,0 +1,45 @@
+# Maintainer:
+
+pkgname=st-luke-git
+_pkgname=st
+pkgver=0.8.2.r1062.2087ab9
+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')
+license=('MIT')
+options=('zipman')
+depends=('libxft')
+makedepends=('ncurses' 'libxext' 'git')
+optdepends=('dmenu: feed urls to dmenu')
+source=('git://github.com/LukeSmithxyz/st')
+sha1sums=('SKIP')
+
+provides=("${_pkgname}")
+conflicts=("${_pkgname}")
+
+pkgver() {
+ cd "${_pkgname}"
+ printf "%s.r%s.%s" "$(awk '/^VERSION =/ {print $3}' config.mk)" \
+ "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
+}
+
+prepare() {
+ cd $srcdir/${_pkgname}
+ # skip terminfo which conflicts with ncurses
+ sed -i '/tic /d' Makefile
+}
+
+build() {
+ cd "${_pkgname}"
+ make X11INC=/usr/include/X11 X11LIB=/usr/lib/X11
+}
+
+package() {
+ cd "${_pkgname}"
+ 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/st/st/README.md b/st/st/README.md
index 9a6c849..c7a1d9b 100644
--- a/st/st/README.md
+++ b/st/st/README.md
@@ -1,55 +1,76 @@
# Luke's build of st - the simple (suckless) terminal
-Forked from [https://github.com/shiva/st](https://github.com/shiva/st) for simplicity's sake, which is the [suckless terminal (st)](https://st.suckless.org/) with some patches added:
-+ transparency
-+ copy to clipboard (alt-shift-c)
-+ Solarized colors (light and dark toggleable)
-+ vertcenter
-+ scrollback with keyboard
-+ scrollback with mouse
-+ updated to latest version 0.8.1
+The [suckless terminal (st)](https://st.suckless.org/) with some additional features that make it literally the best terminal emulator ever:
-## My own additions
+## Unique features (using dmenu)
-+ Default font is system "mono" at 14pt, meaning the font will match your system font.
-+ Hold alt and press either ↑/↓ or the vim keys k/j to move up/down in the terminal.
-+ Alt-u and Alt-d scroll back/foward in history a page at a time.
-+ Alt-PageUp and Alt-PageDown scroll back/foward in history a page at a time.
-+ Transparency with solarized colors by default.
-+ Zoom in/out with Alt+Shift+k/j or u/d for larger intervals.
++ **follow urls** by pressing `alt-l`
++ **copy urls** in the same way with `alt-y`
++ **copy the output of commands** with `alt-o`
-## Terminal-specific mappings
+## Bindings for
-(Additions before me.)
++ **scrollback** with `alt-↑/↓` or `alt-pageup/down` or `shift` while scrolling the mouse
++ OR **vim-bindings**: scroll up/down in history with `alt-k` and `alt-j`. Faster with `alt-u`/`alt-d`.
++ **zoom/change font size**: same bindings as above, but holding down shift as well. `alt-home` returns to default
++ **copy text** with `alt-c`, **paste** is `alt-v` or `shift-insert`
-+ Scroll through history -- Shift+PageUp/PageDown or Shift+Mouse wheel
-+ Increase/decrease font size -- Shift+Alt+PageUp/PageDown
-+ Return to default font size -- Shift+Alt+Home
-+ Paste -- Shift+Insert
+## Pretty stuff
+
++ Compatibility with `Xresources` and `pywal` for dynamic colors. The `Xdefaults` file shows a usage example.
++ Default [gruvbox](https://github.com/morhetz/gruvbox) colors otherwise.
++ Transparency/alpha, which is also adjustable from your `Xresources`.
++ Default font is system "mono" at 16pt, meaning the font will match your system font.
+
+## Other st patches
+
++ Vertcenter
++ Scrollback
++ font2
++ updated to latest version 0.8.2
## Installation for newbs
```
-make
+git clone https://github.com/LukeSmithxyz/st
+cd st
sudo make install
```
+Users of Arch-based distros can also install it from the AUR as [st-luke-git](https://aur.archlinux.org/packages/st-luke-git/).
+
Obviously, `make` is required to build. `fontconfig` is required for the default build, since it asks `fontconfig` for your system monospace font. It might be obvious, but `libX11` and `libXft` are required as well. Chances are, you have all of this installed already.
-## Custom changes (`config.def.h` or `config.h`)
+On OpenBSD, be sure to edit `config.mk` first and remove `-lrt` from the `$LIBS` before compiling.
+
+Be sure to have a composite manager (`xcompmgr`, `compton`, etc.) running if you want transparency.
+
+## How to configure dynamically with Xresources
-By default, the terminal is transparent with a blackish background. There's a patch file `solarized-alpha-toggle.patch` which you can use to remove the transparency and give it a typical deep, dark blue solarized background. Just run:
+For many key variables, this build of `st` will look for X settings set in either `~/.Xdefaults` or `~/.Xresources`. You must run `xrdb` on one of these files to load the settings.
+
+For example, you can define your desired fonts, transparency or colors:
```
-patch < solarized-alpha-toggle.patch
+*.font: Liberation Mono:pixelsize=12:antialias=true:autohint=true;
+*.alpha: 0.9
+*.color0: #111
+...
```
-Then, run `make` & `sudo make install` again to install the new build. You make reverse the solarized background by running the same command as above, but giving `patch` the `-R` option as well.
+The `alpha` value (for transparency) goes from `0` (transparent) to `1` (opaque).
+
+### Colors
+
+To be clear about the color settings:
+
+- This build will use gruvbox colors by default and as a fallback.
+- If there are Xresources colors defined, those will take priority.
+- But if `wal` has run in your session, its colors will take priority.
+
+Note that when you run `wal`, it will negate the transparency of existing windows, but new windows will continue with the previously defined transparency.
-## Explore `config.h`
+## Contact
-+ Change `colorname[]` array values (88 LOC), default colours are solarized.
-+ Numbers of 0 - 15 are usual terminal colors. Change them to your liking.
-+ Change `bg` to your desired terminal background color.
-+ Change `fg` to your desired terminal foreground color.
-+ Change `cursor` to your desired terminal cursor color.
+- Luke Smith <luke@lukesmith.xyz>
+- [https://lukesmith.xyz](https://lukesmith.xyz)
diff --git a/st/st/TODO b/st/st/TODO
deleted file mode 100644
index 5f74cd5..0000000
--- a/st/st/TODO
+++ /dev/null
@@ -1,28 +0,0 @@
-vt emulation
-------------
-
-* double-height support
-
-code & interface
-----------------
-
-* add a simple way to do multiplexing
-
-drawing
--------
-* add diacritics support to xdraws()
- * switch to a suckless font drawing library
-* make the font cache simpler
-* add better support for brightening of the upper colors
-
-bugs
-----
-
-* fix shift up/down (shift selection in emacs)
-* remove DEC test sequence when appropriate
-
-misc
-----
-
- $ grep -nE 'XXX|TODO' st.c
-
diff --git a/st/st/config.h b/st/st/config.h
index 57cc5a6..22e9d21 100644
--- a/st/st/config.h
+++ b/st/st/config.h
@@ -5,7 +5,8 @@
*
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
*/
-static char *font = "mono:pixelsize=18:antialias=true:autohint=true";
+static char *font = "mono:pixelsize=16:antialias=true:autohint=true";
+static char *font2[] = { "Inconsolata for Powerline:pixelsize=16:antialias=true:autohint=true" };
static int borderpx = 2;
/*
@@ -30,9 +31,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,15 +84,42 @@ char *termname = "st-256color";
unsigned int tabspaces = 8;
/* bg opacity */
-//unsigned int alpha = 0xe6; //230
-unsigned int alpha = 0xff; //205
+float alpha = 0.92;
+
+/* Terminal colors (16 first used in escape sequence) */
+static const char *colorname[] = {
+ "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */
+ "#cc241d",
+ "#98971a",
+ "#d79921",
+ "#458588",
+ "#b16286",
+ "#689d6a",
+ "#a89984",
+ "#928374",
+ "#fb4934",
+ "#b8bb26",
+ "#fabd2f",
+ "#83a598",
+ "#d3869b",
+ "#8ec07c",
+ "#ebdbb2",
+ [255] = 0,
+ /* more colors can be added after 255 to use with DefaultXX */
+ "#282828", /* 256 -> bg */
+ "#ebdbb2", /* 257 -> fg */
+ "#add8e6", /* 258 -> cursor */
+};
-#include "/home/kdam0/.cache/wal/colors-wal-st.h"
/*
* Default colors (colorname index)
* foreground, background, cursor, reverse cursor
*/
+unsigned int defaultfg = 257;
+unsigned int defaultbg = 256;
+static unsigned int defaultcs = 258;
+static unsigned int defaultrcs = 0;
/*
* Default shape of cursor
@@ -123,6 +151,44 @@ static unsigned int mousebg = 0;
static unsigned int defaultattr = 11;
/*
+ * Xresources preferences to load at startup
+ */
+ResourcePref resources[] = {
+ { "font", STRING, &font },
+ { "fontalt0", STRING, &font2[0] },
+ { "color0", STRING, &colorname[0] },
+ { "color1", STRING, &colorname[1] },
+ { "color2", STRING, &colorname[2] },
+ { "color3", STRING, &colorname[3] },
+ { "color4", STRING, &colorname[4] },
+ { "color5", STRING, &colorname[5] },
+ { "color6", STRING, &colorname[6] },
+ { "color7", STRING, &colorname[7] },
+ { "color8", STRING, &colorname[8] },
+ { "color9", STRING, &colorname[9] },
+ { "color10", STRING, &colorname[10] },
+ { "color11", STRING, &colorname[11] },
+ { "color12", STRING, &colorname[12] },
+ { "color13", STRING, &colorname[13] },
+ { "color14", STRING, &colorname[14] },
+ { "color15", STRING, &colorname[15] },
+ { "background", STRING, &colorname[256] },
+ { "foreground", STRING, &colorname[257] },
+ { "cursorColor", STRING, &colorname[258] },
+ { "termname", STRING, &termname },
+ { "shell", STRING, &shell },
+ { "xfps", INTEGER, &xfps },
+ { "actionfps", INTEGER, &actionfps },
+ { "blinktimeout", INTEGER, &blinktimeout },
+ { "bellvolume", INTEGER, &bellvolume },
+ { "tabspaces", INTEGER, &tabspaces },
+ { "borderpx", INTEGER, &borderpx },
+ { "cwscale", FLOAT, &cwscale },
+ { "chscale", FLOAT, &chscale },
+ { "alpha", FLOAT, &alpha },
+};
+
+/*
* Internal mouse shortcuts.
* Beware that overloading Button1 will disable the selection.
*/
@@ -132,15 +198,29 @@ static MouseShortcut mshortcuts[] = {
{ Button5, XK_NO_MOD, "\005" },
};
+/* Internal keyboard shortcuts. */
+#define MODKEY Mod1Mask
+#define TERMMOD (Mod1Mask|ShiftMask)
+
MouseKey mkeys[] = {
/* button mask function argument */
{ Button4, ShiftMask, kscrollup, {.i = 1} },
{ Button5, ShiftMask, kscrolldown, {.i = 1} },
+ { Button4, MODKEY, kscrollup, {.i = 1} },
+ { Button5, MODKEY, kscrolldown, {.i = 1} },
+ { Button4, TERMMOD, zoom, {.f = +1} },
+ { Button5, TERMMOD, zoom, {.f = -1} },
};
-/* Internal keyboard shortcuts. */
-#define MODKEY Mod1Mask
-#define TERMMOD (ControlMask|ShiftMask)
+static char *openurlcmd[] = { "/bin/sh", "-c",
+ "sed 's/.*│//g' | tr -d '\n' | grep -aEo '(((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./&%?#=_-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)'| uniq | sed 's/^www./http:\\/\\/www\\./g' | dmenu -i -p 'Follow which url?' -l 10 | xargs -r xdg-open",
+ "externalpipe", NULL };
+
+static char *copyurlcmd[] = { "/bin/sh", "-c",
+ "sed 's/.*│//g' | tr -d '\n' | grep -aEo '(((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./&%?#=_-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)' | uniq | sed 's/^www./http:\\/\\/www\\./g' | dmenu -i -p 'Copy which url?' -l 10 | tr -d '\n' | xclip -selection clipboard",
+ "externalpipe", NULL };
+
+static char *copyoutput[] = { "/bin/sh", "-c", "st-copyout", "externalpipe", NULL };
static Shortcut shortcuts[] = {
/* mask keysym function argument */
@@ -148,14 +228,14 @@ 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|ShiftMask, XK_Home, zoomreset, {.f = 0} },
- { ShiftMask, XK_Insert, selpaste, {.i = 0} },
- { MODKEY|ShiftMask, XK_Insert, clippaste, {.i = 0} },
- { MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} },
- { MODKEY|ShiftMask, XK_V, clippaste, {.i = 0} },
- { TERMMOD, XK_Num_Lock, numlock, {.i = 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_Control_L, iso14755, {.i = 0} },
{ ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
{ ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
@@ -165,12 +245,17 @@ static Shortcut shortcuts[] = {
{ 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_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_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 } },
+ { MODKEY, XK_o, externalpipe, {.v = copyoutput } },
};
/*
diff --git a/st/st/config.mk b/st/st/config.mk
index 3b00d7e..eba98c3 100644
--- a/st/st/config.mk
+++ b/st/st/config.mk
@@ -1,28 +1,35 @@
# st version
-VERSION = 0.8.1
+VERSION = 0.8.2
# Customize below to fit your system
# paths
-PREFIX = /usr/local
+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`
-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/st/solarized-alpha-toggle.patch b/st/st/solarized-alpha-toggle.patch
deleted file mode 100644
index 901c392..0000000
--- a/st/st/solarized-alpha-toggle.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- config.h 2018-05-01 14:09:36.752813283 -0700
-+++ config.sol.h 2018-05-01 14:10:20.132810913 -0700
-@@ -83,7 +83,7 @@
- unsigned int tabspaces = 8;
-
- /* bg opacity */
--unsigned int alpha = 0xcd;
-+unsigned int alpha = 0xff;
-
- static const char *colorname[] = {
- "#073642", /* 0: black */
-@@ -114,7 +114,7 @@
- * foreground, background, cursor, reverse cursor
- */
- unsigned int defaultfg = 12;
--unsigned int defaultbg = 256;
-+unsigned int defaultbg = 0;
- static unsigned int defaultcs = 14;
- static unsigned int defaultrcs = 15;
-
diff --git a/st/st/st b/st/st/st
index 0ff17b5..bc94133 100755
--- a/st/st/st
+++ b/st/st/st
Binary files differ
diff --git a/st/st/st-copyout b/st/st/st-copyout
new file mode 100755
index 0000000..8eafc58
--- /dev/null
+++ b/st/st/st-copyout
@@ -0,0 +1,12 @@
+#!/bin/sh
+# Using external pipe with st, give a dmenu prompt of recent commands,
+# allowing the user to copy the output of one.
+# xclip required for this script.
+# By Jaywalker and Luke
+tmpfile=$(mktemp /tmp/st-cmd-output.XXXXXX)
+trap 'rm "$tmpfile"' 0 1 15
+sed -n "w $tmpfile"
+ps1="$(grep "\S" "$tmpfile" | tail -n 1 | sed 's/^\s*//' | cut -d' ' -f1)"
+chosen="$(grep -F "$ps1" "$tmpfile" | sed '$ d' | tac | dmenu -p "Copy which command's output?" -i -l 10 | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
+eps1="$(echo "$ps1" | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
+awk "/^$chosen$/{p=1;print;next} p&&/$eps1/{p=0};p" "$tmpfile" | xclip -selection clipboard
diff --git a/st/st/st.1 b/st/st/st.1
index 81bceff..57c35f4 100644
--- a/st/st/st.1
+++ b/st/st/st.1
@@ -1,6 +1,6 @@
.TH ST 1 st\-VERSION
.SH NAME
-st \- simple terminal
+st \- simple terminal (Luke Smith (https://lukesmith.xyz)'s build)
.SH SYNOPSIS
.B st
.RB [ \-aiv ]
@@ -125,6 +125,38 @@ and all the remaining arguments are used as a command
even without it.
.SH SHORTCUTS
.TP
+.B Alt-j/k or Alt-Up/Down or Alt-Mouse Wheel
+Scroll up/down one line at a time.
+.TP
+.B Alt-u/d or Alt-Page Up/Page Down
+Scroll up/down one screen at a time.
+.TP
+.B Alt-Shift-k/j or Alt-Shift-Page Up/Page Down or Alt-Shift-Mouse Wheel
+Increase or decrease font size.
+.TP
+.B Alt-Home
+Reset to default font size.
+.TP
+.B Shift-Insert or Alt-v
+Paste from clipboard.
+.TP
+.B Alt-c
+Copy to clipboard.
+.TP
+.B Alt-p
+Paste/input primary selection.
+.TP
+.B Alt-l
+Show dmenu menu of all URLs on screen and choose one to open.
+.TP
+.B Alt-y
+Show dmenu menu of all URLs on screen and choose one to copy.
+.TP
+.B Alt-o
+Show dmenu menu of all recently run commands and copy the output of the chosen command to the clipboard.
+.I xclip
+required.
+.TP
.B Break
Send a break in the serial line.
Break key is obtained in PC keyboards
@@ -142,25 +174,7 @@ Print the full screen to the
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.
-.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/st/st.c b/st/st/st.c
index 45d2544..21c6739 100644
--- a/st/st/st.c
+++ b/st/st/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,12 @@
#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])
+
+#define TLINE_HIST(y) ((y) <= HISTSIZE-term.row+2 ? term.hist[(y)] : term.line[(y-HISTSIZE+term.row-3)])
/* constants */
#define ISO14755CMD "dmenu -w \"$WINDOWID\" -p codepoint: </dev/null"
@@ -217,7 +223,6 @@ static void selsnap(int *, int *, int);
static size_t utf8decode(const char *, Rune *, size_t);
static Rune utf8decodebyte(char, size_t *);
static char utf8encodebyte(Rune, size_t);
-static char *utf8strchr(char *, Rune);
static size_t utf8validate(Rune *, size_t);
static char *base64dec(const char *);
@@ -259,10 +264,10 @@ xwrite(int fd, const char *s, size_t len)
void *
xmalloc(size_t len)
{
- void *p = malloc(len);
+ void *p;
- if (!p)
- die("Out of memory\n");
+ if (!(p = malloc(len)))
+ die("malloc: %s\n", strerror(errno));
return p;
}
@@ -271,7 +276,7 @@ void *
xrealloc(void *p, size_t len)
{
if ((p = realloc(p, len)) == NULL)
- die("Out of memory\n");
+ die("realloc: %s\n", strerror(errno));
return p;
}
@@ -280,7 +285,7 @@ char *
xstrdup(char *s)
{
if ((s = strdup(s)) == NULL)
- die("Out of memory\n");
+ die("strdup: %s\n", strerror(errno));
return s;
}
@@ -344,23 +349,6 @@ utf8encodebyte(Rune u, size_t i)
return utfbyte[i] | (u & ~utfmask[i]);
}
-char *
-utf8strchr(char *s, Rune u)
-{
- Rune r;
- size_t i, j, len;
-
- len = strlen(s);
- for (i = 0, j = 0; i < len; i += j) {
- if (!(j = utf8decode(&s[i], &r, len - i)))
- break;
- if (r == u)
- return &(s[i]);
- }
-
- return NULL;
-}
-
size_t
utf8validate(Rune *u, size_t i)
{
@@ -443,12 +431,27 @@ tlinelen(int y)
return i;
}
+int
+tlinehistlen(int y)
+{
+ int i = term.col;
+
+ if (TLINE_HIST(y)[i - 1].mode & ATTR_WRAP)
+ return i;
+
+ while (i > 0 && TLINE_HIST(y)[i - 1].u == ' ')
+ --i;
+
+ return i;
+}
+
void
selstart(int col, int row, int snap)
{
selclear();
sel.mode = SEL_EMPTY;
sel.type = SEL_REGULAR;
+ sel.alt = IS_SET(MODE_ALTSCREEN);
sel.snap = snap;
sel.oe.x = sel.ob.x = col;
sel.oe.y = sel.ob.y = row;
@@ -477,13 +480,12 @@ selextend(int col, int row, int type, int done)
oldsey = sel.ne.y;
oldtype = sel.type;
- sel.alt = IS_SET(MODE_ALTSCREEN);
sel.oe.x = col;
sel.oe.y = row;
selnormalize();
sel.type = type;
- if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type)
+ if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type || sel.mode == SEL_EMPTY)
tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey));
sel.mode = done ? SEL_IDLE : SEL_READY;
@@ -690,7 +692,7 @@ execsh(char *cmd, char **args)
errno = 0;
if ((pw = getpwuid(getuid())) == NULL) {
if (errno)
- die("getpwuid:%s\n", strerror(errno));
+ die("getpwuid: %s\n", strerror(errno));
else
die("who are you?\n");
}
@@ -733,13 +735,15 @@ sigchld(int a)
pid_t p;
if ((p = waitpid(pid, &stat, WNOHANG)) < 0)
- die("Waiting for pid %hd failed: %s\n", pid, strerror(errno));
+ die("waiting for pid %hd failed: %s\n", pid, strerror(errno));
if (pid != p)
return;
- if (!WIFEXITED(stat) || WEXITSTATUS(stat))
- die("child finished with error '%d'\n", stat);
+ if (WIFEXITED(stat) && WEXITSTATUS(stat))
+ die("child exited with status %d\n", WEXITSTATUS(stat));
+ else if (WIFSIGNALED(stat))
+ die("child terminated due to signal %d\n", WTERMSIG(stat));
exit(0);
}
@@ -784,7 +788,8 @@ ttynew(char *line, char *cmd, char *out, char **args)
if (line) {
if ((cmdfd = open(line, O_RDWR)) < 0)
- die("open line failed: %s\n", strerror(errno));
+ die("open line '%s' failed: %s\n",
+ line, strerror(errno));
dup2(cmdfd, 0);
stty(args);
return cmdfd;
@@ -796,7 +801,7 @@ ttynew(char *line, char *cmd, char *out, char **args)
switch (pid = fork()) {
case -1:
- die("fork failed\n");
+ die("fork failed: %s\n", strerror(errno));
break;
case 0:
close(iofd);
@@ -808,9 +813,17 @@ ttynew(char *line, char *cmd, char *out, char **args)
die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
close(s);
close(m);
+#ifdef __OpenBSD__
+ if (pledge("stdio getpw proc exec", NULL) == -1)
+ die("pledge\n");
+#endif
execsh(cmd, args);
break;
default:
+#ifdef __OpenBSD__
+ if (pledge("stdio rpath tty proc", NULL) == -1)
+ die("pledge\n");
+#endif
close(s);
cmdfd = m;
signal(SIGCHLD, sigchld);
@@ -829,7 +842,7 @@ ttyread(void)
/* append read bytes to unprocessed bytes */
if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0)
- die("Couldn't read from shell: %s\n", strerror(errno));
+ die("couldn't read from shell: %s\n", strerror(errno));
buflen += ret;
written = twrite(buf, buflen, 0);
@@ -838,9 +851,6 @@ ttyread(void)
if (buflen > 0)
memmove(buf, buf + written, buflen);
- if (term.scr > 0 && term.scr < HISTSIZE-1)
- term.scr++;
-
return ret;
}
@@ -1094,7 +1104,6 @@ kscrollup(const Arg* a)
}
}
-
void
tscrolldown(int orig, int n, int copyhist)
{
@@ -1137,6 +1146,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);
@@ -1504,7 +1516,8 @@ tsetattr(int *attr, int l)
} else {
fprintf(stderr,
"erresc(default): gfx attr %d unknown\n",
- attr[i]), csidump();
+ attr[i]);
+ csidump();
}
break;
}
@@ -1624,6 +1637,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",
@@ -1895,7 +1909,7 @@ csireset(void)
void
strhandle(void)
{
- char *p = NULL;
+ char *p = NULL, *dec;
int j, narg, par;
term.esc &= ~(ESC_STR_END|ESC_STR);
@@ -1913,8 +1927,6 @@ strhandle(void)
return;
case 52:
if (narg > 2) {
- char *dec;
-
dec = base64dec(strescseq.args[2]);
if (dec) {
xsetsel(dec);
@@ -1932,7 +1944,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
@@ -2030,6 +2045,62 @@ tprinter(char *s, size_t len)
}
void
+externalpipe(const Arg *arg)
+{
+ int to[2];
+ char buf[UTF_SIZ];
+ void (*oldsigpipe)(int);
+ Glyph *bp, *end;
+ int lastpos, n, newline;
+
+ if (pipe(to) == -1)
+ return;
+
+ switch (fork()) {
+ case -1:
+ close(to[0]);
+ close(to[1]);
+ return;
+ case 0:
+ dup2(to[0], STDIN_FILENO);
+ close(to[0]);
+ close(to[1]);
+ execvp(((char **)arg->v)[0], (char **)arg->v);
+ fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]);
+ perror("failed");
+ exit(0);
+ }
+
+ close(to[0]);
+ /* ignore sigpipe for now, in case child exists early */
+ oldsigpipe = signal(SIGPIPE, SIG_IGN);
+ newline = 0;
+ /* modify externalpipe patch to pipe history too */
+ for (n = 0; n <= HISTSIZE + 2; n++) {
+ bp = TLINE_HIST(n);
+ lastpos = MIN(tlinehistlen(n) +1, term.col) - 1;
+ if (lastpos < 0)
+ break;
+ if (lastpos == 0)
+ continue;
+ end = &bp[lastpos + 1];
+ for (; bp < end; ++bp)
+ if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
+ break;
+ if ((newline = TLINE_HIST(n)[lastpos].mode & ATTR_WRAP))
+ continue;
+ if (xwrite(to[1], "\n", 1) < 0)
+ break;
+ newline = 0;
+ }
+ if (newline)
+ (void)xwrite(to[1], "\n", 1);
+ close(to[1]);
+ /* restore */
+ signal(SIGPIPE, oldsigpipe);
+}
+
+void
iso14755(const Arg *arg)
{
FILE *p;
@@ -2335,7 +2406,7 @@ eschandle(uchar ascii)
case 'Z': /* DECID -- Identify Terminal */
ttywrite(vtiden, strlen(vtiden), 0);
break;
- case 'c': /* RIS -- Reset to inital state */
+ case 'c': /* RIS -- Reset to initial state */
treset();
resettitle();
xloadcols();
@@ -2406,7 +2477,6 @@ tputc(Rune u)
goto check_control_code;
}
-
if (IS_SET(MODE_SIXEL)) {
/* TODO: implement sixel mode */
return;
@@ -2591,7 +2661,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));
@@ -2669,12 +2739,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/st/st.h b/st/st/st.h
index 850c5f0..94ce5c3 100644
--- a/st/st/st.h
+++ b/st/st/st.h
@@ -3,9 +3,6 @@
#include <stdint.h>
#include <sys/types.h>
-/* 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,
@@ -92,7 +87,10 @@ void die(const char *, ...);
void redraw(void);
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 *);
@@ -123,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/st/st/win.h b/st/st/win.h
index d277477..a6ef1b9 100644
--- a/st/st/win.h
+++ b/st/st/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/st/st/x.c b/st/st/x.c
index 840d2fa..cc7a8a4 100644
--- a/st/st/x.c
+++ b/st/st/x.c
@@ -14,6 +14,7 @@
#include <X11/keysym.h>
#include <X11/Xft/Xft.h>
#include <X11/XKBlib.h>
+#include <X11/Xresource.h>
static char *argv0;
#include "arg.h"
@@ -43,6 +44,19 @@ typedef struct {
signed char appcursor; /* application cursor */
} Key;
+/* Xresources preferences */
+enum resource_type {
+ STRING = 0,
+ INTEGER = 1,
+ FLOAT = 2
+};
+
+typedef struct {
+ char *name;
+ enum resource_type type;
+ void *dst;
+} ResourcePref;
+
/* X modifiers */
#define XK_ANY_MOD UINT_MAX
#define XK_NO_MOD 0
@@ -78,6 +92,7 @@ typedef XftGlyphFontSpec GlyphFontSpec;
typedef struct {
int tw, th; /* tty width and height */
int w, h; /* window width and height */
+ int hborderpx, vborderpx;
int ch; /* char height */
int cw; /* char width */
int cyo; /* char y offset */
@@ -141,6 +156,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);
@@ -148,6 +166,8 @@ static void xhints(void);
static int xloadcolor(int, const char *, Color *);
static int xloadfont(Font *, FcPattern *);
static void xloadfonts(char *, double);
+static int xloadsparefont(FcPattern *, int);
+static void xloadsparefonts(void);
static void xunloadfont(Font *);
static void xunloadfonts(void);
static void xsetenv(void);
@@ -225,12 +245,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;
@@ -294,6 +316,7 @@ zoomabs(const Arg *arg)
{
xunloadfonts();
xloadfonts(usedfont, arg->f);
+ xloadsparefonts();
cresize(0, 0);
redraw();
xhints();
@@ -313,7 +336,7 @@ zoomreset(const Arg *arg)
int
evcol(XEvent *e)
{
- int x = e->xbutton.x - borderpx;
+ int x = e->xbutton.x - win.hborderpx;
LIMIT(x, 0, win.tw - 1);
return x / win.cw;
}
@@ -321,7 +344,7 @@ evcol(XEvent *e)
int
evrow(XEvent *e)
{
- int y = e->xbutton.y - borderpx;
+ int y = e->xbutton.y - win.vborderpx;
LIMIT(y, 0, win.th - 1);
return y / win.ch;
}
@@ -639,7 +662,7 @@ setsel(char *str, Time t)
if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
selclear();
- xclipcopy();
+ clipcopy(NULL);
}
void
@@ -657,7 +680,7 @@ brelease(XEvent *e)
}
if (e->xbutton.button == Button2)
- selpaste(NULL);
+ clippaste(NULL);
else if (e->xbutton.button == Button1)
mousesel(e, 1);
}
@@ -685,6 +708,11 @@ cresize(int width, int height)
col = (win.w - 2 * borderpx) / win.cw;
row = (win.h - 2 * borderpx) / win.ch;
+ col = MAX(1, col);
+ row = MAX(1, row);
+
+ win.hborderpx = (win.w - col * win.cw) / 2;
+ win.vborderpx = (win.h - row * win.ch) / 2;
tresize(col, row);
xresize(col, row);
@@ -694,8 +722,8 @@ cresize(int width, int height)
void
xresize(int col, int row)
{
- win.tw = MAX(1, col * win.cw);
- win.th = MAX(1, row * win.ch);
+ win.tw = col * win.cw;
+ win.th = row * win.ch;
XFreePixmap(xw.dpy, xw.buf);
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
@@ -744,28 +772,34 @@ xloadcols(void)
static int loaded;
Color *cp;
- dc.collen = MAX(LEN(colorname), 256);
- dc.col = xmalloc(dc.collen * sizeof(Color));
-
if (loaded) {
for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
+ } else {
+ dc.collen = MAX(LEN(colorname), 256);
+ dc.col = xmalloc(dc.collen * sizeof(Color));
}
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].color.red =
+ ((unsigned short)(dc.col[defaultbg].color.red * alpha)) & 0xff00;
+ dc.col[defaultbg].color.green =
+ ((unsigned short)(dc.col[defaultbg].color.green * alpha)) & 0xff00;
+ dc.col[defaultbg].color.blue =
+ ((unsigned short)(dc.col[defaultbg].color.blue * alpha)) & 0xff00;
+ dc.col[defaultbg].pixel &= 0x00FFFFFF;
+ dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24;
loaded = 1;
}
@@ -777,7 +811,6 @@ xsetcolorname(int x, const char *name)
if (!BETWEEN(x, 0, dc.collen))
return 1;
-
if (!xloadcolor(x, name, &ncolor))
return 1;
@@ -787,17 +820,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.
*/
@@ -812,22 +834,24 @@ xclear(int x1, int y1, int x2, int y2)
void
xhints(void)
{
- XClassHint class = {opt_name ? opt_name : termname,
- opt_class ? opt_class : termname};
+ XClassHint class = {opt_name ? opt_name : "st",
+ opt_class ? opt_class : "St"};
XWMHints wm = {.flags = InputHint, .input = 1};
XSizeHints *sizeh;
sizeh = XAllocSizeHints();
- sizeh->flags = PSize | PResizeInc | PBaseSize;
+ sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize;
sizeh->height = win.h;
sizeh->width = win.w;
- sizeh->height_inc = win.ch;
- sizeh->width_inc = win.cw;
+ sizeh->height_inc = 1;
+ sizeh->width_inc = 1;
sizeh->base_height = 2 * borderpx;
sizeh->base_width = 2 * borderpx;
+ sizeh->min_height = win.ch + 2 * borderpx;
+ sizeh->min_width = win.cw + 2 * borderpx;
if (xw.isfixed) {
- sizeh->flags |= PMaxSize | PMinSize;
+ sizeh->flags |= PMaxSize;
sizeh->min_width = sizeh->max_width = win.w;
sizeh->min_height = sizeh->max_height = win.h;
}
@@ -900,7 +924,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);
}
}
@@ -909,7 +933,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);
}
}
@@ -937,14 +961,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);
@@ -970,7 +993,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,
@@ -988,21 +1011,116 @@ 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);
}
+int
+xloadsparefont(FcPattern *pattern, int flags)
+{
+ FcPattern *match;
+ FcResult result;
+
+ match = FcFontMatch(NULL, pattern, &result);
+ if (!match) {
+ return 1;
+ }
+
+ if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) {
+ FcPatternDestroy(match);
+ return 1;
+ }
+
+ frc[frclen].flags = flags;
+ /* Believe U+0000 glyph will present in each default font */
+ frc[frclen].unicodep = 0;
+ frclen++;
+
+ return 0;
+}
+
+void
+xloadsparefonts(void)
+{
+ FcPattern *pattern;
+ double sizeshift, fontval;
+ int fc;
+ char **fp;
+
+ if (frclen != 0)
+ die("can't embed spare fonts. cache isn't empty");
+
+ /* Calculate count of spare fonts */
+ fc = sizeof(font2) / sizeof(*font2);
+ if (fc == 0)
+ return;
+
+ /* Allocate memory for cache entries. */
+ if (frccap < 4 * fc) {
+ frccap += 4 * fc - frccap;
+ frc = xrealloc(frc, frccap * sizeof(Fontcache));
+ }
+
+ for (fp = font2; fp - font2 < fc; ++fp) {
+
+ if (**fp == '-')
+ pattern = XftXlfdParse(*fp, False, False);
+ else
+ pattern = FcNameParse((FcChar8 *)*fp);
+
+ if (!pattern)
+ die("can't open spare font %s\n", *fp);
+
+ if (defaultfontsize > 0) {
+ sizeshift = usedfontsize - defaultfontsize;
+ if (sizeshift != 0 &&
+ FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
+ FcResultMatch) {
+ fontval += sizeshift;
+ FcPatternDel(pattern, FC_PIXEL_SIZE);
+ FcPatternDel(pattern, FC_SIZE);
+ FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval);
+ }
+ }
+
+ FcPatternAddBool(pattern, FC_SCALABLE, 1);
+
+ FcConfigSubstitute(NULL, pattern, FcMatchPattern);
+ XftDefaultSubstitute(xw.dpy, xw.scr, pattern);
+
+ if (xloadsparefont(pattern, FRC_NORMAL))
+ die("can't open spare font %s\n", *fp);
+
+ FcPatternDel(pattern, FC_SLANT);
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
+ if (xloadsparefont(pattern, FRC_ITALIC))
+ die("can't open spare font %s\n", *fp);
+
+ FcPatternDel(pattern, FC_WEIGHT);
+ FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
+ if (xloadsparefont(pattern, FRC_ITALICBOLD))
+ die("can't open spare font %s\n", *fp);
+
+ FcPatternDel(pattern, FC_SLANT);
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
+ if (xloadsparefont(pattern, FRC_BOLD))
+ die("can't open spare font %s\n", *fp);
+
+ FcPatternDestroy(pattern);
+ }
+}
+
void
xunloadfont(Font *f)
{
@@ -1026,6 +1144,43 @@ xunloadfonts(void)
}
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)
{
XGCValues gcvalues;
@@ -1033,63 +1188,39 @@ 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.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);
+ /* spare fonts */
+ xloadsparefonts();
+
/* 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 */
- win.w = 2 * borderpx + cols * win.cw;
- win.h = 2 * borderpx + rows * win.ch;
+ win.w = 2 * win.hborderpx + cols * win.cw;
+ win.h = 2 * win.vborderpx + rows * win.ch;
if (xw.gm & XNegative)
xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2;
if (xw.gm & YNegative)
@@ -1099,13 +1230,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
@@ -1114,8 +1243,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);
@@ -1126,22 +1254,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);
@@ -1188,7 +1301,7 @@ xinit(int cols, int rows)
int
xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
{
- float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
+ float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp;
ushort mode, prevmode = USHRT_MAX;
Font *font = &dc.font;
int frcflags = FRC_NORMAL;
@@ -1283,13 +1396,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,
@@ -1324,7 +1434,7 @@ void
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
{
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
- int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
+ int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch,
width = charlen * win.cw;
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
XRenderColor colfg, colbg;
@@ -1361,10 +1471,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];
@@ -1414,17 +1520,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
/* Intelligent cleaning up of the borders. */
if (x == 0) {
- xclear(0, (y == 0)? 0 : winy, borderpx,
+ xclear(0, (y == 0)? 0 : winy, win.vborderpx,
winy + win.ch +
- ((winy + win.ch >= borderpx + win.th)? win.h : 0));
+ ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0));
}
- if (winx + width >= borderpx + win.tw) {
+ if (winx + width >= win.hborderpx + win.tw) {
xclear(winx + width, (y == 0)? 0 : winy, win.w,
- ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch)));
+ ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch)));
}
if (y == 0)
- xclear(winx, 0, winx + width, borderpx);
- if (winy + win.ch >= borderpx + win.th)
+ xclear(winx, 0, winx + width, win.hborderpx);
+ if (winy + win.ch >= win.vborderpx + win.th)
xclear(winx, winy + win.ch, winx + width, win.h);
/* Clean up the region we want to draw to. */
@@ -1438,7 +1544,11 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
/* Render the glyphs. */
- XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
+ FcBool b = FcFalse;
+ FcPatternGetBool(specs->font->pattern, FC_COLOR, 0, &b);
+ if (!b) {
+ XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
+ }
/* Render underline and strikethrough. */
if (base.mode & ATTR_UNDERLINE) {
@@ -1517,35 +1627,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
case 3: /* Blinking Underline */
case 4: /* Steady Underline */
XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + (cy + 1) * win.ch - \
+ win.hborderpx + cx * win.cw,
+ win.vborderpx + (cy + 1) * win.ch - \
cursorthickness,
win.cw, cursorthickness);
break;
case 5: /* Blinking bar */
case 6: /* Steady bar */
XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + cy * win.ch,
+ win.hborderpx + cx * win.cw,
+ win.vborderpx + cy * win.ch,
cursorthickness, win.ch);
break;
}
} else {
XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + cy * win.ch,
+ win.hborderpx + cx * win.cw,
+ win.vborderpx + cy * win.ch,
win.cw - 1, 1);
XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + cy * win.ch,
+ win.hborderpx + cx * win.cw,
+ win.vborderpx + cy * win.ch,
1, win.ch - 1);
XftDrawRect(xw.draw, &drawcol,
- borderpx + (cx + 1) * win.cw - 1,
- borderpx + cy * win.ch,
+ win.hborderpx + (cx + 1) * win.cw - 1,
+ win.vborderpx + cy * win.ch,
1, win.ch - 1);
XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + (cy + 1) * win.ch - 1,
+ win.hborderpx + cx * win.cw,
+ win.vborderpx + (cy + 1) * win.ch - 1,
win.cw, 1);
}
}
@@ -1620,6 +1730,16 @@ xfinishdraw(void)
}
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)
{
redraw();
@@ -1796,7 +1916,6 @@ kpress(XEvent *ev)
ttywrite(buf, len, 1);
}
-
void
cmessage(XEvent *e)
{
@@ -1935,6 +2054,59 @@ run(void)
}
}
+int
+resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
+{
+ char **sdst = dst;
+ int *idst = dst;
+ float *fdst = dst;
+
+ char fullname[256];
+ char fullclass[256];
+ char *type;
+ XrmValue ret;
+
+ snprintf(fullname, sizeof(fullname), "%s.%s",
+ opt_name ? opt_name : "st", name);
+ snprintf(fullclass, sizeof(fullclass), "%s.%s",
+ opt_class ? opt_class : "St", name);
+ fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0';
+
+ XrmGetResource(db, fullname, fullclass, &type, &ret);
+ if (ret.addr == NULL || strncmp("String", type, 64))
+ return 1;
+
+ switch (rtype) {
+ case STRING:
+ *sdst = ret.addr;
+ break;
+ case INTEGER:
+ *idst = strtoul(ret.addr, NULL, 10);
+ break;
+ case FLOAT:
+ *fdst = strtof(ret.addr, NULL);
+ break;
+ }
+ return 0;
+}
+
+void
+config_init(void)
+{
+ char *resm;
+ XrmDatabase db;
+ ResourcePref *p;
+
+ XrmInitialize();
+ resm = XResourceManagerString(xw.dpy);
+ if (!resm)
+ return;
+
+ db = XrmGetStringDatabase(resm);
+ for (p = resources; p < resources + LEN(resources); p++)
+ resource_load(db, p->name, p->type, p->dst);
+}
+
void
usage(void)
{
@@ -1959,6 +2131,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;
@@ -1993,7 +2168,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();
@@ -2008,6 +2183,11 @@ run:
setlocale(LC_CTYPE, "");
XSetLocaleModifiers("");
+
+ if(!(xw.dpy = XOpenDisplay(NULL)))
+ die("Can't open display\n");
+
+ config_init();
cols = MAX(cols, 1);
rows = MAX(rows, 1);
tnew(cols, rows);