├── .github └── workflows │ └── build.yml ├── .gitignore ├── .resources ├── images │ ├── mde_banner_v1.18.png │ ├── vtm.ico │ └── vtm.rc └── status │ ├── arch_any.svg │ ├── arch_arm32.svg │ ├── arch_arm64.svg │ ├── arch_x86.svg │ ├── arch_x86_64.svg │ ├── freebsd.svg │ ├── linux.svg │ ├── macos.svg │ ├── netbsd.svg │ ├── openbsd.svg │ └── windows.svg ├── CMakeLists.txt ├── CMakeSettings.json ├── LICENSE ├── doc ├── apps.md ├── architecture.md ├── build.md ├── character_geometry.md ├── command-line-options.md ├── images │ ├── A_1x1.png │ ├── E_2x2.png │ ├── deva_2x1_glyph_run_transparent.png │ ├── deva_3x1.png │ ├── vtm_character_geometry_modifiers_16x4.png │ ├── vtm_character_geometry_modifiers_16x4.xhtml │ ├── vtm_character_geometry_modifiers_screenshot.png │ └── vtm_character_geometry_modifiers_summary.png ├── panel.md ├── settings.md ├── user-interface.md └── vt-input-mode.md ├── readme.md └── src ├── netxs ├── apps.hpp ├── apps │ ├── calc.cpp │ ├── calc.hpp │ ├── desk.hpp │ ├── shop.hpp │ ├── term.cpp │ ├── term.hpp │ ├── test.hpp │ ├── text.hpp │ └── tile.hpp └── desktopio │ ├── ansivt.hpp │ ├── application.hpp │ ├── baseui.hpp │ ├── canvas.hpp │ ├── console.hpp │ ├── consrv.hpp │ ├── controls.hpp │ ├── directvt.hpp │ ├── events.hpp │ ├── gcscale.md │ ├── generics.hpp │ ├── geometry.hpp │ ├── gui.hpp │ ├── input.hpp │ ├── intmath.hpp │ ├── logger.hpp │ ├── macrogen.hpp │ ├── ptr.hpp │ ├── quartz.hpp │ ├── richtext.hpp │ ├── system.hpp │ ├── terminal.hpp │ ├── unidata.hpp │ ├── unidatagen.py │ ├── utf.hpp │ └── xml.hpp ├── vtm.cpp ├── vtm.hpp └── vtm.xml /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build binaries 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | build: 11 | name: ${{ matrix.platform }} / ${{ matrix.cpu }} 12 | runs-on: ${{ matrix.os }} 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | os: [ windows-latest, ubuntu-latest ] 17 | cpu: [ x64, x86, arm64, arm ] 18 | exclude: 19 | - os: windows-latest 20 | cpu: x86 21 | - os: windows-latest 22 | cpu: arm 23 | include: 24 | - os: macos-latest 25 | platform: macos 26 | cpu: universal 27 | arch: any 28 | cxx: c++ 29 | cc: cc 30 | flags: '-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 -DCMAKE_CXX_FLAGS_RELEASE="-O2 -DNDEBUG -Wall -Wextra -Wno-missing-field-initializers -Werror"' 31 | - os: windows-latest 32 | platform: windows 33 | cpu: Win32 34 | arch: x86 35 | cxx: cl 36 | cc: cl 37 | flags: '-DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" -DCMAKE_EXE_LINKER_FLAGS_RELEASE="/DEBUG /OPT:REF /OPT:ICF" -DCMAKE_C_FLAGS_RELEASE="/MT /O2 /c" -DCMAKE_CXX_FLAGS_RELEASE="/MT /O2 /DNDEBUG /Zi /Zc:preprocessor /W4" -A ' 38 | - os: windows-latest 39 | cxx: cl 40 | - os: ubuntu-latest 41 | cpu: x64 42 | cxx: g++ 43 | cc: gcc 44 | - os: ubuntu-latest 45 | cpu: x86 46 | apt: g++-i686-linux-gnu gcc-i686-linux-gnu 47 | cxx: /bin/i686-linux-gnu-g++ 48 | cc: /bin/i686-linux-gnu-gcc 49 | - os: ubuntu-latest 50 | cpu: arm 51 | apt: g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf 52 | cxx: /bin/arm-linux-gnueabihf-g++ 53 | cc: /bin/arm-linux-gnueabihf-gcc 54 | - os: ubuntu-latest 55 | cpu: arm64 56 | apt: g++-aarch64-linux-gnu gcc-aarch64-linux-gnu 57 | cxx: /bin/aarch64-linux-gnu-g++ 58 | cc: /bin/aarch64-linux-gnu-gcc 59 | 60 | - os: ubuntu-latest 61 | flags: '-DCMAKE_C_FLAGS="-O2 -static" -DCMAKE_CXX_FLAGS_RELEASE="-static -s -O2 -DNDEBUG -Wall -Wextra -Wno-missing-field-initializers -Wno-psabi -Werror"' 62 | - os: windows-latest 63 | flags: '-DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" -DCMAKE_EXE_LINKER_FLAGS_RELEASE="/DEBUG /OPT:REF /OPT:ICF" -DCMAKE_C_FLAGS_RELEASE="/MT /O2 /c" -DCMAKE_CXX_FLAGS_RELEASE="/MT /O2 /DNDEBUG /Zi /Zc:preprocessor /W4" -A ' 64 | 65 | - os: ubuntu-latest 66 | platform: linux 67 | - os: windows-latest 68 | platform: windows 69 | 70 | - cpu: x64 71 | arch: x86_64 72 | - cpu: x86 73 | arch: x86 74 | - cpu: arm64 75 | arch: arm64 76 | - cpu: arm 77 | arch: arm32 78 | 79 | steps: 80 | - uses: actions/checkout@main 81 | 82 | - name: Set reusable strings 83 | id: strings 84 | shell: bash 85 | run: | 86 | echo "bin=${{ github.workspace }}/bin" >> "$GITHUB_OUTPUT" 87 | 88 | - name: Install compiler 89 | if: ${{ matrix.apt }} 90 | run: > 91 | sudo apt -y update && sudo apt -y install ${{ matrix.apt }} 92 | 93 | - name: Configure CMake 94 | run: > 95 | cmake -B ${{ steps.strings.outputs.bin }} 96 | -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} 97 | -DCMAKE_C_COMPILER=${{ matrix.cc }} 98 | ${{ matrix.flags }} ${{ matrix.os == 'windows-latest' && matrix.cpu || '' }} 99 | -DCMAKE_BUILD_TYPE=Release 100 | -S ${{ github.workspace }} 101 | 102 | - name: Build 103 | run: cmake --build ${{ steps.strings.outputs.bin }} --config Release 104 | 105 | - name: Pack (POSIX) 106 | if: matrix.os != 'windows-latest' 107 | run: 7z a -ttar vtm_${{ matrix.platform }}_${{ matrix.arch }}.tar ${{ steps.strings.outputs.bin }}/vtm 108 | 109 | - name: Upload Artifact (POSIX) 110 | if: matrix.os != 'windows-latest' 111 | uses: actions/upload-artifact@main 112 | with: 113 | name: vtm_${{ matrix.platform }}_${{ matrix.arch }} 114 | path: vtm_${{ matrix.platform }}_${{ matrix.arch }}.tar 115 | 116 | - name: Upload Symbols (Windows) 117 | if: matrix.os == 'windows-latest' 118 | uses: actions/upload-artifact@main 119 | with: 120 | name: vtm_pdb_${{ matrix.platform }}_${{ matrix.arch }} 121 | path: ${{ steps.strings.outputs.bin }}/Release/vtm.pdb 122 | 123 | - name: Upload Artifact (Windows) 124 | if: matrix.os == 'windows-latest' 125 | uses: actions/upload-artifact@main 126 | with: 127 | name: vtm_${{ matrix.platform }}_${{ matrix.arch }} 128 | path: ${{ steps.strings.outputs.bin }}/Release/vtm.exe -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.vs 2 | /.vscode 3 | /bin 4 | /build 5 | -------------------------------------------------------------------------------- /.resources/images/mde_banner_v1.18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/directvt/vtm/0ec775643d927345ce62d81f4e89bcfd6e0c3035/.resources/images/mde_banner_v1.18.png -------------------------------------------------------------------------------- /.resources/images/vtm.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/directvt/vtm/0ec775643d927345ce62d81f4e89bcfd6e0c3035/.resources/images/vtm.ico -------------------------------------------------------------------------------- /.resources/images/vtm.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON_VTM ICON "vtm.ico" -------------------------------------------------------------------------------- /.resources/status/arch_any.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Universal 17 | Universal 19 | 20 | -------------------------------------------------------------------------------- /.resources/status/arch_arm32.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | ARM 17 | ARM 19 | 32-bit 21 | 32-bit 23 | 24 | -------------------------------------------------------------------------------- /.resources/status/arch_arm64.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | ARM 17 | ARM 19 | 64-bit 21 | 64-bit 23 | 24 | -------------------------------------------------------------------------------- /.resources/status/arch_x86.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Intel 17 | Intel 19 | 32-bit 21 | 32-bit 23 | 24 | -------------------------------------------------------------------------------- /.resources/status/arch_x86_64.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Intel 17 | Intel 19 | 64-bit 21 | 64-bit 23 | 24 | -------------------------------------------------------------------------------- /.resources/status/freebsd.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | FreeBSD 6 | 7 | -------------------------------------------------------------------------------- /.resources/status/linux.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | Linux 6 | 7 | -------------------------------------------------------------------------------- /.resources/status/macos.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | macOS 6 | 7 | -------------------------------------------------------------------------------- /.resources/status/netbsd.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | NetBSD 6 | 7 | -------------------------------------------------------------------------------- /.resources/status/openbsd.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | OpenBSD 6 | 7 | -------------------------------------------------------------------------------- /.resources/status/windows.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | Windows 6 | 7 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.24) 2 | 3 | project("vtm") 4 | # project("term") 5 | # project("calc") 6 | 7 | set(CMAKE_CXX_STANDARD 20) 8 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 9 | 10 | # Set the build type to Release if none is specified. 11 | if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") 12 | set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) 13 | endif() 14 | 15 | if(CMAKE_SYSTEM_NAME STREQUAL "Windows") # WIN32 and similar checks are soft-deprecated 16 | # Disable manifest embedding for the windows builds. 17 | # Reason: Anti-virus program (Windows Defender) may lock and scan `vtm.exe` file before embedding the manifest. 18 | # mt.exe: general error c101008d: Failed to write the updated manifest to the resource of file... 19 | #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") 20 | # /EHsc Tells the compiler that exceptions can only occur at a throw statement or at a function call. 21 | # /bigobj Our event model spawns a large number of objects. By default, an object file can hold up to 65,279 (almost 2^16) addressable sections. This limit applies no matter which target platform is specified. /bigobj increases that address capacity to 4,294,967,296 (2^32). 22 | # /utf-8 All literals in our source code are in UTF-8 format. 23 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2 /EHsc /bigobj /utf-8 /Zc:preprocessor") 24 | set(WIN32_RESOURCES ".resources/images/vtm.rc") 25 | else() 26 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -pthread") 27 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -DLUA_USE_POSIX") 28 | # Static linkage 29 | #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static -O2 -pthread") 30 | #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static -O2 -DLUA_USE_POSIX") 31 | endif() 32 | 33 | # Lua 34 | include(FetchContent) 35 | FetchContent_Declare(lua 36 | URL https://www.lua.org/ftp/lua-5.4.7.tar.gz 37 | URL_HASH SHA256=9fbf5e28ef86c69858f6d3d34eccc32e911c1a28b4120ff3e84aaa70cfbf1e30 38 | DOWNLOAD_EXTRACT_TIMESTAMP true) 39 | FetchContent_MakeAvailable(lua) 40 | file(GLOB lua_src CONFIGURE_DEPENDS ${lua_SOURCE_DIR}/src/*.c) 41 | list(REMOVE_ITEM lua_src ${lua_SOURCE_DIR}/src/lua.c ${lua_SOURCE_DIR}/src/luac.c) 42 | add_library(lua ${lua_src}) 43 | target_include_directories(lua PUBLIC ${lua_SOURCE_DIR}/src) 44 | target_sources(lua PRIVATE ${lua_src}) 45 | 46 | add_executable(vtm "src/vtm.cpp" ${WIN32_RESOURCES}) 47 | # add_executable(term "src/netxs/apps/term.cpp") 48 | # add_executable(calc "src/netxs/apps/calc.cpp") 49 | 50 | target_link_libraries(vtm lua) 51 | # target_link_libraries(term lua) 52 | # target_link_libraries(calc lua) 53 | 54 | if(NOT WIN32) 55 | install(TARGETS vtm DESTINATION bin) 56 | endif() 57 | -------------------------------------------------------------------------------- /CMakeSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "1.Win-x64-Debug", 5 | "generator": "Visual Studio 17 2022 Win64", 6 | "configurationType": "Debug", 7 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 8 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 9 | "cmakeCommandArgs": "", 10 | "buildCommandArgs": "", 11 | "ctestCommandArgs": "", 12 | "inheritEnvironments": [ "msvc_x64_x64" ], 13 | "variables": [ 14 | { 15 | "name": "CMAKE_CXX_FLAGS_DEBUG", 16 | "value": "/DDEBUG /MTd /Zi /Ob0 /Od /RTC1 /bigobj /utf-8 /Zc:preprocessor /W4", 17 | "type": "STRING" 18 | }, 19 | { 20 | "name": "CMAKE_C_FLAGS_DEBUG", 21 | "value": "/DDEBUG /MTd /c", 22 | "type": "STRING" 23 | }, 24 | { 25 | "name": "CMAKE_MSVC_RUNTIME_LIBRARY", 26 | "value": "MultiThreadedDebug", 27 | "type": "STRING" 28 | } 29 | ], 30 | "intelliSenseMode": "windows-msvc-x64" 31 | }, 32 | { 33 | "name": "2.WSL-x64-Debug", 34 | "generator": "Unix Makefiles", 35 | "configurationType": "Debug", 36 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 37 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 38 | "cmakeExecutable": "/usr/bin/cmake", 39 | "cmakeCommandArgs": "-S ../../", 40 | "buildCommandArgs": "", 41 | "ctestCommandArgs": "", 42 | "inheritEnvironments": [ "linux_x64" ], 43 | "wslPath": "${defaultWSLPath}", 44 | "addressSanitizerRuntimeFlags": "detect_leaks=0", 45 | "variables": [ 46 | { 47 | "name": "CMAKE_CXX_FLAGS_DEBUG", 48 | "value": "-O0 -DDEBUG -pthread -g -Wall -Wextra -Wno-missing-field-initializers", 49 | "type": "STRING" 50 | }, 51 | { 52 | "name": "CMAKE_C_FLAGS_DEBUG", 53 | "value": "-O0 -DDEBUG", 54 | "type": "STRING" 55 | }, 56 | { 57 | "name": "CMAKE_CXX_COMPILER", 58 | "value": "/bin/g++", 59 | "_comment": "/bin/clang++", 60 | "type": "STRING" 61 | }, 62 | { 63 | "name": "CMAKE_C_COMPILER", 64 | "value": "/bin/gcc", 65 | "_comment": "/bin/clang", 66 | "type": "STRING" 67 | } 68 | ], 69 | "intelliSenseMode": "linux-gcc-x64" 70 | }, 71 | { 72 | "name": "3.Win-x32-Debug", 73 | "generator": "Visual Studio 17 2022", 74 | "configurationType": "Debug", 75 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 76 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 77 | "cmakeCommandArgs": "", 78 | "buildCommandArgs": "", 79 | "ctestCommandArgs": "", 80 | "inheritEnvironments": [ "msvc_x86_x64" ], 81 | "variables": [ 82 | { 83 | "name": "CMAKE_CXX_FLAGS_DEBUG", 84 | "value": "/DDEBUG /MTd /Zi /Ob0 /Od /RTC1 /bigobj /utf-8 /Zc:preprocessor /W4", 85 | "type": "STRING" 86 | }, 87 | { 88 | "name": "CMAKE_C_FLAGS_DEBUG", 89 | "value": "/DDEBUG /MTd /c", 90 | "type": "STRING" 91 | }, 92 | { 93 | "name": "CMAKE_MSVC_RUNTIME_LIBRARY", 94 | "value": "MultiThreadedDebug", 95 | "type": "STRING" 96 | } 97 | ] 98 | }, 99 | { 100 | "name": "4.WSL-x32-Debug", 101 | "generator": "Unix Makefiles", 102 | "configurationType": "Debug", 103 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 104 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 105 | "cmakeExecutable": "/usr/bin/cmake", 106 | "cmakeCommandArgs": "-S ../../", 107 | "buildCommandArgs": "", 108 | "ctestCommandArgs": "", 109 | "inheritEnvironments": [ "linux_x86" ], 110 | "variables": [ 111 | { 112 | "name": "CMAKE_CXX_FLAGS_DEBUG", 113 | "value": "-O0 -static -DDEBUG -pthread -Wall -Wextra -Wno-missing-field-initializers", 114 | "type": "STRING" 115 | }, 116 | { 117 | "name": "CMAKE_C_FLAGS_DEBUG", 118 | "value": "-O0 -static -DDEBUG", 119 | "type": "STRING" 120 | }, 121 | { 122 | "name": "CMAKE_CXX_COMPILER", 123 | "value": "/bin/i686-linux-gnu-g++", 124 | "type": "STRING" 125 | }, 126 | { 127 | "name": "CMAKE_C_COMPILER", 128 | "value": "/bin/i686-linux-gnu-gcc", 129 | "type": "STRING" 130 | } 131 | ], 132 | "intelliSenseMode": "linux-gcc-x86", 133 | "wslPath": "${defaultWSLPath}", 134 | "addressSanitizerRuntimeFlags": "detect_leaks=0" 135 | }, 136 | { 137 | "name": "5.WSL-ARM64-Debug", 138 | "generator": "Unix Makefiles", 139 | "configurationType": "Debug", 140 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 141 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 142 | "cmakeExecutable": "/usr/bin/cmake", 143 | "cmakeCommandArgs": "-S ../../", 144 | "buildCommandArgs": "", 145 | "ctestCommandArgs": "", 146 | "inheritEnvironments": [ "linux_arm" ], 147 | "variables": [ 148 | { 149 | "name": "CMAKE_CXX_FLAGS_DEBUG", 150 | "value": "-O0 -DDEBUG -static -pthread -g", 151 | "type": "STRING" 152 | }, 153 | { 154 | "name": "CMAKE_C_FLAGS_DEBUG", 155 | "value": "-O0 -DDEBUG -static", 156 | "type": "STRING" 157 | }, 158 | { 159 | "name": "CMAKE_CXX_COMPILER", 160 | "value": "/bin/aarch64-linux-gnu-g++", 161 | "type": "STRING" 162 | }, 163 | { 164 | "name": "CMAKE_C_COMPILER", 165 | "value": "/bin/aarch64-linux-gnu-gcc", 166 | "type": "STRING" 167 | } 168 | ], 169 | "intelliSenseMode": "linux-gcc-arm", 170 | "wslPath": "${defaultWSLPath}", 171 | "addressSanitizerRuntimeFlags": "detect_leaks=0", 172 | "remoteCopyUseCompilerDefaults": true 173 | }, 174 | { 175 | "name": "PROD-Win-ARM32", 176 | "generator": "Visual Studio 17 2022 ARM", 177 | "configurationType": "Release", 178 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 179 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 180 | "cmakeCommandArgs": "", 181 | "buildCommandArgs": "", 182 | "ctestCommandArgs": "", 183 | "inheritEnvironments": [ "msvc_arm_x64" ], 184 | "variables": [ 185 | { 186 | "name": "CMAKE_CXX_FLAGS_RELEASE", 187 | "value": "/DNDEBUG /MT /O2 /EHsc /bigobj /utf-8 /Zc:preprocessor /W4", 188 | "type": "STRING" 189 | }, 190 | { 191 | "name": "CMAKE_C_FLAGS_RELEASE", 192 | "value": "/DNDEBUG /MT /O2 /c", 193 | "type": "STRING" 194 | }, 195 | { 196 | "name": "CMAKE_MSVC_RUNTIME_LIBRARY", 197 | "value": "MultiThreaded", 198 | "type": "STRING" 199 | } 200 | ], 201 | "intelliSenseMode": "windows-msvc-arm" 202 | }, 203 | { 204 | "name": "PROD-Win-ARM64", 205 | "generator": "Visual Studio 17 2022 ARM64", 206 | "configurationType": "Release", 207 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 208 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 209 | "cmakeCommandArgs": "", 210 | "buildCommandArgs": "", 211 | "ctestCommandArgs": "", 212 | "inheritEnvironments": [ "msvc_arm64_x64" ], 213 | "variables": [ 214 | { 215 | "name": "CMAKE_CXX_FLAGS_RELEASE", 216 | "value": "/DNDEBUG /MT /O2 /EHsc /bigobj /utf-8 /Zc:preprocessor /W4", 217 | "type": "STRING" 218 | }, 219 | { 220 | "name": "CMAKE_C_FLAGS_RELEASE", 221 | "value": "/DNDEBUG /MT /O2 /c", 222 | "type": "STRING" 223 | }, 224 | { 225 | "name": "CMAKE_MSVC_RUNTIME_LIBRARY", 226 | "value": "MultiThreaded", 227 | "type": "STRING" 228 | } 229 | ], 230 | "intelliSenseMode": "windows-msvc-arm64" 231 | }, 232 | { 233 | "name": "PROD-Win-x32", 234 | "generator": "Visual Studio 17 2022", 235 | "configurationType": "Release", 236 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 237 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 238 | "cmakeCommandArgs": "", 239 | "buildCommandArgs": "", 240 | "ctestCommandArgs": "", 241 | "inheritEnvironments": [ "msvc_x86_x64" ], 242 | "variables": [ 243 | { 244 | "name": "CMAKE_CXX_FLAGS_RELEASE", 245 | "value": "/DNDEBUG /MT /O2 /EHsc /bigobj /utf-8 /Zi /Zc:preprocessor /W4", 246 | "type": "STRING" 247 | }, 248 | { 249 | "name": "CMAKE_C_FLAGS_RELEASE", 250 | "value": "/DNDEBUG /MT /O2 /c", 251 | "type": "STRING" 252 | }, 253 | { 254 | "name": "CMAKE_EXE_LINKER_FLAGS_RELEASE", 255 | "value": "/DEBUG /OPT:REF /OPT:ICF", 256 | "type": "STRING" 257 | }, 258 | { 259 | "name": "CMAKE_MSVC_RUNTIME_LIBRARY", 260 | "value": "MultiThreaded", 261 | "type": "STRING" 262 | } 263 | ] 264 | }, 265 | { 266 | "name": "PROD-Win-x64", 267 | "generator": "Visual Studio 17 2022 Win64", 268 | "configurationType": "Release", 269 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 270 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 271 | "cmakeCommandArgs": "", 272 | "buildCommandArgs": "", 273 | "ctestCommandArgs": "", 274 | "inheritEnvironments": [ "msvc_x64_x64" ], 275 | "variables": [ 276 | { 277 | "name": "CMAKE_CXX_FLAGS_RELEASE", 278 | "value": "/DNDEBUG /MT /O2 /EHsc /bigobj /utf-8 /Zi /Zc:preprocessor /W4", 279 | "type": "STRING" 280 | }, 281 | { 282 | "name": "CMAKE_C_FLAGS_RELEASE", 283 | "value": "/DNDEBUG /MT /O2 /c", 284 | "type": "STRING" 285 | }, 286 | { 287 | "name": "DCMAKE_EXE_LINKER_FLAGS_RELEASE", 288 | "value": "/DEBUG /OPT:REF /OPT:ICF", 289 | "type": "STRING" 290 | }, 291 | { 292 | "name": "CMAKE_MSVC_RUNTIME_LIBRARY", 293 | "value": "MultiThreaded", 294 | "type": "STRING" 295 | } 296 | ] 297 | }, 298 | { 299 | "name": "PROD-WSL-ARM32", 300 | "generator": "Unix Makefiles", 301 | "configurationType": "Release", 302 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 303 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 304 | "cmakeExecutable": "/usr/bin/cmake", 305 | "cmakeCommandArgs": "-S ../../", 306 | "buildCommandArgs": "", 307 | "ctestCommandArgs": "", 308 | "inheritEnvironments": [ "linux_arm" ], 309 | "variables": [ 310 | { 311 | "name": "CMAKE_CXX_FLAGS_RELEASE", 312 | "value": "-O2 -DNDEBUG -static -pthread -s -Wno-psabi -Wall -Wextra -Wno-missing-field-initializers", 313 | "type": "STRING" 314 | }, 315 | { 316 | "name": "CMAKE_C_FLAGS_RELEASE", 317 | "value": "-O2 -DNDEBUG -static", 318 | "type": "STRING" 319 | }, 320 | { 321 | "name": "CMAKE_CXX_COMPILER", 322 | "value": "/bin/arm-linux-gnueabihf-g++", 323 | "type": "STRING" 324 | }, 325 | { 326 | "name": "CMAKE_C_COMPILER", 327 | "value": "/bin/arm-linux-gnueabihf-gcc", 328 | "type": "STRING" 329 | } 330 | ], 331 | "intelliSenseMode": "linux-gcc-arm", 332 | "wslPath": "${defaultWSLPath}", 333 | "addressSanitizerRuntimeFlags": "detect_leaks=0", 334 | "remoteCopyUseCompilerDefaults": true 335 | }, 336 | { 337 | "name": "PROD-WSL-ARM64", 338 | "generator": "Unix Makefiles", 339 | "configurationType": "Release", 340 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 341 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 342 | "cmakeExecutable": "/usr/bin/cmake", 343 | "cmakeCommandArgs": "-S ../../", 344 | "buildCommandArgs": "", 345 | "ctestCommandArgs": "", 346 | "inheritEnvironments": [ "linux_arm" ], 347 | "variables": [ 348 | { 349 | "name": "CMAKE_CXX_FLAGS_RELEASE", 350 | "value": "-O2 -DNDEBUG -static -pthread -s -Wall -Wextra -Wno-missing-field-initializers", 351 | "type": "STRING" 352 | }, 353 | { 354 | "name": "CMAKE_C_FLAGS_RELEASE", 355 | "value": "-O2 -DNDEBUG -static", 356 | "type": "STRING" 357 | }, 358 | { 359 | "name": "CMAKE_CXX_COMPILER", 360 | "value": "/bin/aarch64-linux-gnu-g++", 361 | "type": "STRING" 362 | }, 363 | { 364 | "name": "CMAKE_C_COMPILER", 365 | "value": "/bin/aarch64-linux-gnu-gcc", 366 | "type": "STRING" 367 | } 368 | ], 369 | "intelliSenseMode": "linux-gcc-arm", 370 | "wslPath": "${defaultWSLPath}", 371 | "addressSanitizerRuntimeFlags": "detect_leaks=0", 372 | "remoteCopyUseCompilerDefaults": true 373 | }, 374 | { 375 | "name": "PROD-WSL-x32", 376 | "generator": "Unix Makefiles", 377 | "configurationType": "Release", 378 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 379 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 380 | "cmakeExecutable": "/usr/bin/cmake", 381 | "cmakeCommandArgs": "-S ../../", 382 | "buildCommandArgs": "", 383 | "ctestCommandArgs": "", 384 | "inheritEnvironments": [ "linux_x86" ], 385 | "variables": [ 386 | { 387 | "name": "CMAKE_CXX_FLAGS_RELEASE", 388 | "value": "-O2 -DNDEBUG -static -pthread -s -Wall -Wextra -Wno-missing-field-initializers", 389 | "type": "STRING" 390 | }, 391 | { 392 | "name": "CMAKE_C_FLAGS_RELEASE", 393 | "value": "-O2 -DNDEBUG -static", 394 | "type": "STRING" 395 | }, 396 | { 397 | "name": "CMAKE_CXX_COMPILER", 398 | "value": "/bin/i686-linux-gnu-g++", 399 | "type": "STRING" 400 | }, 401 | { 402 | "name": "CMAKE_C_COMPILER", 403 | "value": "/bin/i686-linux-gnu-gcc", 404 | "type": "STRING" 405 | } 406 | ], 407 | "intelliSenseMode": "linux-gcc-x86", 408 | "wslPath": "${defaultWSLPath}", 409 | "addressSanitizerRuntimeFlags": "detect_leaks=0" 410 | }, 411 | { 412 | "name": "PROD-WSL-x64", 413 | "generator": "Unix Makefiles", 414 | "configurationType": "Release", 415 | "buildRoot": "${workspaceRoot}\\.vs\\build\\${name}", 416 | "installRoot": "${workspaceRoot}\\.vs\\build\\install\\${name}", 417 | "cmakeExecutable": "/usr/bin/cmake", 418 | "cmakeCommandArgs": "-S ../../", 419 | "buildCommandArgs": "", 420 | "ctestCommandArgs": "", 421 | "inheritEnvironments": [ "linux_x64" ], 422 | "variables": [ 423 | { 424 | "name": "CMAKE_CXX_FLAGS_RELEASE", 425 | "value": "-O2 -DNDEBUG -static -pthread -s -Wall -Wextra -Wno-missing-field-initializers", 426 | "type": "STRING" 427 | }, 428 | { 429 | "name": "CMAKE_C_FLAGS_RELEASE", 430 | "value": "-O2 -DNDEBUG -static", 431 | "type": "STRING" 432 | }, 433 | { 434 | "name": "CMAKE_CXX_COMPILER", 435 | "value": "/bin/g++", 436 | "_comment": "/bin/clang++", 437 | "type": "STRING" 438 | }, 439 | { 440 | "name": "CMAKE_C_COMPILER", 441 | "value": "/bin/gcc", 442 | "_comment": "/bin/clang", 443 | "type": "STRING" 444 | } 445 | ], 446 | "intelliSenseMode": "linux-gcc-x64", 447 | "wslPath": "${defaultWSLPath}", 448 | "addressSanitizerRuntimeFlags": "detect_leaks=0", 449 | "remoteCopyUseCompilerDefaults": true 450 | } 451 | ] 452 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Dmitry Sapozhnikov 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /doc/apps.md: -------------------------------------------------------------------------------- 1 | # Text-based Desktop Environment 2 | 3 | ## Desktop Objects and Built-in Applications 4 | 5 | Type | Object | Description 6 | -----------|--------------------------------|---------------------- 7 | `teletype` | `Teletype Console` | A solid rectangular truecolor text canvas depicting a freely scrollable buffer of the text runs generated by an xterm-compatible parser from the standard output of an attached CUI application. It can be a very heavy object due to maintaining a scrollback buffer of arbitrary length. Not used directly in the desktop process's address space. 8 | `terminal` | `Terminal Console` | A derivative of `Teletype Console` with additional UI controls. 9 | `dtvt` | `DirectVT Gateway` | A lightweight truecolor text canvas depicting content received from an external dtvt-aware process. 10 | `vtty` | `Teletype Console dtvt‑bridge` | A `DirectVT Gateway` hosting an external standalone `Teletype Console` process. It is designed to run a heavy `Teletype Console` object in the external process's address space to optimize desktop resource consumption. 11 | `term` | `Terminal Console dtvt‑bridge` | A `DirectVT Gateway` hosting an external standalone `Terminal Console` process. It is designed to run a heavy `Terminal Console` object in the external process's address space to optimize desktop resource consumption. 12 | `dtty` | `DirectVT Gateway with TTY` | A derivative of `DirectVT Gateway` stacked with additional limited `Teletype Console` as a controlling terminal. It is used for CUI applications that redirect DirectVT traffic to standard output and require user input via platform's TTY. Depending on activity the corresponding console became active for the user. 13 | `tile` | `Tiling Window Manager` | A window container with an organization of the hosting window area into mutually non-overlapping panes for nested windows. 14 | `site` | `Desktop Region Marker` | A transparent resizable frame for marking the specific desktop region for quick navigation across the borderless workspace. 15 | 16 | ## Terminal and Teletype Console 17 | 18 | ### Features 19 | 20 | - Non-wrapped text output with horizontal scrolling support. 21 | - Configurable scrollback buffer size (100k lines by default, limited by `max_int32` and system RAM). 22 | - Search for text in the scrollback buffer. 23 | - Linear and rectangular text selection for copying and searching. 24 | - Support for several formats of copying the selected text: 25 | - Plain text 26 | - RTF 27 | - HTML 28 | - ANSI/VT 29 | - Protected (Windows platform only: `ExcludeClipboardContentFromMonitorProcessing`, `CanIncludeInClipboardHistory`, `CanUploadToCloudClipboard`) 30 | - In-process Windows Console API Server of our implementation: 31 | - Win32 Console API support without Windows Console Host (conhost.exe) dependency. 32 | - Fullduplex passthrough VT input/output. 33 | - Support for OEM/National, UTF-8 and UTF-16 encodings. 34 | - Enforced ENABLE_WINDOW_INPUT mode. 35 | Note: In fact it is a viewport resize event reporting. Viewport dimensions is always equal to the classic win32 console buffer dimensions. 36 | - Enforced ENABLE_PROCESSED_OUTPUT and ENABLE_VIRTUAL_TERMINAL_PROCESSING modes. 37 | - Disabled ENABLE_QUICK_EDIT_MODE mode. 38 | - Per process (not per process name) Windows Command Prompt (cmd.exe) input history, aka "Line input" or "Cooked read". 39 | - Stdin/stdout logging. 40 | 41 | ### Private control sequences 42 | 43 | Name | Sequence | Description 44 | -------------|----------------------------------|------------ 45 | `CCC_SBS` | `CSI` 24 : n : m : q `p` | Set scrollback buffer limits:
`n` Initial buffer size
`m` Grow step
`q` Grow limit 46 | `CCC_SGR` | `CSI` 28 : Pm `p` | Set terminal background using SGR attributes (one attribute per call):
`Pm` Colon-separated list of attributes, 0 — reset all attributes, _default is 0_ 47 | `CCC_SEL` | `CSI` 29 : n `p` | Set text selection mode:
`n = 0` Selection is off
`n = 1` Select and copy as plaintext (default)
`n = 2` Select and copy as ANSI/VT text
`n = 3` Select and copy as RTF-document
`n = 4` Select and copy as HTML-code
`n = 5` Select and copy as protected plaintext (suppressed preview, [details](https://learn.microsoft.com/en-us/windows/win32/dataxchg/clipboard-formats#cloud-clipboard-and-clipboard-history-formats)) 48 | `CCC_PAD` | `CSI` 30 : n `p` | Set scrollback buffer left and right side padding:
`n` Width in cells, _max = 255, default is 0_ 49 | `CCC_RST` | `CSI` 1 `p` | Reset all parameters to default 50 | `CCC_TBS` | `CSI` 5 : n `p` | Set tab length in cells:
`n` Length in cells, _max = 256, default is 8_ 51 | `CCC_JET` | `CSI` 11 : n `p` | Set text alignment, _default is Left_:
`n = 0`
`n = 1` Left
`n = 2` Right
`n = 3` Center 52 | `CCC_WRP` | `CSI` 12 : n `p` | Set text autowrap mode, _default is On_:
`n = 0`
`n = 1` On
`n = 2` Off (_enables horizontal scrolling_) 53 | `CCC_RTL` | `CSI` 13 : n `p` | Set text right-to-left mode, _default is Off_:
`n = 0`
`n = 1` On
`n = 2` Off 54 | 55 | Note: It is possible to combine multiple command into a single sequence using a semicolon. For example, the following sequence disables line wrapping, enables text selection, and sets background to blue: `\e[12:2;29:1;28:44p` or `\e[12:2;29:1;28:48:2:0:0:255p`. 56 | 57 | It is possible to create your own terminal window menu from scratch by configuring own menu items in the `` subsection of the configuration file. See (`doc/settings.md#event-scripting`)[https://github.com/directvt/vtm/blob/master/doc/settings.md#event-scripting] for details. 58 | 59 | Common syntax for window menu item declaration: 60 | 61 | ```xml 62 | 63 | 64 | 65 | 66 | 67 | 68 | " Tooltip text. \n" 69 | " Can be multi-line. " 70 | 71 | 72 | ... 73 | 74 | 75 | 76 | ``` 77 | 78 | ### Default Hotkeys 79 | 80 | List of hotkeys defined in the default configuration. 81 | 82 | Hotkey | Description 83 | -----------------------------|------------ 84 | `Ctrl-Alt \| Alt-Ctrl` | Win32: Toggle exclusive keyboard mode. 85 | `Alt+Shift+B` | Unix: Toggle exclusive keyboard mode. 86 | `Alt+RightArrow` | Highlight next match of selected text fragment. Clipboard content is used if no active selection. 87 | `Alt+LeftArrow` | Highlight previous match of selected text fragment. Clipboard content is used if no active selection. 88 | `Ctrl+Shift+PageUp` | Scroll one page up. 89 | `Ctrl+Shift+PageDown` | Scroll one page down. 90 | `Alt+Shift+LeftArrow` | Scroll one page to the left. 91 | `Alt+Shift+RightArrow` | Scroll one page to the right. 92 | `Ctrl+Shift+UpArrow` | Scroll one line up. 93 | `Ctrl+Shift+DownArrow` | Scroll one line down. 94 | `Ctrl+Shift+LeftArrow` | Scroll one cell to the left. 95 | `Ctrl+Shift+RightArrow` | Scroll one cell to the right. 96 | `Ctrl+Shift+Home` | Scroll to the scrollback top. 97 | `Ctrl+Shift+End` | Scroll to the scrollback bottom (reset viewport position). 98 | `Ctrl+Insert` | Copy selection to the clipboard if it is. 99 | `Shift+Insert` | Paste from clipboard. 100 | `Esc` | Deselect a selection if it is. 101 | 102 | ### Configuration example 103 | 104 | ```xml 105 | 106 | 107 | 108 | 109 | 110 | 111 | 119 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 156 | 157 | 158 | 159 | 160 | 161 | " One-shot toggle to select and copy text \n" 162 | " while mouse tracking is active. " 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | ``` 208 | 209 | ## DirectVT Gateway 210 | 211 | DirectVT Gateway is used to attach DirectVT-aware sources. It is mainly used to receive DirectVT traffic from an external dtvt-endpoint. 212 | 213 | ## DirectVT Gateway with TTY 214 | 215 | DirectVT Gateway with TTY is used when there is a need for interactive interaction with the user through the controlling terminal. For example, this is required when connecting via SSH with keyboard-interactive authentication or requesting a private key passphrase. 216 | 217 | In case of running in standalone mode this window object type is used automatically if the first command line argument begins with `ssh` keyword. 218 | 219 | The following commands are identical: 220 | ``` 221 | vtm -r dtty ssh user@host vtm 222 | ``` 223 | ``` 224 | vtm ssh user@host vtm 225 | ``` 226 | 227 | ## Desktop Region Marker 228 | 229 | The Desktop Region Marker is used to quickly navigate the desktop by left-clicking on an instance in the taskbar. The region title can be set using the clipboard text data by right-clicking once on the region frame (swap clipboard text with title text). 230 | 231 | ## Tiling Window Manager 232 | 233 | Tiling Window Manager is a window container that organizes the workspace into mutually non-overlapping panes for nested windows. 234 | 235 | ### Features 236 | 237 | - Supports Drag and Drop for panes (like tabs in a browser). Use any modifiers (`Ctrl` or `Alt`) while pane dragging to suppress this functionality. 238 | - For convenient management of running applets, there is a parallel list of them on the right side of the Tile Manager window: 239 | - `LeftClick` -- To set exclusive focus for applet. 240 | - `Ctrl+LeftClick` -- To set/unset group focus. 241 | - `LeftDoubleClick` -- Maximize/Restore selected applet. 242 | - It is configurable via settings (See configuration example in doc\settings.md`). 243 | 244 | ### Configuration example 245 | 246 | ```xml 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 268 | 269 | 270 | 271 | 272 | " Launch application instances in active empty slots. \n" 273 | " The app to run can be set by RightClick on the taskbar. " 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | ``` -------------------------------------------------------------------------------- /doc/build.md: -------------------------------------------------------------------------------- 1 | # Text-based Desktop Environment 2 | 3 | ## Building from source 4 | 5 | Note: As part of the build process, cmake downloads and compiles the Lua source code from https://www.lua.org. 6 | 7 | ### Unix 8 | 9 | Build-time dependencies 10 | - `git` 11 | - `cmake` 12 | - `C++20 compiler` ([GCC 11](https://gcc.gnu.org/projects/cxx-status.html), [Clang 14](https://clang.llvm.org/cxx_status.html)) 13 | 14 | Use any terminal as a build environment 15 | ``` 16 | git clone https://github.com/directvt/vtm.git 17 | cd vtm 18 | cmake . -B bin 19 | cmake --build bin 20 | sudo cmake --install bin 21 | vtm 22 | ``` 23 | 24 | ### Windows 25 | 26 | Build-time dependencies 27 | - [git](https://git-scm.com/download/win) 28 | - [cmake](https://learn.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=msvc-170#installation) 29 | - [MSVC (Desktop Development with C++)](https://visualstudio.microsoft.com/downloads/) 30 | 31 | Use Developer Command Prompt as a build environment 32 | 33 | ``` 34 | git clone https://github.com/directvt/vtm.git 35 | cd vtm 36 | cmake . -B bin 37 | cmake --build bin --config Release 38 | bin\Release\vtm.exe --install 39 | vtm 40 | ``` -------------------------------------------------------------------------------- /doc/character_geometry.md: -------------------------------------------------------------------------------- 1 | # VT2D: Unicode character Geometry Modifiers 2 | 3 | A user interface based solely on monospaced Unicode characters (a concept known as a text-based user interface, or TUI) has known issues with character width detection, leading to the following limits: 4 | 5 | - No way to specify a custom width for displayed characters. 6 | - No way to display the same characters in narrow and wide variants. 7 | - No way to use triple and quadruple characters along with narrow and wide. 8 | - Different character width assumptions across applications and terminal emulators. 9 | - No way to partially display wide characters. 10 | - No way to display characters taller than one cell. 11 | - No way to display subcell sized characters. 12 | - No way to rotate or mirror characters. 13 | 14 | ## Character matrix 15 | 16 | Each Unicode character is a sequence of codepoints (one or more) - this is the so-called grapheme cluster. Using a font, this sequence is translated into a glyph run. 17 | 18 | ![DEVA-2x1](images/deva_2x1_glyph_run_transparent.png) 19 | 20 | By defining that the graphical representation of the character is a cellular matrix (1x1 matrix consists of one fragment), the final scaling and rasterization of the glyph run can be performed in a rectangular cell matrix defined either implicitly based on the Unicode properties of the cluster codepoints, or explicitly using a modifier codepoint from the Unicode codepoint range 0xD0000-0xD08F6. 21 | 22 | 1x1 | 2x2 | 3x1 23 | ----|-----|----- 24 | ![SGR-CFA-A](images/A_1x1.png) | ![SGR-CFA-E](images/E_2x2.png) | ![SGR-CFA-Indic](images/deva_3x1.png) 25 | 26 | Matrix fragments up to 16x4 cells require at least four associated integer values, which can be packed into the Unicode codepoint space by enumerating "wh_xy" values, where: 27 | - w: Character matrix width. 28 | - h: Character matrix height. 29 | - x: Horizontal fragment selector within the matrix. 30 | - y: Vertical fragment selector within the matrix. 31 | - For character matrices larger than 16x4, pixel graphics should be used. 32 | 33 | [Table source](images/vtm_character_geometry_modifiers_16x4.xhtml) 34 | 35 | ![image](images/vtm_character_geometry_modifiers_16x4.png) 36 | 37 | ### The resulting concept 38 | 39 | - Terminals can annotate each scrollback cell with character matrix metadata and use it to display either the entire character image or a specific fragment within the cell. 40 | - Users/applications can explicitly specify the size of the character matrix (by zeroing out `_xy`) or select any fragment of it (non-zero `_xy`) by placing a specific modifier character after the grapheme cluster. 41 | 42 | Example 1. Output a 3x1 (31_00) character: 43 | - `pwsh` 44 | ```pwsh 45 | "👩‍👩‍👧‍👧`u{D009F}" 46 | ``` 47 | - `bash` 48 | ```bash 49 | printf "👩‍👩‍👧‍👧\UD009F\n" 50 | ``` 51 | Example 2. Output a 6x2 character (by stacking two 6x1 fragments 62_01 and 62_02 on top of each other): 52 | - `pwsh` 53 | ```pwsh 54 | "👩‍👩‍👧‍👧`u{D0279}`n👩‍👩‍👧‍👧`u{D0312}" 55 | ``` 56 | - `bash` 57 | ```bash 58 | printf "👩‍👩‍👧‍👧\UD0279\n👩‍👩‍👧‍👧\UD0312\n" 59 | ``` 60 | Example 3. Output a solid 9x3 character: 61 | - `pwsh` 62 | ```pwsh 63 | "👩‍👩‍👧‍👧`u{D03C3}" 64 | ``` 65 | - `bash` 66 | ```bash 67 | printf "👩‍👩‍👧‍👧\UD03C3\n" 68 | ``` 69 | Example 4. Output the longest word in the Hindi language 16x1 (G1_00): 70 | - `pwsh` 71 | ```pwsh 72 | "`u{2}विश्वविज्ञानकोशनिर्माणसमिति`u{D0121}" 73 | ``` 74 | - `bash` 75 | ```bash 76 | printf "\U2विश्वविज्ञानकोशनिर्माणसमिति\UD0121\n" 77 | ``` 78 | Expected result: 79 | ![image](images/vtm_character_geometry_modifiers_screenshot.png) 80 | 81 | ### Helper functions 82 | 83 | Possible implementation of helper functions for converting between modifier codepoints and character matrix parameter tuples `wh_xy`. 84 | 85 | ```c++ 86 | struct wh_xy 87 | { 88 | int w, h, x, y; 89 | }; 90 | static int p(int n) { return n * (n + 1) / 2; } 91 | const int kx = 16; // Max width of the character matrix. 92 | const int ky = 4; // Max height of the character matrix. 93 | const int mx = p(kx + 1); // Lookup table boundaries. 94 | const int my = p(ky + 1); // 95 | const int unicode_block = 0xD0000; // Unicode codepoint block for geometry modifiers. 96 | 97 | // Returns the modifier codepoint value for the specified tuple w, h, x, y. 98 | static int modifier(int w, int h, int x, int y) { return unicode_block + p(w) + x + (p(h) + y) * mx; }; 99 | 100 | // Returns a tuple w, h, x, y for the specified codepoint modifier using a static lookup table. 101 | static wh_xy matrix(int codepoint) 102 | { 103 | static auto lut = [] 104 | { 105 | auto v = std::vector(mx * my, wh_xy{}); 106 | for (auto w = 1; w <= kx; w++) 107 | for (auto h = 1; h <= ky; h++) 108 | for (auto y = 0; y <= h; y++) 109 | for (auto x = 0; x <= w; x++) 110 | { 111 | v[p(w) + x + (p(h) + y) * mx] = wh_xy{ w, h, x, y }; 112 | } 113 | return v; 114 | }(); 115 | return lut[codepoint - unicode_block]; 116 | } 117 | ``` 118 | 119 | ## Grapheme cluster boundaries 120 | 121 | By default, grapheme clustering occurs according to `Unicode UAX #29` https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules. 122 | 123 | To set arbitrary boundaries, the C0 control character `ASCII 0x02 STX` is used, signaling the beginning of a grapheme cluster. The closing character of a grapheme cluster in that case is always a codepoint from the range 0xD0000-0xDFFFF, which sets the dimension of the character matrix. All codepoints between STX and the closing codepoint that sets the matrix size will be included in the grapheme cluster. 124 | 125 | ## Another brick in the wall 126 | 127 | > At present only standardized variation sequences with VS1, VS2, VS3, VS15 and VS16 have been defined; VS15 and VS16 are reserved to request that a character should be displayed as text or as an emoji respectively. 128 | 129 | > VS4–VS14 (U+FE03–U+FE0D) are not used for any variation sequences 130 | 131 | - https://en.wikipedia.org/wiki/Variation_Selectors_(Unicode_block) 132 | - https://www.unicode.org/Public/UNIDATA/StandardizedVariants.txt 133 | - https://www.unicode.org/reports/tr51/tr51-16.html#Direction 134 | 135 | So, let's try to play this way: 136 | 137 | ### Glyph run alignment inside the matrix 138 | 139 | VS | Codepoint | Axis | Alignment 140 | ----|-----------|------------|-------------- 141 | VS4 | 0xFE03 | Horizontal | Left 142 | VS5 | 0xFE04 | Horizontal | Center 143 | VS6 | 0xFE05 | Horizontal | Right 144 | VS7 | 0xFE06 | Vertical | Top 145 | VS8 | 0xFE07 | Vertical | Middle 146 | VS9 | 0xFE08 | Vertical | Bottom 147 | 148 | Notes: 149 | - We are not operating at a low enough level to support justified alignment. 150 | - By default, glyphs are aligned on the baseline at the writing origin. 151 | 152 | ### Matrix rotation and flips 153 | 154 | VS | Codepoint | Fx 155 | -----|-----------|----------- 156 | VS10 | 0xFE09 | Rotate 90° CCW 157 | VS11 | 0xFE0A | Rotate 180° CCW 158 | VS12 | 0xFE0B | Rotate 270° CCW 159 | VS13 | 0xFE0C | Horizontal flip 160 | VS14 | 0xFE0D | Vertical flip 161 | 162 | Example functions for applying a rotation operation to the current three bits integer `state`: 163 | ```c++ 164 | void VS10(int& state) { state = (state & 0b100) | ((state + 0b001) & 0b011); } 165 | void VS11(int& state) { state = (state & 0b100) | ((state + 0b010) & 0b011); } 166 | void VS12(int& state) { state = (state & 0b100) | ((state + 0b011) & 0b011); } 167 | void VS13(int& state) { state = (state ^ 0b100) | ((state + (state & 1 ? 0 : 0b010)) & 0b011); } 168 | void VS14(int& state) { state = (state ^ 0b100) | ((state + (state & 1 ? 0b010 : 0)) & 0b011); } 169 | 170 | int get_angle(int state) { int angle = 90 * (state & 0b011); return angle; } 171 | int get_hflip(int state) { int hflip = state >> 2; return hflip; } 172 | ``` 173 | 174 | # New Look for Text-based User Interface 175 | 176 | Screenshot of a test page in a terminal emulator that supports the VT2D concept: 177 | 178 | ![image](images/vtm_character_geometry_modifiers_summary.png) 179 | -------------------------------------------------------------------------------- /doc/command-line-options.md: -------------------------------------------------------------------------------- 1 | # Text-based Desktop Environment 2 | 3 | ## Command-line options 4 | 5 | ### Syntax 6 | 7 | ``` 8 | vtm [ -c ][ -q ][ -p ][ -s | -d | -m ][ -x ] 9 | vtm [ -c ][ -q ][ -t | -g ][ -r [ ]][ ] 10 | vtm [ -c ] -l 11 | vtm -i | -u | -v | -? 12 | 13 |