├── .github └── workflows │ └── build-chafa.yml ├── LICENSE ├── Makefile ├── README.md ├── canvas.go ├── chafa.go ├── config.go ├── embedded.go ├── examples ├── adaptive │ ├── go.mod │ ├── go.sum │ └── main.go ├── aspectratio │ └── main.go ├── image.png ├── passthrough │ └── main.go └── simple │ └── main.go ├── features.go ├── frame.go ├── go.mod ├── go.sum ├── image.go ├── libs ├── BUILD_INFO.txt ├── CHECKSUMS.txt ├── darwin-arm64 │ └── libchafa.dylib ├── linux-386 │ └── libchafa.so └── linux-amd64 │ └── libchafa.so ├── miscellaneous.go ├── placement.go ├── showcase.png ├── symbol_map.go ├── termdb.go └── terminfo.go /.github/workflows/build-chafa.yml: -------------------------------------------------------------------------------- 1 | name: Build Multi-Architecture Binaries 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | chafa_version: 7 | description: 'Chafa version to build' 8 | required: true 9 | default: '1.16' 10 | 11 | jobs: 12 | build-linux: 13 | runs-on: ubuntu-latest 14 | strategy: 15 | matrix: 16 | arch: [amd64, 386] 17 | steps: 18 | - uses: actions/checkout@v4 19 | with: 20 | token: ${{ secrets.GITHUB_TOKEN }} 21 | 22 | - name: Install cross-compilation tools 23 | run: | 24 | sudo apt update 25 | sudo apt install -y \ 26 | autotools-dev \ 27 | autoconf \ 28 | automake \ 29 | libtool \ 30 | pkg-config \ 31 | build-essential \ 32 | libglib2.0-dev 33 | 34 | case "${{ matrix.arch }}" in 35 | amd64) 36 | ;; 37 | # arm64) 38 | # sudo dpkg --add-architecture armhf 39 | # sudo dpkg --add-architecture arm64 40 | # sudo apt update 41 | # sudo apt install -y gcc-aarch64-linux-gnu libglib2.0-dev:arm64 42 | # ;; 43 | 386) 44 | sudo dpkg --add-architecture i386 45 | sudo apt update 46 | sudo apt install -y gcc-multilib libc6-dev-i386 libglib2.0-dev:i386 47 | ;; 48 | esac 49 | 50 | - name: Build Linux ${{ matrix.arch }} 51 | run: | 52 | case "${{ matrix.arch }}" in 53 | amd64) 54 | make libs/linux_amd64/libchafa.so 55 | ;; 56 | # arm64) 57 | # make libs/linux_arm64/libchafa.so 58 | # ;; 59 | 386) 60 | make libs/linux_386/libchafa.so 61 | ;; 62 | esac 63 | 64 | - name: Upload artifacts 65 | uses: actions/upload-artifact@v4 66 | with: 67 | name: linux-${{ matrix.arch }} 68 | path: libs/linux_${{ matrix.arch }}/ 69 | 70 | build-darwin: 71 | runs-on: macos-latest 72 | strategy: 73 | matrix: 74 | arch: [arm64] 75 | steps: 76 | - uses: actions/checkout@v4 77 | with: 78 | token: ${{ secrets.GITHUB_TOKEN }} 79 | 80 | - name: Install dependencies 81 | run: | 82 | brew install autoconf automake libtool pkg-config 83 | 84 | - name: Setup GNU tools for autotools 85 | run: | 86 | # Create symlinks so autotools can find GNU libtool 87 | sudo ln -sf $(brew --prefix)/bin/glibtool /usr/local/bin/libtool 88 | sudo ln -sf $(brew --prefix)/bin/glibtoolize /usr/local/bin/libtoolize 89 | # Add to PATH 90 | echo "$(brew --prefix)/bin" >> $GITHUB_PATH 91 | 92 | - name: Build Darwin ${{ matrix.arch }} 93 | run: | 94 | case "${{ matrix.arch }}" in 95 | arm64) 96 | make libs/darwin_arm64/libchafa.dylib 97 | ;; 98 | esac 99 | 100 | - name: Upload artifacts 101 | uses: actions/upload-artifact@v4 102 | with: 103 | name: darwin-${{ matrix.arch }} 104 | path: libs/darwin_${{ matrix.arch }}/ 105 | 106 | combine-and-commit: 107 | needs: [build-linux, build-darwin] 108 | runs-on: ubuntu-latest 109 | 110 | permissions: 111 | contents: write 112 | 113 | steps: 114 | - uses: actions/checkout@v4 115 | with: 116 | token: ${{ secrets.GITHUB_TOKEN }} 117 | 118 | - name: Download all artifacts 119 | uses: actions/download-artifact@v4 120 | with: 121 | path: artifacts/ 122 | 123 | - name: Organize binaries 124 | run: | 125 | mkdir -p libs/ 126 | cp -r artifacts/. libs/ 127 | 128 | - name: Generate checksums and build info 129 | run: | 130 | find libs/ -name "*.so" -o -name "*.dylib" | xargs sha256sum > libs/CHECKSUMS.txt 131 | echo "Chafa Version: ${{ github.event.inputs.chafa_version || '1.16' }}" > libs/BUILD_INFO.txt 132 | echo "Build Date: $(date)" >> libs/BUILD_INFO.txt 133 | echo "Workflow: ${{ github.run_id }}" >> libs/BUILD_INFO.txt 134 | 135 | - name: Commit binaries 136 | run: | 137 | git config --local user.email "action@github.com" 138 | git config --local user.name "GitHub Action" 139 | git add libs/ 140 | git diff --staged --quiet || git commit -m "[skip ci] Generate binaries" 141 | git push 142 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025 Konstantinos Artopoulos 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | 9 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CHAFAVERSION = 1.16 2 | PREFIX = $(CURDIR)/build 3 | LIBDIR = libs 4 | 5 | # Define all target architectures 6 | LINUX_TARGETS = $(LIBDIR)/linux_amd64/libchafa.so $(LIBDIR)/linux_arm64/libchafa.so $(LIBDIR)/linux_386/libchafa.so 7 | DARWIN_TARGETS = $(LIBDIR)/darwin_amd64/libchafa.dylib $(LIBDIR)/darwin_arm64/libchafa.dylib 8 | 9 | .PHONY: all clean linux darwin 10 | 11 | all: linux darwin 12 | 13 | linux: $(LINUX_TARGETS) 14 | 15 | darwin: $(DARWIN_TARGETS) 16 | 17 | # Linux AMD64 18 | $(LIBDIR)/linux_amd64/libchafa.so: 19 | mkdir -p $(CURDIR)/$(LIBDIR)/linux_amd64 && \ 20 | mkdir -p build/chafa-linux-amd64 && cd build/chafa-linux-amd64 && \ 21 | git clone --branch $(CHAFAVERSION) --depth 1 https://github.com/hpjansson/chafa.git . && \ 22 | CC=gcc \ 23 | CFLAGS="-m64" \ 24 | LDFLAGS="-m64" \ 25 | ./autogen.sh --without-tools --host=x86_64-linux-gnu && make 26 | cp build/chafa-linux-amd64/chafa/.libs/libchafa.so $(CURDIR)/$(LIBDIR)/linux_amd64/libchafa.so 27 | 28 | # Linux ARM64 29 | $(LIBDIR)/linux_arm64/libchafa.so: 30 | mkdir -p $(CURDIR)/$(LIBDIR)/linux_arm64 && \ 31 | mkdir -p build/chafa-linux-arm64 && cd build/chafa-linux-arm64 && \ 32 | git clone --branch $(CHAFAVERSION) --depth 1 https://github.com/hpjansson/chafa.git . && \ 33 | CC=aarch64-linux-gnu-gcc \ 34 | ./autogen.sh --without-tools --host=aarch64-linux-gnu && make 35 | cp build/chafa-linux-arm64/chafa/.libs/libchafa.so $(CURDIR)/$(LIBDIR)/linux_arm64/libchafa.so 36 | 37 | # Linux 386 38 | $(LIBDIR)/linux_386/libchafa.so: 39 | mkdir -p $(CURDIR)/$(LIBDIR)/linux_386 && \ 40 | mkdir -p build/chafa-linux-386 && cd build/chafa-linux-386 && \ 41 | git clone --branch $(CHAFAVERSION) --depth 1 https://github.com/hpjansson/chafa.git . && \ 42 | CC=gcc \ 43 | CFLAGS="-m32" \ 44 | LDFLAGS="-m32" \ 45 | ./autogen.sh --without-tools --host=i686-linux-gnu && make 46 | cp build/chafa-linux-386/chafa/.libs/libchafa.so $(CURDIR)/$(LIBDIR)/linux_386/libchafa.so 47 | 48 | # Darwin AMD64 49 | $(LIBDIR)/darwin_amd64/libchafa.dylib: 50 | mkdir -p $(CURDIR)/$(LIBDIR)/darwin_amd64 && \ 51 | mkdir -p build/chafa-darwin-amd64 && cd build/chafa-darwin-amd64 && \ 52 | git clone --branch $(CHAFAVERSION) --depth 1 https://github.com/hpjansson/chafa.git . && \ 53 | CC=clang \ 54 | CFLAGS="-arch x86_64" \ 55 | LDFLAGS="-arch x86_64" \ 56 | LIBTOOL=glibtool \ 57 | LIBTOOLIZE=glibtoolize \ 58 | ./autogen.sh --without-tools --host=x86_64-apple-darwin && make 59 | cp build/chafa-darwin-amd64/chafa/.libs/libchafa.dylib $(CURDIR)/$(LIBDIR)/darwin_amd64/libchafa.dylib 60 | 61 | # Darwin ARM64 (Apple Silicon) 62 | $(LIBDIR)/darwin_arm64/libchafa.dylib: 63 | mkdir -p $(CURDIR)/$(LIBDIR)/darwin_arm64 && \ 64 | mkdir -p build/chafa-darwin-arm64 && cd build/chafa-darwin-arm64 && \ 65 | git clone --branch $(CHAFAVERSION) --depth 1 https://github.com/hpjansson/chafa.git . && \ 66 | CC=clang \ 67 | CFLAGS="-arch arm64" \ 68 | LDFLAGS="-arch arm64" \ 69 | LIBTOOL=glibtool \ 70 | LIBTOOLIZE=glibtoolize \ 71 | ./autogen.sh --without-tools --host=aarch64-apple-darwin && make 72 | cp build/chafa-darwin-arm64/chafa/.libs/libchafa.dylib $(CURDIR)/$(LIBDIR)/darwin_arm64/libchafa.dylib 73 | 74 | clean: 75 | rm -rf build $(LIBDIR)/ 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # chafa-go 2 | 3 | [![Go Reference](https://pkg.go.dev/badge/github.com/ploMP4/chafa-go.svg)](https://pkg.go.dev/github.com/ploMP4/chafa-go) 4 | 5 | **chafa-go** provides Go bindings for the [Chafa](https://hpjansson.org/chafa/) C library using [purego](https://github.com/ebitengine/purego), meaning **no CGO is required**. Chafa is a powerful image-to-text converter for terminal graphics, supporting a variety of character sets, color modes, and dithering options. 6 | 7 |
8 | slideshow 9 |
10 | 11 | There are precompiled `libchafa` shared objects embedded in the repository using Go’s `embed` feature. 12 | These binaries are automatically built from the official Chafa source and committed via a GitHub Action. 13 | At runtime, the correct binary for your platform is selected and loaded dynamically. 14 | 15 | Currently Supported Platforms: 16 | 17 | - linux/amd64 18 | - linux/386 19 | - darwin/arm64 20 | 21 | ## Installation 22 | 23 | ```bash 24 | go get github.com/ploMP4/chafa-go 25 | ``` 26 | 27 | ## Usage 28 | 29 | Basic usage is shown below. For more complete examples, see the [examples/](./examples/) directory. 30 | 31 | ```go 32 | package main 33 | 34 | import ( 35 | "fmt" 36 | 37 | "github.com/ploMP4/chafa-go" 38 | ) 39 | 40 | const ( 41 | PixWidth = 3 42 | PixHeight = 3 43 | NChannels = 4 44 | ) 45 | 46 | func main() { 47 | pixels := []uint8{ 48 | 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 49 | 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 50 | 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 51 | } 52 | 53 | // Specify the symbols we want 54 | symbolMap := chafa.SymbolMapNew() 55 | defer chafa.SymbolMapUnref(symbolMap) 56 | 57 | chafa.SymbolMapAddByTags(symbolMap, chafa.CHAFA_SYMBOL_TAG_ALL) 58 | 59 | // Set up a configuration with the symbols and the canvas size in characters 60 | config := chafa.CanvasConfigNew() 61 | defer chafa.CanvasConfigUnref(config) 62 | 63 | chafa.CanvasConfigSetGeometry(config, 40, 20) 64 | chafa.CanvasConfigSetSymbolMap(config, symbolMap) 65 | 66 | // Create canvas 67 | canvas := chafa.CanvasNew(config) 68 | defer chafa.CanvasUnRef(canvas) 69 | 70 | // Draw pixels to canvas 71 | chafa.CanvasDrawAllPixels( 72 | canvas, 73 | chafa.CHAFA_PIXEL_RGBA8_UNASSOCIATED, 74 | pixels, 75 | PixWidth, 76 | PixHeight, 77 | PixWidth*NChannels, 78 | ) 79 | 80 | // Generate a string that will show the canvas contents on a terminal 81 | gs := chafa.CanvasPrint(canvas, nil) 82 | 83 | fmt.Println(gs) 84 | } 85 | ``` 86 | 87 | ## Contributing 88 | 89 | All contributions are welcome! If you're planning a significant change or you're unsure about an idea, please open an issue first so we can discuss it in detail. 90 | 91 | ## Acknowledgments 92 | 93 | - [Chafa](https://hpjansson.org/chafa/) by Hans Petter Jansson 94 | - [purego](https://github.com/ebitengine/purego) by the Ebitengine project 95 | -------------------------------------------------------------------------------- /canvas.go: -------------------------------------------------------------------------------- 1 | package chafa 2 | 3 | import "unsafe" 4 | 5 | var ( 6 | // Creates a new canvas with the specified configuration. The canvas makes 7 | // a private copy of the configuration, so it will not be affected by subsequent changes. 8 | CanvasNew func(config *CanvasConfig) *Canvas 9 | 10 | // Creates a new canvas configured similarly to orig. 11 | CanvasNewSimilar func(orig *Canvas) *Canvas 12 | 13 | // Adds a reference to canvas. 14 | CanvasRef func(canvas *Canvas) 15 | 16 | // Removes a reference from canvas. When remaining references drops to zero, 17 | // the canvas is freed and can no longer be used. 18 | CanvasUnRef func(canvas *Canvas) 19 | 20 | // Returns a pointer to the configuration belonging to canvas. 21 | // This can be inspected using the [CanvasConfig] getter functions, but not changed. 22 | CanvasPeekConfig func(canvas *Canvas) *CanvasConfig 23 | 24 | // Places placement on canvas, replacing the latter's content. The placement will cover the entire canvas. 25 | // 26 | // The canvas will keep a reference to the placement until it is replaced or the canvas itself is freed. 27 | CanvasSetPlacement func(canvas *Canvas, placement *Placement) 28 | 29 | // Replaces pixel data of canvas with a copy of that found at src_pixels , 30 | // which must be in one of the formats supported by [PixelType]. 31 | CanvasDrawAllPixels func( 32 | canvas *Canvas, 33 | srcPixelType PixelType, 34 | srcPixels []uint8, 35 | srcWidth int32, 36 | srcHeight int32, 37 | srcRowstride int32, 38 | ) 39 | 40 | // Builds a UTF-8 string of terminal control sequences and symbols representing the canvas' current contents. 41 | // This can be printed to a terminal. The exact choice of escape sequences and symbols, dimensions, etc. 42 | // is determined by the configuration assigned to canvas on its creation. 43 | // 44 | // All output lines except for the last one will end in a newline. 45 | CanvasPrint func(canvas *Canvas, termInfo *TermInfo) *GString 46 | 47 | //Builds an array of UTF-8 strings made up of terminal control sequences and symbols 48 | // representing the canvas' current contents. These can be printed to a terminal. 49 | // The exact choice of escape sequences and symbols, dimensions, etc. is determined 50 | // by the configuration assigned to canvas on its creation. 51 | // 52 | // The array will be NULL-terminated. The element count does not include the terminator. 53 | // 54 | // When the canvas' pixel mode is [CHAFA_PIXEL_MODE_SYMBOLS], each element will hold 55 | // the contents of exactly one symbol row. There will be no row separators, 56 | // newlines or control sequences to reposition the cursor between rows. 57 | // Row positioning is left to the caller. 58 | // 59 | // In other pixel modes, there may be one or more strings, but the splitting 60 | // criteria should not be relied on. They must be printed in sequence, exactly as they appear. 61 | CanvasPrintRows func(canvas *Canvas, termInfo *TermInfo, arrayOut *unsafe.Pointer, lenOut *int32) 62 | 63 | // Builds an array of UTF-8 strings made up of terminal control sequences and symbols 64 | // representing the canvas' current contents. These can be printed to a terminal. 65 | // The exact choice of escape sequences and symbols, dimensions, etc. is determined by 66 | // the configuration assigned to canvas on its creation. 67 | // 68 | // When the canvas' pixel mode is [CHAFA_PIXEL_MODE_SYMBOLS], each element 69 | // will hold the contents of exactly one symbol row. There will be no row separators, 70 | // newlines or control sequences to reposition the cursor between rows. 71 | // Row positioning is left to the caller. 72 | // 73 | // In other pixel modes, there may be one or more strings, 74 | // but the splitting criteria should not be relied on. 75 | // They must be printed in sequence, exactly as they appear. 76 | CanvasPrintRowsStrv func(canvas *Canvas, termInfo *TermInfo) unsafe.Pointer 77 | 78 | // Returns the character at cell (x, y). The coordinates are zero-indexed. 79 | // For double-width characters, the leftmost cell will contain the character 80 | // and the rightmost cell will contain 0. 81 | CanvasGetCharAt func(canvas *Canvas, x, y int32) rune 82 | 83 | // Sets the character at cell (x, y). The coordinates are zero-indexed. 84 | // For double-width characters, the leftmost cell must contain the character 85 | // and the cell to the right of it will automatically be set to 0. 86 | // 87 | // If the character is a nonprintable or zero-width, no change will be made. 88 | CanvasSetCharAt func(canvas *Canvas, x, y int32, c rune) int32 89 | 90 | // Gets the colors at cell (x, y). The coordinates are zero-indexed. 91 | // For double-width characters, both cells will contain the same colors. 92 | // 93 | // The colors will be -1 for transparency, packed 8bpc RGB otherwise, i.e. 0x00RRGGBB hex. 94 | // 95 | // If the canvas is in an indexed mode, palette lookups will be made for you. 96 | CanvasGetColorsAt func(canvas *Canvas, x, y int32, fgOut, bgOut *int32) 97 | 98 | // Sets the colors at cell (x, y). The coordinates are zero-indexed. 99 | // For double-width characters, both cells will be set to the same color. 100 | // 101 | // The colors must be -1 for transparency, packed 8bpc RGB otherwise, i.e. 0x00RRGGBB hex. 102 | // 103 | // If the canvas is in an indexed mode, palette lookups will be made for you. 104 | CanvasSetColorsAt func(canvas *Canvas, x, y, fg, bg int32) 105 | 106 | // Gets the colors at cell (x, y). The coordinates are zero-indexed. 107 | // For double-width characters, both cells will contain the same colors. 108 | // 109 | // The colors will be -1 for transparency, packed 8bpc RGB, i.e. 0x00RRGGBB hex 110 | // in truecolor mode, or the raw pen value (0-255) in indexed modes. 111 | // 112 | // It's the caller's responsibility to handle the color values correctly 113 | // according to the canvas mode (truecolor or indexed). 114 | CanvasGetRawColorsAt func(canvas *Canvas, x, y int32, fgOut, bgOut *int32) 115 | 116 | // Sets the colors at cell (x, y). The coordinates are zero-indexed. 117 | // For double-width characters, both cells will be set to the same color. 118 | // 119 | // The colors must be -1 for transparency, packed 8bpc RGB, i.e. 0x00RRGGBB hex 120 | // in truecolor mode, or the raw pen value (0-255) in indexed modes. 121 | // 122 | // It's the caller's responsibility to handle the color values correctly 123 | // according to the canvas mode (truecolor or indexed). 124 | CanvasSetRawColorsAt func(canvas *Canvas, x, y, fg, bg int32) 125 | ) 126 | 127 | type Canvas struct { 128 | Refs int32 129 | 130 | WidthPixels, HeightPixels int32 131 | Pixels *Pixel 132 | Cells *CanvasCell 133 | HaveAlpha bool 134 | NeedsClear bool 135 | 136 | // Whether to consider inverted symbols; FALSE if using FG only 137 | ConsiderInverted bool 138 | 139 | // Whether to extract symbol colors; FALSE if using default colors 140 | ExtractColors bool 141 | 142 | // Whether to quantize colors before calculating error (slower, but 143 | // yields better results in palettized modes, especially 16/8) 144 | UseQuantizedError bool 145 | 146 | DefaultColors ColorPair 147 | WorkFactorInt uint32 148 | 149 | // Character to use in cells where fg color == bg color. Typically 150 | // space, but could be something else depending on the symbol map. 151 | BlankChar uint8 // gunichar 152 | 153 | // Character to use in cells where fg color == bg color and the color 154 | // is only legal in FG. Typically 0x2588 (solid block), but could be 155 | // something else depending on the symbol map. Can be zero if there is 156 | // no good candidate! 157 | SolidChar uint8 // gunichar 158 | 159 | Config CanvasConfig 160 | 161 | // Used when setting pixel data 162 | Dither Dither 163 | 164 | // This is NULL in CHAFA_PIXEL_MODE_SYMBOLS, otherwise one of: 165 | // (ChafaSixelCanvas *), (ChafaKittyCanvas *), (ChafaIterm2Canvas *) 166 | PixelCanvas unsafe.Pointer 167 | 168 | // It's possible to have a single placement that covers the entire 169 | // canvas. In this case, it is stored here. 170 | Placement *Placement 171 | 172 | // Our palettes. Kind of a big structure, so they go last. 173 | FgPalette Palette 174 | BgPalette Palette 175 | } 176 | 177 | type Pixel struct { 178 | Col Color 179 | } 180 | 181 | type Color struct { 182 | Ch [4]uint8 183 | } 184 | 185 | type CanvasCell struct { 186 | C uint8 187 | 188 | // Colors can be either packed RGBA or index 189 | FgColor uint32 190 | BgColor uint32 191 | } 192 | 193 | type ColorPair struct { 194 | Colors [2]Color 195 | } 196 | 197 | type Dither struct { 198 | Mode DitherMode 199 | Intensity float64 200 | GrainWidthShift int32 201 | GrainHeightShift int32 202 | 203 | TextureSizeShift int32 204 | TextureSizeMask uint32 205 | TextureData *int32 206 | } 207 | 208 | type DitherMode int32 209 | 210 | const ( 211 | CHAFA_DITHER_MODE_NONE DitherMode = 0 212 | CHAFA_DITHER_MODE_ORDERED DitherMode = 1 213 | CHAFA_DITHER_MODE_DIFFUSION DitherMode = 2 214 | CHAFA_DITHER_MODE_MAX DitherMode = 3 215 | 216 | // CHAFA_DITHER_MODE_NOISE DitherMode = 3 217 | ) 218 | 219 | type PixelType int32 220 | 221 | const ( 222 | /* 32 bits per pixel */ 223 | 224 | CHAFA_PIXEL_RGBA8_PREMULTIPLIED PixelType = 0 225 | CHAFA_PIXEL_BGRA8_PREMULTIPLIED PixelType = 1 226 | CHAFA_PIXEL_ARGB8_PREMULTIPLIED PixelType = 2 227 | CHAFA_PIXEL_ABGR8_PREMULTIPLIED PixelType = 3 228 | 229 | CHAFA_PIXEL_RGBA8_UNASSOCIATED PixelType = 4 230 | CHAFA_PIXEL_BGRA8_UNASSOCIATED PixelType = 5 231 | CHAFA_PIXEL_ARGB8_UNASSOCIATED PixelType = 6 232 | CHAFA_PIXEL_ABGR8_UNASSOCIATED PixelType = 7 233 | 234 | /* 24 bits per pixel */ 235 | 236 | CHAFA_PIXEL_RGB8 PixelType = 8 237 | CHAFA_PIXEL_BGR8 PixelType = 9 238 | 239 | CHAFA_PIXEL_MAX PixelType = 10 240 | ) 241 | 242 | const CHAFA_PALETTE_INDEX_MAX = 259 243 | 244 | type Palette struct { 245 | Type PaletteType 246 | Colors [CHAFA_PALETTE_INDEX_MAX]PaletteColor 247 | Table [CHAFA_COLOR_SPACE_MAX]ColorTable 248 | FirstColor int32 249 | NColors int32 250 | AlphaThreshold int32 251 | TransparentIndex int32 252 | } 253 | 254 | type PaletteType int32 255 | 256 | const ( 257 | CHAFA_PALETTE_TYPE_DYNAMIC_256 PaletteType = 0 258 | CHAFA_PALETTE_TYPE_FIXED_256 PaletteType = 1 259 | CHAFA_PALETTE_TYPE_FIXED_240 PaletteType = 2 260 | CHAFA_PALETTE_TYPE_FIXED_16 PaletteType = 3 261 | CHAFA_PALETTE_TYPE_FIXED_8 PaletteType = 4 262 | CHAFA_PALETTE_TYPE_FIXED_FGBG PaletteType = 5 263 | ) 264 | 265 | type PaletteColor struct { 266 | Col [CHAFA_COLOR_SPACE_MAX]Color 267 | } 268 | 269 | type ColorSpace int32 270 | 271 | const ( 272 | CHAFA_COLOR_SPACE_RGB ColorSpace = 0 273 | CHAFA_COLOR_SPACE_DIN99D ColorSpace = 1 274 | CHAFA_COLOR_SPACE_MAX ColorSpace = 2 275 | ) 276 | 277 | const CHAFA_COLOR_TABLE_MAX_ENTRIES = 256 278 | 279 | type ColorTableEntry struct { 280 | V [2]int32 281 | Pen int32 282 | } 283 | 284 | type ColorTable struct { 285 | Entries [CHAFA_COLOR_TABLE_MAX_ENTRIES]ColorTableEntry 286 | 287 | // Each pen is 24 bits (B8G8R8) of color information 288 | Pens [CHAFA_COLOR_TABLE_MAX_ENTRIES]uint32 289 | 290 | NEntries int32 291 | IsSorted bool 292 | 293 | Eigenvectors [2]Vec3i32 294 | Average Vec3i32 295 | 296 | EigenMul [2]uint32 297 | } 298 | 299 | type Vec3i32 struct { 300 | V [3]int32 301 | } 302 | 303 | type CanvasMode int32 304 | 305 | const ( 306 | CHAFA_CANVAS_MODE_TRUECOLOR CanvasMode = 0 307 | CHAFA_CANVAS_MODE_INDEXED_256 CanvasMode = 1 308 | CHAFA_CANVAS_MODE_INDEXED_240 CanvasMode = 2 309 | CHAFA_CANVAS_MODE_INDEXED_16 CanvasMode = 3 310 | CHAFA_CANVAS_MODE_FGBG_BGFG CanvasMode = 4 311 | CHAFA_CANVAS_MODE_FGBG CanvasMode = 5 312 | CHAFA_CANVAS_MODE_INDEXED_8 CanvasMode = 6 313 | CHAFA_CANVAS_MODE_INDEXED_16_8 CanvasMode = 7 314 | CHAFA_CANVAS_MODE_MAX CanvasMode = 8 315 | ) 316 | 317 | type ColorExtractor int32 318 | 319 | const ( 320 | CHAFA_COLOR_EXTRACTOR_AVERAGE ColorExtractor = 0 321 | CHAFA_COLOR_EXTRACTOR_MEDIAN ColorExtractor = 1 322 | CHAFA_COLOR_EXTRACTOR_MAX ColorExtractor = 2 323 | ) 324 | 325 | type PixelMode int32 326 | 327 | const ( 328 | CHAFA_PIXEL_MODE_SYMBOLS PixelMode = 0 329 | CHAFA_PIXEL_MODE_SIXELS PixelMode = 1 330 | CHAFA_PIXEL_MODE_KITTY PixelMode = 2 331 | CHAFA_PIXEL_MODE_ITERM2 PixelMode = 3 332 | CHAFA_PIXEL_MODE_MAX PixelMode = 4 333 | ) 334 | 335 | type Optimizations int32 336 | 337 | const ( 338 | CHAFA_OPTIMIZATION_REUSE_ATTRIBUTES Optimizations = (1 << 0) 339 | CHAFA_OPTIMIZATION_SKIP_CELLS Optimizations = (1 << 1) 340 | CHAFA_OPTIMIZATION_REPEAT_CELLS Optimizations = (1 << 2) 341 | CHAFA_OPTIMIZATION_NONE Optimizations = 0 342 | CHAFA_OPTIMIZATION_ALL Optimizations = 0x7fffffff 343 | ) 344 | 345 | type Passthrough int32 346 | 347 | const ( 348 | CHAFA_PASSTHROUGH_NONE Passthrough = 0 349 | CHAFA_PASSTHROUGH_SCREEN Passthrough = 1 350 | CHAFA_PASSTHROUGH_TMUX Passthrough = 2 351 | CHAFA_PASSTHROUGH_MAX Passthrough = 3 352 | ) 353 | -------------------------------------------------------------------------------- /chafa.go: -------------------------------------------------------------------------------- 1 | package chafa 2 | 3 | import ( 4 | "fmt" 5 | "image" 6 | "image/draw" 7 | "image/gif" 8 | "image/jpeg" 9 | "image/png" 10 | "os" 11 | "path/filepath" 12 | "runtime" 13 | "strings" 14 | "sync" 15 | 16 | "github.com/ebitengine/purego" 17 | ) 18 | 19 | const libName = "libchafa" 20 | 21 | func loadLibrary() (uintptr, error) { 22 | // Try to extract embedded library first 23 | libPath, err := extractEmbeddedLibrary() 24 | if err == nil { 25 | // Successfully extracted embedded library, try to load it 26 | slib, err := purego.Dlopen(libPath, purego.RTLD_NOW|purego.RTLD_GLOBAL) 27 | if err == nil { 28 | return slib, nil 29 | } 30 | // If loading failed, log the error and fall back to system paths 31 | fmt.Printf("Warning: Failed to load embedded library: %v\n", err) 32 | } else { 33 | fmt.Printf("Warning: Failed to extract embedded library: %v\n", err) 34 | } 35 | 36 | // Fall back to original behavior for compatibility 37 | var libraryName string 38 | switch runtime.GOOS { 39 | case "darwin": 40 | libraryName = fmt.Sprintf("%s.dylib", libName) 41 | case "linux": 42 | libraryName = fmt.Sprintf("%s.so", libName) 43 | default: 44 | return 0, fmt.Errorf("GOOS=%s is not supported", runtime.GOOS) 45 | } 46 | 47 | libPath = os.Getenv("LD_LIBRARY_PATH") 48 | paths := strings.Split(libPath, ":") 49 | cwd, err := os.Getwd() 50 | if err != nil { 51 | return 0, err 52 | } 53 | paths = append(paths, cwd) 54 | 55 | for _, path := range paths { 56 | libPath := filepath.Join(path, libraryName) 57 | if _, err := os.Stat(libPath); err == nil { 58 | slib, dlerr := purego.Dlopen(libPath, purego.RTLD_NOW|purego.RTLD_GLOBAL) 59 | if dlerr != nil { 60 | return 0, fmt.Errorf("failed to load library at %s: %w", libPath, dlerr) 61 | } 62 | return slib, nil 63 | } 64 | } 65 | return 0, fmt.Errorf("%s library not found in LD_LIBRARY_PATH or CWD", libName) 66 | } 67 | 68 | var libOnce sync.Once 69 | 70 | func init() { 71 | libOnce.Do(func() { 72 | libchafa, err := loadLibrary() 73 | if err != nil { 74 | panic(err) 75 | } 76 | 77 | // Canvas 78 | purego.RegisterLibFunc(&CanvasNew, libchafa, "chafa_canvas_new") 79 | purego.RegisterLibFunc(&CanvasNewSimilar, libchafa, "chafa_canvas_new_similar") 80 | purego.RegisterLibFunc(&CanvasRef, libchafa, "chafa_canvas_ref") 81 | purego.RegisterLibFunc(&CanvasUnRef, libchafa, "chafa_canvas_unref") 82 | purego.RegisterLibFunc(&CanvasPeekConfig, libchafa, "chafa_canvas_peek_config") 83 | purego.RegisterLibFunc(&CanvasSetPlacement, libchafa, "chafa_canvas_set_placement") 84 | purego.RegisterLibFunc(&CanvasDrawAllPixels, libchafa, "chafa_canvas_draw_all_pixels") 85 | purego.RegisterLibFunc(&CanvasPrint, libchafa, "chafa_canvas_print") 86 | purego.RegisterLibFunc(&CanvasPrintRows, libchafa, "chafa_canvas_print_rows") 87 | purego.RegisterLibFunc(&CanvasPrintRowsStrv, libchafa, "chafa_canvas_print_rows_strv") 88 | purego.RegisterLibFunc(&CanvasGetCharAt, libchafa, "chafa_canvas_get_char_at") 89 | purego.RegisterLibFunc(&CanvasSetCharAt, libchafa, "chafa_canvas_set_char_at") 90 | purego.RegisterLibFunc(&CanvasGetColorsAt, libchafa, "chafa_canvas_get_colors_at") 91 | purego.RegisterLibFunc(&CanvasSetColorsAt, libchafa, "chafa_canvas_set_colors_at") 92 | purego.RegisterLibFunc(&CanvasGetRawColorsAt, libchafa, "chafa_canvas_get_raw_colors_at") 93 | purego.RegisterLibFunc(&CanvasSetRawColorsAt, libchafa, "chafa_canvas_set_raw_colors_at") 94 | 95 | // Config 96 | purego.RegisterLibFunc(&CanvasConfigNew, libchafa, "chafa_canvas_config_new") 97 | purego.RegisterLibFunc(&CanvasConfigCopy, libchafa, "chafa_canvas_config_copy") 98 | purego.RegisterLibFunc(&CanvasConfigRef, libchafa, "chafa_canvas_config_ref") 99 | purego.RegisterLibFunc(&CanvasConfigUnref, libchafa, "chafa_canvas_config_unref") 100 | purego.RegisterLibFunc( 101 | &CanvasConfigGetGeometry, 102 | libchafa, 103 | "chafa_canvas_config_get_geometry", 104 | ) 105 | purego.RegisterLibFunc( 106 | &CanvasConfigSetGeometry, 107 | libchafa, 108 | "chafa_canvas_config_set_geometry", 109 | ) 110 | purego.RegisterLibFunc( 111 | &CanvasConfigGetCellGeometry, 112 | libchafa, 113 | "chafa_canvas_config_get_cell_geometry", 114 | ) 115 | purego.RegisterLibFunc( 116 | &CanvasConfigSetCellGeometry, 117 | libchafa, 118 | "chafa_canvas_config_set_cell_geometry", 119 | ) 120 | purego.RegisterLibFunc( 121 | &CanvasConfigGetPixelMode, 122 | libchafa, 123 | "chafa_canvas_config_get_pixel_mode", 124 | ) 125 | purego.RegisterLibFunc( 126 | &CanvasConfigSetPixelMode, 127 | libchafa, 128 | "chafa_canvas_config_set_pixel_mode", 129 | ) 130 | purego.RegisterLibFunc( 131 | &CanvasConfigGetCanvasMode, 132 | libchafa, 133 | "chafa_canvas_config_get_canvas_mode", 134 | ) 135 | purego.RegisterLibFunc( 136 | &CanvasConfigSetCanvasMode, 137 | libchafa, 138 | "chafa_canvas_config_set_canvas_mode", 139 | ) 140 | purego.RegisterLibFunc( 141 | &CanvasConfigGetColorExtractor, 142 | libchafa, 143 | "chafa_canvas_config_get_color_extractor", 144 | ) 145 | purego.RegisterLibFunc( 146 | &CanvasConfigSetColorExtractor, 147 | libchafa, 148 | "chafa_canvas_config_set_color_extractor", 149 | ) 150 | purego.RegisterLibFunc( 151 | &CanvasConfigGetColorSpace, 152 | libchafa, 153 | "chafa_canvas_config_get_color_space", 154 | ) 155 | purego.RegisterLibFunc( 156 | &CanvasConfigSetColorSpace, 157 | libchafa, 158 | "chafa_canvas_config_set_color_space", 159 | ) 160 | purego.RegisterLibFunc( 161 | &CanvasConfigGetPreprocessingEnabled, 162 | libchafa, 163 | "chafa_canvas_config_get_preprocessing_enabled", 164 | ) 165 | purego.RegisterLibFunc( 166 | &CanvasConfigSetPreprocessingEnabled, 167 | libchafa, 168 | "chafa_canvas_config_set_preprocessing_enabled", 169 | ) 170 | purego.RegisterLibFunc( 171 | &CanvasConfigPeekSymbolMap, 172 | libchafa, 173 | "chafa_canvas_config_peek_symbol_map", 174 | ) 175 | purego.RegisterLibFunc( 176 | &CanvasConfigSetSymbolMap, 177 | libchafa, 178 | "chafa_canvas_config_set_symbol_map", 179 | ) 180 | purego.RegisterLibFunc( 181 | &CanvasConfigPeekFillSymbolMap, 182 | libchafa, 183 | "chafa_canvas_config_peek_fill_symbol_map", 184 | ) 185 | purego.RegisterLibFunc( 186 | &CanvasConfigGetTransparencyThreshold, 187 | libchafa, 188 | "chafa_canvas_config_get_transparency_threshold", 189 | ) 190 | purego.RegisterLibFunc( 191 | &CanvasConfigSetTransparencyThreshold, 192 | libchafa, 193 | "chafa_canvas_config_set_transparency_threshold", 194 | ) 195 | purego.RegisterLibFunc( 196 | &CanvasConfigGetFgOnlyEnabled, 197 | libchafa, 198 | "chafa_canvas_config_get_fg_only_enabled", 199 | ) 200 | purego.RegisterLibFunc( 201 | &CanvasConfigSetFgOnlyEnabled, 202 | libchafa, 203 | "chafa_canvas_config_set_fg_only_enabled", 204 | ) 205 | purego.RegisterLibFunc( 206 | &CanvasConfigGetFgColor, 207 | libchafa, 208 | "chafa_canvas_config_get_fg_color", 209 | ) 210 | purego.RegisterLibFunc( 211 | &CanvasConfigSetFgColor, 212 | libchafa, 213 | "chafa_canvas_config_set_fg_color", 214 | ) 215 | purego.RegisterLibFunc( 216 | &CanvasConfigGetBgColor, 217 | libchafa, 218 | "chafa_canvas_config_get_bg_color", 219 | ) 220 | purego.RegisterLibFunc( 221 | &CanvasConfigSetBgColor, 222 | libchafa, 223 | "chafa_canvas_config_set_bg_color", 224 | ) 225 | purego.RegisterLibFunc( 226 | &CanvasConfigGetWorkFactor, 227 | libchafa, 228 | "chafa_canvas_config_get_work_factor", 229 | ) 230 | purego.RegisterLibFunc( 231 | &CanvasConfigSetWorkFactor, 232 | libchafa, 233 | "chafa_canvas_config_set_work_factor", 234 | ) 235 | purego.RegisterLibFunc( 236 | &CanvasConfigGetDitherMode, 237 | libchafa, 238 | "chafa_canvas_config_get_dither_mode", 239 | ) 240 | purego.RegisterLibFunc( 241 | &CanvasConfigSetDitherMode, 242 | libchafa, 243 | "chafa_canvas_config_set_dither_mode", 244 | ) 245 | purego.RegisterLibFunc( 246 | &CanvasConfigGetDitherGrainSize, 247 | libchafa, 248 | "chafa_canvas_config_get_dither_grain_size", 249 | ) 250 | purego.RegisterLibFunc( 251 | &CanvasConfigSetDitherGrainSize, 252 | libchafa, 253 | "chafa_canvas_config_set_dither_grain_size", 254 | ) 255 | purego.RegisterLibFunc( 256 | &CanvasConfigGetDitherIntensity, 257 | libchafa, 258 | "chafa_canvas_config_get_dither_intensity", 259 | ) 260 | purego.RegisterLibFunc( 261 | &CanvasConfigSetDitherIntensity, 262 | libchafa, 263 | "chafa_canvas_config_set_dither_intensity", 264 | ) 265 | purego.RegisterLibFunc( 266 | &CanvasConfigGetOptimizations, 267 | libchafa, 268 | "chafa_canvas_config_get_optimizations", 269 | ) 270 | purego.RegisterLibFunc( 271 | &CanvasConfigSetOptimizations, 272 | libchafa, 273 | "chafa_canvas_config_set_optimizations", 274 | ) 275 | purego.RegisterLibFunc( 276 | &CanvasConfigGetPassthrough, 277 | libchafa, 278 | "chafa_canvas_config_get_passthrough", 279 | ) 280 | purego.RegisterLibFunc( 281 | &CanvasConfigSetPassthrough, 282 | libchafa, 283 | "chafa_canvas_config_set_passthrough", 284 | ) 285 | 286 | // Placement 287 | purego.RegisterLibFunc(&PlacementNew, libchafa, "chafa_placement_new") 288 | purego.RegisterLibFunc(&PlacementRef, libchafa, "chafa_placement_ref") 289 | purego.RegisterLibFunc(&PlacementUnref, libchafa, "chafa_placement_unref") 290 | purego.RegisterLibFunc(&PlacementGetTuck, libchafa, "chafa_placement_get_tuck") 291 | purego.RegisterLibFunc(&PlacementSetTuck, libchafa, "chafa_placement_set_tuck") 292 | purego.RegisterLibFunc(&PlacementGetHAlign, libchafa, "chafa_placement_get_halign") 293 | purego.RegisterLibFunc(&PlacementSetHAlign, libchafa, "chafa_placement_set_halign") 294 | purego.RegisterLibFunc(&PlacementGetVAlign, libchafa, "chafa_placement_get_valign") 295 | purego.RegisterLibFunc(&PlacementSetVAlign, libchafa, "chafa_placement_set_valign") 296 | 297 | // Image 298 | purego.RegisterLibFunc(&ImageNew, libchafa, "chafa_image_new") 299 | purego.RegisterLibFunc(&ImageRef, libchafa, "chafa_image_ref") 300 | purego.RegisterLibFunc(&ImageUnref, libchafa, "chafa_image_unref") 301 | purego.RegisterLibFunc(&ImageSetFrame, libchafa, "chafa_image_set_frame") 302 | 303 | // Frame 304 | purego.RegisterLibFunc(&FrameNew, libchafa, "chafa_frame_new") 305 | purego.RegisterLibFunc(&FrameNewBorrow, libchafa, "chafa_frame_new_borrow") 306 | purego.RegisterLibFunc(&FrameNewSteal, libchafa, "chafa_frame_new_steal") 307 | purego.RegisterLibFunc(&FrameRef, libchafa, "chafa_frame_ref") 308 | purego.RegisterLibFunc(&FrameUnref, libchafa, "chafa_frame_unref") 309 | 310 | // SymbolMap 311 | purego.RegisterLibFunc(&SymbolMapNew, libchafa, "chafa_symbol_map_new") 312 | purego.RegisterLibFunc(&SymbolMapCopy, libchafa, "chafa_symbol_map_copy") 313 | purego.RegisterLibFunc(&SymbolMapRef, libchafa, "chafa_symbol_map_ref") 314 | purego.RegisterLibFunc(&SymbolMapUnref, libchafa, "chafa_symbol_map_unref") 315 | purego.RegisterLibFunc(&SymbolMapAddByTags, libchafa, "chafa_symbol_map_add_by_tags") 316 | purego.RegisterLibFunc(&SymbolMapAddByRange, libchafa, "chafa_symbol_map_add_by_range") 317 | purego.RegisterLibFunc(&SymbolMapRemoveByTags, libchafa, "chafa_symbol_map_remove_by_tags") 318 | purego.RegisterLibFunc( 319 | &SymbolMapRemoveByRange, 320 | libchafa, 321 | "chafa_symbol_map_remove_by_range", 322 | ) 323 | purego.RegisterLibFunc( 324 | &SymbolMapApplySelectors, 325 | libchafa, 326 | "chafa_symbol_map_apply_selectors", 327 | ) 328 | purego.RegisterLibFunc( 329 | &SymbolMapGetAllowBuiltinGlyphs, 330 | libchafa, 331 | "chafa_symbol_map_get_allow_builtin_glyphs", 332 | ) 333 | purego.RegisterLibFunc( 334 | &SymbolMapSetAllowBuiltinGlyphs, 335 | libchafa, 336 | "chafa_symbol_map_set_allow_builtin_glyphs", 337 | ) 338 | purego.RegisterLibFunc(&SymbolMapGetGlyph, libchafa, "chafa_symbol_map_get_glyph") 339 | purego.RegisterLibFunc(&SymbolMapAddGlyph, libchafa, "chafa_symbol_map_add_glyph") 340 | 341 | // TermDb 342 | purego.RegisterLibFunc(&TermDbNew, libchafa, "chafa_term_db_new") 343 | purego.RegisterLibFunc(&TermDbCopy, libchafa, "chafa_term_db_copy") 344 | purego.RegisterLibFunc(&TermDbRef, libchafa, "chafa_term_db_ref") 345 | purego.RegisterLibFunc(&TermDbUnref, libchafa, "chafa_term_db_unref") 346 | purego.RegisterLibFunc(&TermDbGetDefault, libchafa, "chafa_term_db_get_default") 347 | purego.RegisterLibFunc(&termDbDetect, libchafa, "chafa_term_db_detect") 348 | purego.RegisterLibFunc(&TermDbGetFallbackInfo, libchafa, "chafa_term_db_get_fallback_info") 349 | 350 | // TermInfo 351 | purego.RegisterLibFunc(&TermInfoNew, libchafa, "chafa_term_info_new") 352 | purego.RegisterLibFunc(&TermInfoCopy, libchafa, "chafa_term_info_copy") 353 | purego.RegisterLibFunc(&TermInfoRef, libchafa, "chafa_term_info_ref") 354 | purego.RegisterLibFunc(&TermInfoUnref, libchafa, "chafa_term_info_unref") 355 | purego.RegisterLibFunc(&TermInfoChain, libchafa, "chafa_term_info_chain") 356 | purego.RegisterLibFunc(&TermInfoSupplement, libchafa, "chafa_term_info_supplement") 357 | purego.RegisterLibFunc(&TermInfoGetName, libchafa, "chafa_term_info_get_name") 358 | purego.RegisterLibFunc(&TermInfoSetName, libchafa, "chafa_term_info_set_name") 359 | purego.RegisterLibFunc(&TermInfoGetQuirks, libchafa, "chafa_term_info_get_quirks") 360 | purego.RegisterLibFunc(&TermInfoSetQuirks, libchafa, "chafa_term_info_set_quirks") 361 | purego.RegisterLibFunc( 362 | &TermInfoGetSafeSymbolTags, 363 | libchafa, 364 | "chafa_term_info_get_safe_symbol_tags", 365 | ) 366 | purego.RegisterLibFunc( 367 | &TermInfoSetSafeSymbolTags, 368 | libchafa, 369 | "chafa_term_info_set_safe_symbol_tags", 370 | ) 371 | purego.RegisterLibFunc(&TermInfoGetSeq, libchafa, "chafa_term_info_get_seq") 372 | purego.RegisterLibFunc(&TermInfoSetSeq, libchafa, "chafa_term_info_set_seq") 373 | purego.RegisterLibFunc(&TermInfoHaveSeq, libchafa, "chafa_term_info_have_seq") 374 | purego.RegisterLibFunc(&TermInfoGetInheritSeq, libchafa, "chafa_term_info_get_inherit_seq") 375 | purego.RegisterLibFunc(&TermInfoSetInheritSeq, libchafa, "chafa_term_info_set_inherit_seq") 376 | purego.RegisterLibFunc(&TermInfoEmitSeq, libchafa, "chafa_term_info_emit_seq") 377 | purego.RegisterLibFunc(&TermInfoEmitSeqValist, libchafa, "chafa_term_info_emit_seq_valist") 378 | purego.RegisterLibFunc(&TermInfoParseSeq, libchafa, "chafa_term_info_parse_seq") 379 | purego.RegisterLibFunc( 380 | &TermInfoParseSeqVarargs, 381 | libchafa, 382 | "chafa_term_info_parse_seq_varargs", 383 | ) 384 | purego.RegisterLibFunc( 385 | &TermInfoIsCanvasModeSupported, 386 | libchafa, 387 | "chafa_term_info_is_canvas_mode_supported", 388 | ) 389 | purego.RegisterLibFunc( 390 | &TermInfoGetBestCanvasMode, 391 | libchafa, 392 | "chafa_term_info_get_best_canvas_mode", 393 | ) 394 | purego.RegisterLibFunc( 395 | &TermInfoIsPixelModeSupported, 396 | libchafa, 397 | "chafa_term_info_is_pixel_mode_supported", 398 | ) 399 | purego.RegisterLibFunc( 400 | &TermInfoGetBestPixelMode, 401 | libchafa, 402 | "chafa_term_info_get_best_pixel_mode", 403 | ) 404 | purego.RegisterLibFunc( 405 | &TermInfoGetIsPixelPassthroughNeeded, 406 | libchafa, 407 | "chafa_term_info_get_is_pixel_passthrough_needed", 408 | ) 409 | purego.RegisterLibFunc( 410 | &TermInfoSetIsPixelPassthroughNeeded, 411 | libchafa, 412 | "chafa_term_info_set_is_pixel_passthrough_needed", 413 | ) 414 | purego.RegisterLibFunc( 415 | &TermInfoGetPassthroughType, 416 | libchafa, 417 | "chafa_term_info_get_passthrough_type", 418 | ) 419 | purego.RegisterLibFunc( 420 | &TermInfoEmitResetTerminalSoft, 421 | libchafa, 422 | "chafa_term_info_emit_reset_terminal_soft", 423 | ) 424 | purego.RegisterLibFunc( 425 | &TermInfoEmitResetTerminalHard, 426 | libchafa, 427 | "chafa_term_info_emit_reset_terminal_hard", 428 | ) 429 | purego.RegisterLibFunc( 430 | &TermInfoEmitResetAttributes, 431 | libchafa, 432 | "chafa_term_info_emit_reset_attributes", 433 | ) 434 | purego.RegisterLibFunc(&TermInfoEmitClear, libchafa, "chafa_term_info_emit_clear") 435 | purego.RegisterLibFunc( 436 | &TermInfoEmitCursorToPos, 437 | libchafa, 438 | "chafa_term_info_emit_cursor_to_pos", 439 | ) 440 | purego.RegisterLibFunc( 441 | &TermInfoEmitCursorToTopLeft, 442 | libchafa, 443 | "chafa_term_info_emit_cursor_to_top_left", 444 | ) 445 | purego.RegisterLibFunc( 446 | &TermInfoEmitCursorToBottomLeft, 447 | libchafa, 448 | "chafa_term_info_emit_cursor_to_bottom_left", 449 | ) 450 | purego.RegisterLibFunc(&TermInfoEmitCursorUp, libchafa, "chafa_term_info_emit_cursor_up") 451 | purego.RegisterLibFunc( 452 | &TermInfoEmitCursorDown, 453 | libchafa, 454 | "chafa_term_info_emit_cursor_down", 455 | ) 456 | purego.RegisterLibFunc( 457 | &TermInfoEmitCursorLeft, 458 | libchafa, 459 | "chafa_term_info_emit_cursor_left", 460 | ) 461 | purego.RegisterLibFunc( 462 | &TermInfoEmitCursorRight, 463 | libchafa, 464 | "chafa_term_info_emit_cursor_right", 465 | ) 466 | purego.RegisterLibFunc(&TermInfoEmitCursorUp1, libchafa, "chafa_term_info_emit_cursor_up_1") 467 | purego.RegisterLibFunc( 468 | &TermInfoEmitCursorDown1, 469 | libchafa, 470 | "chafa_term_info_emit_cursor_down_1", 471 | ) 472 | purego.RegisterLibFunc( 473 | &TermInfoEmitCursorLeft1, 474 | libchafa, 475 | "chafa_term_info_emit_cursor_left_1", 476 | ) 477 | purego.RegisterLibFunc( 478 | &TermInfoEmitCursorRight1, 479 | libchafa, 480 | "chafa_term_info_emit_cursor_right_1", 481 | ) 482 | purego.RegisterLibFunc( 483 | &TermInfoEmitCursorUpScroll, 484 | libchafa, 485 | "chafa_term_info_emit_cursor_up_scroll", 486 | ) 487 | purego.RegisterLibFunc( 488 | &TermInfoEmitCursorDownScroll, 489 | libchafa, 490 | "chafa_term_info_emit_cursor_down_scroll", 491 | ) 492 | purego.RegisterLibFunc( 493 | &TermInfoEmitInsertCells, 494 | libchafa, 495 | "chafa_term_info_emit_insert_cells", 496 | ) 497 | purego.RegisterLibFunc( 498 | &TermInfoEmitDeleteCells, 499 | libchafa, 500 | "chafa_term_info_emit_delete_cells", 501 | ) 502 | purego.RegisterLibFunc( 503 | &TermInfoEmitInsertRows, 504 | libchafa, 505 | "chafa_term_info_emit_insert_rows", 506 | ) 507 | purego.RegisterLibFunc( 508 | &TermInfoEmitDeleteRows, 509 | libchafa, 510 | "chafa_term_info_emit_delete_rows", 511 | ) 512 | purego.RegisterLibFunc( 513 | &TermInfoEmitEnableCursor, 514 | libchafa, 515 | "chafa_term_info_emit_enable_cursor", 516 | ) 517 | purego.RegisterLibFunc( 518 | &TermInfoEmitDisableCursor, 519 | libchafa, 520 | "chafa_term_info_emit_disable_cursor", 521 | ) 522 | purego.RegisterLibFunc( 523 | &TermInfoEmitEnableEcho, 524 | libchafa, 525 | "chafa_term_info_emit_enable_echo", 526 | ) 527 | purego.RegisterLibFunc( 528 | &TermInfoEmitDisableEcho, 529 | libchafa, 530 | "chafa_term_info_emit_disable_echo", 531 | ) 532 | purego.RegisterLibFunc( 533 | &TermInfoEmitEnableInsert, 534 | libchafa, 535 | "chafa_term_info_emit_enable_insert", 536 | ) 537 | purego.RegisterLibFunc( 538 | &TermInfoEmitDisableInsert, 539 | libchafa, 540 | "chafa_term_info_emit_disable_insert", 541 | ) 542 | purego.RegisterLibFunc( 543 | &TermInfoEmitEnableWrap, 544 | libchafa, 545 | "chafa_term_info_emit_enable_wrap", 546 | ) 547 | purego.RegisterLibFunc( 548 | &TermInfoEmitDisableWrap, 549 | libchafa, 550 | "chafa_term_info_emit_disable_wrap", 551 | ) 552 | purego.RegisterLibFunc( 553 | &TermInfoEmitEnableBold, 554 | libchafa, 555 | "chafa_term_info_emit_enable_bold", 556 | ) 557 | purego.RegisterLibFunc( 558 | &TermInfoEmitInvertColors, 559 | libchafa, 560 | "chafa_term_info_emit_invert_colors", 561 | ) 562 | purego.RegisterLibFunc( 563 | &TermInfoEmitSetColorBg8, 564 | libchafa, 565 | "chafa_term_info_emit_set_color_bg_8", 566 | ) 567 | purego.RegisterLibFunc( 568 | &TermInfoEmitSetColorFg8, 569 | libchafa, 570 | "chafa_term_info_emit_set_color_fg_8", 571 | ) 572 | purego.RegisterLibFunc( 573 | &TermInfoEmitSetColorFgbg8, 574 | libchafa, 575 | "chafa_term_info_emit_set_color_fgbg_8", 576 | ) 577 | purego.RegisterLibFunc( 578 | &TermInfoEmitSetColorFg16, 579 | libchafa, 580 | "chafa_term_info_emit_set_color_fg_16", 581 | ) 582 | purego.RegisterLibFunc( 583 | &TermInfoEmitSetColorBg16, 584 | libchafa, 585 | "chafa_term_info_emit_set_color_bg_16", 586 | ) 587 | purego.RegisterLibFunc( 588 | &TermInfoEmitSetColorFgbg16, 589 | libchafa, 590 | "chafa_term_info_emit_set_color_fgbg_16", 591 | ) 592 | purego.RegisterLibFunc( 593 | &TermInfoEmitSetColorFg256, 594 | libchafa, 595 | "chafa_term_info_emit_set_color_fg_256", 596 | ) 597 | purego.RegisterLibFunc( 598 | &TermInfoEmitSetColorBg256, 599 | libchafa, 600 | "chafa_term_info_emit_set_color_bg_256", 601 | ) 602 | purego.RegisterLibFunc( 603 | &TermInfoEmitSetColorFgbg256, 604 | libchafa, 605 | "chafa_term_info_emit_set_color_fgbg_256", 606 | ) 607 | purego.RegisterLibFunc( 608 | &TermInfoEmitSetColorFgDirect, 609 | libchafa, 610 | "chafa_term_info_emit_set_color_fg_direct", 611 | ) 612 | purego.RegisterLibFunc( 613 | &TermInfoEmitSetColorBgDirect, 614 | libchafa, 615 | "chafa_term_info_emit_set_color_bg_direct", 616 | ) 617 | purego.RegisterLibFunc( 618 | &TermInfoEmitSetColorFgbgDirect, 619 | libchafa, 620 | "chafa_term_info_emit_set_color_fgbg_direct", 621 | ) 622 | purego.RegisterLibFunc( 623 | &TermInfoEmitResetColorFg, 624 | libchafa, 625 | "chafa_term_info_emit_reset_color_fg", 626 | ) 627 | purego.RegisterLibFunc( 628 | &TermInfoEmitResetColorBg, 629 | libchafa, 630 | "chafa_term_info_emit_reset_color_bg", 631 | ) 632 | purego.RegisterLibFunc( 633 | &TermInfoEmitResetColorFgbg, 634 | libchafa, 635 | "chafa_term_info_emit_reset_color_fgbg", 636 | ) 637 | purego.RegisterLibFunc( 638 | &TermInfoEmitSetDefaultFg, 639 | libchafa, 640 | "chafa_term_info_emit_set_default_fg", 641 | ) 642 | purego.RegisterLibFunc( 643 | &TermInfoEmitSetDefaultBg, 644 | libchafa, 645 | "chafa_term_info_emit_set_default_bg", 646 | ) 647 | purego.RegisterLibFunc( 648 | &TermInfoEmitResetDefaultFg, 649 | libchafa, 650 | "chafa_term_info_emit_reset_default_fg", 651 | ) 652 | purego.RegisterLibFunc( 653 | &TermInfoEmitResetDefaultBg, 654 | libchafa, 655 | "chafa_term_info_emit_reset_default_bg", 656 | ) 657 | purego.RegisterLibFunc( 658 | &TermInfoEmitQueryDefaultFg, 659 | libchafa, 660 | "chafa_term_info_emit_query_default_fg", 661 | ) 662 | purego.RegisterLibFunc( 663 | &TermInfoEmitQueryDefaultBg, 664 | libchafa, 665 | "chafa_term_info_emit_query_default_bg", 666 | ) 667 | purego.RegisterLibFunc( 668 | &TermInfoEmitQueryPrimaryDeviceAttributes, 669 | libchafa, 670 | "chafa_term_info_emit_query_primary_device_attributes", 671 | ) 672 | purego.RegisterLibFunc( 673 | &TermInfoEmitPrimaryDeviceAttributes, 674 | libchafa, 675 | "chafa_term_info_emit_primary_device_attributes", 676 | ) 677 | purego.RegisterLibFunc( 678 | &TermInfoEmitQueryCellSizePx, 679 | libchafa, 680 | "chafa_term_info_emit_query_cell_size_px", 681 | ) 682 | purego.RegisterLibFunc( 683 | &TermInfoEmitCellSizePx, 684 | libchafa, 685 | "chafa_term_info_emit_cell_size_px", 686 | ) 687 | purego.RegisterLibFunc( 688 | &TermInfoEmitQueryTextAreaSizeCells, 689 | libchafa, 690 | "chafa_term_info_emit_query_text_area_size_cells", 691 | ) 692 | purego.RegisterLibFunc( 693 | &TermInfoEmitTextAreaSizeCells, 694 | libchafa, 695 | "chafa_term_info_emit_text_area_size_cells", 696 | ) 697 | purego.RegisterLibFunc( 698 | &TermInfoEmitQueryTextAreaSizePx, 699 | libchafa, 700 | "chafa_term_info_emit_query_text_area_size_px", 701 | ) 702 | purego.RegisterLibFunc( 703 | &TermInfoEmitTextAreaSizePx, 704 | libchafa, 705 | "chafa_term_info_emit_text_area_size_px", 706 | ) 707 | purego.RegisterLibFunc( 708 | &TermInfoEmitRepeatChar, 709 | libchafa, 710 | "chafa_term_info_emit_repeat_char", 711 | ) 712 | purego.RegisterLibFunc( 713 | &TermInfoEmitSetScrollingRows, 714 | libchafa, 715 | "chafa_term_info_emit_set_scrolling_rows", 716 | ) 717 | purego.RegisterLibFunc( 718 | &TermInfoEmitResetScrollingRows, 719 | libchafa, 720 | "chafa_term_info_emit_reset_scrolling_rows", 721 | ) 722 | purego.RegisterLibFunc( 723 | &TermInfoEmitSaveCursorPos, 724 | libchafa, 725 | "chafa_term_info_emit_save_cursor_pos", 726 | ) 727 | purego.RegisterLibFunc( 728 | &TermInfoEmitRestoreCursorPos, 729 | libchafa, 730 | "chafa_term_info_emit_restore_cursor_pos", 731 | ) 732 | purego.RegisterLibFunc( 733 | &TermInfoEmitBeginSixels, 734 | libchafa, 735 | "chafa_term_info_emit_begin_sixels", 736 | ) 737 | purego.RegisterLibFunc(&TermInfoEmitEndSixels, libchafa, "chafa_term_info_emit_end_sixels") 738 | purego.RegisterLibFunc( 739 | &TermInfoEmitEnableSixelScrolling, 740 | libchafa, 741 | "chafa_term_info_emit_enable_sixel_scrolling", 742 | ) 743 | purego.RegisterLibFunc( 744 | &TermInfoEmitDisableSixelScrolling, 745 | libchafa, 746 | "chafa_term_info_emit_disable_sixel_scrolling", 747 | ) 748 | purego.RegisterLibFunc( 749 | &TermInfoEmitSetSixelAdvanceDown, 750 | libchafa, 751 | "chafa_term_info_emit_set_sixel_advance_down", 752 | ) 753 | purego.RegisterLibFunc( 754 | &TermInfoEmitSetSixelAdvanceRight, 755 | libchafa, 756 | "chafa_term_info_emit_set_sixel_advance_right", 757 | ) 758 | purego.RegisterLibFunc( 759 | &TermInfoEmitBeginKittyImmediateImageV1, 760 | libchafa, 761 | "chafa_term_info_emit_begin_kitty_immediate_image_v1", 762 | ) 763 | purego.RegisterLibFunc( 764 | &TermInfoEmitBeginKittyImmediateVirtImageV1, 765 | libchafa, 766 | "chafa_term_info_emit_begin_kitty_immediate_virt_image_v1", 767 | ) 768 | purego.RegisterLibFunc( 769 | &TermInfoEmitEndKittyImage, 770 | libchafa, 771 | "chafa_term_info_emit_end_kitty_image", 772 | ) 773 | purego.RegisterLibFunc( 774 | &TermInfoEmitBeginKittyImageChunk, 775 | libchafa, 776 | "chafa_term_info_emit_begin_kitty_image_chunk", 777 | ) 778 | purego.RegisterLibFunc( 779 | &TermInfoEmitEndKittyImageChunk, 780 | libchafa, 781 | "chafa_term_info_emit_end_kitty_image_chunk", 782 | ) 783 | purego.RegisterLibFunc( 784 | &TermInfoEmitBeginIterm2Image, 785 | libchafa, 786 | "chafa_term_info_emit_begin_iterm2_image", 787 | ) 788 | purego.RegisterLibFunc( 789 | &TermInfoEmitEndIterm2Image, 790 | libchafa, 791 | "chafa_term_info_emit_end_iterm2_image", 792 | ) 793 | purego.RegisterLibFunc( 794 | &TermInfoEmitBeginScreenPassthrough, 795 | libchafa, 796 | "chafa_term_info_emit_begin_screen_passthrough", 797 | ) 798 | purego.RegisterLibFunc( 799 | &TermInfoEmitEndScreenPassthrough, 800 | libchafa, 801 | "chafa_term_info_emit_end_screen_passthrough", 802 | ) 803 | purego.RegisterLibFunc( 804 | &TermInfoEmitEnableAltScreen, 805 | libchafa, 806 | "chafa_term_info_emit_enable_alt_screen", 807 | ) 808 | purego.RegisterLibFunc( 809 | &TermInfoEmitDisableAltScreen, 810 | libchafa, 811 | "chafa_term_info_emit_disable_alt_screen", 812 | ) 813 | purego.RegisterLibFunc( 814 | &TermInfoEmitBeginTmuxPassthrough, 815 | libchafa, 816 | "chafa_term_info_emit_begin_tmux_passthrough", 817 | ) 818 | purego.RegisterLibFunc( 819 | &TermInfoEmitEndTmuxPassthrough, 820 | libchafa, 821 | "chafa_term_info_emit_end_tmux_passthrough", 822 | ) 823 | purego.RegisterLibFunc(&TermInfoEmitReturnKey, libchafa, "chafa_term_info_emit_return_key") 824 | purego.RegisterLibFunc( 825 | &TermInfoEmitBackspaceKey, 826 | libchafa, 827 | "chafa_term_info_emit_backspace_key", 828 | ) 829 | purego.RegisterLibFunc(&TermInfoEmitDeleteKey, libchafa, "chafa_term_info_emit_delete_key") 830 | purego.RegisterLibFunc( 831 | &TermInfoEmitDeleteCtrlKey, 832 | libchafa, 833 | "chafa_term_info_emit_delete_ctrl_key", 834 | ) 835 | purego.RegisterLibFunc( 836 | &TermInfoEmitDeleteShiftKey, 837 | libchafa, 838 | "chafa_term_info_emit_delete_shift_key", 839 | ) 840 | purego.RegisterLibFunc(&TermInfoEmitInsertKey, libchafa, "chafa_term_info_emit_insert_key") 841 | purego.RegisterLibFunc( 842 | &TermInfoEmitInsertCtrlKey, 843 | libchafa, 844 | "chafa_term_info_emit_insert_ctrl_key", 845 | ) 846 | purego.RegisterLibFunc( 847 | &TermInfoEmitInsertShiftKey, 848 | libchafa, 849 | "chafa_term_info_emit_insert_shift_key", 850 | ) 851 | purego.RegisterLibFunc(&TermInfoEmitHomeKey, libchafa, "chafa_term_info_emit_home_key") 852 | purego.RegisterLibFunc( 853 | &TermInfoEmitHomeCtrlKey, 854 | libchafa, 855 | "chafa_term_info_emit_home_ctrl_key", 856 | ) 857 | purego.RegisterLibFunc( 858 | &TermInfoEmitHomeShiftKey, 859 | libchafa, 860 | "chafa_term_info_emit_home_shift_key", 861 | ) 862 | purego.RegisterLibFunc(&TermInfoEmitEndKey, libchafa, "chafa_term_info_emit_end_key") 863 | purego.RegisterLibFunc( 864 | &TermInfoEmitEndCtrlKey, 865 | libchafa, 866 | "chafa_term_info_emit_end_ctrl_key", 867 | ) 868 | purego.RegisterLibFunc( 869 | &TermInfoEmitEndShiftKey, 870 | libchafa, 871 | "chafa_term_info_emit_end_shift_key", 872 | ) 873 | purego.RegisterLibFunc(&TermInfoEmitUpKey, libchafa, "chafa_term_info_emit_up_key") 874 | purego.RegisterLibFunc(&TermInfoEmitUpCtrlKey, libchafa, "chafa_term_info_emit_up_ctrl_key") 875 | purego.RegisterLibFunc( 876 | &TermInfoEmitUpShiftKey, 877 | libchafa, 878 | "chafa_term_info_emit_up_shift_key", 879 | ) 880 | purego.RegisterLibFunc(&TermInfoEmitDownKey, libchafa, "chafa_term_info_emit_down_key") 881 | purego.RegisterLibFunc( 882 | &TermInfoEmitDownCtrlKey, 883 | libchafa, 884 | "chafa_term_info_emit_down_ctrl_key", 885 | ) 886 | purego.RegisterLibFunc( 887 | &TermInfoEmitDownShiftKey, 888 | libchafa, 889 | "chafa_term_info_emit_down_shift_key", 890 | ) 891 | purego.RegisterLibFunc(&TermInfoEmitLeftKey, libchafa, "chafa_term_info_emit_left_key") 892 | purego.RegisterLibFunc( 893 | &TermInfoEmitLeftCtrlKey, 894 | libchafa, 895 | "chafa_term_info_emit_left_ctrl_key", 896 | ) 897 | purego.RegisterLibFunc( 898 | &TermInfoEmitLeftShiftKey, 899 | libchafa, 900 | "chafa_term_info_emit_left_shift_key", 901 | ) 902 | purego.RegisterLibFunc(&TermInfoEmitRightKey, libchafa, "chafa_term_info_emit_right_key") 903 | purego.RegisterLibFunc( 904 | &TermInfoEmitRightCtrlKey, 905 | libchafa, 906 | "chafa_term_info_emit_right_ctrl_key", 907 | ) 908 | purego.RegisterLibFunc( 909 | &TermInfoEmitRightShiftKey, 910 | libchafa, 911 | "chafa_term_info_emit_right_shift_key", 912 | ) 913 | purego.RegisterLibFunc(&TermInfoEmitPageUpKey, libchafa, "chafa_term_info_emit_page_up_key") 914 | purego.RegisterLibFunc( 915 | &TermInfoEmitPageUpCtrlKey, 916 | libchafa, 917 | "chafa_term_info_emit_page_up_ctrl_key", 918 | ) 919 | purego.RegisterLibFunc( 920 | &TermInfoEmitPageUpShiftKey, 921 | libchafa, 922 | "chafa_term_info_emit_page_up_shift_key", 923 | ) 924 | purego.RegisterLibFunc( 925 | &TermInfoEmitPageDownKey, 926 | libchafa, 927 | "chafa_term_info_emit_page_down_key", 928 | ) 929 | purego.RegisterLibFunc( 930 | &TermInfoEmitPageDownCtrlKey, 931 | libchafa, 932 | "chafa_term_info_emit_page_down_ctrl_key", 933 | ) 934 | purego.RegisterLibFunc( 935 | &TermInfoEmitPageDownShiftKey, 936 | libchafa, 937 | "chafa_term_info_emit_page_down_shift_key", 938 | ) 939 | purego.RegisterLibFunc(&TermInfoEmitTabKey, libchafa, "chafa_term_info_emit_tab_key") 940 | purego.RegisterLibFunc( 941 | &TermInfoEmitTabShiftKey, 942 | libchafa, 943 | "chafa_term_info_emit_tab_shift_key", 944 | ) 945 | purego.RegisterLibFunc(&TermInfoEmitF1Key, libchafa, "chafa_term_info_emit_f1_key") 946 | purego.RegisterLibFunc(&TermInfoEmitF1CtrlKey, libchafa, "chafa_term_info_emit_f1_ctrl_key") 947 | purego.RegisterLibFunc( 948 | &TermInfoEmitF1ShiftKey, 949 | libchafa, 950 | "chafa_term_info_emit_f1_shift_key", 951 | ) 952 | purego.RegisterLibFunc(&TermInfoEmitF2Key, libchafa, "chafa_term_info_emit_f2_key") 953 | purego.RegisterLibFunc(&TermInfoEmitF2CtrlKey, libchafa, "chafa_term_info_emit_f2_ctrl_key") 954 | purego.RegisterLibFunc( 955 | &TermInfoEmitF2ShiftKey, 956 | libchafa, 957 | "chafa_term_info_emit_f2_shift_key", 958 | ) 959 | purego.RegisterLibFunc(&TermInfoEmitF3Key, libchafa, "chafa_term_info_emit_f3_key") 960 | purego.RegisterLibFunc(&TermInfoEmitF3CtrlKey, libchafa, "chafa_term_info_emit_f3_ctrl_key") 961 | purego.RegisterLibFunc( 962 | &TermInfoEmitF3ShiftKey, 963 | libchafa, 964 | "chafa_term_info_emit_f3_shift_key", 965 | ) 966 | purego.RegisterLibFunc(&TermInfoEmitF4Key, libchafa, "chafa_term_info_emit_f4_key") 967 | purego.RegisterLibFunc(&TermInfoEmitF4CtrlKey, libchafa, "chafa_term_info_emit_f4_ctrl_key") 968 | purego.RegisterLibFunc( 969 | &TermInfoEmitF4ShiftKey, 970 | libchafa, 971 | "chafa_term_info_emit_f4_shift_key", 972 | ) 973 | purego.RegisterLibFunc(&TermInfoEmitF5Key, libchafa, "chafa_term_info_emit_f5_key") 974 | purego.RegisterLibFunc(&TermInfoEmitF5CtrlKey, libchafa, "chafa_term_info_emit_f5_ctrl_key") 975 | purego.RegisterLibFunc( 976 | &TermInfoEmitF5ShiftKey, 977 | libchafa, 978 | "chafa_term_info_emit_f5_shift_key", 979 | ) 980 | purego.RegisterLibFunc(&TermInfoEmitF6Key, libchafa, "chafa_term_info_emit_f6_key") 981 | purego.RegisterLibFunc(&TermInfoEmitF6CtrlKey, libchafa, "chafa_term_info_emit_f6_ctrl_key") 982 | purego.RegisterLibFunc( 983 | &TermInfoEmitF6ShiftKey, 984 | libchafa, 985 | "chafa_term_info_emit_f6_shift_key", 986 | ) 987 | purego.RegisterLibFunc(&TermInfoEmitF7Key, libchafa, "chafa_term_info_emit_f7_key") 988 | purego.RegisterLibFunc(&TermInfoEmitF7CtrlKey, libchafa, "chafa_term_info_emit_f7_ctrl_key") 989 | purego.RegisterLibFunc( 990 | &TermInfoEmitF7ShiftKey, 991 | libchafa, 992 | "chafa_term_info_emit_f7_shift_key", 993 | ) 994 | purego.RegisterLibFunc(&TermInfoEmitF8Key, libchafa, "chafa_term_info_emit_f8_key") 995 | purego.RegisterLibFunc(&TermInfoEmitF8CtrlKey, libchafa, "chafa_term_info_emit_f8_ctrl_key") 996 | purego.RegisterLibFunc( 997 | &TermInfoEmitF8ShiftKey, 998 | libchafa, 999 | "chafa_term_info_emit_f8_shift_key", 1000 | ) 1001 | purego.RegisterLibFunc(&TermInfoEmitF9Key, libchafa, "chafa_term_info_emit_f9_key") 1002 | purego.RegisterLibFunc(&TermInfoEmitF9CtrlKey, libchafa, "chafa_term_info_emit_f9_ctrl_key") 1003 | purego.RegisterLibFunc( 1004 | &TermInfoEmitF9ShiftKey, 1005 | libchafa, 1006 | "chafa_term_info_emit_f9_shift_key", 1007 | ) 1008 | purego.RegisterLibFunc(&TermInfoEmitF10Key, libchafa, "chafa_term_info_emit_f10_key") 1009 | purego.RegisterLibFunc( 1010 | &TermInfoEmitF10CtrlKey, 1011 | libchafa, 1012 | "chafa_term_info_emit_f10_ctrl_key", 1013 | ) 1014 | purego.RegisterLibFunc( 1015 | &TermInfoEmitF10ShiftKey, 1016 | libchafa, 1017 | "chafa_term_info_emit_f10_shift_key", 1018 | ) 1019 | purego.RegisterLibFunc(&TermInfoEmitF11Key, libchafa, "chafa_term_info_emit_f11_key") 1020 | purego.RegisterLibFunc( 1021 | &TermInfoEmitF11CtrlKey, 1022 | libchafa, 1023 | "chafa_term_info_emit_f11_ctrl_key", 1024 | ) 1025 | purego.RegisterLibFunc( 1026 | &TermInfoEmitF11ShiftKey, 1027 | libchafa, 1028 | "chafa_term_info_emit_f11_shift_key", 1029 | ) 1030 | purego.RegisterLibFunc(&TermInfoEmitF12Key, libchafa, "chafa_term_info_emit_f12_key") 1031 | purego.RegisterLibFunc( 1032 | &TermInfoEmitF12CtrlKey, 1033 | libchafa, 1034 | "chafa_term_info_emit_f12_ctrl_key", 1035 | ) 1036 | purego.RegisterLibFunc( 1037 | &TermInfoEmitF12ShiftKey, 1038 | libchafa, 1039 | "chafa_term_info_emit_f12_shift_key", 1040 | ) 1041 | 1042 | // Features 1043 | purego.RegisterLibFunc(&GetBuiltinFeatures, libchafa, "chafa_get_builtin_features") 1044 | purego.RegisterLibFunc(&GetSupportedFeatures, libchafa, "chafa_get_supported_features") 1045 | purego.RegisterLibFunc(&DescribeFeatures, libchafa, "chafa_describe_features") 1046 | purego.RegisterLibFunc(&GetNThreads, libchafa, "chafa_get_n_threads") 1047 | purego.RegisterLibFunc(&SetNThreads, libchafa, "chafa_set_n_threads") 1048 | purego.RegisterLibFunc(&GetNActualThreads, libchafa, "chafa_get_n_actual_threads") 1049 | 1050 | // Miscellaneous 1051 | purego.RegisterLibFunc(&CalcCanvasGeometry, libchafa, "chafa_calc_canvas_geometry") 1052 | }) 1053 | } 1054 | 1055 | type GString struct { 1056 | str string 1057 | } 1058 | 1059 | func (gstr *GString) String() string { 1060 | return gstr.str 1061 | } 1062 | 1063 | type GError struct { 1064 | Domain uint32 1065 | Code int32 1066 | Message string 1067 | } 1068 | 1069 | func Load(path string) (pixels []uint8, width, height int32, err error) { 1070 | file, err := os.Open(path) 1071 | if err != nil { 1072 | return nil, 0, 0, err 1073 | } 1074 | defer file.Close() 1075 | 1076 | var img image.Image 1077 | 1078 | switch filepath.Ext(path) { 1079 | case "png": 1080 | img, err = png.Decode(file) 1081 | if err != nil { 1082 | return nil, 0, 0, err 1083 | } 1084 | case "jpg", "jpeg": 1085 | img, err = jpeg.Decode(file) 1086 | if err != nil { 1087 | return nil, 0, 0, err 1088 | } 1089 | case "gif": 1090 | img, err = gif.Decode(file) 1091 | if err != nil { 1092 | return nil, 0, 0, err 1093 | } 1094 | default: 1095 | img, _, err = image.Decode(file) 1096 | if err != nil { 1097 | return nil, 0, 0, err 1098 | } 1099 | } 1100 | 1101 | bounds := img.Bounds() 1102 | width = int32(bounds.Dx()) 1103 | height = int32(bounds.Dy()) 1104 | 1105 | rgbaImg := image.NewRGBA(bounds) 1106 | draw.Draw(rgbaImg, bounds, img, bounds.Min, draw.Src) 1107 | 1108 | return rgbaImg.Pix, width, height, nil 1109 | } 1110 | -------------------------------------------------------------------------------- /config.go: -------------------------------------------------------------------------------- 1 | package chafa 2 | 3 | var ( 4 | // Creates a new [CanvasConfig] with default settings. 5 | // This object can later be used in the creation of a [Canvas]. 6 | CanvasConfigNew func() *CanvasConfig 7 | 8 | // Creates a new [CanvasConfig] that's a copy of config. 9 | CanvasConfigCopy func(config *CanvasConfig) *CanvasConfig 10 | 11 | // Adds a reference to config. 12 | CanvasConfigRef func(config *CanvasConfig) 13 | 14 | // Removes a reference from config. 15 | CanvasConfigUnref func(config *CanvasConfig) 16 | 17 | // Returns config's width and height in character cells in the provided output locations. 18 | CanvasConfigGetGeometry func(config *CanvasConfig, widthOut, heightOut *int32) 19 | 20 | // Sets config's width and height in character cells to width x height. 21 | CanvasConfigSetGeometry func(config *CanvasConfig, width, height int32) 22 | 23 | // Returns config's cell width and height in pixels in the provided output locations. 24 | CanvasConfigGetCellGeometry func(config *CanvasConfig, cellWidthOut, cellHeightOut *int32) 25 | 26 | // Sets config's cell width and height in pixels to cellWidth x cellHeight. 27 | CanvasConfigSetCellGeometry func(config *CanvasConfig, cellWidth, cellHeight int32) 28 | 29 | // Returns config's [PixelMode]. 30 | CanvasConfigGetPixelMode func(config *CanvasConfig) PixelMode 31 | 32 | // Sets config's stored [PixelMode] to pixelMode. 33 | // This determines how pixel graphics are rendered in the output. 34 | CanvasConfigSetPixelMode func(config *CanvasConfig, pixelMode PixelMode) 35 | 36 | // Returns config's [CanvasMode]. This determines how colors (and color control codes) 37 | // are used in the output. 38 | CanvasConfigGetCanvasMode func(config *CanvasConfig) CanvasMode 39 | 40 | // Sets config's stored [CanvasMode] to mode. 41 | // This determines how colors (and color control codes) are used in the output. 42 | CanvasConfigSetCanvasMode func(config *CanvasConfig, mode CanvasMode) 43 | 44 | // Returns config's [ColorExtractor]. This determines how colors 45 | // are approximated in character symbol output. 46 | CanvasConfigGetColorExtractor func(config *CanvasConfig) ColorExtractor 47 | 48 | // Sets config's stored [ColorExtractor] to colorExtractor. 49 | // This determines how colors are approximated in character symbol output. 50 | CanvasConfigSetColorExtractor func(config *CanvasConfig, colorExtractor ColorExtractor) 51 | 52 | // Returns config's [ColorSpace]. 53 | CanvasConfigGetColorSpace func(config *CanvasConfig) ColorSpace 54 | 55 | // Sets config's stored [ColorSpace] to colorSpace. 56 | CanvasConfigSetColorSpace func(config *CanvasConfig, colorSpace ColorSpace) 57 | 58 | // Queries whether automatic image preprocessing is enabled. This allows Chafa 59 | // to boost contrast and saturation in an attempt to improve legibility. 60 | // The type of preprocessing applied (if any) depends on the canvas mode. 61 | CanvasConfigGetPreprocessingEnabled func(config *CanvasConfig) bool 62 | 63 | // Indicates whether automatic image preprocessing should be enabled. This 64 | // allows Chafa to boost contrast and saturation in an attempt to improve legibility. 65 | // The type of preprocessing applied (if any) depends on the canvas mode. 66 | CanvasConfigSetPreprocessingEnabled func(config *CanvasConfig, preprocessing_enabled bool) 67 | 68 | // Returns a pointer to the symbol map belonging to config. This can be 69 | // inspected using the [SymbolMap] getter functions, but not changed. 70 | CanvasConfigPeekSymbolMap func(config *CanvasConfig) *SymbolMap 71 | 72 | // Assigns a copy of symbolMap to config. 73 | CanvasConfigSetSymbolMap func(config *CanvasConfig, symbolMap *SymbolMap) 74 | 75 | // Returns a pointer to the fill symbol map belonging to config. This can 76 | // be inspected using the [SymbolMap] getter functions, but not changed. 77 | // 78 | // Fill symbols are assigned according to their overall foreground to 79 | // background coverage, disregarding shape. 80 | CanvasConfigPeekFillSymbolMap func(config *CanvasConfig) *SymbolMap 81 | 82 | // Returns the threshold above which full transparency will be used. 83 | CanvasConfigGetTransparencyThreshold func(config *CanvasConfig) float32 84 | 85 | // Sets the threshold above which full transparency will be used. 86 | CanvasConfigSetTransparencyThreshold func(config *CanvasConfig, alphaThreshold float32) 87 | 88 | // Queries whether to use foreground colors only, leaving the background 89 | // unmodified in the canvas output. This is relevant only when the [PixelMode] 90 | // is set to [CHAFA_PIXEL_MODE_SYMBOLS]. 91 | // 92 | // When this is set, the canvas will emit escape codes to set the foreground color only. 93 | CanvasConfigGetFgOnlyEnabled func(config *CanvasConfig) bool 94 | 95 | // Indicates whether to use foreground colors only, leaving the background 96 | // unmodified in the canvas output. This is relevant only when the [PixelMode] 97 | // is set to [CHAFA_PIXEL_MODE_SYMBOLS]. 98 | // 99 | //When this is set, the canvas will emit escape codes to set the foreground color only. 100 | CanvasConfigSetFgOnlyEnabled func(config *CanvasConfig, fgOnlyEnabled bool) 101 | 102 | // Gets the assumed foreground color of the output device. This is used to 103 | // determine how to apply the foreground pen in FGBG modes. 104 | CanvasConfigGetFgColor func(config *CanvasConfig) uint32 105 | 106 | // Sets the assumed foreground color of the output device. This is used to 107 | // determine how to apply the foreground pen in FGBG modes. 108 | CanvasConfigSetFgColor func(config *CanvasConfig, fgColorPackedRGB uint32) 109 | 110 | // Gets the assumed background color of the output device. This is used to 111 | // determine how to apply the background pen in FGBG modes. 112 | CanvasConfigGetBgColor func(config *CanvasConfig) uint32 113 | 114 | // Sets the assumed background color of the output device. This is used to 115 | // determine how to apply the background and transparency pens in FGBG modes, 116 | // and will also be substituted for partial transparency. 117 | CanvasConfigSetBgColor func(config *CanvasConfig, bgColorPackedRGB uint32) 118 | 119 | // Gets the work/quality tradeoff factor. A higher value means more time 120 | // and memory will be spent towards a higher quality output. 121 | CanvasConfigGetWorkFactor func(config *CanvasConfig) float32 122 | 123 | // Sets the work/quality tradeoff factor. A higher value means more time 124 | // and memory will be spent towards a higher quality output. 125 | CanvasConfigSetWorkFactor func(config *CanvasConfig, workFactor float32) 126 | 127 | // Returns config's [DitherMode]. 128 | CanvasConfigGetDitherMode func(config *CanvasConfig) DitherMode 129 | 130 | // Sets config's stored [DitherMode] to ditherMode. 131 | CanvasConfigSetDitherMode func(config *CanvasConfig, ditherMode DitherMode) 132 | 133 | // Returns config's dither grain size in widthOut and heightOut. 134 | CanvasConfigGetDitherGrainSize func(config *CanvasConfig, widthOut, heightOut *int32) 135 | 136 | // Sets config's stored dither grain size to width by height pixels. 137 | // These values can be 1, 2, 4 or 8. 8 corresponds to the size of an entire 138 | // character cell. The default is 4 pixels by 4 pixels. 139 | CanvasConfigSetDitherGrainSize func(config *CanvasConfig, width, height int32) 140 | 141 | // Returns the relative intensity of the dithering pattern applied during 142 | // image conversion. 1.0 is the default, corresponding to a moderate intensity. 143 | CanvasConfigGetDitherIntensity func(config *CanvasConfig) float32 144 | 145 | // Sets config's stored relative intensity of the dithering pattern applied 146 | // during image conversion. 1.0 is the default, corresponding to a moderate 147 | // intensity. Possible values range from 0.0 to infinity, but in practice, 148 | // values above 10.0 are rarely useful. 149 | CanvasConfigSetDitherIntensity func(config *CanvasConfig, intensity float32) 150 | 151 | // Returns config's optimization flags. When enabled, these may produce 152 | // more compact output at the cost of reduced compatibility and increased 153 | // CPU use. Output quality is unaffected. 154 | CanvasConfigGetOptimizations func(config *CanvasConfig) Optimizations 155 | 156 | // Sets config's stored optimization flags. When enabled, these may produce 157 | // more compact output at the cost of reduced compatibility and increased 158 | // CPU use. Output quality is unaffected. 159 | CanvasConfigSetOptimizations func(config *CanvasConfig, optimizations Optimizations) 160 | 161 | // Returns config's [Passthrough] setting. This defaults to [CHAFA_PASSTHROUGH_NONE]. 162 | // 163 | // Passthrough is needed to transmit certain escape codes to the outer terminal 164 | // when running in an inner terminal environment like tmux. When enabled, 165 | // this will happen automatically as needed, dictated by information 166 | // contained in a [TermInfo]. 167 | CanvasConfigGetPassthrough func(config *CanvasConfig) Passthrough 168 | 169 | // Indicates which passthrough mode to use. This defaults to [CHAFA_PASSTHROUGH_NONE]. 170 | // 171 | // [Passthrough] is needed to transmit certain escape codes to the outer 172 | // terminal when running in an inner terminal environment like tmux. When 173 | // enabled, this will happen automatically as needed, dictated by information 174 | // contained in a [TermInfo]. 175 | CanvasConfigSetPassthrough func(config *CanvasConfig, passthrough Passthrough) 176 | ) 177 | 178 | type CanvasConfig struct { 179 | Refs int32 180 | 181 | Width, Height int32 182 | CellWidth, CellHeight int32 183 | CanvasMode CanvasMode 184 | ColorSpace ColorSpace 185 | DitherMode DitherMode 186 | ColorExtractor ColorExtractor 187 | PixelMode PixelMode 188 | DitherGrainWidth, DitherGrainHeight int32 189 | DitherIntensity float32 190 | FgColorPackedRgb uint32 191 | BgColorPackedRgb uint32 192 | AlphaThreshold int32 // 0-255. 255 = no alpha in output 193 | WorkFactor float32 194 | SymbolMap SymbolMap 195 | FillSymbolMap SymbolMap 196 | PreprocessingEnabled bool 197 | FgOnlyEnabled bool 198 | Optimizations Optimizations 199 | Passthrough Passthrough 200 | } 201 | -------------------------------------------------------------------------------- /embedded.go: -------------------------------------------------------------------------------- 1 | // This file implements library embedding and extraction at runtime, a pattern 2 | // also used in several other Go projects that need to distribute native binaries: 3 | // 4 | // - github.com/kluctl/go-embed-python: Embeds a full Python distribution in Go 5 | // binaries, extracting to temporary directories at runtime. The approach used here 6 | // was directly inspired by its embed_util implementation. 7 | // 8 | // - github.com/kluctl/go-jinja2: Uses the same pattern to embed Jinja2 and related 9 | // Python libraries, allowing Go applications to use Jinja2 templates without 10 | // external dependencies. 11 | // 12 | // This approach has several advantages: 13 | // - Allows distribution of a single, self-contained binary 14 | // - Eliminates the need for users to set LD_LIBRARY_PATH or other environment variables 15 | // - Works cross-platform with the same codebase 16 | // - Preserves backward compatibility with existing methods 17 | // - Extracts libraries only once per execution via sync.Once 18 | // 19 | // The embedded library is extracted to a user-specific temporary directory and 20 | // loaded dynamically. If extraction fails, the code falls back to the traditional 21 | // method of searching system paths. 22 | package chafa 23 | 24 | import ( 25 | "embed" 26 | "fmt" 27 | "io" 28 | "os" 29 | "path/filepath" 30 | "runtime" 31 | "sync" 32 | ) 33 | 34 | //go:embed libs/* 35 | var embeddedLibs embed.FS 36 | 37 | var ( 38 | extractOnce sync.Once 39 | extractedPath string 40 | extractErr error 41 | ) 42 | 43 | // extractEmbeddedLibrary extracts the library for the current platform 44 | // to a temporary directory and returns the path to the extracted library 45 | func extractEmbeddedLibrary() (string, error) { 46 | extractOnce.Do(func() { 47 | // Determine platform-specific details 48 | var libName string 49 | var platformDir string 50 | 51 | switch runtime.GOOS { 52 | case "darwin": 53 | libName = "libchafa.dylib" 54 | case "linux": 55 | libName = "libchafa.so" 56 | default: 57 | extractErr = fmt.Errorf("unsupported operating system: %s", runtime.GOOS) 58 | return 59 | } 60 | 61 | // Determine architecture suffix 62 | var archSuffix string 63 | switch runtime.GOARCH { 64 | case "amd64": 65 | archSuffix = "amd64" 66 | case "arm64": 67 | archSuffix = "arm64" 68 | case "386": 69 | archSuffix = "386" 70 | default: 71 | extractErr = fmt.Errorf("unsupported architecture: %s", runtime.GOARCH) 72 | return 73 | } 74 | 75 | // Create platform directory string 76 | platformDir = fmt.Sprintf("%s-%s", runtime.GOOS, archSuffix) 77 | 78 | // Create a unique temporary directory for the current user 79 | tempDir := filepath.Join(os.TempDir(), fmt.Sprintf("chafa-go-%d", os.Getuid())) 80 | if err := os.MkdirAll(tempDir, 0755); err != nil { 81 | extractErr = fmt.Errorf("failed to create temp directory: %w", err) 82 | return 83 | } 84 | 85 | // Path to the library within the embedded filesystem 86 | libPath := filepath.Join("libs", platformDir, libName) 87 | 88 | // Where the library will be extracted 89 | extractedPath = filepath.Join(tempDir, libName) 90 | 91 | // Check if library already exists and is valid 92 | if stat, err := os.Stat(extractedPath); err == nil && stat.Size() > 0 { 93 | // Library already exists, nothing to do 94 | return 95 | } 96 | 97 | // Open the embedded library 98 | embeddedLib, err := embeddedLibs.Open(libPath) 99 | if err != nil { 100 | extractErr = fmt.Errorf("failed to open embedded library %s: %w", libPath, err) 101 | return 102 | } 103 | defer embeddedLib.Close() 104 | 105 | // Create the output file 106 | outFile, err := os.Create(extractedPath) 107 | if err != nil { 108 | extractErr = fmt.Errorf("failed to create output file: %w", err) 109 | return 110 | } 111 | defer outFile.Close() 112 | 113 | // Copy the library to the temporary directory 114 | if _, err := io.Copy(outFile, embeddedLib); err != nil { 115 | extractErr = fmt.Errorf("failed to extract library: %w", err) 116 | return 117 | } 118 | 119 | // On Unix systems, make the library executable 120 | if err := os.Chmod(extractedPath, 0755); err != nil { 121 | extractErr = fmt.Errorf("failed to make library executable: %w", err) 122 | return 123 | } 124 | }) 125 | 126 | return extractedPath, extractErr 127 | } 128 | -------------------------------------------------------------------------------- /examples/adaptive/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ploMP4/chafa-go/examples/adaptive 2 | 3 | go 1.24.3 4 | 5 | replace github.com/ploMP4/chafa-go => ../.. 6 | 7 | require ( 8 | github.com/ploMP4/chafa-go v0.0.0 9 | golang.org/x/term v0.32.0 10 | ) 11 | 12 | require ( 13 | github.com/ebitengine/purego v0.8.3 // indirect 14 | golang.org/x/sys v0.33.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /examples/adaptive/go.sum: -------------------------------------------------------------------------------- 1 | github.com/ebitengine/purego v0.8.3 h1:K+0AjQp63JEZTEMZiwsI9g0+hAMNohwUOtY0RPGexmc= 2 | github.com/ebitengine/purego v0.8.3/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= 3 | golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= 4 | golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 5 | golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= 6 | golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= 7 | -------------------------------------------------------------------------------- /examples/adaptive/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/ploMP4/chafa-go" 8 | "golang.org/x/sys/unix" 9 | ) 10 | 11 | const ( 12 | PIX_WIDTH = 3 13 | PIX_HEIGHT = 3 14 | N_CHANNELS = 4 15 | ) 16 | 17 | type TermSize struct { 18 | widthCells int32 19 | heightCells int32 20 | widthPixels int32 21 | heightPixels int32 22 | } 23 | 24 | func detectTerminal() (*chafa.TermInfo, chafa.CanvasMode, chafa.PixelMode, chafa.Passthrough, *chafa.SymbolMap) { 25 | //Examine the environment variables and guess what the terminal can do 26 | termInfo := chafa.TermDbDetect(chafa.TermDbGetDefault(), os.Environ()) 27 | 28 | // Pick the most high-quality rendering possible 29 | mode := chafa.TermInfoGetBestCanvasMode(termInfo) 30 | pixelMode := chafa.TermInfoGetBestPixelMode(termInfo) 31 | 32 | passthrough := chafa.CHAFA_PASSTHROUGH_NONE 33 | if chafa.TermInfoGetIsPixelPassthroughNeeded(termInfo, pixelMode) { 34 | passthrough = chafa.TermInfoGetPassthroughType(termInfo) 35 | } 36 | 37 | symbolMap := chafa.SymbolMapNew() 38 | chafa.SymbolMapAddByTags(symbolMap, chafa.TermInfoGetSafeSymbolTags(termInfo)) 39 | 40 | return termInfo, mode, pixelMode, passthrough, symbolMap 41 | } 42 | 43 | func getTTYSize() TermSize { 44 | termSize := TermSize{ 45 | widthCells: -1, 46 | heightCells: -1, 47 | widthPixels: -1, 48 | heightPixels: -1, 49 | } 50 | 51 | fds := []uintptr{os.Stdout.Fd(), os.Stderr.Fd(), os.Stdin.Fd()} 52 | for _, fd := range fds { 53 | winsize, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ) 54 | if err == nil { 55 | termSize.widthCells = int32(winsize.Col) 56 | termSize.heightCells = int32(winsize.Row) 57 | termSize.widthPixels = int32(winsize.Xpixel) 58 | termSize.heightPixels = int32(winsize.Ypixel) 59 | break 60 | } 61 | } 62 | 63 | if termSize.widthCells <= 0 { 64 | termSize.widthCells = -1 65 | } 66 | if termSize.heightCells <= 2 { 67 | termSize.heightCells = -1 68 | } 69 | 70 | // If .xpixel and .ypixel are filled out, we can calculate 71 | // aspect information for the font used. Sixel-capable terminals 72 | // like mlterm set these fields, but most others do not. 73 | 74 | if termSize.widthPixels <= 0 || termSize.heightPixels <= 0 { 75 | termSize.widthPixels = -1 76 | termSize.heightPixels = -1 77 | } 78 | 79 | return termSize 80 | } 81 | 82 | func convertImage( 83 | pixels []uint8, 84 | pixWidth, pixHeight, pixRowstride int32, 85 | pixelType chafa.PixelType, 86 | widthCells, heightCells, cellWidth, cellHeight int32, 87 | ) string { 88 | termInfo, mode, pixelMode, passthrough, symbolMap := detectTerminal() 89 | defer chafa.SymbolMapUnref(symbolMap) 90 | defer chafa.TermInfoUnref(termInfo) 91 | 92 | // Set up a configuration based on detected characteristics 93 | config := chafa.CanvasConfigNew() 94 | defer chafa.CanvasConfigUnref(config) 95 | 96 | chafa.CanvasConfigSetCanvasMode(config, mode) 97 | chafa.CanvasConfigSetPixelMode(config, pixelMode) 98 | chafa.CanvasConfigSetGeometry(config, widthCells, heightCells) 99 | chafa.CanvasConfigSetPassthrough(config, passthrough) 100 | chafa.CanvasConfigSetSymbolMap(config, symbolMap) 101 | 102 | if cellWidth > 0 && cellHeight > 0 { 103 | // We know the pixel dimensions of each cell. Store it in the config. 104 | chafa.CanvasConfigSetCellGeometry(config, cellWidth, cellHeight) 105 | } 106 | 107 | // Create canvas 108 | canvas := chafa.CanvasNew(config) 109 | defer chafa.CanvasUnRef(canvas) 110 | 111 | // Draw pixels to the canvas 112 | chafa.CanvasDrawAllPixels(canvas, pixelType, pixels, pixWidth, pixHeight, pixRowstride) 113 | 114 | // Build printable string 115 | printable := chafa.CanvasPrint(canvas, termInfo) 116 | 117 | return printable.String() 118 | } 119 | 120 | func main() { 121 | pixels := [PIX_WIDTH * PIX_HEIGHT * N_CHANNELS]uint8{ 122 | 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 123 | 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 124 | 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 125 | } 126 | 127 | var fontRatio float32 = 0.5 128 | var cellWidth int32 = -1 129 | var cellHeight int32 = -1 130 | 131 | termSize := getTTYSize() 132 | 133 | if termSize.widthCells > 0 && termSize.heightCells > 0 && 134 | termSize.widthPixels > 0 && termSize.heightPixels > 0 { 135 | cellWidth = termSize.widthPixels / termSize.widthCells 136 | cellHeight = termSize.heightPixels / termSize.heightCells 137 | fontRatio = float32(cellWidth) / float32(cellHeight) 138 | } 139 | 140 | widthCells := termSize.widthCells 141 | heightCells := termSize.heightCells 142 | 143 | chafa.CalcCanvasGeometry( 144 | PIX_HEIGHT, 145 | PIX_HEIGHT, 146 | &widthCells, 147 | &heightCells, 148 | fontRatio, 149 | true, 150 | false, 151 | ) 152 | 153 | printable := convertImage( 154 | pixels[:], 155 | PIX_WIDTH, 156 | PIX_HEIGHT, 157 | PIX_WIDTH*N_CHANNELS, 158 | chafa.CHAFA_PIXEL_RGBA8_UNASSOCIATED, 159 | widthCells, 160 | heightCells, 161 | cellWidth, 162 | cellHeight, 163 | ) 164 | 165 | fmt.Println(printable) 166 | } 167 | -------------------------------------------------------------------------------- /examples/aspectratio/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/ploMP4/chafa-go" 8 | ) 9 | 10 | const ( 11 | FONT_WIDTH = 11 12 | FONT_HEIGHT = 24 13 | N_CHANNELS = 4 14 | ) 15 | 16 | func main() { 17 | pixels, width, height, err := chafa.Load("./examples/image.png") 18 | if err != nil { 19 | fmt.Fprintln(os.Stderr, err) 20 | return 21 | } 22 | 23 | config := chafa.CanvasConfigNew() 24 | defer chafa.CanvasConfigUnref(config) 25 | 26 | chafa.CanvasConfigSetGeometry(config, 30, 30) 27 | chafa.CanvasConfigSetCellGeometry(config, FONT_WIDTH, FONT_HEIGHT) 28 | 29 | widthNew := config.Width 30 | heightNew := config.Height 31 | 32 | chafa.CalcCanvasGeometry( 33 | width, height, 34 | &widthNew, &heightNew, 35 | float32(FONT_WIDTH)/float32(FONT_HEIGHT), 36 | false, false, 37 | ) 38 | chafa.CanvasConfigSetGeometry(config, widthNew, heightNew) 39 | 40 | canvas := chafa.CanvasNew(config) 41 | defer chafa.CanvasUnRef(canvas) 42 | 43 | chafa.CanvasDrawAllPixels( 44 | canvas, 45 | chafa.CHAFA_PIXEL_RGBA8_UNASSOCIATED, 46 | pixels, 47 | int32(width), 48 | int32(height), 49 | int32(width)*N_CHANNELS, 50 | ) 51 | 52 | gs := chafa.CanvasPrint(canvas, nil) 53 | 54 | fmt.Println(gs) 55 | } 56 | -------------------------------------------------------------------------------- /examples/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ploMP4/chafa-go/6f28a6434c0d26b91bcfe72bbd67f947ea05f3af/examples/image.png -------------------------------------------------------------------------------- /examples/passthrough/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/ploMP4/chafa-go" 8 | ) 9 | 10 | const ( 11 | FONT_WIDTH = 18 12 | FONT_HEIGHT = 36 13 | N_CHANNELS = 4 14 | ) 15 | 16 | func main() { 17 | if len(os.Args) < 2 { 18 | return 19 | } 20 | 21 | pixels, width, height, err := chafa.Load(os.Args[1]) 22 | if err != nil { 23 | fmt.Fprintln(os.Stderr, err) 24 | return 25 | } 26 | 27 | termInfo := chafa.TermDbDetect(chafa.TermDbGetDefault(), os.Environ()) 28 | defer chafa.TermInfoUnref(termInfo) 29 | 30 | mode := chafa.TermInfoGetBestCanvasMode(termInfo) 31 | pixelMode := chafa.TermInfoGetBestPixelMode(termInfo) 32 | 33 | passthrough := chafa.CHAFA_PASSTHROUGH_NONE 34 | if chafa.TermInfoGetIsPixelPassthroughNeeded(termInfo, pixelMode) { 35 | passthrough = chafa.TermInfoGetPassthroughType(termInfo) 36 | } 37 | 38 | config := chafa.CanvasConfigNew() 39 | defer chafa.CanvasConfigUnref(config) 40 | 41 | chafa.CanvasConfigSetGeometry(config, 40, 20) 42 | chafa.CanvasConfigSetCellGeometry(config, FONT_WIDTH, FONT_HEIGHT) 43 | chafa.CanvasConfigSetCanvasMode(config, mode) 44 | chafa.CanvasConfigSetPixelMode(config, pixelMode) 45 | chafa.CanvasConfigSetPassthrough(config, passthrough) 46 | 47 | chafa.CalcCanvasGeometry( 48 | width, height, 49 | &config.Width, &config.Height, 50 | float32(FONT_WIDTH)/float32(FONT_HEIGHT), 51 | false, false, 52 | ) 53 | chafa.CanvasConfigSetGeometry(config, config.Width, config.Height) 54 | 55 | canvas := chafa.CanvasNew(config) 56 | defer chafa.CanvasUnRef(canvas) 57 | 58 | frame := chafa.FrameNew( 59 | pixels, 60 | chafa.CHAFA_PIXEL_RGBA8_UNASSOCIATED, 61 | width, 62 | height, 63 | width*N_CHANNELS, 64 | ) 65 | defer chafa.FrameUnref(frame) 66 | 67 | img := chafa.ImageNew() 68 | defer chafa.ImageUnref(img) 69 | 70 | chafa.ImageSetFrame(img, frame) 71 | 72 | placement := chafa.PlacementNew(img, 1) 73 | defer chafa.PlacementUnref(placement) 74 | 75 | chafa.CanvasSetPlacement(canvas, placement) 76 | 77 | gs := chafa.CanvasPrint(canvas, termInfo) 78 | 79 | fmt.Println(gs) 80 | } 81 | -------------------------------------------------------------------------------- /examples/simple/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/ploMP4/chafa-go" 7 | ) 8 | 9 | const ( 10 | PIX_WIDTH = 3 11 | PIX_HEIGHT = 3 12 | N_CHANNELS = 4 13 | ) 14 | 15 | func main() { 16 | pixels := []uint8{ 17 | 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 18 | 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 19 | 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 20 | } 21 | 22 | // Specify the symbols we want 23 | symbolMap := chafa.SymbolMapNew() 24 | defer chafa.SymbolMapUnref(symbolMap) 25 | 26 | chafa.SymbolMapAddByTags(symbolMap, chafa.CHAFA_SYMBOL_TAG_ALL) 27 | 28 | // Set up a configuration with the symbols and the canvas size in characters 29 | config := chafa.CanvasConfigNew() 30 | defer chafa.CanvasConfigUnref(config) 31 | 32 | chafa.CanvasConfigSetGeometry(config, 40, 20) 33 | chafa.CanvasConfigSetSymbolMap(config, symbolMap) 34 | 35 | // Create canvas 36 | canvas := chafa.CanvasNew(config) 37 | defer chafa.CanvasUnRef(canvas) 38 | 39 | // Draw pixels to canvas 40 | chafa.CanvasDrawAllPixels( 41 | canvas, 42 | chafa.CHAFA_PIXEL_RGBA8_UNASSOCIATED, 43 | pixels, 44 | PIX_WIDTH, 45 | PIX_HEIGHT, 46 | PIX_WIDTH*N_CHANNELS, 47 | ) 48 | 49 | // Generate a string that will show the canvas contents on a terminal 50 | gs := chafa.CanvasPrint(canvas, nil) 51 | 52 | fmt.Println(gs) 53 | } 54 | -------------------------------------------------------------------------------- /features.go: -------------------------------------------------------------------------------- 1 | package chafa 2 | 3 | var ( 4 | // Gets a list of the platform-specific features this library was built with. 5 | GetBuiltinFeatures func() Features 6 | 7 | // Gets a list of the platform-specific features that are built in and usable on the runtime platform. 8 | GetSupportedFeatures func() Features 9 | 10 | // Takes a set of flags potentially returned from [GetBuiltinFeatures] or 11 | // [GetSupportedFeatures] and generates a human-readable ASCII string descriptor. 12 | DescribeFeatures func(features Features) string 13 | 14 | // Queries the maximum number of worker threads to use for parallel processing. 15 | GetNThreads func() int32 16 | 17 | // Sets the maximum number of worker threads to use for parallel processing, 18 | // or -1 to determine this automatically. The default is -1. 19 | // 20 | // Setting this to 0 or 1 will avoid using thread pools and instead perform 21 | // all processing in the main thread. 22 | SetNThreads func(n int32) 23 | 24 | // Queries the number of worker threads that will actually be used for 25 | // parallel processing. 26 | GetNActualThreads func() int32 27 | ) 28 | 29 | type Features int32 30 | 31 | const ( 32 | CHAFA_FEATURE_MMX Features = 0 33 | CHAFA_FEATURE_SSE41 Features = 1 34 | CHAFA_FEATURE_POPCNT Features = 2 35 | CHAFA_FEATURE_AVX2 Features = 3 36 | ) 37 | -------------------------------------------------------------------------------- /frame.go: -------------------------------------------------------------------------------- 1 | package chafa 2 | 3 | var ( 4 | // Creates a new [Frame] containing a copy of the image data pointed to by data. 5 | FrameNew func(data []uint8, pixelType PixelType, width, height, rowstride int32) *Frame 6 | 7 | // Creates a new [Frame] embedding the data pointer. It's the caller's 8 | // responsibility to ensure the pointer remains valid for the lifetime of 9 | // the frame. The frame will not free the buffer when its reference count 10 | // drops to zero. 11 | // 12 | // THIS IS DANGEROUS API which should only be used when the life cycle of 13 | // the frame is short, stealing the buffer is impossible, and copying would 14 | // cause unacceptable performance degradation. 15 | // 16 | // Use [FrameNew] instead. 17 | FrameNewBorrow func(data []uint8, pixelType PixelType, width, height, rowstride int32) *Frame 18 | 19 | // Creates a new [Frame], which takes ownership of the data buffer. The 20 | // buffer will be freed with g_free() when the frame's reference count drops 21 | // to zero. 22 | FrameNewSteal func(data []uint8, pixelType PixelType, width, height, rowstride int32) *Frame 23 | 24 | // Adds a reference to frame. 25 | FrameRef func(frame *Frame) 26 | 27 | // Removes a reference from frame. When the reference count drops to zero, 28 | // the frame is freed and can no longer be used. 29 | FrameUnref func(frame *Frame) 30 | ) 31 | 32 | type Frame struct { 33 | Refs int32 34 | PixelType PixelType 35 | Width, Height, Rowstride int32 36 | 37 | Data []uint8 38 | 39 | DataIsOwned bool 40 | } 41 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ploMP4/chafa-go 2 | 3 | go 1.24.3 4 | 5 | require github.com/ebitengine/purego v0.8.3 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/ebitengine/purego v0.8.3 h1:K+0AjQp63JEZTEMZiwsI9g0+hAMNohwUOtY0RPGexmc= 2 | github.com/ebitengine/purego v0.8.3/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= 3 | -------------------------------------------------------------------------------- /image.go: -------------------------------------------------------------------------------- 1 | package chafa 2 | 3 | var ( 4 | // Creates a new [Image]. The image is initially transparent 5 | // and dimensionless. 6 | ImageNew func() *Image 7 | 8 | // Adds a reference to image. 9 | ImageRef func(image *Image) 10 | 11 | // Removes a reference from image. When the reference count drops to zero, 12 | // the image is freed and can no longer be used. 13 | ImageUnref func(image *Image) 14 | 15 | // Assigns frame as the content for image. The image will keep its own 16 | // reference to the frame. 17 | ImageSetFrame func(image *Image, frame *Frame) 18 | ) 19 | 20 | type Image struct { 21 | Refs int32 22 | Frame *Frame 23 | } 24 | -------------------------------------------------------------------------------- /libs/BUILD_INFO.txt: -------------------------------------------------------------------------------- 1 | Chafa Version: 1.16 2 | Build Date: Fri May 23 18:22:03 UTC 2025 3 | Workflow: 15216675454 4 | -------------------------------------------------------------------------------- /libs/CHECKSUMS.txt: -------------------------------------------------------------------------------- 1 | 014091a301553e94b25407c262c69ea348f530ca8f796f8606659e9c638fc30a libs/linux-386/libchafa.so 2 | 7478c9bbc454811b2c9a5347273528339f18e043015d98d043bd79942a0d95b8 libs/linux-amd64/libchafa.so 3 | 81652d439732bda86f05855ee1335ef563cc98382bf3a9f16772caf7e84ec30e libs/darwin-arm64/libchafa.dylib 4 | -------------------------------------------------------------------------------- /libs/darwin-arm64/libchafa.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ploMP4/chafa-go/6f28a6434c0d26b91bcfe72bbd67f947ea05f3af/libs/darwin-arm64/libchafa.dylib -------------------------------------------------------------------------------- /libs/linux-386/libchafa.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ploMP4/chafa-go/6f28a6434c0d26b91bcfe72bbd67f947ea05f3af/libs/linux-386/libchafa.so -------------------------------------------------------------------------------- /libs/linux-amd64/libchafa.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ploMP4/chafa-go/6f28a6434c0d26b91bcfe72bbd67f947ea05f3af/libs/linux-amd64/libchafa.so -------------------------------------------------------------------------------- /miscellaneous.go: -------------------------------------------------------------------------------- 1 | package chafa 2 | 3 | // Calculates an optimal geometry for a [Canvas] given the width and height 4 | // of an input image, maximum width and height of the canvas, font ratio, zoom and 5 | // stretch preferences. 6 | // 7 | // srcWidth and srcHeight must both be zero or greater. 8 | // 9 | // destWidthInout and destHeightInout must point to integers containing the 10 | // maximum dimensions of the canvas in character cells. These will be replaced 11 | // by the calculated values, which may be zero if one of the input dimensions is 12 | // zero. If one or both of the input parameters is negative, they will be treated 13 | // as unspecified and calculated based on the remaining parameters and aspect ratio. 14 | // 15 | // fontRatio is the font's width divided by its height. 0.5 is a typical value. 16 | var CalcCanvasGeometry func( 17 | srcWidth, srcHeight int32, 18 | destWidthInout, destHeightInout *int32, 19 | fontRatio float32, 20 | zoom, stretch bool, 21 | ) 22 | -------------------------------------------------------------------------------- /placement.go: -------------------------------------------------------------------------------- 1 | package chafa 2 | 3 | var ( 4 | // Creates a new [Placement] for the specified image and ID. 5 | // If id <= 0, an ID is assigned automatically. 6 | PlacementNew func(image *Image, id int32) *Placement 7 | 8 | // Adds a reference to placement. 9 | PlacementRef func(placement *Placement) 10 | 11 | // Removes a reference from placement. When remaining references drops to zero, 12 | // the placement is freed and can no longer be used. 13 | PlacementUnref func(placement *Placement) 14 | 15 | // Gets the tucking policy of placement. This describes how the image is 16 | // resized to fit placement's extents, and defaults to [CHAFA_TUCK_STRETCH]. 17 | PlacementGetTuck func(placement *Placement) Tuck 18 | 19 | // Sets the tucking policy for placement to tuck . This describes how the 20 | // image is resized to fit placement 's extents, and defaults to [CHAFA_TUCK_STRETCH]. 21 | PlacementSetTuck func(placement *Placement, tuck Tuck) 22 | 23 | // Gets the horizontal alignment of placement. This determines how any 24 | // padding added by the tucking policy is distributed, and defaults to [CHAFA_ALIGN_START]. 25 | PlacementGetHAlign func(placement *Placement) Align 26 | 27 | // Sets the horizontal alignment of placement. This determines how any 28 | // padding added by the tucking policy is distributed, and defaults to [CHAFA_ALIGN_START]. 29 | PlacementSetHAlign func(placement *Placement, align Align) 30 | 31 | // Gets the vertical alignment of placement. This determines how any padding 32 | // added by the tucking policy is distributed, and defaults to [CHAFA_ALIGN_START]. 33 | PlacementGetVAlign func(placement *Placement) Align 34 | 35 | // Sets the vertical alignment of placement . This determines how any 36 | // padding added by the tucking policy is distributed. 37 | PlacementSetVAlign func(placement *Placement, align Align) 38 | ) 39 | 40 | type Placement struct { 41 | Refs int32 42 | 43 | Image *Image 44 | Id int32 45 | Halign, Valign Align 46 | Tuck Tuck 47 | } 48 | 49 | type Tuck int32 50 | 51 | const ( 52 | CHAFA_TUCK_STRETCH Tuck = 0 53 | CHAFA_TUCK_FIT Tuck = 1 54 | CHAFA_TUCK_SHRINK_TO_FIT Tuck = 2 55 | CHAFA_TUCK_MAX Tuck = 3 56 | ) 57 | 58 | type Align int32 59 | 60 | const ( 61 | CHAFA_ALIGN_START Align = 0 62 | CHAFA_ALIGN_END Align = 1 63 | CHAFA_ALIGN_CENTER Align = 2 64 | CHAFA_ALIGN_MAX Align = 3 65 | ) 66 | -------------------------------------------------------------------------------- /showcase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ploMP4/chafa-go/6f28a6434c0d26b91bcfe72bbd67f947ea05f3af/showcase.png -------------------------------------------------------------------------------- /symbol_map.go: -------------------------------------------------------------------------------- 1 | package chafa 2 | 3 | import "unsafe" 4 | 5 | var ( 6 | // Creates a new [SymbolMap] representing a set of Unicode symbols. 7 | // The symbol map starts out empty. 8 | SymbolMapNew func() *SymbolMap 9 | 10 | // Creates a new [SymbolMap] that's a copy of symbolMap. 11 | SymbolMapCopy func(symbolMap *SymbolMap) *SymbolMap 12 | 13 | // Adds a reference to symbolMap. 14 | SymbolMapRef func(symbolMap *SymbolMap) 15 | 16 | // Removes a reference from symbolMap. When remaining references drops to 17 | // zero, the symbol map is freed and can no longer be used. 18 | SymbolMapUnref func(symbolMap *SymbolMap) 19 | 20 | // Adds symbols matching the set of tags to symbolMap. 21 | SymbolMapAddByTags func(symbolMap *SymbolMap, tags SymbolTags) 22 | 23 | // Adds symbols in the code point range starting with first and ending 24 | // with last to symbolMap. 25 | SymbolMapAddByRange func(symbolMap *SymbolMap, first, last rune) 26 | 27 | // Removes symbols matching the set of tags from symbolMap. 28 | SymbolMapRemoveByTags func(symbolMap *SymbolMap, tags SymbolTags) 29 | 30 | // Removes symbols in the code point range starting with first and ending 31 | // with last from symbolMap. 32 | SymbolMapRemoveByRange func(symbolMap *SymbolMap, first, last rune) 33 | 34 | // Parses a string consisting of symbol tags separated by [+-,] and applies 35 | // the pattern to symbolMap . If the string begins with + or -, it's 36 | // understood to be relative to the current set in symbolMap, otherwise the 37 | // map is cleared first. 38 | // 39 | // The symbol tags are string versions of [SymbolTags], i.e. [all, none, 40 | // space, solid, stipple, block, border, diagonal, dot, quad, half, hhalf, 41 | // vhalf, braille, technical, geometric, ascii, extra]. 42 | // 43 | // Examples: "block,border" sets map to contain symbols matching either of 44 | // those tags. "+block,border-dot,stipple" adds block and border symbols then 45 | // removes dot and stipple symbols. 46 | // 47 | // If there is a parse error, none of the changes are applied. 48 | SymbolMapApplySelectors func(symbolMap *SymbolMap, selectors string) bool 49 | 50 | // Queries whether a symbol map is allowed to use built-in glyphs for symbol 51 | // selection. This can be turned off if you want to use your own glyphs 52 | // exclusively (see [SymbolMapAddGlyph]). 53 | // 54 | // Defaults to TRUE. 55 | SymbolMapGetAllowBuiltinGlyphs func(symbolMap *SymbolMap) bool 56 | 57 | // Controls whether a symbol map is allowed to use built-in glyphs for symbol 58 | // selection. This can be turned off if you want to use your own glyphs 59 | // exclusively (see [SymbolMapAddGlyph]). 60 | // 61 | // Defaults to TRUE. 62 | SymbolMapSetAllowBuiltinGlyphs func(symbolMap *SymbolMap, allow bool) 63 | 64 | // Returns data for the glyph corresponding to codePoint stored in symbolMap. 65 | // Any of pixelsOut , widthOut , heightOut and rowstrideOut can be nil, 66 | // in which case the corresponding data is not retrieved. 67 | // 68 | // If pixelsOut is not nil, a pointer to freshly allocated memory containing 69 | // height * rowstride bytes in the pixel format specified by pixelFormat will 70 | // be stored at this address. It must be freed using g_free() when you're 71 | // done with it. 72 | // 73 | // Monochrome glyphs (the only kind currently supported) will be rendered 74 | // as opaque white on a transparent black background 75 | // (0xffffffff for inked pixels and 0x00000000 for uninked). 76 | SymbolMapGetGlyph func( 77 | symbolMap *SymbolMap, 78 | codePoint rune, 79 | pixelFormat PixelType, 80 | pixelsOut **byte, 81 | widthOut, heightOut, rowstrideOut *int32, 82 | ) bool 83 | 84 | // Assigns a rendered glyph to a Unicode code point. This tells Chafa what 85 | // the glyph looks like so the corresponding symbol can be used appropriately 86 | // in output. 87 | // 88 | // Assigned glyphs override built-in glyphs and any earlier glyph that may 89 | // have been assigned to the same code point. 90 | // 91 | // If the input is in a format with an alpha channel, the alpha channel will 92 | // be used for the shape. If not, an average of the color channels will be used. 93 | SymbolMapAddGlyph func( 94 | symbolMap *SymbolMap, 95 | codePoint rune, 96 | pixelFormat PixelType, 97 | pixels unsafe.Pointer, 98 | width, height, rowstride int32, 99 | ) 100 | ) 101 | 102 | type SymbolMap struct { 103 | Refs int32 104 | 105 | NeedRebuild bool 106 | UseBuiltinGlyphs bool 107 | 108 | Glyphs unsafe.Pointer 109 | Glyphs2 unsafe.Pointer // Wide glyphs with left/right bitmaps 110 | Selectors unsafe.Pointer 111 | 112 | // /* Remaining fields are populated by chafa_symbol_map_prepare () */ 113 | 114 | // Narrow symbols 115 | Symbols []Symbol 116 | NSymbols int32 117 | PackedBitmaps *uint64 118 | 119 | // Wide symbols 120 | Symbols2 []Symbol2 121 | NSymbols2 int32 122 | PackedBitmaps2 *uint64 123 | } 124 | 125 | type Symbol struct { 126 | Sc SymbolTags 127 | C uint8 128 | Coverage byte //gchar * 129 | MaskU32 *uint32 130 | FgWeight, BgWeight int32 131 | Bitmap uint64 132 | Popcount int32 133 | } 134 | 135 | type Symbol2 struct { 136 | Sym [2]Symbol 137 | } 138 | 139 | type SymbolTags int32 140 | 141 | const ( 142 | CHAFA_SYMBOL_TAG_NONE SymbolTags = 0 143 | CHAFA_SYMBOL_TAG_SPACE SymbolTags = (1 << 0) 144 | CHAFA_SYMBOL_TAG_SOLID SymbolTags = (1 << 1) 145 | CHAFA_SYMBOL_TAG_STIPPLE SymbolTags = (1 << 2) 146 | CHAFA_SYMBOL_TAG_BLOCK SymbolTags = (1 << 3) 147 | CHAFA_SYMBOL_TAG_BORDER SymbolTags = (1 << 4) 148 | CHAFA_SYMBOL_TAG_DIAGONAL SymbolTags = (1 << 5) 149 | CHAFA_SYMBOL_TAG_DOT SymbolTags = (1 << 6) 150 | CHAFA_SYMBOL_TAG_QUAD SymbolTags = (1 << 7) 151 | CHAFA_SYMBOL_TAG_HHALF SymbolTags = (1 << 8) 152 | CHAFA_SYMBOL_TAG_VHALF SymbolTags = (1 << 9) 153 | CHAFA_SYMBOL_TAG_HALF SymbolTags = ((CHAFA_SYMBOL_TAG_HHALF) | (CHAFA_SYMBOL_TAG_VHALF)) 154 | CHAFA_SYMBOL_TAG_INVERTED SymbolTags = (1 << 10) 155 | CHAFA_SYMBOL_TAG_BRAILLE SymbolTags = (1 << 11) 156 | CHAFA_SYMBOL_TAG_TECHNICAL SymbolTags = (1 << 12) 157 | CHAFA_SYMBOL_TAG_GEOMETRIC SymbolTags = (1 << 13) 158 | CHAFA_SYMBOL_TAG_ASCII SymbolTags = (1 << 14) 159 | CHAFA_SYMBOL_TAG_ALPHA SymbolTags = (1 << 15) 160 | CHAFA_SYMBOL_TAG_DIGIT SymbolTags = (1 << 16) 161 | CHAFA_SYMBOL_TAG_ALNUM SymbolTags = CHAFA_SYMBOL_TAG_ALPHA | CHAFA_SYMBOL_TAG_DIGIT 162 | CHAFA_SYMBOL_TAG_NARROW SymbolTags = (1 << 17) 163 | CHAFA_SYMBOL_TAG_WIDE SymbolTags = (1 << 18) 164 | CHAFA_SYMBOL_TAG_AMBIGUOUS SymbolTags = (1 << 19) 165 | CHAFA_SYMBOL_TAG_UGLY SymbolTags = (1 << 20) 166 | CHAFA_SYMBOL_TAG_LEGACY SymbolTags = (1 << 21) 167 | CHAFA_SYMBOL_TAG_SEXTANT SymbolTags = (1 << 22) 168 | CHAFA_SYMBOL_TAG_WEDGE SymbolTags = (1 << 23) 169 | CHAFA_SYMBOL_TAG_LATIN SymbolTags = (1 << 24) 170 | CHAFA_SYMBOL_TAG_IMPORTED SymbolTags = (1 << 25) 171 | CHAFA_SYMBOL_TAG_OCTANT SymbolTags = (1 << 26) 172 | CHAFA_SYMBOL_TAG_EXTRA SymbolTags = (1 << 30) 173 | CHAFA_SYMBOL_TAG_BAD SymbolTags = CHAFA_SYMBOL_TAG_AMBIGUOUS | CHAFA_SYMBOL_TAG_UGLY 174 | CHAFA_SYMBOL_TAG_ALL SymbolTags = ^(CHAFA_SYMBOL_TAG_EXTRA | CHAFA_SYMBOL_TAG_BAD) 175 | ) 176 | -------------------------------------------------------------------------------- /termdb.go: -------------------------------------------------------------------------------- 1 | package chafa 2 | 3 | import "unsafe" 4 | 5 | var ( 6 | // Creates a new, blank [TermDb]. 7 | TermDbNew func() *TermDb 8 | 9 | // Creates a new [TermDb] that's a copy of termDb. 10 | TermDbCopy func(termDb *TermDb) *TermDb 11 | 12 | // Adds a reference to termDb. 13 | TermDbRef func(termDb *TermDb) 14 | 15 | // Removes a reference from termDb. 16 | TermDbUnref func(termDb *TermDb) 17 | 18 | // Gets the global [TermDb]. This can normally be used safely in a read-only 19 | // capacity. The caller should not unref the returned object. 20 | TermDbGetDefault func() *TermDb 21 | 22 | // Builds a new [TermInfo] with capabilities implied by the provided 23 | // environment variables (principally the TERM variable, but also others). 24 | termDbDetect func(termDb *TermDb, envp **byte) *TermInfo 25 | 26 | // Builds a new [TermInfo] with fallback control sequences. This can be used 27 | // with unknown but presumably modern terminals, or to supplement missing 28 | // capabilities in a detected terminal. 29 | // 30 | // Fallback control sequences may cause unpredictable behavior and should 31 | // only be used as a last resort. 32 | TermDbGetFallbackInfo func(termDb *TermDb) *TermInfo 33 | ) 34 | 35 | func TermDbDetect(termDb *TermDb, envp []string) *TermInfo { 36 | ptrs := make([]*byte, len(envp)) 37 | allocated := make([][]byte, len(envp)) 38 | 39 | for i, s := range envp { 40 | cstr := append([]byte(s), 0) 41 | allocated[i] = cstr 42 | ptrs[i] = &cstr[0] 43 | } 44 | 45 | ptrBlock := make([]uintptr, len(ptrs)) 46 | for i, p := range ptrs { 47 | ptrBlock[i] = uintptr(unsafe.Pointer(p)) 48 | } 49 | 50 | return termDbDetect(termDb, (**byte)(unsafe.Pointer(&ptrBlock[0]))) 51 | } 52 | 53 | type TermDb struct { 54 | Refs int32 55 | } 56 | -------------------------------------------------------------------------------- /terminfo.go: -------------------------------------------------------------------------------- 1 | package chafa 2 | 3 | var ( 4 | // Creates a new, blank [TermInfo]. 5 | TermInfoNew func() *TermInfo 6 | 7 | // Creates a new [TermInfo] that's a copy of termInfo. 8 | TermInfoCopy func(termInfo *TermInfo) *TermInfo 9 | 10 | // Adds a reference to termInfo. 11 | TermInfoRef func(termInfo *TermInfo) 12 | 13 | // Removes a reference from termInfo. 14 | TermInfoUnref func(termInfo *TermInfo) 15 | 16 | // Gets the string equivalent of seq stored in termInfo. 17 | TermInfoGetSeq func(termInfo *TermInfo, seq TermSeq) string 18 | 19 | // Sets the control sequence string equivalent of seq stored in termInfo to str. 20 | // 21 | // The string may contain argument indexes to be substituted with integers on 22 | // formatting. The indexes are preceded by a percentage character and 23 | // start at 1, i.e. %1, %2, %3, etc. 24 | // 25 | // The string's length after formatting must not exceed [CHAFA_TERM_SEQ_LENGTH_MAX] bytes. 26 | // Each argument can add up to four digits, or three for those specified as 8-bit integers. 27 | // If the string could potentially exceed this length when formatted, 28 | // [TermInfoSetSeq] will return FALSE. 29 | // 30 | // If parsing fails or str is too long, any previously existing sequence will be left untouched. 31 | // 32 | // Passing NULL for str clears the corresponding control sequence. 33 | TermInfoSetSeq func(termInfo *TermInfo, seq TermSeq, str string, err **GError) bool // TODO: 34 | 35 | // Checks if termInfo can emit seq. 36 | TermInfoHaveSeq func(termInfo *TermInfo, seq TermSeq) bool 37 | 38 | // Formats the terminal sequence seq, inserting positional arguments. 39 | // The seq's number of arguments must be supplied exactly. 40 | // 41 | // The argument list must be terminated by -1, or undefined behavior will result. 42 | // 43 | // If the wrong number of arguments is supplied, or an argument is out of range, 44 | // this function will return NULL. Otherwise, it returns a zero-terminated string 45 | // that must be freed with g_free(). 46 | // 47 | // If you want compile-time validation of arguments, consider using one of 48 | // the specific chafa_term_info_emit_*() functions. They are also faster, 49 | // but require you to allocate at least [CHAFA_TERM_SEQ_LENGTH_MAX] bytes up front. 50 | TermInfoEmitSeq func(termInfo *TermInfo, seq TermSeq, args ...any) string 51 | 52 | // Attempts to parse a terminal sequence from an input data array. 53 | // If successful, [CHAFA_PARSE_SUCCESS] will be returned, the input pointer 54 | // will be advanced and the parsed length will be subtracted from inputLen. 55 | TermInfoParseSeq func( 56 | term_info *TermInfo, 57 | seq TermSeq, 58 | input []string, 59 | inputLen *int32, 60 | argsOut *uint32, 61 | ) ParseResult 62 | 63 | // Supplements missing sequences in termInfo with ones copied from source. 64 | TermInfoSupplement func(termInfo, source *TermInfo) 65 | 66 | // Prints the control sequence for [CHAFA_TERM_SEQ_RESET_TERMINAL_SOFT]. 67 | // 68 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 69 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 70 | TermInfoEmitResetTerminalSoft func(termInfo *TermInfo, dest *string) string 71 | 72 | // Prints the control sequence for [CHAFA_TERM_SEQ_RESET_TERMINAL_HARD]. 73 | // 74 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 75 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 76 | TermInfoEmitResetTerminalHard func(termInfo *TermInfo, dest *string) string 77 | 78 | // Prints the control sequence for [CHAFA_TERM_SEQ_RESET_ATTRIBUTES]. 79 | // 80 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 81 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 82 | TermInfoEmitResetAttributes func(termInfo *TermInfo, dest *string) string 83 | 84 | // Prints the control sequence for [CHAFA_TERM_SEQ_CLEAR]. 85 | // 86 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 87 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 88 | TermInfoEmitClear func(termInfo *TermInfo, dest *string) string 89 | 90 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_TO_POS]. 91 | // 92 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 93 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 94 | TermInfoEmitCursorToPos func(termInfo *TermInfo, dest *string, x, y uint32) string 95 | 96 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_TO_TOP_LEFT]. 97 | // 98 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 99 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 100 | TermInfoEmitCursorToTopLeft func(termInfo *TermInfo, dest *string) string 101 | 102 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_TO_BOTTOM_LEFT]. 103 | // 104 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 105 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 106 | TermInfoEmitCursorToBottomLeft func(termInfo *TermInfo, dest *string) string 107 | 108 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_UP]. 109 | // 110 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 111 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 112 | TermInfoEmitCursorUp func(termInfo *TermInfo, dest *string, n uint32) string 113 | 114 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_DOWN]. 115 | // 116 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 117 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 118 | TermInfoEmitCursorDown func(termInfo *TermInfo, dest *string, n uint32) string 119 | 120 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_LEFT]. 121 | // 122 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 123 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 124 | TermInfoEmitCursorLeft func(termInfo *TermInfo, dest *string, n uint32) string 125 | 126 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_RIGHT]. 127 | // 128 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 129 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 130 | TermInfoEmitCursorRight func(termInfo *TermInfo, dest *string, n uint32) string 131 | 132 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_UP_1]. 133 | // 134 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 135 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 136 | TermInfoEmitCursorUp1 func(termInfo *TermInfo, dest *string) string 137 | 138 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_DOWN_1]. 139 | // 140 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 141 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 142 | TermInfoEmitCursorDown1 func(termInfo *TermInfo, dest *string) string 143 | 144 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_LEFT_1]. 145 | // 146 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 147 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 148 | TermInfoEmitCursorLeft1 func(termInfo *TermInfo, dest *string) string 149 | 150 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_RIGHT_1]. 151 | // 152 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 153 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 154 | TermInfoEmitCursorRight1 func(termInfo *TermInfo, dest *string) string 155 | 156 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_UP_SCROLL]. 157 | // 158 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 159 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 160 | TermInfoEmitCursorUpScroll func(termInfo *TermInfo, dest *string) string 161 | 162 | // Prints the control sequence for [CHAFA_TERM_SEQ_CURSOR_DOWN_SCROLL]. 163 | // 164 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 165 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 166 | TermInfoEmitCursorDownScroll func(termInfo *TermInfo, dest *string) string 167 | 168 | // Prints the control sequence for [CHAFA_TERM_SEQ_INSERT_CELLS]. 169 | // 170 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 171 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 172 | TermInfoEmitInsertCells func(termInfo *TermInfo, dest *string, n uint32) string 173 | 174 | // Prints the control sequence for [CHAFA_TERM_SEQ_DELETE_CELLS]. 175 | // 176 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 177 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 178 | TermInfoEmitDeleteCells func(termInfo *TermInfo, dest *string, n uint32) string 179 | 180 | // Prints the control sequence for [CHAFA_TERM_SEQ_INSERT_ROWS]. 181 | // 182 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 183 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 184 | TermInfoEmitInsertRows func(termInfo *TermInfo, dest *string, n uint32) string 185 | 186 | // Prints the control sequence for [CHAFA_TERM_SEQ_DELETE_ROWS]. 187 | // 188 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 189 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 190 | TermInfoEmitDeleteRows func(termInfo *TermInfo, dest *string, n uint32) string 191 | 192 | // Prints the control sequence for [CHAFA_TERM_SEQ_ENABLE_CURSOR]. 193 | // 194 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 195 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 196 | TermInfoEmitEnableCursor func(termInfo *TermInfo, dest *string) string 197 | 198 | // Prints the control sequence for [CHAFA_TERM_SEQ_DISABLE_CURSOR]. 199 | // 200 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 201 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 202 | TermInfoEmitDisableCursor func(termInfo *TermInfo, dest *string) string 203 | 204 | // Prints the control sequence for [CHAFA_TERM_SEQ_ENABLE_ECHO]. 205 | // 206 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 207 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 208 | TermInfoEmitEnableEcho func(termInfo *TermInfo, dest *string) string 209 | 210 | // Prints the control sequence for [CHAFA_TERM_SEQ_DISABLE_ECHO]. 211 | // 212 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 213 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 214 | TermInfoEmitDisableEcho func(termInfo *TermInfo, dest *string) string 215 | 216 | // Prints the control sequence for [CHAFA_TERM_SEQ_ENABLE_INSERT]. 217 | // 218 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 219 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 220 | TermInfoEmitEnableInsert func(termInfo *TermInfo, dest *string) string 221 | 222 | // Prints the control sequence for [CHAFA_TERM_SEQ_DISABLE_INSERT]. 223 | // 224 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 225 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 226 | TermInfoEmitDisableInsert func(termInfo *TermInfo, dest *string) string 227 | 228 | // Prints the control sequence for [CHAFA_TERM_SEQ_ENABLE_WRAP]. 229 | // 230 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 231 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 232 | TermInfoEmitEnableWrap func(termInfo *TermInfo, dest *string) string 233 | 234 | // Prints the control sequence for [CHAFA_TERM_SEQ_DISABLE_WRAP]. 235 | // 236 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 237 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 238 | TermInfoEmitDisableWrap func(termInfo *TermInfo, dest *string) string 239 | 240 | // Prints the control sequence for [CHAFA_TERM_SEQ_ENABLE_BOLD]. 241 | // 242 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 243 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 244 | TermInfoEmitEnableBold func(termInfo *TermInfo, dest *string) string 245 | 246 | // Prints the control sequence for [CHAFA_TERM_SEQ_INVERT_COLORS]. 247 | // 248 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 249 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 250 | TermInfoEmitInvertColors func(termInfo *TermInfo, dest *string) string 251 | 252 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_BG_8]. 253 | // 254 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 255 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 256 | TermInfoEmitSetColorBg8 func(termInfo *TermInfo, dest *string, pen uint8) string 257 | 258 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_FG_8]. 259 | // 260 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 261 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 262 | TermInfoEmitSetColorFg8 func(termInfo *TermInfo, dest *string, pen uint8) string 263 | 264 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_FGBG_8]. 265 | // 266 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 267 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 268 | TermInfoEmitSetColorFgbg8 func(termInfo *TermInfo, dest *string, fgPen, bgPen uint8) string 269 | 270 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_FG_16]. 271 | // 272 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 273 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 274 | TermInfoEmitSetColorFg16 func(termInfo *TermInfo, dest *string, pen uint8) string 275 | 276 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_BG_16]. 277 | // 278 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 279 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 280 | TermInfoEmitSetColorBg16 func(termInfo *TermInfo, dest *string, pen uint8) string 281 | 282 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_FGBG_16]. 283 | // 284 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 285 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 286 | TermInfoEmitSetColorFgbg16 func(termInfo *TermInfo, dest *string, fgPen, bgPen uint8) string 287 | 288 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_FG_256]. 289 | // 290 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 291 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 292 | TermInfoEmitSetColorFg256 func(termInfo *TermInfo, dest *string, pen uint8) string 293 | 294 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_BG_256]. 295 | // 296 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 297 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 298 | TermInfoEmitSetColorBg256 func(termInfo *TermInfo, dest *string, pen uint8) string 299 | 300 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_FGBG_256]. 301 | // 302 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 303 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 304 | TermInfoEmitSetColorFgbg256 func(termInfo *TermInfo, dest *string, fgPen, bgPen uint8) string 305 | 306 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_FG_DIRECT]. 307 | // 308 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 309 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 310 | TermInfoEmitSetColorFgDirect func(termInfo *TermInfo, dest *string, r, g, b uint8) string 311 | 312 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_BG_DIRECT]. 313 | // 314 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 315 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 316 | TermInfoEmitSetColorBgDirect func(termInfo *TermInfo, dest *string, r, g, b uint8) string 317 | 318 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_COLOR_FGBG_DIRECT]. 319 | // 320 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 321 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 322 | TermInfoEmitSetColorFgbgDirect func(termInfo *TermInfo, dest *string, fgR, fgG, fgB, bgR, bgG, bgB uint8) string 323 | 324 | // Prints the control sequence for [CHAFA_TERM_SEQ_RESET_COLOR_FG]. 325 | // 326 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 327 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 328 | TermInfoEmitResetColorFg func(termInfo *TermInfo, dest *string) string 329 | 330 | // Prints the control sequence for [CHAFA_TERM_SEQ_RESET_COLOR_BG]. 331 | // 332 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 333 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 334 | TermInfoEmitResetColorBg func(termInfo *TermInfo, dest *string) string 335 | 336 | // Prints the control sequence for [CHAFA_TERM_SEQ_RESET_COLOR_FGBG]. 337 | // 338 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 339 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 340 | TermInfoEmitResetColorFgbg func(termInfo *TermInfo, dest *string) string 341 | 342 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_DEFAULT_FG]. 343 | // 344 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 345 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 346 | TermInfoEmitSetDefaultFg func(termInfo *TermInfo, dest *string, r, g, b uint16) string 347 | 348 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_DEFAULT_BG]. 349 | // 350 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 351 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 352 | TermInfoEmitSetDefaultBg func(termInfo *TermInfo, dest *string, r, g, b uint16) string 353 | 354 | // Prints the control sequence for [CHAFA_TERM_SEQ_RESET_DEFAULT_FG]. 355 | // 356 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 357 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 358 | TermInfoEmitResetDefaultFg func(termInfo *TermInfo, dest *string) string 359 | 360 | // Prints the control sequence for [CHAFA_TERM_SEQ_RESET_DEFAULT_BG]. 361 | // 362 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 363 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 364 | TermInfoEmitResetDefaultBg func(termInfo *TermInfo, dest *string) string 365 | 366 | // Prints the control sequence for [CHAFA_TERM_SEQ_QUERY_DEFAULT_FG]. 367 | // 368 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 369 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 370 | TermInfoEmitQueryDefaultFg func(termInfo *TermInfo, dest *string) string 371 | 372 | // Prints the control sequence for [CHAFA_TERM_SEQ_QUERY_DEFAULT_BG]. 373 | // 374 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 375 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 376 | TermInfoEmitQueryDefaultBg func(termInfo *TermInfo, dest *string) string 377 | 378 | // Prints the control sequence for [CHAFA_TERM_SEQ_REPEAT_CHAR]. 379 | // 380 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 381 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 382 | TermInfoEmitRepeatChar func(termInfo *TermInfo, dest *string, n uint8) string 383 | 384 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_SCROLLING_ROWS]. 385 | // 386 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 387 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 388 | TermInfoEmitSetScrollingRows func(termInfo *TermInfo, dest *string, top, bottom uint8) string 389 | 390 | // Prints the control sequence for [CHAFA_TERM_SEQ_RESET_SCROLLING_ROWS]. 391 | // 392 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 393 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 394 | TermInfoEmitResetScrollingRows func(termInfo *TermInfo, dest *string) string 395 | 396 | // Prints the control sequence for [CHAFA_TERM_SEQ_SAVE_CURSOR_POS]. 397 | // 398 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 399 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 400 | TermInfoEmitSaveCursorPos func(termInfo *TermInfo, dest *string) string 401 | 402 | // Prints the control sequence for [CHAFA_TERM_SEQ_RESTORE_CURSOR_POS]. 403 | // 404 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 405 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 406 | TermInfoEmitRestoreCursorPos func(termInfo *TermInfo, dest *string) string 407 | 408 | // Prints the control sequence for [CHAFA_TERM_SEQ_BEGIN_SIXELS]. 409 | // 410 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 411 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 412 | // 413 | // All three parameters (p1 , p2 and p3 ) can normally be set to 0. 414 | TermInfoEmitBeginSixels func(termInfo *TermInfo, dest *string, p1, p2, p3 uint8) string 415 | 416 | // Prints the control sequence for [CHAFA_TERM_SEQ_END_SIXELS]. 417 | // 418 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 419 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 420 | TermInfoEmitEndSixels func(termInfo *TermInfo, dest *string) string 421 | 422 | // Prints the control sequence for [CHAFA_TERM_SEQ_ENABLE_SIXEL_SCROLLING]. 423 | // 424 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 425 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 426 | TermInfoEmitEnableSixelScrolling func(termInfo *TermInfo, dest *string) string 427 | 428 | // Prints the control sequence for [CHAFA_TERM_SEQ_DISABLE_SIXEL_SCROLLING]. 429 | // 430 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 431 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 432 | TermInfoEmitDisableSixelScrolling func(termInfo *TermInfo, dest *string) string 433 | 434 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_DOWN]. 435 | // 436 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 437 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 438 | TermInfoEmitSetSixelAdvanceDown func(termInfo *TermInfo, dest *string) string 439 | 440 | // Prints the control sequence for [CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_RIGHT]. 441 | // 442 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 443 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 444 | TermInfoEmitSetSixelAdvanceRight func(termInfo *TermInfo, dest *string) string 445 | 446 | // Prints the control sequence for [CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1]. 447 | // 448 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 449 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 450 | // 451 | // bpp must be set to either 24 for RGB data, 32 for RGBA, or 100 to embed a PNG file. 452 | // 453 | // This sequence must be followed by zero or more paired sequences of type 454 | // [CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK] and [CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK] 455 | // with base-64 encoded image data between them. 456 | // 457 | // When the image data has been transferred, [CHAFA_TERM_SEQ_END_KITTY_IMAGE] must be emitted. 458 | TermInfoEmitBeginKittyImmediateImageV1 func( 459 | termInfo *TermInfo, 460 | dest *string, 461 | bpp, widthPixels, heightPixels, widthCells, heightCells uint8, 462 | ) string 463 | 464 | // Prints the control sequence for [CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1]. 465 | // 466 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 467 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 468 | // 469 | // bpp must be set to either 24 for RGB data, 32 for RGBA, or 100 to embed a PNG file. 470 | // 471 | // This sequence must be followed by zero or more paired sequences of type 472 | // [CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK] and [CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK] 473 | // with base-64 encoded image data between them. 474 | // 475 | // When the image data has been transferred, [CHAFA_TERM_SEQ_END_KITTY_IMAGE] must be emitted. 476 | TermInfoEmitBeginKittyImmediateVirtImageV1 func( 477 | termInfo *TermInfo, 478 | dest *string, 479 | bpp, widthPixels, heightPixels, widthCells, heightCells, id uint8, 480 | ) string 481 | 482 | // Prints the control sequence for [CHAFA_TERM_SEQ_END_KITTY_IMAGE]. 483 | // 484 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 485 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 486 | TermInfoEmitEndKittyImage func(termInfo *TermInfo, dest *string) string 487 | 488 | // Prints the control sequence for [CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK]. 489 | // 490 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 491 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 492 | TermInfoEmitBeginKittyImageChunk func(termInfo *TermInfo, dest *string) string 493 | 494 | // Prints the control sequence for [CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK]. 495 | // 496 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 497 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 498 | TermInfoEmitEndKittyImageChunk func(termInfo *TermInfo, dest *string) string 499 | 500 | // Prints the control sequence for [CHAFA_TERM_SEQ_BEGIN_ITERM2_IMAGE]. 501 | // 502 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 503 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 504 | // 505 | // This sequence must be followed by base64-encoded image file data. The image 506 | // can be any format supported by MacOS, e.g. PNG, JPEG, TIFF, GIF. When the 507 | // image data has been transferred, [CHAFA_TERM_SEQ_END_ITERM2_IMAGE] must be emitted. 508 | TermInfoEmitBeginIterm2Image func(termInfo *TermInfo, dest *string, width, height uint8) string 509 | 510 | // Prints the control sequence for [CHAFA_TERM_SEQ_END_ITERM2_IMAGE]. 511 | // 512 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 513 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 514 | TermInfoEmitEndIterm2Image func(termInfo *TermInfo, dest *string) string 515 | 516 | // Prints the control sequence for [CHAFA_TERM_SEQ_BEGIN_SCREEN_PASSTHROUGH]. 517 | // 518 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 519 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 520 | // 521 | // Any control sequences between the beginning and end passthrough seqs must 522 | // be escaped by turning \033 into \033\033. 523 | TermInfoEmitBeginScreenPassthrough func(termInfo *TermInfo, dest *string) string 524 | 525 | // Prints the control sequence for [CHAFA_TERM_SEQ_END_SCREEN_PASSTHROUGH]. 526 | // 527 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 528 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 529 | // 530 | // Any control sequences between the beginning and end passthrough seqs must 531 | // be escaped by turning \033 into \033\033. 532 | TermInfoEmitEndScreenPassthrough func(termInfo *TermInfo, dest *string) string 533 | 534 | // Prints the control sequence for [CHAFA_TERM_SEQ_ENABLE_ALT_SCREEN]. 535 | // 536 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 537 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 538 | TermInfoEmitEnableAltScreen func(termInfo *TermInfo, dest *string) string 539 | 540 | // Prints the control sequence for [CHAFA_TERM_SEQ_DISABLE_ALT_SCREEN]. 541 | // 542 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 543 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 544 | TermInfoEmitDisableAltScreen func(termInfo *TermInfo, dest *string) string 545 | 546 | // Prints the control sequence for [CHAFA_TERM_SEQ_BEGIN_TMUX_PASSTHROUGH]. 547 | // 548 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 549 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 550 | // 551 | // Any control sequences between the beginning and end passthrough seqs must 552 | // be escaped by turning \033 into \033\033. 553 | TermInfoEmitBeginTmuxPassthrough func(termInfo *TermInfo, dest *string) string 554 | 555 | // Prints the control sequence for [CHAFA_TERM_SEQ_END_TMUX_PASSTHROUGH]. 556 | // 557 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 558 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 559 | // 560 | // Any control sequences between the beginning and end passthrough seqs must 561 | // be escaped by turning \033 into \033\033. 562 | TermInfoEmitEndTmuxPassthrough func(termInfo *TermInfo, dest *string) string 563 | 564 | // Prints the control sequence for [CHAFA_TERM_SEQ_RETURN_KEY]. 565 | // 566 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 567 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 568 | TermInfoEmitReturnKey func(termInfo *TermInfo, dest *string) string 569 | 570 | // Prints the control sequence for [CHAFA_TERM_SEQ_BACKSPACE_KEY]. 571 | // 572 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 573 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 574 | TermInfoEmitBackspaceKey func(termInfo *TermInfo, dest *string) string 575 | 576 | // Prints the control sequence for [CHAFA_TERM_SEQ_DELETE_KEY]. 577 | // 578 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 579 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 580 | TermInfoEmitDeleteKey func(termInfo *TermInfo, dest *string) string 581 | 582 | // Prints the control sequence for [CHAFA_TERM_SEQ_DELETE_CTRL_KEY]. 583 | // 584 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 585 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 586 | TermInfoEmitDeleteCtrlKey func(termInfo *TermInfo, dest *string) string 587 | 588 | // Prints the control sequence for [CHAFA_TERM_SEQ_DELETE_SHIFT_KEY]. 589 | // 590 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 591 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 592 | TermInfoEmitDeleteShiftKey func(termInfo *TermInfo, dest *string) string 593 | 594 | // Prints the control sequence for [CHAFA_TERM_SEQ_INSERT_KEY]. 595 | // 596 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 597 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 598 | TermInfoEmitInsertKey func(termInfo *TermInfo, dest *string) string 599 | 600 | // Prints the control sequence for [CHAFA_TERM_SEQ_INSERT_CTRL_KEY]. 601 | // 602 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 603 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 604 | TermInfoEmitInsertCtrlKey func(termInfo *TermInfo, dest *string) string 605 | 606 | // Prints the control sequence for [CHAFA_TERM_SEQ_INSERT_SHIFT_KEY]. 607 | // 608 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 609 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 610 | TermInfoEmitInsertShiftKey func(termInfo *TermInfo, dest *string) string 611 | 612 | // Prints the control sequence for [CHAFA_TERM_SEQ_HOME_KEY]. 613 | // 614 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 615 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 616 | TermInfoEmitHomeKey func(termInfo *TermInfo, dest *string) string 617 | 618 | // Prints the control sequence for [CHAFA_TERM_SEQ_HOME_CTRL_KEY]. 619 | // 620 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 621 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 622 | TermInfoEmitHomeCtrlKey func(termInfo *TermInfo, dest *string) string 623 | 624 | // Prints the control sequence for [CHAFA_TERM_SEQ_HOME_CTRL_KEY]. 625 | // 626 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 627 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 628 | TermInfoEmitHomeShiftKey func(termInfo *TermInfo, dest *string) string 629 | 630 | // Prints the control sequence for [CHAFA_TERM_SEQ_END_KEY]. 631 | // 632 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 633 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 634 | TermInfoEmitEndKey func(termInfo *TermInfo, dest *string) string 635 | 636 | // Prints the control sequence for [CHAFA_TERM_SEQ_END_CTRL_KEY]. 637 | // 638 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 639 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 640 | TermInfoEmitEndCtrlKey func(termInfo *TermInfo, dest *string) string 641 | 642 | // Prints the control sequence for [CHAFA_TERM_SEQ_END_SHIFT_KEY]. 643 | // 644 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 645 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 646 | TermInfoEmitEndShiftKey func(termInfo *TermInfo, dest *string) string 647 | 648 | // Prints the control sequence for [CHAFA_TERM_SEQ_UP_KEY]. 649 | // 650 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 651 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 652 | TermInfoEmitUpKey func(termInfo *TermInfo, dest *string) string 653 | 654 | // Prints the control sequence for [CHAFA_TERM_SEQ_UP_KEY]. 655 | // 656 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 657 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 658 | TermInfoEmitUpCtrlKey func(termInfo *TermInfo, dest *string) string 659 | 660 | // Prints the control sequence for [CHAFA_TERM_SEQ_UP_SHIFT_KEY]. 661 | // 662 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 663 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 664 | TermInfoEmitUpShiftKey func(termInfo *TermInfo, dest *string) string 665 | 666 | // Prints the control sequence for [CHAFA_TERM_SEQ_DOWN_KEY]. 667 | // 668 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 669 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 670 | TermInfoEmitDownKey func(termInfo *TermInfo, dest *string) string 671 | 672 | // Prints the control sequence for [CHAFA_TERM_SEQ_DOWN_CTRL_KEY]. 673 | // 674 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 675 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 676 | TermInfoEmitDownCtrlKey func(termInfo *TermInfo, dest *string) string 677 | 678 | // Prints the control sequence for [CHAFA_TERM_SEQ_DOWN_SHIFT_KEY]. 679 | // 680 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 681 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 682 | TermInfoEmitDownShiftKey func(termInfo *TermInfo, dest *string) string 683 | 684 | // Prints the control sequence for [CHAFA_TERM_SEQ_LEFT_KEY]. 685 | // 686 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 687 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 688 | TermInfoEmitLeftKey func(termInfo *TermInfo, dest *string) string 689 | 690 | // Prints the control sequence for [CHAFA_TERM_SEQ_LEFT_CTRL_KEY]. 691 | // 692 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 693 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 694 | TermInfoEmitLeftCtrlKey func(termInfo *TermInfo, dest *string) string 695 | 696 | // Prints the control sequence for [CHAFA_TERM_SEQ_LEFT_SHIFT_KEY]. 697 | // 698 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 699 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 700 | TermInfoEmitLeftShiftKey func(termInfo *TermInfo, dest *string) string 701 | 702 | // Prints the control sequence for [CHAFA_TERM_SEQ_RIGHT_KEY]. 703 | // 704 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 705 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 706 | TermInfoEmitRightKey func(termInfo *TermInfo, dest *string) string 707 | 708 | // Prints the control sequence for [CHAFA_TERM_SEQ_RIGHT_CTRL_KEY]. 709 | // 710 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 711 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 712 | TermInfoEmitRightCtrlKey func(termInfo *TermInfo, dest *string) string 713 | 714 | // Prints the control sequence for [CHAFA_TERM_SEQ_RIGHT_SHIFT_KEY]. 715 | // 716 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 717 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 718 | TermInfoEmitRightShiftKey func(termInfo *TermInfo, dest *string) string 719 | 720 | // Prints the control sequence for [CHAFA_TERM_SEQ_PAGE_UP_KEY]. 721 | // 722 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 723 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 724 | TermInfoEmitPageUpKey func(termInfo *TermInfo, dest *string) string 725 | 726 | // Prints the control sequence for [CHAFA_TERM_SEQ_PAGE_UP_CTRL_KEY]. 727 | // 728 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 729 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 730 | TermInfoEmitPageUpCtrlKey func(termInfo *TermInfo, dest *string) string 731 | 732 | // Prints the control sequence for [CHAFA_TERM_SEQ_PAGE_UP_SHIFT_KEY]. 733 | // 734 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 735 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 736 | TermInfoEmitPageUpShiftKey func(termInfo *TermInfo, dest *string) string 737 | 738 | // Prints the control sequence for [CHAFA_TERM_SEQ_PAGE_DOWN_KEY]. 739 | // 740 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 741 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 742 | TermInfoEmitPageDownKey func(termInfo *TermInfo, dest *string) string 743 | 744 | // Prints the control sequence for [CHAFA_TERM_SEQ_PAGE_DOWN_CTRL_KEY]. 745 | // 746 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 747 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 748 | TermInfoEmitPageDownCtrlKey func(termInfo *TermInfo, dest *string) string 749 | 750 | // Prints the control sequence for [CHAFA_TERM_SEQ_PAGE_DOWN_CTRL_KEY]. 751 | // 752 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 753 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 754 | TermInfoEmitPageDownShiftKey func(termInfo *TermInfo, dest *string) string 755 | 756 | // Prints the control sequence for [CHAFA_TERM_SEQ_TAB_KEY]. 757 | // 758 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 759 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 760 | TermInfoEmitTabKey func(termInfo *TermInfo, dest *string) string 761 | 762 | // Prints the control sequence for [CHAFA_TERM_SEQ_TAB_SHIFT_KEY]. 763 | // 764 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 765 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 766 | TermInfoEmitTabShiftKey func(termInfo *TermInfo, dest *string) string 767 | 768 | // Prints the control sequence for [CHAFA_TERM_SEQ_F1_KEY]. 769 | // 770 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 771 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 772 | TermInfoEmitF1Key func(termInfo *TermInfo, dest *string) string 773 | 774 | // Prints the control sequence for [CHAFA_TERM_SEQ_F1_CTRL_KEY]. 775 | // 776 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 777 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 778 | TermInfoEmitF1CtrlKey func(termInfo *TermInfo, dest *string) string 779 | 780 | // Prints the control sequence for [CHAFA_TERM_SEQ_F1_SHIFT_KEY]. 781 | // 782 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 783 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 784 | TermInfoEmitF1ShiftKey func(termInfo *TermInfo, dest *string) string 785 | 786 | // Prints the control sequence for [CHAFA_TERM_SEQ_F2_KEY]. 787 | // 788 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 789 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 790 | TermInfoEmitF2Key func(termInfo *TermInfo, dest *string) string 791 | 792 | // Prints the control sequence for [CHAFA_TERM_SEQ_F2_CTRL_KEY]. 793 | // 794 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 795 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 796 | TermInfoEmitF2CtrlKey func(termInfo *TermInfo, dest *string) string 797 | 798 | // Prints the control sequence for [CHAFA_TERM_SEQ_F2_SHIFT_KEY]. 799 | // 800 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 801 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 802 | TermInfoEmitF2ShiftKey func(termInfo *TermInfo, dest *string) string 803 | 804 | // Prints the control sequence for [CHAFA_TERM_SEQ_F3_KEY]. 805 | // 806 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 807 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 808 | TermInfoEmitF3Key func(termInfo *TermInfo, dest *string) string 809 | 810 | // Prints the control sequence for [CHAFA_TERM_SEQ_F3_CTRL_KEY]. 811 | // 812 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 813 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 814 | TermInfoEmitF3CtrlKey func(termInfo *TermInfo, dest *string) string 815 | 816 | // Prints the control sequence for [CHAFA_TERM_SEQ_F3_SHIFT_KEY]. 817 | // 818 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 819 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 820 | TermInfoEmitF3ShiftKey func(termInfo *TermInfo, dest *string) string 821 | 822 | // Prints the control sequence for [CHAFA_TERM_SEQ_F4_KEY]. 823 | // 824 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 825 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 826 | TermInfoEmitF4Key func(termInfo *TermInfo, dest *string) string 827 | 828 | // Prints the control sequence for [CHAFA_TERM_SEQ_F4_CTRL_KEY]. 829 | // 830 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 831 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 832 | TermInfoEmitF4CtrlKey func(termInfo *TermInfo, dest *string) string 833 | 834 | // Prints the control sequence for [CHAFA_TERM_SEQ_F4_SHIFT_KEY]. 835 | // 836 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 837 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 838 | TermInfoEmitF4ShiftKey func(termInfo *TermInfo, dest *string) string 839 | 840 | // Prints the control sequence for [CHAFA_TERM_SEQ_F5_KEY]. 841 | // 842 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 843 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 844 | TermInfoEmitF5Key func(termInfo *TermInfo, dest *string) string 845 | 846 | // Prints the control sequence for [CHAFA_TERM_SEQ_F5_CTRL_KEY]. 847 | // 848 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 849 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 850 | TermInfoEmitF5CtrlKey func(termInfo *TermInfo, dest *string) string 851 | 852 | // Prints the control sequence for [CHAFA_TERM_SEQ_F5_SHIFT_KEY]. 853 | // 854 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 855 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 856 | TermInfoEmitF5ShiftKey func(termInfo *TermInfo, dest *string) string 857 | 858 | // Prints the control sequence for [CHAFA_TERM_SEQ_F6_KEY]. 859 | // 860 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 861 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 862 | TermInfoEmitF6Key func(termInfo *TermInfo, dest *string) string 863 | 864 | // Prints the control sequence for [CHAFA_TERM_SEQ_F6_CTRL_KEY]. 865 | // 866 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 867 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 868 | TermInfoEmitF6CtrlKey func(termInfo *TermInfo, dest *string) string 869 | 870 | // Prints the control sequence for [CHAFA_TERM_SEQ_F6_SHIFT_KEY]. 871 | // 872 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 873 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 874 | TermInfoEmitF6ShiftKey func(termInfo *TermInfo, dest *string) string 875 | 876 | // Prints the control sequence for [CHAFA_TERM_SEQ_F7_KEY]. 877 | // 878 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 879 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 880 | TermInfoEmitF7Key func(termInfo *TermInfo, dest *string) string 881 | 882 | // Prints the control sequence for [CHAFA_TERM_SEQ_F7_CTRL_KEY]. 883 | // 884 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 885 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 886 | TermInfoEmitF7CtrlKey func(termInfo *TermInfo, dest *string) string 887 | 888 | // Prints the control sequence for [CHAFA_TERM_SEQ_F7_SHIFT_KEY]. 889 | // 890 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 891 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 892 | TermInfoEmitF7ShiftKey func(termInfo *TermInfo, dest *string) string 893 | 894 | // Prints the control sequence for [CHAFA_TERM_SEQ_F8_KEY]. 895 | // 896 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 897 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 898 | TermInfoEmitF8Key func(termInfo *TermInfo, dest *string) string 899 | 900 | // Prints the control sequence for [CHAFA_TERM_SEQ_F8_CTRL_KEY]. 901 | // 902 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 903 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 904 | TermInfoEmitF8CtrlKey func(termInfo *TermInfo, dest *string) string 905 | 906 | // Prints the control sequence for [CHAFA_TERM_SEQ_F8_SHIFT_KEY]. 907 | // 908 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 909 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 910 | TermInfoEmitF8ShiftKey func(termInfo *TermInfo, dest *string) string 911 | 912 | // Prints the control sequence for [CHAFA_TERM_SEQ_F9_KEY]. 913 | // 914 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 915 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 916 | TermInfoEmitF9Key func(termInfo *TermInfo, dest *string) string 917 | 918 | // Prints the control sequence for [CHAFA_TERM_SEQ_F9_CTRL_KEY]. 919 | // 920 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 921 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 922 | TermInfoEmitF9CtrlKey func(termInfo *TermInfo, dest *string) string 923 | 924 | // Prints the control sequence for [CHAFA_TERM_SEQ_F9_SHIFT_KEY]. 925 | // 926 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 927 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 928 | TermInfoEmitF9ShiftKey func(termInfo *TermInfo, dest *string) string 929 | 930 | // Prints the control sequence for [CHAFA_TERM_SEQ_F10_KEY]. 931 | // 932 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 933 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 934 | TermInfoEmitF10Key func(termInfo *TermInfo, dest *string) string 935 | 936 | // Prints the control sequence for [CHAFA_TERM_SEQ_F10_CTRL_KEY]. 937 | // 938 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 939 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 940 | TermInfoEmitF10CtrlKey func(termInfo *TermInfo, dest *string) string 941 | 942 | // Prints the control sequence for [CHAFA_TERM_SEQ_F10_SHIFT_KEY]. 943 | // 944 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 945 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 946 | TermInfoEmitF10ShiftKey func(termInfo *TermInfo, dest *string) string 947 | 948 | // Prints the control sequence for [CHAFA_TERM_SEQ_F11_KEY]. 949 | // 950 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 951 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 952 | TermInfoEmitF11Key func(termInfo *TermInfo, dest *string) string 953 | 954 | // Prints the control sequence for [CHAFA_TERM_SEQ_F11_CTRL_KEY]. 955 | // 956 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 957 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 958 | TermInfoEmitF11CtrlKey func(termInfo *TermInfo, dest *string) string 959 | 960 | // Prints the control sequence for [CHAFA_TERM_SEQ_F11_SHIFT_KEY]. 961 | // 962 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 963 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 964 | TermInfoEmitF11ShiftKey func(termInfo *TermInfo, dest *string) string 965 | 966 | // Prints the control sequence for [CHAFA_TERM_SEQ_F12_KEY]. 967 | // 968 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 969 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 970 | TermInfoEmitF12Key func(termInfo *TermInfo, dest *string) string 971 | 972 | // Prints the control sequence for [CHAFA_TERM_SEQ_F12_CTRL_KEY]. 973 | // 974 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 975 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 976 | TermInfoEmitF12CtrlKey func(termInfo *TermInfo, dest *string) string 977 | 978 | // Prints the control sequence for [CHAFA_TERM_SEQ_F12_SHIFT_KEY]. 979 | // 980 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 981 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 982 | TermInfoEmitF12ShiftKey func(termInfo *TermInfo, dest *string) string 983 | 984 | // Terminal emulators and applications are often nested, with the inner 985 | // application's capabilities limiting, extending or modifying the outer's. 986 | // 987 | // Examples are terminal multiplexers like Screen and tmux, or terminal 988 | // emulators running inside editors like Emacs and vi. 989 | // 990 | // This merges the outer and inner sequences into a single [ChafaTermInfo] 991 | // according to the following rules. 992 | // 993 | // For sequences marked as inherited in inner: 994 | // 995 | // - If either inner or outer sequence is nil, pick the outer sequence. 996 | // - Otherwise, pick inner sequence. 997 | // 998 | // For sequences not marked as inherited, always use the inner sequence. 999 | // 1000 | // This allows for using the inner term's sequences while clearing them if 1001 | // the outer term does not support the sequence at all. This is useful for 1002 | // muxers (e.g. fbterm supports 256 colors, but with private seqs; we want to 1003 | // use the inner mux' corresponding seqs). 1004 | // 1005 | // The merged [TermInfo] is a new instance, with the initial reference owned 1006 | // by the caller. 1007 | // 1008 | // This function can be used repeatedly to create chains that're arbitrarily long, 1009 | // but is unlikely to be useful beyond three levels 1010 | // (terminal emulator, multiplexer, application). 1011 | TermInfoChain func(outer, inner *TermInfo) *TermInfo 1012 | 1013 | // Prints the control sequence for [CHAFA_TERM_SEQ_CELL_SIZE_PX]. 1014 | // 1015 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 1016 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 1017 | TermInfoEmitCellSizePx func(termInfo *TermInfo, dest *string, heightPx, widthPx uint32) string 1018 | 1019 | // Prints the control sequence for [CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES]. 1020 | // 1021 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 1022 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 1023 | TermInfoEmitPrimaryDeviceAttributes func(termInfo *TermInfo, dest *string, args *uint32, nArgs int32) string 1024 | 1025 | // Prints the control sequence for [CHAFA_TERM_SEQ_QUERY_CELL_SIZE_PX]. 1026 | // 1027 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 1028 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 1029 | TermInfoEmitQueryCellSizePx func(termInfo *TermInfo, dest *string) string 1030 | 1031 | // Prints the control sequence for [CHAFA_TERM_SEQ_QUERY_PRIMARY_DEVICE_ATTRIBUTES]. 1032 | // 1033 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 1034 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 1035 | TermInfoEmitQueryPrimaryDeviceAttributes func(termInfo *TermInfo, dest *string) string 1036 | 1037 | // Prints the control sequence for [CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_CELLS]. 1038 | // 1039 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX bytes], 1040 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 1041 | TermInfoEmitQueryTextAreaSizeCells func(termInfo *TermInfo, dest *string) string 1042 | 1043 | // Prints the control sequence for [CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_PX]. 1044 | // 1045 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 1046 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 1047 | TermInfoEmitQueryTextAreaSizePx func(termInfo *TermInfo, dest *string) string 1048 | 1049 | // Behaves like [TermInfoEmitSeq] 1050 | TermInfoEmitSeqValist func(termInfo *TermInfo, seq TermSeq, args ...any) string 1051 | 1052 | // Prints the control sequence for [CHAFA_TERM_SEQ_TEXT_AREA_SIZE_CELLS]. 1053 | // 1054 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX bytes], 1055 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 1056 | TermInfoEmitTextAreaSizeCells func(termInfo *TermInfo, dest *string, heightCells, widthCells uint32) string 1057 | 1058 | // Prints the control sequence for [CHAFA_TERM_SEQ_TEXT_AREA_SIZE_PX]. 1059 | // 1060 | // dest must have enough space to hold [CHAFA_TERM_SEQ_LENGTH_MAX] bytes, 1061 | // even if the emitted sequence is shorter. The output will not be zero-terminated. 1062 | TermInfoEmitTextAreaSizePx func(termInfo *TermInfo, dest *string, heightPx, widthPx uint32) string 1063 | 1064 | // Gets the optimal [CanvasMode] supported by termInfo. 1065 | TermInfoGetBestCanvasMode func(termInfo *TermInfo) CanvasMode 1066 | 1067 | // Gets the optimal [PixelMode] supported by termInfo. 1068 | TermInfoGetBestPixelMode func(termInfo *TermInfo) PixelMode 1069 | 1070 | // Gets whether seq can be inherited from the outer [TermInfo] when chaining 1071 | // with [TermInfoChain]. 1072 | TermInfoGetInheritSeq func(termInfo *TermInfo, seq TermSeq) bool 1073 | 1074 | // Gets if passthrough should be used to convey images in pixel_mode. 1075 | // If needed, the passthrough type can be gotten from [TermInfoGetPassthroughType]. 1076 | TermInfoGetIsPixelPassthroughNeeded func(termInfo *TermInfo, pixelMode PixelMode) bool 1077 | 1078 | // Gets the name associated with the termInfo. This may be nil. The returned 1079 | // string belongs to termInfo, and is only valid until the next operation on 1080 | // this data structure. 1081 | TermInfoGetName func(termInfo *TermInfo) string 1082 | 1083 | // Gets the passthrough mode supported by termInfo. 1084 | TermInfoGetPassthroughType func(termInfo *TermInfo) Passthrough 1085 | 1086 | // Gets the quirks associated with termInfo. 1087 | TermInfoGetQuirks func(termInfo *TermInfo) TermQuirks 1088 | 1089 | // Gets the [SymbolTags] that are likely safe to use with termInfo. 1090 | // The [SymbolTags] are a bitwise OR of flags from the enum. 1091 | TermInfoGetSafeSymbolTags func(termInfo *TermInfo) SymbolTags 1092 | 1093 | // Checks if termInfo has terminal sequences that support canvasMode. 1094 | TermInfoIsCanvasModeSupported func(termInfo *TermInfo, canvasMode CanvasMode) bool 1095 | 1096 | // Checks if termInfo has terminal sequences that support pixelMode. 1097 | TermInfoIsPixelModeSupported func(termInfo *TermInfo, pixelMode PixelMode) bool 1098 | 1099 | // Attempts to parse a terminal sequence from an input data array. If successful, 1100 | // [CHAFA_PARSE_SUCCESS] will be returned, the input pointer will be advanced 1101 | // and the parsed length will be subtracted from inputLen. 1102 | // 1103 | // Any numeric parsed arguments are returned as an array starting at argsOut , 1104 | // which must have room for up to [CHAFA_TERM_SEQ_ARGS_MAX] elements. 1105 | // 1106 | // The number of parsed arguments is returned in nArgsOut. This is useful for 1107 | // seqs with a variable number of arguments, like 1108 | // [CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES]. 1109 | // 1110 | // Either or both of argsOut and nArgsOut can be NULL, in which case nothing 1111 | // is returned for that parameter. 1112 | TermInfoParseSeqVarargs func( 1113 | term_info *TermInfo, 1114 | seq TermSeq, 1115 | input []string, 1116 | inputLen *int32, 1117 | argsOut *uint32, 1118 | nArgsOut *int32, 1119 | ) ParseResult 1120 | 1121 | // Sets whether seq can be inherited from the outer [TermInfo] when chaining 1122 | // with [TermInfoChain]. 1123 | TermInfoSetInheritSeq func(termInfo *TermInfo, seq TermSeq, inherit bool) 1124 | 1125 | // Specifies if passthrough should be used to convey images in pixelMode. 1126 | TermInfoSetIsPixelPassthroughNeeded func(termInfo *TermInfo, pixelMode PixelMode, pixelPassthroughNeeded bool) 1127 | 1128 | // Assigns a new name to termInfo. The name should be a short lowercase ASCII 1129 | // string that uniquely identifies the terminal or program described by termInfo. 1130 | TermInfoSetName func(termInfo *TermInfo, name string) 1131 | 1132 | // Assigns a set of quirks to termInfo. 1133 | TermInfoSetQuirks func(termInfo *TermInfo, quirks TermQuirks) 1134 | 1135 | // Sets the [SymbolTags] that are likely safe to use with termInfo. 1136 | // The tags are a bitwise OR of flags from the enum. 1137 | TermInfoSetSafeSymbolTags func(termInfo *TermInfo, tags SymbolTags) 1138 | ) 1139 | 1140 | type TermInfo struct { 1141 | Refs int32 1142 | Name string 1143 | SeqStr [CHAFA_TERM_SEQ_MAX][CHAFA_TERM_SEQ_LENGTH_MAX]byte 1144 | SeqArgs [CHAFA_TERM_SEQ_MAX][CHAFA_TERM_SEQ_ARGS_MAX]SeqArgInfo 1145 | UnparsedStr [CHAFA_TERM_SEQ_MAX]string 1146 | PixelPassthroughNeeded [CHAFA_PIXEL_MODE_MAX]uint8 1147 | InheritSeq [CHAFA_TERM_SEQ_MAX]uint8 1148 | Quirks TermQuirks 1149 | SafeSymbolTags SymbolTags 1150 | } 1151 | 1152 | type SeqArgInfo struct { 1153 | IsVarargs bool 1154 | PreLen uint8 1155 | ArgIndex uint8 1156 | } 1157 | 1158 | type TermSeq int32 1159 | 1160 | const ( 1161 | CHAFA_TERM_SEQ_RESET_TERMINAL_SOFT TermSeq = 0 1162 | CHAFA_TERM_SEQ_RESET_TERMINAL_HARD TermSeq = 1 1163 | CHAFA_TERM_SEQ_RESET_ATTRIBUTES TermSeq = 2 1164 | CHAFA_TERM_SEQ_CLEAR TermSeq = 3 1165 | CHAFA_TERM_SEQ_INVERT_COLORS TermSeq = 4 1166 | CHAFA_TERM_SEQ_CURSOR_TO_TOP_LEFT TermSeq = 5 1167 | CHAFA_TERM_SEQ_CURSOR_TO_BOTTOM_LEFT TermSeq = 6 1168 | CHAFA_TERM_SEQ_CURSOR_TO_POS TermSeq = 7 1169 | CHAFA_TERM_SEQ_CURSOR_UP_1 TermSeq = 8 1170 | CHAFA_TERM_SEQ_CURSOR_UP TermSeq = 9 1171 | CHAFA_TERM_SEQ_CURSOR_DOWN_1 TermSeq = 10 1172 | CHAFA_TERM_SEQ_CURSOR_DOWN TermSeq = 11 1173 | CHAFA_TERM_SEQ_CURSOR_LEFT_1 TermSeq = 12 1174 | CHAFA_TERM_SEQ_CURSOR_LEFT TermSeq = 13 1175 | CHAFA_TERM_SEQ_CURSOR_RIGHT_1 TermSeq = 14 1176 | CHAFA_TERM_SEQ_CURSOR_RIGHT TermSeq = 15 1177 | CHAFA_TERM_SEQ_CURSOR_UP_SCROLL TermSeq = 16 1178 | CHAFA_TERM_SEQ_CURSOR_DOWN_SCROLL TermSeq = 17 1179 | CHAFA_TERM_SEQ_INSERT_CELLS TermSeq = 18 1180 | CHAFA_TERM_SEQ_DELETE_CELLS TermSeq = 19 1181 | CHAFA_TERM_SEQ_INSERT_ROWS TermSeq = 20 1182 | CHAFA_TERM_SEQ_DELETE_ROWS TermSeq = 21 1183 | CHAFA_TERM_SEQ_SET_SCROLLING_ROWS TermSeq = 22 1184 | CHAFA_TERM_SEQ_ENABLE_INSERT TermSeq = 23 1185 | CHAFA_TERM_SEQ_DISABLE_INSERT TermSeq = 24 1186 | CHAFA_TERM_SEQ_ENABLE_CURSOR TermSeq = 25 1187 | CHAFA_TERM_SEQ_DISABLE_CURSOR TermSeq = 26 1188 | CHAFA_TERM_SEQ_ENABLE_ECHO TermSeq = 27 1189 | CHAFA_TERM_SEQ_DISABLE_ECHO TermSeq = 28 1190 | CHAFA_TERM_SEQ_ENABLE_WRAP TermSeq = 29 1191 | CHAFA_TERM_SEQ_DISABLE_WRAP TermSeq = 30 1192 | CHAFA_TERM_SEQ_SET_COLOR_FG_DIRECT TermSeq = 31 1193 | CHAFA_TERM_SEQ_SET_COLOR_BG_DIRECT TermSeq = 32 1194 | CHAFA_TERM_SEQ_SET_COLOR_FGBG_DIRECT TermSeq = 33 1195 | CHAFA_TERM_SEQ_SET_COLOR_FG_256 TermSeq = 34 1196 | CHAFA_TERM_SEQ_SET_COLOR_BG_256 TermSeq = 35 1197 | CHAFA_TERM_SEQ_SET_COLOR_FGBG_256 TermSeq = 36 1198 | CHAFA_TERM_SEQ_SET_COLOR_FG_16 TermSeq = 37 1199 | CHAFA_TERM_SEQ_SET_COLOR_BG_16 TermSeq = 38 1200 | CHAFA_TERM_SEQ_SET_COLOR_FGBG_16 TermSeq = 39 1201 | CHAFA_TERM_SEQ_BEGIN_SIXELS TermSeq = 40 1202 | CHAFA_TERM_SEQ_END_SIXELS TermSeq = 41 1203 | CHAFA_TERM_SEQ_REPEAT_CHAR TermSeq = 42 1204 | CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1 TermSeq = 43 1205 | CHAFA_TERM_SEQ_END_KITTY_IMAGE TermSeq = 44 1206 | CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK TermSeq = 45 1207 | CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK TermSeq = 46 1208 | CHAFA_TERM_SEQ_BEGIN_ITERM2_IMAGE TermSeq = 47 1209 | CHAFA_TERM_SEQ_END_ITERM2_IMAGE TermSeq = 48 1210 | CHAFA_TERM_SEQ_ENABLE_SIXEL_SCROLLING TermSeq = 49 1211 | CHAFA_TERM_SEQ_DISABLE_SIXEL_SCROLLING TermSeq = 50 1212 | CHAFA_TERM_SEQ_ENABLE_BOLD TermSeq = 51 1213 | CHAFA_TERM_SEQ_SET_COLOR_FG_8 TermSeq = 52 1214 | CHAFA_TERM_SEQ_SET_COLOR_BG_8 TermSeq = 53 1215 | CHAFA_TERM_SEQ_SET_COLOR_FGBG_8 TermSeq = 54 1216 | CHAFA_TERM_SEQ_RESET_DEFAULT_FG TermSeq = 55 1217 | CHAFA_TERM_SEQ_SET_DEFAULT_FG TermSeq = 56 1218 | CHAFA_TERM_SEQ_QUERY_DEFAULT_FG TermSeq = 57 1219 | CHAFA_TERM_SEQ_RESET_DEFAULT_BG TermSeq = 58 1220 | CHAFA_TERM_SEQ_SET_DEFAULT_BG TermSeq = 59 1221 | CHAFA_TERM_SEQ_QUERY_DEFAULT_BG TermSeq = 60 1222 | CHAFA_TERM_SEQ_RETURN_KEY TermSeq = 61 1223 | CHAFA_TERM_SEQ_BACKSPACE_KEY TermSeq = 62 1224 | CHAFA_TERM_SEQ_TAB_KEY TermSeq = 63 1225 | CHAFA_TERM_SEQ_TAB_SHIFT_KEY TermSeq = 64 1226 | CHAFA_TERM_SEQ_UP_KEY TermSeq = 65 1227 | CHAFA_TERM_SEQ_UP_CTRL_KEY TermSeq = 66 1228 | CHAFA_TERM_SEQ_UP_SHIFT_KEY TermSeq = 67 1229 | CHAFA_TERM_SEQ_DOWN_KEY TermSeq = 68 1230 | CHAFA_TERM_SEQ_DOWN_CTRL_KEY TermSeq = 69 1231 | CHAFA_TERM_SEQ_DOWN_SHIFT_KEY TermSeq = 70 1232 | CHAFA_TERM_SEQ_LEFT_KEY TermSeq = 71 1233 | CHAFA_TERM_SEQ_LEFT_CTRL_KEY TermSeq = 72 1234 | CHAFA_TERM_SEQ_LEFT_SHIFT_KEY TermSeq = 73 1235 | CHAFA_TERM_SEQ_RIGHT_KEY TermSeq = 74 1236 | CHAFA_TERM_SEQ_RIGHT_CTRL_KEY TermSeq = 75 1237 | CHAFA_TERM_SEQ_RIGHT_SHIFT_KEY TermSeq = 76 1238 | CHAFA_TERM_SEQ_PAGE_UP_KEY TermSeq = 77 1239 | CHAFA_TERM_SEQ_PAGE_UP_CTRL_KEY TermSeq = 78 1240 | CHAFA_TERM_SEQ_PAGE_UP_SHIFT_KEY TermSeq = 79 1241 | CHAFA_TERM_SEQ_PAGE_DOWN_KEY TermSeq = 80 1242 | CHAFA_TERM_SEQ_PAGE_DOWN_CTRL_KEY TermSeq = 81 1243 | CHAFA_TERM_SEQ_PAGE_DOWN_SHIFT_KEY TermSeq = 82 1244 | CHAFA_TERM_SEQ_HOME_KEY TermSeq = 83 1245 | CHAFA_TERM_SEQ_HOME_CTRL_KEY TermSeq = 84 1246 | CHAFA_TERM_SEQ_HOME_SHIFT_KEY TermSeq = 85 1247 | CHAFA_TERM_SEQ_END_KEY TermSeq = 86 1248 | CHAFA_TERM_SEQ_END_CTRL_KEY TermSeq = 87 1249 | CHAFA_TERM_SEQ_END_SHIFT_KEY TermSeq = 88 1250 | CHAFA_TERM_SEQ_INSERT_KEY TermSeq = 89 1251 | CHAFA_TERM_SEQ_INSERT_CTRL_KEY TermSeq = 90 1252 | CHAFA_TERM_SEQ_INSERT_SHIFT_KEY TermSeq = 91 1253 | CHAFA_TERM_SEQ_DELETE_KEY TermSeq = 92 1254 | CHAFA_TERM_SEQ_DELETE_CTRL_KEY TermSeq = 93 1255 | CHAFA_TERM_SEQ_DELETE_SHIFT_KEY TermSeq = 94 1256 | CHAFA_TERM_SEQ_F1_KEY TermSeq = 95 1257 | CHAFA_TERM_SEQ_F1_CTRL_KEY TermSeq = 96 1258 | CHAFA_TERM_SEQ_F1_SHIFT_KEY TermSeq = 97 1259 | CHAFA_TERM_SEQ_F2_KEY TermSeq = 98 1260 | CHAFA_TERM_SEQ_F2_CTRL_KEY TermSeq = 99 1261 | CHAFA_TERM_SEQ_F2_SHIFT_KEY TermSeq = 100 1262 | CHAFA_TERM_SEQ_F3_KEY TermSeq = 101 1263 | CHAFA_TERM_SEQ_F3_CTRL_KEY TermSeq = 102 1264 | CHAFA_TERM_SEQ_F3_SHIFT_KEY TermSeq = 103 1265 | CHAFA_TERM_SEQ_F4_KEY TermSeq = 104 1266 | CHAFA_TERM_SEQ_F4_CTRL_KEY TermSeq = 105 1267 | CHAFA_TERM_SEQ_F4_SHIFT_KEY TermSeq = 106 1268 | CHAFA_TERM_SEQ_F5_KEY TermSeq = 107 1269 | CHAFA_TERM_SEQ_F5_CTRL_KEY TermSeq = 108 1270 | CHAFA_TERM_SEQ_F5_SHIFT_KEY TermSeq = 109 1271 | CHAFA_TERM_SEQ_F6_KEY TermSeq = 110 1272 | CHAFA_TERM_SEQ_F6_CTRL_KEY TermSeq = 111 1273 | CHAFA_TERM_SEQ_F6_SHIFT_KEY TermSeq = 112 1274 | CHAFA_TERM_SEQ_F7_KEY TermSeq = 113 1275 | CHAFA_TERM_SEQ_F7_CTRL_KEY TermSeq = 114 1276 | CHAFA_TERM_SEQ_F7_SHIFT_KEY TermSeq = 115 1277 | CHAFA_TERM_SEQ_F8_KEY TermSeq = 116 1278 | CHAFA_TERM_SEQ_F8_CTRL_KEY TermSeq = 117 1279 | CHAFA_TERM_SEQ_F8_SHIFT_KEY TermSeq = 118 1280 | CHAFA_TERM_SEQ_F9_KEY TermSeq = 119 1281 | CHAFA_TERM_SEQ_F9_CTRL_KEY TermSeq = 120 1282 | CHAFA_TERM_SEQ_F9_SHIFT_KEY TermSeq = 121 1283 | CHAFA_TERM_SEQ_F10_KEY TermSeq = 122 1284 | CHAFA_TERM_SEQ_F10_CTRL_KEY TermSeq = 123 1285 | CHAFA_TERM_SEQ_F10_SHIFT_KEY TermSeq = 124 1286 | CHAFA_TERM_SEQ_F11_KEY TermSeq = 125 1287 | CHAFA_TERM_SEQ_F11_CTRL_KEY TermSeq = 126 1288 | CHAFA_TERM_SEQ_F11_SHIFT_KEY TermSeq = 127 1289 | CHAFA_TERM_SEQ_F12_KEY TermSeq = 128 1290 | CHAFA_TERM_SEQ_F12_CTRL_KEY TermSeq = 129 1291 | CHAFA_TERM_SEQ_F12_SHIFT_KEY TermSeq = 130 1292 | CHAFA_TERM_SEQ_RESET_COLOR_FG TermSeq = 131 1293 | CHAFA_TERM_SEQ_RESET_COLOR_BG TermSeq = 132 1294 | CHAFA_TERM_SEQ_RESET_COLOR_FGBG TermSeq = 133 1295 | CHAFA_TERM_SEQ_RESET_SCROLLING_ROWS TermSeq = 134 1296 | CHAFA_TERM_SEQ_SAVE_CURSOR_POS TermSeq = 135 1297 | CHAFA_TERM_SEQ_RESTORE_CURSOR_POS TermSeq = 136 1298 | CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_DOWN TermSeq = 137 1299 | CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_RIGHT TermSeq = 138 1300 | CHAFA_TERM_SEQ_ENABLE_ALT_SCREEN TermSeq = 139 1301 | CHAFA_TERM_SEQ_DISABLE_ALT_SCREEN TermSeq = 140 1302 | CHAFA_TERM_SEQ_BEGIN_SCREEN_PASSTHROUGH TermSeq = 141 1303 | CHAFA_TERM_SEQ_END_SCREEN_PASSTHROUGH TermSeq = 142 1304 | CHAFA_TERM_SEQ_BEGIN_TMUX_PASSTHROUGH TermSeq = 143 1305 | CHAFA_TERM_SEQ_END_TMUX_PASSTHROUGH TermSeq = 144 1306 | CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_VIRT_IMAGE_V1 TermSeq = 145 1307 | CHAFA_TERM_SEQ_QUERY_PRIMARY_DEVICE_ATTRIBUTES TermSeq = 146 1308 | CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES TermSeq = 147 1309 | CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_CELLS TermSeq = 148 1310 | CHAFA_TERM_SEQ_TEXT_AREA_SIZE_CELLS TermSeq = 149 1311 | CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_PX TermSeq = 150 1312 | CHAFA_TERM_SEQ_TEXT_AREA_SIZE_PX TermSeq = 151 1313 | CHAFA_TERM_SEQ_QUERY_CELL_SIZE_PX TermSeq = 152 1314 | CHAFA_TERM_SEQ_CELL_SIZE_PX TermSeq = 153 1315 | CHAFA_TERM_SEQ_MAX TermSeq = 154 1316 | ) 1317 | 1318 | const CHAFA_TERM_SEQ_LENGTH_MAX = 96 1319 | 1320 | const CHAFA_TERM_SEQ_ARGS_MAX = 24 1321 | 1322 | type TermQuirks int32 1323 | 1324 | const ( 1325 | CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT TermQuirks = (1 << 0) 1326 | ) 1327 | 1328 | type ParseResult int32 1329 | 1330 | const ( 1331 | CHAFA_PARSE_SUCCESS ParseResult = 0 1332 | CHAFA_PARSE_FAILURE ParseResult = 1 1333 | CHAFA_PARSE_AGAIN ParseResult = 2 1334 | ) 1335 | --------------------------------------------------------------------------------