├── .github └── workflows │ ├── build_package.yml │ ├── c-cpp2.yml │ └── release.yml ├── CHANGELOG ├── LICENSE ├── Makefile ├── PATCHES.md ├── README.md ├── config.make ├── dist └── debian │ └── DEBIAN │ ├── control │ └── postinst ├── doc ├── BLURP.md ├── ansi_escape_sequences.txt ├── ascii-controlchars-vt102.txt ├── ascii_0-127.png ├── ascii_0-127.txt ├── ascii_128-255.png ├── ascii_128-255.txt ├── colornames.html ├── colornames_gray.html ├── fontconfig.txt ├── old │ ├── DEVLOG.md │ ├── FAQ.md │ ├── LOG.md │ ├── README │ └── cheatsheet.md └── patches-applied ├── images ├── ascii.png ├── colors-bold.png ├── colors.png ├── indexed_colors.jpg ├── indexed_fgcolors.jpg ├── noticket.jpg ├── st-asc_with_i3.png └── vt-102-1984.jpg ├── ori └── st.c ├── slterm.1 ├── slterm.1.rst ├── src ├── Makefile ├── base64.c ├── base64.h ├── build │ └── .emptydir ├── charmaps.c ├── charmaps.h ├── colors.c ├── colors.h ├── colors.sh ├── config.h ├── controlchars.c ├── controlchars.h ├── debug.h ├── embed │ ├── README │ ├── embed_font.h │ ├── slterm_font.ttf │ ├── slterm_font_bold.ttf │ ├── slterm_font_bold_italic.ttf │ ├── slterm_font_italic.ttf │ └── updatesizes.sh ├── fonts.c ├── fonts.h ├── globals.c ├── globals.h ├── help.h ├── help.h.in ├── help.txt ├── helphead.txt ├── includes.h ├── keyref.txt ├── keyreffilter.pl ├── license.txt ├── main.c ├── mem.c ├── mem.h ├── retmarks.c ├── scroll.c ├── scroll.h ├── selection.c ├── selection.h ├── sinfl.h ├── slterm.1 ├── slterm.terminfo ├── slterm_info.h ├── slterm_license.h ├── slterm_man.h ├── slterm_shared.c ├── slterm_src.c ├── slterm_terminfo.h ├── statusbar.c ├── statusbar.h ├── system.c ├── system.h ├── term.c ├── term.h ├── termdraw.c ├── termdraw.h ├── tty.c ├── tty.h ├── utf8.c ├── utf8.h ├── xclipboard.c ├── xclipboard.h ├── xcursor.c ├── xcursor.h ├── xdraw.c ├── xdraw.h ├── xevent.c ├── xevent.h ├── xkeyboard.c ├── xkeyboard.h ├── xmouse.c ├── xmouse.h ├── xwindow.c └── xwindow.h ├── test ├── 16bgcolors.sh ├── 16colors.sh ├── 8colors.sh ├── UTF-8-demo.txt ├── ansicolors.sh ├── ascii-tiny.c ├── ascii.c ├── asciitable.txt ├── attributes.sh ├── bgcolors3.pl ├── colors2.pl ├── colors3.pl ├── gray.sh ├── test.sh ├── test2.sh └── umlaut.txt └── tools ├── Makefile ├── README ├── cpfilter.c ├── sdefl.h ├── sinfl.h ├── tic ├── Makefile ├── README ├── cdbw.c ├── cdbw.h ├── compile.c ├── hash.c ├── mi_vector_hash.c ├── mi_vector_hash.h ├── term.h ├── term_private.h ├── tic.1 └── tic.c ├── ttfdz.c └── ttfz.c /.github/workflows/build_package.yml: -------------------------------------------------------------------------------- 1 | name: Build package 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'never*' 7 | 8 | #push: 9 | # branches: [ "master" ] 10 | #pull_request: 11 | # branches: [ "master" ] 12 | 13 | 14 | 15 | 16 | jobs: 17 | build: 18 | 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - uses: actions/checkout@v4 23 | - name: requisites 24 | run: sudo apt-get install libfreetype-dev x11proto-dev fontconfig libx11-dev libxft-dev python3-docutils 25 | - name: make 26 | run: make 27 | - name: make check 28 | run: make check 29 | - name: Install project 30 | run: sudo make install DESTDIR=$(pwd)/dist/debian 31 | - name: Get version from config.make 32 | id: get_version 33 | run: | 34 | VERSION=$(sed -ne 's/^VERSION := //p' config.make | tr -d '\n') 35 | echo "::set-output name=version::$VERSION" 36 | - name: build package 37 | run: | 38 | VERSION=${{ steps.get_version.outputs.version }} 39 | sed -i "s/VERSION/$VERSION/" dist/debian/DEBIAN/control 40 | cat dist/debian/DEBIAN/control 41 | dpkg-deb --build dist/debian slterm_${{ steps.get_version.outputs.version }}.deb 42 | - name: package check 43 | run: | 44 | sudo apt-get install libfreetype6 libxft2 libfontconfig1 fonts-liberation 45 | sudo dpkg -i slterm_${{ steps.get_version.outputs.version }}.deb 46 | slterm -V 47 | - name: Upload package 48 | uses: actions/upload-artifact@v4 49 | with: 50 | name: slterm_${{ steps.get_version.outputs.version }}.deb 51 | path: slterm_${{ steps.get_version.outputs.version }}.deb 52 | -------------------------------------------------------------------------------- /.github/workflows/c-cpp2.yml: -------------------------------------------------------------------------------- 1 | name: C/C++ CI 2 | 3 | on: 4 | push: 5 | branches: [ "devel" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: requisites 17 | run: sudo apt-get install libfreetype-dev x11proto-dev fontconfig libx11-dev libxft-dev python3-docutils 18 | - name: make 19 | run: make 20 | - name: make check 21 | run: make check 22 | 23 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Create Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | #push: 9 | # branches: [ "master" ] 10 | # pull_request: 11 | # branches: [ "master" ] 12 | 13 | 14 | jobs: 15 | release: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v4 20 | 21 | - name: Get version from config.make 22 | id: get_version 23 | run: | 24 | VERSION=$(sed -ne 's/^VERSION := //p' config.make | tr -d '\n') 25 | echo "::set-output name=version::$VERSION" 26 | 27 | 28 | - name: Download Binary using wget 29 | run: | 30 | wget https://github.com/michael105/static-bin/raw/refs/heads/main/xorg/slterm 31 | chmod a+x slterm 32 | mv slterm slterm_linux_amd64 33 | - name: Create GitHub Release 34 | id: create_release 35 | uses: actions/create-release@v1 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | with: 39 | tag_name: ${{ steps.get_version.outputs.version }} 40 | release_name: Release ${{ steps.get_version.outputs.version }} 41 | body: | 42 | automated package builds 43 | draft: false 44 | prerelease: false 45 | 46 | - name: Upload Release Asset 47 | uses: actions/upload-release-asset@v1 48 | env: 49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 50 | with: 51 | upload_url: ${{ steps.create_release.outputs.upload_url }} 52 | asset_path: ./slterm_linux_amd64 53 | asset_name: slterm_linux_amd64 54 | asset_content_type: application/octet-stream 55 | 56 | - name: build static package 57 | run: | 58 | VERSION=${{ steps.get_version.outputs.version }} 59 | echo Version - $VERSION 60 | sed -i "s/VERSION/$VERSION/" dist/debian/DEBIAN/control 61 | cp dist/debian/DEBIAN/control ./control.tmp 62 | sed -i "/^Depends:/d" dist/debian/DEBIAN/control 63 | cat dist/debian/DEBIAN/control 64 | mkdir -p dist/debian/usr/local/bin 65 | cp slterm_linux_amd64 dist/debian/usr/local/bin/slterm 66 | mkdir -p dist/debian/usr/local/share/man/man1 67 | cp src/slterm.1 dist/debian/usr/local/share/man/man1/ 68 | mkdir -p dist/debian/usr/local/share/doc/slterm 69 | cp -R README.md LICENSE PATCHES.md test dist/debian/usr/local/share/doc/slterm/ 70 | mkdir dist/debian/usr/local/share/doc/slterm/doc 71 | cp doc/BLURP.md doc/ansi_escape_sequences.txt doc/ascii-controlchars-vt102.txt doc/ascii_0-127.png doc/ascii_0-127.txt doc/ascii_128-255.png doc/ascii_128-255.txt doc/colornames.html doc/colornames_gray.html doc/fontconfig.txt doc/patches-applied dist/debian/usr/local/share/doc/slterm/doc/ 72 | dpkg-deb --build dist/debian slterm_${{ steps.get_version.outputs.version }}_static.deb 73 | 74 | - name: upload static package 75 | uses: actions/upload-release-asset@v1 76 | env: 77 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 78 | with: 79 | upload_url: ${{ steps.create_release.outputs.upload_url }} 80 | asset_path: slterm_${{ steps.get_version.outputs.version }}_static.deb 81 | asset_name: slterm_${{ steps.get_version.outputs.version }}_static.deb 82 | asset_content_type: application/vnd.debian.binary-package 83 | 84 | - name: build requisites 85 | run: sudo apt-get install libfreetype-dev x11proto-dev fontconfig libx11-dev libxft-dev python3-docutils 86 | - name: make 87 | run: make 88 | - name: make check 89 | run: make check 90 | - name: Install project 91 | run: | 92 | rm dist/debian/usr/local/bin/slterm 93 | cp ./control.tmp dist/debian/DEBIAN/control 94 | sudo make install DESTDIR=$(pwd)/dist/debian 95 | - name: build package 96 | run: | 97 | cat dist/debian/DEBIAN/control 98 | dpkg-deb --build dist/debian slterm_${{ steps.get_version.outputs.version }}.deb 99 | - name: package check 100 | run: | 101 | sudo apt-get install libfreetype6 libxft2 libfontconfig1 fonts-liberation 102 | sudo dpkg -i slterm_${{ steps.get_version.outputs.version }}.deb 103 | slterm -V 104 | - name: upload package 105 | uses: actions/upload-release-asset@v1 106 | env: 107 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 108 | with: 109 | upload_url: ${{ steps.create_release.outputs.upload_url }} 110 | asset_path: slterm_${{ steps.get_version.outputs.version }}.deb 111 | asset_name: slterm_${{ steps.get_version.outputs.version }}.deb 112 | asset_content_type: application/vnd.debian.binary-package 113 | 114 | 115 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 2 | 0.99.6.0 3 | Documentation 4 | minor changes. 5 | Mainly a release, which should be stable. 6 | 7 | 8 | 0.99.5.7 (2025/02/01) 9 | 10 | Fixed segfault with alt screen 11 | Documentation 12 | Add .deb package build workflow 13 | 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # slterm - simple terminal 2 | # See LICENSE file for copyright and license details. 3 | .POSIX: 4 | 5 | 6 | define HELP 7 | Makefile help 8 | 9 | for the build configuration, edit config.make 10 | further configuration and preferences can be set in src/config.h 11 | 12 | make targets 13 | ------------ 14 | slterm: (default) build slterm 15 | static: build slterm as static binary 16 | static_embedfont: static build, embed fonts into the binary 17 | 18 | install: install slterm 19 | 20 | endef 21 | 22 | 23 | 24 | all: man tools 25 | cd src && $(MAKE) 26 | 27 | 28 | help: 29 | $(info $(HELP)) 30 | 31 | 32 | slterm: man tools 33 | cd src && $(MAKE) 34 | 35 | static: man tools 36 | cd src && $(MAKE) static 37 | 38 | static_embedfont: man tools 39 | cd src && $(MAKE) static EMBEDFONT=1 40 | 41 | tools: 42 | cd tools && $(MAKE) 43 | 44 | check: 45 | cd src && $(MAKE) check 46 | 47 | #local (use config.in.loc) 48 | l: cd src && $(MAKE) 49 | 50 | man: slterm.1 51 | 52 | slterm.1: slterm.1.rst 53 | rst2man slterm.1.rst > slterm.1 || rst2man.py slterm.1.rst > slterm.1 54 | 55 | 56 | install: 57 | cd src && make install 58 | 59 | 60 | loc-install: src/slterm slterm.1 61 | su -c 'sh -c "mv /usr/local/bin/st /usr/local/bin/st.bak; cp src/slterm /usr/local/bin/st; chmod a+rx /usr/local/bin/st" ' 62 | 63 | 64 | .PHONY: all install 65 | 66 | 67 | -------------------------------------------------------------------------------- /PATCHES.md: -------------------------------------------------------------------------------- 1 | ## applied Patches 2 | 3 | 4 |
5 | 6 | - [keyboard\_select](#keyboard_select) 7 | - [scrollback](#scrollback) 8 | - [anysize](#anysize) 9 | - [one clipboard](#one-clipboard) 10 | - [relativeborder](#relativeborder) 11 | - [selectioncolors](#selectioncolors) 12 | - [xresources](#xresources) 13 | 14 |
15 | 16 | omitted: 17 | 18 | newterm ( doesn't detach->parent killed->child too ) 19 | 20 | vertcenter ( somehow doesn't look right to me) 21 | 22 | 23 | --- 24 | ### keyboard\_select 25 | 26 | #### Description 27 | 28 | This patch allows you to select and copy text to primary buffer with 29 | keyboard shortcuts like the perl extension keyboard-select for urxvt. 30 | 31 | #### Instructions 32 | 33 | The patch changes the config.def.h. Delete your config.h or add the 34 | shortcut below if you use a custom one. 35 | 36 | Shortcut shortcuts[] = { 37 | ... 38 | { TERMMOD, XK_s, keyboard_select, { 0 } }, 39 | }; 40 | 41 | #### Notes 42 | 43 | When you run "keyboard\_select", you have 3 modes available : 44 | 45 | - move mode : to set the start of the selection; 46 | - select mode : to activate and set the end of the selection; 47 | - input mode : to enter the search criteria. 48 | 49 | Shortcuts for move and select modes : 50 | 51 | ``` 52 | h, j, k, l: move cursor left/down/up/right (also with arrow keys) 53 | !, _, *: move cursor to the middle of the line/column/screen 54 | Backspace, $: move cursor to the beginning/end of the line 55 | PgUp, PgDown : move cursor to the beginning/end of the column 56 | Home, End: move cursor to the top/bottom left corner of the screen 57 | /, ?: activate input mode and search up/down 58 | n, N: repeat last search, up/down 59 | s: toggle move/selection mode 60 | t: toggle regular/rectangular selection type 61 | Return: quit keyboard_select, keeping the highlight of the selection 62 | Escape: quit keyboard_select 63 | ``` 64 | 65 | With h,j,k,l (also with arrow keys), you can use a quantifier. Enter a 66 | number before hitting the appropriate key. 67 | 68 | Shortcuts for input mode : 69 | 70 | ``` 71 | Return: Return to the previous mode 72 | ``` 73 | 74 | #### Authors 75 | 76 | - Tonton Couillon - \ 77 | 78 | 79 | 80 | --- 81 | ### scrollback 82 | 83 | #### Description 84 | 85 | Scroll back through terminal output using Shift+{PageUp, PageDown}. 86 | 87 | patch on top of the previous to allow scrolling using 88 | `Shift+MouseWheel`. 89 | 90 | patch on top of the previous two to allow scrollback using mouse wheel 91 | only when not in `MODE_ALTSCREEN`. For example the content is being 92 | scrolled instead of the scrollback buffer in `less`. Consequently the 93 | Shift modifier for scrolling is not needed anymore. **Note: patches 94 | before `20191024-a2c479c` might break mkeys other than scrolling 95 | functions.** 96 | 97 | patch on top of the first two to allow changing how fast the mouse 98 | scrolls. 99 | 100 | #### Notes 101 | 102 | - Patches modify config.def.h, you need to add mkeys to your own 103 | config.h 104 | - With patches before `20191024-a2c479c`: you can not have a mshortcut 105 | for the same mkey so remove Button4 and Button5 from mshortcuts in 106 | config.h 107 | - The mouse and altscreen patches `20191024-a2c479c` (and later) are 108 | simpler and more robust because st gained better support for 109 | customized mouse shortcuts. As a result, the altscreen patch doesn't 110 | really need the mouse patch. However to keep it simple the 111 | instructions stay the same: the alrscreen patch still applies on top 112 | of the (now very minimal) mouse patch. 113 | 114 | #### Authors 115 | 116 | - Jochen Sprickerhof - 117 | - M Farkas-Dyck - 118 | - Ivan Tham - (mouse scrolling) 119 | - Ori Bernstein - (fix memory bug) 120 | - Matthias Schoth - (auto altscreen scrolling) 121 | - Laslo Hunhold - (unscrambling, git port) 122 | - Paride Legovini - (don't require the Shift 123 | modifier when using the auto altscreen scrolling) 124 | - Lorenzo Bracco - (update base patch, use static 125 | variable for config) 126 | - Kamil Kleban - (fix altscreen detection) 127 | - Avi Halachmi - (mouse + altscreen rewrite after 128 | `a2c479c`) 129 | - Jacob Prosser - 130 | 131 | 132 | 133 | 134 | --- 135 | ### anysize 136 | 137 | #### Description 138 | 139 | By default, st's window size always snaps to the nearest multiple of the 140 | character size plus a fixed inner border (set with borderpx in 141 | config.h). When the size of st does not perfectly match the space 142 | allocated to it (when using a tiling WM, for example), unsightly gaps 143 | will appear between st and other apps, or between instances of st. 144 | 145 | This patch allows st to resize to any pixel size, makes the inner border 146 | size dynamic, and centers the content of the terminal so that the 147 | left/right and top/bottom borders are balanced. With this patch, st on a 148 | tiling WM will always fill the entire space allocated to it. 149 | 150 | #### Authors 151 | 152 | - Augusto Born de Oliveira - 153 | 154 | --- 155 | ### one clipboard 156 | 157 | Free Desktop mandates the user to remember which of two clipboards you 158 | are keeping selections in. If you switch between a terminal and browser, 159 | you might this UX jarring. This patch modifies st to work from one 160 | CLIPBOARD, the same as your browser. 161 | 162 | #### Description 163 | 164 | st by default only sets PRIMARY on selection since 165 | [March 2015](http://git.suckless.org/st/commit/?id=28259f5750f0dc7f52bbaf8b746ec3dc576a58ee) 166 | according to the [Freedesktop 167 | standard](http://standards.freedesktop.org/clipboards-spec/clipboards-latest.txt). 168 | 169 | This patch makes st set CLIPBOARD on selection. Furthermore from 170 | `st-clipboard-0.8.2.diff` middle click pastes from CLIPBOARD. 171 | 172 | You may want to replace selpaste with clippaste in your config.h to 173 | complete the affect. 174 | 175 | #### Authors 176 | 177 | - Kai Hendry - 178 | - Laslo Hunhold - (git port) 179 | - Matthew Parnell - (0.7, git ports) 180 | 181 | 182 | --- 183 | ### relativeborder 184 | 185 | #### Description 186 | 187 | When working with a mixture of different DPI scales on different 188 | monitors, you need to use a flexible font that will size correctly no 189 | matter the DPI - for example, `DejaVu Sans Mono-10`. If you have a 190 | border set in pixels, this border will look vastly different in size 191 | depending on the DPI of your display. 192 | 193 | This patch allows you to specify a border that is relative in size to 194 | the width of a cell in the terminal. 195 | 196 | #### Authors 197 | 198 | - Doug Whiteley - 199 | 200 | 201 | 202 | --- 203 | ### selectioncolors 204 | 205 | #### Description 206 | 207 | This patch adds the two color-settings *selectionfg* and *selectionbg* 208 | to config.def.h. Those define the fore- and background colors which are 209 | used when text on the screen is selected with the mouse. This removes 210 | the default behaviour which would simply reverse the colors. 211 | 212 | Additionally, a third setting *ingnoreselfg* exists. If true then the 213 | setting *selectionfg* is ignored and the original foreground-colors of 214 | each cell are not changed during selection. Basically only the 215 | background-color would change. This might be more visually appealing to 216 | some folks. 217 | 218 | #### Authors 219 | 220 | - Aleksandrs Stier 221 | 222 | 223 | 224 | --- 225 | ### xresources 226 | 227 | #### Description 228 | 229 | This patch adds the ability to configure st via Xresources. At startup, 230 | st will read and apply the resources named in the `resources[]` array in 231 | config.h. 232 | 233 | #### Authors 234 | 235 | - @dcat on [Github](https://github.com/dcat/st-xresources) 236 | - Devin J. Pohly - (git port) 237 | - Sai Praneeth Reddy - (read borderpx from 238 | xresources) 239 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/README.md -------------------------------------------------------------------------------- /config.make: -------------------------------------------------------------------------------- 1 | # build configuration 2 | # More options to configure are in src/config.h 3 | # This is a makefile, included by src/Makefile 4 | 5 | # Set to 0 6 | SHOWCONFIGINFO := 1 7 | 8 | # Dump debugging info 9 | # Values: 0 (off), 1 (on) 10 | ENABLEDEBUG := 0 11 | 12 | # Dump all available debug 13 | FULLDEBUG := 0 14 | 15 | # version 16 | VERSION := 0.99.6.0 17 | 18 | # Set to 1 enable Xresource configuration 19 | # (in addition, slterm has to be started with the option "-x on") 20 | XRESOURCES := 0 21 | 22 | # embed terminfo and manual page (+12k) 23 | EMBEDRESOURCES := 1 24 | 25 | # Embed fonts into the binary 26 | EMBEDFONT := 0 27 | 28 | # utf8-support (currently abandoned. Will not work ) 29 | #UTF8 := 0 30 | 31 | # Length of history, in bits, -> log(size in lines) ~ bits */ 32 | # 8 equals 1<<8 = 256 lines, 9 = 512, 10 = 1024, .. 33 | HISTSIZEBITS := 16 34 | #HISTSIZEBITS = 7 35 | 36 | # opt Flag. -O2 might be save, -O3 sometimes gives troubles 37 | OPT_FLAG := -Os 38 | #OPT_FLAG = -g 39 | 40 | # Linker Flags 41 | #LINKER_FLAG = -g 42 | LINKER_FLAG := -Os -s 43 | 44 | # paths 45 | PREFIX := /usr/local 46 | MANPREFIX := $(PREFIX)/share/man 47 | 48 | X11INC := /usr/X11R6/include 49 | X11LIB := /usr/X11R6/lib 50 | 51 | # Executables 52 | 53 | # pkg-config 54 | PKG_CONFIG := pkg-config 55 | 56 | # compiler and linker 57 | CC := gcc 58 | 59 | # gcc options 60 | OPTIONS := -Wall 61 | 62 | # enable bzip2 fonts 63 | #OPTIONS += -DWITHBZIP2 -lbz2 64 | 65 | 66 | -------------------------------------------------------------------------------- /dist/debian/DEBIAN/control: -------------------------------------------------------------------------------- 1 | Package: slterm 2 | Version: VERSION 3 | Section: base 4 | Priority: optional 5 | Architecture: all 6 | Maintainer: misc147 7 | Depends: libfreetype6, libxft2, libfontconfig1, fonts-liberation 8 | Description: slterm - slim terminal for X 9 | 10 | -------------------------------------------------------------------------------- /dist/debian/DEBIAN/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | tic -sx - << ENDINFO 6 | slterm| slimterm, 7 | acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssltermtuuvvwwxxyyzz{{||}}~~, 8 | am, 9 | bce, 10 | bel=^G, 11 | blink=\E[5m, 12 | bold=\E[1m, 13 | cbt=\E[Z, 14 | cvvis=\E[?25h, 15 | civis=\E[?25l, 16 | clear=\E[H\E[2J, 17 | cnorm=\E[?12l\E[?25h, 18 | colors#8, 19 | cols#80, 20 | cr=^M, 21 | csr=\E[%i%p1%d;%p2%dr, 22 | cub=\E[%p1%dD, 23 | cub1=^H, 24 | cud1=^J, 25 | cud=\E[%p1%dB, 26 | cuf1=\E[C, 27 | cuf=\E[%p1%dC, 28 | cup=\E[%i%p1%d;%p2%dH, 29 | cuu1=\E[A, 30 | cuu=\E[%p1%dA, 31 | dch=\E[%p1%dP, 32 | dch1=\E[P, 33 | dim=\E[2m, 34 | dl=\E[%p1%dM, 35 | dl1=\E[M, 36 | ech=\E[%p1%dX, 37 | ed=\E[J, 38 | el=\E[K, 39 | el1=\E[1K, 40 | enacs=\E)0, 41 | flash=\E[?5h$<80/>\E[?5l, 42 | fsl=^G, 43 | home=\E[H, 44 | hpa=\E[%i%p1%dG, 45 | hs, 46 | ht=^I, 47 | hts=\EH, 48 | ich=\E[%p1%d@, 49 | il1=\E[L, 50 | il=\E[%p1%dL, 51 | ind=^J, 52 | indn=\E[%p1%dS, 53 | invis=\E[8m, 54 | is2=\E[4l\E>\E[?1034l, 55 | it#8, 56 | kel=\E[1;2F, 57 | ked=\E[1;5F, 58 | ka1=\E[1~, 59 | ka3=\E[5~, 60 | kc1=\E[4~, 61 | kc3=\E[6~, 62 | kbs=\177, 63 | kcbt=\E[Z, 64 | kb2=\EOu, 65 | kcub1=\EOD, 66 | kcud1=\EOB, 67 | kcuf1=\EOC, 68 | kcuu1=\EOA, 69 | kDC=\E[3;2~, 70 | kent=\EOM, 71 | kEND=\E[1;2F, 72 | kIC=\E[2;2~, 73 | kNXT=\E[6;2~, 74 | kPRV=\E[5;2~, 75 | kHOM=\E[1;2H, 76 | kLFT=\E[1;2D, 77 | kRIT=\E[1;2C, 78 | kind=\E[1;2B, 79 | kri=\E[1;2A, 80 | kclr=\E[3;5~, 81 | kdl1=\E[3;2~, 82 | kdch1=\E[3~, 83 | kich1=\E[2~, 84 | kend=\E[4~, 85 | kf1=\EOP, 86 | kf2=\EOQ, 87 | kf3=\EOR, 88 | kf4=\EOS, 89 | kf5=\E[15~, 90 | kf6=\E[17~, 91 | kf7=\E[18~, 92 | kf8=\E[19~, 93 | kf9=\E[20~, 94 | kf10=\E[21~, 95 | kf11=\E[23~, 96 | kf12=\E[24~, 97 | kf13=\E[1;2P, 98 | kf14=\E[1;2Q, 99 | kf15=\E[1;2R, 100 | kf16=\E[1;2S, 101 | kf17=\E[15;2~, 102 | kf18=\E[17;2~, 103 | kf19=\E[18;2~, 104 | kf20=\E[19;2~, 105 | kf21=\E[20;2~, 106 | kf22=\E[21;2~, 107 | kf23=\E[23;2~, 108 | kf24=\E[24;2~, 109 | kf25=\E[1;5P, 110 | kf26=\E[1;5Q, 111 | kf27=\E[1;5R, 112 | kf28=\E[1;5S, 113 | kf29=\E[15;5~, 114 | kf30=\E[17;5~, 115 | kf31=\E[18;5~, 116 | kf32=\E[19;5~, 117 | kf33=\E[20;5~, 118 | kf34=\E[21;5~, 119 | kf35=\E[23;5~, 120 | kf36=\E[24;5~, 121 | kf37=\E[1;6P, 122 | kf38=\E[1;6Q, 123 | kf39=\E[1;6R, 124 | kf40=\E[1;6S, 125 | kf41=\E[15;6~, 126 | kf42=\E[17;6~, 127 | kf43=\E[18;6~, 128 | kf44=\E[19;6~, 129 | kf45=\E[20;6~, 130 | kf46=\E[21;6~, 131 | kf47=\E[23;6~, 132 | kf48=\E[24;6~, 133 | kf49=\E[1;3P, 134 | kf50=\E[1;3Q, 135 | kf51=\E[1;3R, 136 | kf52=\E[1;3S, 137 | kf53=\E[15;3~, 138 | kf54=\E[17;3~, 139 | kf55=\E[18;3~, 140 | kf56=\E[19;3~, 141 | kf57=\E[20;3~, 142 | kf58=\E[21;3~, 143 | kf59=\E[23;3~, 144 | kf60=\E[24;3~, 145 | kf61=\E[1;4P, 146 | kf62=\E[1;4Q, 147 | kf63=\E[1;4R, 148 | khome=\E[1~, 149 | kil1=\E[2;5~, 150 | krmir=\E[2;2~, 151 | knp=\E[6~, 152 | kmous=\E[M, 153 | kpp=\E[5~, 154 | lines#24, 155 | mir, 156 | msgr, 157 | npc, 158 | op=\E[39;49m, 159 | pairs#64, 160 | mc0=\E[i, 161 | mc4=\E[4i, 162 | mc5=\E[5i, 163 | rc=\E8, 164 | rev=\E[7m, 165 | ri=\EM, 166 | ritm=\E[23m, 167 | rmacs=\E(B, 168 | rmcup=\E[?1049l, 169 | rmir=\E[4l, 170 | rmkx=\E[?1l\E>, 171 | rmso=\E[27m, 172 | rmul=\E[24m, 173 | rs1=\Ec, 174 | rs2=\E[4l\E>\E[?1034l, 175 | sc=\E7, 176 | setab=\E[4%p1%dm, 177 | setaf=\E[3%p1%dm, 178 | setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 179 | setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 180 | sgr0=\E[0m, 181 | 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, 182 | sitm=\E[3m, 183 | smacs=\E(0, 184 | smcup=\E[?1049h, 185 | smir=\E[4h, 186 | smkx=\E[?1h\E=, 187 | smso=\E[7m, 188 | smul=\E[4m, 189 | tbc=\E[3g, 190 | tsl=\E]0;, 191 | xenl, 192 | vpa=\E[%i%p1%dd, 193 | # XTerm extensions 194 | rmxx=\E[29m, 195 | smxx=\E[9m, 196 | # tmux extensions, see TERMINFO EXTENSIONS in tmux(1) 197 | Tc, 198 | Ms=\E]52;%p1%s;%p2%s\007, 199 | Se=\E[2 q, 200 | Ss=\E[%p1%d q, 201 | 202 | slterm-256color| slimterm with 256 colors, 203 | use=slterm, 204 | ccc, 205 | colors#256, 206 | oc=\E]104\007, 207 | pairs#32767, 208 | # Nicked from xterm-256color 209 | initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\, 210 | setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, 211 | setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, 212 | 213 | slterm-meta| slimterm with meta key, 214 | use=slterm, 215 | km, 216 | rmm=\E[?1034l, 217 | smm=\E[?1034h, 218 | rs2=\E[4l\E>\E[?1034h, 219 | is2=\E[4l\E>\E[?1034h, 220 | 221 | slterm-meta-256color| slimterm with meta key and 256 colors, 222 | use=slterm-256color, 223 | km, 224 | rmm=\E[?1034l, 225 | smm=\E[?1034h, 226 | rs2=\E[4l\E>\E[?1034h, 227 | is2=\E[4l\E>\E[?1034h, 228 | 229 | ENDINFO 230 | -------------------------------------------------------------------------------- /doc/BLURP.md: -------------------------------------------------------------------------------- 1 | 2 | Unicode encoding needs 4 Bytes per char within st, 3 | and I nearly never need unicode chars in the terminal. 4 | 5 | Same for rgb colors. Stripping them of st spares 6 Bytes per Glyph. 6 | 7 | Before the changes every Glyph needed 15 Bytes, 8 | now it's 4 Bytes. I personally prefer having a quite big (10.000 lines or more) 9 | scrollback buffer, so this is a factor. 10 | Resulting in a faster and more responsive terminal emulation. 11 | 12 | 13 | ![](images/vt-102-1984.jpg) 14 | 15 | 16 | 17 | >(..I'd propose, unicode isn't needed for system administration/ 18 | development at all. You are going to get into all sort of troubles, 19 | when, e.g., you'd be naming files and directories in the root fs 20 | using unicode characters. Furthermore, let's assume, there are, say, 21 | 100.000 instances of st running. Now, on the world. Multiply this 22 | with, umm, 10 MB, multiply with cpu cycles of 100.000 (swapping, and so on), 23 | and . It's not theoretical anymore. Ok. The calculation might be a little bit too easy. 24 | Admittedly, you shouldn't multiply memory and cpu cycles. 25 | Anyways, my point is valid. And there is the computing time to add, 26 | generated by typos. Adding a unicode character in the wrong script could create.. uuh 27 | never mind. But it's a good reason to stick to KISS (keep it simple, stupid..) principles. 28 | Murphy's law will strike, anyways. That's the law..) 29 | 30 | 31 | 32 | So, in my quest to slim down all programs I'm using, 33 | I'm about to strip unicode and utf8 support. 34 | 35 | Yet I managed to get a virtual memory footprint of around 8MB. 36 | Ok. Added all patches, and with the current history of 10k lines, 37 | it's at 12MB. 38 | (>20MB before) 39 | I'm always keeping more than 10 terminals open, 40 | so that sums up. 41 | Every Glyph (char at the screen, with attributes and colors) now 42 | needs 4 Bytes. ( 15 Bytes before stripping unicode and rgb) 43 | 44 | 45 | The smaller memory footprint also pays out in a more responsive 46 | system overall, improving st's speed as well. (3x here) Ok. 47 | I tried hard, to get "benchmarks", the removed unicode support 48 | doesn't profit of. Still, this shows up with a gain of 2x. 49 | 50 | I checked several emulators, closest in terms of performance would be 51 | urxvt. However, testing and comparing more, the speed of urxvt is given 52 | by a (neat) trick. When dumping many chars into the terminal, eg. with cat, 53 | the screen doesn't show every single character. It's more sort of an animation, 54 | showing only enough chars to give the perception of a continous scrolling 55 | terminal. When confronted with, e.g., a `dd if=data bs=1000`; 56 | this cheat doesn't work anymore, dumping the data takes (depending on the size, etc) 57 | up to 20times longer. 58 | st seems to be the fastest terminal emulator available. 59 | 60 | 61 | 62 | The (pseudo) rgb color support is stripped. 63 | Saving 6 Bytes per glyph. 64 | There still is the option to 65 | have "rgb" colors via modifying the indexed 256 color palette, 66 | the default is the ("standardized") xterm 256 color palette. 67 | This slims down the memory usage of the colors from 8 Bytes to 2 Bytes per glyph. 68 | 69 | 70 | ;) To quote Bill, 256 colors ought be enough for everyone. 71 | (Am I confusing something..?..) 72 | 73 | 74 | 75 | ![](images/noticket.jpg) 76 | 77 | 78 | -------------------------------------------------------------------------------- /doc/ansi_escape_sequences.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Some of the ansi escape sequences, 5 | also documented in ./doc/.. 6 | 7 | Available colors can be displayed with the script ansicolors.sh in ./test 8 | 9 | 10 | COLORS 11 | ------ 12 | 13 | '\e[X1m' 14 | '\e[X1;X2m' 15 | '\e[X1;X2;X3m' 16 | ... 17 | 18 | 19 | X1..X defines color and attributes. 20 | 21 | 22 | 30..37: foreground color 23 | 40..47: background color 24 | 25 | colors, in order: 26 | 27 | black 28 | red 29 | green 30 | yellow(brown) 31 | blue 32 | magenta 33 | cyan 34 | white(gray) 35 | 36 | 90..97: bold fg color 37 | 100..107: bold bg color 38 | 39 | 40 | ATTRIBUTES 41 | ---------- 42 | 43 | 0 clear all attributes 44 | 1 bold 45 | 2 faint 46 | 3 cursive 47 | 4 underline 48 | 5 blink 49 | 6 blink 50 | 7 reverse 51 | 9 strikethrough 52 | 21 double underline 53 | 54 | 55 | attributes can be combined, also 1 and 2 (=bold_faint) 56 | combining blink and reverse blinks by reversing 57 | foreground and background colors. 58 | strikethrough and underline gets double underline 59 | 60 | 61 | 62 | 255 COLORS 63 | ---------- 64 | 65 | foreground: '\e[38;5;XXm' 66 | 67 | xx one of 16-255 68 | 69 | background: '\e[48;5;XXm' 70 | 71 | 72 | 73 | CURSOR 74 | ------ 75 | 76 | '\e[X q' 77 | 78 | standard (no blinking): 79 | 1,2: block cursor 80 | 3,4: underline 81 | 5,6: vertical bar 82 | 83 | slterm: 84 | 7: 'X' 85 | 7;Y: Y is the ascii code of the char, used as cursor 86 | 8: double underline 87 | 9: empty block 88 | 10: underline, two lines at the sides 89 | 11: underline and overline, lines right and left 90 | 12: overline, lines right and left 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /doc/ascii-controlchars-vt102.txt: -------------------------------------------------------------------------------- 1 | VT100.net VT102 User Guide 2 | 3 | -------------------------------------------------------------------------- 4 | 5 | Table 5-2 Control Characters Recognized by VT102 6 | Character Mnemonic Octal Code Function 7 | -------------------------------------------------------------------------- 8 | Null NUL 000 Ignored when received (not 9 | stored in input buffer) and 10 | used as a fill character. 11 | End of text ETX 003 Can be selected as a 12 | half-duplex turnaround 13 | character. 14 | End of transmission EOT 004 Can be selected as a 15 | disconnect character or 16 | half-duplex turnaround 17 | character. When used as a 18 | turnaround character, the 19 | disconnect character is 20 | DLE-EOT. 21 | Enquire ENQ 005 Transmits answerback message. 22 | Bell BEL 007 Generates bell tone. 23 | Backspace BS 010 Moves cursor to the left one 24 | character position; if cursor 25 | is at left margin, no action 26 | occurs. 27 | Horizontal tab HT 011 Moves cursor to next tab 28 | stop, or to right margin if 29 | there are no more tab stops. 30 | Linefeed LF 012 Causes a linefeed or a new 31 | line operation. (See 32 | Linefeed/New Line). Also 33 | causes printing if auto print 34 | operation is selected. 35 | Vertical tab VT 013 Processed as LF. 36 | Form feed FF 014 Processed as LF. FF can also 37 | be selected as a half-duplex 38 | turnaround character. 39 | Carriage return CR 015 Moves cursor to left margin 40 | on current line. CR can also 41 | be selected as a half-duplex 42 | turnaround character. 43 | Shift out SO 016 Selects G1 character set 44 | designated by a select 45 | character set sequence. 46 | Shift in SI 017 Selects G0 character set 47 | designated by a select 48 | character set sequence. 49 | Device control 1 DC1 021 Processed as XON. DC1 causes 50 | terminal to continue 51 | transmitting characters. 52 | Device control 3 DC3 023 Processed as XOFF. DC3 causes 53 | terminal to stop transmitting 54 | all characters except XOFF 55 | and XON. DC3 can also be 56 | selected as a half-duplex 57 | turnaround character. 58 | Cancel CAN 030 If received during an escape 59 | or control sequence, cancels 60 | the sequence and displays 61 | substitution character 62 | ([4][]). 63 | Substitute SUB 032 Processed as CAN. 64 | Escape ESC 033 Processed as a sequence 65 | introducer. 66 | 67 | 68 | -------------------------------------------------------------------------- 69 | 70 | 71 | source: 72 | VT100.net VT102 User Guide 73 | http://vt100.net/docs/vt102-ug/table5-2.html 74 | 75 | -------------------------------------------------------------------------------- /doc/ascii_0-127.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/doc/ascii_0-127.png -------------------------------------------------------------------------------- /doc/ascii_0-127.txt: -------------------------------------------------------------------------------- 1 | VT100.net VT220 Programmer Reference Manual 2 | 3 | 4 | Table 2-3: DEC Multinational Character Set (C0 and GL Codes) 5 | +-----+---------------+----------+-------------+---------+---------+---------+---------+---------+-----------+ 6 | | | COLUMN | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 7 | | +---------------+----------+-------------+---------+---------+---------+---------+---------+-----------+ 8 | | |b8 BITS |0 |0 |0 |0 |0 |0 |0 |0 | 9 | | | b7 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 10 | | | b6 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 11 | | | b5 | 0| 1 | 0| 1| 0| 1| 0| 1 | 12 | | ROW|b4 b3 b2 b1 | | | | | | | | | 13 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 14 | | | | |0 | |20 | |40 | |60 | |100 | |120 | |140 | |160 | 15 | | 0|0 0 0 0 |NUL |0 |DLE |16 |SP |32 |0 |48 |@ |64 |P |80 |` |96 |p |112 | 16 | | | | |0 | |10 | |20 | |30 | |40 | |50 | |60 | |70 | 17 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 18 | | | | |1 |DC1 |21 | |41 | |61 | |101 | |121 | |141 | |161 | 19 | | 1|0 0 0 1 |SOH |1 |(XON) |17 |! |33 |1 |49 |A |65 |Q |81 |a |97 |q |113 | 20 | | | | |1 | |11 | |21 | |31 | |41 | |51 | |61 | |71 | 21 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 22 | | | | |2 | |22 | |42 | |62 | |102 | |122 | |142 | |162 | 23 | | 2|0 0 1 0 |STX |2 |DC2 |18 |" |34 |2 |50 |B |66 |R |82 |b |98 |r |114 | 24 | | | | |2 | |12 | |22 | |32 | |42 | |52 | |62 | |72 | 25 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 26 | | | | |3 |DC3 |23 | |43 | |63 | |103 | |123 | |143 | |163 | 27 | | 3|0 0 1 1 |ETX |3 |(XOFF) |19 |# |35 |3 |51 |C |67 |S |83 |c |99 |s |115 | 28 | | | | |3 | |13 | |23 | |33 | |43 | |53 | |63 | |73 | 29 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 30 | | | | |4 | |24 | |44 | |64 | |104 | |124 | |144 | |164 | 31 | | 4|0 1 0 0 |EOT |4 |DC4 |20 |$ |36 |4 |52 |D |68 |T |84 |d |100 |t |116 | 32 | | | | |4 | |14 | |24 | |34 | |44 | |54 | |64 | |74 | 33 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 34 | | | | |5 | |25 | |45 | |65 | |105 | |125 | |145 | |165 | 35 | | 5|0 1 0 1 |ENQ |5 |NAK |21 |% |37 |5 |53 |E |69 |U |85 |e |101 |u |117 | 36 | | | | |5 | |15 | |25 | |35 | |45 | |55 | |65 | |75 | 37 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 38 | | | | |6 | |26 | |46 | |66 | |106 | |126 | |146 | |166 | 39 | | 6|0 1 1 0 |ACK |6 |SYN |22 |& |38 |6 |54 |F |70 |V |86 |f |102 |v |118 | 40 | | | | |6 | |16 | |26 | |36 | |46 | |56 | |66 | |76 | 41 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 42 | | | | |7 | |27 | |47 | |67 | |107 | |127 | |147 | |167 | 43 | | 7|0 1 1 1 |BEL |7 |ETB |23 |' |39 |7 |55 |G |71 |W |87 |g |103 |w |119 | 44 | | | | |7 | |17 | |27 | |37 | |47 | |57 | |67 | |77 | 45 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 46 | | | | |10 | |30 | |50 | |70 | |110 | |130 | |150 | |170 | 47 | | 8|1 0 0 0 |BS |8 |CAN |24 |( |40 |8 |56 |H |72 |X |88 |h |104 |x |120 | 48 | | | | |8 | |18 | |28 | |38 | |48 | |58 | |68 | |78 | 49 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 50 | | | | |11 | |31 | |51 | |71 | |111 | |131 | |151 | |171 | 51 | | 9|1 0 0 1 |HT |9 |EM |25 |) |41 |9 |57 |I |73 |Y |89 |i |105 |y |121 | 52 | | | | |9 | |19 | |29 | |39 | |49 | |59 | |69 | |79 | 53 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 54 | | | | |12 | |32 | |52 | |72 | |112 | |132 | |152 | |172 | 55 | | 10|1 0 1 0 |LF |10 |SUB |26 |* |42 |: |58 |J |74 |Z |90 |j |106 |z |122 | 56 | | | | |A | |1A | |2A | |3A | |4A | |5A | |6A | |7A | 57 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 58 | | | | |13 | |33 | |53 | |73 | |113 | |133 | |153 | |173 | 59 | | 11|1 0 1 1 |VT |11 |ESC |27 |+ |43 |; |59 |K |75 |[ |91 |k |107 |{ |123 | 60 | | | | |B | |1B | |2B | |3B | |4B | |5B | |6B | |7B | 61 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 62 | | | | |14 | |34 | |54 | |74 | |114 | |134 | |154 | |174 | 63 | | 12|1 1 0 0 |FF |12 |FS |28 |, |44 |< |60 |L |76 |\ |92 |l |108 || |124 | 64 | | | | |C | |1C | |2C | |3C | |4C | |5C | |6C | |7C | 65 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 66 | | | | |15 | |35 | |55 | |75 | |115 | |135 | |155 | |175 | 67 | | 13|1 1 0 1 |CR |13 |GS |29 |- |45 |= |61 |M |77 |] |93 |m |109 |} |125 | 68 | | | | |D | |1D | |2D | |3D | |4D | |5D | |6D | |7D | 69 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 70 | | | | |16 | |36 | |56 | |76 | |116 | |136 | |156 | |176 | 71 | | 14|1 1 1 0 |SO |14 |RS |30 |. |46 |> |62 |N |78 |^ |94 |n |110 |~ |126 | 72 | | | | |E | |1E | |2E | |3E | |4E | |5E | |6E | |7E | 73 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 74 | | | | |17 | |37 | |57 | |77 | |117 | |137 | |157 | |177 | 75 | | 15|1 1 1 1 |SI |15 |US |31 |/ |47 |? |63 |O |79 |_ |95 |o |111 |DEL |127 | 76 | | | | |F | |1F | |2F | |3F | |4F | |5F | |6F | |7F | 77 | +-----+---------------+-----+----+--------+----+----+----+----+----+---+-----+---+-----+---+-----+-----+-----+ 78 | | |C0 CODES |GL CODES | 79 | | | |(ASCII GRAPHICS) | 80 | +---------------------+------------------------+-------------------------------------------------------------+ 81 | 82 | 83 | KEY 84 | +-----+----+ 85 | | | 33 | OCTAL 86 | CHARACTER | ESC | 27 | DECIMAL 87 | | | 1B | HEX 88 | +-----+----+ 89 | 90 | -------------------------------------------------------------------------- 91 | 92 | 93 | source 94 | VT100.net VT220 Programmer Reference Manual 95 | http://vt100.net/docs/vt220-rm/table2-3a.html 96 | 97 | -------------------------------------------------------------------------------- /doc/ascii_128-255.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/doc/ascii_128-255.png -------------------------------------------------------------------------------- /doc/fontconfig.txt: -------------------------------------------------------------------------------- 1 | 2 | Copied from the documentation of fontconfig 3 | 4 | 5 | Font Pattern, possible settings 6 | 7 | -------------------------------------------------------------- 8 | 9 | antialias Bool Whether glyphs can be antialiased 10 | aspect Double Stretches glyphs horizontally before hinting 11 | autohint Bool Use autohinter instead of normal hinter 12 | capability String List of layout capabilities in the font 13 | charset CharSet Unicode chars encoded by the font 14 | color Bool Whether any glyphs have color 15 | decorative Bool Whether the style is a decorative variant 16 | dpi Double Target dots per inch 17 | embeddedbitmap Bool Use the embedded bitmap instead of the outline 18 | embolden Bool Rasterizer should synthetically embolden the font 19 | family String Font family names 20 | familylang String Languages corresponding to each family 21 | file String The filename holding the font 22 | fontfeatures String List of the feature tags in OpenType to be enabled 23 | fontformat String String name of the font format 24 | fontversion Int Version number of the font 25 | foundry String Font foundry name 26 | ftface FT_Face Use the specified FreeType face object 27 | fullname String Font full names (often includes style) 28 | fullnamelang String Languages corresponding to each fullname 29 | globaladvance Bool Use font global advance data (deprecated) 30 | hinting Bool Whether the rasterizer should use hinting 31 | hintstyle Int Automatic hinting style 32 | index Int The index of the font within the file 33 | lang String List of RFC-3066-style languages this font supports 34 | lcdfilter Int Type of LCD filter 35 | minspace Bool Eliminate leading from line spacing 36 | namelang String Language name, default value of familylang, stylelang, fullnamelang 37 | outline Bool Whether the glyphs are outlines 38 | pixelsize Double Pixel size 39 | postscriptname String Font family name in PostScript 40 | prgname String String Name of the running program 41 | rasterizer String Which rasterizer is in use (deprecated) 42 | rgba Int unknown, rgb, bgr, vrgb, vbgr, none - subpixel geometry 43 | scalable Bool Whether glyphs can be scaled 44 | scale Double Scale factor for point->pixel conversions (deprecated) 45 | size Double Point size 46 | slant Int Italic, oblique or roman 47 | spacing Int Proportional, dual-width, monospace or charcell 48 | style String Font style. Overrides weight and slant 49 | stylelang String Languages corresponding to each style 50 | verticallayout Bool Use vertical layout 51 | weight Int Light, medium, demibold, bold or black 52 | width Int Condensed, normal or expanded 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /doc/old/README: -------------------------------------------------------------------------------- 1 | old docs, 2 | more or less irrelevant 3 | -------------------------------------------------------------------------------- /doc/old/cheatsheet.md: -------------------------------------------------------------------------------- 1 | ## Short ref 2 | 3 | #### Keys: 4 | 5 | 6 | 7 | Shift+Insert: Insert from Clipboard 8 | 9 | Ctrl+Shift+S: Enter Selectmode - goto a place on screen, start selecting with 's', 10 | end selection with enter and copy contents to clipboard 11 | 12 | Ctrl+Alt+[0-9]: set bookmark in history 13 | Ctrl+[0-9]: goto bookmark 14 | 15 | Shift+Return: Set mark, when the output of the current command 16 | exceeds one page, go into lessmode 17 | 18 | Shift+Backspace: Go back in history to the location of the last command 19 | 20 | 21 | Ctrl+Shift+[ l / Up / PageUp ]: Enter lessmode (Cursorkeys scroll up/down) 22 | 23 | Alt+Shift+[ PageUp / PageDown ]: Enlarge/Shrink fontsize 24 | Alt+Shift+[ Insert / Delete ]: Enlarge/Shrink font width 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /doc/patches-applied: -------------------------------------------------------------------------------- 1 | anysize 2 | clipboard 3 | relativeborder 4 | scrollback 5 | scrollback-mouse 6 | scrollback-mouse-increment 7 | selectioncolors 8 | vim_browse 9 | xresources (only optional, via switch -x on) 10 | 11 | //st-keyboard-select in suckless dir 12 | 13 | 14 | omitted: 15 | newterm ( doesn't detach->parent killed->child too ) 16 | vertcenter ( somehow doesn't look right) 17 | 18 | -------------------------------------------------------------------------------- /images/ascii.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/images/ascii.png -------------------------------------------------------------------------------- /images/colors-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/images/colors-bold.png -------------------------------------------------------------------------------- /images/colors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/images/colors.png -------------------------------------------------------------------------------- /images/indexed_colors.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/images/indexed_colors.jpg -------------------------------------------------------------------------------- /images/indexed_fgcolors.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/images/indexed_fgcolors.jpg -------------------------------------------------------------------------------- /images/noticket.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/images/noticket.jpg -------------------------------------------------------------------------------- /images/st-asc_with_i3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/images/st-asc_with_i3.png -------------------------------------------------------------------------------- /images/vt-102-1984.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/images/vt-102-1984.jpg -------------------------------------------------------------------------------- /src/base64.c: -------------------------------------------------------------------------------- 1 | #ifndef BASE64_C 2 | #define BASE64_C 3 | // base64 coding/decoding 4 | 5 | 6 | #include "mem.h" 7 | #include "includes.h" 8 | 9 | static const char base64_digits[] = { 10 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12 | 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 13 | 61, 0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 14 | 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 15 | 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 16 | 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23 | 0, 0, 0, 0, 0, 0, 0, 0}; 24 | 25 | char base64dec_getc(const char **src) { 26 | while (**src && !isprint(**src)) { 27 | (*src)++; 28 | } 29 | return **src ? *((*src)++) : '='; /* emulate padding if string ends */ 30 | } 31 | 32 | char *base64dec(const char *src) { 33 | size_t in_len = strlen(src); 34 | char *result, *dst; 35 | 36 | if (in_len % 4) { 37 | in_len += 4 - (in_len % 4); 38 | } 39 | result = dst = xmalloc(in_len / 4 * 3 + 1); 40 | while (*src) { 41 | int a = base64_digits[(unsigned char)base64dec_getc(&src)]; 42 | int b = base64_digits[(unsigned char)base64dec_getc(&src)]; 43 | int c = base64_digits[(unsigned char)base64dec_getc(&src)]; 44 | int d = base64_digits[(unsigned char)base64dec_getc(&src)]; 45 | 46 | /* invalid input. 'a' can be -1, e.g. if src is "\n" (c-str) */ 47 | if (a == -1 || b == -1) { 48 | break; 49 | } 50 | 51 | *dst++ = (a << 2) | ((b & 0x30) >> 4); 52 | if (c == -1) { 53 | break; 54 | } 55 | *dst++ = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2); 56 | if (d == -1) { 57 | break; 58 | } 59 | *dst++ = ((c & 0x03) << 6) | d; 60 | } 61 | *dst = '\0'; 62 | return result; 63 | } 64 | 65 | 66 | #endif 67 | 68 | -------------------------------------------------------------------------------- /src/base64.h: -------------------------------------------------------------------------------- 1 | #ifndef base64_h 2 | #define base64_h 3 | 4 | 5 | char *base64dec(const char *src); 6 | 7 | 8 | 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/build/.emptydir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/src/build/.emptydir -------------------------------------------------------------------------------- /src/charmaps.c: -------------------------------------------------------------------------------- 1 | 2 | // convert runes from current charmap to unicode 3 | static inline uint charmap_convert(uint rune,uint attribute){ 4 | // 1252 / dec-mcs / ansi 5 | //if ( rune > 0x7f && (rune < 0xA0) ) 6 | // return( cp1252[rune-0x80] ); 7 | if ( rune > 0x7f && (rune < 0x100) ) 8 | return( codepage[selected_codepage][rune-0x80] ); 9 | 10 | // greek (1st try - need beta code translation table) 11 | //if ( attribute & ATTR_REVERSE ){ 12 | // return( rune+(0x390 - 0x40) ); 13 | //} 14 | 15 | //if ( attribute & ATTR_BLINK ){ 16 | // return( rune+(0x1D44e - 0x40) ); 17 | //} 18 | 19 | return(rune); 20 | } 21 | 22 | // reverse table, to convert and display utf8 in the selected codepage 23 | // works obviously only once, when the runes are created. 24 | // Later, a redraw or repaste is needed. 25 | void create_unicode_table(){ 26 | memset(uni_to_cp,0,UNITABLE); 27 | for ( int a = 0; a<128; a++ ) 28 | if ( codepage[selected_codepage][a] < UNITABLE ) 29 | uni_to_cp[codepage[selected_codepage][a]]= a+128; 30 | } 31 | 32 | char unicode_to_charmap( uint uc ){ 33 | if ( uc < UNITABLE ){ 34 | if ( uni_to_cp[uc] ) 35 | return( uni_to_cp[uc] ); 36 | } else { 37 | // search our charmap table 38 | // currently not needed, all unicode points are below UNITABLE (=0x2600) 39 | } 40 | 41 | return(0); 42 | } 43 | 44 | // callback, called by keystroke 45 | void set_charmap(const Arg *a){ 46 | if ( a->i < sizeof(codepage)/sizeof(uint*)){ 47 | selected_codepage = a->i; 48 | create_unicode_table(); 49 | 50 | fill_font_asciitable(&dc.font); 51 | if ( useboldfont ) 52 | fill_font_asciitable(&dc.bfont); 53 | if ( useitalicfont ) 54 | fill_font_asciitable(&dc.ifont); 55 | if ( usebolditalicfont ) 56 | fill_font_asciitable(&dc.ibfont); 57 | 58 | 59 | redraw(); 60 | } 61 | 62 | } 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/charmaps.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/src/charmaps.h -------------------------------------------------------------------------------- /src/colors.h: -------------------------------------------------------------------------------- 1 | #ifndef colors_h 2 | #define colors_h 3 | // color related functions and definitions 4 | 5 | // number of colors to cache 6 | #define COLORCACHESIZE 64 7 | 8 | 9 | #define FOR_RGB(_do) _do(red);_do(green);_do(blue) 10 | 11 | #define INVERT_COLOR(_color) _color.red = ~_color.red; _color.green = ~_color.green; _color.blue = ~_color.blue 12 | 13 | #ifndef UTF8 14 | #define IS_TRUECOL(x)(0) 15 | #define TRUECOLOR(r,g,b) (0) 16 | #else 17 | #define TRUECOLOR(r, g, b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) 18 | #define IS_TRUECOL(x) (1 << 24 & (x)) 19 | #endif 20 | 21 | #define TRUERED(x) (((x)&0xff0000) >> 8) 22 | #define TRUEGREEN(x) (((x)&0xff00)) 23 | #define TRUEBLUE(x) (((x)&0xff) << 8) 24 | 25 | 26 | 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /src/colors.sh: -------------------------------------------------------------------------------- 1 | export BLACK=""$'\033[30m'"" 2 | export BGBLACK=""$'\033[40m'"" 3 | export GRAY=""$'\033[01;30m'"" 4 | export LGREEN=""$'\033[01;32m'"" 5 | export GREEN=""$'\033[32m'"" 6 | export BGGREEN=""$'\033[42m'"" 7 | export LRED=""$'\033[01;31m'"" 8 | export RED=""$'\033[31m'"" 9 | export BGRED=""$'\033[41m'"" 10 | export YELLOW=""$'\033[01;33m'"" 11 | export BROWN=""$'\033[33m'"" 12 | export BGYELLOW=""$'\033[43m'"" 13 | export LBLUE=""$'\033[01;34m'"" 14 | export BLUE=""$'\033[34m'"" 15 | export BGBLUE=""$'\033[44m'"" 16 | export PINK=""$'\033[01;35m'"" 17 | export MAGENTA=""$'\033[00;35m'"" 18 | export BGMAGENTA=""$'\033[45m'"" 19 | export LMAGENTA=""$'\033[01;35m'"" 20 | export CYAN=""$'\033[36m'"" 21 | export BGCYAN=""$'\033[46m'"" 22 | export LCYAN=""$'\033[01;36m'"" 23 | export WHITE=""$'\033[01;37m'"" 24 | export BGWHITE=""$'\033[47m'"" 25 | export LGRAY=""$'\033[37m'"" 26 | 27 | export NORM=""$'\033[0;0m'"" 28 | export N=$NORM 29 | export BOLD=""$'\033[1m'"" 30 | export FAINT=""$'\033[2m'"" 31 | export CURSIVE=""$'\033[3m'"" 32 | export UNDERLINE=""$'\033[4m'"" 33 | export UL=$UNDERLINE 34 | export BLINK=""$'\033[5m'"" 35 | export INVERTED=""$'\033[7m'"" 36 | export INVERSE=""$'\033[7m'"" 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/controlchars.h: -------------------------------------------------------------------------------- 1 | 2 | // handle control chars and sequences, ansi escape sequences. 3 | // 4 | 5 | #pragma once 6 | 7 | #define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == 0x7f) // 0x7f = delete 8 | 9 | //#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) 10 | #define ISCONTROLC1(c) (0) 11 | 12 | #define ISCONTROL(c) ((c <= 0x1f) || (c==0x7f)) 13 | //#define ISCONTROL(c) ((c <= 0x1f) || BETWEEN(c, 0x7f, 0x9f)) 14 | //#define ISCONTROL(c) (0) 15 | 16 | 17 | 18 | 19 | #define ESC_BUF_SIZ (256 * UTF_SIZ) // UTF_SIZ is 4 with utf8, 1 without 20 | #define ESC_ARG_SIZ 16 21 | #define STR_BUF_SIZ ESC_BUF_SIZ 22 | #define STR_ARG_SIZ ESC_ARG_SIZ 23 | 24 | 25 | enum escape_state { 26 | ESC_START = 1, 27 | ESC_CSI = 2, 28 | ESC_STR = 4, /* OSC, PM, APC */ 29 | ESC_ALTCHARSET = 8, 30 | ESC_STR_END = 16, /* a final string was encountered */ 31 | ESC_TEST = 32, /* Enter in test mode */ 32 | ESC_UTF8 = 64, 33 | ESC_DCS = 128, 34 | }; 35 | 36 | 37 | 38 | /* CSI Escape sequence structs */ 39 | /* ESC '[' [[ [] [;]] []] */ 40 | typedef struct { 41 | char buf[ESC_BUF_SIZ]; /* raw string */ 42 | size_t len; /* raw string length */ 43 | char priv; 44 | int arg[ESC_ARG_SIZ]; 45 | int narg; /* nb of args */ 46 | char mode[2]; 47 | } CSIEscape; 48 | 49 | /* STR Escape sequence structs */ 50 | /* ESC type [[ [] [;]] ] ESC '\' */ 51 | typedef struct { 52 | char type; /* ESC type ... */ 53 | char *buf; /* allocated raw string */ 54 | size_t siz; /* allocation size */ 55 | size_t len; /* raw string length */ 56 | char *args[STR_ARG_SIZ]; 57 | int narg; /* nb of args */ 58 | } STREscape; 59 | 60 | 61 | 62 | #ifdef UTF8 63 | int handle_controlchars( Rune u, uint decoded_len, char* decoded_char ); 64 | #else 65 | int _handle_controlchars( Rune u ); 66 | #define handle_controlchars( _rune, ... ) _handle_controlchars( _rune ) 67 | #endif 68 | 69 | 70 | static void tdefutf8(utfchar); 71 | static void tdeftran(utfchar); 72 | static void tsetmode(int, int, int *, int); 73 | 74 | static void tstrsequence(uchar); 75 | static void tcontrolcode(uchar); 76 | 77 | 78 | static void csidump(void); 79 | static void csihandle(void); 80 | static void csiparse(void); 81 | static void csireset(void); 82 | static int eschandle(uchar); 83 | 84 | static void strdump(void); 85 | static void strparse(void); 86 | static void strreset(void); 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /src/embed/README: -------------------------------------------------------------------------------- 1 | The fonts LiberationMono_Bold and LiberationMono_BoldItalic, 2 | to be optionally embedded into the binary. 3 | 4 | The files are renamed to slterm_font.ttf and slterm_font_italic.ttf, 5 | regardless of their weight, I prefer bold fonts at the terminal. 6 | "Bold" is shown as bright color instead. 7 | 8 | This can be changed in config.h 9 | 10 | 11 | I suggest to install those Liberation fonts when installing slterm, 12 | if not already present. 13 | 14 | 15 | Anyways, to have a working font especially with the statically linked binary, 16 | they can be embedded. (+400kB) 17 | 18 | 19 | The empty ttf files are needed anyways for the build process. 20 | 21 | 22 | To change the embedded fonts, copy the ttf font files into this directory, 23 | overwriting the existing ttf files, 24 | update the size of the uncompressed ttf files in embed_fonts.h, 25 | (manually or execute updatesizes.sh) 26 | and rerun make. (set EMBEDFONT := 1 in config.make, or `make static_embedfont`) 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/embed/embed_font.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | // Exact size of the decompressed fonts in bytes. 5 | // Need to be updated when the fonts are changed 6 | unsigned int slterm_font_ttf_len = 303656; 7 | unsigned int slterm_font_italic_ttf_len = 279668; 8 | unsigned int slterm_font_bold_ttf_len = 0; 9 | unsigned int slterm_font_bold_italic_ttf_len = 0; 10 | 11 | 12 | extern unsigned int slterm_font_ttfz_len; 13 | extern unsigned char slterm_font_ttfz[]; 14 | 15 | 16 | extern unsigned int slterm_font_italic_ttfz_len; 17 | extern unsigned char slterm_font_italic_ttfz[]; 18 | 19 | extern unsigned int slterm_font_bold_ttfz_len; 20 | extern unsigned char slterm_font_bold_ttfz[]; 21 | 22 | extern unsigned int slterm_font_bold_italic_ttfz_len; 23 | extern unsigned char slterm_font_bold_italic_ttfz[]; 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/embed/slterm_font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/src/embed/slterm_font.ttf -------------------------------------------------------------------------------- /src/embed/slterm_font_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/src/embed/slterm_font_bold.ttf -------------------------------------------------------------------------------- /src/embed/slterm_font_bold_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/src/embed/slterm_font_bold_italic.ttf -------------------------------------------------------------------------------- /src/embed/slterm_font_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/src/embed/slterm_font_italic.ttf -------------------------------------------------------------------------------- /src/embed/updatesizes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in *ttf 4 | do 5 | echo $i 6 | sed -Ei "s/("$i"_len = ).*/\1"`stat $i -c %s`";/" embed_font.h 7 | done 8 | -------------------------------------------------------------------------------- /src/fonts.h: -------------------------------------------------------------------------------- 1 | #ifndef fonts_h 2 | #define fonts_h 3 | 4 | 5 | #include 6 | 7 | #include "xevent.h" 8 | #include "term.h" 9 | 10 | typedef XftGlyphFontSpec GlyphFontSpec; 11 | 12 | 13 | //extern char *usedfont; 14 | 15 | 16 | /* Font structure */ 17 | #define Font Font_ 18 | typedef struct { 19 | #ifndef UTF8 20 | int asciitable[256]; // cache codepoints 21 | #endif 22 | int height; 23 | int width; 24 | int ascent; 25 | int descent; 26 | int badslant; 27 | int badweight; 28 | short lbearing; 29 | short rbearing; 30 | XftFont *match; 31 | FcFontSet *set; 32 | FcPattern *pattern; 33 | } Font; 34 | 35 | // font cache. growing array. no ring. as stated below. 36 | // in theory, this shouldn't be global, the cache depends 37 | // on the used font. 38 | enum { FRC_NORMAL, FRC_ITALIC, FRC_BOLD, FRC_ITALICBOLD }; 39 | 40 | typedef struct { 41 | XftFont *font; 42 | int flags; 43 | Rune unicodep; 44 | } Fontcache; 45 | 46 | /* Fontcache is an array now. A new font will be appended to the array. */ 47 | Fontcache *frc = NULL; 48 | int frclen = 0; 49 | int frccap = 0; 50 | 51 | 52 | // callbacks 53 | void set_fontwidth( const Arg *a ); 54 | void set_fontheight( const Arg *a ); 55 | void zoom(const Arg *); 56 | void zoomabs(const Arg *); 57 | void zoomreset(const Arg *); 58 | 59 | 60 | int noutf8_xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); 61 | int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); 62 | 63 | 64 | int xloadfont(Font *, FcPattern *, int pixelsize, const char* filename); 65 | 66 | void xloadfonts(double); 67 | void xunloadfont(Font *); 68 | void xunloadfonts(void); 69 | 70 | 71 | void fill_font_asciitable(Font *f); 72 | 73 | #endif 74 | 75 | -------------------------------------------------------------------------------- /src/globals.c: -------------------------------------------------------------------------------- 1 | // globals. 2 | 3 | // need to check, in which files they are used. 4 | 5 | 6 | // pid of executed shell 7 | pid_t shellpid; 8 | 9 | Term *term=0; 10 | Term *p_term=0; 11 | Term *p_help=0; 12 | Term *p_help_storedterm=0; 13 | Term *p_alt=0; 14 | 15 | 16 | // term.c 17 | int enterlessmode; 18 | 19 | 20 | XWindow xwin; 21 | TermWindow twin; 22 | 23 | 24 | 25 | 26 | // in selection.c 27 | //Selection sel; 28 | //XSelection xsel; 29 | 30 | 31 | 32 | 33 | // dummy functions, to remove dependencies on unused libraries 34 | 35 | 36 | // overwrite the (only) dependency of fontconfig to lbintl, and therefore iconv. 37 | // The internationalization is used solely for the font info name. 38 | // adding nearly 1MB to the memory usage 39 | const char *libintl_dgettext( const char* domain, const char* text){ 40 | return(text); 41 | } 42 | 43 | 44 | 45 | #ifndef WITHBZIP2 46 | // bzip2 dummies 47 | // only needed to load bzip2 compressed fonts. (seems so..) 48 | int BZ2_bzDecompressEnd(void*v, int a,int b){ return 0; }; 49 | int BZ2_bzDecompress( void*v ){ return 0; }; 50 | int BZ2_bzDecompressInit( void*v, int a,int b ){ die("bzip2 not linked. remove dummie functions, and relink\n"); return 0; }; 51 | #endif 52 | 53 | 54 | 55 | void XdmcpWrap ( 56 | unsigned char *input, 57 | unsigned char *wrapper, 58 | unsigned char *output, 59 | int bytes) 60 | {}; 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/globals.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/src/globals.h -------------------------------------------------------------------------------- /src/help.h.in: -------------------------------------------------------------------------------- 1 | // the help content. 2 | // It's shown on F1, and compiled into st. 3 | // I guess, it's better to have a help screen always there, 4 | // when to load it (hopefully, when nothing did fuck up). 5 | // Especially, it's maybe 1/100 of the memory usage, 6 | // and furthermore quite possibly shared anyways. 7 | static char* helpcontents = "\ 8 | \n\r\ 9 |  slterm - slim terminal emulator for X \n\r\ 10 | \n\r\ 11 | http://github.com/michael105/slterm\n\r\ 12 | Version: {VERSION}\n\r\ 13 | \n\r\ 14 | \n\r\ 15 |  Help \n\r\ 16 | \n\r\ 17 | \n\r\ 18 | Colors\n\r\ 19 | \n\r\ 20 | \e[1;30mecho -e \"\\e[A;Nm\" text ..\n\r\ 21 | N: fg color 30 - 37, and bg color 40 - 47\n\r\ 22 | \n\r\ 23 | 255 colors\n\r\ 24 | echo -e \"\\e[A;38;5;Nm\" text ...\n\r\ 25 | echo -e \"\\e[0,48,5,Nm text\" for colored background.\n\r\ 26 | N: color 0-255\n\r\ 27 | A: 0=normal, 1=light, 2=dark\n\r\ 28 | \n\r\ 29 | \n\r\ 30 | \n\r\ 31 | -------------------------------------------------------------------------------- /src/help.txt: -------------------------------------------------------------------------------- 1 | $YELLOW Keybinding reference $NORM 2 | 3 | The keycombinations can be changed in config.h(recompile needed) 4 | 5 | For other information please have a look into the man page, 6 | also accessible with 'slterm -H' 7 | 8 | 9 | $YELLOW Keystrokes $NORM 10 | 11 | ${GRAY}There are 4 different modes in slterm; 12 | regular mode, lessmode, selection mode and alt mode(alt screen). 13 | slterm is started in the regular mode. 14 | When the alt mode is used, e.g. by man or links, 15 | scrollmarks and lessmode are disabled. 16 | $N 17 | 18 | $UL${LGREEN}All modes:$N 19 | 20 | Ctrl+Shift + I: Inverse colors 21 | (Anymod)+F1: Show this help 22 | 23 | 24 | ${BOLD}Set font width/size:$N 25 | 26 | Ctrl+Shift + Insert/Delete: Enlarge/Shrink width 27 | Ctrl+Shift + Home/End: Enlarge/Shrink height 28 | Ctrl+Shift + PageUp/PageDown: Zoom in / out 29 | Ctrl+Shift + Backspace: Reset font display 30 | 31 | 32 | ${BOLD}Select Codepage:$N 33 | 34 | Ctrl+Win + 0 CP1250 35 | 1 CP1251 36 | 2 CP1252 ${GRAY}(this is mostly ANSI, and the 1. page of Unicode)$N 37 | 3 CP1253 38 | 4 CP437 ${GRAY}(Old IBM codetable, borders and tables)$N 39 | 5 CP850 ${GRAY}(DOS Standard table)$N 40 | 6 CP4002 ${GRAY}(Custom table, mix of 1252 and 437)$N 41 | 42 | 43 | $BOLD${UL}${LGREEN}Regular mode:$N 44 | 45 | ${BOLD}Scrolling:$N 46 | 47 | Shift + Up/Down/PageUp/Pagedown: Scroll up/down 48 | Shift + Home/End: Scroll to top/bottom 49 | Shift + Backspace: Scroll to the location of the last command (shell) 50 | and enter lessmode 51 | Shift+Enter: Execute command, enter lessmode if more than 52 | one screen is displayed by the command. 53 | 54 | 55 | ${BOLD}Clipboard:$N 56 | 57 | Shift + Insert / Ctrl+Shift + y: Paste 58 | Ctrl+Shift + c / mouse selection: Copy 59 | 60 | 61 | ${BOLD}Scrollmarks:$N 62 | 63 | Ctrl+Alt + [0..9]: Set Scrollmark 0 - 9 64 | Ctrl + [0..9]: Scroll to mark 0 - 9 65 | Shift + Backspace: Scroll to the last entered command (in shell) 66 | 67 | 68 | 69 | $BOLD${UL}${LGREEN}Lessmode:$N 70 | 71 | Alt+Shift + Down/PageDown/Up/PageUp/l, ScrollLock: Enter lessmode. 72 | Scroll around with cursor keys, Home, End. 73 | Backspace/Tab left go to the location of the previous command in shell, 74 | Tab scrolls down to the next entered command location. 75 | Exit with q/ESC 76 | 77 | Shift+Backspace/Tab left: Scroll to the location of the last entered command, 78 | enter lessmode 79 | 80 | Tab: Scroll downwards to the next entered command line 81 | 82 | Ctrl+Alt + [0..9]: Set Scrollmark 0 - 9 83 | Ctrl + [0..9]: Goto Scrollmark 0 - 9 84 | Lessmode: [0..9]: Goto Retmark 1 - 10 85 | 86 | 87 | 88 | $BOLD${UL}${LGREEN}Selection Mode:$N 89 | 90 | Ctrl+Shift + S, Alt + S: Enter selection mode 91 | 92 | There are 3 submodes in selection mode: 93 | - move mode : to set the start of the selection; 94 | - select mode : to activate and set the end of the selection; 95 | - input mode : to enter the search criteria. 96 | 97 | 98 | Shortcuts for move and select modes : 99 | 100 | h, j, k, l: move cursor left/down/up/right (also with arrow keys) 101 | !, _, *: move cursor to the middle of the line/column/screen 102 | Backspace,Home move cursor to the beginning of line 103 | $,End move cursor to end of line 104 | PgUp, PgDown: move cursor to the beginning/end of the column 105 | g, G: move cursor to the top/bottom left corner of the screen 106 | 107 | y: In move mode, select the current line. 108 | In select mode, copy the selection to the clipboard, quit selection 109 | (yy means yank the current line) 110 | /, ?: activate input mode and search up/down 111 | n, N: repeat last search, up/down 112 | 113 | s: toggle move/selection mode 114 | v/V: toggle move/selection mode, select regular/rectangular type 115 | t: toggle regular/rectangular selection type 116 | 117 | p: quit keyboard_select, copy and paste selection 118 | Return: quit keyboard_select, copy selection to clipboard 119 | Escape: quit keyboard_select 120 | 121 | With h,j,k,l (also with arrow keys), you can use a quantifier. 122 | Enter a number before hitting the appropriate key. 123 | 124 | 125 | Shortcuts for input mode : 126 | 127 | Return: Return to the previous mode 128 | 129 | 130 | 131 | ${YELLOW} Shortcut list, without selection mode bindings $NORM 132 | 133 | 134 | Mode\t Modifiers\t\t Key\t\t Function\t Info 135 | 136 | 137 | -------------------------------------------------------------------------------- /src/helphead.txt: -------------------------------------------------------------------------------- 1 | 2 | $CYAN slterm - ${MAGENTA}sl${CYAN}im ${MAGENTA}t${CYAN}erminal emulator for X $NORM 3 | 4 | (Homepage: http://github.com/michael105/slterm) 5 | 6 | 7 | $YELLOW Help $NORM 8 | 9 | Colors 10 | 11 | Colors can be printed at the shell with 'echo -e \"\e[A;Nm\"' 12 | 13 | A: one of 0..7, text attributes 14 | N: fg color 30 - 37, and bg color 40 - 47 15 | 16 | 255 colors are available with: 'echo -e \"\e[A;38;5;Nm\"', 17 | and 'echo -e \"\e[0,48,5,Nm'\" for the background. 18 | A: 0=normal, 1=light, 2=dark 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/includes.h: -------------------------------------------------------------------------------- 1 | #ifndef includes_h 2 | #define includes_h 3 | // all system includes 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/keyref.txt: -------------------------------------------------------------------------------- 1 | All All Break sendbreak 2 | All All Print printsel 3 | All All Scroll_Lock lessmode_toggle 4 | All Alt s keyboard_select 5 | All Alt+Shift Down lessmode_toggle 6 | All Alt+Shift Home lessmode_toggle 7 | All Alt+Shift L lessmode_toggle 8 | All Alt+Shift Page_Down lessmode_toggle 9 | All Alt+Shift Page_Up lessmode_toggle 10 | All Alt+Shift Up lessmode_toggle 11 | All Control 0 scrollmark 12 | All Control 1 scrollmark 13 | All Control 2 scrollmark 14 | All Control 3 scrollmark 15 | All Control 4 scrollmark 16 | All Control 5 scrollmark 17 | All Control 6 scrollmark 18 | All Control 7 scrollmark 19 | All Control 8 scrollmark 20 | All Control 9 scrollmark 21 | All Control F1 showhelp 22 | All Control Print toggleprinter 23 | All Control+Alt 0 set_scrollmark 24 | All Control+Alt 1 set_scrollmark 25 | All Control+Alt 2 set_scrollmark 26 | All Control+Alt 3 set_scrollmark 27 | All Control+Alt 4 set_scrollmark 28 | All Control+Alt 5 set_scrollmark 29 | All Control+Alt 6 set_scrollmark 30 | All Control+Alt 7 set_scrollmark 31 | All Control+Alt 8 set_scrollmark 32 | All Control+Alt 9 set_scrollmark 33 | All Control+Alt Return enterscroll 34 | All Control+Shift C clipcopy 35 | All Control+Shift I inverse_screen 36 | All Control+Shift Num_Lock numlock 37 | All Control+Shift S keyboard_select 38 | All Control+Shift V clippaste 39 | All Control+Shift Y selpaste 40 | All Control+Win 0 set_charmap 41 | All Control+Win 1 set_charmap 42 | All Control+Win 2 set_charmap 43 | All Control+Win 3 set_charmap 44 | All Control+Win 4 set_charmap 45 | All Control+Win 5 set_charmap 46 | All Control+Win 6 set_charmap 47 | All Control+Win 7 set_charmap 48 | All Control+Win 8 set_charmap 49 | All Control+Win 9 set_charmap 50 | All Shift BackSpace retmark 51 | All Shift Down kscrolldown 52 | All Shift End scrolltobottom 53 | All Shift Home scrolltotop 54 | All Shift ISO_Left_Tab retmark 55 | All Shift Insert selpaste 56 | All Shift Page_Down kscrolldown 57 | All Shift Page_Up kscrollup 58 | All Shift Print printscreen 59 | All Shift Return enterscroll 60 | All Shift Up kscrollup 61 | All Shift+Control BackSpace zoomreset 62 | All Shift+Control Delete set_fontwidth 63 | All Shift+Control End set_fontheight 64 | All Shift+Control Home set_fontheight 65 | All Shift+Control Insert set_fontwidth 66 | All Shift+Control Page_Down zoom 67 | All Shift+Control Page_Up zoom 68 | Help All ALL_KEYS dummy 69 | Help All Down kscrolldown 70 | Help All End scrolltobottom 71 | Help All Escape quithelp 72 | Help All Home scrolltotop 73 | Help All Page_Down kscrolldown 74 | Help All Page_Up kscrollup 75 | Help All Up kscrollup 76 | Help All q quithelp 77 | Help All space kscrolldown 78 | Less All 0 retmark 79 | Less All 1 retmark 80 | Less All 2 retmark 81 | Less All 3 retmark 82 | Less All 4 retmark 83 | Less All 5 retmark 84 | Less All 6 retmark 85 | Less All 7 retmark 86 | Less All 8 retmark 87 | Less All 9 retmark 88 | Less All BackSpace retmark 89 | Less All Down kscrolldown 90 | Less All End scrolltobottom 91 | Less All Escape lessmode_toggle 92 | Less All Home scrolltotop 93 | Less All Page_Down kscrolldown 94 | Less All Page_Up kscrollup 95 | Less All Tab retmark 96 | Less All Up kscrollup 97 | Less All q lessmode_toggle 98 | Less All space kscrolldown 99 | Less Shift Return lessmode_toggle 100 | MODE_DEFAULT Control+Shift|Alt|Win I dump_terminfo 101 | -------------------------------------------------------------------------------- /src/keyreffilter.pl: -------------------------------------------------------------------------------- 1 | #!/bin/perl 2 | # 3 | 4 | foreach my $l (<>){ 5 | @a=split(";",$l); 6 | $a[1]=~s/[()]//g; 7 | printf "%s\t%-20s\t%-12s\t%s\t%s\n", $a[0],$a[1],$a[2],$a[3]; 8 | }; 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/license.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | ${CYAN} 4 | =============================================================================== 5 | 6 | ${LGRAY}(2019-2025 miSc, Michael 147, started with the "suckless" st sources) 7 | ${GRAY} 8 | License: MIT 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | 27 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | // function main 2 | // option parsing, config init. 3 | // 4 | // 5 | 6 | #include "xwindow.h" 7 | #include "xevent.h" 8 | #include "includes.h" 9 | #include "scroll.h" 10 | #include "selection.h" 11 | #include "system.h" 12 | #include "compile.h" 13 | #include "config.h" 14 | 15 | #include 16 | #include 17 | 18 | 19 | #ifdef XRESOURCES 20 | int resource_load(XrmDatabase db, char *name, enum resource_type rtype, 21 | void *dst) { 22 | char **sdst = dst; 23 | int *idst = dst; 24 | float *fdst = dst; 25 | 26 | char fullname[256]; 27 | char fullclass[256]; 28 | char *type; 29 | XrmValue ret; 30 | 31 | snprintf(fullname, sizeof(fullname), "%s.%s", opt_name ? opt_name : "st", 32 | name); 33 | snprintf(fullclass, sizeof(fullclass), "%s.%s", opt_class ? opt_class : "St", 34 | name); 35 | fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0'; 36 | 37 | XrmGetResource(db, fullname, fullclass, &type, &ret); 38 | if (ret.addr == NULL || strncmp("String", type, 64)) 39 | return 1; 40 | 41 | switch (rtype) { 42 | case STRING: 43 | *sdst = ret.addr; 44 | break; 45 | case INTEGER: 46 | *idst = strtoul(ret.addr, NULL, 10); 47 | break; 48 | case FLOAT: 49 | *fdst = strtof(ret.addr, NULL); 50 | break; 51 | } 52 | return 0; 53 | } 54 | 55 | 56 | 57 | void config_init(void) { 58 | char *resm; 59 | XrmDatabase db; 60 | ResourcePref *p; 61 | 62 | XrmInitialize(); 63 | resm = XResourceManagerString(xwin.dpy); 64 | if (!resm) 65 | return; 66 | 67 | db = XrmGetStringDatabase(resm); 68 | for (p = resources; p < resources + LEN(resources); p++) 69 | resource_load(db, p->name, p->type, p->dst); 70 | } 71 | #endif 72 | 73 | void printversion(){ 74 | fprintf( stderr, "slterm version " _Q(VERSION) "\n" ); 75 | } 76 | 77 | void printhelp(){ 78 | } 79 | 80 | 81 | void fontusage(){ 82 | fprintf(stderr, 83 | " slterm [-f fontname] [-fb boldname] [-fi italicname] [-fI bolditalicname]\n" 84 | " [-fw fontwidth] [-fh fontheight] [other options]\n" 85 | "\n The fontname format is specified in the fontconfig documentation,\n" 86 | " http://freedesktop.org/software/fontconfig/fontconfig-user.html\n" 87 | " A list of attributes is in doc/fontconfig.txt\n" 88 | " Supply 0 to disable bold, italic or bolditalic fonts,\n" 89 | " using colors only for the text rendering of the different fonts.\n" 90 | "\n"); 91 | } 92 | 93 | 94 | void usage(void) { 95 | printversion(); 96 | fprintf(stderr,"\nusage:\n\n" 97 | " slterm -H: Display the manpage\n" 98 | " -I: dump terminfo file\n" 99 | " -L display license\n\n" 100 | " slterm [-aiv] [-c class] [-f font] [-g geometry] [-n name] [-o file]\n" 101 | " [-T title] [-t title] [-w windowid] [[-e] command [args ...]]\n\n" 102 | " slterm [-aiv] [-c class] [-f font] [-g geometry] [-n name] [-o file]\n" 103 | " [-x] [-v] [-V] [-X] [-T title] [-t title] [-w windowid] -l line\n" 104 | " [stty_args ...]\n\n" 105 | ); 106 | fontusage(); 107 | 108 | fprintf(stderr," Original author Aurelien Aptel. 20xx-2019 st, suckless.\n 2020-2025 fork, slterm, misc147 github.com/michael105, MIT license\n\n"); 109 | 110 | exit(0); 111 | } 112 | 113 | void missingfontname( const char* option ){ 114 | fprintf(stderr, "Missing font name for option %s\nUsage: ", 115 | option ); 116 | fontusage(); 117 | exit(1); 118 | } 119 | 120 | 121 | #ifdef shared 122 | // share the whole text segment, including main 123 | int shared_main(int argc, char *argv[]) { 124 | iofd = 1; // 125 | #else 126 | int main(int argc, char *argv[]) { 127 | #endif 128 | xwin.l = xwin.t = 0; 129 | xwin.isfixed = False; 130 | twin.cursor = cursorshape; 131 | argv0 = *argv; 132 | 133 | #define EARGF(_unneeded) ({ if ( ! *++argv ){ fprintf(stderr, "missing option for %s\n", argv[-1] ); usage(); }; *argv; }) 134 | 135 | 136 | #define ARGFONT(_type) ({ if ( ! *++argv ) missingfontname( argv[-1] ); \ 137 | if ( **argv == '0' ){ _type##_font = 0; use##_type##font=0; } \ 138 | else { _type##_font = *argv; use##_type##font=1; opt_##_type##_font = 1; } \ 139 | *argv; }) 140 | 141 | int useregularfont=1; // dummy 142 | 143 | while ( *++argv && argv[0][0] == '-' ){ 144 | for ( char *opt = *argv; *opt && *++opt; ){ 145 | //for ( char *opt = *argv+1; *opt; *opt ? opt++:0 ){ 146 | switch ( *opt ){ 147 | #ifdef INCLUDETERMINFO 148 | case 'I': // dump terminfo 149 | write(STDOUT_FILENO, slterm_terminfo, strlen(slterm_terminfo) ); 150 | exit(0); 151 | #endif 152 | #ifdef INCLUDELICENSE 153 | case 'L': 154 | write(STDOUT_FILENO, slterm_license, strlen(slterm_license) ); 155 | exit(0); 156 | #endif 157 | #ifdef INCLUDEMANPAGE 158 | case 'H': 159 | write(STDOUT_FILENO, slterm_man, strlen(slterm_man) ); 160 | exit(0); 161 | #endif 162 | case 'X': 163 | if ( mlockall(MCL_CURRENT|MCL_FUTURE) ){ 164 | perror("Unable to lock memory pages into memory"); 165 | exit(errno); 166 | } 167 | break; 168 | case 'a': 169 | allowaltscreen = 0; 170 | break; 171 | case 'c': 172 | opt_class = EARGF(usage()); 173 | break; 174 | case 'e': 175 | argv++; 176 | goto run; 177 | case 'f': 178 | switch ( *++opt ){ 179 | case 'w': fontwidth = atoi( EARGF() ); break; 180 | case 'h': fontheight = atoi( EARGF() ); break; 181 | case 'R': 182 | case 'b': ARGFONT(bold); break; 183 | case 'i': ARGFONT(italic); break; 184 | case 'I': ARGFONT(bolditalic); break; 185 | 186 | case 'r': 187 | case 0: 188 | opt_font = ARGFONT(regular); 189 | break; 190 | default: 191 | usage(); 192 | } 193 | break; 194 | case 'g': 195 | xwin.gm = XParseGeometry(EARGF(usage()), &xwin.l, &xwin.t, &cols, &rows); 196 | break; 197 | case 'i': 198 | xwin.isfixed = 1; 199 | break; 200 | case 'o': 201 | opt_io = EARGF(usage()); 202 | break; 203 | case 'l': 204 | opt_line = EARGF(usage()); 205 | break; 206 | case 'n': 207 | opt_name = EARGF(usage()); 208 | break; 209 | case 't': 210 | case 'T': 211 | opt_title = EARGF(usage()); 212 | break; 213 | case 'w': 214 | opt_embed = EARGF(usage()); 215 | break; 216 | case 'x': 217 | opt_xresources = 1; 218 | break; 219 | case 'v': 220 | printversion(); 221 | exit(0); 222 | case 'V': 223 | printversion(); 224 | printf( "Git Revision " _GITREVISION_"\n"); 225 | printf( "\nCompiled " __COMPILEDATE__ "\n" 226 | __UNAME__ "\n" 227 | "CC: "__CC__" "__CC_VERSION__"\n\n" 228 | "Compileflags: " 229 | __OPT_FLAG__ "\n" 230 | "HISTORY: %d\n" 231 | "DEBUGLEVEL: "__ENABLEDEBUG__"\n" 232 | "XRESOURCES: "__XRESOURCES__"\n" 233 | "XProtocol Version " _Q(X_PROTOCOL) "." _Q(X_PROTOCOL_REVISION) "\n" 234 | __COMPILECOMMAND__ "\n", ( 1< 0) /* eat all remaining arguments */ 248 | if ( *argv ) 249 | opt_cmd = argv; 250 | 251 | if (!opt_title) 252 | opt_title = (opt_line || !opt_cmd) ? "slterm" : opt_cmd[0]; 253 | 254 | //setlocale(LC_CTYPE, ""); 255 | XSetLocaleModifiers(""); 256 | 257 | #ifdef XRESOURCES 258 | if (!(xwin.dpy = XOpenDisplay(NULL))) 259 | die("Can't open display\n"); 260 | 261 | if (opt_xresources) 262 | config_init(); 263 | #endif 264 | 265 | cols = MAX(cols, 1); 266 | rows = MAX(rows, 1); 267 | tnew(cols, rows, HISTSIZE); 268 | xinit(cols, rows); 269 | xsetenv(); 270 | selinit(); 271 | 272 | create_unicode_table(); // unicode to current cp table 273 | sort_shortcuts(); 274 | 275 | run(); 276 | 277 | return 0; 278 | } 279 | -------------------------------------------------------------------------------- /src/mem.c: -------------------------------------------------------------------------------- 1 | #ifndef MEM_C 2 | #define MEM_C 3 | 4 | // memory related functions 5 | 6 | #include "mem.h" 7 | 8 | // Set glyphs (non utf8 - one glyph is one int32 ) 9 | void memset32( uint32_t* i, uint32_t value, int count ){ 10 | for ( int a=0; a>1; 20 | uint64_t i64 = value | (ulong)( (ulong)value << 32UL ); 21 | asm volatile ("rep stosq\n" : "+D"(i), "+c"(c): "a"(i64) : "cc", "memory" ); 22 | */ 23 | } 24 | 25 | 26 | // optimized, only usable for even count values 27 | void memset64( uint32_t* i, uint32_t value, int count ){ 28 | count >>=1; 29 | uint64_t i64 = value | (ulong)( (ulong)value << 32UL ); 30 | asm volatile ("rep stosq\n" : "+D"(i), "+c"(count): "a"(i64) : "cc", "memory" ); 31 | } 32 | 33 | 34 | ssize_t xwrite(int fd, const char *s, size_t len) { 35 | size_t aux = len; 36 | ssize_t r; 37 | 38 | while (len > 0) { 39 | r = write(fd, s, len); 40 | if (r < 0) { 41 | return r; 42 | } 43 | len -= r; 44 | s += r; 45 | } 46 | 47 | return aux; 48 | } 49 | // opt - power of 8? -> memset32 -> memset64 50 | void *xmalloc(size_t len) { 51 | void *p; 52 | 53 | if (!(p = malloc(len))) { 54 | die("malloc: %s\n", strerror(errno)); 55 | } 56 | 57 | return p; 58 | } 59 | 60 | void *xcalloc(size_t len) { 61 | void *p; 62 | 63 | if (!(p = malloc(len))) { 64 | die("malloc: %s\n", strerror(errno)); 65 | } 66 | bzero( p, len ); 67 | 68 | return p; 69 | } 70 | 71 | 72 | 73 | 74 | void *xrealloc(void *p, size_t len) { 75 | if ((p = realloc(p, len)) == NULL) { 76 | die("realloc: %s\n", strerror(errno)); 77 | } 78 | 79 | return p; 80 | } 81 | 82 | char *xstrdup(char *s) { 83 | if ((s = strdup(s)) == NULL) { 84 | die("strdup: %s\n", strerror(errno)); 85 | } 86 | 87 | return s; 88 | } 89 | 90 | 91 | #endif 92 | 93 | -------------------------------------------------------------------------------- /src/mem.h: -------------------------------------------------------------------------------- 1 | #ifndef mem_h 2 | #define mem_h 3 | 4 | 5 | 6 | #include "includes.h" 7 | 8 | 9 | void memset32( uint32_t* i, uint32_t value, int count ); 10 | void memset64( uint32_t* i, uint32_t value, int count ); 11 | 12 | ssize_t xwrite(int fd, const char *s, size_t len); 13 | void *xmalloc(size_t len); 14 | void *xcalloc(size_t len); 15 | void *xrealloc(void *p, size_t len); 16 | char *xstrdup(char *s); 17 | 18 | 19 | 20 | 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /src/retmarks.c: -------------------------------------------------------------------------------- 1 | /* retmarks. 2 | stored in term->retmarks[N] 3 | the store is used circular, 4 | term->current_retmark points to the currently unused place, 5 | the last retmark can be accessed with (current_retmark - 1) &( RETMARKCOUNT-1) 6 | The position is given as term->histindex (histindex) 7 | */ 8 | 9 | 10 | 11 | void retmark_scrolledup(){ // scan upwards for the next retmark, update 12 | for ( int t = term->current_retmark - (term->scrolled_retmark?term->scrolled_retmark:1); 13 | t!=term->current_retmark; 14 | t-- ){ 15 | t &= ( RETMARKCOUNT-1 ); 16 | DBG("mark upw: %d %d\n",t, term->retmarks[t] ); 17 | if ( (term->retmarks[t]==0) || (term->histindex - term->retmarks[t] >= term->scr) ){ 18 | term->scrolled_retmark = (term->current_retmark - t) & ( RETMARKCOUNT-1); 19 | return; 20 | } 21 | } 22 | } 23 | 24 | 25 | 26 | void retmark_scrolleddown(){ // scan downwards for the next retmark, update 27 | for ( int t = (term->current_retmark - (term->scrolled_retmark?term->scrolled_retmark:1 )) & (RETMARKCOUNT-1); t!=term->current_retmark; 28 | t = (t+1) & ( RETMARKCOUNT-1 ) ){ 29 | if ( (term->histindex - term->retmarks[t] < term->scr) ){ 30 | term->scrolled_retmark = ( term->current_retmark - t + 1 ) & ( RETMARKCOUNT-1); 31 | //DBG("mark: %d %d\n",t, term->retmarks[t] ); 32 | return; 33 | } 34 | } 35 | // at the bottom 36 | term->scrolled_retmark = 1; 37 | } 38 | 39 | 40 | void set_retmark() { 41 | if (term==p_alt) return; 42 | // check, if (e.g. vi) we are above the last retmark 43 | if ( (term->retmarks[ (term->current_retmark - 1) & (RETMARKCOUNT-1) ] < 44 | (term->histindex + term->cursor.y ) ) || 45 | ( term->circledhist && (term->retmarks[ (term->current_retmark - 1) & (RETMARKCOUNT-1) ] > 46 | (term->histindex + term->cursor.y + term->histsize/2 ) ) ) ){ 47 | // second case: circled buffer, first case: try to detect screen based programs 48 | // e.g. vim 49 | term->retmarks[ term->current_retmark ] = term->histindex + term->cursor.y; 50 | term->current_retmark = (term->current_retmark + 1) & (RETMARKCOUNT-1); 51 | term->scrolled_retmark = 0; 52 | } 53 | //DBG("Setretmark: n:%d histindex:%d scr:%d cursor: %d\n", term->current_retmark, term->histindex, term->scr, term->cursor.y ); 54 | } 55 | 56 | void retmark(const Arg* a){ 57 | if (term==p_alt) return; // not usable in alt screen 58 | //DBG("Retmark: n:%d scrm:%d histindex:%d scr:%d scroll_mark %d current_mark %d\n", term->rows, term->retmarks[0],term->histindex, term->scr, term->scroll_retmark, term->current_retmark ); 59 | 60 | // rewrite that. (count curentretmark from 0 to UINT_MAX. Limit bits when 61 | // accessing the array. ->scrolled_retmark can be set absolute. 62 | 63 | if ( a->i == -1 ){ // tab right in lessmode -> scrolling down 64 | 65 | // todo: rewrite. also for a circled buffer 66 | int b = 1; 67 | // todo: reverse scanning. 68 | for ( int t = (term->current_retmark +1 ) & (RETMARKCOUNT-1); t!=term->current_retmark; 69 | t = (t+1) & ( RETMARKCOUNT-1 ) ){ 70 | //if ( (term->retmarks[t] < term->histindex - term->scr) ){ 71 | if ( (term->histindex - term->retmarks[t] < term->scr) ){ 72 | term->scr=(term->histindex - term->retmarks[t]); 73 | term->scrolled_retmark = ( term->current_retmark - t ) & ( RETMARKCOUNT-1); 74 | b = 0; 75 | //DBG("mark: %d %d\n",t, term->retmarks[t] ); 76 | break; 77 | } 78 | } 79 | if ( b ){ 80 | term->scrolled_retmark = 0; 81 | scrolltobottom(); 82 | } 83 | 84 | 85 | } else if ( a->i >= 1 ){ // number, scroll to retmark number x 86 | int t = (term->current_retmark - a->i ) & (RETMARKCOUNT-1); 87 | term->scr=(term->histindex-term->retmarks[t]); 88 | term->scrolled_retmark = ( term->current_retmark - t ) & ( RETMARKCOUNT-1); 89 | 90 | } else if ( a->i == -2 ){ // = key '0' 91 | term->scrolled_retmark = 0; 92 | scrolltobottom(); 93 | } else { // scroll backward / Up 94 | if ( term->histindexrows){ // at the top 95 | scrolltotop(); 96 | lessmode_toggle( ARGPi(LESSMODE_ON) ); 97 | return; 98 | } 99 | 100 | #if 0 101 | // todo: scroll to next retmark 102 | int t = term->scrolled_retmark; 103 | if ( t ){ 104 | //t= (t-1) & (RETMARKCOUNT-1); 105 | t--; 106 | term->scrolled_retmark = t; 107 | term->scr=(term->histindex - term->retmarks[(term->current_retmark - t)&(RETMARKCOUNT-1) ]); 108 | 109 | } 110 | #else 111 | for ( int t = (term->current_retmark -1 ) & (RETMARKCOUNT-1); t!=term->current_retmark; 112 | t = (t-1) & ( RETMARKCOUNT-1 ) ){ 113 | DBG("mark: %d %d\n",t, term->retmarks[t] ); 114 | if ( (term->retmarks[t]==0) || (term->histindex - term->retmarks[t] > term->scr) ){ 115 | term->scr=(term->histindex - term->retmarks[t]); 116 | term->scrolled_retmark = (term->current_retmark - t) & ( RETMARKCOUNT-1); 117 | break; 118 | } 119 | } 120 | #endif 121 | 122 | } 123 | DBG("scr: %d\n", term->scr ); 124 | if ( term->scr<0 ){ 125 | // TODO: circledhist 126 | if ( term->circledhist ) 127 | term->scr&=(term->histsize); 128 | else 129 | term->scr=0; 130 | 131 | DBG("scr: %d\n", term->scr ); 132 | }; 133 | //DBG("Retmark OUT: n:%d scrm:%d histindex:%d scr:%d scroll_mark %d current_mark %d\n", term->rows, term->retmarks[0],term->histindex, term->scr, term->scroll_retmark, term->current_retmark ); 134 | 135 | selscroll(0, term->scr); 136 | tfulldirt(); 137 | //updatestatus(); 138 | lessmode_toggle( ARGPi(LESSMODE_ON) ); 139 | } 140 | 141 | 142 | -------------------------------------------------------------------------------- /src/scroll.h: -------------------------------------------------------------------------------- 1 | #ifndef scroll_h 2 | #define scroll_h 3 | 4 | #include "xevent.h" 5 | 6 | // SCROLL and LESSMODE are to be or'ed and given to lessmode_toggle 7 | #define LESSMODE(mode) ({ enum { off=(1<<28), toggle=((1<<28)|(1<<29)), on=(1<<29) }; mode; }) 8 | #define LESSMODE_OFF (1<<28) 9 | #define LESSMODE_ON (1<<29) 10 | #define LESSMODE_TOGGLE (LESSMODE_OFF|LESSMODE_ON) 11 | #define SCROLL_BOTTOM (1<<26) 12 | #define SCROLL_PAGEDOWN (1<<30) 13 | #define SCROLL_PAGEUP ((1<<30)|(1<<31)) 14 | #define SCROLL_TOP (1<<31) 15 | #define SCROLLUP(x) (x|(1<<27)) 16 | // scroll down x lines, argument to scroll 17 | #define SCROLLDOWN(x) (x&(~(1<<27))) 18 | #define LESSMODEMASK (3<<28) 19 | #define SCROLLMASK ((3<<30)|((1<<28)-1)) 20 | #define SCROLL_LINEMASK ((1<<26)-1) 21 | 22 | #define ISSCROLLDOWN(x) ( !(x&(1<<27)) && ( (x&SCROLL_LINEMASK)>0 )) 23 | //#define ISSCROLLDOWN(x) ( x>0 && x<(1<<31) ) 24 | //#define ISSCROLLUP(x) ( x<0 && x> -(1UI<<32UI) ) 25 | #define ISSCROLLUP(x) ( x&(1<<27) ) 26 | //#define ISSCROLLUP(x) ( ( x&(SCROLLMASK&&(~(1<<32))) ) && (x&(1<<32)) ) 27 | 28 | //extern int scrollmarks[12]; 29 | //extern int retmarks[10]; 30 | 31 | 32 | /* Notes for history (todo) 33 | term->scr : scroll 34 | term->histpos: line in history buffer 35 | term->pos : histpos - scroll 36 | 37 | line: (TLINE): position of screen 'line' in the buffer 38 | 39 | double buffering of screen(?) 40 | 41 | 42 | zwei optionen: entweder in der history raw terminal input speichern. 43 | schwierig: scrollen, kann sprunghaft werden. oder aufwendig. 44 | (bsp farben: fast unmoeglich) 45 | oder eben den output, wie gehabt. 46 | 47 | */ 48 | 49 | 50 | // callbacks 51 | void kscrolldown(const Arg *); 52 | void kscrollup(const Arg *); 53 | // Argument Arg.i is one of LESSMODE_ON, LESSMODE_OFF, LESSMODE_TOGGLE 54 | // can be or'ed with SCROLL (all definitions), then scrolls also 55 | void lessmode_toggle(const Arg*); 56 | 57 | void set_scrollmark(const Arg *a); 58 | void set_retmark(); 59 | void retmark(const Arg *a); 60 | void scrollmark(const Arg *a); 61 | void leavescroll(const Arg *a); 62 | void enterscroll(const Arg *a); 63 | 64 | // scroll up i lines (-1,..) down (1,..), i must be < (1<<30) (actually > as well ) 65 | // or SCROLL(bottom), SCROLL(pagedown), SCROLL(pageup) SCROLL(top) 66 | void scroll(const Arg *a); 67 | 68 | void tnewline(int); 69 | void scrolltobottom(); 70 | void scrolltotop(); 71 | 72 | void tsetscroll(int, int); 73 | void tscrollup(int, int, int); 74 | void tscrolldown(int, int, int); 75 | 76 | 77 | #endif 78 | 79 | -------------------------------------------------------------------------------- /src/selection.h: -------------------------------------------------------------------------------- 1 | #ifndef selection_h 2 | #define selection_h 3 | 4 | #include "includes.h" 5 | #include 6 | 7 | typedef struct { 8 | int mode; 9 | int type; 10 | int snap; 11 | /* 12 | * Selection variables: 13 | * nb – normalized coordinates of the beginning of the selection 14 | * ne – normalized coordinates of the end of the selection 15 | * ob – original coordinates of the beginning of the selection 16 | * oe – original coordinates of the end of the selection 17 | */ 18 | struct { 19 | int x, y; 20 | } nb, ne, ob, oe; 21 | 22 | int alt; 23 | } Selection; 24 | 25 | 26 | enum selection_mode { SEL_IDLE = 0, SEL_EMPTY = 1, SEL_READY = 2 }; 27 | 28 | enum selection_type { SEL_REGULAR = 1, SEL_RECTANGULAR = 2 }; 29 | 30 | enum selection_snap { SNAP_WORD = 1, SNAP_LINE = 2 }; 31 | 32 | 33 | // selction 34 | 35 | extern Selection sel; 36 | 37 | 38 | 39 | // callbacks 40 | void keyboard_select(const Arg *); 41 | 42 | void mousesel(XEvent *, int); 43 | 44 | void selnormalize(void); 45 | void selscroll(int, int); 46 | void selsnap(int *, int *, int); 47 | 48 | void setsel(char *, Time); 49 | void xsetsel(char *); 50 | 51 | void selclear(void); 52 | void selinit(void); 53 | void selstart(int, int, int); 54 | void selextend(int, int, int, int); 55 | int selected(int, int); 56 | char *getsel(void); 57 | 58 | int trt_kbdselect(KeySym, char *, int); 59 | 60 | static void tdumpsel(void); 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/slterm.terminfo: -------------------------------------------------------------------------------- 1 | slterm| slimterm, 2 | acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssltermtuuvvwwxxyyzz{{||}}~~, 3 | am, 4 | bce, 5 | bel=^G, 6 | blink=\E[5m, 7 | bold=\E[1m, 8 | cbt=\E[Z, 9 | cvvis=\E[?25h, 10 | civis=\E[?25l, 11 | clear=\E[H\E[2J, 12 | cnorm=\E[?12l\E[?25h, 13 | colors#8, 14 | cols#80, 15 | cr=^M, 16 | csr=\E[%i%p1%d;%p2%dr, 17 | cub=\E[%p1%dD, 18 | cub1=^H, 19 | cud1=^J, 20 | cud=\E[%p1%dB, 21 | cuf1=\E[C, 22 | cuf=\E[%p1%dC, 23 | cup=\E[%i%p1%d;%p2%dH, 24 | cuu1=\E[A, 25 | cuu=\E[%p1%dA, 26 | dch=\E[%p1%dP, 27 | dch1=\E[P, 28 | dim=\E[2m, 29 | dl=\E[%p1%dM, 30 | dl1=\E[M, 31 | ech=\E[%p1%dX, 32 | ed=\E[J, 33 | el=\E[K, 34 | el1=\E[1K, 35 | enacs=\E)0, 36 | flash=\E[?5h$<80/>\E[?5l, 37 | fsl=^G, 38 | home=\E[H, 39 | hpa=\E[%i%p1%dG, 40 | hs, 41 | ht=^I, 42 | hts=\EH, 43 | ich=\E[%p1%d@, 44 | il1=\E[L, 45 | il=\E[%p1%dL, 46 | ind=^J, 47 | indn=\E[%p1%dS, 48 | invis=\E[8m, 49 | is2=\E[4l\E>\E[?1034l, 50 | it#8, 51 | kel=\E[1;2F, 52 | ked=\E[1;5F, 53 | ka1=\E[1~, 54 | ka3=\E[5~, 55 | kc1=\E[4~, 56 | kc3=\E[6~, 57 | kbs=\177, 58 | kcbt=\E[Z, 59 | kb2=\EOu, 60 | kcub1=\EOD, 61 | kcud1=\EOB, 62 | kcuf1=\EOC, 63 | kcuu1=\EOA, 64 | kDC=\E[3;2~, 65 | kent=\EOM, 66 | kEND=\E[1;2F, 67 | kIC=\E[2;2~, 68 | kNXT=\E[6;2~, 69 | kPRV=\E[5;2~, 70 | kHOM=\E[1;2H, 71 | kLFT=\E[1;2D, 72 | kRIT=\E[1;2C, 73 | kind=\E[1;2B, 74 | kri=\E[1;2A, 75 | kclr=\E[3;5~, 76 | kdl1=\E[3;2~, 77 | kdch1=\E[3~, 78 | kich1=\E[2~, 79 | kend=\E[4~, 80 | kf1=\EOP, 81 | kf2=\EOQ, 82 | kf3=\EOR, 83 | kf4=\EOS, 84 | kf5=\E[15~, 85 | kf6=\E[17~, 86 | kf7=\E[18~, 87 | kf8=\E[19~, 88 | kf9=\E[20~, 89 | kf10=\E[21~, 90 | kf11=\E[23~, 91 | kf12=\E[24~, 92 | kf13=\E[1;2P, 93 | kf14=\E[1;2Q, 94 | kf15=\E[1;2R, 95 | kf16=\E[1;2S, 96 | kf17=\E[15;2~, 97 | kf18=\E[17;2~, 98 | kf19=\E[18;2~, 99 | kf20=\E[19;2~, 100 | kf21=\E[20;2~, 101 | kf22=\E[21;2~, 102 | kf23=\E[23;2~, 103 | kf24=\E[24;2~, 104 | kf25=\E[1;5P, 105 | kf26=\E[1;5Q, 106 | kf27=\E[1;5R, 107 | kf28=\E[1;5S, 108 | kf29=\E[15;5~, 109 | kf30=\E[17;5~, 110 | kf31=\E[18;5~, 111 | kf32=\E[19;5~, 112 | kf33=\E[20;5~, 113 | kf34=\E[21;5~, 114 | kf35=\E[23;5~, 115 | kf36=\E[24;5~, 116 | kf37=\E[1;6P, 117 | kf38=\E[1;6Q, 118 | kf39=\E[1;6R, 119 | kf40=\E[1;6S, 120 | kf41=\E[15;6~, 121 | kf42=\E[17;6~, 122 | kf43=\E[18;6~, 123 | kf44=\E[19;6~, 124 | kf45=\E[20;6~, 125 | kf46=\E[21;6~, 126 | kf47=\E[23;6~, 127 | kf48=\E[24;6~, 128 | kf49=\E[1;3P, 129 | kf50=\E[1;3Q, 130 | kf51=\E[1;3R, 131 | kf52=\E[1;3S, 132 | kf53=\E[15;3~, 133 | kf54=\E[17;3~, 134 | kf55=\E[18;3~, 135 | kf56=\E[19;3~, 136 | kf57=\E[20;3~, 137 | kf58=\E[21;3~, 138 | kf59=\E[23;3~, 139 | kf60=\E[24;3~, 140 | kf61=\E[1;4P, 141 | kf62=\E[1;4Q, 142 | kf63=\E[1;4R, 143 | khome=\E[1~, 144 | kil1=\E[2;5~, 145 | krmir=\E[2;2~, 146 | knp=\E[6~, 147 | kmous=\E[M, 148 | kpp=\E[5~, 149 | lines#24, 150 | mir, 151 | msgr, 152 | npc, 153 | op=\E[39;49m, 154 | pairs#64, 155 | mc0=\E[i, 156 | mc4=\E[4i, 157 | mc5=\E[5i, 158 | rc=\E8, 159 | rev=\E[7m, 160 | ri=\EM, 161 | ritm=\E[23m, 162 | rmacs=\E(B, 163 | rmcup=\E[?1049l, 164 | rmir=\E[4l, 165 | rmkx=\E[?1l\E>, 166 | rmso=\E[27m, 167 | rmul=\E[24m, 168 | rs1=\Ec, 169 | rs2=\E[4l\E>\E[?1034l, 170 | sc=\E7, 171 | setab=\E[4%p1%dm, 172 | setaf=\E[3%p1%dm, 173 | setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 174 | setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 175 | sgr0=\E[0m, 176 | 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, 177 | sitm=\E[3m, 178 | smacs=\E(0, 179 | smcup=\E[?1049h, 180 | smir=\E[4h, 181 | smkx=\E[?1h\E=, 182 | smso=\E[7m, 183 | smul=\E[4m, 184 | tbc=\E[3g, 185 | tsl=\E]0;, 186 | xenl, 187 | vpa=\E[%i%p1%dd, 188 | # XTerm extensions 189 | rmxx=\E[29m, 190 | smxx=\E[9m, 191 | # tmux extensions, see TERMINFO EXTENSIONS in tmux(1) 192 | Tc, 193 | Ms=\E]52;%p1%s;%p2%s\007, 194 | Se=\E[2 q, 195 | Ss=\E[%p1%d q, 196 | 197 | slterm-256color| slimterm with 256 colors, 198 | use=slterm, 199 | ccc, 200 | colors#256, 201 | oc=\E]104\007, 202 | pairs#32767, 203 | # Nicked from xterm-256color 204 | initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\, 205 | setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, 206 | setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, 207 | 208 | slterm-meta| slimterm with meta key, 209 | use=slterm, 210 | km, 211 | rmm=\E[?1034l, 212 | smm=\E[?1034h, 213 | rs2=\E[4l\E>\E[?1034h, 214 | is2=\E[4l\E>\E[?1034h, 215 | 216 | slterm-meta-256color| slimterm with meta key and 256 colors, 217 | use=slterm-256color, 218 | km, 219 | rmm=\E[?1034l, 220 | smm=\E[?1034h, 221 | rs2=\E[4l\E>\E[?1034h, 222 | is2=\E[4l\E>\E[?1034h, 223 | -------------------------------------------------------------------------------- /src/slterm_license.h: -------------------------------------------------------------------------------- 1 | const char* slterm_license = R"(MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | )"; 21 | 22 | -------------------------------------------------------------------------------- /src/slterm_shared.c: -------------------------------------------------------------------------------- 1 | #include "xwindow.h" 2 | 3 | 4 | int main(int argc, char *argv[]){ 5 | return(shared_main(argc,argv)); 6 | } 7 | 8 | -------------------------------------------------------------------------------- /src/slterm_src.c: -------------------------------------------------------------------------------- 1 | // Including all sources into a single file 2 | // leaves more possibilities for optimizations to the compiler. 3 | // Did try to split the huge term.c file, 4 | // but there are many globals left. 5 | // beware. it wasn't me.. ;misc 2021 6 | 7 | //#define DEBUG_FILELEVEL 5 8 | //#define FULLDEBUG 5 9 | #include "debug.h" 10 | 11 | #include "includes.h" 12 | #include "globals.h" 13 | //#include "arg.h" 14 | #include "term.h" 15 | #include "xwindow.h" 16 | #include "xcursor.h" 17 | #include "system.h" 18 | #include "tty.h" 19 | #include "selection.h" 20 | #include "xclipboard.h" 21 | #include "xevent.h" 22 | #include "xmouse.h" 23 | #include "xkeyboard.h" 24 | #include "fonts.h" 25 | #include "statusbar.h" 26 | #include "scroll.h" 27 | #include "xdraw.h" 28 | #include "termdraw.h" 29 | #include "charmaps.h" 30 | #include "colors.h" 31 | 32 | // embedded resources 33 | #ifdef INCLUDETERMINFO 34 | #include "slterm_terminfo.h" 35 | #endif 36 | #ifdef INCLUDELICENSE 37 | #include "slterm_license.h" 38 | #endif 39 | 40 | #ifdef INCLUDEMANPAGE 41 | #include "slterm_man.h" 42 | #endif 43 | 44 | #if 0 45 | #define DBG(...) printf(__VA_ARGS__) 46 | #else 47 | #define DBG(...) 48 | #endif 49 | #define DBG2(...) DBG(__VA_ARGS__) 50 | 51 | 52 | 53 | #include "globals.c" 54 | #include "statusbar.c" 55 | #include "retmarks.c" 56 | //#include "arg.c" 57 | #include "term.c" 58 | #include "controlchars.c" 59 | #include "charmaps.c" 60 | // termdraw needs to go after term.c .? 61 | // otherweise delete and cursor keys do make trouble. 62 | // Not looking for the source now. 63 | #include "termdraw.c" 64 | 65 | #include "fonts.c" 66 | #include "mem.c" 67 | #include "base64.c" 68 | #include "selection.c" 69 | #include "xclipboard.c" 70 | #include "colors.c" 71 | #include "xwindow.c" 72 | #include "xcursor.c" 73 | #include "xevent.c" 74 | #include "xmouse.c" 75 | #include "xkeyboard.c" 76 | #include "main.c" 77 | #include "system.c" 78 | #include "tty.c" 79 | #include "utf8.c" 80 | #include "scroll.c" 81 | #include "xdraw.c" 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/slterm_terminfo.h: -------------------------------------------------------------------------------- 1 | const char* slterm_terminfo = R"(slterm| slimterm, 2 | acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssltermtuuvvwwxxyyzz{{||}}~~, 3 | am, 4 | bce, 5 | bel=^G, 6 | blink=\E[5m, 7 | bold=\E[1m, 8 | cbt=\E[Z, 9 | cvvis=\E[?25h, 10 | civis=\E[?25l, 11 | clear=\E[H\E[2J, 12 | cnorm=\E[?12l\E[?25h, 13 | colors#8, 14 | cols#80, 15 | cr=^M, 16 | csr=\E[%i%p1%d;%p2%dr, 17 | cub=\E[%p1%dD, 18 | cub1=^H, 19 | cud1=^J, 20 | cud=\E[%p1%dB, 21 | cuf1=\E[C, 22 | cuf=\E[%p1%dC, 23 | cup=\E[%i%p1%d;%p2%dH, 24 | cuu1=\E[A, 25 | cuu=\E[%p1%dA, 26 | dch=\E[%p1%dP, 27 | dch1=\E[P, 28 | dim=\E[2m, 29 | dl=\E[%p1%dM, 30 | dl1=\E[M, 31 | ech=\E[%p1%dX, 32 | ed=\E[J, 33 | el=\E[K, 34 | el1=\E[1K, 35 | enacs=\E)0, 36 | flash=\E[?5h$<80/>\E[?5l, 37 | fsl=^G, 38 | home=\E[H, 39 | hpa=\E[%i%p1%dG, 40 | hs, 41 | ht=^I, 42 | hts=\EH, 43 | ich=\E[%p1%d@, 44 | il1=\E[L, 45 | il=\E[%p1%dL, 46 | ind=^J, 47 | indn=\E[%p1%dS, 48 | invis=\E[8m, 49 | is2=\E[4l\E>\E[?1034l, 50 | it#8, 51 | kel=\E[1;2F, 52 | ked=\E[1;5F, 53 | ka1=\E[1~, 54 | ka3=\E[5~, 55 | kc1=\E[4~, 56 | kc3=\E[6~, 57 | kbs=\177, 58 | kcbt=\E[Z, 59 | kb2=\EOu, 60 | kcub1=\EOD, 61 | kcud1=\EOB, 62 | kcuf1=\EOC, 63 | kcuu1=\EOA, 64 | kDC=\E[3;2~, 65 | kent=\EOM, 66 | kEND=\E[1;2F, 67 | kIC=\E[2;2~, 68 | kNXT=\E[6;2~, 69 | kPRV=\E[5;2~, 70 | kHOM=\E[1;2H, 71 | kLFT=\E[1;2D, 72 | kRIT=\E[1;2C, 73 | kind=\E[1;2B, 74 | kri=\E[1;2A, 75 | kclr=\E[3;5~, 76 | kdl1=\E[3;2~, 77 | kdch1=\E[3~, 78 | kich1=\E[2~, 79 | kend=\E[4~, 80 | kf1=\EOP, 81 | kf2=\EOQ, 82 | kf3=\EOR, 83 | kf4=\EOS, 84 | kf5=\E[15~, 85 | kf6=\E[17~, 86 | kf7=\E[18~, 87 | kf8=\E[19~, 88 | kf9=\E[20~, 89 | kf10=\E[21~, 90 | kf11=\E[23~, 91 | kf12=\E[24~, 92 | kf13=\E[1;2P, 93 | kf14=\E[1;2Q, 94 | kf15=\E[1;2R, 95 | kf16=\E[1;2S, 96 | kf17=\E[15;2~, 97 | kf18=\E[17;2~, 98 | kf19=\E[18;2~, 99 | kf20=\E[19;2~, 100 | kf21=\E[20;2~, 101 | kf22=\E[21;2~, 102 | kf23=\E[23;2~, 103 | kf24=\E[24;2~, 104 | kf25=\E[1;5P, 105 | kf26=\E[1;5Q, 106 | kf27=\E[1;5R, 107 | kf28=\E[1;5S, 108 | kf29=\E[15;5~, 109 | kf30=\E[17;5~, 110 | kf31=\E[18;5~, 111 | kf32=\E[19;5~, 112 | kf33=\E[20;5~, 113 | kf34=\E[21;5~, 114 | kf35=\E[23;5~, 115 | kf36=\E[24;5~, 116 | kf37=\E[1;6P, 117 | kf38=\E[1;6Q, 118 | kf39=\E[1;6R, 119 | kf40=\E[1;6S, 120 | kf41=\E[15;6~, 121 | kf42=\E[17;6~, 122 | kf43=\E[18;6~, 123 | kf44=\E[19;6~, 124 | kf45=\E[20;6~, 125 | kf46=\E[21;6~, 126 | kf47=\E[23;6~, 127 | kf48=\E[24;6~, 128 | kf49=\E[1;3P, 129 | kf50=\E[1;3Q, 130 | kf51=\E[1;3R, 131 | kf52=\E[1;3S, 132 | kf53=\E[15;3~, 133 | kf54=\E[17;3~, 134 | kf55=\E[18;3~, 135 | kf56=\E[19;3~, 136 | kf57=\E[20;3~, 137 | kf58=\E[21;3~, 138 | kf59=\E[23;3~, 139 | kf60=\E[24;3~, 140 | kf61=\E[1;4P, 141 | kf62=\E[1;4Q, 142 | kf63=\E[1;4R, 143 | khome=\E[1~, 144 | kil1=\E[2;5~, 145 | krmir=\E[2;2~, 146 | knp=\E[6~, 147 | kmous=\E[M, 148 | kpp=\E[5~, 149 | lines#24, 150 | mir, 151 | msgr, 152 | npc, 153 | op=\E[39;49m, 154 | pairs#64, 155 | mc0=\E[i, 156 | mc4=\E[4i, 157 | mc5=\E[5i, 158 | rc=\E8, 159 | rev=\E[7m, 160 | ri=\EM, 161 | ritm=\E[23m, 162 | rmacs=\E(B, 163 | rmcup=\E[?1049l, 164 | rmir=\E[4l, 165 | rmkx=\E[?1l\E>, 166 | rmso=\E[27m, 167 | rmul=\E[24m, 168 | rs1=\Ec, 169 | rs2=\E[4l\E>\E[?1034l, 170 | sc=\E7, 171 | setab=\E[4%p1%dm, 172 | setaf=\E[3%p1%dm, 173 | setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 174 | setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 175 | sgr0=\E[0m, 176 | 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, 177 | sitm=\E[3m, 178 | smacs=\E(0, 179 | smcup=\E[?1049h, 180 | smir=\E[4h, 181 | smkx=\E[?1h\E=, 182 | smso=\E[7m, 183 | smul=\E[4m, 184 | tbc=\E[3g, 185 | tsl=\E]0;, 186 | xenl, 187 | vpa=\E[%i%p1%dd, 188 | # XTerm extensions 189 | rmxx=\E[29m, 190 | smxx=\E[9m, 191 | # tmux extensions, see TERMINFO EXTENSIONS in tmux(1) 192 | Tc, 193 | Ms=\E]52;%p1%s;%p2%s\007, 194 | Se=\E[2 q, 195 | Ss=\E[%p1%d q, 196 | 197 | slterm-256color| slimterm with 256 colors, 198 | use=slterm, 199 | ccc, 200 | colors#256, 201 | oc=\E]104\007, 202 | pairs#32767, 203 | # Nicked from xterm-256color 204 | initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\, 205 | setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, 206 | setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, 207 | 208 | slterm-meta| slimterm with meta key, 209 | use=slterm, 210 | km, 211 | rmm=\E[?1034l, 212 | smm=\E[?1034h, 213 | rs2=\E[4l\E>\E[?1034h, 214 | is2=\E[4l\E>\E[?1034h, 215 | 216 | slterm-meta-256color| slimterm with meta key and 256 colors, 217 | use=slterm-256color, 218 | km, 219 | rmm=\E[?1034l, 220 | smm=\E[?1034h, 221 | rs2=\E[4l\E>\E[?1034h, 222 | is2=\E[4l\E>\E[?1034h, 223 | )"; 224 | 225 | -------------------------------------------------------------------------------- /src/statusbar.c: -------------------------------------------------------------------------------- 1 | 2 | #include "statusbar.h" 3 | #include "term.h" 4 | #include "mem.h" 5 | #include "config.h" 6 | 7 | 8 | int statusvisible; 9 | Glyph *statusbar = NULL; 10 | char* p_status = NULL; 11 | static int statuswidth = 0; 12 | static int focusdraw = 1; 13 | 14 | 15 | void drawstatus(){ 16 | term->dirty[term->scroll_bottom] = 1; 17 | drawregion(0, term->scroll_bottom, term->cols, term->scroll_bottom + 1); 18 | } 19 | 20 | void statusbar_focusin(){ 21 | if ( !focusdraw && statusvisible && statusbar ){ 22 | focusdraw = 1; 23 | for ( Glyph *g = statusbar; g < &statusbar[statuswidth]; g++) { 24 | g->mode = statusattr; 25 | g->fg = statusfg; 26 | g->bg = statusbg; 27 | 28 | } 29 | drawstatus(); 30 | } 31 | } 32 | 33 | 34 | void statusbar_focusout(){ 35 | if ( focusdraw && statusvisible && statusbar ){ 36 | focusdraw = 0; 37 | for ( Glyph *g = statusbar; g < &statusbar[statuswidth]; g++) { 38 | g->mode = ATTR_REVERSE; 39 | g->fg = defaultfg, 40 | g->bg = defaultbg; 41 | } 42 | drawstatus(); 43 | } 44 | } 45 | 46 | // text entering, textfield 47 | // besser als struct, objektorientiert. 48 | uchar tfbuf[512]; 49 | int tfbuflen = 512; 50 | 51 | int tfpos = 0; // is not necessarily the pos of the cursor. 52 | int tftextlen = 0; 53 | int tfvisible = 0; 54 | 55 | uchar tfinput[512]; 56 | int tfinputlen = 512; 57 | 58 | // callbacks 59 | // 60 | // xkeyboard -> keypress 61 | // verarbeitet input, auch keycombos 62 | // 63 | // tfevent -> receiver (searchwidget) 64 | // sendet: 65 | // textentered (buf) 66 | // search (buf) 67 | // complete (buf) 68 | // 69 | // setcursor(x) -> relative cursor position 70 | // 71 | // redraw() -> receiver (statusbar) 72 | // ->redraw() beide richtungen. d.h. in statusbarupdate: setwidth(), paint(), getcursor() 73 | // 74 | // ->setwidth(x) 75 | // 76 | // ->view,hide 77 | // ->setfocus() 78 | // 79 | // 80 | // eventfilterlist. (Ctrl+F,Tab,ESC, . hm. evtl zu weit.) 81 | // benoetige ein sinnvolles format fuewr die glyphen. 82 | // vermutlich am besten "doppelt". textstring, und glyphlist fuer farbe und attribute. 83 | // 84 | // auch moeglich: die callbacks von sprintf in minilib fuer colorierung schreiben. 85 | // ->sprintf: marker fuer farbe. zb ein Test in %ROT%Farbe 86 | // hatte ja schonmal ein konzept. 87 | // 88 | // sinnvoll, hier, hab keine zeit: variablen und callbacks als struktur. 89 | // 90 | // Rest koennte ich immer noch aufbauen. bspw sender- verteiler -receiver 91 | // usw. 92 | // 93 | // besser: slots. 94 | // in der strukt slot registerkey[], drin struct: key,callback(key,sender) 95 | // -> structs muessen fuer alle widgets eine selbe grundstruktur am anfang haben. 96 | // -> = "parent" class. 97 | // -> sogar die syntax wird nett: struct _textinput { struct widget; ... 98 | // laesst sich dann auch polymorph gestalten. 99 | // create_widget( typ )... setzt callbacks, initialisiert. 100 | // 101 | // kann natuerlich auch macros machen: 102 | // struct widget; wird zu PARENTCLASS widget; 103 | // "public" scheint unpassend. 104 | // genaugenommen: struct _textinput{ CLASS widget; 105 | // und struct _widget{ CLASS object; 106 | // ... 107 | // nicht mal casten notwendig. 108 | // nur upcasten, von object auf widget, usw. 109 | // 110 | // kann ich natuerlich auch gleich mit ids arbeiten. 111 | // fuer jede instanz, und jede klasse. 112 | // 113 | 114 | 115 | 116 | // for the mode MODE_ENTERSTRING 117 | int statusbar_kpress( XKeyEvent *ke, KeySym *ks, char *buf ){ 118 | 119 | return(0); 120 | } 121 | 122 | 123 | 124 | 125 | // updates the statusbar with current line, etc., when visible. 126 | void updatestatus(){ 127 | 128 | if ( !statusvisible ) 129 | return; 130 | 131 | // currently shown number of cols 132 | int stwidth = statuswidth; 133 | if ( term->cols != statuswidth ) 134 | stwidth = term->cols; 135 | 136 | char buf[512]; 137 | memset( buf, ' ', 256 ); 138 | //bzero(buf+256,256); 139 | 140 | //int p = sprintf(buf," %s %5d-%2d %5d %5d %3d%% (%3d%%) RM:%3d", p_status, 141 | int p = 0; 142 | 143 | int fstwidth = stwidth; 144 | 145 | stwidth -= strlen(p_status)+3; // try to keep that much free space at the left 146 | 147 | // scrollinfo 148 | if ( stwidth > 32 + 11 ){ 149 | p = sprintf(buf+256,"%5d-%2d %5d %5d %3d%% (%3d%%) RM:%3d ", 150 | term->histindex-term->scr,term->histindex-term->scr+term->rows, 151 | term->histindex+term->rows, term->histindex+term->rows-(term->histindex-term->scr+term->rows), 152 | ((term->histindex-term->scr)*100)/((term->histindex)?term->histindex:1), 153 | ((term->histindex-term->scr-term->scrollmarks[0]+1)*100)/((term->histindex-term->scrollmarks[0]+1)?term->histindex-term->scrollmarks[0]+1:1), 154 | term->scrolled_retmark 155 | ); 156 | 157 | if ( stwidth > p+10 ){ 158 | for ( int a=1; a<10; a++ ){ 159 | if ( term->scrollmarks[a] ) 160 | buf[p++] = a+'0'; 161 | else 162 | buf[p++] = ' '; 163 | } 164 | if ( term->scrollmarks[0] ) 165 | buf[p++] = '0'; 166 | else 167 | buf[p++] = ' '; 168 | } 169 | 170 | } else if ( stwidth > 20 + 6 ){ //TODO: other values (line number) 171 | p = sprintf(buf+256,"%5d %5d %3d%% RM:%3d ", 172 | term->histindex+term->rows, term->histindex+term->rows-(term->histindex-term->scr+term->rows), 173 | ((term->histindex-term->scr)*100)/((term->histindex)?term->histindex:1), 174 | term->scrolled_retmark ); 175 | } else { 176 | p = sprintf(buf+256,"%5d %3d%% ", 177 | term->histindex+term->rows-(term->histindex-term->scr+term->rows), 178 | ((term->histindex-term->scr)*100)/((term->histindex)?term->histindex:1) ); 179 | } 180 | 181 | //printf("p: %d\n",p); 182 | buf[p] = 0; 183 | 184 | int bp = 256 - fstwidth + p; 185 | if ( bp <0 ) bp = 0; 186 | if ( 256-bp > strlen(p_status) +3 ) 187 | memcpy( buf+bp+3, p_status, strlen(p_status) ); 188 | 189 | setstatus(buf+bp); 190 | } 191 | 192 | 193 | void setstatus(char* status){ 194 | Glyph *deb, *fin; 195 | 196 | if ( term->colalloc != statuswidth ){ 197 | free(statusbar); 198 | statusbar = xmalloc(term->colalloc * sizeof(Glyph)); 199 | //statusbar = xrealloc(statusbar, term->colalloc * sizeof(Glyph)); 200 | statuswidth = term->colalloc; 201 | } 202 | int stwidth = statuswidth; 203 | if ( term->cols != stwidth ) 204 | stwidth = term->cols; 205 | 206 | #ifndef UTF8 207 | Glyph g = { .fg = statusfg, .bg = statusbg, .mode = statusattr, .u = ' ' }; 208 | #endif 209 | 210 | for (deb = statusbar,fin=&statusbar[stwidth]; (deb < fin); deb++) { 211 | #ifdef UTF8 212 | deb->mode = statusattr; 213 | deb->fg = statusfg; 214 | deb->bg = statusbg; 215 | #else 216 | deb->intG = g.intG; 217 | #endif 218 | if ( *status ){ 219 | deb->u = *status; 220 | status++; 221 | } 222 | } 223 | 224 | } 225 | 226 | void showstatus(int show, char *status){ 227 | if ( p_status ){ 228 | free(p_status); 229 | p_status = NULL; 230 | } 231 | 232 | if ( show ){ 233 | p_status = strdup(status); 234 | if ( !statusvisible ){ 235 | statusvisible = 1; 236 | Arg a = { .i=0 }; 237 | kscrollup(&a); // (clears the statusbar). I know. But works. 238 | setstatus(status); 239 | // paint status 240 | redraw(); 241 | } 242 | 243 | } else { 244 | if ( statusvisible ){ 245 | statusvisible = 0; 246 | // clear status 247 | term->dirty[term->scroll_bottom] = 1; 248 | drawregion(0, term->scroll_bottom, term->cols, term->scroll_bottom + 1); 249 | //term->rows++; 250 | //tresize(term->cols,term->rows+1); 251 | } 252 | } 253 | } 254 | 255 | // shows a small message at the bottom right corner 256 | void set_notifmode(int type, KeySym ksym) { 257 | static char *lib[] = {" MOVE ", "SELECT"," LESS " }; 258 | static Glyph *g, *deb, *fin; 259 | static int col, bot; 260 | col = term->cols, bot = term->scroll_bottom; 261 | 262 | if (ksym == -1) { // show 263 | free(g); 264 | g = xmalloc(term->colalloc * sizeof(Glyph)); 265 | memcpy(g, TLINE(bot), term->colalloc * sizeof(Glyph)); 266 | //tresize(term->cols,term->rows-1); 267 | } else if (ksym == -2) { // hide 268 | memcpy(TLINE(bot), g, term->colalloc * sizeof(Glyph)); 269 | //tresize(term->cols,term->rows+1); 270 | } 271 | 272 | if (type < 3) { 273 | char *z = lib[type]; 274 | for (deb = &TLINE(bot)[col - 6], fin = &TLINE(bot)[col]; deb < fin; 275 | z++, deb++) { 276 | deb->mode = ATTR_REVERSE, deb->u = *z, deb->fg = defaultfg, 277 | deb->bg = defaultbg; 278 | } 279 | } else if (type < 5) { 280 | memcpy(TLINE(bot), g, term->colalloc * sizeof(Glyph)); 281 | //memcpy(TLINE(bot), g, term->colalloc * sizeof(Glyph)); 282 | } else { 283 | for (deb = &TLINE(bot)[0], fin = &TLINE(bot)[col]; deb < fin; 284 | deb++) { 285 | deb->mode = ATTR_REVERSE, deb->u = ' ', deb->fg = defaultfg, 286 | deb->bg = defaultbg; 287 | } 288 | TLINE(bot)[0].u = ksym; 289 | } 290 | 291 | term->dirty[bot] = 1; 292 | drawregion(0, bot, col, bot + 1); 293 | } 294 | 295 | -------------------------------------------------------------------------------- /src/statusbar.h: -------------------------------------------------------------------------------- 1 | #ifndef statusbar_h 2 | #define statusbar_h 3 | 4 | 5 | extern int statusvisible; 6 | 7 | int statusbar_kpress( XKeyEvent *ke, KeySym *ks, char *buf ); 8 | void updatestatus(); 9 | void setstatus(char* status); 10 | void statusbar_focusin(); 11 | void statusbar_focusout(); 12 | 13 | 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /src/system.c: -------------------------------------------------------------------------------- 1 | // system related. fork, exec, die 2 | 3 | #include "includes.h" 4 | 5 | 6 | void die(const char *errstr, ...) { 7 | va_list ap; 8 | 9 | va_start(ap, errstr); 10 | vfprintf(stderr, errstr, ap); 11 | va_end(ap); 12 | exit(1); 13 | } 14 | 15 | 16 | void execsh(char *cmd, char **args) { 17 | char *sh, *prog; 18 | const struct passwd *pw; 19 | 20 | errno = 0; 21 | if ((pw = getpwuid(getuid())) == NULL) { 22 | if (errno) { 23 | die("getpwuid: %s\n", strerror(errno)); 24 | } else { 25 | die("Cannout read uid\n"); 26 | } 27 | } 28 | 29 | if ((sh = getenv("SHELL")) == NULL) { 30 | sh = (pw->pw_shell[0]) ? pw->pw_shell : cmd; 31 | } 32 | 33 | if (args) { 34 | prog = args[0]; 35 | } else if (utmp) { 36 | prog = utmp; 37 | } else { 38 | prog = sh; 39 | } 40 | DEFAULT(args, ((char *[]){prog, NULL})); 41 | 42 | unsetenv("COLUMNS"); 43 | unsetenv("LINES"); 44 | unsetenv("TERMCAP"); 45 | setenv("LOGNAME", pw->pw_name, 1); 46 | setenv("USER", pw->pw_name, 1); 47 | setenv("SHELL", sh, 1); 48 | setenv("HOME", pw->pw_dir, 1); 49 | setenv("TERM", termname, 1); 50 | 51 | // define env in config.h 52 | for ( const char **p = (const char**)export_env; *p; p++ ){ 53 | setenv( p[0], p[1], 1 ); 54 | } 55 | 56 | 57 | signal(SIGCHLD, SIG_DFL); 58 | signal(SIGHUP, SIG_DFL); 59 | signal(SIGINT, SIG_DFL); 60 | signal(SIGQUIT, SIG_DFL); 61 | signal(SIGTERM, SIG_DFL); 62 | signal(SIGALRM, SIG_DFL); 63 | 64 | execvp(prog, args); 65 | // didn't work. 66 | // try default, set in config.h.in 67 | execvp(shell,args); 68 | _exit(1); 69 | } 70 | 71 | void sigchld(int a) { 72 | int stat; 73 | pid_t p; 74 | 75 | if ((p = waitpid(shellpid, &stat, WNOHANG)) < 0) { 76 | die("waiting for pid %hd failed: %s\n", shellpid, strerror(errno)); 77 | } 78 | 79 | if (shellpid != p) { 80 | return; 81 | } 82 | 83 | if (WIFEXITED(stat) && WEXITSTATUS(stat)) { 84 | die("child exited with status %d\n", WEXITSTATUS(stat)); 85 | } else if (WIFSIGNALED(stat)) { 86 | die("child terminated due to signal %d\n", WTERMSIG(stat)); 87 | } 88 | exit(0); 89 | } 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/system.h: -------------------------------------------------------------------------------- 1 | #ifndef st_system_h 2 | #define st_system_h 3 | 4 | 5 | void die(const char *errstr, ...); 6 | void execsh(char *, char **); 7 | void sigchld(int a); 8 | 9 | 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /src/term.h: -------------------------------------------------------------------------------- 1 | /* See LICENSE for license details. */ 2 | #ifndef st_H 3 | #define st_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "xevent.h" 13 | 14 | /* macros */ 15 | 16 | #define ATTRCMP(a, b) \ 17 | ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) 18 | 19 | 20 | // get pointer to a line. 21 | // 22 | // todo: rewrite the whole history buffer. 23 | // concept: 24 | // drop t->line and t->hist 25 | // use t->buf instead. 26 | // pos from 0 to UINT_MAX. 27 | // -> only 2 pointers needed: current pos, and scrolled pos. 28 | // fetch and write buffer by limiting to &(HISTSIZE-1). 29 | // when scrolling, obviously limit to currentpos & (HISTSIZE-1). 30 | // funny enough, overflowing UINT_MAX won't be a problem. 31 | // use absolute values in TLINE(line) ( add pos + scroll to line, &(HISTSIZE-1) ) 32 | // use negative - no, positive, since we need in theory scroll up to UINT_NAX lines - 33 | // values for scroll to scroll. scrolling to 0 = pos. 34 | 35 | //#define TLINETOBUF( _y ) ( _y+ term->linebufpos & 36 | 37 | 38 | // get the pointer to a line, depending on scroll 39 | #define TLINE(y) \ 40 | ((y) < term->scr \ 41 | ? term->hist[( (y) + term->histindex - term->scr +1 ) & (term->histsize) ] : term->line[ (y) - term->scr ]) 42 | //? term->hist[( (y) + term->histindex - term->scr +1 ) & (HISTSIZE-1) ] : term->line[ (y) - term->scr ]) 43 | 44 | //? term->hist[(((y) + term->histindex - term->scr + HISTSIZE +1 ) ^ HISTSIZE ) & (HISTSIZE-1) ] : term->line[(y)-term->scr]) 45 | 46 | 47 | #define ISDELIM(u) (u && wcschr(worddelimiters, u)) 48 | 49 | // inputmode. switchable via lessmode_toggle 50 | //extern int inputmode; 51 | 52 | enum term_mode { 53 | MODE_WRAP = 1 << 0, 54 | MODE_INSERT = 1 << 1, 55 | MODE_ALTSCREEN = 1 << 2, 56 | MODE_CRLF = 1 << 3, 57 | MODE_ECHO = 1 << 4, 58 | MODE_PRINT = 1 << 5, 59 | #ifdef UTF8 60 | MODE_UTF8 = 1 << 6, 61 | #else 62 | MODE_UTF8 = 0, 63 | #endif 64 | MODE_SIXEL = 1 << 7, 65 | TMODE_HELP = 1 << 8, 66 | }; 67 | 68 | 69 | 70 | #ifndef HISTSIZEBITS 71 | // Should be set in config.h 72 | #define HISTSIZEBITS 11 73 | #endif 74 | 75 | #if (HISTSIZEBITS>20) 76 | #error You most possibly do not want a history with a length > 1.000.000 77 | #error Either change HISTSIZEBITS accordingly, or edit the sources 78 | #endif 79 | 80 | 81 | #define HISTSIZE (1<rows; 45 | w.ws_col = term->cols; 46 | w.ws_xpixel = tw; 47 | w.ws_ypixel = th; 48 | if (ioctl(cmdfd, TIOCSWINSZ, &w) < 0) { 49 | fprintf(stderr, "Couldn't set window size: %s\n", strerror(errno)); 50 | } 51 | } 52 | 53 | void stty(char **args) { 54 | char cmd[_POSIX_ARG_MAX], **p, *q, *s; 55 | size_t n, siz; 56 | 57 | if ((n = strlen(stty_args)) > sizeof(cmd) - 1) { 58 | die("incorrect stty parameters\n"); 59 | } 60 | memcpy(cmd, stty_args, n); 61 | q = cmd + n; 62 | siz = sizeof(cmd) - n; 63 | for (p = args; p && (s = *p); ++p) { 64 | if ((n = strlen(s)) > siz - 1) { 65 | die("stty parameter length too long\n"); 66 | } 67 | *q++ = ' '; 68 | memcpy(q, s, n); 69 | q += n; 70 | siz -= n + 1; 71 | } 72 | *q = '\0'; 73 | if (system(cmd) != 0) { 74 | perror("Couldn't call stty"); 75 | } 76 | } 77 | 78 | int ttynew(char *line, char *cmd, char *out, char **args) { 79 | int m, s; 80 | 81 | if (out) { 82 | term->mode |= MODE_PRINT; 83 | iofd = (!strcmp(out, "-")) ? 1 : open(out, O_WRONLY | O_CREAT, 0666); 84 | if (iofd < 0) { 85 | fprintf(stderr, "Error opening %s:%s\n", out, strerror(errno)); 86 | } 87 | } 88 | 89 | if (line) { 90 | if ((cmdfd = open(line, O_RDWR)) < 0) { 91 | die("open line '%s' failed: %s\n", line, strerror(errno)); 92 | } 93 | dup2(cmdfd, 0); 94 | stty(args); 95 | return cmdfd; 96 | } 97 | 98 | /* seems to work fine on linux, openbsd and freebsd */ 99 | if (openpty(&m, &s, NULL, NULL, NULL) < 0) { 100 | die("openpty failed: %s\n", strerror(errno)); 101 | } 102 | 103 | switch (shellpid = fork()) { 104 | case -1: 105 | die("fork failed: %s\n", strerror(errno)); 106 | break; 107 | case 0: 108 | close(iofd); 109 | setsid(); /* create a new process group */ 110 | dup2(s, 0); 111 | dup2(s, 1); 112 | dup2(s, 2); 113 | if (ioctl(s, TIOCSCTTY, NULL) < 0) { 114 | die("ioctl TIOCSCTTY failed: %s\n", strerror(errno)); 115 | } 116 | close(s); 117 | close(m); 118 | #ifdef __OpenBSD__ 119 | if (pledge("stdio getpw proc exec", NULL) == -1) { 120 | die("pledge\n"); 121 | } 122 | #endif 123 | execsh(cmd, args); 124 | break; 125 | default: 126 | #ifdef __OpenBSD__ 127 | if (pledge("stdio rpath tty proc", NULL) == -1) { 128 | die("pledge\n"); 129 | } 130 | #endif 131 | close(s); 132 | cmdfd = m; 133 | signal(SIGCHLD, sigchld); 134 | break; 135 | } 136 | return cmdfd; 137 | } 138 | 139 | size_t ttyread(void) { 140 | static utfchar buf[BUFSIZ]; 141 | static int buflen = 0; 142 | int written; 143 | int ret; 144 | 145 | /* append read bytes to unprocessed bytes */ 146 | if ((ret = read(cmdfd, buf + buflen, LEN(buf) - buflen)) < 0) { 147 | die("couldn't read from shell: %s\n", strerror(errno)); 148 | } 149 | buflen += ret; 150 | 151 | dbg("ttyread, ret: %d, buflen: %d, buf[0] %c", ret, buflen, buf[0]); 152 | 153 | written = twrite(buf, buflen, 0); 154 | buflen -= written; 155 | /* keep any uncomplete utf8 char for the next call */ 156 | if (buflen > 0) { 157 | memmove(buf, buf + written, buflen); 158 | } 159 | 160 | return ret; 161 | } 162 | 163 | // writes to the terminal / shell 164 | void ttywrite(const utfchar *s, size_t n, int may_echo) { 165 | const utfchar *next; 166 | Arg arg = (Arg){.i = term->scr}; 167 | 168 | // don't scroll on new output, when in lessmode. 169 | if ( !(inputmode & MODE_LESS) ) 170 | kscrolldown(&arg); 171 | 172 | dbg("ttywrite %d %x %c", n, s[0], s[0]); 173 | if (may_echo && IS_SET(MODE_ECHO)) { 174 | dbg("t1\n"); 175 | twrite(s, n, 1); 176 | } 177 | 178 | if (!IS_SET(MODE_CRLF)) { 179 | dbg("t2\n"); 180 | ttywriteraw(s, n); 181 | return; 182 | } 183 | 184 | dbg("ttywrite2 %d %x %c\n", n, s[0], s[0]); 185 | /* This is similar to how the kernel handles ONLCR for ttys */ 186 | while (n > 0) { 187 | dbg("ttywrite3 %d %x %c\n", n, s[0], s[0]); 188 | if (*s == '\r') { 189 | next = s + 1; 190 | ttywriteraw((uchar*)"\r\n", 2); 191 | } else { 192 | next = memchr(s, '\r', n); 193 | DEFAULT(next, s + n); 194 | ttywriteraw(s, next - s); 195 | } 196 | n -= next - s; 197 | s = next; 198 | } 199 | } 200 | 201 | 202 | void ttywriteraw(const utfchar *s, size_t n) { 203 | fd_set wfd, rfd; 204 | ssize_t r; 205 | size_t lim = 256; 206 | 207 | dbg("ttywriteraw n: %d s[0]: %c\n", n, s[0]); 208 | 209 | /* 210 | * Remember that we are using a pty, which might be a modem line. 211 | * Writing too much will clog the line. That's why we are doing this 212 | * dance. 213 | * FIXME: Migrate the world to Plan 9. 214 | */ 215 | while (n > 0) { 216 | FD_ZERO(&wfd); 217 | FD_ZERO(&rfd); 218 | FD_SET(cmdfd, &wfd); 219 | FD_SET(cmdfd, &rfd); 220 | 221 | dbg("ttywriteraw while n: %d s[0]: %c\n", n, s[0]); 222 | /* Check if we can write. */ 223 | if (pselect(cmdfd + 1, &rfd, &wfd, NULL, NULL, NULL) < 0) { 224 | if (errno == EINTR) { 225 | continue; 226 | } 227 | die("select failed: %s\n", strerror(errno)); 228 | } 229 | if (FD_ISSET(cmdfd, &wfd)) { 230 | /* 231 | * Only write the bytes written by ttywrite() or the 232 | * default of 256. This seems to be a reasonable value 233 | * for a serial line. Bigger values might clog the I/O. 234 | */ 235 | if ((r = write(cmdfd, s, (n < lim) ? n : lim)) < 0) { 236 | goto write_error; 237 | } 238 | dbg("ttywriteraw n: %d s[0]: %c lim: %d r: %d", n, s[0], lim, r); 239 | if (r < n) { 240 | /* 241 | * We weren't able to write out everything. 242 | * This means the buffer is getting full 243 | * again. Empty it. 244 | */ 245 | if (n < lim) { 246 | lim = ttyread(); 247 | } 248 | n -= r; 249 | s += r; 250 | } else { 251 | /* All bytes have been written. */ 252 | break; 253 | } 254 | } 255 | if (FD_ISSET(cmdfd, &rfd)) { 256 | lim = ttyread(); 257 | } 258 | } 259 | return; 260 | 261 | write_error: 262 | die("write error on tty: %s\n", strerror(errno)); 263 | } 264 | 265 | 266 | -------------------------------------------------------------------------------- /src/tty.h: -------------------------------------------------------------------------------- 1 | #ifndef stTTY_H 2 | #define stTTY_H 3 | 4 | extern char *stty_args; 5 | 6 | extern int iofd; 7 | extern int cmdfd; 8 | 9 | 10 | void ttyresize(int, int); 11 | void stty(char **); 12 | void sigchld(int); 13 | void ttywriteraw(const utfchar *, size_t); 14 | void sendbreak(const Arg *); 15 | void tprinter(char *s, size_t len); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/utf8.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "utf8.h" 4 | #include "term.h" 5 | 6 | #ifdef UTF8 7 | static uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; 8 | static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; 9 | static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; 10 | static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; 11 | #else 12 | static uchar utfbyte[UTF_SIZ + 4] = {0x80, 0, 0xC0, 0xE0, 0xF0}; 13 | static uchar utfmask[UTF_SIZ + 4] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; 14 | static Rune utfmin[UTF_SIZ + 4] = {0, 0, 0x80, 0x0, 0x0}; 15 | static Rune utfmax[UTF_SIZ + 4] = {0xFF, 0x7F, 0xFF, 0xFF, 0xFF}; 16 | #endif 17 | 18 | 19 | size_t utf8validate(Rune *u, size_t i) { 20 | if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) { 21 | *u = UTF_INVALID; 22 | } 23 | for (i = 1; *u > utfmax[i]; ++i) { 24 | } 25 | 26 | return i; 27 | } 28 | 29 | char utf8encodebyte(Rune u, size_t i) { return utfbyte[i] | (u & ~utfmask[i]); } 30 | 31 | #ifdef UTF8 32 | char *utf8strchr(char *s, Rune u) { 33 | Rune r; 34 | size_t i, j, len; 35 | 36 | len = strlen(s); 37 | for (i = 0, j = 0; i < len; i += j) { 38 | if (!(j = utf8decode(&s[i], &r, len - i))) 39 | break; 40 | if (r == u) 41 | return &(s[i]); 42 | } 43 | 44 | return NULL; 45 | } 46 | #endif 47 | 48 | 49 | size_t utf8decode(const char *c, Rune *u, size_t clen) { 50 | size_t i, j, len, type; 51 | Rune udecoded; 52 | 53 | *u = UTF_INVALID; 54 | if (!clen) { 55 | return 0; 56 | } 57 | udecoded = utf8decodebyte(c[0], &len); 58 | if (!BETWEEN(len, 1, UTF_SIZ)) { 59 | return 1; 60 | } 61 | for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { 62 | udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); 63 | if (type != 0) { 64 | return j; 65 | } 66 | } 67 | if (j < len) { 68 | return 0; 69 | } 70 | *u = udecoded; 71 | utf8validate(u, len); 72 | 73 | return len; 74 | } 75 | 76 | Rune utf8decodebyte(char c, size_t *i) { 77 | for (*i = 0; *i < LEN(utfmask); ++(*i)) { 78 | if (((uchar)c & utfmask[*i]) == utfbyte[*i]) { 79 | return (uchar)c & ~utfmask[*i]; 80 | } 81 | } 82 | 83 | return 0; 84 | } 85 | 86 | size_t utf8encode(Rune u, char *c) { 87 | #ifndef UTF8 88 | c[0] = u; 89 | return 1; 90 | #else 91 | size_t len, i; 92 | 93 | len = utf8validate(&u, 0); 94 | if (len > UTF_SIZ) { 95 | return 0; 96 | } 97 | 98 | for (i = len - 1; i != 0; --i) { 99 | c[i] = utf8encodebyte(u, 0); 100 | u >>= 6; 101 | } 102 | c[0] = utf8encodebyte(u, len); 103 | 104 | return len; 105 | #endif 106 | } 107 | 108 | 109 | -------------------------------------------------------------------------------- /src/utf8.h: -------------------------------------------------------------------------------- 1 | #ifndef utf8_h 2 | #define utf8_h 3 | 4 | #include 5 | 6 | 7 | #ifdef UTF8 8 | typedef uint_least32_t Rune; 9 | #else 10 | typedef unsigned char Rune; 11 | #endif 12 | 13 | 14 | size_t utf8decode(const char *c, Rune *u, size_t clen); 15 | size_t utf8encode(Rune u, char *c); 16 | size_t utf8validate(Rune *u, size_t i); 17 | char utf8encodebyte(Rune u, size_t i); 18 | Rune utf8decodebyte(char c, size_t *i); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/xclipboard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | // clipboard 5 | typedef struct { 6 | Atom xtarget; 7 | char *primary, *clipboard; 8 | struct timespec tclick1; 9 | struct timespec tclick2; 10 | } XSelection; 11 | 12 | 13 | extern XSelection xsel; 14 | 15 | 16 | //clipboard events 17 | void selnotify(XEvent *); 18 | void selclear_(XEvent *); 19 | void selrequest(XEvent *); 20 | 21 | void clipcopy(const Arg *); 22 | void clippaste(const Arg *); 23 | void selpaste(const Arg *); 24 | 25 | -------------------------------------------------------------------------------- /src/xcursor.c: -------------------------------------------------------------------------------- 1 | // cursor drawing and 2 | // cursor color functions 3 | // 4 | 5 | #include "xcursor.h" 6 | 7 | 8 | int _xsetcursor(int cursor, int attr) { 9 | DEFAULT(cursor, 1); 10 | if (!BETWEEN(cursor, 0, 12)) 11 | return 1; 12 | twin.cursor = cursor; 13 | twin.cursor_attr[0] = attr; 14 | return 0; 15 | } 16 | 17 | int xgetcursor(){ 18 | return(twin.cursor); 19 | } 20 | 21 | 22 | Color *getcursorcolor( Glyph g, int cx, int cy ){ 23 | Color *col; 24 | Color drawcol; 25 | if ( g.bg == defaultbg ){ 26 | col = &dc.color_array[defaultcs]; 27 | } else { 28 | if ( !( col = getcachecolor( 2, &g, twin.mode ) ) ){ 29 | col = xdrawglyph(g, cx, cy); // unneccessary, but need the bg color 30 | 31 | // invert bgcolor 32 | XRenderColor csc; 33 | //#define ASB(c) csc.c = 0xff-col->color.c //~col->color.c 34 | #define ASB(c) csc.c = ~col->color.c 35 | ASB(red);ASB(green);ASB(blue); 36 | #undef ASB 37 | XftColorAllocValue(xwin.dpy, xwin.vis, xwin.cmap, &csc, &drawcol); 38 | col = cachecolor(2,&g,twin.mode,&drawcol); 39 | //col = &drawcol; 40 | } 41 | 42 | } 43 | 44 | return(col); 45 | } 46 | 47 | void xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) { 48 | Color drawcol; 49 | static int focusinx, focusiny; 50 | uchar tmp; 51 | Color *col = 0; 52 | 53 | // hide cursor in lessmode 54 | if (inputmode&MODE_LESS && !(twin.mode & MODE_KBDSELECT)) 55 | return; 56 | 57 | //printf("xdrawcursor: %d %d, %d %d, %d\n",cx,cy,ox,oy, term->scr); 58 | 59 | /* remove the old cursor */ 60 | if (selected(ox, oy)) 61 | og.mode ^= ATTR_REVERSE; 62 | 63 | xdrawglyph(og, ox, oy); 64 | 65 | /* 66 | * Select the right color for the right mode. 67 | */ 68 | /* 69 | #ifdef UTF8 70 | g.mode &= ATTR_BOLD | ATTR_ITALIC | ATTR_UNDERLINE | ATTR_STRUCK | ATTR_WIDE; 71 | #else 72 | g.mode &= ATTR_BOLD | ATTR_ITALIC | ATTR_UNDERLINE | ATTR_STRUCK; 73 | #endif 74 | 75 | if (IS_SET(MODE_REVERSE)) { 76 | g.mode |= ATTR_REVERSE; 77 | g.bg = defaultfg; 78 | if (selected(cx, cy)) { 79 | drawcol = dc.color_array[defaultrcs]; 80 | g.fg = defaultbg; 81 | } else { 82 | drawcol = dc.color_array[defaultrcs]; 83 | g.fg = defaultbg; 84 | } 85 | } else { 86 | if (selected(cx, cy)) { 87 | g.fg = defaultfg; 88 | g.bg = defaultrcs; 89 | } else { 90 | g.fg = defaultbg; 91 | g.bg = defaultcs; 92 | } 93 | drawcol = dc.color_array[g.bg]; 94 | } 95 | */ 96 | 97 | /* draw text cursor */ 98 | if (IS_SET(MODE_FOCUSED)) { 99 | 100 | switch (twin.cursor) { 101 | case 7: /* st extension: snowman (U+2603) */ 102 | // g.u = 0x2603; 103 | if ( twin.cursor_attr[0] ) 104 | g.u = twin.cursor_attr[0]; 105 | else 106 | g.u = 'X'; 107 | g.bg = 9; 108 | case 0: /* Blinking Block */ 109 | case 1: /* Blinking Block */ // doesnt work out. I dislike blinking anyways. 110 | // Thats a feature! 111 | //g.mode |= ATTR_BLINK | ATTR_REVERSE; 112 | //term->cursor.attr.mode |= ATTR_BLINK; 113 | //printf("blc\n"); 114 | //term->cursor.attr.mode |= ATTR_BLINK; 115 | //tsetdirtattr(ATTR_BLINK); 116 | //xdrawglyph(g, cx, cy); 117 | //break; 118 | case 2: /* Steady Block */ 119 | //if ( g.bg == defaultbg ){ 120 | // g.bg = defaultcs; 121 | //} else { 122 | //if ( (twin.cursor==2) || !( twin.mode & MODE_BLINK )){ 123 | tmp = g.fg; 124 | g.fg = g.bg; 125 | g.bg = tmp; 126 | //} 127 | //} 128 | xdrawglyph(g, cx, cy); 129 | break; 130 | 131 | case 3: /* Blinking Underline */ 132 | case 4: /* Steady Underline */ 133 | case 8: // double underline 134 | if ( focusinx == cx && focusiny == cy ) { // highlight cursor on focusin 135 | g.bg = 208; 136 | g.fg = 4; 137 | xdrawglyph(g, cx, cy); 138 | 139 | drawcol = dc.color_array[1]; 140 | 141 | // underline 142 | drawcol = dc.color_array[defaultcs]; 143 | XftDrawRect(xwin.draw, &drawcol, twin.hborderpx + cx * twin.cw, 144 | twin.vborderpx + (cy + 1) * twin.ch - cursorthickness, twin.cw, 145 | cursorthickness); 146 | 147 | } else { // draw cursor as underline 148 | focusinx=focusiny=0; 149 | //drawcol = dc.color_array[defaultcs]; 150 | 151 | col = getcursorcolor( g, cx, cy ); 152 | 153 | if ( twin.cursor == 8 ){ // double underline 154 | XftDrawRect(xwin.draw, col, 155 | twin.hborderpx + cx * twin.cw, 156 | twin.vborderpx + (cy + 1) * twin.ch - 1, twin.cw, 1); 157 | XftDrawRect(xwin.draw, col, 158 | twin.hborderpx + cx * twin.cw, 159 | twin.vborderpx + (cy + 1) * twin.ch - 3, twin.cw, 1); 160 | } else { // underline 161 | XftDrawRect(xwin.draw, col, twin.hborderpx + cx * twin.cw, 162 | twin.vborderpx + (cy + 1) * twin.ch - cursorthickness, twin.cw, 163 | cursorthickness); 164 | } 165 | 166 | } 167 | break; 168 | 169 | case 5: /* Blinking bar */ 170 | case 6: /* Steady bar */ 171 | col = getcursorcolor( g, cx, cy ); 172 | 173 | XftDrawRect(xwin.draw, col, twin.hborderpx + cx * twin.cw, 174 | twin.vborderpx + (cy) * twin.ch, cursorthickness, twin.ch); 175 | break; 176 | 177 | case 9: // empty block, unfilled 178 | col = getcursorcolor( g, cx, cy ); 179 | 180 | // upper line 181 | XftDrawRect(xwin.draw, col, twin.hborderpx + cx * twin.cw, 182 | twin.vborderpx + cy * twin.ch, twin.cw - 1, 1); 183 | 184 | // lines at sides 185 | XftDrawRect(xwin.draw, col, twin.hborderpx + cx * twin.cw, 186 | twin.vborderpx + cy * twin.ch, 1, twin.ch); 187 | 188 | XftDrawRect(xwin.draw, col, twin.hborderpx + (cx + 1) * twin.cw - 1, 189 | twin.vborderpx + cy * twin.ch, 1, twin.ch); 190 | 191 | // lower line 192 | XftDrawRect(xwin.draw, col, twin.hborderpx + cx * twin.cw, 193 | twin.vborderpx + (cy + 1) * twin.ch -1, twin.cw, 1); 194 | 195 | break; 196 | 197 | case 11: // 198 | case 10: // bar with two lines at the sides 199 | col = getcursorcolor( g, cx, cy ); 200 | // lower cursor part 201 | XftDrawRect(xwin.draw, col, twin.hborderpx + cx * twin.cw, 202 | (twin.vborderpx + cy * twin.ch )+(twin.ch*12)/16, 1, twin.ch-twin.ch*12/16 ); 203 | 204 | XftDrawRect(xwin.draw, col, twin.hborderpx + (cx + 1) * twin.cw - 1, 205 | (twin.vborderpx + cy * twin.ch )+(twin.ch*12)/16, 1, twin.ch-twin.ch*12/16 ); 206 | 207 | XftDrawRect(xwin.draw, col, twin.hborderpx + cx * twin.cw, 208 | twin.vborderpx + (cy + 1) * twin.ch -1, twin.cw, 1); 209 | 210 | if ( twin.cursor == 10 ) 211 | break; 212 | 213 | case 12: 214 | if ( !col ) col = getcursorcolor( g, cx, cy ); 215 | // upper line 216 | XftDrawRect(xwin.draw, col, twin.hborderpx + cx * twin.cw, 217 | twin.vborderpx + cy * twin.ch, twin.cw - 1, 1); 218 | 219 | // lines at sides 220 | XftDrawRect(xwin.draw, col, twin.hborderpx + cx * twin.cw, 221 | twin.vborderpx + cy * twin.ch, 1, twin.ch-twin.ch*12/16); 222 | XftDrawRect(xwin.draw, col, twin.hborderpx + (cx + 1) * twin.cw - 1, 223 | twin.vborderpx + cy * twin.ch, 1, twin.ch-twin.ch*12/16); 224 | break; 225 | 226 | case 13: // unfinished 227 | col = getcursorcolor( g, cx, cy ); 228 | // a cross 229 | XftDrawRect(xwin.draw, col, twin.hborderpx + cx * twin.cw + twin.cw/2 , 230 | twin.vborderpx + cy * twin.ch+3, 1, twin.ch - twin.ch*12/16); 231 | XftDrawRect(xwin.draw, col, (twin.hborderpx + cx * twin.cw) + 2, 232 | twin.vborderpx + cy * twin.ch + (twin.ch/2)-1, twin.ch - twin.ch*12/16, 1); 233 | break; 234 | 235 | 236 | 237 | } 238 | } else { // window hasn't the focus. 239 | //g.fg = unfocusedrcs; 240 | drawcol = dc.color_array[unfocusedrcs]; 241 | XftDrawRect(xwin.draw, &drawcol, twin.hborderpx + cx * twin.cw, 242 | twin.vborderpx + cy * twin.ch, twin.cw - 1, 1); 243 | XftDrawRect(xwin.draw, &drawcol, twin.hborderpx + cx * twin.cw, 244 | twin.vborderpx + cy * twin.ch, 1, twin.ch-twin.ch/16*12); 245 | XftDrawRect(xwin.draw, &drawcol, twin.hborderpx + (cx + 1) * twin.cw - 1, 246 | twin.vborderpx + cy * twin.ch, 1, twin.ch-twin.ch/16*12); 247 | 248 | 249 | XftDrawRect(xwin.draw, &drawcol, twin.hborderpx + cx * twin.cw, 250 | (twin.vborderpx + cy * twin.ch )+(twin.ch/16)*12, 1, twin.ch-twin.ch/16*12); 251 | XftDrawRect(xwin.draw, &drawcol, twin.hborderpx + (cx + 1) * twin.cw - 1, 252 | twin.vborderpx + cy * twin.ch + (twin.ch/16)*12, 1, twin.ch-twin.ch/16*12); 253 | XftDrawRect(xwin.draw, &drawcol, twin.hborderpx + cx * twin.cw, 254 | twin.vborderpx + (cy + 1) * twin.ch -1, twin.cw, 1); 255 | focusinx = cx; 256 | focusiny = cy; 257 | } 258 | } 259 | 260 | 261 | -------------------------------------------------------------------------------- /src/xcursor.h: -------------------------------------------------------------------------------- 1 | // cursor drawing and 2 | // cursor color functions 3 | 4 | #pragma once 5 | 6 | 7 | int _xsetcursor(int cursor, int attr); 8 | #define __xsetcursor(_a,_b,...) _xsetcursor(_a,_b) 9 | #define xsetcursor(_cursor,...) __xsetcursor(_cursor,__VA_OPT__(__VA_ARGS__,) 0 ) 10 | 11 | int xgetcursor(); 12 | 13 | Color *getcursorcolor( Glyph g, int cx, int cy ); 14 | 15 | void xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og); 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/xdraw.h: -------------------------------------------------------------------------------- 1 | #ifndef xdraw_h 2 | #define xdraw_h 3 | 4 | 5 | // Returns the used background color 6 | Color* xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); 7 | // Returns the used background color 8 | Color* xdrawglyph(Glyph, int, int); 9 | void xclear(int, int, int, int); 10 | 11 | int xstartdraw(void); 12 | 13 | void xdrawcursor(int, int, Glyph, int, int, Glyph); 14 | void xdrawline(Line, int, int, int); 15 | void xfinishdraw(void); 16 | 17 | 18 | 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /src/xevent.c: -------------------------------------------------------------------------------- 1 | // input event handling 2 | // 3 | // 4 | 5 | #include "xevent.h" 6 | 7 | /* the configuration is in config.h (generated from config.h.in) */ 8 | #include "config.h" 9 | 10 | 11 | 12 | 13 | // The callbacks for the different Events are egistered here. 14 | void (*handler[LASTEvent])(XEvent *) = { 15 | [KeyPress] = kpress, 16 | [ClientMessage] = cmessage, 17 | [ConfigureNotify] = resize, 18 | [VisibilityNotify] = visibility, 19 | [UnmapNotify] = unmap, 20 | [Expose] = expose, 21 | [FocusIn] = focus, 22 | [FocusOut] = focus, 23 | [MotionNotify] = bmotion, 24 | [ButtonPress] = bpress, 25 | [ButtonRelease] = brelease, 26 | /* 27 | * Uncomment if you want the selection to disappear when you select 28 | * something different in another window. 29 | */ 30 | /* [SelectionClear] = selclear_, */ 31 | [SelectionNotify] = selnotify, 32 | /* 33 | * PropertyNotify is only turned on when there is some INCR transfer 34 | * happening for the selection retrieval. 35 | */ 36 | [PropertyNotify] = propnotify, 37 | [SelectionRequest] = selrequest, 38 | }; 39 | 40 | 41 | // the main event loop 42 | void run() { 43 | XEvent ev; 44 | int w = twin.w, h = twin.h; 45 | fd_set rfd; 46 | int xfd = XConnectionNumber(xwin.dpy), xev, blinkset = 0, dodraw = 0; 47 | int ttyfd; 48 | struct timespec drawtimeout, *tv = NULL, now, last, lastblink; 49 | long deltatime; 50 | 51 | /* Waiting for window mapping */ 52 | do { 53 | XNextEvent(xwin.dpy, &ev); 54 | /* 55 | * This XFilterEvent call is required because of XOpenIM. It 56 | * does filter out the key event and some client message for 57 | * the input method too. 58 | */ 59 | if (XFilterEvent(&ev, None)) 60 | continue; 61 | if (ev.type == ConfigureNotify) { 62 | w = ev.xconfigure.width; 63 | h = ev.xconfigure.height; 64 | } 65 | } while (ev.type != MapNotify); 66 | 67 | // also start shell in ttynew. args are global. somewhere. 68 | ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd); 69 | cresize(w, h); 70 | 71 | clock_gettime(CLOCK_MONOTONIC, &last); 72 | lastblink = last; 73 | 74 | xev = (1<> xfps_shift; 101 | //drawtimeout.tv_nsec = (1000 * 1E6) / xfps; 102 | tv = &drawtimeout; 103 | 104 | dodraw = 0; 105 | if (blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) { 106 | tsetdirtattr(ATTR_BLINK); 107 | twin.mode ^= MODE_BLINK; // read in xdraw. 108 | lastblink = now; 109 | dodraw = 1; 110 | } 111 | deltatime = TIMEDIFF(now, last); 112 | if (deltatime > (1000 >> (xev ? xfps_shift : actionfps_shift) ) ) { 113 | dodraw = 1; 114 | last = now; 115 | } 116 | 117 | if (dodraw) { 118 | while (XPending(xwin.dpy)) { 119 | XNextEvent(xwin.dpy, &ev); 120 | if (XFilterEvent(&ev, None)) 121 | continue; 122 | if (handler[ev.type]) // process x events 123 | (handler[ev.type])(&ev); 124 | } 125 | 126 | draw(); 127 | XFlush(xwin.dpy); 128 | 129 | if (xev && !FD_ISSET(xfd, &rfd)) 130 | xev--; 131 | if (!FD_ISSET(ttyfd, &rfd) && !FD_ISSET(xfd, &rfd)) { 132 | if (blinkset) { 133 | if (TIMEDIFF(now, lastblink) > blinktimeout) { 134 | drawtimeout.tv_nsec = 1000; 135 | } else { 136 | drawtimeout.tv_nsec = 137 | ((long)(blinktimeout - TIMEDIFF(now, lastblink)) << 20); 138 | //(1E6 * (blinktimeout - TIMEDIFF(now, lastblink))); 139 | } 140 | // drawtimeout.tv_nsec = ( drawtimeout.tv_nsec - ( drawtimeout.tv_sec = (drawtimeout.tv_nsec >> 9 )) >>9) ; // 141 | //drawtimeout.tv_sec = drawtimeout.tv_nsec / 1E9; // Thats bad misc 142 | //drawtimeout.tv_nsec %= (long)1E9; // Better don't divide 143 | // 144 | // better shift ? division is the most expensive operation. 145 | // Anyways. doesn't seem to be a big difference. I'm however wondering. 146 | // More strange. E.g. dividing by 512 prevents blinking??? 147 | // Ok. I confused exponential and hexadecimal. It's exponential. 148 | // 1E9 equals 1.000.000.000 149 | // 2^30 might be close enough 150 | 151 | drawtimeout.tv_sec = (drawtimeout.tv_nsec >> 30); // .. 152 | drawtimeout.tv_nsec -= (long)(drawtimeout.tv_sec << 30); 153 | } else { 154 | tv = NULL; 155 | } 156 | } 157 | } 158 | } 159 | } 160 | void toggle_winmode(int flag) { twin.mode ^= flag; } 161 | 162 | 163 | void ttysend(const Arg *arg) { ttywrite((utfchar*)arg->s, strlen(arg->s), 1); } 164 | 165 | 166 | 167 | void resize(XEvent *e) { 168 | if (e->xconfigure.width == twin.w && e->xconfigure.height == twin.h) 169 | return; 170 | 171 | cresize(e->xconfigure.width, e->xconfigure.height); 172 | } 173 | 174 | void cmessage(XEvent *e) { 175 | /* 176 | * See xembed specs 177 | * http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html 178 | */ 179 | if (e->xclient.message_type == xwin.xembed && e->xclient.format == 32) { 180 | if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) { 181 | twin.mode |= MODE_FOCUSED; 182 | xseturgency(0); 183 | } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { 184 | twin.mode &= ~MODE_FOCUSED; 185 | } 186 | } else if (e->xclient.data.l[0] == xwin.wmdeletewin) { 187 | ttyhangup(); 188 | exit(0); 189 | } 190 | } 191 | 192 | #define FCB 4 193 | void focus(XEvent *ev) { 194 | XFocusChangeEvent *e = &ev->xfocus; 195 | 196 | if (e->mode == NotifyGrab) 197 | return; 198 | static int colorsaved = 0; 199 | static Color tmp; 200 | if ( !colorsaved ){ 201 | tmp = dc.color_array[FCB]; 202 | colorsaved = 1; 203 | } 204 | 205 | if (ev->type == FocusIn) { 206 | if ( !( twin.mode & MODE_FOCUSED) ){ 207 | twin.mode |= MODE_FOCUSED; 208 | XSetICFocus(xwin.xic); 209 | xseturgency(0); 210 | if (IS_SET(MODE_FOCUS)) 211 | ttywrite((utfchar*)"\033[I", 3, 0); 212 | statusbar_focusin(); 213 | dc.color_array[FCB] = tmp; 214 | redraw(); 215 | } 216 | 217 | } else { // focus out 218 | if ( ( twin.mode & MODE_FOCUSED) ){ 219 | twin.mode &= ~MODE_FOCUSED; 220 | XUnsetICFocus(xwin.xic); 221 | if (IS_SET(MODE_FOCUS)) 222 | ttywrite((utfchar*)"\033[O", 3, 0); 223 | statusbar_focusout(); 224 | dc.color_array[FCB] = dc.color_array[7]; 225 | redraw(); 226 | } 227 | 228 | } 229 | } 230 | 231 | 232 | void expose(XEvent *ev) { redraw(); } 233 | 234 | void visibility(XEvent *ev) { 235 | XVisibilityEvent *e = &ev->xvisibility; 236 | 237 | MODBIT(twin.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE); 238 | } 239 | 240 | void unmap(XEvent *ev) { twin.mode &= ~MODE_VISIBLE; } 241 | 242 | void propnotify(XEvent *e) { 243 | XPropertyEvent *xpev; 244 | Atom clipboard = XInternAtom(xwin.dpy, "CLIPBOARD", 0); 245 | 246 | xpev = &e->xproperty; 247 | if (xpev->state == PropertyNewValue && 248 | (xpev->atom == XA_PRIMARY || xpev->atom == clipboard)) { 249 | selnotify(e); 250 | } 251 | } 252 | 253 | 254 | 255 | -------------------------------------------------------------------------------- /src/xevent.h: -------------------------------------------------------------------------------- 1 | #ifndef input_h 2 | #define input_h 3 | #include 4 | 5 | extern void (*handler[LASTEvent])(XEvent *); 6 | 7 | 8 | //void tty_send_unicode(const Arg *arg); 9 | 10 | 11 | /* XEMBED messages */ 12 | #define XEMBED_FOCUS_IN 4 13 | #define XEMBED_FOCUS_OUT 5 14 | 15 | 16 | // the main event loop 17 | void run(); 18 | 19 | // callbacks 20 | //void temp(const Arg *); 21 | 22 | 23 | // event handling 24 | 25 | // xwindow related 26 | void expose(XEvent *); 27 | void visibility(XEvent *); 28 | void unmap(XEvent *); 29 | void cmessage(XEvent *); 30 | void resize(XEvent *); 31 | void focus(XEvent *); 32 | void propnotify(XEvent *); 33 | 34 | 35 | 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /src/xkeyboard.c: -------------------------------------------------------------------------------- 1 | 2 | // keyboard handling 3 | 4 | // inputmode. switchable via lessmode_toggle GLBLMARK 5 | int inputmode = 1; 6 | int help_storedinputmode = 0; 7 | 8 | 9 | 10 | int match(uint mask, uint state) { 11 | return mask == XK_ANY_MOD || mask == (state & ~ignoremod); 12 | } 13 | 14 | int kmap(KeySym k, uint state) { 15 | Key *kp; 16 | int i; 17 | //KeySym k2 = k; 18 | 19 | dbg("Key: %d %c\n", k,k); 20 | /* Check for mapped keys out of X11 function keys. */ 21 | for (i = 0; i < LEN(mappedkeys); i++) { //? misc. 22 | // Better compare first with a bitfield, 23 | // by the or'ed mapped keys 24 | if (mappedkeys[i] == k) 25 | break; 26 | } 27 | 28 | if (i == LEN(mappedkeys)) { // no mapped key 29 | KeySym tk = k; 30 | if ( tk>0x1000000 ) 31 | tk-= 0x1000000; // convert to unicode 32 | 33 | if ((tk & 0xFFFF) < 0xFD00) { // No control/function/mod key 34 | // dbg ("Here\n");// -> no multibyte key. no match. ret. 35 | dbg("Key2: %x %c\n", tk,tk); 36 | /* Check for mapped keys out of X11 function keys. */ 37 | if ( (tk > 0x80) && ( tk<0xf000 ) ){ //unicode translation to current codepage needed 38 | if ( tk >= UNITABLE ){ // greater than the cached table 39 | for ( uchar a = 0; a<128; a++ ){ 40 | if ( codepage[selected_codepage][a] == tk ){ 41 | ttywrite( &a,1,1 ); 42 | return(1); 43 | //k = codepage[selected_codepage][a]; 44 | //goto CONT; 45 | } 46 | } 47 | } else { 48 | if ( uni_to_cp[tk] ){ 49 | dbg("uni to cp: %x\n",uni_to_cp[tk]); 50 | ttywrite( &uni_to_cp[tk],1,1 ); 51 | return(1); 52 | //k = uni_to_cp[tk]; 53 | //goto CONT; 54 | } 55 | } 56 | ttywrite((utfchar*)"~",1,1); // drop utf8 here 57 | } 58 | 59 | return(0); 60 | } 61 | } 62 | //CONT: 63 | 64 | // key ist the key binding array (!) defined in config.h. man. 65 | // doesn't seem useful to sort, normally a key is within the array, when 66 | // arrived here. 67 | for (kp = key; kp < key + LEN(key); kp++) { 68 | if (kp->k != k) 69 | continue; 70 | 71 | if (!match(kp->mask, state)) 72 | continue; 73 | if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0) 74 | continue; 75 | if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2) 76 | continue; 77 | 78 | if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0) 79 | continue; 80 | 81 | ttywrite((utfchar*)kp->s, kp->len, 1); 82 | return(1); // abort further handling 83 | } 84 | // if ( k2 != k ){ // translated from unicode to codepage 85 | // ttywrite((uchar*)&k, 1, 1); 86 | // return(1); 87 | // } 88 | //printf("looking for: %x\n",kp->k); 89 | return(0); 90 | } 91 | 92 | // sort the shortcuts, 93 | // to be able to abort scanning through all of them for each key 94 | // gets callen at startup 95 | void sort_shortcuts(){ 96 | // Do a stable sort. Elements of the same 97 | // keysym value stay in the same order. 98 | // This is callen only once at startup. for about 100 elements. 99 | #define SIZE (sizeof(shortcuts)/sizeof(Shortcut)) 100 | //uint cp[SIZE]; 101 | KeySym bing; // 102 | uint pt = 0; // 103 | 104 | for ( int a = 0; axkey; 163 | KeySym ksym; 164 | unsigned char buf[32]; 165 | buf[0] = 0; 166 | int len; 167 | Rune c; 168 | Status status; 169 | Shortcut *bp; 170 | 171 | if (IS_SET(MODE_KBDLOCK)) 172 | return; 173 | 174 | len = XmbLookupString(xwin.xic, e, (char*)buf, sizeof buf, &ksym, &status); 175 | 176 | if (IS_SET(MODE_KBDSELECT)) { 177 | if (match(XK_NO_MOD, e->state) || (XK_Shift_L | XK_Shift_R) & e->state) 178 | twin.mode ^= trt_kbdselect(ksym, (char*)buf, len); 179 | return; 180 | } 181 | 182 | DBG("key: %lx, keycode: %x, state: %x, buf: %s\n",ksym, e->keycode, e->state,buf ); 183 | 184 | if ( IS_SET( MODE_ENTERSTRING ) ){ 185 | if ( statusbar_kpress( e, &ksym, (char*)buf ) == 1 ) 186 | return; 187 | } 188 | 189 | 190 | // handle return, add retmark 191 | if ( ( ksym == XK_Return ) && (term->scr==0) && ( inputmode == MODE_REGULAR ) && !( twin.mode & MODE_KBDSELECT ) ){ 192 | //if ( (!IS_SET(MODE_ALTSCREEN)) && ( ksym == XK_Return ) ){ 193 | set_retmark(); 194 | } 195 | 196 | 197 | /* 1. shortcuts */ 198 | for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { 199 | if ( ksym < bp->keysym ){ // bp->keysym > ksym 200 | break; 201 | } 202 | 203 | if ( (( ksym == bp->keysym ) || ( bp->keysym == ALL_KEYS )) && 204 | match(bp->mod, e->state) && 205 | (bp->inputmode & inputmode)) { 206 | 207 | bp->func(&(bp->arg)); 208 | return; 209 | } 210 | } 211 | 212 | 213 | if ( term->mode & TMODE_HELP ) // in the help browser. Only shortcuts used 214 | //if ( inputmode & MODE_HELP ) 215 | return; 216 | 217 | /* 2. keys to translate, defined in config.h */ 218 | if (kmap(ksym, e->state)) { 219 | //ttywrite(customkey, strlen(customkey), 1); 220 | return; 221 | } 222 | 223 | dbg("Key2: %d %c, state:%x, mod1: %x, len %d\n", ksym, ksym, e->state, 224 | Mod1Mask, len); 225 | /* 3. composed string from input method */ 226 | if (len == 0) 227 | return; 228 | if (len == 1 && e->state & Mod1Mask) { 229 | dbg("K\n"); 230 | if (IS_SET(MODE_8BIT)) { 231 | if (*buf < 0177) { 232 | c = *buf | 0x80; 233 | len = utf8encode(c, (char*)buf); 234 | } 235 | } else { 236 | buf[1] = buf[0]; 237 | buf[0] = '\033'; 238 | len = 2; 239 | } 240 | } 241 | ttywrite(buf, len, 1); 242 | } 243 | 244 | 245 | void numlock(const Arg *dummy) { 246 | twin.mode ^= MODE_NUMLOCK; 247 | } 248 | 249 | /* 250 | void temp(const Arg *dummy){ 251 | for ( int a = 0; a<128; a++){//2190 252 | //cpe4002a[a] = a+0x238a; 253 | } 254 | } */ 255 | 256 | 257 | // does nothing. Aborts shortcut scanning and key processing 258 | void dummy( const Arg *a){ 259 | } 260 | 261 | void dump_terminfo( const Arg *a){ 262 | #ifdef INCLUDETERMINFO 263 | ttywrite((utfchar*)slterm_terminfo, strlen(slterm_terminfo),1 ); 264 | #endif 265 | } 266 | 267 | 268 | 269 | 270 | -------------------------------------------------------------------------------- /src/xkeyboard.h: -------------------------------------------------------------------------------- 1 | 2 | // keyboard input handling. 3 | 4 | /* types used in config.h */ 5 | typedef struct { 6 | unsigned int mod; 7 | KeySym keysym; 8 | void (*func)(const Arg *); 9 | const Arg arg; 10 | unsigned int inputmode; 11 | } Shortcut; 12 | 13 | 14 | typedef struct { 15 | KeySym k; // this is unsigned int (32) here 16 | unsigned int mask; 17 | char *s; 18 | unsigned char len; 19 | /* three-valued logic variables: 0 indifferent, 1 on, -1 off */ 20 | signed char appkey; /* application keypad */ 21 | signed char appcursor; /* application cursor */ 22 | } Key; 23 | 24 | 25 | // save different inputmodes 26 | extern int inputmode; 27 | extern int help_storedinputmode; 28 | 29 | 30 | /* X modifiers */ 31 | #define XK_ANY_MOD UINT_MAX 32 | #define XK_NO_MOD 0 33 | #define XK_SWITCH_MOD (1 << 13) 34 | 35 | 36 | 37 | int kmap(KeySym k, unsigned int state); 38 | void numlock(const Arg *); 39 | void kpress(XEvent *ev); 40 | 41 | int match(unsigned int mask, unsigned int state); 42 | 43 | 44 | // callbacks . Used in config.h 45 | void ttysend(const Arg *); 46 | 47 | void dummy( const Arg *a); 48 | void dump_terminfo( const Arg *a); 49 | -------------------------------------------------------------------------------- /src/xmouse.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | // mouse handling 4 | void mousereport(XEvent *e) { 5 | static int oldbutton = 3; /* button event on startup: 3 = release */ 6 | 7 | int len, x = evcol(e), y = evrow(e), button = e->xbutton.button, 8 | state = e->xbutton.state; 9 | char buf[40]; 10 | static int ox, oy; 11 | 12 | /* from urxvt */ 13 | if (e->xbutton.type == MotionNotify) { 14 | if (x == ox && y == oy) 15 | return; 16 | if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY)) 17 | return; 18 | /* MOUSE_MOTION: no reporting if no button is pressed */ 19 | if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3) 20 | return; 21 | 22 | button = oldbutton + 32; 23 | ox = x; 24 | oy = y; 25 | } else { 26 | if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) { 27 | button = 3; 28 | } else { 29 | button -= Button1; 30 | if (button >= 3) 31 | button += 64 - 3; 32 | } 33 | if (e->xbutton.type == ButtonPress) { 34 | oldbutton = button; 35 | ox = x; 36 | oy = y; 37 | } else if (e->xbutton.type == ButtonRelease) { 38 | oldbutton = 3; 39 | /* MODE_MOUSEX10: no button release reporting */ 40 | if (IS_SET(MODE_MOUSEX10)) 41 | return; 42 | if (button == 64 || button == 65) 43 | return; 44 | } 45 | } 46 | 47 | if (!IS_SET(MODE_MOUSEX10)) { 48 | button += ((state & ShiftMask) ? 4 : 0) + ((state & Mod4Mask) ? 8 : 0) + 49 | ((state & ControlMask) ? 16 : 0); 50 | } 51 | 52 | if (IS_SET(MODE_MOUSESGR)) { 53 | len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", button, x + 1, y + 1, 54 | e->xbutton.type == ButtonRelease ? 'm' : 'M'); 55 | } else if (x < 223 && y < 223) { 56 | len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", 32 + button, 32 + x + 1, 57 | 32 + y + 1); 58 | } else { 59 | return; 60 | } 61 | 62 | ttywrite((utfchar*)buf, len, 0); 63 | } 64 | 65 | int mouseaction(XEvent *e, uint release) { 66 | MouseShortcut *ms; 67 | 68 | for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { 69 | if (ms->release == release && ms->button == e->xbutton.button && 70 | (!ms->altscrn || (ms->altscrn == (tisaltscr() ? 1 : -1))) && 71 | (match(ms->mod, e->xbutton.state) || /* exact or forced */ 72 | match(ms->mod, e->xbutton.state & ~forcemousemod))) { 73 | ms->func(&(ms->arg)); 74 | return 1; 75 | } 76 | } 77 | 78 | return 0; 79 | } 80 | 81 | void bpress(XEvent *e) { 82 | struct timespec now; 83 | int snap; 84 | 85 | if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { 86 | mousereport(e); 87 | return; 88 | } 89 | 90 | if (mouseaction(e, 0)) 91 | return; 92 | 93 | if (e->xbutton.button == Button1) { 94 | /* 95 | * If the user clicks below predefined timeouts specific 96 | * snapping behaviour is exposed. 97 | */ 98 | clock_gettime(CLOCK_MONOTONIC, &now); 99 | if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { 100 | snap = SNAP_LINE; 101 | } else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { 102 | snap = SNAP_WORD; 103 | } else { 104 | snap = 0; 105 | } 106 | xsel.tclick2 = xsel.tclick1; 107 | xsel.tclick1 = now; 108 | 109 | selstart(evcol(e), evrow(e), snap); 110 | } 111 | } 112 | 113 | void brelease(XEvent *e) { 114 | if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { 115 | mousereport(e); 116 | return; 117 | } 118 | 119 | // if (mouseaction(e, 1)) 120 | // return; 121 | 122 | if (e->xbutton.button == Button2) 123 | clippaste(NULL); 124 | else if (e->xbutton.button == Button1) 125 | mousesel(e, 1); 126 | } 127 | 128 | void bmotion(XEvent *e) { 129 | if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { 130 | mousereport(e); 131 | return; 132 | } 133 | 134 | mousesel(e, 0); 135 | } 136 | 137 | 138 | int evcol(XEvent *e) { 139 | int x = e->xbutton.x - twin.hborderpx; 140 | LIMIT(x, 0, twin.tw - 1); 141 | return x / twin.cw; 142 | } 143 | 144 | int evrow(XEvent *e) { 145 | int y = e->xbutton.y - twin.vborderpx; 146 | LIMIT(y, 0, twin.th - 1); 147 | return y / twin.ch; 148 | } 149 | 150 | 151 | -------------------------------------------------------------------------------- /src/xmouse.h: -------------------------------------------------------------------------------- 1 | 2 | // mouse events handling 3 | typedef struct { 4 | unsigned int mod; 5 | unsigned int button; 6 | void (*func)(const Arg *); 7 | const Arg arg; 8 | unsigned int release; 9 | int altscrn; /* 0: don't care, -1: not alt screen, 1: alt screen */ 10 | } MouseShortcut; 11 | 12 | 13 | 14 | // event handling 15 | 16 | int mouseaction(XEvent *, unsigned int); 17 | void brelease(XEvent *); 18 | void bpress(XEvent *); 19 | void bmotion(XEvent *); 20 | void mousereport(XEvent *); 21 | 22 | int evcol(XEvent *); 23 | int evrow(XEvent *); 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/xwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef stX_H 2 | #define stX_H 3 | 4 | //typedef Glyph; 5 | //typedef Line; 6 | //typedef Arg; 7 | #include "fonts.h" 8 | #include "xdraw.h" 9 | 10 | 11 | /* macros */ 12 | #ifdef IS_SET 13 | #undef IS_SET 14 | #endif 15 | // seems ok. is there a reason? 16 | #define IS_SET(flag) ((twin.mode & (flag)) != 0) 17 | 18 | 19 | void SET(int flag); 20 | 21 | enum win_mode { 22 | MODE_VISIBLE = 1 << 0, 23 | MODE_FOCUSED = 1 << 1, 24 | MODE_APPKEYPAD = 1 << 2, 25 | MODE_MOUSEBTN = 1 << 3, 26 | MODE_MOUSEMOTION = 1 << 4, 27 | MODE_REVERSE = 1 << 5, 28 | MODE_KBDLOCK = 1 << 6, 29 | MODE_HIDE = 1 << 7, // inactive cursor 30 | MODE_APPCURSOR = 1 << 8, 31 | MODE_MOUSESGR = 1 << 9, 32 | MODE_8BIT = 1 << 10, 33 | MODE_BLINK = 1 << 11, 34 | MODE_FBLINK = 1 << 12, 35 | MODE_FOCUS = 1 << 13, 36 | MODE_MOUSEX10 = 1 << 14, 37 | MODE_MOUSEMANY = 1 << 15, 38 | MODE_BRCKTPASTE = 1 << 16, 39 | MODE_NUMLOCK = 1 << 17, 40 | MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10|MODE_MOUSEMANY, 41 | MODE_KBDSELECT = 1 << 18, 42 | MODE_LESS = 1 << 19, // also hides cursor. 43 | MODE_ENTERSTRING = 1 << 20, 44 | }; 45 | 46 | 47 | 48 | void cresize(int, int); 49 | void xhints(void); 50 | 51 | void xinit(int cols, int rows); 52 | void xsetenv(void); 53 | 54 | void xbell(void); 55 | void xclipcopy(void); 56 | void xloadcolors(void); 57 | int xsetcolorname(int, const char *); 58 | void xsettitle(char *); 59 | void xsetmode(int, unsigned int); 60 | void xsetpointermotion(int); 61 | void xximspot(int, int); 62 | void toggle_winmode(int); 63 | #ifdef shared 64 | int stmain(int argc, char *argv[]); 65 | #endif 66 | 67 | #endif 68 | 69 | 70 | -------------------------------------------------------------------------------- /test/16bgcolors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo 4 | echo -e "\033[1;37mBackground colors\e[0m" 5 | 6 | echo 7 | #echo -n ' ' 8 | for i in `seq 0 7`; do echo -ne "\e[48;5;$i""m $i \e[30m"; done 9 | echo -e "\e[0m" 10 | 11 | for i in `seq 8 15`; do printf "\e[30;48;5;$i""m %2d " $i; done 12 | echo -e "\e[0m" 13 | echo 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test/16colors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo -ne "\n\033[1;4;37m"; 4 | echo -e 256 Color mode, \#0-15 "\033[0;1m (indexed palette)" "\033[0;30;40m " 5 | echo 6 | 7 | for i in 0 8; do 8 | for a in 2 '2;1' 0 1; do 9 | printf "\033[37;$a""m $a""m:\t" 10 | for b in 0 1 2 3 4 5 6 7;do 11 | printf "\033[38;5;"$(($b+$i))"m %03d" $(( $b+$i )) 12 | done 13 | echo 14 | done 15 | done 16 | 17 | echo 18 | 19 | -------------------------------------------------------------------------------- /test/8colors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo -ne "\n\033[1;37m"; 4 | echo -e 256 Color mode, \#0-7 "\033[0;1m (indexed palette)" "\033[0;30;40m " 5 | echo 6 | 7 | for a in 2 0 1 '1;2'; do 8 | printf '\033[37;0m%3sm: ' $a 9 | for b in `seq 30 37`;do 10 | printf "\033[$a;$b"'m %03d ' $b 11 | done 12 | printf "\033[0m\n" 13 | done 14 | 15 | echo 16 | 17 | echo -e "\n\033[1;37mInverse\e[0m" 18 | echo 19 | 20 | for a in 2 0 1 '1;2'; do 21 | printf '\033[37;0m%3sm: ' $a 22 | for b in `seq 30 37`;do 23 | printf "\033[$a;7;$b"'m %03d ' $b 24 | done 25 | printf "\033[0m\n" 26 | done 27 | 28 | echo 29 | 30 | -------------------------------------------------------------------------------- /test/UTF-8-demo.txt: -------------------------------------------------------------------------------- 1 | 2 | UTF-8 encoded sample plain-text file 3 | ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 4 | 5 | Markus Kuhn [ˈmaʳkʊs kuːn] — 2002-07-25 CC BY 6 | 7 | 8 | The ASCII compatible UTF-8 encoding used in this plain-text file 9 | is defined in Unicode, ISO 10646-1, and RFC 2279. 10 | 11 | 12 | Using Unicode/UTF-8, you can write in emails and source code things such as 13 | 14 | Mathematics and scien#es: 15 | 16 | ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫ 17 | ⎪⎢⎜│a²+b³ ⎟⎥⎪ 18 | ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), ⎪⎢⎜│───── ⎟⎥⎪ 19 | ⎪⎢⎜⎷ c₈ ⎟⎥⎪ 20 | ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⎨⎢⎜ ⎟⎥⎬ 21 | ⎪⎢⎜ ∞ ⎟⎥⎪ 22 | ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫), ⎪⎢⎜ ⎲ ⎟⎥⎪ 23 | ⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪ 24 | 2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm ⎩⎣⎝i=1 ⎠⎦⎭ 25 | 26 | Linguistics and dictionaries: 27 | 28 | ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn 29 | Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ] 30 | 31 | APL: 32 | 33 | ((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈ 34 | 35 | Nicer typography in plain text files: 36 | 37 | ╔══════════════════════════════════════════╗ 38 | ║ ║ 39 | ║ • ‘single’ and “double” quotes ║ 40 | ║ ║ 41 | ║ • Curly apostrophes: “We’ve been here” ║ 42 | ║ ║ 43 | ║ • Latin-1 apostrophe and accents: '´` ║ 44 | ║ ║ 45 | ║ • ‚deutsche‘ „Anführungszeichen“ ║ 46 | ║ ║ 47 | ║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║ 48 | ║ ║ 49 | ║ • ASCII safety test: 1lI|, 0OD, 8B ║ 50 | ║ ╭─────────╮ ║ 51 | ║ • the euro symbol: │ 14.95 € │ ║ 52 | ║ ╰─────────╯ ║ 53 | ╚══════════════════════════════════════════╝ 54 | 55 | Combining characters: 56 | 57 | STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑ 58 | 59 | Greek (in Polytonic): 60 | 61 | The Greek anthem: 62 | 63 | Σὲ γνωρίζω ἀπὸ τὴν κόψη 64 | τοῦ σπαθιοῦ τὴν τρομερή, 65 | σὲ γνωρίζω ἀπὸ τὴν ὄψη 66 | ποὺ μὲ βία μετράει τὴ γῆ. 67 | 68 | ᾿Απ᾿ τὰ κόκκαλα βγαλμένη 69 | τῶν ῾Ελλήνων τὰ ἱερά 70 | καὶ σὰν πρῶτα ἀνδρειωμένη 71 | χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά! 72 | 73 | From a speech of Demosthenes in the 4th century BC: 74 | 75 | Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι, 76 | ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς 77 | λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ 78 | τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿ 79 | εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ 80 | πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν 81 | οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι, 82 | οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν 83 | ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον 84 | τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι 85 | γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν 86 | προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους 87 | σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ 88 | τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ 89 | τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς 90 | τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον. 91 | 92 | Δημοσθένους, Γ´ ᾿Ολυνθιακὸς 93 | 94 | Georgian: 95 | 96 | From a Unicode conference invitation: 97 | 98 | გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო 99 | კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს, 100 | ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს 101 | ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი, 102 | ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება 103 | ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში, 104 | ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში. 105 | 106 | Russian: 107 | 108 | From a Unicode conference invitation: 109 | 110 | Зарегистрируйтесь сейчас на Десятую Международную Конференцию по 111 | Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии. 112 | Конференция соберет широкий круг экспертов по вопросам глобального 113 | Интернета и Unicode, локализации и интернационализации, воплощению и 114 | применению Unicode в различных операционных системах и программных 115 | приложениях, шрифтах, верстке и многоязычных компьютерных системах. 116 | 117 | Thai (UCS Level 2): 118 | 119 | Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese 120 | classic 'San Gua'): 121 | 122 | [----------------------------|------------------------] 123 | ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่ 124 | สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา 125 | ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา 126 | โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ 127 | เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ 128 | ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ 129 | พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้ 130 | ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ 131 | 132 | (The above is a two-column text. If combining characters are handled 133 | correctly, the lines of the second column should be aligned with the 134 | | character above.) 135 | 136 | Ethiopian: 137 | 138 | Proverbs in the Amharic language: 139 | 140 | ሰማይ አይታረስ ንጉሥ አይከሰስ። 141 | ብላ ካለኝ እንደአባቴ በቆመጠኝ። 142 | ጌጥ ያለቤቱ ቁምጥና ነው። 143 | ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው። 144 | የአፍ ወለምታ በቅቤ አይታሽም። 145 | አይጥ በበላ ዳዋ ተመታ። 146 | ሲተረጉሙ ይደረግሙ። 147 | ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል። 148 | ድር ቢያብር አንበሳ ያስር። 149 | ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም። 150 | እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም። 151 | የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ። 152 | ሥራ ከመፍታት ልጄን ላፋታት። 153 | ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል። 154 | የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ። 155 | ተንጋሎ ቢተፉ ተመልሶ ባፉ። 156 | ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው። 157 | እግርህን በፍራሽህ ልክ ዘርጋ። 158 | 159 | Runes: 160 | 161 | ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ 162 | 163 | (Old English, which transcribed into Latin reads 'He cwaeth that he 164 | bude thaem lande northweardum with tha Westsae.' and means 'He said 165 | that he lived in the northern land near the Western Sea.') 166 | 167 | Braille: 168 | 169 | ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌ 170 | 171 | ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞ 172 | ⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎ 173 | ⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂ 174 | ⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙ 175 | ⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑ 176 | ⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲ 177 | 178 | ⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ 179 | 180 | ⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹ 181 | ⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞ 182 | ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕ 183 | ⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹ 184 | ⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎ 185 | ⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎ 186 | ⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳ 187 | ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞ 188 | ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ 189 | 190 | (The first couple of paragraphs of "A Christmas Carol" by Dickens) 191 | 192 | Compact font selection example text: 193 | 194 | ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789 195 | abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ 196 | –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд 197 | ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა 198 | 199 | Greetings in various languages: 200 | 201 | Hello world, Καλημέρα κόσμε, コンニチハ 202 | 203 | Box drawing alignment tests: █ 204 | ▉ 205 | ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳ 206 | ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳ 207 | ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳ 208 | ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳ 209 | ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎ 210 | ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏ 211 | ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█ 212 | ▝▀▘▙▄▟ 213 | -------------------------------------------------------------------------------- /test/ansicolors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | echo TERM: $TERM COLORTERM: $COLORTERM 4 | 5 | for a in {30..49}; 6 | do (for b in {0..8}; 7 | do echo -n "\033[0;$b;03;$a""m" " $b;$a " 8 | done ;) 9 | echo "\033[0;37m"; 10 | done 11 | 12 | 13 | echo "\033[1;4m"; 14 | echo Attributes 15 | echo -n "\033[0m"; 16 | 17 | for a in {0..15};do printf "\033[0;$a""m\033[38;5;4m %03d" $a; done 18 | echo 19 | for a in {16..31};do printf "\033[0;$a""m\033[38;5;4m %03d" $a; done 20 | echo 21 | 22 | 23 | 24 | echo "\033[1;4;37m"; 25 | echo 256 Color mode, \#0-15 "\033[0;1m (indexed palette)" 26 | echo -n "\033[0m"; 27 | 28 | for i in 0 8; do 29 | for a in 2 0 1; do 30 | printf "\033[37;$a""m $a""m:" 31 | for b in {0..7};do 32 | printf "\033[38;5;$[$b+$i]""m %03d" $[$b+$i] 33 | done 34 | echo 35 | done 36 | done 37 | 38 | echo "\033[1;4m"; 39 | echo Inverted 40 | echo -n "\033[0m"; 41 | 42 | 43 | 44 | for i in 0 8; do 45 | for a in 2 0 1; do 46 | printf "\033[37;$a""m $a""m:" 47 | for b in {0..7};do 48 | printf "\033[38;5;$[$b+$i]m" 49 | # first color; then ivert 50 | printf "\033[7""m %03d" $[$b+$i] 51 | done 52 | echo 53 | done 54 | done 55 | 56 | 57 | function col() { 58 | fi=$1; shift 59 | fa=$[$1*36]; shift 60 | for fb in $@; do 61 | printf "\033[0;$fi""m\033[38;5;$[$fa+$fb]""m %03d" $[$fa+$fb] 62 | done 63 | } 64 | 65 | 66 | function colbg() { 67 | fi=$1; shift 68 | fa=$[$1*36]; shift 69 | for fb in $@; do 70 | printf "\033[0;$fi""m\033[48;5;$[$fa+$fb]""m %03d" $[$fa+$fb] 71 | done 72 | } 73 | 74 | 75 | 76 | 77 | 78 | 79 | echo "\033[0;1;37;4m"; 80 | echo Colors \#16-231 81 | echo -n "\033[0m"; 82 | 83 | 84 | 85 | 86 | for a in {1..15}; do 87 | (for b in {0..15}; do 88 | (( color = a * 16 + b )) 89 | # printf "\033[0;2m\033[38;5;$color""m %03d" $color 90 | printf "\033[0m\033[38;5;$color""m %03d" $color 91 | # printf "\033[0;1m\033[38;5;$color""m %03d" $color 92 | done 93 | ) 94 | echo "\033[0;30m" 95 | done 96 | 97 | 98 | 99 | echo "\033[1;4;37m"; 100 | echo 256 Grayscale, \#232-255 "\033[0;1m" 101 | echo -n "\033[0m"; 102 | 103 | col 2 0 {232..255} 104 | echo 105 | col 0 0 {232..255} 106 | echo 107 | col 1 0 {232..255} 108 | echo 109 | 110 | 111 | 112 | 113 | echo "\033[0;1;37;4m"; 114 | echo Colors \#16-231 - gradient 115 | echo -n "\033[0m"; 116 | 117 | #for i in 2 0 1; do 118 | 119 | i=2 120 | for a in {0..5}; do 121 | col $i $a {16..21} 122 | col $i $a {27..22} 123 | col $i $a {28..33} 124 | col $i $a {39..34} 125 | col $i $a {46..51} 126 | col $i $a {45..41} 127 | echo 128 | done 129 | 130 | 131 | i=0; 132 | for a in {5..0}; do 133 | col $i $a {16..21} 134 | col $i $a {27..22} 135 | col $i $a {28..33} 136 | col $i $a {39..34} 137 | col $i $a {46..51} 138 | col $i $a {45..41} 139 | echo 140 | done 141 | 142 | i=1 143 | 144 | for a in {0..5}; do 145 | col $i $a {16..21} 146 | col $i $a {27..22} 147 | col $i $a {28..33} 148 | col $i $a {39..34} 149 | col $i $a {46..51} 150 | col $i $a {45..41} 151 | echo 152 | done 153 | 154 | echo 155 | 156 | 157 | #col 0 0 {16..21} 158 | #col 0 1 {16..21} 159 | 160 | 161 | 162 | 163 | 164 | echo "\033[0;1;37;4m"; 165 | echo Colors \#16-231 - gradient background 166 | echo -n "\033[0m"; 167 | 168 | #for i in 2 0 1; do 169 | 170 | i=2 171 | for a in {0..5}; do 172 | colbg $i $a {16..21} 173 | colbg $i $a {27..22} 174 | colbg $i $a {28..33} 175 | colbg $i $a {39..34} 176 | colbg $i $a {46..51} 177 | colbg $i $a {45..41} 178 | echo 179 | done 180 | 181 | 182 | i=0; 183 | for a in {5..0}; do 184 | colbg $i $a {16..21} 185 | colbg $i $a {27..22} 186 | colbg $i $a {28..33} 187 | colbg $i $a {39..34} 188 | colbg $i $a {46..51} 189 | colbg $i $a {45..41} 190 | echo 191 | done 192 | 193 | i=1 194 | 195 | for a in {0..5}; do 196 | colbg $i $a {16..21} 197 | colbg $i $a {27..22} 198 | colbg $i $a {28..33} 199 | colbg $i $a {39..34} 200 | colbg $i $a {46..51} 201 | colbg $i $a {45..41} 202 | echo 203 | done 204 | 205 | echo 206 | 207 | 208 | 209 | exit 210 | 211 | echo 212 | 213 | for a in {0..16} # 214 | do 215 | (for b in {0..15} 216 | do 217 | (( color = a * 16 + b )) 218 | printf "\033[48;5;$color""m %03d" $color 219 | done 220 | ) 221 | echo "\033[0;30m" 222 | done 223 | 224 | 225 | 226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /test/ascii-tiny.c: -------------------------------------------------------------------------------- 1 | #if 0 2 | COMPILE PRINTF 3 | 4 | return 5 | #endif 6 | 7 | /* dump a chartable to the terminal */ 8 | 9 | #ifndef MLIB 10 | #include 11 | #endif 12 | 13 | int main(int argc, char **argv){ 14 | for ( int a = 32; a<256; a++ ){ 15 | printf("%2x: %c ", a, a ); 16 | if ( !((a+1)%8) ) 17 | printf("\n"); 18 | } 19 | return(0); 20 | } 21 | -------------------------------------------------------------------------------- /test/ascii.c: -------------------------------------------------------------------------------- 1 | #if 0 2 | COMPILE prints printl itohex printf fmtd strcpy strcat ewrites atoi 3 | SHRINKELF 4 | 5 | return 6 | #endif 7 | 8 | #ifndef MLIB 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define writes(msg) write(1,msg,sizeof(msg)) 15 | #define ewrites(msg) write(2,msg,sizeof(msg)) 16 | #define printl() printf("\n") 17 | 18 | #endif 19 | 20 | 21 | const struct { char *shortname; char *desc; } ctrl[] = { 22 | { "NUL", "Null, End of file" }, 23 | { "SOH", "Start of Heading" }, 24 | { "STX", "Start of Text" }, 25 | { "ETX", "End of Text" }, 26 | { "EOT", "End of Transmission" }, 27 | { "ENQ", "Enquiry" }, 28 | { "ACK", "Acknowledge (Telnet)" }, 29 | { "BEL", "Bell (audible or attention signal)" }, 30 | { "BS" , "Backspace (Delete)" }, 31 | { "TAB", "Horizontal Tabulation" }, 32 | { "LF" , "Line Feed" }, 33 | { "VT" , "Vertical Tabulation" }, 34 | { "FF" , "Form Feed" }, 35 | { "CR" , "Carriage Return, Enter" }, 36 | { "SO" , "Shift Out" }, 37 | { "SI" , "Shift In" }, 38 | { "DLE", "Data Link Escape" }, 39 | { "DC1", "Device Control 1" }, 40 | { "DC2", "Device Control 2" }, 41 | { "DC3", "Device Control 3" }, 42 | { "DC4", "Device Control 4" }, 43 | { "NAK", "Negative Acknowledge" }, 44 | { "SYN", "Synchronous Idle" }, 45 | { "ETB", "End of Transmission Block" }, 46 | { "CAN", "Cancel" }, 47 | { "EM" , "End of Medium" }, 48 | { "SUB", "Substitute" }, 49 | { "ESC", "Escape, VT100 Initiate Control Sequence" }, 50 | { "FS" , "File Separator" }, 51 | { "GS" , "Group Separator" }, 52 | { "RS" , "Record Separator" }, 53 | { "US" , "Unit Separator" }, 54 | }; 55 | 56 | void usage(){ 57 | ewrites( R"(ascii [-dhxct] [-f num] [-t num] 58 | Dump an ascii table to stdout. 59 | Options: 60 | -s num : start with num 61 | -e num : end at num 62 | -c : colorize 63 | -x : show hexadecimal numbers 64 | -d : decimal numbers 65 | -t : dump a table and descriptions of the control chars 0-31 66 | -F fmt : printf format. printf is callen with 3 times c (current char) 67 | -T num : Linebreak after num columns (default 8) 68 | -h : show this help. 69 | 70 | (c) 2023, BSD 3-clause, misc (github.com/michael105) 71 | )" ); 72 | exit(0); 73 | } 74 | 75 | int main(int argc, char **argv){ 76 | int opt=0; 77 | int from = 32; 78 | int to = 255; 79 | int lb = 8; // linebreak after 8 columns 80 | char fmtb[32]; 81 | char *fmt = fmtb; 82 | strcpy(fmt,"%2x:"); 83 | for ( *argv++; *argv; *argv++ ){ 84 | if ( argv[0][0] == '-' ){ 85 | for ( char *o = *argv + 1; *o; o++ ) 86 | switch ( *o ){ 87 | case 'd': 88 | opt |= 1; 89 | strcpy(fmt,"%3d:"); 90 | break; 91 | case 'x': 92 | opt |= 2; 93 | break; 94 | case 'c': 95 | opt |= 4; 96 | break; 97 | case 't': 98 | for ( int a = 0; a<32; a++ ){ 99 | printf("%2d - %2x: %3s %s\n",a,a,ctrl[a].shortname, ctrl[a].desc ); 100 | } 101 | exit(0); 102 | case 's': 103 | *argv++; 104 | from = atoi( *argv ); 105 | break; 106 | case 'e': 107 | *argv++; 108 | to = atoi( *argv ); 109 | break; 110 | case 'T': 111 | *argv++; 112 | lb = atoi( *argv ); 113 | break; 114 | case 'F': 115 | opt = -1; 116 | *argv++; 117 | if ( *argv ) 118 | fmt = *argv; 119 | break; 120 | 121 | case 'h': 122 | usage(); 123 | 124 | default: 125 | writes("ascii [-hdxct] [-s num] [-e num]\n"); 126 | exit(0); 127 | } 128 | } 129 | } 130 | if ( opt >= 0 ){ 131 | if ( (opt&3) == 3 ) 132 | strcpy(fmt,"%3d(%2x):"); 133 | if ( (opt&4) ) 134 | strcat(fmt," \e[36m%c\e[37m "); 135 | else 136 | strcat(fmt," %c "); 137 | } 138 | 139 | int col = 1; 140 | for ( int a = from; a<=to; a++ ){ 141 | printf(fmt, a, a, a ); 142 | 143 | if ( col++ == lb ){ 144 | printl(); 145 | col=1; 146 | } 147 | } 148 | exit(0); 149 | } 150 | -------------------------------------------------------------------------------- /test/asciitable.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/test/asciitable.txt -------------------------------------------------------------------------------- /test/attributes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | for i in `seq 0 18` 5 | do 6 | echo -e "\e[0m" Attr: $i "\e[$i"m Some text 7 | done 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/bgcolors3.pl: -------------------------------------------------------------------------------- 1 | #!/bin/perl -w 2 | 3 | 4 | 5 | #use Data::Dumper::Simple; 6 | 7 | 8 | my @a; 9 | 10 | $col = 0; 11 | $r = 0; 12 | 13 | foreach my $b ( 16,52,88,124,160,196 ){ 14 | for ( my $c = $b; $c<$b+6; $c++ ){ 15 | $a[$c-$b+$r][$col] = $c; 16 | } 17 | $col ++; 18 | } 19 | 20 | 21 | $col=0; 22 | $r += 6; 23 | for( my $b = 27; $b<=207;$b+=36 ){ 24 | for ( my $c = $b; $c>=$b-5; $c-- ){ 25 | $a[$b-$c+$r][$col] = $c; 26 | } 27 | $col ++; 28 | } 29 | 30 | $col=0; 31 | $r += 6; 32 | 33 | for( my $b = 28; $b<=208;$b+=36 ){ 34 | for ( my $c = $b; $c<$b+6; $c++ ){ 35 | $a[$c-$b+$r][$col] = $c; 36 | } 37 | $col ++; 38 | } 39 | 40 | $col=0; 41 | $r += 6; 42 | for( my $b = 39; $b<=219;$b+=36 ){ 43 | for ( my $c = $b; $c>=$b-5; $c-- ){ 44 | $a[$b-$c+$r][$col] = $c; 45 | } 46 | $col ++; 47 | } 48 | 49 | 50 | $col=0; 51 | $r += 6; 52 | 53 | for( my $b = 40; $b<=220;$b+=36 ){ 54 | for ( my $c = $b; $c<$b+6; $c++ ){ 55 | $a[$c-$b+$r][$col] = $c; 56 | } 57 | $col ++; 58 | } 59 | 60 | 61 | $col=0; 62 | $r += 6; 63 | for( my $b = 51; $b<=231;$b+=36 ){ 64 | for ( my $c = $b; $c>=$b-5; $c-- ){ 65 | $a[$b-$c+$r][$col] = $c; 66 | } 67 | $col ++; 68 | } 69 | 70 | 71 | if ( 0 ){ 72 | foreach my $row(@a){ 73 | foreach my $c( @{$row} ){ 74 | #printf("\033[48;5;$c"."m %03d ",$c); 75 | print("\033[0;0m"); 76 | printf("\033[48;5;$c"."m %03d ",$c); 77 | print("\033[0;0m"); 78 | print("\033[0;1m"); 79 | printf("\033[48;5;$c"."m %03d ",$c); 80 | print("\033[0;0m"); 81 | print("\033[0;2m"); 82 | printf("\033[48;5;$c"."m %03d ",$c); 83 | } 84 | print "\n"; 85 | } 86 | 87 | exit; 88 | } 89 | 90 | print "\033[1;4;48;5;237m"." 1 0 2 2 2 2 2 2 0 0 0 0 0 1 1 1 1 1 " ."\033[0m\n"; 91 | 92 | print "\e[0;38;233m"; 93 | 94 | my $i = 48; 95 | #my $i = 48; # 48 = invert - background 96 | 97 | my $split = 1; 98 | 99 | if ( 1 ){ 100 | # print "xx\n"; 101 | foreach my $row(@a){ 102 | my @ap = []; 103 | foreach my $c( (@{$row}) ){ 104 | if ( $split && ($c >=16 && $c <= 51) ){ 105 | push @ap,$c; 106 | printf("\033[0;0m\033[0;1m\033[$i;5;$c"."m %03d ",$c); 107 | printf("\033[0;0m\033[0;0m\033[$i;5;$c"."m %03d ",$c); 108 | printf("\033[0;0m\033[0;2m\033[$i;5;$c"."m %03d ",$c); 109 | 110 | next; 111 | } 112 | 113 | printf("\033[0;0m"); 114 | printf("\033[0;2m\033[$i;5;$c"."m %03d ",$c); 115 | } 116 | 117 | foreach my $c( reverse(@{$row}) ){ 118 | if ( $split && ($c >=16 && $c <= 51) ){ 119 | push @ap,$c; 120 | next; 121 | } 122 | 123 | printf("\033[0;0m"); 124 | printf("\033[0;0m\033[$i;5;$c"."m %03d ",$c); 125 | } 126 | foreach my $c( (@{$row}) ){ 127 | if ( $split && ($c >=16 && $c <= 51) ){ 128 | push @ap,$c; 129 | #printf("\033[0;0m\033[$i;5;$c"."m %03d ",$c); 130 | #printf("\033[0;1m\033[$i;5;$c"."m %03d ",$c); 131 | #printf("\033[0;2m\033[$i;5;$c"."m %03d ",$c); 132 | 133 | 134 | next; 135 | } 136 | printf("\033[0;0m"); 137 | printf("\033[0;1m\033[$i;5;$c"."m %03d ",$c); 138 | } 139 | 140 | # foreach my $c( @{$row} ){ 141 | # printf("\033[0;2m\033[48;5;$c"."m %03d ",$c); 142 | #} 143 | print "\033[40;m\n"; 144 | } 145 | exit; 146 | } 147 | 148 | 149 | 150 | 151 | 152 | 153 | $ln = 0; 154 | foreach my $row(@a){ 155 | if ( $ln == 0 ){ 156 | foreach my $c( @{$row} ){ 157 | printf("\033[48;5;$c"."m %03d ",$c); 158 | } 159 | $ln=1; 160 | } else { 161 | foreach my $c( reverse(@{$row}) ){ 162 | printf("\033[48;5;$c"."m %03d ",$c); 163 | } 164 | $ln=0; 165 | print "\n"; 166 | } 167 | 168 | 169 | #print Dumper($row); 170 | 171 | } 172 | -------------------------------------------------------------------------------- /test/colors2.pl: -------------------------------------------------------------------------------- 1 | #!/bin/perl -w 2 | # 3 | 4 | my %cls; 5 | 6 | sub color{ 7 | my $c = shift; 8 | my $f = shift; 9 | printf("\033[38;5;$c"."m%03d ",$c); 10 | #print "\n" if ( (($c+$f) %12)==0 ); 11 | $cls{$c} = 1 if (( ($c+2) %6) == 0); 12 | } 13 | 14 | 15 | 16 | #for ( 16..45 ){ 17 | # color($_,3); 18 | #} 19 | #foreach my $a ( 20 | # 16,22, 21 | # 28,34, 22 | # 40,76, 23 | # 46,82, 24 | # 118,154, 25 | # 148,112, 26 | # 106,100, 27 | # 136,172, 28 | # 130,166, 29 | # 202,208, 30 | # 214,220, 31 | # 226,190, 32 | # 184,178, 33 | # 172,142, 34 | # 94,58, 35 | # 64,70 36 | 37 | 38 | 39 | print "\e[1m"; 40 | my $r = 0; 41 | foreach my $a ( 42 | 16,22, 43 | 28,34, 44 | 40,76, 45 | 46,82, 46 | 118,154, 47 | 148,112, 48 | 106,100, 49 | 136,172, 50 | 130,166, 51 | 202,208, 52 | 214,220, 53 | 226,190, 54 | 184,178, 55 | 172,142, 56 | 94,58, 57 | 64,70 58 | 59 | ) { 60 | if ( $r==0 ){ 61 | for ( my $c = $a; $c<$a+6; $c++ ){ 62 | color($c,3); 63 | } 64 | $r = 1; 65 | } else { 66 | for ( my $c = $a+5; $c>=$a; $c-- ){ 67 | color($c,3); 68 | } 69 | $r=0; 70 | print "\n"; 71 | } 72 | 73 | } 74 | 75 | print "===\n"; 76 | 77 | 78 | 79 | 80 | for (my $a=16; $a<232; $a+=6 ){ 81 | if ( !exists($cls{$a}) ){ 82 | for ( my $c = $a; $c<$a+6; $c++ ){ 83 | color($c,3); 84 | } 85 | print "\n"; 86 | } 87 | } 88 | 89 | exit; 90 | 91 | color($_,3) for ( 202 .. 231 ); 92 | 93 | 94 | print "=====\n"; 95 | 96 | 97 | 98 | for ( 52..57, 124..233 ){ 99 | color($_,3); 100 | } 101 | 102 | print "=====\n"; 103 | for ( 16..233 ){ 104 | color($_,3); 105 | } 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /test/colors3.pl: -------------------------------------------------------------------------------- 1 | #!/bin/perl -w 2 | 3 | print "\n"; 4 | 5 | #use Data::Dumper::Simple; 6 | 7 | 8 | my @a; 9 | 10 | $col = 0; 11 | $r = 0; 12 | 13 | foreach my $b ( 16,52,88,124,160,196 ){ 14 | for ( my $c = $b; $c<$b+6; $c++ ){ 15 | $a[$c-$b+$r][$col] = $c; 16 | } 17 | $col ++; 18 | } 19 | 20 | 21 | $col=0; 22 | $r += 6; 23 | for( my $b = 27; $b<=207;$b+=36 ){ 24 | for ( my $c = $b; $c>=$b-5; $c-- ){ 25 | $a[$b-$c+$r][$col] = $c; 26 | } 27 | $col ++; 28 | } 29 | 30 | $col=0; 31 | $r += 6; 32 | 33 | for( my $b = 28; $b<=208;$b+=36 ){ 34 | for ( my $c = $b; $c<$b+6; $c++ ){ 35 | $a[$c-$b+$r][$col] = $c; 36 | } 37 | $col ++; 38 | } 39 | 40 | $col=0; 41 | $r += 6; 42 | for( my $b = 39; $b<=219;$b+=36 ){ 43 | for ( my $c = $b; $c>=$b-5; $c-- ){ 44 | $a[$b-$c+$r][$col] = $c; 45 | } 46 | $col ++; 47 | } 48 | 49 | 50 | $col=0; 51 | $r += 6; 52 | 53 | for( my $b = 40; $b<=220;$b+=36 ){ 54 | for ( my $c = $b; $c<$b+6; $c++ ){ 55 | $a[$c-$b+$r][$col] = $c; 56 | } 57 | $col ++; 58 | } 59 | 60 | 61 | $col=0; 62 | $r += 6; 63 | for( my $b = 51; $b<=231;$b+=36 ){ 64 | for ( my $c = $b; $c>=$b-5; $c-- ){ 65 | $a[$b-$c+$r][$col] = $c; 66 | } 67 | $col ++; 68 | } 69 | 70 | 71 | if ( 0 ){ 72 | foreach my $row(@a){ 73 | foreach my $c( @{$row} ){ 74 | #printf("\033[38;5;$c"."m%03d ",$c); 75 | print("\033[0;0m"); 76 | printf("\033[38;5;$c"."m%03d ",$c); 77 | print("\033[0;0m"); 78 | print("\033[0;1m"); 79 | printf("\033[38;5;$c"."m%03d ",$c); 80 | print("\033[0;0m"); 81 | print("\033[0;2m"); 82 | printf("\033[38;5;$c"."m%03d ",$c); 83 | } 84 | print "\n"; 85 | } 86 | 87 | exit; 88 | } 89 | 90 | print "\033[1;4;38;5;237m"." 1 0 2 2 2 2 2 2 0 0 0 0 0 1 1 1 1 1 " ."\033[0m\n"; 91 | 92 | my $i = 38; 93 | #my $i = 38; # 48 = invert - background 94 | 95 | my $split = 1; 96 | 97 | if ( 1 ){ 98 | # print "xx\n"; 99 | foreach my $row(@a){ 100 | my @ap = []; 101 | foreach my $c( (@{$row}) ){ 102 | if ( $split && ($c >=16 && $c <= 51) ){ 103 | push @ap,$c; 104 | printf("\033[0;0m\033[0;1m\033[$i;5;$c"."m%03d ",$c); 105 | printf("\033[0;0m\033[0;0m\033[$i;5;$c"."m%03d ",$c); 106 | printf("\033[0;0m\033[0;2m\033[$i;5;$c"."m%03d ",$c); 107 | 108 | next; 109 | } 110 | 111 | printf("\033[0;0m"); 112 | printf("\033[0;2m\033[$i;5;$c"."m%03d ",$c); 113 | } 114 | 115 | foreach my $c( reverse(@{$row}) ){ 116 | if ( $split && ($c >=16 && $c <= 51) ){ 117 | push @ap,$c; 118 | next; 119 | } 120 | 121 | printf("\033[0;0m"); 122 | printf("\033[0;0m\033[$i;5;$c"."m%03d ",$c); 123 | } 124 | foreach my $c( (@{$row}) ){ 125 | if ( $split && ($c >=16 && $c <= 51) ){ 126 | push @ap,$c; 127 | #printf("\033[0;0m\033[$i;5;$c"."m%03d ",$c); 128 | #printf("\033[0;1m\033[$i;5;$c"."m%03d ",$c); 129 | #printf("\033[0;2m\033[$i;5;$c"."m%03d ",$c); 130 | 131 | 132 | next; 133 | } 134 | printf("\033[0;0m"); 135 | printf("\033[0;1m\033[$i;5;$c"."m%03d ",$c); 136 | } 137 | 138 | # foreach my $c( @{$row} ){ 139 | # printf("\033[0;2m\033[38;5;$c"."m%03d ",$c); 140 | #} 141 | print "\033[40;m\n"; 142 | } 143 | print "\033[1;38;5;237m"." 1 0 2 2 2 2 2 2 0 0 0 0 0 1 1 1 1 1 " ."\033[0m\n"; 144 | print "\n"; 145 | exit; 146 | } 147 | 148 | 149 | 150 | 151 | 152 | 153 | $ln = 0; 154 | foreach my $row(@a){ 155 | if ( $ln == 0 ){ 156 | foreach my $c( @{$row} ){ 157 | printf("\033[38;5;$c"."m%03d ",$c); 158 | } 159 | $ln=1; 160 | } else { 161 | foreach my $c( reverse(@{$row}) ){ 162 | printf("\033[38;5;$c"."m%03d ",$c); 163 | } 164 | $ln=0; 165 | print "\n"; 166 | } 167 | 168 | 169 | #print Dumper($row); 170 | 171 | } 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /test/gray.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | 6 | function col() { 7 | fi=$1; shift 8 | fa=$[$1*36]; shift 9 | for fb in $@; do 10 | printf "\033[0;$fi""m\033[38;5;$[$fa+$fb]""m %03d" $[$fa+$fb] 11 | done 12 | } 13 | 14 | function gray(){ 15 | echo -ne "\033[1;30m$*\033[0m" 16 | } 17 | 18 | gray "Grayscale, #232-255 " 19 | echo 20 | echo 21 | 22 | gray "1: "; col 1 0 {255..232}; echo 23 | gray "0: "; col 0 0 {255..232}; echo 24 | gray "1;2: "; col "1;2" 0 {255..232}; echo 25 | gray "2: "; col 2 0 {255..232}; echo 26 | 27 | echo 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /test/test.sh: -------------------------------------------------------------------------------- 1 | perl -e 'for(32..127,160..255){printf " %3d: %s",$_,chr($_); (($_ | 0x7) == $_) and print "\n";}' 2 | -------------------------------------------------------------------------------- /test/test2.sh: -------------------------------------------------------------------------------- 1 | perl -e 'for(32..127,160..255){printf " %s",chr($_); (($_ | 0xf) 2 | == $_) and print "\n";}' 3 | -------------------------------------------------------------------------------- /test/umlaut.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/test/umlaut.txt -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | CC:=gcc -Os -Wall -Wno-unused-value -static -s 4 | 5 | all: cpfilter ttfz ttfdz 6 | 7 | cpfilter: cpfilter.c ../src/charmaps.h 8 | ${CC} -o cpfilter cpfilter.c 9 | 10 | 11 | ttfz: ttfz.c sdefl.h 12 | gcc -Os -s -o ttfz ttfz.c 13 | 14 | ttfdz: ttfdz.c sdefl.h 15 | gcc -Os -s -o ttfdz ttfdz.c 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tools/README: -------------------------------------------------------------------------------- 1 | contents: 2 | 3 | cpfilter (misc147), filter between different codepages 4 | 5 | szcomp, szdecomp, 6 | uses the sinfl/sdefl library of Micha Mettke, https://github.com/vurtun/lib 7 | used to embed compressed fonts 8 | 9 | -------------------------------------------------------------------------------- /tools/cpfilter.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael105/slterm/b5f7e5b49017f90bf15d55c7456e419cd2678f3e/tools/cpfilter.c -------------------------------------------------------------------------------- /tools/tic/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tic: *.c *.h 6 | gcc -I. -o tic tic.c cdbw.c mi_vector_hash.c compile.c hash.c -Os -s 7 | 8 | 9 | -------------------------------------------------------------------------------- /tools/tic/README: -------------------------------------------------------------------------------- 1 | terminfo compiler 2 | from netbsd/ncurses 3 | 4 | 5 | -------------------------------------------------------------------------------- /tools/tic/cdbw.h: -------------------------------------------------------------------------------- 1 | /* $NetBSD: cdbw.h,v 1.2 2012/06/03 21:21:45 joerg Exp $ */ 2 | /*- 3 | * Copyright (c) 2010 The NetBSD Foundation, Inc. 4 | * All rights reserved. 5 | * 6 | * This code is derived from software contributed to The NetBSD Foundation 7 | * by Joerg Sonnenberger. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in 17 | * the documentation and/or other materials provided with the 18 | * distribution. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | */ 33 | 34 | #ifndef _CDBW_H 35 | #define _CDBW_H 36 | 37 | #include 38 | #include 39 | 40 | struct cdbw; 41 | 42 | struct cdbw *cdbw_open(void); 43 | int cdbw_put(struct cdbw *, const void *, size_t, 44 | const void *, size_t); 45 | int cdbw_put_data(struct cdbw *, const void *, size_t, 46 | uint32_t *); 47 | int cdbw_put_key(struct cdbw *, const void *, size_t, 48 | uint32_t); 49 | uint32_t cdbw_stable_seeder(void); 50 | int cdbw_output(struct cdbw *, int, const char[16], 51 | uint32_t (*)(void)); 52 | void cdbw_close(struct cdbw *); 53 | 54 | #endif /* _CDBW_H */ 55 | -------------------------------------------------------------------------------- /tools/tic/mi_vector_hash.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: mi_vector_hash.c,v 1.1 2013/12/11 01:24:08 joerg Exp $ */ 2 | /*- 3 | * Copyright (c) 2009 The NetBSD Foundation, Inc. 4 | * All rights reserved. 5 | * 6 | * This code is derived from software contributed to The NetBSD Foundation 7 | * by Joerg Sonnenberger. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in 17 | * the documentation and/or other materials provided with the 18 | * distribution. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | */ 33 | 34 | /* 35 | * See http://burtleburtle.net/bob/hash/doobs.html for the full description 36 | * and the original version of the code. This version differs by exposing 37 | * the full internal state and avoiding byte operations in the inner loop 38 | * if the key is aligned correctly. 39 | */ 40 | 41 | #if HAVE_NBTOOL_CONFIG_H 42 | #include "nbtool_config.h" 43 | #endif 44 | 45 | #include 46 | #include 47 | 48 | #define mix(a, b, c) do { \ 49 | a -= b; a -= c; a ^= (c >> 13); \ 50 | b -= c; b -= a; b ^= (a << 8); \ 51 | c -= a; c -= b; c ^= (b >> 13); \ 52 | a -= b; a -= c; a ^= (c >> 12); \ 53 | b -= c; b -= a; b ^= (a << 16); \ 54 | c -= a; c -= b; c ^= (b >> 5); \ 55 | a -= b; a -= c; a ^= (c >> 3); \ 56 | b -= c; b -= a; b ^= (a << 10); \ 57 | c -= a; c -= b; c ^= (b >> 15); \ 58 | } while (/* CONSTCOND */0) 59 | 60 | #define FIXED_SEED 0x9e3779b9 /* Golden ratio, arbitrary constant */ 61 | 62 | void 63 | mi_vector_hash(const void *restrict key, size_t len, uint32_t seed, 64 | uint32_t hashes[3]) 65 | { 66 | uint32_t orig_len, a, b, c; 67 | const uint8_t *k; 68 | 69 | orig_len = (uint32_t)len; 70 | 71 | a = b = FIXED_SEED; 72 | c = seed; 73 | 74 | k = key; 75 | while (len >= 12) { 76 | a += k[0]; 77 | a += (uint32_t)k[1] << 8; 78 | a += (uint32_t)k[2] << 16; 79 | a += (uint32_t)k[3] << 24; 80 | b += k[4]; 81 | b += (uint32_t)k[5] << 8; 82 | b += (uint32_t)k[6] << 16; 83 | b += (uint32_t)k[7] << 24; 84 | c += k[8]; 85 | c += (uint32_t)k[9] << 8; 86 | c += (uint32_t)k[10] << 16; 87 | c += (uint32_t)k[11] << 24; 88 | mix(a, b, c); 89 | k += 12; 90 | len -= 12; 91 | } 92 | c += orig_len; 93 | 94 | if (len > 8) { 95 | switch (len) { 96 | case 11: 97 | c += (uint32_t)k[10] << 24; 98 | /* FALLTHROUGH */ 99 | case 10: 100 | c += (uint32_t)k[9] << 16; 101 | /* FALLTHROUGH */ 102 | case 9: 103 | c += (uint32_t)k[8] << 8; 104 | /* FALLTHROUGH */ 105 | } 106 | b += k[4]; 107 | b += (uint32_t)k[5] << 8; 108 | b += (uint32_t)k[6] << 16; 109 | b += (uint32_t)k[7] << 24; 110 | a += k[0]; 111 | a += (uint32_t)k[1] << 8; 112 | a += (uint32_t)k[2] << 16; 113 | a += (uint32_t)k[3] << 24; 114 | } else if (len > 4) { 115 | switch (len) { 116 | case 8: 117 | b += (uint32_t)k[7] << 24; 118 | /* FALLTHROUGH */ 119 | case 7: 120 | b += (uint32_t)k[6] << 16; 121 | /* FALLTHROUGH */ 122 | case 6: 123 | b += (uint32_t)k[5] << 8; 124 | /* FALLTHROUGH */ 125 | case 5: 126 | b += k[4]; 127 | /* FALLTHROUGH */ 128 | } 129 | a += k[0]; 130 | a += (uint32_t)k[1] << 8; 131 | a += (uint32_t)k[2] << 16; 132 | a += (uint32_t)k[3] << 24; 133 | } else if (len) { 134 | switch (len) { 135 | case 4: 136 | a += (uint32_t)k[3] << 24; 137 | /* FALLTHROUGH */ 138 | case 3: 139 | a += (uint32_t)k[2] << 16; 140 | /* FALLTHROUGH */ 141 | case 2: 142 | a += (uint32_t)k[1] << 8; 143 | /* FALLTHROUGH */ 144 | case 1: 145 | a += k[0]; 146 | /* FALLTHROUGH */ 147 | } 148 | } 149 | mix(a, b, c); 150 | hashes[0] = a; 151 | hashes[1] = b; 152 | hashes[2] = c; 153 | } 154 | -------------------------------------------------------------------------------- /tools/tic/mi_vector_hash.h: -------------------------------------------------------------------------------- 1 | #ifndef MI_VECTOR_HASH_H 2 | #define MI_VECTOR_HASH_H 3 | 4 | void mi_vector_hash(const void *restrict, size_t, uint32_t, uint32_t[3]); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /tools/tic/tic.1: -------------------------------------------------------------------------------- 1 | .\" $NetBSD: tic.1,v 1.13 2017/02/22 13:43:15 abhinav Exp $ 2 | .\" 3 | .\" Copyright (c) 2009, 2010 The NetBSD Foundation, Inc. 4 | .\" All rights reserved. 5 | .\" 6 | .\" This code is derived from software contributed to The NetBSD Foundation 7 | .\" by Roy Marples. 8 | .\" 9 | .\" Redistribution and use in source and binary forms, with or without 10 | .\" modification, are permitted provided that the following conditions 11 | .\" are met: 12 | .\" 1. Redistributions of source code must retain the above copyright 13 | .\" notice, this list of conditions and the following disclaimer. 14 | .\" 2. Redistributions in binary form must reproduce the above copyright 15 | .\" notice, this list of conditions and the following disclaimer in the 16 | .\" documentation and/or other materials provided with the distribution. 17 | .\" 18 | .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 | .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 | .\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 | .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 | .\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | .\" POSSIBILITY OF SUCH DAMAGE. 29 | .\" 30 | .Dd June 3, 2012 31 | .Dt TIC 1 32 | .Os 33 | .Sh NAME 34 | .Nm tic 35 | .Nd terminfo compiler 36 | .Sh SYNOPSIS 37 | .Nm tic 38 | .Op Fl acSsx 39 | .Op Fl o Ar file 40 | .Ar source 41 | .Op Ar term1 term2 ... 42 | .Sh DESCRIPTION 43 | The 44 | .Nm 45 | utility compiles 46 | .Xr terminfo 5 47 | source into a database for use by other programs. 48 | The created database path name is the same as the source but with .cdb appended. 49 | .Pp 50 | The following options are available: 51 | .Bl -tag -width Fl 52 | .It Fl a 53 | Do not discard commented out capabilities. 54 | .It Fl c 55 | Only check for errors, don't write the final database. 56 | .It Fl o Ar file 57 | Write the database to 58 | .Ar file 59 | instead of 60 | .Ar source Ns .cdb . 61 | .It Fl S 62 | For 63 | .Ar term1 , term2 , ... 64 | output a C structure containing name, compiled description, and compiled size. 65 | This can be used to embed terminal descriptions into a program. 66 | .It Fl s 67 | Display the number of terminal descriptions written to the database. 68 | .It Fl x 69 | Include non standard capabilities defined in the 70 | .Ar source . 71 | .El 72 | .Ss Extensions To Terminfo 73 | When 74 | .Nm 75 | discovers a 76 | .Sy use Ns = Ns Va term 77 | capability, the terminal description for 78 | .Va term 79 | is merged in. 80 | Capabilities do not overwrite previously discovered ones and capabilities 81 | ending with @ are marked as absent so the terminal does not inherit the 82 | capability from 83 | .Sy use Ns d 84 | terminals. 85 | .Sh EXIT STATUS 86 | .Ex -std tic 87 | .Sh EXAMPLES 88 | To maintain your private terminfo definitions, if the system supplied 89 | ones do not support your terminal: 90 | .Bd -literal -offset indent 91 | .Ic tic ~/.terminfo 92 | .Ed 93 | .Sh SEE ALSO 94 | .Xr infocmp 1 , 95 | .Xr tput 1 , 96 | .Xr curses 3 , 97 | .Xr terminfo 5 98 | .Sh STANDARDS 99 | The 100 | .Nm 101 | utility works with terminfo files that conform to the 102 | .St -xcurses4.2 103 | standard. 104 | .Sh AUTHORS 105 | .An Roy Marples Aq Mt roy@NetBSD.org 106 | -------------------------------------------------------------------------------- /tools/ttfdz.c: -------------------------------------------------------------------------------- 1 | /* 2 | Decompress font file 3 | intended for testing only. 4 | 5 | usage: ttfdz infile outfile 6 | 7 | misc 2025, Public Domain 8 | This is free and unencumbered software released into the public domain. 9 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 10 | software, either in source code form or as a compiled binary, for any purpose, 11 | commercial or non-commercial, and by any means. 12 | In jurisdictions that recognize copyright laws, the author or authors of this 13 | software dedicate any and all copyright interest in the software to the public 14 | domain. We make this dedication for the benefit of the public at large and to 15 | the detriment of our heirs and successors. We intend this dedication to be an 16 | overt act of relinquishment in perpetuity of all present and future rights to 17 | this software under copyright law. 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | 31 | #define SINFL_IMPLEMENTATION 32 | #include "sinfl.h" 33 | 34 | 35 | 36 | int main( int argc, char **argv ){ 37 | if ( argc!=3 ){ 38 | fprintf(stderr,"Usage: ttfdz infile outfile\n"); 39 | exit(22); 40 | } 41 | 42 | void *in,*out; 43 | 44 | FILE* fp = fopen(argv[1], "r"); 45 | if (!fp) exit(2); 46 | fseek(fp, 0, SEEK_END); 47 | size_t size = (size_t)ftell(fp); 48 | fseek(fp, 0, SEEK_SET); 49 | in = calloc(size, 1); 50 | fread(in, 1, (size_t)size, fp); 51 | fclose(fp); 52 | 53 | 54 | out = calloc( size*8,1 ); // well. should work, for ttf fonts. 55 | // This is for testing only, so. 56 | 57 | size_t len = sinflate( out, size*8, in, size ); 58 | if ( len == size*8 ){ 59 | fprintf( stderr, "buffer too small, internal error\n" ); 60 | exit(1); 61 | } 62 | 63 | //printf("len: %d\n",len); 64 | 65 | fp = fopen( argv[2], "r" ); 66 | if ( fp ){ 67 | fprintf( stderr, "outfile exists: %s\nAbort\n",argv[2] ); 68 | fclose(fp); 69 | exit(1); 70 | } 71 | 72 | fp = fopen( argv[2], "w" ); 73 | 74 | if (!fp){ 75 | fprintf(stderr, "Cannot write to %s\n", argv[2] ); 76 | exit(1); 77 | } 78 | fwrite( out, 1, len, fp ); 79 | fclose(fp); 80 | 81 | printf("Decompress:\n%s -> %s\n%d -> %d\n", argv[1], argv[2], size, len ); 82 | 83 | return(0); 84 | } 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /tools/ttfz.c: -------------------------------------------------------------------------------- 1 | /* 2 | Compress font files (or other files) 3 | Error checking should be done separately, 4 | intended only for the build process of slterm. 5 | 6 | Limits: no error checking, will not work very well with bigger files, 7 | there might be more trouble. 8 | Works for the intended usage, however. 9 | 10 | 11 | usage: ttfz infile outfile 12 | 13 | misc 2025, Public Domain 14 | This is free and unencumbered software released into the public domain. 15 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 16 | software, either in source code form or as a compiled binary, for any purpose, 17 | commercial or non-commercial, and by any means. 18 | In jurisdictions that recognize copyright laws, the author or authors of this 19 | software dedicate any and all copyright interest in the software to the public 20 | domain. We make this dedication for the benefit of the public at large and to 21 | the detriment of our heirs and successors. We intend this dedication to be an 22 | overt act of relinquishment in perpetuity of all present and future rights to 23 | this software under copyright law. 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | */ 32 | 33 | #include 34 | #include 35 | 36 | 37 | #define SDEFL_IMPLEMENTATION 38 | #include "sdefl.h" 39 | 40 | 41 | static struct sdefl sdefl; 42 | 43 | 44 | int main( int argc, char **argv ){ 45 | if ( argc!=3 ){ 46 | fprintf(stderr,"Usage: ttfz infile outfile\n"); 47 | exit(22); 48 | } 49 | 50 | void *in,*out; 51 | 52 | FILE* fp = fopen(argv[1], "r"); 53 | if (!fp) exit(2); 54 | fseek(fp, 0, SEEK_END); 55 | size_t size = (size_t)ftell(fp); 56 | fseek(fp, 0, SEEK_SET); 57 | in = calloc(size, 1); 58 | fread(in, 1, (size_t)size, fp); 59 | fclose(fp); 60 | 61 | 62 | out = calloc( size*2,1 ); 63 | 64 | size_t len = sdeflate(&sdefl, out, in, (int)size, 7); 65 | 66 | //printf("len: %d\n",len); 67 | 68 | fp = fopen( argv[2], "r" ); 69 | if ( fp ){ 70 | fprintf( stderr, "outfile exists: %s\nAbort\n",argv[2] ); 71 | fclose(fp); 72 | exit(1); 73 | } 74 | 75 | fp = fopen( argv[2], "w" ); 76 | 77 | if (!fp){ 78 | fprintf(stderr, "Cannot write to %s\n", argv[2] ); 79 | exit(1); 80 | } 81 | fwrite( out, 1, len, fp ); 82 | fclose(fp); 83 | 84 | printf("Compress:\n%s -> %s\n%d -> %d\n", argv[1], argv[2], size, len ); 85 | 86 | return(0); 87 | } 88 | 89 | 90 | 91 | --------------------------------------------------------------------------------