From 425c86179791cd32e2d4ce0ae7f269940b4b0663 Mon Sep 17 00:00:00 2001 From: Can Celik Date: Thu, 10 Sep 2026 21:51:57 +0300 Subject: chore: upgrade libghostty and preserve terminal behavior (#3906) --- .github/workflows/build-artifacts-manual.yml | 6 +- .github/workflows/ci.yml | 30 +- .github/workflows/preview.yml | 21 +- .github/workflows/release.yml | 19 +- AGENTS.md | 10 +- build.rs | 13 +- flake.nix | 2 +- justfile | 4 + nix/package.nix | 4 +- scripts/generate_libghostty_bindings.sh | 12 + src/ghostty/bindings.rs | 1370 +++- src/ghostty/mod.rs | 389 +- src/pane.rs | 2 +- src/pane/input.rs | 7 +- src/pane/terminal.rs | 311 +- src/pane/terminal/migration_tests.rs | 382 ++ src/pane/terminal/windows_recent_fallback.rs | 17 + src/pane/xtgettcap.rs | 270 +- src/server/headless/tests/pane_graphics.rs | 15 +- tests/live_handoff.rs | 4 +- tests/support/mod.rs | 10 +- vendor/libghostty-vt.patches.md | 78 +- vendor/libghostty-vt.vendor.json | 6 +- .../skills/writing-commit-messages/SKILL.md | 2 +- vendor/libghostty-vt/.clang-format | 1 - .../.github/DISCUSSION_TEMPLATE/issue-triage.yml | 2 + .../.github/ISSUE_TEMPLATE/config.yml | 5 - .../.github/ISSUE_TEMPLATE/preapproved.md | 9 - vendor/libghostty-vt/.github/VOUCHED.td | 61 +- .../.github/scripts/check-apple-libghostty-vt.nu | 131 + .../.github/workflows/clean-artifacts.yml | 2 +- vendor/libghostty-vt/.github/workflows/flatpak.yml | 2 +- .../libghostty-vt/.github/workflows/milestone.yml | 4 +- vendor/libghostty-vt/.github/workflows/nix.yml | 8 +- .../.github/workflows/publish-tag.yml | 2 +- .../.github/workflows/release-tag.yml | 26 +- .../.github/workflows/release-tip.yml | 227 +- vendor/libghostty-vt/.github/workflows/snap.yml | 2 +- vendor/libghostty-vt/.github/workflows/test.yml | 663 +- .../.github/workflows/update-colorschemes.yml | 10 +- .../.github/workflows/vouch-check-issue.yml | 4 +- .../workflows/vouch-manage-by-discussion.yml | 2 +- .../.github/workflows/vouch-manage-by-issue.yml | 2 +- .../.github/workflows/vouch-sync-codeowners.yml | 2 +- vendor/libghostty-vt/.gitignore | 5 +- vendor/libghostty-vt/CODEOWNERS | 3 + vendor/libghostty-vt/Doxyfile | 3 +- vendor/libghostty-vt/HACKING.md | 16 +- vendor/libghostty-vt/PACKAGING.md | 53 + vendor/libghostty-vt/VERSION | 2 +- vendor/libghostty-vt/build.zig | 97 +- vendor/libghostty-vt/build.zig.zon | 55 +- vendor/libghostty-vt/build.zig.zon.json | 108 +- vendor/libghostty-vt/build.zig.zon.nix | 132 +- vendor/libghostty-vt/build.zig.zon.txt | 34 +- vendor/libghostty-vt/flake.lock | 58 +- vendor/libghostty-vt/flake.nix | 35 +- vendor/libghostty-vt/include/ghostty.h | 97 +- vendor/libghostty-vt/include/ghostty/vt.h | 23 +- .../libghostty-vt/include/ghostty/vt/allocator.h | 16 +- vendor/libghostty-vt/include/ghostty/vt/device.h | 2 + .../libghostty-vt/include/ghostty/vt/formatter.h | 27 + vendor/libghostty-vt/include/ghostty/vt/io.h | 151 + vendor/libghostty-vt/include/ghostty/vt/key.h | 3 +- .../include/ghostty/vt/kitty_graphics.h | 18 +- vendor/libghostty-vt/include/ghostty/vt/modes.h | 2 + vendor/libghostty-vt/include/ghostty/vt/mouse.h | 3 +- vendor/libghostty-vt/include/ghostty/vt/osc.h | 4 + vendor/libghostty-vt/include/ghostty/vt/paste.h | 182 +- vendor/libghostty-vt/include/ghostty/vt/point.h | 2 + vendor/libghostty-vt/include/ghostty/vt/render.h | 149 +- vendor/libghostty-vt/include/ghostty/vt/screen.h | 34 +- vendor/libghostty-vt/include/ghostty/vt/search.h | 501 ++ .../libghostty-vt/include/ghostty/vt/selection.h | 25 + vendor/libghostty-vt/include/ghostty/vt/sgr.h | 25 - vendor/libghostty-vt/include/ghostty/vt/snapshot.h | 569 ++ vendor/libghostty-vt/include/ghostty/vt/sys.h | 33 + vendor/libghostty-vt/include/ghostty/vt/terminal.h | 1112 +++- vendor/libghostty-vt/include/ghostty/vt/types.h | 135 +- vendor/libghostty-vt/include/ghostty/vt/wasm.h | 168 +- .../nix/build-support/check-zig-cache.sh | 2 +- .../nix/build-support/update-mirror.nu | 113 +- vendor/libghostty-vt/nix/devShell.nix | 29 +- vendor/libghostty-vt/nix/libghostty-vt.nix | 6 +- vendor/libghostty-vt/nix/package.nix | 4 +- vendor/libghostty-vt/pkg/afl++/build.zig | 24 +- vendor/libghostty-vt/pkg/android-ndk/build.zig | 22 +- vendor/libghostty-vt/pkg/apple-sdk/build.zig | 131 +- vendor/libghostty-vt/pkg/apple-sdk/include/math.h | 21 + vendor/libghostty-vt/pkg/apple-sdk/native_link.zig | 85 + vendor/libghostty-vt/pkg/breakpad/build.zig | 22 +- vendor/libghostty-vt/pkg/dcimgui/build.zig | 40 +- vendor/libghostty-vt/pkg/dcimgui/build.zig.zon | 2 +- vendor/libghostty-vt/pkg/fontconfig/build.zig | 116 +- vendor/libghostty-vt/pkg/fontconfig/build.zig.zon | 4 +- .../pkg/fontconfig/override/fc-case/fccase.h | 354 + .../pkg/fontconfig/override/fc-const/fcconst.h | 700 ++ .../override/fc-genericfamily/fcgenericfamily.h | 6963 ++++++++++++++++++++ .../pkg/fontconfig/override/fc-lang/fclang.h | 5586 ++++++++++++++++ .../fontconfig/override/fontconfig/fontconfig.h | 1245 ++++ .../pkg/fontconfig/override/include/fcalias.h | 0 .../pkg/fontconfig/override/include/fcaliastail.h | 0 .../pkg/fontconfig/override/include/fcftalias.h | 0 .../fontconfig/override/include/fcftaliastail.h | 0 .../pkg/fontconfig/override/include/fcobjshash.h | 347 - .../pkg/fontconfig/override/src/fcalias.h | 472 ++ .../pkg/fontconfig/override/src/fcaliastail.h | 528 ++ .../pkg/fontconfig/override/src/fcftalias.h | 16 + .../pkg/fontconfig/override/src/fcftaliastail.h | 24 + .../pkg/fontconfig/override/src/fcint.h | 1752 +++++ .../pkg/fontconfig/override/src/fcobjshash.h | 375 ++ .../pkg/fontconfig/override/src/fcstdint.h | 9 + vendor/libghostty-vt/pkg/freetype/build.zig | 30 +- vendor/libghostty-vt/pkg/glslang/build.zig | 28 +- .../libghostty-vt/pkg/gtk4-layer-shell/build.zig | 169 +- .../pkg/gtk4-layer-shell/build.zig.zon | 5 + .../pkg/gtk4-layer-shell/src/main.zig | 4 +- vendor/libghostty-vt/pkg/harfbuzz/blob.zig | 2 +- vendor/libghostty-vt/pkg/harfbuzz/buffer.zig | 2 +- vendor/libghostty-vt/pkg/harfbuzz/build.zig | 287 +- vendor/libghostty-vt/pkg/harfbuzz/build.zig.zon | 6 + vendor/libghostty-vt/pkg/harfbuzz/c.zig | 8 - vendor/libghostty-vt/pkg/harfbuzz/common.zig | 2 +- vendor/libghostty-vt/pkg/harfbuzz/coretext.zig | 2 +- vendor/libghostty-vt/pkg/harfbuzz/face.zig | 2 +- vendor/libghostty-vt/pkg/harfbuzz/font.zig | 2 +- vendor/libghostty-vt/pkg/harfbuzz/freetype.zig | 2 +- vendor/libghostty-vt/pkg/harfbuzz/main.zig | 2 +- vendor/libghostty-vt/pkg/harfbuzz/shape.zig | 2 +- vendor/libghostty-vt/pkg/harfbuzz/version.zig | 2 +- vendor/libghostty-vt/pkg/highway/build.zig | 22 +- vendor/libghostty-vt/pkg/libintl/build.zig | 10 +- vendor/libghostty-vt/pkg/libpng/build.zig | 27 +- vendor/libghostty-vt/pkg/libxml2/build.zig | 21 +- vendor/libghostty-vt/pkg/macos/build.zig | 111 +- vendor/libghostty-vt/pkg/macos/build.zig.zon | 5 + .../libghostty-vt/pkg/macos/foundation/string.zig | 6 +- vendor/libghostty-vt/pkg/macos/main.zig | 20 +- vendor/libghostty-vt/pkg/macos/text/font.zig | 13 +- vendor/libghostty-vt/pkg/macos/text/typesetter.zig | 6 +- .../libghostty-vt/pkg/macos/video/display_link.zig | 10 +- vendor/libghostty-vt/pkg/oniguruma/build.zig | 12 +- vendor/libghostty-vt/pkg/sentry/build.zig | 38 +- vendor/libghostty-vt/pkg/simdutf/build.zig | 51 +- vendor/libghostty-vt/pkg/spirv-cross/build.zig | 24 +- vendor/libghostty-vt/pkg/wuffs/build.zig | 97 +- vendor/libghostty-vt/pkg/wuffs/build.zig.zon | 13 +- vendor/libghostty-vt/pkg/wuffs/include/stdlib.h | 13 + vendor/libghostty-vt/pkg/wuffs/include/string.h | 22 + vendor/libghostty-vt/pkg/wuffs/src/c.zig | 18 - vendor/libghostty-vt/pkg/wuffs/src/error.zig | 2 +- vendor/libghostty-vt/pkg/wuffs/src/jpeg.zig | 2 +- vendor/libghostty-vt/pkg/wuffs/src/main.zig | 48 +- vendor/libghostty-vt/pkg/wuffs/src/png.zig | 2 +- vendor/libghostty-vt/pkg/wuffs/src/swizzle.zig | 73 +- vendor/libghostty-vt/pkg/zlib/build.zig | 6 +- vendor/libghostty-vt/src/App.zig | 67 +- vendor/libghostty-vt/src/Command.zig | 307 +- vendor/libghostty-vt/src/Surface.zig | 1073 ++- vendor/libghostty-vt/src/apprt.zig | 10 + vendor/libghostty-vt/src/apprt/action.zig | 99 +- vendor/libghostty-vt/src/apprt/embedded.zig | 475 +- vendor/libghostty-vt/src/apprt/gtk/App.zig | 2 + vendor/libghostty-vt/src/apprt/gtk/Surface.zig | 4 +- vendor/libghostty-vt/src/apprt/gtk/adw_version.zig | 26 +- .../src/apprt/gtk/build/blueprint.zig | 94 +- .../src/apprt/gtk/build/gresource.zig | 33 +- vendor/libghostty-vt/src/apprt/gtk/class.zig | 28 +- .../src/apprt/gtk/class/application.zig | 756 ++- .../gtk/class/clipboard_confirmation_dialog.zig | 5 +- .../src/apprt/gtk/class/command_palette.zig | 10 +- .../src/apprt/gtk/class/global_shortcuts.zig | 71 +- .../src/apprt/gtk/class/imgui_widget.zig | 19 +- .../src/apprt/gtk/class/split_tree.zig | 291 +- .../libghostty-vt/src/apprt/gtk/class/surface.zig | 524 +- .../src/apprt/gtk/class/surface_child_exited.zig | 4 +- .../apprt/gtk/class/surface_scrolled_window.zig | 12 +- vendor/libghostty-vt/src/apprt/gtk/class/tab.zig | 4 +- .../src/apprt/gtk/class/title_dialog.zig | 3 + .../libghostty-vt/src/apprt/gtk/class/window.zig | 147 +- vendor/libghostty-vt/src/apprt/gtk/css/style.css | 54 +- vendor/libghostty-vt/src/apprt/gtk/ext/actions.zig | 6 +- vendor/libghostty-vt/src/apprt/gtk/gtk_version.zig | 42 +- vendor/libghostty-vt/src/apprt/gtk/ipc/DBus.zig | 9 +- vendor/libghostty-vt/src/apprt/gtk/ipc/new_tab.zig | 71 + vendor/libghostty-vt/src/apprt/gtk/key.zig | 120 + vendor/libghostty-vt/src/apprt/gtk/media.zig | 7 +- vendor/libghostty-vt/src/apprt/gtk/portal.zig | 4 +- .../libghostty-vt/src/apprt/gtk/portal/OpenURI.zig | 43 +- vendor/libghostty-vt/src/apprt/gtk/post_fork.zig | 9 +- vendor/libghostty-vt/src/apprt/gtk/pre_exec.zig | 9 +- .../src/apprt/gtk/ui/1.2/config-errors-dialog.blp | 4 +- .../src/apprt/gtk/ui/1.2/search-overlay.blp | 7 +- .../libghostty-vt/src/apprt/gtk/ui/1.2/surface.blp | 72 +- vendor/libghostty-vt/src/apprt/gtk/ui/1.5/tab.blp | 9 +- .../libghostty-vt/src/apprt/gtk/ui/1.5/window.blp | 37 +- vendor/libghostty-vt/src/apprt/gtk/weak_ref.zig | 17 + vendor/libghostty-vt/src/apprt/gtk/winproto.zig | 23 +- .../libghostty-vt/src/apprt/gtk/winproto/noop.zig | 13 +- .../src/apprt/gtk/winproto/wayland.zig | 35 +- .../src/apprt/gtk/winproto/wayland/Globals.zig | 3 + .../src/apprt/gtk/winproto/wayland/Hotkeys.zig | 165 + .../wayland/protocols/vicinae-hotkey-v1.xml | 305 + .../libghostty-vt/src/apprt/gtk/winproto/x11.zig | 13 +- vendor/libghostty-vt/src/apprt/ipc.zig | 100 +- vendor/libghostty-vt/src/apprt/structs.zig | 133 +- vendor/libghostty-vt/src/apprt/surface.zig | 134 +- vendor/libghostty-vt/src/benchmark/ApcParser.zig | 20 +- vendor/libghostty-vt/src/benchmark/Benchmark.zig | 11 +- vendor/libghostty-vt/src/benchmark/CApi.zig | 4 +- .../libghostty-vt/src/benchmark/CodepointWidth.zig | 11 +- .../libghostty-vt/src/benchmark/GraphemeBreak.zig | 9 +- vendor/libghostty-vt/src/benchmark/IsSymbol.zig | 9 +- vendor/libghostty-vt/src/benchmark/OscParser.zig | 7 +- .../src/benchmark/PageCompression.zig | 6 +- vendor/libghostty-vt/src/benchmark/ScreenClone.zig | 8 +- .../src/benchmark/ScrollbackCompression.zig | 9 +- .../src/benchmark/TerminalFormatter.zig | 482 ++ .../libghostty-vt/src/benchmark/TerminalParser.zig | 7 +- .../libghostty-vt/src/benchmark/TerminalResize.zig | 357 + .../src/benchmark/TerminalSnapshot.zig | 350 + .../libghostty-vt/src/benchmark/TerminalStream.zig | 43 +- vendor/libghostty-vt/src/benchmark/cli.zig | 24 +- vendor/libghostty-vt/src/benchmark/main.zig | 3 + vendor/libghostty-vt/src/benchmark/options.zig | 7 +- vendor/libghostty-vt/src/build/Config.zig | 251 +- vendor/libghostty-vt/src/build/GhosttyBench.zig | 4 +- vendor/libghostty-vt/src/build/GhosttyDist.zig | 4 +- vendor/libghostty-vt/src/build/GhosttyDocs.zig | 6 +- vendor/libghostty-vt/src/build/GhosttyExe.zig | 17 +- .../libghostty-vt/src/build/GhosttyFrameData.zig | 8 +- vendor/libghostty-vt/src/build/GhosttyI18n.zig | 21 +- vendor/libghostty-vt/src/build/GhosttyLib.zig | 38 +- vendor/libghostty-vt/src/build/GhosttyLibVt.zig | 217 +- .../libghostty-vt/src/build/GhosttyResources.zig | 30 +- vendor/libghostty-vt/src/build/GhosttyWebdata.zig | 6 +- .../libghostty-vt/src/build/GhosttyXCFramework.zig | 39 - .../libghostty-vt/src/build/GhosttyXcodebuild.zig | 10 +- vendor/libghostty-vt/src/build/GhosttyZig.zig | 18 +- vendor/libghostty-vt/src/build/GitVersion.zig | 14 +- vendor/libghostty-vt/src/build/HelpStrings.zig | 2 +- .../src/build/LibsystemOverrideStep.zig | 51 + vendor/libghostty-vt/src/build/MetallibStep.zig | 11 - vendor/libghostty-vt/src/build/SharedDeps.zig | 299 +- vendor/libghostty-vt/src/build/UnicodeTables.zig | 4 +- vendor/libghostty-vt/src/build/XCFrameworkStep.zig | 4 +- .../libghostty-vt/src/build/combine_archives.zig | 28 +- .../src/build/docker/lib-c-docs/Dockerfile | 1 + vendor/libghostty-vt/src/build/gtk.zig | 2 +- .../libghostty-vt/src/build/libsystem_override.sh | 123 + .../src/build/mdgen/main_ghostty_1.zig | 7 +- .../src/build/mdgen/main_ghostty_5.zig | 7 +- vendor/libghostty-vt/src/build/uucode_config.zig | 227 +- .../src/build/wasm_patch_growable_table.zig | 21 +- .../src/build/webgen/main_actions.zig | 4 +- .../src/build/webgen/main_commands.zig | 4 +- .../libghostty-vt/src/build/webgen/main_config.zig | 4 +- vendor/libghostty-vt/src/cli/Pager.zig | 51 +- vendor/libghostty-vt/src/cli/action.zig | 30 +- vendor/libghostty-vt/src/cli/args.zig | 79 +- vendor/libghostty-vt/src/cli/boo.zig | 8 +- vendor/libghostty-vt/src/cli/crash_report.zig | 25 +- vendor/libghostty-vt/src/cli/diagnostics.zig | 4 +- vendor/libghostty-vt/src/cli/edit_config.zig | 132 +- vendor/libghostty-vt/src/cli/explain_config.zig | 9 +- vendor/libghostty-vt/src/cli/ghostty.zig | 30 +- vendor/libghostty-vt/src/cli/help.zig | 7 +- vendor/libghostty-vt/src/cli/list_actions.zig | 7 +- vendor/libghostty-vt/src/cli/list_colors.zig | 19 +- vendor/libghostty-vt/src/cli/list_fonts.zig | 9 +- vendor/libghostty-vt/src/cli/list_keybinds.zig | 18 +- vendor/libghostty-vt/src/cli/list_themes.zig | 215 +- vendor/libghostty-vt/src/cli/new_tab.zig | 277 + vendor/libghostty-vt/src/cli/new_window.zig | 68 +- vendor/libghostty-vt/src/cli/show_config.zig | 5 +- vendor/libghostty-vt/src/cli/show_face.zig | 7 +- .../libghostty-vt/src/cli/ssh-cache/DiskCache.zig | 226 +- vendor/libghostty-vt/src/cli/ssh.zig | 138 +- vendor/libghostty-vt/src/cli/ssh_cache.zig | 132 +- .../src/cli/toggle_quick_terminal.zig | 3 +- vendor/libghostty-vt/src/cli/validate_config.zig | 11 +- vendor/libghostty-vt/src/cli/version.zig | 12 +- vendor/libghostty-vt/src/config/CApi.zig | 26 +- vendor/libghostty-vt/src/config/Config.zig | 692 +- vendor/libghostty-vt/src/config/c_get.zig | 2 +- vendor/libghostty-vt/src/config/command.zig | 2 +- vendor/libghostty-vt/src/config/conditional.zig | 20 +- vendor/libghostty-vt/src/config/edit.zig | 76 +- vendor/libghostty-vt/src/config/file_load.zig | 42 +- vendor/libghostty-vt/src/config/formatter_file.zig | 2 +- vendor/libghostty-vt/src/config/io.zig | 2 +- vendor/libghostty-vt/src/config/key.zig | 27 +- vendor/libghostty-vt/src/config/limit.zig | 115 + vendor/libghostty-vt/src/config/path.zig | 58 +- vendor/libghostty-vt/src/config/string.zig | 24 +- vendor/libghostty-vt/src/config/theme.zig | 28 +- vendor/libghostty-vt/src/config/url.zig | 16 +- vendor/libghostty-vt/src/crash/dir.zig | 28 +- vendor/libghostty-vt/src/crash/sentry.zig | 164 +- vendor/libghostty-vt/src/crash/sentry_envelope.zig | 6 +- vendor/libghostty-vt/src/crc32c.zig | 424 ++ .../src/datastruct/array_list_collection.zig | 44 - .../src/datastruct/blocking_queue.zig | 83 +- vendor/libghostty-vt/src/datastruct/circ_buf.zig | 67 +- vendor/libghostty-vt/src/datastruct/comparison.zig | 6 +- .../src/datastruct/limited_allocator.zig | 124 + vendor/libghostty-vt/src/datastruct/lru.zig | 349 - vendor/libghostty-vt/src/datastruct/main.zig | 6 +- .../src/datastruct/segmented_list.zig | 533 ++ .../src/datastruct/segmented_pool.zig | 95 - vendor/libghostty-vt/src/datastruct/split_tree.zig | 12 + .../src/datastruct/untouched_pool.zig | 297 + .../src/datastruct/wasm_page_pool.zig | 162 + vendor/libghostty-vt/src/fastprint.zig | 68 + vendor/libghostty-vt/src/font/Atlas.zig | 4 +- vendor/libghostty-vt/src/font/Collection.zig | 7 +- vendor/libghostty-vt/src/font/DeferredFace.zig | 3 +- vendor/libghostty-vt/src/font/Metrics.zig | 22 +- vendor/libghostty-vt/src/font/SharedGrid.zig | 160 +- vendor/libghostty-vt/src/font/SharedGridSet.zig | 33 +- vendor/libghostty-vt/src/font/discovery.zig | 85 +- vendor/libghostty-vt/src/font/face/coretext.zig | 1 + vendor/libghostty-vt/src/font/face/freetype.zig | 45 +- vendor/libghostty-vt/src/font/glyf_rasterize.zig | 12 +- .../src/font/glyf_rasterize_png_test.zig | 28 +- vendor/libghostty-vt/src/font/library.zig | 6 +- vendor/libghostty-vt/src/font/opentype/glyf.zig | 60 +- vendor/libghostty-vt/src/font/opentype/head.zig | 8 +- vendor/libghostty-vt/src/font/opentype/hhea.zig | 7 +- vendor/libghostty-vt/src/font/opentype/os2.zig | 21 +- vendor/libghostty-vt/src/font/opentype/post.zig | 8 +- vendor/libghostty-vt/src/font/opentype/sfnt.zig | 7 +- vendor/libghostty-vt/src/font/opentype/svg.zig | 37 +- vendor/libghostty-vt/src/font/shaper/coretext.zig | 93 +- vendor/libghostty-vt/src/font/shaper/feature.zig | 33 +- vendor/libghostty-vt/src/font/shaper/harfbuzz.zig | 128 +- vendor/libghostty-vt/src/font/shaper/run.zig | 53 +- vendor/libghostty-vt/src/font/sprite/Face.zig | 32 +- vendor/libghostty-vt/src/font/sprite/canvas.zig | 83 +- .../src/font/sprite/draw/powerline.zig | 10 +- .../sprite/testdata/U+1CC00...U+1CCFF-11x21+2.png | Bin 1032 -> 941 bytes .../sprite/testdata/U+1CC00...U+1CCFF-12x24+3.png | Bin 1295 -> 1151 bytes .../sprite/testdata/U+1CC00...U+1CCFF-18x36+4.png | Bin 2193 -> 1994 bytes .../sprite/testdata/U+1CC00...U+1CCFF-9x17+1.png | Bin 794 -> 717 bytes .../sprite/testdata/U+1CD00...U+1CDFF-11x21+2.png | Bin 1280 -> 2146 bytes .../sprite/testdata/U+1CD00...U+1CDFF-12x24+3.png | Bin 1870 -> 2529 bytes .../sprite/testdata/U+1CD00...U+1CDFF-18x36+4.png | Bin 3411 -> 4398 bytes .../sprite/testdata/U+1CD00...U+1CDFF-9x17+1.png | Bin 1103 -> 1625 bytes .../sprite/testdata/U+1CE00...U+1CEFF-11x21+2.png | Bin 1006 -> 881 bytes .../sprite/testdata/U+1CE00...U+1CEFF-12x24+3.png | Bin 1255 -> 1082 bytes .../sprite/testdata/U+1CE00...U+1CEFF-18x36+4.png | Bin 2247 -> 2371 bytes .../sprite/testdata/U+1CE00...U+1CEFF-9x17+1.png | Bin 751 -> 693 bytes .../sprite/testdata/U+1FB00...U+1FBFF-11x21+2.png | Bin 5427 -> 5871 bytes .../sprite/testdata/U+1FB00...U+1FBFF-12x24+3.png | Bin 5724 -> 6354 bytes .../sprite/testdata/U+1FB00...U+1FBFF-18x36+4.png | Bin 9975 -> 11167 bytes .../sprite/testdata/U+1FB00...U+1FBFF-9x17+1.png | Bin 4341 -> 4598 bytes .../sprite/testdata/U+2500...U+25FF-11x21+2.png | Bin 2225 -> 2412 bytes .../sprite/testdata/U+2500...U+25FF-12x24+3.png | Bin 2635 -> 2839 bytes .../sprite/testdata/U+2500...U+25FF-18x36+4.png | Bin 4570 -> 5323 bytes .../sprite/testdata/U+2500...U+25FF-9x17+1.png | Bin 1853 -> 1792 bytes .../sprite/testdata/U+2800...U+28FF-11x21+2.png | Bin 1022 -> 1010 bytes .../sprite/testdata/U+2800...U+28FF-12x24+3.png | Bin 1541 -> 1276 bytes .../sprite/testdata/U+2800...U+28FF-18x36+4.png | Bin 2501 -> 1993 bytes .../sprite/testdata/U+2800...U+28FF-9x17+1.png | Bin 917 -> 953 bytes .../sprite/testdata/U+E000...U+E0FF-11x21+2.png | Bin 1102 -> 1030 bytes .../sprite/testdata/U+E000...U+E0FF-12x24+3.png | Bin 1255 -> 1144 bytes .../sprite/testdata/U+E000...U+E0FF-18x36+4.png | Bin 2217 -> 1978 bytes .../sprite/testdata/U+E000...U+E0FF-9x17+1.png | Bin 894 -> 834 bytes .../sprite/testdata/U+F500...U+F5FF-11x21+2.png | Bin 1114 -> 1044 bytes .../sprite/testdata/U+F500...U+F5FF-12x24+3.png | Bin 1421 -> 1279 bytes .../sprite/testdata/U+F500...U+F5FF-18x36+4.png | Bin 2473 -> 2073 bytes .../sprite/testdata/U+F500...U+F5FF-9x17+1.png | Bin 872 -> 831 bytes .../sprite/testdata/U+F600...U+F6FF-11x21+2.png | Bin 495 -> 359 bytes .../sprite/testdata/U+F600...U+F6FF-12x24+3.png | Bin 637 -> 438 bytes .../sprite/testdata/U+F600...U+F6FF-18x36+4.png | Bin 1210 -> 752 bytes .../sprite/testdata/U+F600...U+F6FF-9x17+1.png | Bin 393 -> 288 bytes .../src/font/testdata/glyf_rasterize.png | Bin 1215 -> 1291 bytes vendor/libghostty-vt/src/global.zig | 513 +- vendor/libghostty-vt/src/helpgen.zig | 8 +- vendor/libghostty-vt/src/input/Binding.zig | 94 +- vendor/libghostty-vt/src/input/command.zig | 387 +- vendor/libghostty-vt/src/input/function_keys.zig | 58 +- vendor/libghostty-vt/src/input/key.zig | 10 +- vendor/libghostty-vt/src/input/key_encode.zig | 428 +- vendor/libghostty-vt/src/input/key_mods.zig | 9 +- vendor/libghostty-vt/src/input/paste.zig | 168 +- vendor/libghostty-vt/src/inspector/Inspector.zig | 2 - vendor/libghostty-vt/src/inspector/widgets.zig | 89 - vendor/libghostty-vt/src/inspector/widgets/key.zig | 14 +- .../src/inspector/widgets/pagelist.zig | 2 +- .../libghostty-vt/src/inspector/widgets/screen.zig | 7 +- .../src/inspector/widgets/surface.zig | 13 +- .../libghostty-vt/src/inspector/widgets/termio.zig | 89 +- vendor/libghostty-vt/src/lib/TinyIo.zig | 269 + vendor/libghostty-vt/src/lib/allocator.zig | 8 +- .../src/lib/allocator/convenience.zig | 59 - vendor/libghostty-vt/src/lib/allocator/wasm.zig | 98 + vendor/libghostty-vt/src/lib/c_abi.zig | 28 + vendor/libghostty-vt/src/lib/compat/README.md | 37 + vendor/libghostty-vt/src/lib/compat/fd.zig | 83 + vendor/libghostty-vt/src/lib/compat/file.zig | 56 + vendor/libghostty-vt/src/lib/compat/reader.zig | 64 + vendor/libghostty-vt/src/lib/compat/testing.zig | 19 + vendor/libghostty-vt/src/lib/compat/thread.zig | 75 + vendor/libghostty-vt/src/lib/enum.zig | 99 +- vendor/libghostty-vt/src/lib/main.zig | 5 +- vendor/libghostty-vt/src/lib/packed.zig | 290 + vendor/libghostty-vt/src/lib/string.zig | 15 - vendor/libghostty-vt/src/lib/struct.zig | 24 +- vendor/libghostty-vt/src/lib/tinyio/posix.zig | 608 ++ vendor/libghostty-vt/src/lib/tinyio/test.zig | 836 +++ vendor/libghostty-vt/src/lib/tinyio/windows.zig | 745 +++ vendor/libghostty-vt/src/lib/types.zig | 17 +- vendor/libghostty-vt/src/lib/union.zig | 126 +- vendor/libghostty-vt/src/lib_vt.zig | 531 +- vendor/libghostty-vt/src/main.zig | 12 + vendor/libghostty-vt/src/main_bench.zig | 6 + vendor/libghostty-vt/src/main_build_data.zig | 6 +- vendor/libghostty-vt/src/main_c.zig | 52 +- vendor/libghostty-vt/src/main_gen.zig | 6 + vendor/libghostty-vt/src/main_ghostty.zig | 95 +- vendor/libghostty-vt/src/os/TempDir.zig | 83 +- vendor/libghostty-vt/src/os/args.zig | 130 - vendor/libghostty-vt/src/os/cf_release_thread.zig | 7 +- vendor/libghostty-vt/src/os/cgroup.zig | 9 +- vendor/libghostty-vt/src/os/desktop.zig | 97 +- vendor/libghostty-vt/src/os/edit.zig | 69 + vendor/libghostty-vt/src/os/env.zig | 178 - vendor/libghostty-vt/src/os/file.zig | 11 +- vendor/libghostty-vt/src/os/flatpak.zig | 173 +- vendor/libghostty-vt/src/os/homedir.zig | 92 +- vendor/libghostty-vt/src/os/hostname.zig | 90 +- vendor/libghostty-vt/src/os/i18n.zig | 17 + vendor/libghostty-vt/src/os/i18n_locales.zig | 3 + vendor/libghostty-vt/src/os/kernel_info.zig | 13 +- vendor/libghostty-vt/src/os/locale.zig | 59 +- vendor/libghostty-vt/src/os/mach.zig | 9 +- vendor/libghostty-vt/src/os/macos.zig | 17 +- vendor/libghostty-vt/src/os/main.zig | 19 +- vendor/libghostty-vt/src/os/open.zig | 100 +- vendor/libghostty-vt/src/os/passwd.zig | 7 +- vendor/libghostty-vt/src/os/path.zig | 51 +- vendor/libghostty-vt/src/os/pipe.zig | 7 +- vendor/libghostty-vt/src/os/resourcesdir.zig | 35 +- vendor/libghostty-vt/src/os/stderr.zig | 60 + vendor/libghostty-vt/src/os/systemd.zig | 28 +- vendor/libghostty-vt/src/os/wasm/log.zig | 16 + vendor/libghostty-vt/src/os/windows.zig | 449 +- vendor/libghostty-vt/src/os/xdg.zig | 127 +- vendor/libghostty-vt/src/pty.zig | 79 +- vendor/libghostty-vt/src/quirks_memset.zig | 338 + vendor/libghostty-vt/src/renderer/Metal.zig | 38 + vendor/libghostty-vt/src/renderer/OpenGL.zig | 6 + vendor/libghostty-vt/src/renderer/Overlay.zig | 5 +- vendor/libghostty-vt/src/renderer/State.zig | 21 +- vendor/libghostty-vt/src/renderer/Thread.zig | 210 +- vendor/libghostty-vt/src/renderer/cell.zig | 156 +- vendor/libghostty-vt/src/renderer/cursor.zig | 12 +- vendor/libghostty-vt/src/renderer/generic.zig | 540 +- vendor/libghostty-vt/src/renderer/image.zig | 733 ++- vendor/libghostty-vt/src/renderer/link.zig | 9 +- .../src/renderer/metal/IOSurfaceLayer.zig | 4 + vendor/libghostty-vt/src/renderer/metal/api.zig | 9 +- vendor/libghostty-vt/src/renderer/metal/buffer.zig | 8 +- .../libghostty-vt/src/renderer/metal/shaders.zig | 30 +- .../libghostty-vt/src/renderer/opengl/shaders.zig | 24 +- vendor/libghostty-vt/src/renderer/shadertoy.zig | 12 +- .../src/shell-integration/bash/bash-preexec.sh | 342 +- vendor/libghostty-vt/src/simd/base64.zig | 363 +- vendor/libghostty-vt/src/simd/base64_scalar.zig | 6 + vendor/libghostty-vt/src/simd/main.zig | 12 + vendor/libghostty-vt/src/simd/vt.zig | 99 +- vendor/libghostty-vt/src/surface_mouse.zig | 85 +- vendor/libghostty-vt/src/synthetic/cli.zig | 29 +- vendor/libghostty-vt/src/synthetic/cli/Ascii.zig | 61 +- vendor/libghostty-vt/src/synthetic/cli/Styled.zig | 410 ++ vendor/libghostty-vt/src/synthetic/cli/Utf8.zig | 1 - vendor/libghostty-vt/src/terminal/PageList.zig | 5131 ++++++++++++--- vendor/libghostty-vt/src/terminal/Parser.zig | 29 +- vendor/libghostty-vt/src/terminal/Screen.zig | 2108 ++++-- vendor/libghostty-vt/src/terminal/ScreenSet.zig | 24 +- vendor/libghostty-vt/src/terminal/Selection.zig | 46 +- .../src/terminal/SelectionGesture.zig | 193 +- vendor/libghostty-vt/src/terminal/StringMap.zig | 38 +- vendor/libghostty-vt/src/terminal/Tabstops.zig | 61 +- vendor/libghostty-vt/src/terminal/Terminal.zig | 3650 +++++++--- vendor/libghostty-vt/src/terminal/ansi.zig | 13 +- vendor/libghostty-vt/src/terminal/apc.zig | 360 +- vendor/libghostty-vt/src/terminal/apc/glyph.zig | 7 +- .../src/terminal/apc/glyph/Glossary.zig | 73 +- .../src/terminal/apc/glyph/request.zig | 35 +- .../src/terminal/bitmap_allocator.zig | 233 +- .../libghostty-vt/src/terminal/build_options.zig | 271 +- vendor/libghostty-vt/src/terminal/c/allocator.zig | 5 +- vendor/libghostty-vt/src/terminal/c/build_info.zig | 2 +- vendor/libghostty-vt/src/terminal/c/cell.zig | 10 +- vendor/libghostty-vt/src/terminal/c/formatter.zig | 186 +- vendor/libghostty-vt/src/terminal/c/grid_ref.zig | 6 +- .../src/terminal/c/grid_ref_tracked.zig | 12 +- vendor/libghostty-vt/src/terminal/c/io.zig | 774 +++ vendor/libghostty-vt/src/terminal/c/key_encode.zig | 10 +- vendor/libghostty-vt/src/terminal/c/key_event.zig | 4 +- .../src/terminal/c/kitty_graphics.zig | 288 +- vendor/libghostty-vt/src/terminal/c/main.zig | 40 +- vendor/libghostty-vt/src/terminal/c/modes.zig | 4 +- .../libghostty-vt/src/terminal/c/mouse_encode.zig | 12 +- .../libghostty-vt/src/terminal/c/mouse_event.zig | 4 +- vendor/libghostty-vt/src/terminal/c/osc.zig | 7 +- vendor/libghostty-vt/src/terminal/c/paste.zig | 392 ++ vendor/libghostty-vt/src/terminal/c/render.zig | 929 ++- vendor/libghostty-vt/src/terminal/c/result.zig | 3 + vendor/libghostty-vt/src/terminal/c/row.zig | 2 +- vendor/libghostty-vt/src/terminal/c/search.zig | 1009 +++ vendor/libghostty-vt/src/terminal/c/selection.zig | 61 +- .../src/terminal/c/selection_gesture.zig | 66 +- vendor/libghostty-vt/src/terminal/c/sgr.zig | 11 - vendor/libghostty-vt/src/terminal/c/snapshot.zig | 1527 +++++ vendor/libghostty-vt/src/terminal/c/style.zig | 124 +- vendor/libghostty-vt/src/terminal/c/sys.zig | 136 +- vendor/libghostty-vt/src/terminal/c/terminal.zig | 3735 +++++++++-- .../src/terminal/c/types-schema-verify.py | 114 + .../libghostty-vt/src/terminal/c/types.schema.json | 506 ++ vendor/libghostty-vt/src/terminal/c/types.zig | 1287 +++- vendor/libghostty-vt/src/terminal/clipboard.zig | 244 +- vendor/libghostty-vt/src/terminal/color.zig | 265 +- .../libghostty-vt/src/terminal/compress/Page.zig | 14 + .../src/terminal/compress/lz4_differential.zig | 2 +- vendor/libghostty-vt/src/terminal/cursor.zig | 34 +- vendor/libghostty-vt/src/terminal/dcs.zig | 141 + .../libghostty-vt/src/terminal/device_status.zig | 60 +- vendor/libghostty-vt/src/terminal/formatter.zig | 1523 +++-- vendor/libghostty-vt/src/terminal/fraction.zig | 142 + vendor/libghostty-vt/src/terminal/hash_map.zig | 315 +- vendor/libghostty-vt/src/terminal/hyperlink.zig | 4 +- vendor/libghostty-vt/src/terminal/kitty.zig | 2 + .../libghostty-vt/src/terminal/kitty/clipboard.zig | 82 + .../src/terminal/kitty/clipboard_command.zig | 502 ++ .../src/terminal/kitty/clipboard_grants.zig | 238 + .../src/terminal/kitty/clipboard_response.zig | 469 ++ .../src/terminal/kitty/clipboard_write.zig | 698 ++ vendor/libghostty-vt/src/terminal/kitty/dnd.zig | 69 + .../src/terminal/kitty/dnd_command.zig | 436 ++ .../libghostty-vt/src/terminal/kitty/dnd_drop.zig | 715 ++ .../src/terminal/kitty/dnd_response.zig | 248 + .../libghostty-vt/src/terminal/kitty/dnd_test.zig | 626 ++ .../libghostty-vt/src/terminal/kitty/graphics.zig | 8 +- .../src/terminal/kitty/graphics_animation.zig | 149 + .../src/terminal/kitty/graphics_command.zig | 914 ++- .../src/terminal/kitty/graphics_exec.zig | 3133 ++++++++- .../src/terminal/kitty/graphics_image.zig | 1505 ++++- .../src/terminal/kitty/graphics_pixel.zig | 235 + .../src/terminal/kitty/graphics_storage.zig | 3883 +++++++++-- .../src/terminal/kitty/graphics_unicode.zig | 78 +- .../libghostty-vt/src/terminal/kitty/windows.zig | 277 + vendor/libghostty-vt/src/terminal/lib.zig | 1 + vendor/libghostty-vt/src/terminal/main.zig | 9 + vendor/libghostty-vt/src/terminal/mem.zig | 52 +- vendor/libghostty-vt/src/terminal/modes.zig | 196 +- vendor/libghostty-vt/src/terminal/mouse.zig | 3 +- vendor/libghostty-vt/src/terminal/osc.zig | 264 +- .../src/terminal/osc/kitty_metadata.zig | 94 + vendor/libghostty-vt/src/terminal/osc/parsers.zig | 1 + .../terminal/osc/parsers/clipboard_operation.zig | 20 +- .../src/terminal/osc/parsers/color.zig | 25 +- .../osc/parsers/kitty_clipboard_protocol.zig | 41 +- .../osc/parsers/kitty_desktop_notification.zig | 1201 ++++ .../terminal/osc/parsers/kitty_dnd_protocol.zig | 319 +- .../src/terminal/osc/parsers/kitty_text_sizing.zig | 2 +- .../src/terminal/osc/parsers/semantic_prompt.zig | 88 +- vendor/libghostty-vt/src/terminal/page.zig | 669 +- vendor/libghostty-vt/src/terminal/parse_table.zig | 60 + vendor/libghostty-vt/src/terminal/paste.zig | 247 + vendor/libghostty-vt/src/terminal/point.zig | 10 +- .../libghostty-vt/src/terminal/ref_counted_set.zig | 209 +- vendor/libghostty-vt/src/terminal/render.zig | 268 +- vendor/libghostty-vt/src/terminal/search.zig | 1 + .../libghostty-vt/src/terminal/search/Thread.zig | 606 +- .../libghostty-vt/src/terminal/search/active.zig | 6 +- .../libghostty-vt/src/terminal/search/pagelist.zig | 91 +- .../libghostty-vt/src/terminal/search/screen.zig | 264 +- .../src/terminal/search/sliding_window.zig | 79 +- .../libghostty-vt/src/terminal/search/terminal.zig | 767 +++ .../libghostty-vt/src/terminal/search/viewport.zig | 18 +- vendor/libghostty-vt/src/terminal/sgr.zig | 13 +- .../libghostty-vt/src/terminal/snapshot/AGENTS.md | 7 + .../src/terminal/snapshot/checkpoint.zig | 177 + .../src/terminal/snapshot/continuation.zig | 320 + .../src/terminal/snapshot/envelope.zig | 104 + .../src/terminal/snapshot/fixture.zig | 479 ++ .../libghostty-vt/src/terminal/snapshot/grid.zig | 2403 +++++++ .../src/terminal/snapshot/history.zig | 716 ++ .../src/terminal/snapshot/hyperlink.zig | 493 ++ vendor/libghostty-vt/src/terminal/snapshot/io.zig | 55 + .../libghostty-vt/src/terminal/snapshot/main.zig | 182 + .../libghostty-vt/src/terminal/snapshot/page.zig | 1828 +++++ .../libghostty-vt/src/terminal/snapshot/record.zig | 601 ++ .../libghostty-vt/src/terminal/snapshot/screen.zig | 2460 +++++++ .../src/terminal/snapshot/snapshot.ksy | 1073 +++ .../src/terminal/snapshot/snapshot.zig | 2100 ++++++ .../libghostty-vt/src/terminal/snapshot/style.zig | 423 ++ .../src/terminal/snapshot/terminal.zig | 1850 ++++++ .../snapshot/testdata/checkpoint-ready-v1.hex | 10 + .../src/terminal/snapshot/testdata/complete-v1.hex | 120 + .../snapshot/testdata/continuation-apc-v1.hex | 8 + .../snapshot/testdata/continuation-csi-v1.hex | 8 + .../snapshot/testdata/continuation-dcs-v1.hex | 8 + .../snapshot/testdata/continuation-esc-v1.hex | 8 + .../snapshot/testdata/continuation-ground-v1.hex | 8 + .../snapshot/testdata/continuation-osc-v1.hex | 8 + .../snapshot/testdata/continuation-utf8-v1.hex | 8 + .../src/terminal/snapshot/testdata/envelope-v1.hex | 10 + .../src/terminal/snapshot/testdata/grid-v1.hex | 15 + .../snapshot/testdata/history-header-v1.hex | 10 + .../snapshot/testdata/hyperlink-explicit-v1.hex | 10 + .../snapshot/testdata/hyperlink-implicit-v1.hex | 10 + .../snapshot/testdata/page-empty-record-v1.hex | 12 + .../terminal/snapshot/testdata/page-header-v1.hex | 11 + .../src/terminal/snapshot/testdata/page-v1.hex | 22 + .../snapshot/testdata/record-page-header-v1.hex | 10 + .../snapshot/testdata/screen-header-v1.hex | 13 + .../snapshot/testdata/screen-saved-cursor-v1.hex | 11 + .../src/terminal/snapshot/testdata/style-v1.hex | 10 + .../snapshot/testdata/terminal-header-v1.hex | 16 + .../src/terminal/snapshot/verify-kaitai.py | 400 ++ vendor/libghostty-vt/src/terminal/stream.zig | 1566 ++++- .../src/terminal/stream_continuation.zig | 606 ++ .../libghostty-vt/src/terminal/stream_terminal.zig | 4612 ++++++++++++- vendor/libghostty-vt/src/terminal/style.zig | 222 +- vendor/libghostty-vt/src/terminal/sys.zig | 48 + vendor/libghostty-vt/src/terminal/tmux/control.zig | 2 +- vendor/libghostty-vt/src/terminal/tmux/output.zig | 24 +- vendor/libghostty-vt/src/terminal/tmux/viewer.zig | 31 +- vendor/libghostty-vt/src/terminfo/Source.zig | 38 +- vendor/libghostty-vt/src/terminfo/ghostty.zig | 13 + vendor/libghostty-vt/src/terminfo/main.zig | 1 + vendor/libghostty-vt/src/termio/Exec.zig | 320 +- vendor/libghostty-vt/src/termio/Termio.zig | 206 +- vendor/libghostty-vt/src/termio/Thread.zig | 24 +- vendor/libghostty-vt/src/termio/mailbox.zig | 15 +- vendor/libghostty-vt/src/termio/message.zig | 46 +- .../libghostty-vt/src/termio/shell_integration.zig | 110 +- vendor/libghostty-vt/src/termio/stream_handler.zig | 732 +- vendor/libghostty-vt/src/tripwire.zig | 2 +- vendor/libghostty-vt/src/unicode/grapheme.zig | 24 +- vendor/libghostty-vt/src/unicode/props.zig | 14 +- vendor/libghostty-vt/src/unicode/props_uucode.zig | 8 +- .../libghostty-vt/src/unicode/symbols_uucode.zig | 8 +- vendor/libghostty-vt/typos.toml | 6 + vendor/libghostty-vt/valgrind.supp | 9 + .../0001-default-grapheme-cluster-mode.patch | 22 - .../0002-expose-modify-other-keys-mode.patch | 67 +- .../0004-fix-hosted-wuffs-builds.patch | 29 + 652 files changed, 109329 insertions(+), 16141 deletions(-) create mode 100644 scripts/generate_libghostty_bindings.sh create mode 100644 src/pane/terminal/migration_tests.rs delete mode 100644 vendor/libghostty-vt/.github/ISSUE_TEMPLATE/config.yml delete mode 100644 vendor/libghostty-vt/.github/ISSUE_TEMPLATE/preapproved.md create mode 100755 vendor/libghostty-vt/.github/scripts/check-apple-libghostty-vt.nu create mode 100644 vendor/libghostty-vt/include/ghostty/vt/io.h create mode 100644 vendor/libghostty-vt/include/ghostty/vt/search.h create mode 100644 vendor/libghostty-vt/include/ghostty/vt/snapshot.h create mode 100644 vendor/libghostty-vt/pkg/apple-sdk/include/math.h create mode 100644 vendor/libghostty-vt/pkg/apple-sdk/native_link.zig create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/fc-case/fccase.h create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/fc-const/fcconst.h create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/fc-genericfamily/fcgenericfamily.h create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/fc-lang/fclang.h create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/fontconfig/fontconfig.h delete mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/include/fcalias.h delete mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/include/fcaliastail.h delete mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/include/fcftalias.h delete mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/include/fcftaliastail.h delete mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/include/fcobjshash.h create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/src/fcalias.h create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/src/fcaliastail.h create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/src/fcftalias.h create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/src/fcftaliastail.h create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/src/fcint.h create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/src/fcobjshash.h create mode 100644 vendor/libghostty-vt/pkg/fontconfig/override/src/fcstdint.h delete mode 100644 vendor/libghostty-vt/pkg/harfbuzz/c.zig create mode 100644 vendor/libghostty-vt/pkg/wuffs/include/stdlib.h create mode 100644 vendor/libghostty-vt/pkg/wuffs/include/string.h delete mode 100644 vendor/libghostty-vt/pkg/wuffs/src/c.zig create mode 100644 vendor/libghostty-vt/src/apprt/gtk/ipc/new_tab.zig create mode 100644 vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/Hotkeys.zig create mode 100644 vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/protocols/vicinae-hotkey-v1.xml create mode 100644 vendor/libghostty-vt/src/benchmark/TerminalFormatter.zig create mode 100644 vendor/libghostty-vt/src/benchmark/TerminalResize.zig create mode 100644 vendor/libghostty-vt/src/benchmark/TerminalSnapshot.zig create mode 100644 vendor/libghostty-vt/src/build/LibsystemOverrideStep.zig create mode 100755 vendor/libghostty-vt/src/build/libsystem_override.sh create mode 100644 vendor/libghostty-vt/src/cli/new_tab.zig create mode 100644 vendor/libghostty-vt/src/config/limit.zig create mode 100644 vendor/libghostty-vt/src/crc32c.zig delete mode 100644 vendor/libghostty-vt/src/datastruct/array_list_collection.zig create mode 100644 vendor/libghostty-vt/src/datastruct/limited_allocator.zig delete mode 100644 vendor/libghostty-vt/src/datastruct/lru.zig create mode 100644 vendor/libghostty-vt/src/datastruct/segmented_list.zig delete mode 100644 vendor/libghostty-vt/src/datastruct/segmented_pool.zig create mode 100644 vendor/libghostty-vt/src/datastruct/untouched_pool.zig create mode 100644 vendor/libghostty-vt/src/datastruct/wasm_page_pool.zig create mode 100644 vendor/libghostty-vt/src/fastprint.zig create mode 100644 vendor/libghostty-vt/src/lib/TinyIo.zig delete mode 100644 vendor/libghostty-vt/src/lib/allocator/convenience.zig create mode 100644 vendor/libghostty-vt/src/lib/allocator/wasm.zig create mode 100644 vendor/libghostty-vt/src/lib/c_abi.zig create mode 100644 vendor/libghostty-vt/src/lib/compat/README.md create mode 100644 vendor/libghostty-vt/src/lib/compat/fd.zig create mode 100644 vendor/libghostty-vt/src/lib/compat/file.zig create mode 100644 vendor/libghostty-vt/src/lib/compat/reader.zig create mode 100644 vendor/libghostty-vt/src/lib/compat/testing.zig create mode 100644 vendor/libghostty-vt/src/lib/compat/thread.zig create mode 100644 vendor/libghostty-vt/src/lib/packed.zig delete mode 100644 vendor/libghostty-vt/src/lib/string.zig create mode 100644 vendor/libghostty-vt/src/lib/tinyio/posix.zig create mode 100644 vendor/libghostty-vt/src/lib/tinyio/test.zig create mode 100644 vendor/libghostty-vt/src/lib/tinyio/windows.zig delete mode 100644 vendor/libghostty-vt/src/os/args.zig create mode 100644 vendor/libghostty-vt/src/os/edit.zig delete mode 100644 vendor/libghostty-vt/src/os/env.zig create mode 100644 vendor/libghostty-vt/src/os/stderr.zig create mode 100644 vendor/libghostty-vt/src/quirks_memset.zig create mode 100644 vendor/libghostty-vt/src/synthetic/cli/Styled.zig create mode 100644 vendor/libghostty-vt/src/terminal/c/io.zig create mode 100644 vendor/libghostty-vt/src/terminal/c/search.zig create mode 100644 vendor/libghostty-vt/src/terminal/c/snapshot.zig create mode 100644 vendor/libghostty-vt/src/terminal/c/types-schema-verify.py create mode 100644 vendor/libghostty-vt/src/terminal/c/types.schema.json create mode 100644 vendor/libghostty-vt/src/terminal/fraction.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/clipboard.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/clipboard_command.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/clipboard_grants.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/clipboard_response.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/clipboard_write.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/dnd.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/dnd_command.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/dnd_drop.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/dnd_response.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/dnd_test.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/graphics_animation.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/graphics_pixel.zig create mode 100644 vendor/libghostty-vt/src/terminal/kitty/windows.zig create mode 100644 vendor/libghostty-vt/src/terminal/osc/kitty_metadata.zig create mode 100644 vendor/libghostty-vt/src/terminal/osc/parsers/kitty_desktop_notification.zig create mode 100644 vendor/libghostty-vt/src/terminal/paste.zig create mode 100644 vendor/libghostty-vt/src/terminal/search/terminal.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/AGENTS.md create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/checkpoint.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/continuation.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/envelope.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/fixture.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/grid.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/history.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/hyperlink.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/io.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/main.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/page.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/record.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/screen.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/snapshot.ksy create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/snapshot.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/style.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/terminal.zig create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/checkpoint-ready-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/complete-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/continuation-apc-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/continuation-csi-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/continuation-dcs-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/continuation-esc-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/continuation-ground-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/continuation-osc-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/continuation-utf8-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/envelope-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/grid-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/history-header-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/hyperlink-explicit-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/hyperlink-implicit-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/page-empty-record-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/page-header-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/page-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/record-page-header-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/screen-header-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/screen-saved-cursor-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/style-v1.hex create mode 100644 vendor/libghostty-vt/src/terminal/snapshot/testdata/terminal-header-v1.hex create mode 100755 vendor/libghostty-vt/src/terminal/snapshot/verify-kaitai.py create mode 100644 vendor/libghostty-vt/src/terminal/stream_continuation.zig delete mode 100644 vendor/patches/libghostty-vt/0001-default-grapheme-cluster-mode.patch create mode 100644 vendor/patches/libghostty-vt/0004-fix-hosted-wuffs-builds.patch diff --git a/.github/workflows/build-artifacts-manual.yml b/.github/workflows/build-artifacts-manual.yml index 7fc2e9b8..e5cf8b4b 100644 --- a/.github/workflows/build-artifacts-manual.yml +++ b/.github/workflows/build-artifacts-manual.yml @@ -72,7 +72,7 @@ jobs: - name: Install Zig uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: - version: 0.15.2 + version: 0.16.0 - name: Prefer official Ubuntu mirrors over Azure run: | @@ -156,7 +156,7 @@ jobs: - name: Install Zig uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: - version: 0.15.2 + version: 0.16.0 - name: Install macOS build tools run: brew install cmake ninja @@ -209,7 +209,7 @@ jobs: - name: Install Zig uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: - version: 0.15.2 + version: 0.16.0 - name: Remove Zig caches shell: pwsh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8723a8e4..535cd871 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,38 +86,25 @@ jobs: bun-version: 1.3.14 - name: Install Zig - if: runner.os != 'macOS' uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: - version: 0.15.2 + version: 0.16.0 use-cache: ${{ matrix.kind != 'windows' }} - - name: Restore Homebrew Zig cache - if: runner.os == 'macOS' - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 - with: - path: ~/Library/Caches/Homebrew/downloads - key: homebrew-zig-0.15-${{ runner.os }}-${{ runner.arch }} - restore-keys: | - homebrew-zig-0.15-${{ runner.os }}- - - - name: Install patched Zig on macOS + - name: Configure Zig cache on macOS if: runner.os == 'macOS' run: | - HOMEBREW_NO_AUTO_UPDATE=1 brew install zig@0.15 - echo "$(brew --prefix zig@0.15)/bin" >> "$GITHUB_PATH" echo "ZIG_GLOBAL_CACHE_DIR=$GITHUB_WORKSPACE/.zig-cache" >> "$GITHUB_ENV" echo "ZIG_LOCAL_CACHE_DIR=$GITHUB_WORKSPACE/.zig-cache" >> "$GITHUB_ENV" - "$(brew --prefix zig@0.15)/bin/zig" version - name: Restore Zig build cache if: runner.os == 'macOS' || matrix.kind == 'windows' uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: .zig-cache - key: zig-build-v1-${{ runner.os }}-${{ runner.arch }}-0.15.2-${{ github.run_id }}-${{ github.run_attempt }} + key: zig-build-v1-${{ runner.os }}-${{ runner.arch }}-0.16.0-${{ github.run_id }}-${{ github.run_attempt }} restore-keys: | - zig-build-v1-${{ runner.os }}-${{ runner.arch }}-0.15.2- + zig-build-v1-${{ runner.os }}-${{ runner.arch }}-0.16.0- - name: Install macOS build tools if: runner.os == 'macOS' @@ -133,6 +120,13 @@ jobs: if: matrix.kind == 'unix' run: just ci '${{ matrix.nextest_filter }}' + - name: Check scalar libghostty with runtime safety + if: runner.os == 'Linux' + env: + LIBGHOSTTY_VT_SIMD: "false" + LIBGHOSTTY_VT_OPTIMIZE: ReleaseSafe + run: just test-one ghostty + - name: Run Windows checks if: matrix.kind == 'windows' shell: pwsh @@ -165,7 +159,7 @@ jobs: - name: Install Zig uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: - version: 0.15.2 + version: 0.16.0 use-cache: false - name: Restore Cargo cache diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index cd880016..880338c7 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -105,7 +105,7 @@ jobs: if: steps.plan.outputs.should_publish == 'true' uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: - version: 0.15.2 + version: 0.16.0 - name: Restore cargo cache if: steps.plan.outputs.should_publish == 'true' @@ -161,26 +161,9 @@ jobs: targets: ${{ matrix.target }} - name: Install Zig - if: runner.os != 'macOS' uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: - version: 0.15.2 - - - name: Restore Homebrew Zig cache - if: runner.os == 'macOS' - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 - with: - path: ~/Library/Caches/Homebrew/downloads - key: homebrew-zig-0.15-${{ runner.os }}-${{ runner.arch }} - restore-keys: | - homebrew-zig-0.15-${{ runner.os }}- - - - name: Install patched Zig on macOS - if: runner.os == 'macOS' - run: | - HOMEBREW_NO_AUTO_UPDATE=1 brew install zig@0.15 - echo "$(brew --prefix zig@0.15)/bin" >> "$GITHUB_PATH" - "$(brew --prefix zig@0.15)/bin/zig" version + version: 0.16.0 - name: Prefer official Ubuntu mirrors over Azure if: runner.os == 'Linux' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3b835c7a..2e833ab2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -96,26 +96,9 @@ jobs: targets: ${{ matrix.target }} - name: Install Zig - if: runner.os != 'macOS' uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: - version: 0.15.2 - - - name: Restore Homebrew Zig cache - if: runner.os == 'macOS' - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 - with: - path: ~/Library/Caches/Homebrew/downloads - key: homebrew-zig-0.15-${{ runner.os }}-${{ runner.arch }} - restore-keys: | - homebrew-zig-0.15-${{ runner.os }}- - - - name: Install patched Zig on macOS - if: runner.os == 'macOS' - run: | - HOMEBREW_NO_AUTO_UPDATE=1 brew install zig@0.15 - echo "$(brew --prefix zig@0.15)/bin" >> "$GITHUB_PATH" - "$(brew --prefix zig@0.15)/bin/zig" version + version: 0.16.0 - name: Prefer official Ubuntu mirrors over Azure if: runner.os == 'Linux' diff --git a/AGENTS.md b/AGENTS.md index 116436fe..acec3c03 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -140,6 +140,12 @@ just check # formatting check + cargo nextest + maintenance script Run `just check` before committing unless Can explicitly accepts narrower validation. Do not bypass failing checks; fix the failure or explain exactly why a narrower check is enough. +Windows MSVC cross-compilation from Unix requires SDK/CRT headers and libraries. +Set `LIBGHOSTTY_VT_WINDOWS_LIBC` to a Zig libc configuration file whose directories +point to that SDK (the format is shown by `zig libc` on Windows). `just windows-lint` +and the Windows stage of `just check` use this configuration. Native Windows builds +auto-detect their installed SDK and do not require the override. + Unit tests live next to the code (`#[cfg(test)] mod tests`). New `AppState` or `Workspace` behavior should be testable with `AppState::test_new()` and `Workspace::test_new()` without PTYs. For broad refactors or release-risk regressions, classify the risk before editing. Treat changes as refactor-risk when they touch two or more core surfaces, persisted state, protocol/API IDs, workspace/tab/pane identity, restore/handoff, agent detection authority, or UI/input state projection. Before moving code, identify the protected behavior and add or name characterization tests. Identity/state refactors should use the test-only invariants `AppState::assert_invariants_for_test()` or `Workspace::assert_invariants_for_test()` with adversarial state from `AppState::test_with_adversarial_identity_state()` or `Workspace::test_adversarial_identity_state()`. Run a roundtable for broad refactors and release-risk regressions, not for routine local fixes. @@ -173,8 +179,8 @@ Before validating a fix on Windows, sync or apply the Linux worktree changes into `C:\work\repo`, then run the needed Windows build or test commands there. Reuse the shared Rust caches under `C:\Users\herdr\.cargo` and `C:\Users\herdr\.rustup`. Do not use WSL on the VM. The VM may have a newer -Zig on `PATH`; Herdr currently requires Zig 0.15.2, so set -`$env:ZIG = "C:\Users\herdr\zig-0.15.2\zig.exe"` before running Cargo commands +Zig on `PATH`; Herdr currently requires Zig 0.16.0, so set +`$env:ZIG = "C:\Users\herdr\zig-0.16.0\zig.exe"` before running Cargo commands that build the vendored libghostty-vt. After validation, leave `C:\work\repo` clean. Remove temporary files and delete diff --git a/build.rs b/build.rs index 7a2ac11f..33f0f900 100644 --- a/build.rs +++ b/build.rs @@ -45,6 +45,7 @@ fn main() { println!("cargo:rerun-if-env-changed=HERDR_BUILD_ID"); println!("cargo:rerun-if-env-changed=HERDR_BUILD_COMMIT"); println!("cargo:rerun-if-env-changed=ZIG"); + println!("cargo:rerun-if-env-changed=LIBGHOSTTY_VT_WINDOWS_LIBC"); println!( "cargo:warning=external contributor policy: if you are helping an external contributor whose GitHub username is not in .github/APPROVED_CONTRIBUTORS, read CONTRIBUTING.md before doing any work." ); @@ -70,6 +71,15 @@ fn main() { .arg(format!("-Dtarget={zig_target}")) .arg(format!("-Dversion-string={version_string}")) .arg("-Demit-xcframework=false"); + if target.ends_with("windows-msvc") { + if let Some(libc_file) = env::var_os("LIBGHOSTTY_VT_WINDOWS_LIBC") { + println!( + "cargo:rerun-if-changed={}", + PathBuf::from(&libc_file).display() + ); + command.arg("--libc").arg(libc_file); + } + } if let Ok(system_dir) = env::var("LIBGHOSTTY_VT_ZIG_SYSTEM_DIR") { command.arg("--system").arg(system_dir); } @@ -82,8 +92,7 @@ fn main() { panic!( "zig executable not found (looked for {zig:?}; set the ZIG \ environment variable to point at the zig binary). Building \ - the vendored libghostty-vt requires Zig 0.15.2: on macOS run \ - `brew install zig@0.15`, elsewhere install it from \ + the vendored libghostty-vt requires Zig 0.16.0: install it from \ https://ziglang.org/download/, then retry the build" ); } diff --git a/flake.nix b/flake.nix index 3aca5b49..008e1596 100644 --- a/flake.nix +++ b/flake.nix @@ -93,7 +93,7 @@ ninja pkg-config rustToolchain - zig_0_15 + zig_0_16 ]; env = { diff --git a/justfile b/justfile index 57f5eaba..0dcce374 100644 --- a/justfile +++ b/justfile @@ -88,6 +88,10 @@ integration-assets-test: bun test src/integration/assets/opencode/herdr-agent-state.test.ts bun test src/integration/assets/opencode/herdr-tui-session.test.ts +# Regenerate the C API bindings with bindgen-cli 0.72.1 +libghostty-bindings *clang_args: + bash scripts/generate_libghostty_bindings.sh {{clang_args}} + # Build the vendored libghostty-vt source dist build-libghostty-vt: scripts/build_vendored_libghostty_vt.sh diff --git a/nix/package.nix b/nix/package.nix index 87bf39f0..48de7085 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -4,7 +4,7 @@ rustPlatform, callPackage, runCommand, - zig_0_15, + zig_0_16, zstd, pkg-config, git, @@ -66,7 +66,7 @@ rustPlatform.buildRustPackage { LIBGHOSTTY_VT_OPTIMIZE = "ReleaseFast"; LIBGHOSTTY_VT_SIMD = "true"; LIBGHOSTTY_VT_ZIG_SYSTEM_DIR = zigDeps; - ZIG = lib.getExe zig_0_15; + ZIG = lib.getExe zig_0_16; }; preBuild = '' diff --git a/scripts/generate_libghostty_bindings.sh b/scripts/generate_libghostty_bindings.sh new file mode 100644 index 00000000..c87efca7 --- /dev/null +++ b/scripts/generate_libghostty_bindings.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +cd "$(dirname "$0")/.." + +# Additional clang arguments can supply a resource directory on minimal hosts. +"${BINDGEN:-bindgen}" vendor/libghostty-vt/include/ghostty/vt.h \ + --allowlist-type 'Ghostty.*' \ + --allowlist-function 'ghostty_.*' \ + --allowlist-var 'GHOSTTY_.*' \ + --with-derive-default \ + --output src/ghostty/bindings.rs \ + -- -Ivendor/libghostty-vt/include "$@" diff --git a/src/ghostty/bindings.rs b/src/ghostty/bindings.rs index bf39199e..49a06ee5 100644 --- a/src/ghostty/bindings.rs +++ b/src/ghostty/bindings.rs @@ -88,7 +88,13 @@ pub const GhosttyResult_GHOSTTY_INVALID_VALUE: GhosttyResult = -2; pub const GhosttyResult_GHOSTTY_OUT_OF_SPACE: GhosttyResult = -3; #[doc = " The requested value has no value"] pub const GhosttyResult_GHOSTTY_NO_VALUE: GhosttyResult = -4; -#[doc = " The requested value has no value"] +#[doc = " Operation failed while reading from or writing to external I/O"] +pub const GhosttyResult_GHOSTTY_IO_ERROR: GhosttyResult = -5; +#[doc = " Operation failed because encoded input exceeded a configured limit"] +pub const GhosttyResult_GHOSTTY_LIMIT_EXCEEDED: GhosttyResult = -6; +#[doc = " Operation was rejected by a safety check (e.g. pasted text that could\n inject commands). Nothing was done. Confirm with the user and retry\n with the operation's allow flag set."] +pub const GhosttyResult_GHOSTTY_REJECTED: GhosttyResult = -7; +#[doc = " Operation was rejected by a safety check (e.g. pasted text that could\n inject commands). Nothing was done. Confirm with the user and retry\n with the operation's allow flag set."] pub const GhosttyResult_GHOSTTY_RESULT_MAX_VALUE: GhosttyResult = 2147483647; #[doc = " Result codes for libghostty-vt operations."] pub type GhosttyResult = ::std::os::raw::c_int; @@ -101,6 +107,13 @@ pub struct GhosttyTerminalImpl { pub type GhosttyTerminal = *mut GhosttyTerminalImpl; #[repr(C)] #[derive(Debug, Copy, Clone)] +pub struct GhosttySnapshotDecoderImpl { + _unused: [u8; 0], +} +#[doc = " Opaque handle to an incremental terminal snapshot decoder.\n\n @ingroup snapshot"] +pub type GhosttySnapshotDecoder = *mut GhosttySnapshotDecoderImpl; +#[repr(C)] +#[derive(Debug, Copy, Clone)] pub struct GhosttyTrackedGridRefImpl { _unused: [u8; 0], } @@ -150,6 +163,13 @@ pub struct GhosttyRenderStateRowCellsImpl { pub type GhosttyRenderStateRowCells = *mut GhosttyRenderStateRowCellsImpl; #[repr(C)] #[derive(Debug, Copy, Clone)] +pub struct GhosttySearchImpl { + _unused: [u8; 0], +} +#[doc = " Opaque handle to a terminal search.\n\n A search is bound to the terminal it was created with. It borrows the\n terminal, so it never frees it, and the search must be freed with\n ghostty_search_free(). If the terminal is freed first, the search\n detects this: calls that need the terminal fail cleanly and the\n search can still be freed.\n\n @ingroup search"] +pub type GhosttySearch = *mut GhosttySearchImpl; +#[repr(C)] +#[derive(Debug, Copy, Clone)] pub struct GhosttySgrParserImpl { _unused: [u8; 0], } @@ -186,8 +206,8 @@ pub const GhosttyFormatterFormat_GHOSTTY_FORMATTER_FORMAT_HTML: GhosttyFormatter pub const GhosttyFormatterFormat_GHOSTTY_FORMATTER_FORMAT_MAX_VALUE: GhosttyFormatterFormat = 2147483647; #[doc = " Terminal content output format.\n\n @ingroup formatter"] -pub type GhosttyFormatterFormat = ::std::os::raw::c_uint; -#[doc = " A borrowed byte string (pointer + length).\n\n The memory is not owned by this struct. The pointer is only valid\n for the lifetime documented by the API that produces or consumes it."] +pub type GhosttyFormatterFormat = ::std::os::raw::c_int; +#[doc = " A borrowed byte string (pointer + length).\n\n The memory is not owned by this struct. The pointer is only valid\n for the lifetime documented by the API that produces or consumes it.\n Empty strings produced by the library have a non-NULL pointer to valid\n storage."] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct GhosttyString { @@ -287,10 +307,10 @@ impl Default for GhosttyCodepoints { } } unsafe extern "C" { - #[doc = " Return a pointer to a null-terminated JSON string describing the\n layout of every C API struct for the current target.\n\n This is primarily useful for language bindings that can't easily\n set C struct fields and need to do so via byte offsets. For example,\n WebAssembly modules can't share struct definitions with the host.\n\n Example (abbreviated):\n @code{.json}\n {\n \"GhosttyMouseEncoderSize\": {\n \"size\": 40,\n \"align\": 8,\n \"fields\": {\n \"size\": { \"offset\": 0, \"size\": 8, \"type\": \"u64\" },\n \"screen_width\": { \"offset\": 8, \"size\": 4, \"type\": \"u32\" },\n \"screen_height\": { \"offset\": 12, \"size\": 4, \"type\": \"u32\" },\n \"cell_width\": { \"offset\": 16, \"size\": 4, \"type\": \"u32\" },\n \"cell_height\": { \"offset\": 20, \"size\": 4, \"type\": \"u32\" },\n \"padding_top\": { \"offset\": 24, \"size\": 4, \"type\": \"u32\" },\n \"padding_bottom\": { \"offset\": 28, \"size\": 4, \"type\": \"u32\" },\n \"padding_right\": { \"offset\": 32, \"size\": 4, \"type\": \"u32\" },\n \"padding_left\": { \"offset\": 36, \"size\": 4, \"type\": \"u32\" }\n }\n }\n }\n @endcode\n\n The returned pointer is valid for the lifetime of the process.\n\n @return Pointer to the null-terminated JSON string."] + #[doc = " Return the versioned libghostty-vt C type manifest for the current target.\n\n The manifest defines all the public types available in the linked\n build. The types contain their layouts, enum values, union fields, and more.\n\n Language bindings, such as WebAssembly hosts, should obtain offsets,\n sizes, alignments, array shapes, enum constants, and tagged-union arms from\n this manifest rather than hardcoding them. Consumers should reject unknown\n schema versions and verify the descriptors they require at initialization.\n\n Packed type descriptors define fields using `lsb` and `width`. `lsb` is\n relative to bit zero of the containing numerical value; for nested packed\n layouts it is relative to the immediate containing field. Tagged packed\n unions select an inline arm layout using the named tag field. These layouts\n describe the current linked build and are not a cross-version stability\n promise.\n\n The formal format is defined by the\n libghostty-vt ABI manifest JSON Schema.\n\n Example (abbreviated):\n @code{.json}\n {\n \"schema\": 1,\n \"abi\": {\n \"target\": \"wasm32\", \"os\": \"freestanding\", \"environment\": \"none\",\n \"pointer_size\": 4, \"usize_size\": 4, \"max_alignment\": 16,\n \"endian\": \"little\"\n },\n \"types\": {\n \"GhosttyRenderStateData\": {\n \"kind\": \"enum\", \"size\": 4, \"align\": 4,\n \"underlying\": \"i32\", \"prefix\": \"GHOSTTY_RENDER_STATE_DATA_\",\n \"values\": { \"INVALID\": 0, \"DIRTY\": 3, \"MAX_VALUE\": 2147483647 }\n },\n \"GhosttyStyleColor\": {\n \"kind\": \"struct\", \"size\": 16, \"align\": 8,\n \"fields\": {\n \"tag\": { \"offset\": 0, \"size\": 4,\n \"type\": \"GhosttyStyleColorTag\" },\n \"value\": { \"offset\": 8, \"size\": 8,\n \"type\": \"GhosttyStyleColorValue\", \"tag\": \"tag\",\n \"arms\": { \"NONE\": null, \"PALETTE\": \"palette\",\n \"RGB\": \"rgb\" } }\n }\n }\n }\n }\n @endcode\n\n The returned pointer is valid for the lifetime of the process.\n\n @return Pointer to the null-terminated JSON string."] pub fn ghostty_type_json() -> *const ::std::os::raw::c_char; } -#[doc = " Function table for custom memory allocator operations.\n\n This vtable defines the interface for a custom memory allocator. All\n function pointers must be valid and non-NULL.\n\n @ingroup allocator\n\n If you're not going to use a custom allocator, you can ignore all of\n this. All functions that take an allocator pointer allow NULL to use a\n default allocator.\n\n The interface is based on the Zig allocator interface. I'll say up front\n that it is easy to look at this interface and think \"wow, this is really\n overcomplicated\". The reason for this complexity is well thought out by\n the Zig folks, and it enables a diverse set of allocation strategies\n as shown by the Zig ecosystem. As a consolation, please note that many\n of the arguments are only needed for advanced use cases and can be\n safely ignored in simple implementations. For example, if you look at\n the Zig implementation of the libc allocator in `lib/std/heap.zig`\n (search for CAllocator), you'll see it is very simple.\n\n We chose to align with the Zig allocator interface because:\n\n 1. It is a proven interface that serves a wide variety of use cases\n in the real world via the Zig ecosystem. It's shown to work.\n\n 2. Our core implementation itself is Zig, and this lets us very\n cheaply and easily convert between C and Zig allocators.\n\n NOTE(mitchellh): In the future, we can have default implementations of\n resize/remap and allow those to be null."] +#[doc = " Function table for custom memory allocator operations.\n\n This vtable defines the interface for a custom memory allocator. All\n function pointers must be valid and non-NULL.\n\n @ingroup allocator\n\n If you're not going to use a custom allocator, you can ignore all of\n this. All functions that take an allocator pointer allow NULL to use a\n default allocator. Native freestanding builds must provide an allocator\n for operations that allocate memory.\n\n The interface is based on the Zig allocator interface. I'll say up front\n that it is easy to look at this interface and think \"wow, this is really\n overcomplicated\". The reason for this complexity is well thought out by\n the Zig folks, and it enables a diverse set of allocation strategies\n as shown by the Zig ecosystem. As a consolation, please note that many\n of the arguments are only needed for advanced use cases and can be\n safely ignored in simple implementations. For example, if you look at\n the Zig implementation of the libc allocator in `lib/std/heap.zig`\n (search for CAllocator), you'll see it is very simple.\n\n We chose to align with the Zig allocator interface because:\n\n 1. It is a proven interface that serves a wide variety of use cases\n in the real world via the Zig ecosystem. It's shown to work.\n\n 2. Our core implementation itself is Zig, and this lets us very\n cheaply and easily convert between C and Zig allocators.\n\n NOTE(mitchellh): In the future, we can have default implementations of\n resize/remap and allow those to be null."] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct GhosttyAllocatorVtable { @@ -350,7 +370,7 @@ const _: () = { ["Offset of field: GhosttyAllocatorVtable::free"] [::std::mem::offset_of!(GhosttyAllocatorVtable, free) - 24usize]; }; -#[doc = " Custom memory allocator.\n\n For functions that take an allocator pointer, a NULL pointer indicates\n that the default allocator should be used. The default allocator will\n be libc malloc/free if we're linking to libc. If libc isn't linked,\n a custom allocator is used (currently Zig's SMP allocator).\n\n @ingroup allocator\n\n Usage example:\n @code\n GhosttyAllocator allocator = {\n .vtable = &my_allocator_vtable,\n .ctx = my_allocator_state\n };\n @endcode"] +#[doc = " Custom memory allocator.\n\n For functions that take an allocator pointer, a NULL pointer indicates\n that the default allocator should be used. The default allocator will\n be libc malloc/free if we're linking to libc. If libc isn't linked,\n a custom allocator is used (currently Zig's SMP allocator). On native\n freestanding targets, the default allocator always fails instead.\n\n @ingroup allocator\n\n Usage example:\n @code\n GhosttyAllocator allocator = {\n .vtable = &my_allocator_vtable,\n .ctx = my_allocator_state\n };\n @endcode"] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct GhosttyAllocator { @@ -378,7 +398,7 @@ impl Default for GhosttyAllocator { } } unsafe extern "C" { - #[doc = " Allocate a buffer of `len` bytes.\n\n Uses the provided allocator, or the default allocator if NULL is passed.\n The returned buffer must be freed with ghostty_free() using the same\n allocator.\n\n @param allocator Pointer to the allocator to use, or NULL for the default\n @param len Number of bytes to allocate\n @return Pointer to the allocated buffer, or NULL if allocation failed\n\n @ingroup allocator"] + #[doc = " Allocate a buffer of `len` bytes.\n\n Uses the provided allocator, or the default allocator if NULL is passed.\n The returned buffer must be freed with ghostty_free() using the same\n allocator.\n\n @param allocator Pointer to the allocator to use, or NULL for the default\n @param len Number of bytes to allocate\n @return Pointer to the allocated buffer, or NULL if len is zero or\n allocation failed\n\n @ingroup allocator"] pub fn ghostty_alloc(allocator: *const GhosttyAllocator, len: usize) -> *mut u8; } unsafe extern "C" { @@ -391,7 +411,7 @@ pub const GhosttyOptimizeMode_GHOSTTY_OPTIMIZE_RELEASE_SMALL: GhosttyOptimizeMod pub const GhosttyOptimizeMode_GHOSTTY_OPTIMIZE_RELEASE_FAST: GhosttyOptimizeMode = 3; pub const GhosttyOptimizeMode_GHOSTTY_OPTIMIZE_MODE_MAX_VALUE: GhosttyOptimizeMode = 2147483647; #[doc = " Build optimization mode."] -pub type GhosttyOptimizeMode = ::std::os::raw::c_uint; +pub type GhosttyOptimizeMode = ::std::os::raw::c_int; #[doc = " Invalid data type. Never results in any data extraction."] pub const GhosttyBuildInfo_GHOSTTY_BUILD_INFO_INVALID: GhosttyBuildInfo = 0; #[doc = " Whether SIMD-accelerated code paths are enabled.\n\n Output type: bool *"] @@ -417,7 +437,7 @@ pub const GhosttyBuildInfo_GHOSTTY_BUILD_INFO_VERSION_BUILD: GhosttyBuildInfo = #[doc = " The build metadata string (e.g. commit hash). Has zero length if\n no build metadata is present.\n\n Output type: GhosttyString *"] pub const GhosttyBuildInfo_GHOSTTY_BUILD_INFO_MAX_VALUE: GhosttyBuildInfo = 2147483647; #[doc = " Build info data types that can be queried.\n\n Each variant documents the expected output pointer type."] -pub type GhosttyBuildInfo = ::std::os::raw::c_uint; +pub type GhosttyBuildInfo = ::std::os::raw::c_int; unsafe extern "C" { #[doc = " Query a compile-time build configuration value.\n\n The caller must pass a pointer to the correct output type for the\n requested data (see GhosttyBuildInfo variants for types).\n\n @param data The build info field to query\n @param out Pointer to store the result (type depends on data parameter)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the\n data type is invalid\n\n @ingroup build_info"] pub fn ghostty_build_info( @@ -555,7 +575,7 @@ pub const GhosttyColorScheme_GHOSTTY_COLOR_SCHEME_LIGHT: GhosttyColorScheme = 0; pub const GhosttyColorScheme_GHOSTTY_COLOR_SCHEME_DARK: GhosttyColorScheme = 1; pub const GhosttyColorScheme_GHOSTTY_COLOR_SCHEME_MAX_VALUE: GhosttyColorScheme = 2147483647; #[doc = " Color scheme reported in response to a CSI ? 996 n query.\n\n @ingroup terminal"] -pub type GhosttyColorScheme = ::std::os::raw::c_uint; +pub type GhosttyColorScheme = ::std::os::raw::c_int; #[doc = " Primary device attributes (DA1) response data.\n\n Returned as part of GhosttyDeviceAttributes in response to a CSI c query.\n The conformance_level is the Pp parameter and features contains the Ps\n feature codes.\n\n @ingroup terminal"] #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -675,7 +695,7 @@ pub const GhosttyFocusEvent_GHOSTTY_FOCUS_LOST: GhosttyFocusEvent = 1; #[doc = " Terminal window lost focus"] pub const GhosttyFocusEvent_GHOSTTY_FOCUS_MAX_VALUE: GhosttyFocusEvent = 2147483647; #[doc = " Focus event types for focus reporting mode (mode 1004)."] -pub type GhosttyFocusEvent = ::std::os::raw::c_uint; +pub type GhosttyFocusEvent = ::std::os::raw::c_int; unsafe extern "C" { #[doc = " Encode a focus event into a terminal escape sequence.\n\n Encodes a focus gained (CSI I) or focus lost (CSI O) report into the\n provided buffer.\n\n If the buffer is too small, the function returns GHOSTTY_OUT_OF_SPACE\n and writes the required buffer size to @p out_written. The caller can\n then retry with a sufficiently sized buffer.\n\n @param event The focus event to encode\n @param buf Output buffer to write the encoded sequence into (may be NULL)\n @param buf_len Size of the output buffer in bytes\n @param[out] out_written On success, the number of bytes written. On\n GHOSTTY_OUT_OF_SPACE, the required buffer size.\n @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if the buffer\n is too small"] pub fn ghostty_focus_encode( @@ -685,10 +705,136 @@ unsafe extern "C" { out_written: *mut usize, ) -> GhosttyResult; } -#[doc = " Opaque cell value.\n\n Represents a single terminal cell. The internal layout is opaque and\n must be queried via ghostty_cell_get(). Obtain cell values from\n terminal query APIs.\n\n @ingroup screen"] +#[doc = " Read bytes from a source.\n\n The callback must set @p out_read to a value no greater than @p capacity\n when returning true. A positive value reports progress; it may be less than\n capacity and does not indicate end-of-file. A zero value is definitive\n end-of-file. It must not be used to report temporary input starvation or a\n would-block condition.\n\n Returning false reports a fatal read error and the value of @p out_read is\n ignored. The library does not inspect or modify errno.\n\n All pointer arguments are borrowed and valid only for the duration of the\n callback. The callback is invoked synchronously on the calling thread.\n\n @param userdata Opaque userdata from GhosttyReader\n @param buffer Destination for read bytes; always non-NULL\n @param capacity Writable capacity of @p buffer; always greater than zero\n @param[out] out_read Number of bytes read when returning true; non-NULL\n @return true for a successful read or end-of-file, false for a fatal error"] +pub type GhosttyReaderFn = ::std::option::Option< + unsafe extern "C" fn( + userdata: *mut ::std::os::raw::c_void, + buffer: *mut u8, + capacity: usize, + out_read: *mut usize, + ) -> bool, +>; +#[doc = " Write bytes to a destination.\n\n Returning true means all @p len bytes were accepted. Returning false\n reports a fatal write error. A callback wrapping an interface that permits\n partial writes must retry internally until the full slice is accepted or\n an error occurs.\n\n On failure, the destination may already contain a prefix of the bytes. The\n calling operation fails and must not be resumed from that partial output.\n The library does not inspect or modify errno.\n\n @p data is borrowed and valid only for the duration of the callback. The\n callback is invoked synchronously on the calling thread. Successful return\n means the bytes were handed to the destination; it does not imply that the\n destination was flushed or made durable.\n\n @param userdata Opaque userdata from GhosttyWriter\n @param data Source bytes; always non-NULL\n @param len Number of source bytes; always greater than zero\n @return true if the complete slice was accepted, false on fatal error"] +pub type GhosttyWriterFn = ::std::option::Option< + unsafe extern "C" fn( + userdata: *mut ::std::os::raw::c_void, + data: *const u8, + len: usize, + ) -> bool, +>; +#[doc = " A byte source callback and its opaque context.\n\n The struct is passed by value. @p read must be non-NULL."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyReader { + pub read: GhosttyReaderFn, + pub userdata: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyReader"][::std::mem::size_of::() - 16usize]; + ["Alignment of GhosttyReader"][::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyReader::read"][::std::mem::offset_of!(GhosttyReader, read) - 0usize]; + ["Offset of field: GhosttyReader::userdata"] + [::std::mem::offset_of!(GhosttyReader, userdata) - 8usize]; +}; +impl Default for GhosttyReader { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " A byte destination callback and its opaque context.\n\n The struct is passed by value. @p write must be non-NULL."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyWriter { + pub write: GhosttyWriterFn, + pub userdata: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyWriter"][::std::mem::size_of::() - 16usize]; + ["Alignment of GhosttyWriter"][::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyWriter::write"] + [::std::mem::offset_of!(GhosttyWriter, write) - 0usize]; + ["Offset of field: GhosttyWriter::userdata"] + [::std::mem::offset_of!(GhosttyWriter, userdata) - 8usize]; +}; +impl Default for GhosttyWriter { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " Read one MIME-typed representation of some content, streaming its\n bytes to a writer.\n\n The library calls this with the MIME type of the representation it\n needs. The callback writes all of that representation's data to\n @p writer, in as many calls to `writer.write(writer.userdata, data,\n len)` as is convenient (one call with everything or many small\n pieces both work), and returns true. Nothing written is retained\n beyond each write call, so the data may be borrowed from anywhere:\n a pasteboard item, a file being read, a stream.\n\n Returning false reports that the data could not be read. If the\n writer refuses a write (returns false), stop and return false\n without writing more.\n\n All pointer arguments, the mime, and the writer are borrowed and\n valid only for the duration of the callback. The callback is\n invoked synchronously on the calling thread. The API receiving the\n GhosttyMimeReader defines which MIME types are requested, how many\n times, and any consistency requirements across repeated reads.\n\n @param userdata Opaque userdata from GhosttyMimeReader\n @param mime The MIME type of the representation to read\n @param writer Where to write the data; valid only during this call\n @return true once all the data was written, false if it could not\n be read or the writer refused a write"] +pub type GhosttyMimeReaderFn = ::std::option::Option< + unsafe extern "C" fn( + userdata: *mut ::std::os::raw::c_void, + mime: GhosttyString, + writer: GhosttyWriter, + ) -> bool, +>; +#[doc = " A MIME-typed content source callback and its opaque context.\n\n The struct is passed by value. @p read must be non-NULL."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyMimeReader { + pub read: GhosttyMimeReaderFn, + pub userdata: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyMimeReader"][::std::mem::size_of::() - 16usize]; + ["Alignment of GhosttyMimeReader"][::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyMimeReader::read"] + [::std::mem::offset_of!(GhosttyMimeReader, read) - 0usize]; + ["Offset of field: GhosttyMimeReader::userdata"] + [::std::mem::offset_of!(GhosttyMimeReader, userdata) - 8usize]; +}; +impl Default for GhosttyMimeReader { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " Packed cell value.\n\n Represents a single terminal cell. Portable callers can query fields via\n ghostty_cell_get(). Boundary-sensitive callers can decode the packed value\n using the GhosttyCell descriptor returned by ghostty_type_json(). The\n manifest is authoritative for the linked build; hardcoding bit positions\n is unsupported.\n\n @ingroup screen"] pub type GhosttyCell = u64; #[doc = " Opaque row value.\n\n Represents a single terminal row. The internal layout is opaque and\n must be queried via ghostty_row_get(). Obtain row values from\n terminal query APIs.\n\n @ingroup screen"] pub type GhosttyRow = u64; +#[doc = " A borrowed view of contiguous raw cell values.\n\n The memory is not owned by this struct. The pointer is only valid\n for the lifetime documented by the API that produces it. Each value\n can be queried via ghostty_cell_get() or decoded using the GhosttyCell\n packed descriptor returned by ghostty_type_json().\n\n @ingroup screen"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyCellsView { + #[doc = " Pointer to len contiguous cell values."] + pub ptr: *const GhosttyCell, + #[doc = " Number of cells."] + pub len: usize, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyCellsView"][::std::mem::size_of::() - 16usize]; + ["Alignment of GhosttyCellsView"][::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyCellsView::ptr"] + [::std::mem::offset_of!(GhosttyCellsView, ptr) - 0usize]; + ["Offset of field: GhosttyCellsView::len"] + [::std::mem::offset_of!(GhosttyCellsView, len) - 8usize]; +}; +impl Default for GhosttyCellsView { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} #[doc = " A single codepoint (may be zero for empty)."] pub const GhosttyCellContentTag_GHOSTTY_CELL_CONTENT_CODEPOINT: GhosttyCellContentTag = 0; #[doc = " A codepoint that is part of a multi-codepoint grapheme cluster."] @@ -701,7 +847,7 @@ pub const GhosttyCellContentTag_GHOSTTY_CELL_CONTENT_BG_COLOR_RGB: GhosttyCellCo pub const GhosttyCellContentTag_GHOSTTY_CELL_CONTENT_TAG_MAX_VALUE: GhosttyCellContentTag = 2147483647; #[doc = " Cell content tag.\n\n Describes what kind of content a cell holds.\n\n @ingroup screen"] -pub type GhosttyCellContentTag = ::std::os::raw::c_uint; +pub type GhosttyCellContentTag = ::std::os::raw::c_int; #[doc = " Not a wide character, cell width 1."] pub const GhosttyCellWide_GHOSTTY_CELL_WIDE_NARROW: GhosttyCellWide = 0; #[doc = " Wide character, cell width 2."] @@ -713,7 +859,7 @@ pub const GhosttyCellWide_GHOSTTY_CELL_WIDE_SPACER_HEAD: GhosttyCellWide = 3; #[doc = " Spacer at end of soft-wrapped line for a wide character."] pub const GhosttyCellWide_GHOSTTY_CELL_WIDE_MAX_VALUE: GhosttyCellWide = 2147483647; #[doc = " Cell wide property.\n\n Describes the width behavior of a cell.\n\n @ingroup screen"] -pub type GhosttyCellWide = ::std::os::raw::c_uint; +pub type GhosttyCellWide = ::std::os::raw::c_int; #[doc = " Regular output content, such as command output."] pub const GhosttyCellSemanticContent_GHOSTTY_CELL_SEMANTIC_OUTPUT: GhosttyCellSemanticContent = 0; #[doc = " Content that is part of user input."] @@ -724,7 +870,7 @@ pub const GhosttyCellSemanticContent_GHOSTTY_CELL_SEMANTIC_PROMPT: GhosttyCellSe pub const GhosttyCellSemanticContent_GHOSTTY_CELL_SEMANTIC_MAX_VALUE: GhosttyCellSemanticContent = 2147483647; #[doc = " Semantic content type of a cell.\n\n Set by semantic prompt sequences (OSC 133) to distinguish between\n command output, user input, and shell prompt text.\n\n @ingroup screen"] -pub type GhosttyCellSemanticContent = ::std::os::raw::c_uint; +pub type GhosttyCellSemanticContent = ::std::os::raw::c_int; #[doc = " Invalid data type. Never results in any data extraction."] pub const GhosttyCellData_GHOSTTY_CELL_DATA_INVALID: GhosttyCellData = 0; #[doc = " The codepoint of the cell (0 if empty or bg-color-only).\n\n Output type: uint32_t *"] @@ -752,7 +898,7 @@ pub const GhosttyCellData_GHOSTTY_CELL_DATA_COLOR_RGB: GhosttyCellData = 11; #[doc = " The RGB value for the cell's background color.\n Only valid when content_tag is GHOSTTY_CELL_CONTENT_BG_COLOR_RGB.\n\n Output type: GhosttyColorRgb *"] pub const GhosttyCellData_GHOSTTY_CELL_DATA_MAX_VALUE: GhosttyCellData = 2147483647; #[doc = " Cell data types.\n\n These values specify what type of data to extract from a cell\n using `ghostty_cell_get`.\n\n @ingroup screen"] -pub type GhosttyCellData = ::std::os::raw::c_uint; +pub type GhosttyCellData = ::std::os::raw::c_int; #[doc = " No prompt cells in this row."] pub const GhosttyRowSemanticPrompt_GHOSTTY_ROW_SEMANTIC_NONE: GhosttyRowSemanticPrompt = 0; #[doc = " Prompt cells exist and this is a primary prompt line."] @@ -764,7 +910,7 @@ pub const GhosttyRowSemanticPrompt_GHOSTTY_ROW_SEMANTIC_PROMPT_CONTINUATION: pub const GhosttyRowSemanticPrompt_GHOSTTY_ROW_SEMANTIC_MAX_VALUE: GhosttyRowSemanticPrompt = 2147483647; #[doc = " Row semantic prompt state.\n\n Indicates whether any cells in a row are part of a shell prompt,\n as reported by OSC 133 sequences.\n\n @ingroup screen"] -pub type GhosttyRowSemanticPrompt = ::std::os::raw::c_uint; +pub type GhosttyRowSemanticPrompt = ::std::os::raw::c_int; #[doc = " Invalid data type. Never results in any data extraction."] pub const GhosttyRowData_GHOSTTY_ROW_DATA_INVALID: GhosttyRowData = 0; #[doc = " Whether this row is soft-wrapped.\n\n Output type: bool *"] @@ -786,7 +932,7 @@ pub const GhosttyRowData_GHOSTTY_ROW_DATA_DIRTY: GhosttyRowData = 8; #[doc = " Whether this row is dirty and requires a redraw.\n\n Output type: bool *"] pub const GhosttyRowData_GHOSTTY_ROW_DATA_MAX_VALUE: GhosttyRowData = 2147483647; #[doc = " Row data types.\n\n These values specify what type of data to extract from a row\n using `ghostty_row_get`.\n\n @ingroup screen"] -pub type GhosttyRowData = ::std::os::raw::c_uint; +pub type GhosttyRowData = ::std::os::raw::c_int; unsafe extern "C" { #[doc = " Get data from a cell.\n\n Extracts typed data from the given cell based on the specified\n data type. The output pointer must be of the appropriate type for the\n requested data kind. Valid data types and output types are documented\n in the `GhosttyCellData` enum.\n\n @param cell The cell value\n @param data The type of data to extract\n @param out Pointer to store the extracted data (type depends on data parameter)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the\n data type is invalid\n\n @ingroup screen"] pub fn ghostty_cell_get( @@ -830,7 +976,7 @@ pub const GhosttyStyleColorTag_GHOSTTY_STYLE_COLOR_PALETTE: GhosttyStyleColorTag pub const GhosttyStyleColorTag_GHOSTTY_STYLE_COLOR_RGB: GhosttyStyleColorTag = 2; pub const GhosttyStyleColorTag_GHOSTTY_STYLE_COLOR_TAG_MAX_VALUE: GhosttyStyleColorTag = 2147483647; #[doc = " Style color tags.\n\n These values identify the type of color in a style color.\n Use the tag to determine which field in the color value union to access.\n\n @ingroup style"] -pub type GhosttyStyleColorTag = ::std::os::raw::c_uint; +pub type GhosttyStyleColorTag = ::std::os::raw::c_int; #[doc = " Style color value union.\n\n Use the tag to determine which field is active.\n\n @ingroup style"] #[repr(C)] #[derive(Copy, Clone)] @@ -1046,7 +1192,7 @@ pub const GhosttyPointTag_GHOSTTY_POINT_TAG_HISTORY: GhosttyPointTag = 3; #[doc = " Scrollback history only (before active area)."] pub const GhosttyPointTag_GHOSTTY_POINT_TAG_MAX_VALUE: GhosttyPointTag = 2147483647; #[doc = " Point reference tag.\n\n Determines which coordinate system a point uses.\n\n @ingroup point"] -pub type GhosttyPointTag = ::std::os::raw::c_uint; +pub type GhosttyPointTag = ::std::os::raw::c_int; #[doc = " Point value union.\n\n @ingroup point"] #[repr(C)] #[derive(Copy, Clone)] @@ -1146,6 +1292,38 @@ impl Default for GhosttySelection { } } } +#[doc = " A caller-provided buffer of selections.\n\n This follows the same conventions as GhosttyBuffer: ptr may be NULL with\n cap 0 to query the required capacity. APIs that fill this type set len to\n the number of entries written on GHOSTTY_SUCCESS, or to the required entry\n capacity on GHOSTTY_OUT_OF_SPACE.\n\n @ingroup selection"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttySelectionBuffer { + #[doc = " Destination buffer for selections. May be NULL when cap is 0 to query\n the required capacity."] + pub ptr: *mut GhosttySelection, + #[doc = " Capacity of ptr in entries."] + pub cap: usize, + #[doc = " Entries written on success, or required entry capacity on\n GHOSTTY_OUT_OF_SPACE."] + pub len: usize, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttySelectionBuffer"][::std::mem::size_of::() - 24usize]; + ["Alignment of GhosttySelectionBuffer"] + [::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttySelectionBuffer::ptr"] + [::std::mem::offset_of!(GhosttySelectionBuffer, ptr) - 0usize]; + ["Offset of field: GhosttySelectionBuffer::cap"] + [::std::mem::offset_of!(GhosttySelectionBuffer, cap) - 8usize]; + ["Offset of field: GhosttySelectionBuffer::len"] + [::std::mem::offset_of!(GhosttySelectionBuffer, len) - 16usize]; +}; +impl Default for GhosttySelectionBuffer { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} #[doc = " Options for deriving a word selection from a terminal grid reference.\n\n This is a sized struct. Use GHOSTTY_INIT_SIZED() to initialize it.\n If boundary_codepoints is NULL and boundary_codepoints_len is 0, Ghostty's\n default word-boundary codepoints are used. If boundary_codepoints_len is\n non-zero, boundary_codepoints must not be NULL.\n\n @ingroup selection"] #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -1327,7 +1505,7 @@ pub const GhosttySelectionOrder_GHOSTTY_SELECTION_ORDER_MIRRORED_REVERSE: Ghostt pub const GhosttySelectionOrder_GHOSTTY_SELECTION_ORDER_MAX_VALUE: GhosttySelectionOrder = 2147483647; #[doc = " Ordering of a selection's endpoints in terminal coordinates.\n\n Mirrored orders are only produced by rectangular selections whose start\n and end endpoints are on opposite diagonal corners that are not simple\n top-left-to-bottom-right or bottom-right-to-top-left orderings.\n\n @ingroup selection"] -pub type GhosttySelectionOrder = ::std::os::raw::c_uint; +pub type GhosttySelectionOrder = ::std::os::raw::c_int; #[doc = " Move left to the previous non-empty cell, wrapping upward."] pub const GhosttySelectionAdjust_GHOSTTY_SELECTION_ADJUST_LEFT: GhosttySelectionAdjust = 0; #[doc = " Move right to the next non-empty cell, wrapping downward."] @@ -1353,7 +1531,7 @@ pub const GhosttySelectionAdjust_GHOSTTY_SELECTION_ADJUST_END_OF_LINE: GhosttySe pub const GhosttySelectionAdjust_GHOSTTY_SELECTION_ADJUST_MAX_VALUE: GhosttySelectionAdjust = 2147483647; #[doc = " Operation used to adjust a selection endpoint.\n\n Adjustment mutates the selection's logical end endpoint, not whichever\n endpoint is visually bottom/right. This preserves keyboard and drag\n behavior for both forward and reversed selections.\n\n @ingroup selection"] -pub type GhosttySelectionAdjust = ::std::os::raw::c_uint; +pub type GhosttySelectionAdjust = ::std::os::raw::c_int; #[doc = " Cell-granular drag selection."] pub const GhosttySelectionGestureBehavior_GHOSTTY_SELECTION_GESTURE_BEHAVIOR_CELL: GhosttySelectionGestureBehavior = 0; @@ -1370,7 +1548,7 @@ pub const GhosttySelectionGestureBehavior_GHOSTTY_SELECTION_GESTURE_BEHAVIOR_OUT pub const GhosttySelectionGestureBehavior_GHOSTTY_SELECTION_GESTURE_BEHAVIOR_MAX_VALUE: GhosttySelectionGestureBehavior = 2147483647; #[doc = " Selection behavior chosen for a gesture's click sequence.\n\n @ingroup selection"] -pub type GhosttySelectionGestureBehavior = ::std::os::raw::c_uint; +pub type GhosttySelectionGestureBehavior = ::std::os::raw::c_int; #[doc = " Selection behaviors for single-, double-, and triple-click gestures.\n\n @ingroup selection"] #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -1445,7 +1623,7 @@ pub const GhosttySelectionGestureAutoscroll_GHOSTTY_SELECTION_GESTURE_AUTOSCROLL pub const GhosttySelectionGestureAutoscroll_GHOSTTY_SELECTION_GESTURE_AUTOSCROLL_MAX_VALUE: GhosttySelectionGestureAutoscroll = 2147483647; #[doc = " Current autoscroll direction for an active selection drag gesture.\n\n @ingroup selection"] -pub type GhosttySelectionGestureAutoscroll = ::std::os::raw::c_uint; +pub type GhosttySelectionGestureAutoscroll = ::std::os::raw::c_int; #[doc = " Current click count: uint8_t*. 0 means inactive."] pub const GhosttySelectionGestureData_GHOSTTY_SELECTION_GESTURE_DATA_CLICK_COUNT: GhosttySelectionGestureData = 0; @@ -1465,7 +1643,7 @@ pub const GhosttySelectionGestureData_GHOSTTY_SELECTION_GESTURE_DATA_ANCHOR: pub const GhosttySelectionGestureData_GHOSTTY_SELECTION_GESTURE_DATA_MAX_VALUE: GhosttySelectionGestureData = 2147483647; #[doc = " Data fields readable from a selection gesture with\n ghostty_selection_gesture_get().\n\n @ingroup selection"] -pub type GhosttySelectionGestureData = ::std::os::raw::c_uint; +pub type GhosttySelectionGestureData = ::std::os::raw::c_int; #[doc = " Press event for ghostty_selection_gesture_event()."] pub const GhosttySelectionGestureEventType_GHOSTTY_SELECTION_GESTURE_EVENT_TYPE_PRESS: GhosttySelectionGestureEventType = 0; @@ -1485,7 +1663,7 @@ pub const GhosttySelectionGestureEventType_GHOSTTY_SELECTION_GESTURE_EVENT_TYPE_ pub const GhosttySelectionGestureEventType_GHOSTTY_SELECTION_GESTURE_EVENT_TYPE_MAX_VALUE: GhosttySelectionGestureEventType = 2147483647; #[doc = " Selection gesture event type.\n\n The event type is fixed when the event is created. Each event type documents\n which options are valid and which options are required by gesture operations.\n\n @ingroup selection"] -pub type GhosttySelectionGestureEventType = ::std::os::raw::c_uint; +pub type GhosttySelectionGestureEventType = ::std::os::raw::c_int; #[doc = " Grid reference under the pointer: GhosttyGridRef*.\n\n Required for PRESS and DRAG events. Optional for RELEASE events; when unset\n or cleared, release records that the pointer did not map to a valid cell."] pub const GhosttySelectionGestureEventOption_GHOSTTY_SELECTION_GESTURE_EVENT_OPT_REF: GhosttySelectionGestureEventOption = 0; @@ -1518,7 +1696,7 @@ pub const GhosttySelectionGestureEventOption_GHOSTTY_SELECTION_GESTURE_EVENT_OPT pub const GhosttySelectionGestureEventOption_GHOSTTY_SELECTION_GESTURE_EVENT_OPT_MAX_VALUE: GhosttySelectionGestureEventOption = 2147483647; #[doc = " Options stored on a reusable selection gesture event.\n\n Passing NULL as the value to ghostty_selection_gesture_event_set() clears the\n corresponding option.\n\n @ingroup selection"] -pub type GhosttySelectionGestureEventOption = ::std::os::raw::c_uint; +pub type GhosttySelectionGestureEventOption = ::std::os::raw::c_int; unsafe extern "C" { #[doc = " Create a reusable selection gesture event object.\n\n @param allocator Allocator, or NULL for the default allocator\n @param out_event Receives the created event handle\n @param type Event type. This is fixed for the lifetime of the event.\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if out_event is\n NULL or type is invalid, or GHOSTTY_OUT_OF_MEMORY if allocation fails\n\n @ingroup selection"] pub fn ghostty_selection_gesture_event_new( @@ -1639,7 +1817,7 @@ unsafe extern "C" { ) -> GhosttyResult; } unsafe extern "C" { - #[doc = " Format a terminal selection into an allocated buffer.\n\n This is a one-shot convenience API for formatting either the terminal's\n active selection or a caller-provided GhosttySelection without explicitly\n creating a GhosttyFormatter.\n\n The returned buffer is allocated using allocator, or the default allocator\n if NULL is passed. The caller owns the returned buffer and must free it with\n ghostty_free(), passing the same allocator and returned length.\n\n The returned bytes are not NUL-terminated. This supports plain text, VT, and\n HTML uniformly as byte output.\n\n If options.selection is NULL and the terminal has no active selection, the\n function returns GHOSTTY_NO_VALUE and leaves out_ptr as NULL and out_len as 0.\n\n @param terminal The terminal to read from (must not be NULL)\n @param allocator Allocator used for the returned buffer, or NULL for the default allocator\n @param options Selection formatting options\n @param out_ptr Receives the allocated output buffer (must not be NULL)\n @param out_len Receives the output length in bytes (must not be NULL)\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup selection"] + #[doc = " Format a terminal selection into an allocated buffer.\n\n This is a one-shot convenience API for formatting either the terminal's\n active selection or a caller-provided GhosttySelection without explicitly\n creating a GhosttyFormatter.\n\n The returned buffer is allocated using allocator, or the default allocator\n if NULL is passed. The caller owns the returned buffer and must free it with\n ghostty_free(), passing the same allocator and returned length.\n Empty output returns GHOSTTY_SUCCESS with *out_ptr set to NULL and\n *out_len set to zero. This result can be passed to ghostty_free().\n\n The returned bytes are not NUL-terminated. This supports plain text, VT, and\n HTML uniformly as byte output.\n\n If options.selection is NULL and the terminal has no active selection, the\n function returns GHOSTTY_NO_VALUE and leaves out_ptr as NULL and out_len as 0.\n\n @param terminal The terminal to read from (must not be NULL)\n @param allocator Allocator used for the returned buffer, or NULL for the default allocator\n @param options Selection formatting options\n @param out_ptr Receives the allocated output buffer (must not be NULL)\n @param out_len Receives the output length in bytes (must not be NULL)\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup selection"] pub fn ghostty_terminal_selection_format_alloc( terminal: GhosttyTerminal, allocator: *const GhosttyAllocator, @@ -1706,7 +1884,7 @@ pub const GhosttyModeReportState_GHOSTTY_MODE_REPORT_PERMANENTLY_RESET: GhosttyM #[doc = " Mode is permanently reset"] pub const GhosttyModeReportState_GHOSTTY_MODE_REPORT_MAX_VALUE: GhosttyModeReportState = 2147483647; #[doc = " DECRPM report state values.\n\n These correspond to the Ps2 parameter in a DECRPM response\n sequence (CSI ? Ps1 ; Ps2 $ y)."] -pub type GhosttyModeReportState = ::std::os::raw::c_uint; +pub type GhosttyModeReportState = ::std::os::raw::c_int; unsafe extern "C" { #[doc = " Encode a DECRPM (DEC Private Mode Report) response sequence.\n\n Writes a mode report escape sequence into the provided buffer.\n The generated sequence has the form:\n - DEC private mode: CSI ? Ps1 ; Ps2 $ y\n - ANSI mode: CSI Ps1 ; Ps2 $ y\n\n If the buffer is too small, the function returns GHOSTTY_OUT_OF_SPACE\n and writes the required buffer size to @p out_written. The caller can\n then retry with a sufficiently sized buffer.\n\n @param mode The mode identifying the mode to report on\n @param state The report state for this mode\n @param buf Output buffer to write the encoded sequence into (may be NULL)\n @param buf_len Size of the output buffer in bytes\n @param[out] out_written On success, the number of bytes written. On\n GHOSTTY_OUT_OF_SPACE, the required buffer size.\n @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if the buffer\n is too small"] pub fn ghostty_mode_report_encode( @@ -1729,7 +1907,7 @@ pub const GhosttySizeReportStyle_GHOSTTY_SIZE_REPORT_CSI_18_T: GhosttySizeReport pub const GhosttySizeReportStyle_GHOSTTY_SIZE_REPORT_STYLE_MAX_VALUE: GhosttySizeReportStyle = 2147483647; #[doc = " Size report style.\n\n Determines the output format for the terminal size report."] -pub type GhosttySizeReportStyle = ::std::os::raw::c_uint; +pub type GhosttySizeReportStyle = ::std::os::raw::c_int; #[doc = " Terminal size information for encoding size reports."] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -1780,7 +1958,7 @@ pub const GhosttyKittyGraphicsData_GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION: pub const GhosttyKittyGraphicsData_GHOSTTY_KITTY_GRAPHICS_DATA_MAX_VALUE: GhosttyKittyGraphicsData = 2147483647; #[doc = " Queryable data kinds for ghostty_kitty_graphics_get().\n\n @ingroup kitty_graphics"] -pub type GhosttyKittyGraphicsData = ::std::os::raw::c_uint; +pub type GhosttyKittyGraphicsData = ::std::os::raw::c_int; #[doc = " Invalid / sentinel value."] pub const GhosttyKittyGraphicsPlacementData_GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_INVALID: GhosttyKittyGraphicsPlacementData = 0; @@ -1824,7 +2002,7 @@ pub const GhosttyKittyGraphicsPlacementData_GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DAT pub const GhosttyKittyGraphicsPlacementData_GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_MAX_VALUE: GhosttyKittyGraphicsPlacementData = 2147483647; #[doc = " Queryable data kinds for ghostty_kitty_graphics_placement_get().\n\n @ingroup kitty_graphics"] -pub type GhosttyKittyGraphicsPlacementData = ::std::os::raw::c_uint; +pub type GhosttyKittyGraphicsPlacementData = ::std::os::raw::c_int; pub const GhosttyKittyPlacementLayer_GHOSTTY_KITTY_PLACEMENT_LAYER_ALL: GhosttyKittyPlacementLayer = 0; pub const GhosttyKittyPlacementLayer_GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_BG: @@ -1836,13 +2014,13 @@ pub const GhosttyKittyPlacementLayer_GHOSTTY_KITTY_PLACEMENT_LAYER_ABOVE_TEXT: pub const GhosttyKittyPlacementLayer_GHOSTTY_KITTY_PLACEMENT_LAYER_MAX_VALUE: GhosttyKittyPlacementLayer = 2147483647; #[doc = " Z-layer classification for kitty graphics placements.\n\n Based on the kitty protocol z-index conventions:\n - BELOW_BG: z < INT32_MIN/2 (drawn below cell background)\n - BELOW_TEXT: INT32_MIN/2 <= z < 0 (above background, below text)\n - ABOVE_TEXT: z >= 0 (above text)\n - ALL: no filtering (current behavior)\n\n @ingroup kitty_graphics"] -pub type GhosttyKittyPlacementLayer = ::std::os::raw::c_uint; +pub type GhosttyKittyPlacementLayer = ::std::os::raw::c_int; #[doc = " Set the z-layer filter for the iterator.\n\n Input type: GhosttyKittyPlacementLayer *"] pub const GhosttyKittyGraphicsPlacementIteratorOption_GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_LAYER : GhosttyKittyGraphicsPlacementIteratorOption = 0 ; #[doc = " Set the z-layer filter for the iterator.\n\n Input type: GhosttyKittyPlacementLayer *"] pub const GhosttyKittyGraphicsPlacementIteratorOption_GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_MAX_VALUE : GhosttyKittyGraphicsPlacementIteratorOption = 2147483647 ; #[doc = " Settable options for ghostty_kitty_graphics_placement_iterator_set().\n\n @ingroup kitty_graphics"] -pub type GhosttyKittyGraphicsPlacementIteratorOption = ::std::os::raw::c_uint; +pub type GhosttyKittyGraphicsPlacementIteratorOption = ::std::os::raw::c_int; pub const GhosttyKittyImageFormat_GHOSTTY_KITTY_IMAGE_FORMAT_RGB: GhosttyKittyImageFormat = 0; pub const GhosttyKittyImageFormat_GHOSTTY_KITTY_IMAGE_FORMAT_RGBA: GhosttyKittyImageFormat = 1; pub const GhosttyKittyImageFormat_GHOSTTY_KITTY_IMAGE_FORMAT_PNG: GhosttyKittyImageFormat = 2; @@ -1852,7 +2030,7 @@ pub const GhosttyKittyImageFormat_GHOSTTY_KITTY_IMAGE_FORMAT_GRAY: GhosttyKittyI pub const GhosttyKittyImageFormat_GHOSTTY_KITTY_IMAGE_FORMAT_MAX_VALUE: GhosttyKittyImageFormat = 2147483647; #[doc = " Pixel format of a Kitty graphics image.\n\n Note that stored images are always fully decoded:\n GHOSTTY_KITTY_IMAGE_FORMAT_PNG is never returned by\n ghostty_kitty_graphics_image_get() because PNG payloads are decoded\n to GHOSTTY_KITTY_IMAGE_FORMAT_RGBA before storage. The PNG value\n exists only for protocol-level completeness.\n\n @ingroup kitty_graphics"] -pub type GhosttyKittyImageFormat = ::std::os::raw::c_uint; +pub type GhosttyKittyImageFormat = ::std::os::raw::c_int; pub const GhosttyKittyImageCompression_GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE: GhosttyKittyImageCompression = 0; pub const GhosttyKittyImageCompression_GHOSTTY_KITTY_IMAGE_COMPRESSION_ZLIB_DEFLATE: @@ -1860,7 +2038,7 @@ pub const GhosttyKittyImageCompression_GHOSTTY_KITTY_IMAGE_COMPRESSION_ZLIB_DEFL pub const GhosttyKittyImageCompression_GHOSTTY_KITTY_IMAGE_COMPRESSION_MAX_VALUE: GhosttyKittyImageCompression = 2147483647; #[doc = " Compression of a Kitty graphics image.\n\n Note that stored images are always decompressed:\n GHOSTTY_KITTY_IMAGE_COMPRESSION_ZLIB_DEFLATE payloads are inflated\n before storage, so ghostty_kitty_graphics_image_get() always reports\n GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE. Consumers never need to\n inflate image data themselves.\n\n @ingroup kitty_graphics"] -pub type GhosttyKittyImageCompression = ::std::os::raw::c_uint; +pub type GhosttyKittyImageCompression = ::std::os::raw::c_int; #[doc = " Invalid / sentinel value."] pub const GhosttyKittyGraphicsImageData_GHOSTTY_KITTY_IMAGE_DATA_INVALID: GhosttyKittyGraphicsImageData = 0; @@ -1882,20 +2060,20 @@ pub const GhosttyKittyGraphicsImageData_GHOSTTY_KITTY_IMAGE_DATA_FORMAT: #[doc = " Compression of the image. Always\n GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE; compressed payloads are\n inflated before storage.\n\n Output type: GhosttyKittyImageCompression *"] pub const GhosttyKittyGraphicsImageData_GHOSTTY_KITTY_IMAGE_DATA_COMPRESSION: GhosttyKittyGraphicsImageData = 6; -#[doc = " Borrowed pointer to the raw pixel data. Valid as long as the\n underlying terminal is not mutated.\n\n The data is always fully decoded, uncompressed pixels in the\n format reported by GHOSTTY_KITTY_IMAGE_DATA_FORMAT: zlib payloads\n are inflated and PNG payloads are decoded to RGBA at transmission\n time, before the image is stored. Consumers can upload this\n directly to the GPU without any decode step.\n\n Output type: const uint8_t **"] +#[doc = " Borrowed pointer to the raw pixel data. Valid as long as the\n underlying terminal is not mutated. Returns GHOSTTY_NO_VALUE when\n the image metadata is resident but its pixel payload is pending.\n\n The data is always fully decoded, uncompressed pixels in the\n format reported by GHOSTTY_KITTY_IMAGE_DATA_FORMAT: zlib payloads\n are inflated and PNG payloads are decoded to RGBA at transmission\n time, before the image is stored. Consumers can upload this\n directly to the GPU without any decode step.\n\n For an animated image (Kitty graphics animation, actions a=f/a=a)\n this is the pixel data of the current animation frame. The\n image's GHOSTTY_KITTY_IMAGE_DATA_GENERATION changes whenever the\n current frame changes, so generation-keyed caches remain\n coherent.\n\n Output type: const uint8_t **"] pub const GhosttyKittyGraphicsImageData_GHOSTTY_KITTY_IMAGE_DATA_DATA_PTR: GhosttyKittyGraphicsImageData = 7; -#[doc = " Length of the raw pixel data in bytes. Always equal to\n width * height * bytes-per-pixel for the reported format.\n\n Output type: size_t *"] +#[doc = " Length of the raw pixel data in bytes. Always equal to\n width * height * bytes-per-pixel for the reported format. For a\n pending image, this is the expected length reserved against the\n storage limit even though DATA_PTR is not available yet.\n\n Output type: size_t *"] pub const GhosttyKittyGraphicsImageData_GHOSTTY_KITTY_IMAGE_DATA_DATA_LEN: GhosttyKittyGraphicsImageData = 8; -#[doc = " Generation stamp assigned when this image was added to (or\n replaced in) the storage. A changed generation for a given image\n ID means the pixel contents may have changed even when the\n dimensions, format, and data length are identical (e.g. a\n retransmission of the same image ID), so texture caches must key\n staleness on this value rather than on size heuristics.\n\n Stamps are unique and monotonically increasing process-wide and\n are drawn from the same sequence as\n GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION. Never zero for a stored\n image, so zero can be used as an \"empty\" sentinel by callers.\n\n Output type: uint64_t *"] +#[doc = " Generation stamp assigned when this image was added to (or\n replaced in) the storage. A changed generation for a given image\n ID means the pixel contents may have changed even when the\n dimensions, format, and data length are identical (e.g. a\n retransmission of the same image ID), so texture caches must key\n staleness on this value rather than on size heuristics.\n\n Stamps are unique and monotonically increasing process-wide and\n are drawn from the same sequence as\n GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION. Never zero for a stored\n image, so zero can be used as an \"empty\" sentinel by callers. Pending\n payload completion preserves this value to retain image age; consumers\n detect that completion through GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION\n and retry DATA_PTR.\n\n Output type: uint64_t *"] pub const GhosttyKittyGraphicsImageData_GHOSTTY_KITTY_IMAGE_DATA_GENERATION: GhosttyKittyGraphicsImageData = 9; -#[doc = " Generation stamp assigned when this image was added to (or\n replaced in) the storage. A changed generation for a given image\n ID means the pixel contents may have changed even when the\n dimensions, format, and data length are identical (e.g. a\n retransmission of the same image ID), so texture caches must key\n staleness on this value rather than on size heuristics.\n\n Stamps are unique and monotonically increasing process-wide and\n are drawn from the same sequence as\n GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION. Never zero for a stored\n image, so zero can be used as an \"empty\" sentinel by callers.\n\n Output type: uint64_t *"] +#[doc = " Generation stamp assigned when this image was added to (or\n replaced in) the storage. A changed generation for a given image\n ID means the pixel contents may have changed even when the\n dimensions, format, and data length are identical (e.g. a\n retransmission of the same image ID), so texture caches must key\n staleness on this value rather than on size heuristics.\n\n Stamps are unique and monotonically increasing process-wide and\n are drawn from the same sequence as\n GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION. Never zero for a stored\n image, so zero can be used as an \"empty\" sentinel by callers. Pending\n payload completion preserves this value to retain image age; consumers\n detect that completion through GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION\n and retry DATA_PTR.\n\n Output type: uint64_t *"] pub const GhosttyKittyGraphicsImageData_GHOSTTY_KITTY_IMAGE_DATA_MAX_VALUE: GhosttyKittyGraphicsImageData = 2147483647; #[doc = " Queryable data kinds for ghostty_kitty_graphics_image_get().\n\n @ingroup kitty_graphics"] -pub type GhosttyKittyGraphicsImageData = ::std::os::raw::c_uint; +pub type GhosttyKittyGraphicsImageData = ::std::os::raw::c_int; #[doc = " Combined rendering geometry for a placement in a single sized struct.\n\n Combines the results of ghostty_kitty_graphics_placement_pixel_size(),\n ghostty_kitty_graphics_placement_grid_size(),\n ghostty_kitty_graphics_placement_viewport_pos(), and\n ghostty_kitty_graphics_placement_source_rect() into one call. This is\n an optimization over calling those four functions individually,\n particularly useful in environments with high per-call overhead such\n as FFI or Cgo.\n\n This struct uses the sized-struct ABI pattern. Initialize with\n GHOSTTY_INIT_SIZED(GhosttyKittyGraphicsPlacementRenderInfo) before calling\n ghostty_kitty_graphics_placement_render_info().\n\n @ingroup kitty_graphics"] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -2095,29 +2273,6 @@ unsafe extern "C" { out_info: *mut GhosttyKittyGraphicsPlacementRenderInfo, ) -> GhosttyResult; } -#[doc = " Terminal initialization options.\n\n @ingroup terminal"] -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct GhosttyTerminalOptions { - #[doc = " Terminal width in cells. Must be greater than zero."] - pub cols: u16, - #[doc = " Terminal height in cells. Must be greater than zero."] - pub rows: u16, - #[doc = " Maximum number of lines to keep in scrollback history."] - pub max_scrollback: usize, -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of GhosttyTerminalOptions"][::std::mem::size_of::() - 16usize]; - ["Alignment of GhosttyTerminalOptions"] - [::std::mem::align_of::() - 8usize]; - ["Offset of field: GhosttyTerminalOptions::cols"] - [::std::mem::offset_of!(GhosttyTerminalOptions, cols) - 0usize]; - ["Offset of field: GhosttyTerminalOptions::rows"] - [::std::mem::offset_of!(GhosttyTerminalOptions, rows) - 2usize]; - ["Offset of field: GhosttyTerminalOptions::max_scrollback"] - [::std::mem::offset_of!(GhosttyTerminalOptions, max_scrollback) - 8usize]; -}; #[doc = " Perform one bounded compression step suitable for idle scheduling."] pub const GhosttyTerminalCompressionMode_GHOSTTY_TERMINAL_COMPRESSION_MODE_INCREMENTAL: GhosttyTerminalCompressionMode = 0; @@ -2128,7 +2283,7 @@ pub const GhosttyTerminalCompressionMode_GHOSTTY_TERMINAL_COMPRESSION_MODE_FULL: pub const GhosttyTerminalCompressionMode_GHOSTTY_TERMINAL_COMPRESSION_MODE_MAX_VALUE: GhosttyTerminalCompressionMode = 2147483647; #[doc = " Amount of compression work to perform before returning.\n\n @ingroup terminal"] -pub type GhosttyTerminalCompressionMode = ::std::os::raw::c_uint; +pub type GhosttyTerminalCompressionMode = ::std::os::raw::c_int; #[doc = " Retained-mapping reclamation is unavailable on this target."] pub const GhosttyTerminalCompressionResult_GHOSTTY_TERMINAL_COMPRESSION_RESULT_UNSUPPORTED: GhosttyTerminalCompressionResult = 0; @@ -2142,7 +2297,7 @@ pub const GhosttyTerminalCompressionResult_GHOSTTY_TERMINAL_COMPRESSION_RESULT_C pub const GhosttyTerminalCompressionResult_GHOSTTY_TERMINAL_COMPRESSION_RESULT_MAX_VALUE: GhosttyTerminalCompressionResult = 2147483647; #[doc = " Scheduling result from terminal compression.\n\n @ingroup terminal"] -pub type GhosttyTerminalCompressionResult = ::std::os::raw::c_uint; +pub type GhosttyTerminalCompressionResult = ::std::os::raw::c_int; #[doc = " Scroll to the top of the scrollback."] pub const GhosttyTerminalScrollViewportTag_GHOSTTY_SCROLL_VIEWPORT_TOP: GhosttyTerminalScrollViewportTag = 0; @@ -2159,7 +2314,7 @@ pub const GhosttyTerminalScrollViewportTag_GHOSTTY_SCROLL_VIEWPORT_ROW: pub const GhosttyTerminalScrollViewportTag_GHOSTTY_SCROLL_VIEWPORT_MAX_VALUE: GhosttyTerminalScrollViewportTag = 2147483647; #[doc = " Scroll viewport behavior tag.\n\n @ingroup terminal"] -pub type GhosttyTerminalScrollViewportTag = ::std::os::raw::c_uint; +pub type GhosttyTerminalScrollViewportTag = ::std::os::raw::c_int; #[doc = " Scroll viewport value.\n\n @ingroup terminal"] #[repr(C)] #[derive(Copy, Clone)] @@ -2228,7 +2383,7 @@ pub const GhosttyTerminalScreen_GHOSTTY_TERMINAL_SCREEN_ALTERNATE: GhosttyTermin pub const GhosttyTerminalScreen_GHOSTTY_TERMINAL_SCREEN_MAX_VALUE: GhosttyTerminalScreen = 2147483647; #[doc = " Terminal screen identifier.\n\n Identifies which screen buffer is active in the terminal.\n\n @ingroup terminal"] -pub type GhosttyTerminalScreen = ::std::os::raw::c_uint; +pub type GhosttyTerminalScreen = ::std::os::raw::c_int; #[doc = " Bar cursor (DECSCUSR 5, 6)."] pub const GhosttyTerminalCursorStyle_GHOSTTY_TERMINAL_CURSOR_STYLE_BAR: GhosttyTerminalCursorStyle = 0; @@ -2245,7 +2400,7 @@ pub const GhosttyTerminalCursorStyle_GHOSTTY_TERMINAL_CURSOR_STYLE_BLOCK_HOLLOW: pub const GhosttyTerminalCursorStyle_GHOSTTY_TERMINAL_CURSOR_STYLE_MAX_VALUE: GhosttyTerminalCursorStyle = 2147483647; #[doc = " Visual style of the terminal cursor.\n\n @ingroup terminal"] -pub type GhosttyTerminalCursorStyle = ::std::os::raw::c_uint; +pub type GhosttyTerminalCursorStyle = ::std::os::raw::c_int; #[doc = " Scrollbar state for the terminal viewport.\n\n Represents the scrollable area dimensions needed to render a scrollbar.\n\n @ingroup terminal"] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -2274,6 +2429,107 @@ const _: () = { pub type GhosttyTerminalBellFn = ::std::option::Option< unsafe extern "C" fn(terminal: GhosttyTerminal, userdata: *mut ::std::os::raw::c_void), >; +#[doc = " Application Program Command (APC)."] +pub const GhosttyTerminalUnknownSequenceTag_GHOSTTY_TERMINAL_UNKNOWN_SEQUENCE_APC: + GhosttyTerminalUnknownSequenceTag = 0; +#[doc = " Application Program Command (APC)."] +pub const GhosttyTerminalUnknownSequenceTag_GHOSTTY_TERMINAL_UNKNOWN_SEQUENCE_MAX_VALUE: + GhosttyTerminalUnknownSequenceTag = 2147483647; +#[doc = " Unsupported terminal sequence tags.\n\n Only APC sequences are currently reported. Additional sequence types may\n be added without changing the callback shape.\n\n @ingroup terminal"] +pub type GhosttyTerminalUnknownSequenceTag = ::std::os::raw::c_int; +#[doc = " An unsupported string terminal sequence.\n\n The content is borrowed and valid only for the callback duration. It\n contains the bytes between the sequence introducer and terminator, may\n contain arbitrary binary data, and is not null-terminated.\n\n @ingroup terminal"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyTerminalUnknownStringSequence { + #[doc = " Whether content was shortened by the byte limit or allocation failure."] + pub truncated: bool, + #[doc = " Retained sequence content."] + pub content: GhosttyString, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyTerminalUnknownStringSequence"] + [::std::mem::size_of::() - 24usize]; + ["Alignment of GhosttyTerminalUnknownStringSequence"] + [::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyTerminalUnknownStringSequence::truncated"] + [::std::mem::offset_of!(GhosttyTerminalUnknownStringSequence, truncated) - 0usize]; + ["Offset of field: GhosttyTerminalUnknownStringSequence::content"] + [::std::mem::offset_of!(GhosttyTerminalUnknownStringSequence, content) - 8usize]; +}; +impl Default for GhosttyTerminalUnknownStringSequence { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " Unsupported terminal sequence value.\n\n @ingroup terminal"] +#[repr(C)] +#[derive(Copy, Clone)] +pub union GhosttyTerminalUnknownSequenceValue { + #[doc = " Application Program Command (APC)."] + pub apc: GhosttyTerminalUnknownStringSequence, + #[doc = " Padding for ABI compatibility. Do not use.\n\n 128 bytes leaves room for future structured sequence payloads, such as\n CSI with borrowed parameter, separator, and intermediate arrays, without\n changing the tagged union's ABI."] + pub _padding: [u64; 16usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyTerminalUnknownSequenceValue"] + [::std::mem::size_of::() - 128usize]; + ["Alignment of GhosttyTerminalUnknownSequenceValue"] + [::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyTerminalUnknownSequenceValue::apc"] + [::std::mem::offset_of!(GhosttyTerminalUnknownSequenceValue, apc) - 0usize]; + ["Offset of field: GhosttyTerminalUnknownSequenceValue::_padding"] + [::std::mem::offset_of!(GhosttyTerminalUnknownSequenceValue, _padding) - 0usize]; +}; +impl Default for GhosttyTerminalUnknownSequenceValue { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " An unsupported terminal sequence.\n\n @ingroup terminal"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct GhosttyTerminalUnknownSequence { + pub tag: GhosttyTerminalUnknownSequenceTag, + pub value: GhosttyTerminalUnknownSequenceValue, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyTerminalUnknownSequence"] + [::std::mem::size_of::() - 136usize]; + ["Alignment of GhosttyTerminalUnknownSequence"] + [::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyTerminalUnknownSequence::tag"] + [::std::mem::offset_of!(GhosttyTerminalUnknownSequence, tag) - 0usize]; + ["Offset of field: GhosttyTerminalUnknownSequence::value"] + [::std::mem::offset_of!(GhosttyTerminalUnknownSequence, value) - 8usize]; +}; +impl Default for GhosttyTerminalUnknownSequence { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " Callback function type for unsupported terminal sequences.\n\n Called synchronously for normally terminated sequences whose identifier is\n not supported by the active terminal handler. Aborted sequences, malformed\n recognized commands, and explicitly disabled known protocols are ignored.\n\n Capture must also be enabled with a nonzero\n GHOSTTY_TERMINAL_OPT_UNKNOWN_MAX_BYTES value. Installing this callback alone\n does not retain sequence content or allocate memory.\n\n @param terminal The terminal handle\n @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA\n @param sequence Borrowed unsupported sequence\n\n @ingroup terminal"] +pub type GhosttyTerminalUnknownSequenceFn = ::std::option::Option< + unsafe extern "C" fn( + terminal: GhosttyTerminal, + userdata: *mut ::std::os::raw::c_void, + sequence: *const GhosttyTerminalUnknownSequence, + ), +>; #[doc = " The standard system clipboard."] pub const GhosttyClipboardLocation_GHOSTTY_CLIPBOARD_LOCATION_STANDARD: GhosttyClipboardLocation = 0; @@ -2286,7 +2542,7 @@ pub const GhosttyClipboardLocation_GHOSTTY_CLIPBOARD_LOCATION_PRIMARY: GhosttyCl pub const GhosttyClipboardLocation_GHOSTTY_CLIPBOARD_LOCATION_MAX_VALUE: GhosttyClipboardLocation = 2147483647; #[doc = " Clipboard destination for a clipboard write.\n\n Protocol-specific destination identifiers are normalized to these values\n before the clipboard write callback is invoked.\n\n @ingroup terminal"] -pub type GhosttyClipboardLocation = ::std::os::raw::c_uint; +pub type GhosttyClipboardLocation = ::std::os::raw::c_int; #[doc = " One MIME representation in a clipboard write.\n\n Both strings are borrowed and valid only for the duration of the callback.\n The data is binary-safe and has already been decoded from any protocol-level\n encoding. A zero-length data string is an explicit empty representation; it\n does not clear the clipboard.\n\n This struct has a frozen layout and will not gain fields in future versions.\n\n @ingroup terminal"] #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -2315,7 +2571,70 @@ impl Default for GhosttyClipboardContent { } } } -#[doc = " A semantic, atomic clipboard write.\n\n This is a sized struct. The callback must only access fields present in the\n size reported by `size`. The request, contents array, MIME strings, and\n data strings are all borrowed and valid only for the callback duration.\n\n All entries in `contents` are representations of the same logical value\n and must be committed atomically. A `contents_len` of zero requests that\n the destination be cleared. This is distinct from a content entry whose data\n has zero length.\n\n @ingroup terminal"] +#[doc = " The clipboard write completed successfully."] +pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_SUCCESS: + GhosttyClipboardWriteResult = 0; +#[doc = " The clipboard write was denied by policy or the user."] +pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_DENIED: + GhosttyClipboardWriteResult = 1; +#[doc = " The destination or one or more representations are unsupported."] +pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_UNSUPPORTED: + GhosttyClipboardWriteResult = 2; +#[doc = " The clipboard is temporarily unavailable."] +pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_BUSY: + GhosttyClipboardWriteResult = 3; +#[doc = " One or more representations contain invalid data."] +pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_INVALID_DATA: + GhosttyClipboardWriteResult = 4; +#[doc = " The clipboard write failed due to an I/O error."] +pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_IO_ERROR: + GhosttyClipboardWriteResult = 5; +#[doc = " The clipboard write failed due to an I/O error."] +pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_MAX_VALUE: + GhosttyClipboardWriteResult = 2147483647; +#[doc = " Result of a clipboard write reply.\n\n @ingroup terminal"] +pub type GhosttyClipboardWriteResult = ::std::os::raw::c_int; +#[doc = " The reply to a clipboard write request.\n\n This is a sized struct; set `size` to `sizeof(GhosttyClipboardWriteReply)`.\n The reply is borrowed only for the duration of the reply call and may be\n freed as soon as it returns.\n\n The result answers the program with the matching protocol status for\n protocols with a write acknowledgement (OSC 5522: DONE, EPERM, ENOSYS,\n EBUSY, EINVAL, EIO); protocols without one (OSC 52, OSC 1337 Copy)\n discard the reply. `remember` is ignored on any result other than\n GHOSTTY_CLIPBOARD_WRITE_RESULT_SUCCESS.\n\n @ingroup terminal"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyClipboardWriteReply { + #[doc = " Size of this struct in bytes."] + pub size: usize, + #[doc = " Outcome of the write."] + pub result: GhosttyClipboardWriteResult, + #[doc = " Record a session grant so future requests from the same program skip\n the permission prompt. Only honored on success when\n GhosttyClipboardWrite::can_remember is set."] + pub remember: bool, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyClipboardWriteReply"] + [::std::mem::size_of::() - 16usize]; + ["Alignment of GhosttyClipboardWriteReply"] + [::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyClipboardWriteReply::size"] + [::std::mem::offset_of!(GhosttyClipboardWriteReply, size) - 0usize]; + ["Offset of field: GhosttyClipboardWriteReply::result"] + [::std::mem::offset_of!(GhosttyClipboardWriteReply, result) - 8usize]; + ["Offset of field: GhosttyClipboardWriteReply::remember"] + [::std::mem::offset_of!(GhosttyClipboardWriteReply, remember) - 12usize]; +}; +impl Default for GhosttyClipboardWriteReply { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " Function type used to answer a clipboard write request. Obtained from\n GhosttyClipboardWrite::reply; see that struct for the contract.\n\n @param write The request being answered\n @param reply The reply, borrowed only for the duration of this call\n\n @ingroup terminal"] +pub type GhosttyClipboardWriteReplyFn = ::std::option::Option< + unsafe extern "C" fn( + write: *const GhosttyClipboardWrite, + reply: *const GhosttyClipboardWriteReply, + ), +>; +#[doc = " A synchronous request to write clipboard contents.\n\n This is a sized struct. The callback must only access fields present in the\n size reported by `size`. The request, contents array, MIME strings, and\n data strings are all borrowed and valid only for the callback duration.\n\n All entries in `contents` are representations of the same logical value\n and must be committed atomically. A `contents_len` of zero requests that\n the destination be cleared. This is distinct from a content entry whose data\n has zero length.\n\n The write is answered by calling `reply` with this request and a\n GhosttyClipboardWriteReply. This must happen within the clipboard write\n request callback. This struct is only valid during that time. Calling\n `reply` more than once is safely ignored. Returning without replying\n denies the write.\n\n @ingroup terminal"] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct GhosttyClipboardWrite { @@ -2327,10 +2646,20 @@ pub struct GhosttyClipboardWrite { pub contents: *const GhosttyClipboardContent, #[doc = " Number of entries in contents; zero means clear the destination."] pub contents_len: usize, + #[doc = " Name of the writing program for permission prompts, if the protocol\n carries one. Empty otherwise."] + pub name: GhosttyString, + #[doc = " True if the terminal already holds a session grant for this request\n The embedder should skip any permission prompt and perform the write."] + pub granted: bool, + #[doc = " True if the program supplied a session password, so the embedder may\n offer to remember the user's decision through\n GhosttyClipboardWriteReply::remember. When false, remember is ignored."] + pub can_remember: bool, + #[doc = " Terminal-owned reply state. Do not access."] + pub ctx: *const ::std::os::raw::c_void, + #[doc = " Answer the write; see the struct documentation."] + pub reply: GhosttyClipboardWriteReplyFn, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { - ["Size of GhosttyClipboardWrite"][::std::mem::size_of::() - 32usize]; + ["Size of GhosttyClipboardWrite"][::std::mem::size_of::() - 72usize]; ["Alignment of GhosttyClipboardWrite"] [::std::mem::align_of::() - 8usize]; ["Offset of field: GhosttyClipboardWrite::size"] @@ -2341,6 +2670,16 @@ const _: () = { [::std::mem::offset_of!(GhosttyClipboardWrite, contents) - 16usize]; ["Offset of field: GhosttyClipboardWrite::contents_len"] [::std::mem::offset_of!(GhosttyClipboardWrite, contents_len) - 24usize]; + ["Offset of field: GhosttyClipboardWrite::name"] + [::std::mem::offset_of!(GhosttyClipboardWrite, name) - 32usize]; + ["Offset of field: GhosttyClipboardWrite::granted"] + [::std::mem::offset_of!(GhosttyClipboardWrite, granted) - 48usize]; + ["Offset of field: GhosttyClipboardWrite::can_remember"] + [::std::mem::offset_of!(GhosttyClipboardWrite, can_remember) - 49usize]; + ["Offset of field: GhosttyClipboardWrite::ctx"] + [::std::mem::offset_of!(GhosttyClipboardWrite, ctx) - 56usize]; + ["Offset of field: GhosttyClipboardWrite::reply"] + [::std::mem::offset_of!(GhosttyClipboardWrite, reply) - 64usize]; }; impl Default for GhosttyClipboardWrite { fn default() -> Self { @@ -2351,36 +2690,258 @@ impl Default for GhosttyClipboardWrite { } } } -#[doc = " The clipboard write completed successfully."] -pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_SUCCESS: - GhosttyClipboardWriteResult = 0; -#[doc = " The clipboard write was denied by policy or the user."] -pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_DENIED: - GhosttyClipboardWriteResult = 1; -#[doc = " The destination or one or more representations are unsupported."] -pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_UNSUPPORTED: - GhosttyClipboardWriteResult = 2; -#[doc = " The clipboard is temporarily unavailable."] -pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_BUSY: - GhosttyClipboardWriteResult = 3; -#[doc = " One or more representations contain invalid data."] -pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_INVALID_DATA: - GhosttyClipboardWriteResult = 4; -#[doc = " The clipboard write failed due to an I/O error."] -pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_IO_ERROR: - GhosttyClipboardWriteResult = 5; -#[doc = " The clipboard write failed due to an I/O error."] -pub const GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_MAX_VALUE: - GhosttyClipboardWriteResult = 2147483647; -#[doc = " Result of a clipboard write callback.\n\n Protocols without write acknowledgements, including OSC 52 and iTerm2\n OSC 1337 Copy, ignore this result.\n\n @ingroup terminal"] -pub type GhosttyClipboardWriteResult = ::std::os::raw::c_uint; -#[doc = " Callback function type for clipboard_write.\n\n Called synchronously for a complete logical clipboard write. Protocol\n details such as OSC 52 selectors, base64 encoding, multipart chunks,\n aliases, and terminators are normalized before this callback is invoked.\n OSC 52 and iTerm2 OSC 1337 Copy writes therefore use the same callback\n shape. OSC 52 clipboard read requests (\"?\") are always ignored and never\n forwarded to this callback.\n\n @param terminal The terminal handle\n @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA\n @param write Borrowed atomic clipboard write request\n @return The result of attempting the clipboard write\n\n @ingroup terminal"] +#[doc = " Callback function type for clipboard_write.\n\n The embedder may ask for permission to write or perform the write\n async, but the callback itself is synchronous and the reply function\n must be called during the lifetime of this function. While this callback\n is active the VT stream is paused.\n\n Answer by calling `write->reply(write, &reply)` before returning. See\n GhosttyClipboardWrite for the full contract.\n\n The request may carry an optional program name requesting the write\n and the state of prior permission granted. If `can_remember` is set\n the response may set the `remember` flag and future requests from this\n same program will be \"granted\" and the embedder can skip permission\n requests.\n\n Clipboard read requests (OSC 52 \"?\" and OSC 5522 reads) are delivered\n to GhosttyTerminalClipboardReadFn instead.\n\n @param terminal The terminal handle\n @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA\n @param write Borrowed atomic clipboard write request\n\n @ingroup terminal"] pub type GhosttyTerminalClipboardWriteFn = ::std::option::Option< unsafe extern "C" fn( terminal: GhosttyTerminal, userdata: *mut ::std::os::raw::c_void, write: *const GhosttyClipboardWrite, - ) -> GhosttyClipboardWriteResult, + ), +>; +#[doc = " The clipboard was read; the reply carries its contents."] +pub const GhosttyClipboardReadResult_GHOSTTY_CLIPBOARD_READ_RESULT_SUCCESS: + GhosttyClipboardReadResult = 0; +#[doc = " The clipboard read was denied by policy or the user."] +pub const GhosttyClipboardReadResult_GHOSTTY_CLIPBOARD_READ_RESULT_DENIED: + GhosttyClipboardReadResult = 1; +#[doc = " The embedder cannot read this clipboard."] +pub const GhosttyClipboardReadResult_GHOSTTY_CLIPBOARD_READ_RESULT_UNSUPPORTED: + GhosttyClipboardReadResult = 2; +#[doc = " The clipboard is temporarily unavailable."] +pub const GhosttyClipboardReadResult_GHOSTTY_CLIPBOARD_READ_RESULT_BUSY: + GhosttyClipboardReadResult = 3; +#[doc = " Reading the clipboard failed due to an I/O error."] +pub const GhosttyClipboardReadResult_GHOSTTY_CLIPBOARD_READ_RESULT_IO_ERROR: + GhosttyClipboardReadResult = 4; +#[doc = " Reading the clipboard failed due to an I/O error."] +pub const GhosttyClipboardReadResult_GHOSTTY_CLIPBOARD_READ_RESULT_MAX_VALUE: + GhosttyClipboardReadResult = 2147483647; +#[doc = " Result of a clipboard read reply.\n\n @ingroup terminal"] +pub type GhosttyClipboardReadResult = ::std::os::raw::c_int; +#[doc = " The reply to a clipboard read request.\n\n This is a sized struct; set `size` to `sizeof(GhosttyClipboardReadReply)`.\n All arrays and the strings they point to are borrowed only for the\n duration of the reply call and may be freed as soon as it returns.\n\n Any result other than GHOSTTY_CLIPBOARD_READ_RESULT_SUCCESS answers the\n program with an empty clipboard (OSC 52) or the matching protocol status\n (OSC 5522: EPERM, ENOSYS, EBUSY, EIO); the other fields are ignored in\n that case. On success, `contents` should carry one representation per\n requested MIME type (GhosttyClipboardRead::mimes) that the clipboard\n has; unrequested representations are ignored. Protocols that carry a\n single text value (OSC 52) use the first entry with a text MIME type\n such as \"text/plain\".\n\n @ingroup terminal"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyClipboardReadReply { + #[doc = " Size of this struct in bytes."] + pub size: usize, + #[doc = " Outcome of the read."] + pub result: GhosttyClipboardReadResult, + #[doc = " Borrowed array of MIME representations of the clipboard contents."] + pub contents: *const GhosttyClipboardContent, + #[doc = " Number of entries in contents."] + pub contents_len: usize, + #[doc = " Borrowed array of all MIME types available on the clipboard. Only\n used when GhosttyClipboardRead::list is set; may be NULL otherwise."] + pub available: *const GhosttyString, + #[doc = " Number of entries in available."] + pub available_len: usize, + #[doc = " Record a session grant so future requests from the same program skip\n the permission prompt. Only honored on success when\n GhosttyClipboardRead::can_remember is set."] + pub remember: bool, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyClipboardReadReply"] + [::std::mem::size_of::() - 56usize]; + ["Alignment of GhosttyClipboardReadReply"] + [::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyClipboardReadReply::size"] + [::std::mem::offset_of!(GhosttyClipboardReadReply, size) - 0usize]; + ["Offset of field: GhosttyClipboardReadReply::result"] + [::std::mem::offset_of!(GhosttyClipboardReadReply, result) - 8usize]; + ["Offset of field: GhosttyClipboardReadReply::contents"] + [::std::mem::offset_of!(GhosttyClipboardReadReply, contents) - 16usize]; + ["Offset of field: GhosttyClipboardReadReply::contents_len"] + [::std::mem::offset_of!(GhosttyClipboardReadReply, contents_len) - 24usize]; + ["Offset of field: GhosttyClipboardReadReply::available"] + [::std::mem::offset_of!(GhosttyClipboardReadReply, available) - 32usize]; + ["Offset of field: GhosttyClipboardReadReply::available_len"] + [::std::mem::offset_of!(GhosttyClipboardReadReply, available_len) - 40usize]; + ["Offset of field: GhosttyClipboardReadReply::remember"] + [::std::mem::offset_of!(GhosttyClipboardReadReply, remember) - 48usize]; +}; +impl Default for GhosttyClipboardReadReply { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " Function type used to answer a clipboard read request. Obtained from\n GhosttyClipboardRead::reply; see that struct for the contract.\n\n @param read The request being answered\n @param reply The reply, borrowed only for the duration of this call\n\n @ingroup terminal"] +pub type GhosttyClipboardReadReplyFn = ::std::option::Option< + unsafe extern "C" fn( + read: *const GhosttyClipboardRead, + reply: *const GhosttyClipboardReadReply, + ), +>; +#[doc = " A synchronous request to read clipboard contents.\n\n This is a sized struct. The callback must only access fields present in the\n size reported by `size`. The request is borrowed and valid only for the\n callback duration.\n\n The read is answered by calling `reply` with this request and a\n GhosttyClipboardReadReply. This must happen before the callback returns;\n the request is invalid afterwards. Calling `reply` more than once is\n ignored. Returning without replying answers the program with an empty\n clipboard (OSC 52) or EPERM (OSC 5522).\n\n @ingroup terminal"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyClipboardRead { + #[doc = " Size of this struct in bytes."] + pub size: usize, + #[doc = " Clipboard to read."] + pub location: GhosttyClipboardLocation, + #[doc = " Borrowed array of the MIME types the program wants, in order of\n preference. Protocols that only carry text (OSC 52) request\n \"text/plain\". NULL when mimes_len is zero."] + pub mimes: *const GhosttyString, + #[doc = " Number of entries in mimes."] + pub mimes_len: usize, + #[doc = " True if the program also wants the list of MIME types available on the\n clipboard, delivered through GhosttyClipboardReadReply::available."] + pub list: bool, + #[doc = " Name of the requesting program for permission prompts, if the protocol\n carries one. Empty otherwise."] + pub name: GhosttyString, + #[doc = " True if the terminal already holds a session grant for this request\n (kitty clipboard protocol passwords). The embedder should skip any\n permission prompt and serve the read.\n\n Always false when mimes_len is zero: such a request is served\n without a prompt (see the callback docs), so the terminal never\n consults grants for it and a one-time password is preserved for\n the follow-up data read."] + pub granted: bool, + #[doc = " True if the program supplied a session password, so the embedder may\n offer to remember the user's decision through\n GhosttyClipboardReadReply::remember. When false, remember is ignored."] + pub can_remember: bool, + #[doc = " Terminal-owned reply state. Do not access."] + pub ctx: *const ::std::os::raw::c_void, + #[doc = " Answer the read; see the struct documentation."] + pub reply: GhosttyClipboardReadReplyFn, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyClipboardRead"][::std::mem::size_of::() - 80usize]; + ["Alignment of GhosttyClipboardRead"][::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyClipboardRead::size"] + [::std::mem::offset_of!(GhosttyClipboardRead, size) - 0usize]; + ["Offset of field: GhosttyClipboardRead::location"] + [::std::mem::offset_of!(GhosttyClipboardRead, location) - 8usize]; + ["Offset of field: GhosttyClipboardRead::mimes"] + [::std::mem::offset_of!(GhosttyClipboardRead, mimes) - 16usize]; + ["Offset of field: GhosttyClipboardRead::mimes_len"] + [::std::mem::offset_of!(GhosttyClipboardRead, mimes_len) - 24usize]; + ["Offset of field: GhosttyClipboardRead::list"] + [::std::mem::offset_of!(GhosttyClipboardRead, list) - 32usize]; + ["Offset of field: GhosttyClipboardRead::name"] + [::std::mem::offset_of!(GhosttyClipboardRead, name) - 40usize]; + ["Offset of field: GhosttyClipboardRead::granted"] + [::std::mem::offset_of!(GhosttyClipboardRead, granted) - 56usize]; + ["Offset of field: GhosttyClipboardRead::can_remember"] + [::std::mem::offset_of!(GhosttyClipboardRead, can_remember) - 57usize]; + ["Offset of field: GhosttyClipboardRead::ctx"] + [::std::mem::offset_of!(GhosttyClipboardRead, ctx) - 64usize]; + ["Offset of field: GhosttyClipboardRead::reply"] + [::std::mem::offset_of!(GhosttyClipboardRead, reply) - 72usize]; +}; +impl Default for GhosttyClipboardRead { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " Callback function type for clipboard_read.\n\n Called synchronously when the running program requests clipboard contents\n via OSC 52 with a \"?\" payload or a Kitty clipboard (OSC 5522) read.\n Answering lets the program read the user's clipboard, so the embedder is\n expected to mediate consent. Because the read is synchronous, an embedder\n that needs to ask the user must block (for example by running a modal\n prompt) until it has an answer; the VT stream waits until the callback\n returns.\n\n Answer by calling `read->reply(read, &reply)` before returning. See\n GhosttyClipboardRead for the full contract.\n\n OSC 5522 requests carry the program's MIME list, name, and password grant\n state; a reply that sets `remember` records a session grant so later\n requests with the same password arrive with `granted` set. Kitty itself\n serves a request for only the targets listing (`list` with no `mimes`)\n without prompting, and embedders are expected to do the same; the\n terminal never consults grants for such requests (`granted` is false\n and one-time passwords are not consumed).\n\n Installing this callback also enables Kitty paste events (mode 5522):\n ghostty_terminal_paste() sends the program an event instead of the text,\n and the program's follow-up read arrives here with `granted` set since\n the user already pasted. See ghostty_terminal_paste().\n\n @param terminal The terminal handle\n @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA\n @param read Borrowed clipboard read request\n\n @ingroup terminal"] +pub type GhosttyTerminalClipboardReadFn = ::std::option::Option< + unsafe extern "C" fn( + terminal: GhosttyTerminal, + userdata: *mut ::std::os::raw::c_void, + read: *const GhosttyClipboardRead, + ), +>; +#[doc = " A request to show a desktop notification.\n\n This is a sized struct. The callback must only access fields present in the\n size reported by `size`. Both strings are borrowed and valid only for the\n duration of the callback.\n\n @ingroup terminal"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyTerminalDesktopNotification { + #[doc = " Size of this struct in bytes."] + pub size: usize, + #[doc = " Notification title, or an empty string when the protocol omits it."] + pub title: GhosttyString, + #[doc = " Notification body."] + pub body: GhosttyString, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyTerminalDesktopNotification"] + [::std::mem::size_of::() - 40usize]; + ["Alignment of GhosttyTerminalDesktopNotification"] + [::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyTerminalDesktopNotification::size"] + [::std::mem::offset_of!(GhosttyTerminalDesktopNotification, size) - 0usize]; + ["Offset of field: GhosttyTerminalDesktopNotification::title"] + [::std::mem::offset_of!(GhosttyTerminalDesktopNotification, title) - 8usize]; + ["Offset of field: GhosttyTerminalDesktopNotification::body"] + [::std::mem::offset_of!(GhosttyTerminalDesktopNotification, body) - 24usize]; +}; +impl Default for GhosttyTerminalDesktopNotification { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " Callback function type for desktop notifications.\n\n Called synchronously when the terminal receives OSC 9 or OSC 777.\n\n @param terminal The terminal handle\n @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA\n @param notification Borrowed desktop notification request\n\n @ingroup terminal"] +pub type GhosttyTerminalDesktopNotificationFn = ::std::option::Option< + unsafe extern "C" fn( + terminal: GhosttyTerminal, + userdata: *mut ::std::os::raw::c_void, + notification: *const GhosttyTerminalDesktopNotification, + ), +>; +#[doc = " Remove any visible progress indication."] +pub const GhosttyTerminalProgressState_GHOSTTY_TERMINAL_PROGRESS_STATE_REMOVE: + GhosttyTerminalProgressState = 0; +#[doc = " Show determinate progress."] +pub const GhosttyTerminalProgressState_GHOSTTY_TERMINAL_PROGRESS_STATE_SET: + GhosttyTerminalProgressState = 1; +#[doc = " Show a failed progress state."] +pub const GhosttyTerminalProgressState_GHOSTTY_TERMINAL_PROGRESS_STATE_ERROR: + GhosttyTerminalProgressState = 2; +#[doc = " Show indeterminate progress."] +pub const GhosttyTerminalProgressState_GHOSTTY_TERMINAL_PROGRESS_STATE_INDETERMINATE: + GhosttyTerminalProgressState = 3; +#[doc = " Show paused progress."] +pub const GhosttyTerminalProgressState_GHOSTTY_TERMINAL_PROGRESS_STATE_PAUSE: + GhosttyTerminalProgressState = 4; +#[doc = " Show paused progress."] +pub const GhosttyTerminalProgressState_GHOSTTY_TERMINAL_PROGRESS_STATE_MAX_VALUE: + GhosttyTerminalProgressState = 2147483647; +#[doc = " State of a terminal progress report.\n\n @ingroup terminal"] +pub type GhosttyTerminalProgressState = ::std::os::raw::c_int; +#[doc = " A progress report emitted by the running program.\n\n This is a sized struct. The callback must only access fields present in the\n size reported by `size`.\n\n @ingroup terminal"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyTerminalProgressReport { + #[doc = " Size of this struct in bytes."] + pub size: usize, + #[doc = " Literal progress state reported by the running program."] + pub state: GhosttyTerminalProgressState, + #[doc = " Progress percentage from 0 through 100, or -1 when omitted."] + pub progress: i8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyTerminalProgressReport"] + [::std::mem::size_of::() - 16usize]; + ["Alignment of GhosttyTerminalProgressReport"] + [::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyTerminalProgressReport::size"] + [::std::mem::offset_of!(GhosttyTerminalProgressReport, size) - 0usize]; + ["Offset of field: GhosttyTerminalProgressReport::state"] + [::std::mem::offset_of!(GhosttyTerminalProgressReport, state) - 8usize]; + ["Offset of field: GhosttyTerminalProgressReport::progress"] + [::std::mem::offset_of!(GhosttyTerminalProgressReport, progress) - 12usize]; +}; +impl Default for GhosttyTerminalProgressReport { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " Callback function type for progress reports.\n\n Called synchronously when the terminal receives OSC 9;4.\n\n @param terminal The terminal handle\n @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA\n @param report Borrowed progress report\n\n @ingroup terminal"] +pub type GhosttyTerminalProgressReportFn = ::std::option::Option< + unsafe extern "C" fn( + terminal: GhosttyTerminal, + userdata: *mut ::std::os::raw::c_void, + report: *const GhosttyTerminalProgressReport, + ), >; #[doc = " Callback function type for color scheme queries (CSI ? 996 n).\n\n Called when the terminal receives a color scheme device status report\n query. Return true and fill *out_scheme with the current color scheme,\n or return false to silently ignore the query.\n\n @param terminal The terminal handle\n @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA\n @param[out] out_scheme Pointer to store the current color scheme\n @return true if the color scheme was filled, false to ignore the query\n\n @ingroup terminal"] pub type GhosttyTerminalColorSchemeFn = ::std::option::Option< @@ -2405,7 +2966,7 @@ pub type GhosttyTerminalEnquiryFn = ::std::option::Option< userdata: *mut ::std::os::raw::c_void, ) -> GhosttyString, >; -#[doc = " Callback function type for size queries (XTWINOPS).\n\n Called in response to XTWINOPS size queries (CSI 14/16/18 t).\n Return true and fill *out_size with the current terminal geometry,\n or return false to silently ignore the query.\n\n @param terminal The terminal handle\n @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA\n @param[out] out_size Pointer to store the terminal size information\n @return true if size was filled, false to ignore the query\n\n @ingroup terminal"] +#[doc = " Callback function type for terminal size reports.\n\n Called in response to XTWINOPS size queries (CSI 14/16/18 t) and when VT\n input enables in-band size reports (mode 2048).\n Return true and fill *out_size with the current terminal geometry,\n or return false to suppress the report.\n\n @param terminal The terminal handle\n @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA\n @param[out] out_size Pointer to store the terminal size information\n @return true if size was filled, false to suppress the XTWINOPS response or\n mode 2048 report\n\n @ingroup terminal"] pub type GhosttyTerminalSizeFn = ::std::option::Option< unsafe extern "C" fn( terminal: GhosttyTerminal, @@ -2421,7 +2982,7 @@ pub type GhosttyTerminalTitleChangedFn = ::std::option::Option< pub type GhosttyTerminalPwdChangedFn = ::std::option::Option< unsafe extern "C" fn(terminal: GhosttyTerminal, userdata: *mut ::std::os::raw::c_void), >; -#[doc = " Callback function type for write_pty.\n\n Called when the terminal needs to write data back to the pty, for\n example in response to a device status report or mode query. The\n data is only valid for the duration of the call; callers must copy\n it if it needs to persist.\n\n @param terminal The terminal handle\n @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA\n @param data Pointer to the response bytes\n @param len Length of the response in bytes\n\n @ingroup terminal"] +#[doc = " Callback function type for write_pty.\n\n Called when the terminal needs to write data back to the pty, for\n example in response to a device status report, mode query, or VT-driven\n mode 2048 enable. The data is only valid for the duration of the call;\n callers must copy it if it needs to persist.\n\n @param terminal The terminal handle\n @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA\n @param data Pointer to the response bytes\n @param len Length of the response in bytes\n\n @ingroup terminal"] pub type GhosttyTerminalWritePtyFn = ::std::option::Option< unsafe extern "C" fn( terminal: GhosttyTerminal, @@ -2437,9 +2998,29 @@ pub type GhosttyTerminalXtversionFn = ::std::option::Option< userdata: *mut ::std::os::raw::c_void, ) -> GhosttyString, >; +#[doc = " A terminal mode and boolean value used for mode configuration and queries.\n\n For GHOSTTY_TERMINAL_DATA_MODE, initialize `mode` before calling\n ghostty_terminal_get(). On success, `value` contains the current mode value.\n\n This struct has a frozen layout and will not gain fields in future versions.\n\n @ingroup terminal"] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct GhosttyTerminalModeConfig { + #[doc = " Mode to configure or query."] + pub mode: GhosttyMode, + #[doc = " Value to set, or the current value returned by a query."] + pub value: bool, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyTerminalModeConfig"] + [::std::mem::size_of::() - 4usize]; + ["Alignment of GhosttyTerminalModeConfig"] + [::std::mem::align_of::() - 2usize]; + ["Offset of field: GhosttyTerminalModeConfig::mode"] + [::std::mem::offset_of!(GhosttyTerminalModeConfig, mode) - 0usize]; + ["Offset of field: GhosttyTerminalModeConfig::value"] + [::std::mem::offset_of!(GhosttyTerminalModeConfig, value) - 2usize]; +}; #[doc = " Opaque userdata pointer passed to all callbacks.\n\n Input type: void*"] pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_USERDATA: GhosttyTerminalOption = 0; -#[doc = " Callback invoked when the terminal needs to write data back\n to the pty (e.g. in response to a DECRQM query or device\n status report). Set to NULL to ignore such sequences.\n\n Input type: GhosttyTerminalWritePtyFn"] +#[doc = " Callback invoked when the terminal needs to write data back\n to the pty (e.g. in response to a DECRQM query, device status\n report, or VT-driven mode 2048 enable). Set to NULL to ignore such\n sequences.\n\n Input type: GhosttyTerminalWritePtyFn"] pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_WRITE_PTY: GhosttyTerminalOption = 1; #[doc = " Callback invoked when the terminal receives a BEL character\n (0x07). Set to NULL to ignore bell events.\n\n Input type: GhosttyTerminalBellFn"] pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_BELL: GhosttyTerminalOption = 2; @@ -2473,7 +3054,7 @@ pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_KITTY_IMAGE_STORAGE_LIMIT: #[doc = " Enable or disable Kitty image loading via the file medium.\n\n A NULL value pointer is a no-op. Has no effect when Kitty graphics\n are disabled at build time.\n\n Input type: bool*"] pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_KITTY_IMAGE_MEDIUM_FILE: GhosttyTerminalOption = 16; -#[doc = " Enable or disable Kitty image loading via the temporary file medium.\n\n A NULL value pointer is a no-op. Has no effect when Kitty graphics\n are disabled at build time.\n\n Input type: bool*"] +#[doc = " Enable Kitty image loading via the temporary file medium, restricted to\n the provided directory. The string data is copied into the terminal.\n\n A NULL value pointer disables the temporary file medium. Has no effect\n when Kitty graphics are disabled at build time.\n\n Input type: GhosttyString*"] pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_KITTY_IMAGE_MEDIUM_TEMP_FILE: GhosttyTerminalOption = 17; #[doc = " Enable or disable Kitty image loading via the shared memory medium.\n\n A NULL value pointer is a no-op. Has no effect when Kitty graphics\n are disabled at build time.\n\n Input type: bool*"] @@ -2496,12 +3077,43 @@ pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_DEFAULT_CURSOR_BLINK: Ghost pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_GLYPH_PROTOCOL: GhosttyTerminalOption = 24; #[doc = " Callback invoked when the terminal pwd changes via escape\n sequences (OSC 7, OSC 9, or OSC 1337 CurrentDir). Set to NULL\n to ignore pwd change events.\n\n Input type: GhosttyTerminalPwdChangedFn"] pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_PWD_CHANGED: GhosttyTerminalOption = 25; -#[doc = " Callback invoked when the running program performs a clipboard write.\n OSC 52 and iTerm2 OSC 1337 Copy writes are normalized to an atomic set\n of decoded MIME representations. Set to NULL to ignore clipboard writes.\n Clipboard read requests are always ignored; see\n GhosttyTerminalClipboardWriteFn.\n\n Input type: GhosttyTerminalClipboardWriteFn"] +#[doc = " Callback invoked when the running program performs a clipboard write.\n OSC 52, iTerm2 OSC 1337 Copy, and Kitty clipboard (OSC 5522) writes\n are normalized to an atomic set of decoded MIME representations. Set\n to NULL to ignore clipboard writes (Kitty clipboard writes are then\n refused with ENOSYS). Clipboard read requests are delivered to\n GHOSTTY_TERMINAL_OPT_CLIPBOARD_READ instead.\n\n Input type: GhosttyTerminalClipboardWriteFn"] pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE: GhosttyTerminalOption = 26; -#[doc = " Callback invoked when the running program performs a clipboard write.\n OSC 52 and iTerm2 OSC 1337 Copy writes are normalized to an atomic set\n of decoded MIME representations. Set to NULL to ignore clipboard writes.\n Clipboard read requests are always ignored; see\n GhosttyTerminalClipboardWriteFn.\n\n Input type: GhosttyTerminalClipboardWriteFn"] +#[doc = " Set the maximum scrollback allocation in bytes.\n\n This is an estimate. Internally, libghostty only prunes bytes up\n to a \"page\"-granularity. A page is the minimum allocated unit of\n grid space within Ghostty. A page at the time of writing these docs\n is about 400KB, so the byte limit will be within this delta.\n\n This works alongside the line limit configuration. If both are set,\n the first-reached limit is used first. Both limits are dependent\n on external state (byte limit can be reached with less lines if\n more styles are used for example, line limit can be reached with\n a narrower terminal viewport). So, they are useful together.\n\n Lowering the limit immediately removes eligible complete historical\n pages. A value of zero disables scrollback and erases retained history.\n A NULL value pointer removes the byte limit.\n\n Input type: size_t*"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_SCROLLBACK_MAX_BYTES: GhosttyTerminalOption = + 27; +#[doc = " Set the maximum number of physical lines retained in scrollback.\n\n This is an estimate. Internally, libghostty only prunes lines up\n to a \"page\"-granularity. A page is the minimum allocated unit of\n grid space within Ghostty. As a result, the actual available scrollback\n lines will almost always be higher than configured. The magnitude\n of the difference depends on the number of used styles, graphemes, etc.\n since the row-count in a page is dynamic based on that. In general,\n it ranges from dozens to a hundred or so lines.\n\n This works alongside the line limit configuration. If both are set,\n the first-reached limit is used first. Both limits are dependent\n on external state (byte limit can be reached with less lines if\n more styles are used for example, line limit can be reached with\n a narrower terminal viewport). So, they are useful together.\n\n Lowering the limit immediately removes eligible complete historical\n pages. A NULL value pointer removes the line limit.\n\n Input type: size_t*"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_SCROLLBACK_MAX_LINES: GhosttyTerminalOption = + 28; +#[doc = " Callback invoked when the running program requests a desktop\n notification via OSC 9 or OSC 777. Set to NULL to ignore desktop\n notification requests.\n\n Input type: GhosttyTerminalDesktopNotificationFn"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_DESKTOP_NOTIFICATION: GhosttyTerminalOption = + 29; +#[doc = " Callback invoked when the running program reports progress via OSC 9;4.\n Set to NULL to ignore progress reports.\n\n Input type: GhosttyTerminalProgressReportFn"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_PROGRESS_REPORT: GhosttyTerminalOption = 30; +#[doc = " Set the maximum number of replay-safe VT continuation bytes retained.\n\n Continuation bytes reconstruct an escape sequence or UTF-8 codepoint\n which was unfinished at the end of the most recent\n VT write call. They are used automatically by terminal snapshots and may\n also be exported directly with the continuation APIs.\n\n Tracking is disabled by default. A nonzero value enables tracking and\n sets its byte limit. Passing NULL or a pointer to zero disables tracking.\n Lowering the limit below an already-retained\n continuation, or enabling tracking while the parser is already\n unfinished, makes the current continuation unavailable because earlier\n bytes cannot be reconstructed. Tracking recovers automatically after a\n later write reaches the ground state or contains a fresh replay start.\n\n Input type: size_t*"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES: GhosttyTerminalOption = + 31; +#[doc = " Enable window title reports in response to CSI 21 t.\n\n This is disabled by default because a running program can set a title and\n query it back into the pty input stream, potentially injecting commands\n that execute after user interaction. Passing NULL or a pointer to false\n disables title reporting.\n\n Input type: bool*"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_TITLE_REPORT: GhosttyTerminalOption = 32; +#[doc = " Set the reset default for a terminal mode.\n\n This unconditionally updates both the current value and the value restored\n by a full terminal reset (RIS).\n\n Some recognized modes represent transitions or mirror additional terminal\n state and cannot safely be configured as reset defaults. Those modes return\n GHOSTTY_INVALID_VALUE. A NULL value pointer also returns\n GHOSTTY_INVALID_VALUE.\n\n Input type: GhosttyTerminalModeConfig*"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_MODE_DEFAULT: GhosttyTerminalOption = 33; +#[doc = " Set the current value of a terminal mode.\n\n This does not change the value restored by a full terminal reset (RIS).\n A NULL value pointer or unknown mode returns GHOSTTY_INVALID_VALUE.\n\n Input type: GhosttyTerminalModeConfig*"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_MODE: GhosttyTerminalOption = 34; +#[doc = " Callback invoked for unsupported terminal sequence identifiers. Set to\n NULL to ignore unsupported sequences. Capture must also be enabled with\n GHOSTTY_TERMINAL_OPT_UNKNOWN_MAX_BYTES.\n\n Input type: GhosttyTerminalUnknownSequenceFn"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_UNKNOWN_SEQUENCE: GhosttyTerminalOption = 35; +#[doc = " Set the maximum content bytes retained for each unsupported terminal\n sequence. A NULL value pointer or zero disables capture and prevents\n unknown-sequence callbacks.\n\n When this limit is hit, the unknown sequence callback will still\n be invoked but `truncated` will be set to true.\n\n Input type: size_t*"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_UNKNOWN_MAX_BYTES: GhosttyTerminalOption = 36; +#[doc = " Set the name of the terminfo entry this terminal runs as, reported\n in response to an XTGETTCAP query for \"TN\" (e.g. \"xterm-256color\").\n\n The string data is copied into the terminal. A NULL value pointer\n clears the name (equivalent to setting an empty string). A name\n longer than 128 bytes returns GHOSTTY_INVALID_VALUE.\n\n If this is unset then we don't report anything for an XTGETTCAP\n TN query, because we don't know what the embedding terminal around\n libghostty is advertising itself as.\n\n Input type: GhosttyString*"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_TERMINFO_NAME: GhosttyTerminalOption = 37; +#[doc = " Callback invoked when the running program requests clipboard contents\n via OSC 52 with a \"?\" payload or a Kitty clipboard (OSC 5522) read. The\n read is synchronous and must be answered before the callback returns.\n Set to NULL (the default) to ignore OSC 52 read requests and refuse\n OSC 5522 reads with EPERM.\n\n Input type: GhosttyTerminalClipboardReadFn"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_CLIPBOARD_READ: GhosttyTerminalOption = 38; +#[doc = " Set the maximum total decoded bytes a single Kitty clipboard protocol\n (OSC 5522) write transaction may accumulate. The limit is captured\n when a transaction begins; an in-flight transaction keeps the limit\n it started with.\n\n Data beyond the limit fails the whole transaction with EFBIG. The\n transaction is discarded, later write-related packets are ignored\n until a new write begins, and nothing reaches the clipboard write\n callback.\n\n Transactions are buffered in memory, so this limit bounds how much\n memory a single write can make the terminal allocate. Pass SIZE_MAX\n to remove the limit. A NULL value pointer reverts to the built-in\n default of 64MiB, the minimum required by the protocol.\n\n This limit doesn't apply to OSC 52 writes, which are bounded by the\n maximum length of an escape sequence instead.\n\n Input type: size_t*"] +pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE_MAX_BYTES: + GhosttyTerminalOption = 39; +#[doc = " Set the maximum total decoded bytes a single Kitty clipboard protocol\n (OSC 5522) write transaction may accumulate. The limit is captured\n when a transaction begins; an in-flight transaction keeps the limit\n it started with.\n\n Data beyond the limit fails the whole transaction with EFBIG. The\n transaction is discarded, later write-related packets are ignored\n until a new write begins, and nothing reaches the clipboard write\n callback.\n\n Transactions are buffered in memory, so this limit bounds how much\n memory a single write can make the terminal allocate. Pass SIZE_MAX\n to remove the limit. A NULL value pointer reverts to the built-in\n default of 64MiB, the minimum required by the protocol.\n\n This limit doesn't apply to OSC 52 writes, which are bounded by the\n maximum length of an escape sequence instead.\n\n Input type: size_t*"] pub const GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_MAX_VALUE: GhosttyTerminalOption = 2147483647; #[doc = " Terminal option identifiers.\n\n These values are used with ghostty_terminal_set() to configure\n terminal callbacks and associated state.\n\n @ingroup terminal"] -pub type GhosttyTerminalOption = ::std::os::raw::c_uint; +pub type GhosttyTerminalOption = ::std::os::raw::c_int; #[doc = " Invalid data type. Never results in any data extraction."] pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_INVALID: GhosttyTerminalData = 0; #[doc = " Terminal width in cells.\n\n Output type: uint16_t *"] @@ -2526,9 +3138,9 @@ pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_SCROLLBAR: GhosttyTerminalDa pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_CURSOR_STYLE: GhosttyTerminalData = 10; #[doc = " Whether any mouse tracking mode is active.\n\n Returns true if any of the mouse tracking modes (X10, normal, button,\n or any-event) are enabled.\n\n Output type: bool *"] pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_MOUSE_TRACKING: GhosttyTerminalData = 11; -#[doc = " The terminal title as set by escape sequences (e.g. OSC 0/2).\n\n Returns a borrowed string. The pointer is valid until the next call\n to ghostty_terminal_vt_write() or ghostty_terminal_reset(). An empty\n string (len=0) is returned when no title has been set.\n\n Output type: GhosttyString *"] +#[doc = " The terminal title as set by escape sequences (e.g. OSC 0/2).\n\n Returns a borrowed string. The pointer is valid until the next mutating\n terminal call. An empty string (len=0) is returned when no title has been\n set.\n\n Output type: GhosttyString *"] pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_TITLE: GhosttyTerminalData = 12; -#[doc = " The terminal's current working directory as set by escape sequences\n (e.g. OSC 7).\n\n Returns a borrowed string. The pointer is valid until the next call\n to ghostty_terminal_vt_write() or ghostty_terminal_reset(). An empty\n string (len=0) is returned when no pwd has been set.\n\n Output type: GhosttyString *"] +#[doc = " The terminal's current working directory as set by escape sequences\n (e.g. OSC 7).\n\n Returns a borrowed string. The pointer is valid until the next mutating\n terminal call. An empty string (len=0) is returned when no pwd has been\n set.\n\n Output type: GhosttyString *"] pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_PWD: GhosttyTerminalData = 13; #[doc = " The total number of rows in the active screen including scrollback.\n\n Output type: size_t *"] pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_TOTAL_ROWS: GhosttyTerminalData = 14; @@ -2562,7 +3174,7 @@ pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_KITTY_IMAGE_STORAGE_LIMIT: G #[doc = " Whether the file medium is enabled for Kitty image loading on the\n active screen.\n\n Returns GHOSTTY_NO_VALUE when Kitty graphics are disabled at build time.\n\n Output type: bool *"] pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_KITTY_IMAGE_MEDIUM_FILE: GhosttyTerminalData = 27; -#[doc = " Whether the temporary file medium is enabled for Kitty image loading\n on the active screen.\n\n Returns GHOSTTY_NO_VALUE when Kitty graphics are disabled at build time.\n\n Output type: bool *"] +#[doc = " The directory allowed for Kitty image loading via the temporary file\n medium on the active screen. The string is empty when the medium is\n disabled.\n\n Returns GHOSTTY_NO_VALUE when Kitty graphics are disabled at build time.\n\n Output type: GhosttyString *"] pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_KITTY_IMAGE_MEDIUM_TEMP_FILE: GhosttyTerminalData = 28; #[doc = " Whether the shared memory medium is enabled for Kitty image loading\n on the active screen.\n\n Returns GHOSTTY_NO_VALUE when Kitty graphics are disabled at build time.\n\n Output type: bool *"] @@ -2574,17 +3186,37 @@ pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_KITTY_GRAPHICS: GhosttyTermi pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_SELECTION: GhosttyTerminalData = 31; #[doc = " Whether the viewport is currently pinned to the active area.\n\n This is true when the viewport is following the active terminal area,\n and false when the user has scrolled into history.\n\n Output type: bool *"] pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_VIEWPORT_ACTIVE: GhosttyTerminalData = 32; +#[doc = " Whether VT processing encountered a non-gracefully handled error that may\n have prevented a terminal-owned semantic update.\n\n Processing remains best-effort, and ghostty_terminal_reset() does not\n clear it. Gracefully handled protocol failures, configured limits,\n malformed or unsupported input, and failures limited to external effects\n or query responses do not set it.\n\n This can't currently be unset. This is purely informational to consumers\n if there was some error that happened at some point during VT processing.\n\n Output type: bool *"] +pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_VT_PROCESSING_ERROR: GhosttyTerminalData = 33; +#[doc = " The configured maximum scrollback allocation in bytes.\n\n This always reports the primary screen's configured value, including\n while an alternate screen is active. Returns GHOSTTY_NO_VALUE when the\n configured byte limit is unlimited.\n\n Output type: size_t *"] +pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_SCROLLBACK_MAX_BYTES: GhosttyTerminalData = 34; +#[doc = " The configured maximum number of physical scrollback lines.\n\n This always reports the primary screen's configured value, including\n while an alternate screen is active. Returns GHOSTTY_NO_VALUE when the\n configured line limit is unlimited.\n\n Output type: size_t *"] +pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_SCROLLBACK_MAX_LINES: GhosttyTerminalData = 35; +#[doc = " The configured maximum retained VT continuation size in bytes.\n\n A value of zero means continuation tracking is disabled. This reports the\n configured limit even when a current unfinished continuation is\n temporarily unavailable.\n\n Output type: size_t *"] +pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_CONTINUATION_MAX_BYTES: GhosttyTerminalData = + 36; +#[doc = " Get the current value of a terminal mode.\n\n The caller must initialize the `mode` field. On success, the `value` field\n is updated with the current value. A NULL pointer or unknown mode returns\n GHOSTTY_INVALID_VALUE.\n\n Input/output type: GhosttyTerminalModeConfig *"] +pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_MODE: GhosttyTerminalData = 37; +#[doc = " Whether VT processing is at ground.\n\n Ground is when the stream isn't in the middle of any type of sequence:\n UTF-8, ESC, CSI, OSC, etc. It is the stateless point of the stream.\n\n This is useful to know because it is a point at which you can\n safely insert out-of-band VT sequences. For example, while reading\n from a pty if you want to make your own changes, you can wait until\n the pty input reaches ground, then write yours.\n\n Output type: bool *"] +pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_VT_GROUND: GhosttyTerminalData = 38; +#[doc = " Whether the cursor is currently at a semantic shell prompt or input area.\n\n This depends on semantic prompt markers such as OSC 133. Returns false\n when semantic prompt information is unavailable or the alternate screen\n is active.\n\n Output type: bool *"] +pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_CURSOR_AT_PROMPT: GhosttyTerminalData = 39; +#[doc = " The configured maximum decoded bytes per Kitty clipboard protocol\n (OSC 5522) write transaction. See\n GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE_MAX_BYTES.\n\n Output type: size_t *"] +pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_CLIPBOARD_WRITE_MAX_BYTES: GhosttyTerminalData = + 40; +#[doc = " Whether xterm modifyOtherKeys mode 2 is enabled.\n\n Output type: bool *"] +pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_MODIFY_OTHER_KEYS: GhosttyTerminalData = 41; #[doc = " Whether xterm modifyOtherKeys mode 2 is enabled.\n\n Output type: bool *"] -pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_MODIFY_OTHER_KEYS: GhosttyTerminalData = 33; pub const GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_MAX_VALUE: GhosttyTerminalData = 2147483647; #[doc = " Terminal data types.\n\n These values specify what type of data to extract from a terminal\n using `ghostty_terminal_get`.\n\n @ingroup terminal"] -pub type GhosttyTerminalData = ::std::os::raw::c_uint; +pub type GhosttyTerminalData = ::std::os::raw::c_int; unsafe extern "C" { - #[doc = " Create a new terminal instance.\n\n @param allocator Pointer to allocator, or NULL to use the default allocator\n @param terminal Pointer to store the created terminal handle\n @param options Terminal initialization options\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup terminal"] + #[doc = " Create a new terminal instance.\n\n The terminal starts with various reasonable defaults e.g. around\n scrollback limits. Use ghostty_terminal_set() to change any options\n prior to using the terminal.\n\n @param allocator Pointer to allocator, or NULL to use the default allocator\n @param terminal Pointer to store the created terminal handle\n @param cols Terminal width in cells (must be greater than zero)\n @param rows Terminal height in cells (must be greater than zero)\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup terminal"] pub fn ghostty_terminal_new( allocator: *const GhosttyAllocator, terminal: *mut GhosttyTerminal, - options: GhosttyTerminalOptions, + cols: u16, + rows: u16, ) -> GhosttyResult; } unsafe extern "C" { @@ -2606,7 +3238,7 @@ unsafe extern "C" { ) -> GhosttyResult; } unsafe extern "C" { - #[doc = " Set an option on the terminal.\n\n Configures terminal callbacks and associated state such as the\n write_pty callback and userdata pointer. The value is passed\n directly for pointer types (callbacks, userdata) or as a pointer\n to the value for non-pointer types (e.g. GhosttyString*).\n NULL clears the option to its default.\n\n Callbacks are invoked synchronously during ghostty_terminal_vt_write().\n Callbacks must not call ghostty_terminal_vt_write() on the same\n terminal (no reentrancy).\n\n @param terminal The terminal handle (may be NULL, in which case this is a no-op)\n @param option The option to set\n @param value Pointer to the value to set (type depends on the option),\n or NULL to clear the option\n\n @ingroup terminal"] + #[doc = " Set an option on the terminal.\n\n Configures terminal callbacks and associated state such as the\n write_pty callback and userdata pointer. The value is passed\n directly for pointer types (callbacks, userdata) or as a pointer\n to the value for non-pointer types (e.g. GhosttyString*).\n The behavior of a NULL value is specific to each option and is\n documented by the corresponding GhosttyTerminalOption value.\n\n Callbacks are invoked synchronously during VT writes. Callbacks must not\n call ghostty_terminal_vt_write() or\n ghostty_terminal_vt_write_until_ground() on the same terminal\n (no reentrancy).\n\n @param terminal The terminal handle (may be NULL, in which case this is a no-op)\n @param option The option to set\n @param value Pointer to the value to set (type depends on the option),\n or NULL to clear the option\n\n @ingroup terminal"] pub fn ghostty_terminal_set( terminal: GhosttyTerminal, option: GhosttyTerminalOption, @@ -2617,6 +3249,40 @@ unsafe extern "C" { #[doc = " Write VT-encoded data to the terminal for processing.\n\n Feeds raw bytes through the terminal's VT stream parser, updating\n terminal state accordingly. By default, sequences that require output\n (queries, device status reports) are silently ignored. Use\n ghostty_terminal_set() with GHOSTTY_TERMINAL_OPT_WRITE_PTY to install\n a callback that receives response data.\n\n This never fails. Any erroneous input or errors in processing the\n input are logged internally but do not cause this function to fail\n because this input is assumed to be untrusted and from an external\n source; so the primary goal is to keep the terminal state consistent and\n not allow malformed input to corrupt or crash.\n\n @param terminal The terminal handle\n @param data Pointer to the data to write\n @param len Length of the data in bytes\n\n @ingroup terminal"] pub fn ghostty_terminal_vt_write(terminal: GhosttyTerminal, data: *const u8, len: usize); } +unsafe extern "C" { + #[doc = " Write VT-encoded data, but only the shortest prefix needed to reach ground.\n\n Ground is when the stream isn't in the middle of any type of sequence:\n UTF-8, ESC, CSI, OSC, etc. It is the stateless point of the stream.\n\n This is useful to know because it is a point at which you can\n safely insert out-of-band VT sequences. For example, while reading\n from a pty if you want to make your own changes, you can wait until\n the pty input reaches ground, then write yours.\n\n If the stream is already at ground then this consumes nothing and returns\n GHOSTTY_SUCCESS. On success, out_consumed is the number of bytes consumed\n before reaching ground, including the byte that reaches it.\n GHOSTTY_NO_VALUE means the full slice was consumed without reaching ground.\n\n @param terminal The terminal handle (must not be NULL)\n @param data Pointer to the data to write, or NULL when len is zero\n @param len Length of the data in bytes\n @param[out] out_consumed Number of bytes consumed (must not be NULL)\n @return GHOSTTY_SUCCESS if ground was reached, GHOSTTY_NO_VALUE if all input\n was consumed without reaching ground, or GHOSTTY_INVALID_VALUE if\n an argument is invalid\n\n @ingroup terminal"] + pub fn ghostty_terminal_vt_write_until_ground( + terminal: GhosttyTerminal, + data: *const u8, + len: usize, + out_consumed: *mut usize, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Write the terminal's replay-safe VT continuation to a callback writer.\n\n The continuation is the exact byte suffix needed to reconstruct unfinished\n VT parser or UTF-8 decoder state in an equivalent terminal. It is empty\n when the stream is at ground. The callback is invoked synchronously and\n may be called more than once. It must not call terminal APIs with the same\n terminal handle.\n\n Continuation tracking must have been enabled by setting\n GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to a nonzero value before the\n input that produced the continuation was written.\n\n The caller must serialize this operation with both VT write functions and\n all other access to the same terminal.\n\n @param terminal Terminal to read from (must not be NULL)\n @param writer Destination writer whose write callback must not be NULL\n @return GHOSTTY_SUCCESS on success, GHOSTTY_IO_ERROR if the callback rejects\n a write, GHOSTTY_LIMIT_EXCEEDED if output accounting overflows, or\n GHOSTTY_INVALID_VALUE if an argument is invalid, tracking is\n disabled, or the current continuation is unavailable\n\n @ingroup terminal"] + pub fn ghostty_terminal_continuation_write( + terminal: GhosttyTerminal, + writer: GhosttyWriter, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Copy the terminal's replay-safe VT continuation into a caller buffer.\n\n Pass NULL for buf with buf_len zero to query the required size. A size query\n returns GHOSTTY_OUT_OF_SPACE and stores the required size in out_written,\n including zero when the stream is at ground. If a non-NULL buffer is too\n small, the function has the same result and reports the full required size.\n Continuation tracking must have been enabled by setting\n GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to a nonzero value before the\n input that produced the continuation was written.\n\n The caller must serialize this operation with all other access to the same\n terminal.\n\n @param terminal Terminal to read from (must not be NULL)\n @param buf Destination buffer, or NULL when buf_len is zero\n @param buf_len Destination buffer capacity in bytes\n @param[out] out_written Bytes written, or required size on\n GHOSTTY_OUT_OF_SPACE (must not be NULL)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE for a size query or\n insufficient buffer, or GHOSTTY_INVALID_VALUE if an argument is\n invalid, tracking is disabled, or the current continuation is\n unavailable\n\n @ingroup terminal"] + pub fn ghostty_terminal_continuation_buf( + terminal: GhosttyTerminal, + buf: *mut u8, + buf_len: usize, + out_written: *mut usize, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Return an allocated copy of the terminal's replay-safe VT continuation.\n\n The returned bytes are allocated with allocator, or the default allocator\n when allocator is NULL. The caller must release them with ghostty_free(),\n passing the same allocator and returned length. An empty continuation is a\n successful result with *out_ptr set to NULL and *out_len set to zero,\n which can also be passed to ghostty_free().\n Continuation tracking must have been enabled by setting\n GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to a nonzero value before the\n input that produced the continuation was written.\n\n The caller must serialize this operation with all other access to the same\n terminal.\n\n @param terminal Terminal to read from (must not be NULL)\n @param allocator Allocator for the output, or NULL for the default allocator\n @param[out] out_ptr Allocated continuation bytes (must not be NULL)\n @param[out] out_len Number of continuation bytes (must not be NULL)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation\n failure, or GHOSTTY_INVALID_VALUE if an argument is invalid,\n tracking is disabled, or the current continuation is unavailable\n\n @ingroup terminal"] + pub fn ghostty_terminal_continuation_alloc( + terminal: GhosttyTerminal, + allocator: *const GhosttyAllocator, + out_ptr: *mut *mut u8, + out_len: *mut usize, + ) -> GhosttyResult; +} unsafe extern "C" { #[doc = " Scroll the terminal viewport.\n\n Scrolls the terminal's viewport according to the given behavior.\n When using GHOSTTY_SCROLL_VIEWPORT_DELTA, set the delta field in\n the value union to specify the number of rows to scroll (negative\n for up, positive for down). When using GHOSTTY_SCROLL_VIEWPORT_ROW,\n set the row field to the absolute row offset from the top of the\n scrollable area (the same row space as the offset field of\n GhosttyTerminalScrollbar). For other behaviors, the value is ignored.\n\n @param terminal The terminal handle (may be NULL, in which case this is a no-op)\n @param behavior The scroll behavior as a tagged union\n\n @ingroup terminal"] pub fn ghostty_terminal_scroll_viewport( @@ -2639,22 +3305,6 @@ unsafe extern "C" { out_result: *mut GhosttyTerminalCompressionResult, ) -> GhosttyResult; } -unsafe extern "C" { - #[doc = " Get the current value of a terminal mode.\n\n Returns the value of the mode identified by the given mode.\n\n @param terminal The terminal handle (NULL returns GHOSTTY_INVALID_VALUE)\n @param mode The mode identifying the mode to query\n @param[out] out_value On success, set to true if the mode is set, false\n if it is reset\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the terminal\n is NULL or the mode does not correspond to a known mode\n\n @ingroup terminal"] - pub fn ghostty_terminal_mode_get( - terminal: GhosttyTerminal, - mode: GhosttyMode, - out_value: *mut bool, - ) -> GhosttyResult; -} -unsafe extern "C" { - #[doc = " Set the value of a terminal mode.\n\n Sets the mode identified by the given mode to the specified value.\n\n @param terminal The terminal handle (NULL returns GHOSTTY_INVALID_VALUE)\n @param mode The mode identifying the mode to set\n @param value true to set the mode, false to reset it\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the terminal\n is NULL or the mode does not correspond to a known mode\n\n @ingroup terminal"] - pub fn ghostty_terminal_mode_set( - terminal: GhosttyTerminal, - mode: GhosttyMode, - value: bool, - ) -> GhosttyResult; -} unsafe extern "C" { #[doc = " Get data from a terminal instance.\n\n Extracts typed data from the given terminal based on the specified\n data type. The output pointer must be of the appropriate type for the\n requested data kind. Valid data types and output types are documented\n in the `GhosttyTerminalData` enum.\n\n @param terminal The terminal handle (may be NULL)\n @param data The type of data to extract\n @param out Pointer to store the extracted data (type depends on data parameter)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the terminal\n is NULL or the data type is invalid\n\n @ingroup terminal"] pub fn ghostty_terminal_get( @@ -2836,6 +3486,13 @@ unsafe extern "C" { options: GhosttyFormatterTerminalOptions, ) -> GhosttyResult; } +unsafe extern "C" { + #[doc = " Run the formatter and stream output to a writer.\n\n Each call formats the current terminal state and invokes the writer\n synchronously as output becomes available. The callback may be called more\n than once and must not call formatter or terminal APIs using the same\n formatter or its terminal.\n\n If an error occurs, the writer may already contain a partial formatted\n output. The operation cannot be resumed from that partial output. This\n function does not flush or make the caller's destination durable.\n\n @param formatter The formatter handle (must not be NULL)\n @param writer Destination writer whose write callback must not be NULL\n @return GHOSTTY_SUCCESS on success, GHOSTTY_IO_ERROR if the writer rejects\n output, GHOSTTY_LIMIT_EXCEEDED if output accounting overflows, or\n GHOSTTY_INVALID_VALUE if an argument is invalid\n\n @ingroup formatter"] + pub fn ghostty_formatter_format( + formatter: GhosttyFormatter, + writer: GhosttyWriter, + ) -> GhosttyResult; +} unsafe extern "C" { #[doc = " Run the formatter and produce output into the caller-provided buffer.\n\n Each call formats the current terminal state. Pass NULL for buf to\n query the required buffer size without writing any output; in that case\n out_written receives the required size and the return value is\n GHOSTTY_OUT_OF_SPACE.\n\n If the buffer is too small, returns GHOSTTY_OUT_OF_SPACE and sets\n out_written to the required size. The caller can then retry with a\n larger buffer.\n\n @param formatter The formatter handle (must not be NULL)\n @param buf Pointer to the output buffer, or NULL to query size\n @param buf_len Length of the output buffer in bytes\n @param out_written Pointer to receive the number of bytes written,\n or the required size on failure\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup formatter"] pub fn ghostty_formatter_format_buf( @@ -2846,7 +3503,7 @@ unsafe extern "C" { ) -> GhosttyResult; } unsafe extern "C" { - #[doc = " Run the formatter and return an allocated buffer with the output.\n\n Each call formats the current terminal state. The buffer is allocated\n using the provided allocator (or the default allocator if NULL).\n The caller is responsible for freeing the returned buffer with\n ghostty_free(), passing the same allocator (or NULL for the default)\n that was used for the allocation.\n\n @param formatter The formatter handle (must not be NULL)\n @param allocator Pointer to allocator, or NULL to use the default allocator\n @param out_ptr Pointer to receive the allocated buffer\n @param out_len Pointer to receive the length of the output in bytes\n @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation\n failure\n\n @ingroup formatter"] + #[doc = " Run the formatter and return an allocated buffer with the output.\n\n Each call formats the current terminal state. The buffer is allocated\n using the provided allocator (or the default allocator if NULL).\n The caller is responsible for freeing the returned buffer with\n ghostty_free(), passing the same allocator (or NULL for the default)\n that was used for the allocation.\n Empty output returns GHOSTTY_SUCCESS with *out_ptr set to NULL and\n *out_len set to zero. This result can be passed to ghostty_free().\n\n @param formatter The formatter handle (must not be NULL)\n @param allocator Pointer to allocator, or NULL to use the default allocator\n @param out_ptr Pointer to receive the allocated buffer\n @param out_len Pointer to receive the length of the output in bytes\n @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation\n failure\n\n @ingroup formatter"] pub fn ghostty_formatter_format_alloc( formatter: GhosttyFormatter, allocator: *const GhosttyAllocator, @@ -2868,7 +3525,7 @@ pub const GhosttyRenderStateDirty_GHOSTTY_RENDER_STATE_DIRTY_FULL: GhosttyRender pub const GhosttyRenderStateDirty_GHOSTTY_RENDER_STATE_DIRTY_MAX_VALUE: GhosttyRenderStateDirty = 2147483647; #[doc = " Dirty state of a render state after update.\n\n @ingroup render"] -pub type GhosttyRenderStateDirty = ::std::os::raw::c_uint; +pub type GhosttyRenderStateDirty = ::std::os::raw::c_int; #[doc = " Bar cursor (DECSCUSR 5, 6)."] pub const GhosttyRenderStateCursorVisualStyle_GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_BAR: GhosttyRenderStateCursorVisualStyle = 0; @@ -2884,7 +3541,7 @@ pub const GhosttyRenderStateCursorVisualStyle_GHOSTTY_RENDER_STATE_CURSOR_VISUAL pub const GhosttyRenderStateCursorVisualStyle_GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_MAX_VALUE: GhosttyRenderStateCursorVisualStyle = 2147483647; #[doc = " Visual style of the cursor.\n\n @ingroup render"] -pub type GhosttyRenderStateCursorVisualStyle = ::std::os::raw::c_uint; +pub type GhosttyRenderStateCursorVisualStyle = ::std::os::raw::c_int; #[doc = " Invalid / sentinel value."] pub const GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_INVALID: GhosttyRenderStateData = 0; #[doc = " Viewport width in cells (uint16_t)."] @@ -2933,18 +3590,22 @@ pub const GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_Y: #[doc = " Whether the cursor is on the tail of a wide character (bool).\n Only valid when CURSOR_VIEWPORT_HAS_VALUE is true."] pub const GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_WIDE_TAIL: GhosttyRenderStateData = 17; -#[doc = " Whether the cursor is on the tail of a wide character (bool).\n Only valid when CURSOR_VIEWPORT_HAS_VALUE is true."] +#[doc = " All cursor state in one sized struct (GhosttyRenderStateCursor).\n Initialize the output with GHOSTTY_INIT_SIZED before querying."] +pub const GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_CURSOR: GhosttyRenderStateData = 18; +#[doc = " All render-state colors in one sized struct (GhosttyRenderStateColors).\n Initialize the output with GHOSTTY_INIT_SIZED before querying."] +pub const GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_COLORS: GhosttyRenderStateData = 19; +#[doc = " All render-state colors in one sized struct (GhosttyRenderStateColors).\n Initialize the output with GHOSTTY_INIT_SIZED before querying."] pub const GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_MAX_VALUE: GhosttyRenderStateData = 2147483647; #[doc = " Queryable data kinds for ghostty_render_state_get().\n\n @ingroup render"] -pub type GhosttyRenderStateData = ::std::os::raw::c_uint; +pub type GhosttyRenderStateData = ::std::os::raw::c_int; #[doc = " Set dirty state (GhosttyRenderStateDirty)."] pub const GhosttyRenderStateOption_GHOSTTY_RENDER_STATE_OPTION_DIRTY: GhosttyRenderStateOption = 0; #[doc = " Set dirty state (GhosttyRenderStateDirty)."] pub const GhosttyRenderStateOption_GHOSTTY_RENDER_STATE_OPTION_MAX_VALUE: GhosttyRenderStateOption = 2147483647; #[doc = " Settable options for ghostty_render_state_set().\n\n @ingroup render"] -pub type GhosttyRenderStateOption = ::std::os::raw::c_uint; +pub type GhosttyRenderStateOption = ::std::os::raw::c_int; #[doc = " Invalid / sentinel value."] pub const GhosttyRenderStateRowData_GHOSTTY_RENDER_STATE_ROW_DATA_INVALID: GhosttyRenderStateRowData = 0; @@ -2960,11 +3621,14 @@ pub const GhosttyRenderStateRowData_GHOSTTY_RENDER_STATE_ROW_DATA_CELLS: Ghostty #[doc = " Row-local selected cell range (GhosttyRenderStateRowSelection)."] pub const GhosttyRenderStateRowData_GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION: GhosttyRenderStateRowData = 4; -#[doc = " Row-local selected cell range (GhosttyRenderStateRowSelection)."] +#[doc = " A borrowed view of the raw cell values for the current row\n (GhosttyCellsView). One value per column, identical to querying\n GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_RAW for each cell. The view\n is only valid as long as the underlying render state is not\n updated; it is unsafe to use after updating the render state.\n\n This is the bulk alternative to iterating cells one at a time.\n It lets callers with expensive call boundaries (e.g. WebAssembly\n embedders) read an entire row with a single call.\n\n Bit positions aren't protected by ABI, so callers should parse them\n out of the manifest from `ghostty_type_json`. Callers with access\n to the C header or without high FFI costs should use `ghostty_cell_get`."] +pub const GhosttyRenderStateRowData_GHOSTTY_RENDER_STATE_ROW_DATA_CELLS_RAW: + GhosttyRenderStateRowData = 5; +#[doc = " A borrowed view of the raw cell values for the current row\n (GhosttyCellsView). One value per column, identical to querying\n GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_RAW for each cell. The view\n is only valid as long as the underlying render state is not\n updated; it is unsafe to use after updating the render state.\n\n This is the bulk alternative to iterating cells one at a time.\n It lets callers with expensive call boundaries (e.g. WebAssembly\n embedders) read an entire row with a single call.\n\n Bit positions aren't protected by ABI, so callers should parse them\n out of the manifest from `ghostty_type_json`. Callers with access\n to the C header or without high FFI costs should use `ghostty_cell_get`."] pub const GhosttyRenderStateRowData_GHOSTTY_RENDER_STATE_ROW_DATA_MAX_VALUE: GhosttyRenderStateRowData = 2147483647; #[doc = " Queryable data kinds for ghostty_render_state_row_get().\n\n @ingroup render"] -pub type GhosttyRenderStateRowData = ::std::os::raw::c_uint; +pub type GhosttyRenderStateRowData = ::std::os::raw::c_int; #[doc = " Set dirty state for the current row (bool)."] pub const GhosttyRenderStateRowOption_GHOSTTY_RENDER_STATE_ROW_OPTION_DIRTY: GhosttyRenderStateRowOption = 0; @@ -2972,7 +3636,7 @@ pub const GhosttyRenderStateRowOption_GHOSTTY_RENDER_STATE_ROW_OPTION_DIRTY: pub const GhosttyRenderStateRowOption_GHOSTTY_RENDER_STATE_ROW_OPTION_MAX_VALUE: GhosttyRenderStateRowOption = 2147483647; #[doc = " Settable options for ghostty_render_state_row_set().\n\n @ingroup render"] -pub type GhosttyRenderStateRowOption = ::std::os::raw::c_uint; +pub type GhosttyRenderStateRowOption = ::std::os::raw::c_int; #[doc = " Row-local selection range.\n\n This struct uses the sized-struct ABI pattern. Initialize with\n GHOSTTY_INIT_SIZED(GhosttyRenderStateRowSelection) before querying\n GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION.\n\n Querying GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION returns GHOSTTY_NO_VALUE\n if the current row does not intersect the current selection.\n\n @ingroup render"] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -2997,7 +3661,64 @@ const _: () = { ["Offset of field: GhosttyRenderStateRowSelection::end_x"] [::std::mem::offset_of!(GhosttyRenderStateRowSelection, end_x) - 10usize]; }; -#[doc = " Render-state color information.\n\n This struct uses the sized-struct ABI pattern. Initialize with\n GHOSTTY_INIT_SIZED(GhosttyRenderStateColors) before calling\n ghostty_render_state_colors_get().\n\n Example:\n @code\n GhosttyRenderStateColors colors = GHOSTTY_INIT_SIZED(GhosttyRenderStateColors);\n GhosttyResult result = ghostty_render_state_colors_get(state, &colors);\n @endcode\n\n @ingroup render"] +#[doc = " Render-state cursor information.\n\n This struct uses the sized-struct ABI pattern. Initialize with\n GHOSTTY_INIT_SIZED(GhosttyRenderStateCursor) before querying\n GHOSTTY_RENDER_STATE_DATA_CURSOR.\n\n When viewport_has_value is false, viewport_x, viewport_y, and wide_tail\n contain undefined data and must not be read.\n\n @ingroup render"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyRenderStateCursor { + #[doc = " Size of this struct in bytes. Must be set to sizeof(GhosttyRenderStateCursor)."] + pub size: usize, + #[doc = " Whether the cursor is visible within the viewport."] + pub viewport_has_value: bool, + #[doc = " Cursor viewport x position in cells."] + pub viewport_x: u16, + #[doc = " Cursor viewport y position in cells."] + pub viewport_y: u16, + #[doc = " Whether the cursor is on the tail of a wide character."] + pub wide_tail: bool, + #[doc = " Whether the cursor is visible based on terminal modes."] + pub visible: bool, + #[doc = " Whether the cursor should blink based on terminal modes."] + pub blinking: bool, + #[doc = " Whether the cursor is at a password input field."] + pub password_input: bool, + #[doc = " The visual style of the cursor."] + pub visual_style: GhosttyRenderStateCursorVisualStyle, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyRenderStateCursor"] + [::std::mem::size_of::() - 24usize]; + ["Alignment of GhosttyRenderStateCursor"] + [::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyRenderStateCursor::size"] + [::std::mem::offset_of!(GhosttyRenderStateCursor, size) - 0usize]; + ["Offset of field: GhosttyRenderStateCursor::viewport_has_value"] + [::std::mem::offset_of!(GhosttyRenderStateCursor, viewport_has_value) - 8usize]; + ["Offset of field: GhosttyRenderStateCursor::viewport_x"] + [::std::mem::offset_of!(GhosttyRenderStateCursor, viewport_x) - 10usize]; + ["Offset of field: GhosttyRenderStateCursor::viewport_y"] + [::std::mem::offset_of!(GhosttyRenderStateCursor, viewport_y) - 12usize]; + ["Offset of field: GhosttyRenderStateCursor::wide_tail"] + [::std::mem::offset_of!(GhosttyRenderStateCursor, wide_tail) - 14usize]; + ["Offset of field: GhosttyRenderStateCursor::visible"] + [::std::mem::offset_of!(GhosttyRenderStateCursor, visible) - 15usize]; + ["Offset of field: GhosttyRenderStateCursor::blinking"] + [::std::mem::offset_of!(GhosttyRenderStateCursor, blinking) - 16usize]; + ["Offset of field: GhosttyRenderStateCursor::password_input"] + [::std::mem::offset_of!(GhosttyRenderStateCursor, password_input) - 17usize]; + ["Offset of field: GhosttyRenderStateCursor::visual_style"] + [::std::mem::offset_of!(GhosttyRenderStateCursor, visual_style) - 20usize]; +}; +impl Default for GhosttyRenderStateCursor { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " Render-state color information.\n\n This struct uses the sized-struct ABI pattern. Initialize with\n GHOSTTY_INIT_SIZED(GhosttyRenderStateColors) before querying\n GHOSTTY_RENDER_STATE_DATA_COLORS.\n\n Example:\n @code\n GhosttyRenderStateColors colors = GHOSTTY_INIT_SIZED(GhosttyRenderStateColors);\n GhosttyResult result = ghostty_render_state_get(\n state, GHOSTTY_RENDER_STATE_DATA_COLORS, &colors);\n @endcode\n\n @ingroup render"] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct GhosttyRenderStateColors { @@ -3072,7 +3793,11 @@ unsafe extern "C" { pub fn ghostty_render_state_end_update(state: GhosttyRenderState) -> GhosttyResult; } unsafe extern "C" { - #[doc = " Get a value from a render state.\n\n The `out` pointer must point to a value of the type corresponding to the\n requested data kind (see GhosttyRenderStateData).\n\n @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE)\n @param data The data kind to query\n @param[out] out Pointer to receive the queried value\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` is\n NULL or `data` is not a recognized enum value\n\n @ingroup render"] + #[doc = " Mark all dirty render-state data as consumed.\n\n This sets the global dirty state to GHOSTTY_RENDER_STATE_DIRTY_FALSE and\n clears every per-row dirty flag. It is idempotent and does not modify cell\n contents or dirty state owned by the terminal. Call this only after a\n complete frame has been rendered successfully; partial consumers should\n use ghostty_render_state_set() and ghostty_render_state_row_set() instead.\n\n @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` is\n NULL\n\n @ingroup render"] + pub fn ghostty_render_state_clean(state: GhosttyRenderState) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Get a value from a render state.\n\n The `out` pointer must point to a value of the type corresponding to the\n requested data kind (see GhosttyRenderStateData).\n\n @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE)\n @param data The data kind to query\n @param[out] out Pointer to receive the queried value\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` or\n `out` is NULL, `data` is not a recognized enum value, or a sized\n output struct is smaller than `sizeof(size_t)`\n\n @ingroup render"] pub fn ghostty_render_state_get( state: GhosttyRenderState, data: GhosttyRenderStateData, @@ -3097,13 +3822,6 @@ unsafe extern "C" { value: *const ::std::os::raw::c_void, ) -> GhosttyResult; } -unsafe extern "C" { - #[doc = " Get the current color information from a render state.\n\n This writes as many fields as fit in the caller-provided sized struct.\n `out_colors->size` must be set by the caller (typically via\n GHOSTTY_INIT_SIZED(GhosttyRenderStateColors)).\n\n @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE)\n @param[out] out_colors Sized output struct to receive render-state colors\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` or\n `out_colors` is NULL, or if `out_colors->size` is smaller than\n `sizeof(size_t)`\n\n @ingroup render"] - pub fn ghostty_render_state_colors_get( - state: GhosttyRenderState, - out_colors: *mut GhosttyRenderStateColors, - ) -> GhosttyResult; -} unsafe extern "C" { #[doc = " Create a new row iterator instance.\n\n All fields except the allocator are left undefined until populated\n via ghostty_render_state_get() with\n GHOSTTY_RENDER_STATE_DATA_ROW_ITERATOR.\n\n @param allocator Pointer to allocator, or NULL to use the default allocator\n @param[out] out_iterator On success, receives the created iterator handle\n @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation\n failure\n\n @ingroup render"] pub fn ghostty_render_state_row_iterator_new( @@ -3116,11 +3834,18 @@ unsafe extern "C" { pub fn ghostty_render_state_row_iterator_free(iterator: GhosttyRenderStateRowIterator); } unsafe extern "C" { - #[doc = " Move a render-state row iterator to the next row.\n\n Returns true if the iterator moved successfully and row data is\n available to read at the new position.\n\n @param iterator The iterator handle to advance (may be NULL)\n @return true if advanced to the next row, false if `iterator` is\n NULL or if the iterator has reached the end\n\n @ingroup render"] + #[doc = " Move a render-state row iterator to the next row.\n\n Rows are visited contiguously in ascending viewport order, starting at\n y = 0. Returns true if the iterator moved successfully and row data is\n available to read at the new position.\n\n @param iterator The iterator handle to advance (may be NULL)\n @return true if advanced to the next row, false if `iterator` is\n NULL or if the iterator has reached the end\n\n @ingroup render"] pub fn ghostty_render_state_row_iterator_next(iterator: GhosttyRenderStateRowIterator) -> bool; } unsafe extern "C" { - #[doc = " Get a value from the current row in a render-state row iterator.\n\n The `out` pointer must point to a value of the type corresponding to the\n requested data kind (see GhosttyRenderStateRowData).\n Call ghostty_render_state_row_iterator_next() at least once before\n calling this function.\n\n @param iterator The iterator handle to query (NULL returns GHOSTTY_INVALID_VALUE)\n @param data The data kind to query\n @param[out] out Pointer to receive the queried value\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if\n `iterator` is NULL or the iterator is not positioned on a row\n\n @ingroup render"] + #[doc = " Move a render-state row iterator to the next row requiring a redraw.\n\n If the global dirty state is GHOSTTY_RENDER_STATE_DIRTY_FALSE, this returns\n false. If it is GHOSTTY_RENDER_STATE_DIRTY_PARTIAL, clean rows are skipped.\n If it is GHOSTTY_RENDER_STATE_DIRTY_FULL, every remaining row is returned\n regardless of its per-row dirty flag. Rows are returned in ascending\n viewport order. This function does not clear any dirty state.\n\n @param iterator The iterator handle to advance (NULL returns false)\n @param[out] out_y Receives the viewport y coordinate when true is returned\n (NULL returns false); it is not modified when false is\n returned\n @return true if advanced to a row requiring a redraw, false if an argument\n is NULL or the iterator has reached the end of the effective dirty\n rows\n\n @ingroup render"] + pub fn ghostty_render_state_row_iterator_next_dirty( + iterator: GhosttyRenderStateRowIterator, + out_y: *mut u16, + ) -> bool; +} +unsafe extern "C" { + #[doc = " Get a value from the current row in a render-state row iterator.\n\n The `out` pointer must point to a value of the type corresponding to the\n requested data kind (see GhosttyRenderStateRowData).\n Call ghostty_render_state_row_iterator_next() or\n ghostty_render_state_row_iterator_next_dirty() at least once before\n calling this function.\n\n @param iterator The iterator handle to query (NULL returns GHOSTTY_INVALID_VALUE)\n @param data The data kind to query\n @param[out] out Pointer to receive the queried value\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if\n `iterator` is NULL or the iterator is not positioned on a row\n\n @ingroup render"] pub fn ghostty_render_state_row_get( iterator: GhosttyRenderStateRowIterator, data: GhosttyRenderStateRowData, @@ -3138,7 +3863,7 @@ unsafe extern "C" { ) -> GhosttyResult; } unsafe extern "C" { - #[doc = " Set an option on the current row in a render-state row iterator.\n\n The `value` pointer must point to a value of the type corresponding to the\n requested option kind (see GhosttyRenderStateRowOption).\n Call ghostty_render_state_row_iterator_next() at least once before\n calling this function.\n\n @param iterator The iterator handle to update (NULL returns GHOSTTY_INVALID_VALUE)\n @param option The option to set\n @param[in] value Pointer to the value to set (NULL returns\n GHOSTTY_INVALID_VALUE)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if\n `iterator` is NULL or the iterator is not positioned on a row\n\n @ingroup render"] + #[doc = " Set an option on the current row in a render-state row iterator.\n\n The `value` pointer must point to a value of the type corresponding to the\n requested option kind (see GhosttyRenderStateRowOption).\n Call ghostty_render_state_row_iterator_next() or\n ghostty_render_state_row_iterator_next_dirty() at least once before\n calling this function.\n\n @param iterator The iterator handle to update (NULL returns GHOSTTY_INVALID_VALUE)\n @param option The option to set\n @param[in] value Pointer to the value to set (NULL returns\n GHOSTTY_INVALID_VALUE)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if\n `iterator` is NULL or the iterator is not positioned on a row\n\n @ingroup render"] pub fn ghostty_render_state_row_set( iterator: GhosttyRenderStateRowIterator, option: GhosttyRenderStateRowOption, @@ -3186,7 +3911,7 @@ pub const GhosttyRenderStateRowCellsData_GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_GRA pub const GhosttyRenderStateRowCellsData_GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_MAX_VALUE: GhosttyRenderStateRowCellsData = 2147483647; #[doc = " Queryable data kinds for ghostty_render_state_row_cells_get().\n\n @ingroup render"] -pub type GhosttyRenderStateRowCellsData = ::std::os::raw::c_uint; +pub type GhosttyRenderStateRowCellsData = ::std::os::raw::c_int; unsafe extern "C" { #[doc = " Move a render-state row cells iterator to the next cell.\n\n Returns true if the iterator moved successfully and cell data is\n available to read at the new position.\n\n @param cells The row cells handle to advance (may be NULL)\n @return true if advanced to the next cell, false if `cells` is\n NULL or if the iterator has reached the end\n\n @ingroup render"] pub fn ghostty_render_state_row_cells_next(cells: GhosttyRenderStateRowCells) -> bool; @@ -3280,10 +4005,16 @@ pub const GhosttyOscCommandType_GHOSTTY_OSC_COMMAND_CONEMU_XTERM_EMULATION: Ghos 20; pub const GhosttyOscCommandType_GHOSTTY_OSC_COMMAND_CONEMU_COMMENT: GhosttyOscCommandType = 21; pub const GhosttyOscCommandType_GHOSTTY_OSC_COMMAND_KITTY_TEXT_SIZING: GhosttyOscCommandType = 22; +pub const GhosttyOscCommandType_GHOSTTY_OSC_COMMAND_KITTY_CLIPBOARD_PROTOCOL: + GhosttyOscCommandType = 23; +pub const GhosttyOscCommandType_GHOSTTY_OSC_COMMAND_KITTY_DND_PROTOCOL: GhosttyOscCommandType = 24; +pub const GhosttyOscCommandType_GHOSTTY_OSC_COMMAND_CONTEXT_SIGNAL: GhosttyOscCommandType = 25; +pub const GhosttyOscCommandType_GHOSTTY_OSC_COMMAND_KITTY_DESKTOP_NOTIFICATION: + GhosttyOscCommandType = 26; pub const GhosttyOscCommandType_GHOSTTY_OSC_COMMAND_TYPE_MAX_VALUE: GhosttyOscCommandType = 2147483647; #[doc = " OSC command types.\n\n @ingroup osc"] -pub type GhosttyOscCommandType = ::std::os::raw::c_uint; +pub type GhosttyOscCommandType = ::std::os::raw::c_int; #[doc = " Invalid data type. Never results in any data extraction."] pub const GhosttyOscCommandData_GHOSTTY_OSC_DATA_INVALID: GhosttyOscCommandData = 0; #[doc = " Window title string data.\n\n Valid for: GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_TITLE\n\n Output type: const char ** (pointer to null-terminated string)\n\n Lifetime: Valid until the next call to any ghostty_osc_* function with\n the same parser instance. Memory is owned by the parser."] @@ -3291,7 +4022,7 @@ pub const GhosttyOscCommandData_GHOSTTY_OSC_DATA_CHANGE_WINDOW_TITLE_STR: Ghostt #[doc = " Window title string data.\n\n Valid for: GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_TITLE\n\n Output type: const char ** (pointer to null-terminated string)\n\n Lifetime: Valid until the next call to any ghostty_osc_* function with\n the same parser instance. Memory is owned by the parser."] pub const GhosttyOscCommandData_GHOSTTY_OSC_DATA_MAX_VALUE: GhosttyOscCommandData = 2147483647; #[doc = " OSC command data types.\n\n These values specify what type of data to extract from an OSC command\n using `ghostty_osc_command_data`.\n\n @ingroup osc"] -pub type GhosttyOscCommandData = ::std::os::raw::c_uint; +pub type GhosttyOscCommandData = ::std::os::raw::c_int; unsafe extern "C" { #[doc = " Create a new OSC parser instance.\n\n Creates a new OSC (Operating System Command) parser using the provided\n allocator. The parser must be freed using ghostty_vt_osc_free() when\n no longer needed.\n\n @param allocator Pointer to the allocator to use for memory management, or NULL to use the default allocator\n @param parser Pointer to store the created parser handle\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup osc"] pub fn ghostty_osc_new( @@ -3361,7 +4092,7 @@ pub const GhosttySgrAttributeTag_GHOSTTY_SGR_ATTR_BG_256: GhosttySgrAttributeTag pub const GhosttySgrAttributeTag_GHOSTTY_SGR_ATTR_FG_256: GhosttySgrAttributeTag = 30; pub const GhosttySgrAttributeTag_GHOSTTY_SGR_ATTR_MAX_VALUE: GhosttySgrAttributeTag = 2147483647; #[doc = " SGR attribute tags.\n\n These values identify the type of an SGR attribute in a tagged union.\n Use the tag to determine which field in the attribute value union to access.\n\n @ingroup sgr"] -pub type GhosttySgrAttributeTag = ::std::os::raw::c_uint; +pub type GhosttySgrAttributeTag = ::std::os::raw::c_int; pub const GhosttySgrUnderline_GHOSTTY_SGR_UNDERLINE_NONE: GhosttySgrUnderline = 0; pub const GhosttySgrUnderline_GHOSTTY_SGR_UNDERLINE_SINGLE: GhosttySgrUnderline = 1; pub const GhosttySgrUnderline_GHOSTTY_SGR_UNDERLINE_DOUBLE: GhosttySgrUnderline = 2; @@ -3370,7 +4101,7 @@ pub const GhosttySgrUnderline_GHOSTTY_SGR_UNDERLINE_DOTTED: GhosttySgrUnderline pub const GhosttySgrUnderline_GHOSTTY_SGR_UNDERLINE_DASHED: GhosttySgrUnderline = 5; pub const GhosttySgrUnderline_GHOSTTY_SGR_UNDERLINE_MAX_VALUE: GhosttySgrUnderline = 2147483647; #[doc = " Underline style types.\n\n @ingroup sgr"] -pub type GhosttySgrUnderline = ::std::os::raw::c_uint; +pub type GhosttySgrUnderline = ::std::os::raw::c_int; #[doc = " Unknown SGR attribute data.\n\n Contains the full parameter list and the partial list where parsing\n encountered an unknown or invalid sequence.\n\n @ingroup sgr"] #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -3574,7 +4305,7 @@ pub const GhosttySysLogLevel_GHOSTTY_SYS_LOG_LEVEL_INFO: GhosttySysLogLevel = 2; pub const GhosttySysLogLevel_GHOSTTY_SYS_LOG_LEVEL_DEBUG: GhosttySysLogLevel = 3; pub const GhosttySysLogLevel_GHOSTTY_SYS_LOG_LEVEL_MAX_VALUE: GhosttySysLogLevel = 2147483647; #[doc = " Log severity levels for the log callback."] -pub type GhosttySysLogLevel = ::std::os::raw::c_uint; +pub type GhosttySysLogLevel = ::std::os::raw::c_int; #[doc = " Callback type for logging.\n\n When installed, internal library log messages are delivered through\n this callback instead of being discarded. The embedder is responsible\n for formatting and routing log output.\n\n @p scope is the log scope name as UTF-8 bytes (e.g. \"osc\", \"kitty\").\n When the log is unscoped (default scope), @p scope_len is 0.\n\n All pointer arguments are only valid for the duration of the callback.\n The callback must be safe to call from any thread.\n\n @param userdata The userdata pointer set via GHOSTTY_SYS_OPT_USERDATA\n @param level The severity level of the log message\n @param scope Pointer to the scope name bytes\n @param scope_len Length of the scope name in bytes\n @param message Pointer to the log message bytes\n @param message_len Length of the log message in bytes"] pub type GhosttySysLogFn = ::std::option::Option< unsafe extern "C" fn( @@ -3596,16 +4327,22 @@ pub type GhosttySysDecodePngFn = ::std::option::Option< out: *mut GhosttySysImage, ) -> bool, >; +#[doc = " Callback type for secure random bytes.\n\n Fills @p buf with @p len cryptographically secure random bytes. The\n library uses this for secrets, so it must be a real CSPRNG (getrandom,\n arc4random_buf, BCryptGenRandom, crypto.getRandomValues, ...); a\n predictable source is a security hole.\n\n @param userdata The userdata pointer set via GHOSTTY_SYS_OPT_USERDATA\n @param buf Buffer to fill\n @param len Number of bytes to fill\n @return true if the buffer was filled, false if no entropy is available"] +pub type GhosttySysRandomSecureFn = ::std::option::Option< + unsafe extern "C" fn(userdata: *mut ::std::os::raw::c_void, buf: *mut u8, len: usize) -> bool, +>; #[doc = " Set the userdata pointer passed to all sys callbacks.\n\n Input type: void* (or NULL)"] pub const GhosttySysOption_GHOSTTY_SYS_OPT_USERDATA: GhosttySysOption = 0; #[doc = " Set the PNG decode function.\n\n When set, the terminal can accept PNG images via the Kitty\n Graphics Protocol. When cleared (NULL value), PNG decoding is\n unsupported and PNG image data will be rejected.\n\n Input type: GhosttySysDecodePngFn (function pointer, or NULL)"] pub const GhosttySysOption_GHOSTTY_SYS_OPT_DECODE_PNG: GhosttySysOption = 1; #[doc = " Set the log callback.\n\n When set, internal library log messages are delivered to this\n callback. When cleared (NULL value), log messages are silently\n discarded.\n\n Use ghostty_sys_log_stderr as a convenience callback that\n writes formatted messages to stderr.\n\n Which log levels are emitted depends on the build mode of the\n library and is not configurable at runtime. Debug builds emit\n all levels (debug and above). Release builds emit info and\n above; debug-level messages are compiled out entirely and will\n never reach the callback.\n\n Input type: GhosttySysLogFn (function pointer, or NULL)"] pub const GhosttySysOption_GHOSTTY_SYS_OPT_LOG: GhosttySysOption = 2; -#[doc = " Set the log callback.\n\n When set, internal library log messages are delivered to this\n callback. When cleared (NULL value), log messages are silently\n discarded.\n\n Use ghostty_sys_log_stderr as a convenience callback that\n writes formatted messages to stderr.\n\n Which log levels are emitted depends on the build mode of the\n library and is not configurable at runtime. Debug builds emit\n all levels (debug and above). Release builds emit info and\n above; debug-level messages are compiled out entirely and will\n never reach the callback.\n\n Input type: GhosttySysLogFn (function pointer, or NULL)"] +#[doc = " Override the secure random source.\n\n By default the library draws secure random bytes from the\n platform (getrandom or arc4random_buf on POSIX, CNG on Windows).\n Targets without one, such as wasm32-freestanding, have no default\n and operations that need entropy fail with GHOSTTY_IO_ERROR until\n this is set. When set,\n it is used instead of the platform source on every target. When\n cleared (NULL value), the platform default is restored.\n\n Input type: GhosttySysRandomSecureFn (function pointer, or NULL)"] +pub const GhosttySysOption_GHOSTTY_SYS_OPT_RANDOM_SECURE: GhosttySysOption = 3; +#[doc = " Override the secure random source.\n\n By default the library draws secure random bytes from the\n platform (getrandom or arc4random_buf on POSIX, CNG on Windows).\n Targets without one, such as wasm32-freestanding, have no default\n and operations that need entropy fail with GHOSTTY_IO_ERROR until\n this is set. When set,\n it is used instead of the platform source on every target. When\n cleared (NULL value), the platform default is restored.\n\n Input type: GhosttySysRandomSecureFn (function pointer, or NULL)"] pub const GhosttySysOption_GHOSTTY_SYS_OPT_MAX_VALUE: GhosttySysOption = 2147483647; #[doc = " System option identifiers for ghostty_sys_set()."] -pub type GhosttySysOption = ::std::os::raw::c_uint; +pub type GhosttySysOption = ::std::os::raw::c_int; unsafe extern "C" { #[doc = " Set a system-level option.\n\n Configures a process-global implementation function. These should be\n set once at startup before using any terminal functionality that\n depends on them.\n\n @param option The option to set\n @param value Pointer to the value (type depends on the option),\n or NULL to clear it\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the\n option is not recognized"] pub fn ghostty_sys_set( @@ -3640,7 +4377,7 @@ pub const GhosttyKeyAction_GHOSTTY_KEY_ACTION_REPEAT: GhosttyKeyAction = 2; #[doc = " Key is being repeated (held down)"] pub const GhosttyKeyAction_GHOSTTY_KEY_ACTION_MAX_VALUE: GhosttyKeyAction = 2147483647; #[doc = " Keyboard input event types.\n\n @ingroup key"] -pub type GhosttyKeyAction = ::std::os::raw::c_uint; +pub type GhosttyKeyAction = ::std::os::raw::c_int; #[doc = " Keyboard modifier keys bitmask.\n\n A bitmask representing all keyboard modifiers. This tracks which modifier keys\n are pressed and, where supported by the platform, which side (left or right)\n of each modifier is active.\n\n Use the GHOSTTY_MODS_* constants to test and set individual modifiers.\n\n Modifier side bits are only meaningful when the corresponding modifier bit is set.\n Not all platforms support distinguishing between left and right modifier\n keys and Ghostty is built to expect that some platforms may not provide this\n information.\n\n @ingroup key"] pub type GhosttyMods = u16; pub const GhosttyKey_GHOSTTY_KEY_UNIDENTIFIED: GhosttyKey = 0; @@ -3821,7 +4558,7 @@ pub const GhosttyKey_GHOSTTY_KEY_CUT: GhosttyKey = 174; pub const GhosttyKey_GHOSTTY_KEY_PASTE: GhosttyKey = 175; pub const GhosttyKey_GHOSTTY_KEY_MAX_VALUE: GhosttyKey = 2147483647; #[doc = " Physical key codes.\n\n The set of key codes that Ghostty is aware of. These represent physical keys\n on the keyboard and are layout-independent. For example, the \"a\" key on a US\n keyboard is the same as the \"ф\" key on a Russian keyboard, but both will\n report the same key_a value.\n\n Layout-dependent strings are provided separately as UTF-8 text and are produced\n by the platform. These values are based on the W3C UI Events KeyboardEvent code\n standard. See: https://www.w3.org/TR/uievents-code\n\n @ingroup key"] -pub type GhosttyKey = ::std::os::raw::c_uint; +pub type GhosttyKey = ::std::os::raw::c_int; unsafe extern "C" { #[doc = " Create a new key event instance.\n\n Creates a new key event with default values. The event must be freed using\n ghostty_key_event_free() when no longer needed.\n\n @param allocator Pointer to the allocator to use for memory management, or NULL to use the default allocator\n @param event Pointer to store the created key event handle\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup key"] pub fn ghostty_key_event_new( @@ -3916,7 +4653,7 @@ pub const GhosttyOptionAsAlt_GHOSTTY_OPTION_AS_ALT_RIGHT: GhosttyOptionAsAlt = 3 #[doc = " Only right option key is treated as alt"] pub const GhosttyOptionAsAlt_GHOSTTY_OPTION_AS_ALT_MAX_VALUE: GhosttyOptionAsAlt = 2147483647; #[doc = " macOS option key behavior.\n\n Determines whether the \"option\" key on macOS is treated as \"alt\" or not.\n See the Ghostty `macos-option-as-alt` configuration option for more details.\n\n @ingroup key"] -pub type GhosttyOptionAsAlt = ::std::os::raw::c_uint; +pub type GhosttyOptionAsAlt = ::std::os::raw::c_int; #[doc = " Terminal DEC mode 1: cursor key application mode (value: bool)"] pub const GhosttyKeyEncoderOption_GHOSTTY_KEY_ENCODER_OPT_CURSOR_KEY_APPLICATION: GhosttyKeyEncoderOption = 0; @@ -3944,7 +4681,7 @@ pub const GhosttyKeyEncoderOption_GHOSTTY_KEY_ENCODER_OPT_BACKARROW_KEY_MODE: pub const GhosttyKeyEncoderOption_GHOSTTY_KEY_ENCODER_OPT_MAX_VALUE: GhosttyKeyEncoderOption = 2147483647; #[doc = " Key encoder option identifiers.\n\n These values are used with ghostty_key_encoder_setopt() to configure\n the behavior of the key encoder.\n\n @ingroup key"] -pub type GhosttyKeyEncoderOption = ::std::os::raw::c_uint; +pub type GhosttyKeyEncoderOption = ::std::os::raw::c_int; unsafe extern "C" { #[doc = " Create a new key encoder instance.\n\n Creates a new key encoder with default options. The encoder can be configured\n using ghostty_key_encoder_setopt() and must be freed using\n ghostty_key_encoder_free() when no longer needed.\n\n @param allocator Pointer to the allocator to use for memory management, or NULL to use the default allocator\n @param encoder Pointer to store the created encoder handle\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup key"] pub fn ghostty_key_encoder_new( @@ -3997,7 +4734,7 @@ pub const GhosttyMouseAction_GHOSTTY_MOUSE_ACTION_MOTION: GhosttyMouseAction = 2 #[doc = " Mouse moved."] pub const GhosttyMouseAction_GHOSTTY_MOUSE_ACTION_MAX_VALUE: GhosttyMouseAction = 2147483647; #[doc = " Mouse event action type.\n\n @ingroup mouse"] -pub type GhosttyMouseAction = ::std::os::raw::c_uint; +pub type GhosttyMouseAction = ::std::os::raw::c_int; pub const GhosttyMouseButton_GHOSTTY_MOUSE_BUTTON_UNKNOWN: GhosttyMouseButton = 0; pub const GhosttyMouseButton_GHOSTTY_MOUSE_BUTTON_LEFT: GhosttyMouseButton = 1; pub const GhosttyMouseButton_GHOSTTY_MOUSE_BUTTON_RIGHT: GhosttyMouseButton = 2; @@ -4012,7 +4749,7 @@ pub const GhosttyMouseButton_GHOSTTY_MOUSE_BUTTON_TEN: GhosttyMouseButton = 10; pub const GhosttyMouseButton_GHOSTTY_MOUSE_BUTTON_ELEVEN: GhosttyMouseButton = 11; pub const GhosttyMouseButton_GHOSTTY_MOUSE_BUTTON_MAX_VALUE: GhosttyMouseButton = 2147483647; #[doc = " Mouse button identity.\n\n @ingroup mouse"] -pub type GhosttyMouseButton = ::std::os::raw::c_uint; +pub type GhosttyMouseButton = ::std::os::raw::c_int; #[doc = " Mouse position in surface-space pixels.\n\n @ingroup mouse"] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -4103,7 +4840,7 @@ pub const GhosttyMouseTrackingMode_GHOSTTY_MOUSE_TRACKING_ANY: GhosttyMouseTrack pub const GhosttyMouseTrackingMode_GHOSTTY_MOUSE_TRACKING_MAX_VALUE: GhosttyMouseTrackingMode = 2147483647; #[doc = " Mouse tracking mode.\n\n @ingroup mouse"] -pub type GhosttyMouseTrackingMode = ::std::os::raw::c_uint; +pub type GhosttyMouseTrackingMode = ::std::os::raw::c_int; pub const GhosttyMouseFormat_GHOSTTY_MOUSE_FORMAT_X10: GhosttyMouseFormat = 0; pub const GhosttyMouseFormat_GHOSTTY_MOUSE_FORMAT_UTF8: GhosttyMouseFormat = 1; pub const GhosttyMouseFormat_GHOSTTY_MOUSE_FORMAT_SGR: GhosttyMouseFormat = 2; @@ -4111,7 +4848,7 @@ pub const GhosttyMouseFormat_GHOSTTY_MOUSE_FORMAT_URXVT: GhosttyMouseFormat = 3; pub const GhosttyMouseFormat_GHOSTTY_MOUSE_FORMAT_SGR_PIXELS: GhosttyMouseFormat = 4; pub const GhosttyMouseFormat_GHOSTTY_MOUSE_FORMAT_MAX_VALUE: GhosttyMouseFormat = 2147483647; #[doc = " Mouse output format.\n\n @ingroup mouse"] -pub type GhosttyMouseFormat = ::std::os::raw::c_uint; +pub type GhosttyMouseFormat = ::std::os::raw::c_int; #[doc = " Mouse encoder size and geometry context.\n\n This describes the rendered terminal geometry used to convert\n surface-space positions into encoded coordinates.\n\n @ingroup mouse"] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -4175,7 +4912,7 @@ pub const GhosttyMouseEncoderOption_GHOSTTY_MOUSE_ENCODER_OPT_TRACK_LAST_CELL: pub const GhosttyMouseEncoderOption_GHOSTTY_MOUSE_ENCODER_OPT_MAX_VALUE: GhosttyMouseEncoderOption = 2147483647; #[doc = " Mouse encoder option identifiers.\n\n These values are used with ghostty_mouse_encoder_setopt() to configure\n the behavior of the mouse encoder.\n\n @ingroup mouse"] -pub type GhosttyMouseEncoderOption = ::std::os::raw::c_uint; +pub type GhosttyMouseEncoderOption = ::std::os::raw::c_int; unsafe extern "C" { #[doc = " Create a new mouse encoder instance.\n\n @param allocator Pointer to allocator, or NULL to use the default allocator\n @param encoder Pointer to store the created encoder handle\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup mouse"] pub fn ghostty_mouse_encoder_new( @@ -4216,12 +4953,73 @@ unsafe extern "C" { out_len: *mut usize, ) -> GhosttyResult; } +#[doc = " The user pasted from a clipboard: keybind, menu, middle click."] +pub const GhosttyPasteSource_GHOSTTY_PASTE_SOURCE_CLIPBOARD: GhosttyPasteSource = 0; +#[doc = " Text inserted some other way: IME commit, drag and drop, scripted\n input. Always written as text, never as a paste event, matching\n kitty. This is not a way to opt out of paste events; an embedder\n that doesn't want them doesn't install a clipboard_read callback."] +pub const GhosttyPasteSource_GHOSTTY_PASTE_SOURCE_TEXT: GhosttyPasteSource = 1; +#[doc = " Text inserted some other way: IME commit, drag and drop, scripted\n input. Always written as text, never as a paste event, matching\n kitty. This is not a way to opt out of paste events; an embedder\n that doesn't want them doesn't install a clipboard_read callback."] +pub const GhosttyPasteSource_GHOSTTY_PASTE_SOURCE_MAX_VALUE: GhosttyPasteSource = 2147483647; +#[doc = " Why a paste happened."] +pub type GhosttyPasteSource = ::std::os::raw::c_int; +#[doc = " A paste of clipboard contents into the terminal.\n\n This is a sized struct; set `size` to `sizeof(GhosttyPaste)`. The\n MIME type array and the strings it points to are borrowed only for\n the duration of the ghostty_terminal_paste() call, as is everything\n the reader produces."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct GhosttyPaste { + #[doc = " Size of this struct in bytes."] + pub size: usize, + #[doc = " The clipboard the contents came from. Reported to the program on a\n paste event (the selection and primary locations are both reported\n as the primary selection, the protocol knows only two); no effect\n on a text paste."] + pub location: GhosttyClipboardLocation, + #[doc = " Why this paste happened."] + pub source: GhosttyPasteSource, + #[doc = " Borrowed array of the MIME types of the representations available,\n in preferred order. A text paste reads and writes the first entry\n with a text MIME type such as \"text/plain\" and ignores the rest. A\n paste event lists every entry and reads none. May be NULL when\n mimes_len is zero, which is nothing to paste."] + pub mimes: *const GhosttyString, + #[doc = " Number of entries in mimes."] + pub mimes_len: usize, + #[doc = " Produces the data of a representation on demand. Required when\n mimes_len is nonzero.\n\n Called at most once per ghostty_terminal_paste() call: for the\n text representation being pasted, never for anything else and\n never for a paste event. The MIME type requested is always an\n entry of `mimes`, passed through exactly as given there (the same\n pointer and length), so the callback may identify the\n representation by pointer or by content. A false return fails the\n paste with GHOSTTY_IO_ERROR."] + pub reader: GhosttyMimeReader, + #[doc = " Write text that could inject commands. Call with false, confirm\n with the user on GHOSTTY_REJECTED, and call again with true."] + pub allow_unsafe: bool, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of GhosttyPaste"][::std::mem::size_of::() - 56usize]; + ["Alignment of GhosttyPaste"][::std::mem::align_of::() - 8usize]; + ["Offset of field: GhosttyPaste::size"][::std::mem::offset_of!(GhosttyPaste, size) - 0usize]; + ["Offset of field: GhosttyPaste::location"] + [::std::mem::offset_of!(GhosttyPaste, location) - 8usize]; + ["Offset of field: GhosttyPaste::source"] + [::std::mem::offset_of!(GhosttyPaste, source) - 12usize]; + ["Offset of field: GhosttyPaste::mimes"][::std::mem::offset_of!(GhosttyPaste, mimes) - 16usize]; + ["Offset of field: GhosttyPaste::mimes_len"] + [::std::mem::offset_of!(GhosttyPaste, mimes_len) - 24usize]; + ["Offset of field: GhosttyPaste::reader"] + [::std::mem::offset_of!(GhosttyPaste, reader) - 32usize]; + ["Offset of field: GhosttyPaste::allow_unsafe"] + [::std::mem::offset_of!(GhosttyPaste, allow_unsafe) - 48usize]; +}; +impl Default for GhosttyPaste { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +unsafe extern "C" { + #[doc = " Paste into the terminal according to its current state: a Kitty\n clipboard protocol paste event if mode 5522 is enabled and a\n clipboard_read callback is installed, otherwise the text framed per\n mode 2004. See the group documentation for the full behavior. Output\n streams through the write_pty callback in chunks. The viewport is not\n scrolled; that is up to the embedder, as for key input.\n\n A paste event records a session grant for its one-time password only\n once the event is written; a failed call never leaves a grant for an\n event that was never sent.\n\n @param terminal The terminal handle\n @param paste The paste request, borrowed for the duration of the call\n @param[out] out_written On success, whether anything was written to\n the pty (the encoded text or a paste event). False means\n there was nothing to paste: no non-empty text\n representation. May be NULL.\n @return GHOSTTY_SUCCESS on success (see @p out_written);\n GHOSTTY_REJECTED if the text could inject commands and\n GhosttyPaste::allow_unsafe is false (nothing was written);\n GHOSTTY_INVALID_VALUE for a NULL terminal or paste, MIME\n types without a reader, or when no write_pty callback is\n installed; GHOSTTY_OUT_OF_MEMORY; GHOSTTY_IO_ERROR if the\n reader failed or there is no secure entropy source to mint a\n paste event password (wasm32-freestanding without\n GHOSTTY_SYS_OPT_RANDOM_SECURE set). Errors write nothing."] + pub fn ghostty_terminal_paste( + terminal: GhosttyTerminal, + paste: *const GhosttyPaste, + out_written: *mut bool, + ) -> GhosttyResult; +} unsafe extern "C" { - #[doc = " Check if paste data is safe to paste into the terminal.\n\n Data is considered unsafe if it contains:\n - Newlines (`\\n`) which can inject commands\n - The bracketed paste end sequence (`\\x1b[201~`) which can be used\n to exit bracketed paste mode and inject commands\n\n This check is conservative and considers data unsafe regardless of\n current terminal state.\n\n @param data The paste data to check (must not be NULL)\n @param len The length of the data in bytes\n @return true if the data is safe to paste, false otherwise"] + #[doc = " Check if paste data is safe to paste into the terminal.\n\n Data is considered unsafe if it contains:\n - Newlines (`\\n`) which can inject commands\n - The bracketed paste end sequence (`\\x1b[201~`) which can be used\n to exit bracketed paste mode and inject commands\n\n This check is conservative and considers data unsafe regardless of\n current terminal state. ghostty_terminal_paste() applies the\n terminal-state-aware rule itself (newlines are safe inside a\n bracketed paste); use this to apply the stricter rule on top.\n\n @param data The paste data to check (must not be NULL)\n @param len The length of the data in bytes\n @return true if the data is safe to paste, false otherwise"] pub fn ghostty_paste_is_safe(data: *const ::std::os::raw::c_char, len: usize) -> bool; } unsafe extern "C" { - #[doc = " Encode paste data for writing to the terminal pty.\n\n This function prepares paste data for terminal input by:\n - Stripping unsafe control bytes (NUL, ESC, DEL, etc.) by replacing\n them with spaces\n - Wrapping the data in bracketed paste sequences if @p bracketed is true\n - Replacing newlines with carriage returns if @p bracketed is false\n\n The input @p data buffer is modified in place during encoding. The\n encoded result (potentially with bracketed paste prefix/suffix) is\n written to the output buffer.\n\n If the output buffer is too small, the function returns\n GHOSTTY_OUT_OF_SPACE and sets the required size in @p out_written.\n The caller can then retry with a sufficiently sized buffer.\n\n @param data The paste data to encode (modified in place, may be NULL)\n @param data_len The length of the input data in bytes\n @param bracketed Whether bracketed paste mode is active\n @param buf Output buffer to write the encoded result into (may be NULL)\n @param buf_len Size of the output buffer in bytes\n @param[out] out_written On success, the number of bytes written. On\n GHOSTTY_OUT_OF_SPACE, the required buffer size.\n @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if the buffer\n is too small"] + #[doc = " Encode paste data for writing to the terminal pty.\n\n This function prepares paste data for terminal input by:\n - Stripping unsafe control bytes (NUL, ESC, DEL, etc.) by replacing\n them with spaces\n - Wrapping the data in bracketed paste sequences if @p bracketed is true\n - Replacing newlines with carriage returns if @p bracketed is false\n\n The input @p data buffer is modified in place during encoding. The\n encoded result (potentially with bracketed paste prefix/suffix) is\n written to the output buffer.\n\n If the output buffer is too small, the function returns\n GHOSTTY_OUT_OF_SPACE and sets the required size in @p out_written.\n The caller can then retry with a sufficiently sized buffer.\n\n This is the encoder ghostty_terminal_paste() uses for a text paste;\n use it directly when there is no terminal to paste into.\n\n @param data The paste data to encode (modified in place, may be NULL)\n @param data_len The length of the input data in bytes\n @param bracketed Whether bracketed paste mode is active\n @param buf Output buffer to write the encoded result into (may be NULL)\n @param buf_len Size of the output buffer in bytes\n @param[out] out_written On success, the number of bytes written. On\n GHOSTTY_OUT_OF_SPACE, the required buffer size.\n @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if the buffer\n is too small"] pub fn ghostty_paste_encode( data: *mut ::std::os::raw::c_char, data_len: usize, @@ -4231,6 +5029,242 @@ unsafe extern "C" { out_written: *mut usize, ) -> GhosttyResult; } +#[doc = " ghostty_search_tick() can make progress without terminal access."] +pub const GhosttySearchStatus_GHOSTTY_SEARCH_STATUS_RUNNING: GhosttySearchStatus = 0; +#[doc = " Blocked until ghostty_search_feed(). This is also the state right\n after a needle is set, since the search has not yet seen the\n terminal."] +pub const GhosttySearchStatus_GHOSTTY_SEARCH_STATUS_FEED_REQUIRED: GhosttySearchStatus = 1; +#[doc = " Caught up with the terminal state as of the last feed. This never\n means finished forever, since later terminal writes require\n another feed to be seen. A search with no needle set also reports\n complete, since there is nothing to look for."] +pub const GhosttySearchStatus_GHOSTTY_SEARCH_STATUS_COMPLETE: GhosttySearchStatus = 2; +#[doc = " Caught up with the terminal state as of the last feed. This never\n means finished forever, since later terminal writes require\n another feed to be seen. A search with no needle set also reports\n complete, since there is nothing to look for."] +pub const GhosttySearchStatus_GHOSTTY_SEARCH_STATUS_MAX_VALUE: GhosttySearchStatus = 2147483647; +#[doc = " Progress state of a search.\n\n @ingroup search"] +pub type GhosttySearchStatus = ::std::os::raw::c_int; +#[doc = " Scroll the viewport so the match is visible, only if it is not\n already visible. This is the default."] +pub const GhosttySearchScroll_GHOSTTY_SEARCH_SCROLL_IF_NEEDED: GhosttySearchScroll = 0; +#[doc = " Never scroll the viewport."] +pub const GhosttySearchScroll_GHOSTTY_SEARCH_SCROLL_NONE: GhosttySearchScroll = 1; +#[doc = " Never scroll the viewport."] +pub const GhosttySearchScroll_GHOSTTY_SEARCH_SCROLL_MAX_VALUE: GhosttySearchScroll = 2147483647; +#[doc = " Scroll policy applied when a match becomes selected via\n GHOSTTY_SEARCH_OPT_SELECT_NEXT or GHOSTTY_SEARCH_OPT_SELECT_PREV.\n\n @ingroup search"] +pub type GhosttySearchScroll = ::std::os::raw::c_int; +#[doc = " Current search status: GhosttySearchStatus*."] +pub const GhosttySearchData_GHOSTTY_SEARCH_DATA_STATUS: GhosttySearchData = 0; +#[doc = " The needle this search is looking for: GhosttyString*. The bytes\n are borrowed from the search and remain valid until the needle is\n changed or the search is freed. Returns GHOSTTY_NO_VALUE when no\n needle is set."] +pub const GhosttySearchData_GHOSTTY_SEARCH_DATA_NEEDLE: GhosttySearchData = 1; +#[doc = " Total matches found so far on the active screen: size_t*. Zero\n until the first feed."] +pub const GhosttySearchData_GHOSTTY_SEARCH_DATA_TOTAL_MATCHES: GhosttySearchData = 2; +#[doc = " Index of the selected match: size_t*. This indexes the newest to\n oldest ordering of GHOSTTY_SEARCH_DATA_MATCHES, where 0 is the\n newest match, so a \"k of n\" find bar renders index + 1 of\n GHOSTTY_SEARCH_DATA_TOTAL_MATCHES. Returns GHOSTTY_NO_VALUE when\n nothing is selected."] +pub const GhosttySearchData_GHOSTTY_SEARCH_DATA_SELECTED_INDEX: GhosttySearchData = 3; +#[doc = " The selected match: GhosttySelection*. This is an untracked\n snapshot with standard GhosttySelection lifetime rules. Returns\n GHOSTTY_NO_VALUE when nothing is selected."] +pub const GhosttySearchData_GHOSTTY_SEARCH_DATA_SELECTED_MATCH: GhosttySearchData = 4; +#[doc = " All matches on the active screen, ordered newest to oldest, from\n the bottom of the active area up through scrollback:\n GhosttySelectionBuffer*. Set ptr to NULL with cap 0 to query the\n required capacity. An undersized buffer returns\n GHOSTTY_OUT_OF_SPACE with the required capacity in len."] +pub const GhosttySearchData_GHOSTTY_SEARCH_DATA_MATCHES: GhosttySearchData = 5; +#[doc = " Matches on the pages covering the viewport, for drawing highlight\n rectangles: GhosttySelectionBuffer*. The list is computed during\n feeds and cached, so it reflects the viewport as of the last\n feed.\n\n Matches are found a page at a time, so the list can include\n matches slightly outside the visible viewport when they share a\n page with it. Ghostty's own renderer behaves the same way.\n Converting each match to viewport coordinates with\n ghostty_terminal_point_from_grid_ref() clips this naturally: skip\n matches that fail the conversion or whose row is beyond the\n visible row count."] +pub const GhosttySearchData_GHOSTTY_SEARCH_DATA_VIEWPORT_MATCHES: GhosttySearchData = 6; +#[doc = " Current scroll policy: GhosttySearchScroll*."] +pub const GhosttySearchData_GHOSTTY_SEARCH_DATA_SELECT_SCROLL: GhosttySearchData = 7; +#[doc = " Current scroll policy: GhosttySearchScroll*."] +pub const GhosttySearchData_GHOSTTY_SEARCH_DATA_MAX_VALUE: GhosttySearchData = 2147483647; +#[doc = " Data fields readable with ghostty_search_get(). The output value\n type is documented per field.\n\n All reads reflect the terminal's active screen as of the last feed.\n When the running application switches to the alternate screen, the\n next feed switches counts, matches, and selection to that screen's\n results. Primary screen results, including completed scrollback\n searches, are retained and restored on the way back.\n\n @ingroup search"] +pub type GhosttySearchData = ::std::os::raw::c_int; +#[doc = " Set the needle to search for: const GhosttyString*. The bytes are\n copied, so the caller's memory does not need to outlive the call.\n Matching is byte-exact except ASCII letters, which compare\n case-insensitively.\n\n Changing the needle restarts the search from scratch and drops\n all results. As an exception, setting a needle equal to the current\n one (compared the same way as matching) keeps existing results,\n so find bars can resubmit freely. A NULL or empty value clears\n the needle and returns the search to idle.\n\n Replacing or clearing a needle releases tracked state held\n within the terminal, so the caller must serialize this with all\n other access to the same terminal. Returns GHOSTTY_INVALID_VALUE\n after the terminal was freed."] +pub const GhosttySearchOption_GHOSTTY_SEARCH_OPT_NEEDLE: GhosttySearchOption = 0; +#[doc = " Select the next match, moving toward older content: from the\n bottom of the screen upward into history, the direction a search\n from the prompt usually wants. Wraps around past the oldest\n match.\n\n The value must be NULL. It is reserved for future use.\n\n This catches up with the terminal first, so it is safe to call at\n any time relative to feeds. The viewport scrolls to the newly\n selected match according to GHOSTTY_SEARCH_OPT_SELECT_SCROLL.\n This reads the terminal, so the caller must serialize it with all\n other access to the same terminal. Returns GHOSTTY_NO_VALUE when\n there are no matches."] +pub const GhosttySearchOption_GHOSTTY_SEARCH_OPT_SELECT_NEXT: GhosttySearchOption = 1; +#[doc = " Select the previous match, moving toward newer content, wrapping\n around past the newest match. Otherwise identical to\n GHOSTTY_SEARCH_OPT_SELECT_NEXT."] +pub const GhosttySearchOption_GHOSTTY_SEARCH_OPT_SELECT_PREV: GhosttySearchOption = 2; +#[doc = " Set the scroll policy applied by the select options: const\n GhosttySearchScroll*. The policy persists until changed. A NULL\n value resets it to GHOSTTY_SEARCH_SCROLL_IF_NEEDED. This only\n modifies search-owned state and never reads the terminal."] +pub const GhosttySearchOption_GHOSTTY_SEARCH_OPT_SELECT_SCROLL: GhosttySearchOption = 3; +#[doc = " Set the scroll policy applied by the select options: const\n GhosttySearchScroll*. The policy persists until changed. A NULL\n value resets it to GHOSTTY_SEARCH_SCROLL_IF_NEEDED. This only\n modifies search-owned state and never reads the terminal."] +pub const GhosttySearchOption_GHOSTTY_SEARCH_OPT_MAX_VALUE: GhosttySearchOption = 2147483647; +#[doc = " Options writable with ghostty_search_set(). The value type, and\n what a NULL value means, is documented per option.\n\n @ingroup search"] +pub type GhosttySearchOption = ::std::os::raw::c_int; +unsafe extern "C" { + #[doc = " Create a search bound to a terminal.\n\n The search borrows the terminal and never frees it. The search and\n the terminal can be freed in either order; see ghostty_search_free().\n\n The search starts idle with no needle: it reports\n GHOSTTY_SEARCH_STATUS_COMPLETE and finds nothing. Set\n GHOSTTY_SEARCH_OPT_NEEDLE to start searching.\n\n Creation is cheap and does not read terminal contents, but it\n registers the search with the terminal so the two can be freed in\n any order. The caller must serialize this call with all other\n access to the same terminal.\n\n @param allocator Allocator, or NULL for the default allocator\n @param out_search Receives the created search handle\n @param terminal Terminal to bind the search to\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if\n out_search or terminal is invalid, or GHOSTTY_OUT_OF_MEMORY\n if allocation fails\n\n @ingroup search"] + pub fn ghostty_search_new( + allocator: *const GhosttyAllocator, + out_search: *mut GhosttySearch, + terminal: GhosttyTerminal, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Free a search.\n\n If the bound terminal is still alive, this releases tracked state\n the search holds within it, so the caller must serialize this call\n with all other access to the same terminal. If the terminal was\n already freed, the search has been detached and this releases only\n search-owned memory. Passing NULL is allowed and is a no-op.\n\n @param search Search handle to free\n\n @ingroup search"] + pub fn ghostty_search_free(search: GhosttySearch); +} +unsafe extern "C" { + #[doc = " Make a bounded amount of search progress.\n\n This only works on data the search has already copied and never\n reads the terminal, so it is safe to call while another thread\n modifies the terminal. Call it in a loop while the status is\n GHOSTTY_SEARCH_STATUS_RUNNING. When the status becomes\n GHOSTTY_SEARCH_STATUS_FEED_REQUIRED, call ghostty_search_feed() to\n unblock it.\n\n @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE)\n @param[out] out_status Receives the status after the tick (may be NULL)\n @return GHOSTTY_SUCCESS on success, or GHOSTTY_INVALID_VALUE if\n search is NULL\n\n @ingroup search"] + pub fn ghostty_search_tick( + search: GhosttySearch, + out_status: *mut GhosttySearchStatus, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Read the terminal to update the search.\n\n Each feed catches the search up with the terminal: it reconciles\n the tracked screens against the live ones, re-scans the active\n area, refreshes the viewport match list, gives the scrollback\n searcher its next chunk of data, and prunes results that scrollback\n eviction invalidated. Feeding is also the only way the search\n learns about terminal changes, so keep feeding periodically while\n the search is in use, even after it reports complete.\n\n This reads the terminal, so the caller must serialize it with all\n other access to the same terminal. Each call does a bounded amount\n of work so that any caller-held terminal lock is held only briefly.\n\n @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE)\n @return GHOSTTY_SUCCESS on success, or GHOSTTY_INVALID_VALUE if\n search is NULL or the terminal was freed\n\n @ingroup search"] + pub fn ghostty_search_feed(search: GhosttySearch) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Feed and tick until the search is caught up with the terminal.\n\n This is a blocking convenience for one-shot and single-threaded\n embedders. It always performs at least one feed, so it also picks\n up any terminal changes since the last feed, then loops until the\n status is GHOSTTY_SEARCH_STATUS_COMPLETE. Searching a large\n scrollback can take a while, so interactive embedders should drive\n ghostty_search_tick() and ghostty_search_feed() themselves.\n\n This reads the terminal for the entire call, so the caller must\n serialize it with all other access to the same terminal.\n\n @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE)\n @return GHOSTTY_SUCCESS on success, or GHOSTTY_INVALID_VALUE if\n search is NULL or the terminal was freed\n\n @ingroup search"] + pub fn ghostty_search_run(search: GhosttySearch) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Write an option to a search.\n\n The value type, and what a NULL value means, depends on the option\n and is documented by GhosttySearchOption. The needle and select\n options touch the terminal, so the caller must serialize those\n calls with all other access to the same terminal.\n GHOSTTY_SEARCH_OPT_SELECT_SCROLL only modifies search-owned state.\n\n @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE)\n @param option Option to write\n @param value Pointer to the input value for the option. The meaning\n of NULL is documented per option.\n @return GHOSTTY_SUCCESS on success, GHOSTTY_NO_VALUE if a select\n option found no matches, GHOSTTY_OUT_OF_MEMORY if\n allocation fails, or GHOSTTY_INVALID_VALUE if search,\n option, or value is invalid or the option needs a terminal\n that was already freed\n\n @ingroup search"] + pub fn ghostty_search_set( + search: GhosttySearch, + option: GhosttySearchOption, + value: *const ::std::os::raw::c_void, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Read a data field from a search.\n\n The output value type depends on data and is documented by\n GhosttySearchData. This never reads the terminal, so it is safe to\n call while another thread modifies the terminal. Returned\n selections are untracked snapshots with standard GhosttySelection\n lifetime rules.\n\n @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE)\n @param data Data field to read\n @param value Output pointer whose type depends on data\n @return GHOSTTY_SUCCESS on success, GHOSTTY_NO_VALUE if the\n requested data has no value, GHOSTTY_OUT_OF_SPACE if a\n provided GhosttySelectionBuffer is too small (required\n capacity in its len), GHOSTTY_OUT_OF_MEMORY if collecting\n viewport matches fails, or GHOSTTY_INVALID_VALUE if search,\n data, or value is invalid\n\n @ingroup search"] + pub fn ghostty_search_get( + search: GhosttySearch, + data: GhosttySearchData, + value: *mut ::std::os::raw::c_void, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Read multiple data fields from a search in a single call.\n\n This is an optimization over calling ghostty_search_get() multiple\n times. Each entry in values must point to storage of the type\n documented by the corresponding GhosttySearchData key.\n\n If any individual read fails, the function returns that error and\n writes the index of the failing key to out_written when out_written\n is non-NULL. Earlier keys have already been written. On success,\n out_written receives count when non-NULL. A too-small\n GhosttySelectionBuffer stops the batch with GHOSTTY_OUT_OF_SPACE at\n that key's index with the required capacity in its len, so order\n buffer-valued keys after scalar keys.\n\n @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE)\n @param count Number of data fields to read\n @param keys Data fields to read (must not be NULL)\n @param values Output pointers corresponding to keys (must not be NULL)\n @param out_written Optional number of fields read, or failing index\n on error\n @return GHOSTTY_SUCCESS on success, or the first failing read's\n result\n\n @ingroup search"] + pub fn ghostty_search_get_multi( + search: GhosttySearch, + count: usize, + keys: *const GhosttySearchData, + values: *mut *mut ::std::os::raw::c_void, + out_written: *mut usize, + ) -> GhosttyResult; +} +#[doc = " Largest non-ground continuation the decoder will accept.\n\n A value of zero accepts only snapshots whose VT parser is in the ground\n state. The decoder default matches the largest built-in APC protocol\n buffer limit, currently 65 MiB.\n\n This is primarily an input validation limit. When\n GHOSTTY_SNAPSHOT_DECODER_OPT_RETAIN_CONTINUATION is true, the same value\n also becomes the continuation tracking limit on the returned terminal.\n\n Input type: size_t *"] +pub const GhosttySnapshotDecoderOption_GHOSTTY_SNAPSHOT_DECODER_OPT_MAX_CONTINUATION_BYTES: + GhosttySnapshotDecoderOption = 0; +#[doc = " Retain the decoded continuation on the returned terminal.\n\n When true, terminals returned by ghostty_snapshot_decoder_ready() and\n ghostty_snapshot_decoder_decode() use\n GHOSTTY_SNAPSHOT_DECODER_OPT_MAX_CONTINUATION_BYTES as their continuation\n tracking limit. The existing ghostty_terminal_continuation_* APIs can then\n export the exact unfinished VT or UTF-8 input restored from the snapshot.\n\n This is false by default. A maximum continuation size of zero leaves\n tracking disabled. With a nonzero maximum, tracking remains enabled even\n when the decoded continuation is empty. Exporting an empty continuation\n does not disable it. Callers that do not need ongoing tracking must still\n set GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to zero after export and\n before writing post-snapshot input.\n\n Input type: bool *"] +pub const GhosttySnapshotDecoderOption_GHOSTTY_SNAPSHOT_DECODER_OPT_RETAIN_CONTINUATION: + GhosttySnapshotDecoderOption = 1; +#[doc = " Retain the decoded continuation on the returned terminal.\n\n When true, terminals returned by ghostty_snapshot_decoder_ready() and\n ghostty_snapshot_decoder_decode() use\n GHOSTTY_SNAPSHOT_DECODER_OPT_MAX_CONTINUATION_BYTES as their continuation\n tracking limit. The existing ghostty_terminal_continuation_* APIs can then\n export the exact unfinished VT or UTF-8 input restored from the snapshot.\n\n This is false by default. A maximum continuation size of zero leaves\n tracking disabled. With a nonzero maximum, tracking remains enabled even\n when the decoded continuation is empty. Exporting an empty continuation\n does not disable it. Callers that do not need ongoing tracking must still\n set GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to zero after export and\n before writing post-snapshot input.\n\n Input type: bool *"] +pub const GhosttySnapshotDecoderOption_GHOSTTY_SNAPSHOT_DECODER_OPT_MAX_VALUE: + GhosttySnapshotDecoderOption = 2147483647; +#[doc = " Configurable snapshot decoder options.\n\n Options may only be changed before decoding starts. Calling\n ghostty_snapshot_decoder_set() after ghostty_snapshot_decoder_ready() or\n ghostty_snapshot_decoder_decode() returns GHOSTTY_INVALID_VALUE."] +pub type GhosttySnapshotDecoderOption = ::std::os::raw::c_int; +#[doc = " Invalid data type. Never results in data extraction."] +pub const GhosttySnapshotDecoderData_GHOSTTY_SNAPSHOT_DECODER_DATA_INVALID: + GhosttySnapshotDecoderData = 0; +#[doc = " Current maximum accepted continuation size.\n\n This value is available in every non-failed decoder state.\n\n Output type: size_t *"] +pub const GhosttySnapshotDecoderData_GHOSTTY_SNAPSHOT_DECODER_DATA_MAX_CONTINUATION_BYTES: + GhosttySnapshotDecoderData = 1; +#[doc = " Number of snapshot source bytes consumed so far.\n\n At FINISH this identifies the first byte after the snapshot. Trailing\n bytes are not consumed. This value is unavailable after a decoding error,\n because the decoder can no longer guarantee its source position.\n\n Output type: size_t *"] +pub const GhosttySnapshotDecoderData_GHOSTTY_SNAPSHOT_DECODER_DATA_SOURCE_OFFSET: + GhosttySnapshotDecoderData = 2; +#[doc = " Advisory complete logical history extent for the primary screen.\n\n The value counts rows before the active area, including any resident\n overlap carried before READY. It becomes available after READY validates.\n\n Output type: uint64_t *"] +pub const GhosttySnapshotDecoderData_GHOSTTY_SNAPSHOT_DECODER_DATA_HISTORY_ROWS_PRIMARY: + GhosttySnapshotDecoderData = 3; +#[doc = " Advisory complete logical history extent for the alternate screen.\n\n The value has the same semantics and lifetime as\n GHOSTTY_SNAPSHOT_DECODER_DATA_HISTORY_ROWS_PRIMARY. Querying it returns\n GHOSTTY_NO_VALUE when the snapshot does not declare an alternate screen.\n\n Output type: uint64_t *"] +pub const GhosttySnapshotDecoderData_GHOSTTY_SNAPSHOT_DECODER_DATA_HISTORY_ROWS_ALTERNATE: + GhosttySnapshotDecoderData = 4; +#[doc = " Screen associated with the most recently decoded history page.\n\n This value is available only after ghostty_snapshot_decoder_next()\n returns GHOSTTY_SUCCESS. A later call to next replaces it or clears it\n when FINISH is reached or an error occurs.\n\n Output type: GhosttyTerminalScreen *"] +pub const GhosttySnapshotDecoderData_GHOSTTY_SNAPSHOT_DECODER_DATA_PROGRESS_SCREEN: + GhosttySnapshotDecoderData = 5; +#[doc = " Rows prepended by the most recently decoded history page.\n\n Zero means the page was consumed and validated but could not be\n applied to the live terminal.\n\n Output type: size_t *"] +pub const GhosttySnapshotDecoderData_GHOSTTY_SNAPSHOT_DECODER_DATA_PROGRESS_ROWS: + GhosttySnapshotDecoderData = 6; +#[doc = " Page records remaining in the same screen's HISTORY sequence.\n\n This is not a count of all pages remaining in the snapshot.\n\n Output type: uint32_t *"] +pub const GhosttySnapshotDecoderData_GHOSTTY_SNAPSHOT_DECODER_DATA_PROGRESS_REMAINING: + GhosttySnapshotDecoderData = 7; +#[doc = " Whether decoded continuation tracking is retained on returned terminals.\n\n This value is available in every non-failed decoder state.\n\n Output type: bool *"] +pub const GhosttySnapshotDecoderData_GHOSTTY_SNAPSHOT_DECODER_DATA_RETAIN_CONTINUATION: + GhosttySnapshotDecoderData = 8; +#[doc = " Whether decoded continuation tracking is retained on returned terminals.\n\n This value is available in every non-failed decoder state.\n\n Output type: bool *"] +pub const GhosttySnapshotDecoderData_GHOSTTY_SNAPSHOT_DECODER_DATA_MAX_VALUE: + GhosttySnapshotDecoderData = 2147483647; +#[doc = " Queryable snapshot decoder data.\n\n Each variant documents the output pointer type expected by\n ghostty_snapshot_decoder_get()."] +pub type GhosttySnapshotDecoderData = ::std::os::raw::c_int; +unsafe extern "C" { + #[doc = " Encode a complete terminal snapshot to a writer.\n\n The terminal's persistent VT stream supplies the continuation bytes needed\n to reconstruct unfinished parser state. The caller must prevent concurrent\n writes or other terminal mutation for the duration of this call. The writer\n callback must not call terminal APIs with the same terminal handle.\n A terminal can be encoded with tracking disabled when its VT parser and\n UTF-8 decoder are both at ground. If either is unfinished, tracking must\n have been enabled before the input that produced that state was written;\n otherwise this returns GHOSTTY_INVALID_VALUE.\n\n Encoding begins at the writer's current position. If an error occurs, the\n writer may contain a partial snapshot without a valid FINISH marker.\n Calls to the writer are synchronous; this function does not flush or make\n the caller's destination durable.\n\n @param terminal Terminal to encode (must not be NULL)\n @param writer Destination writer whose write callback must not be NULL\n @return GHOSTTY_SUCCESS on success, GHOSTTY_IO_ERROR if the writer rejects\n output, GHOSTTY_LIMIT_EXCEEDED if output accounting overflows, or\n another error code on failure\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_encode( + terminal: GhosttyTerminal, + writer: GhosttyWriter, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Encode a complete terminal snapshot to a caller-provided buffer.\n\n Pass NULL for buf with buf_len zero to query the required size. If the\n buffer is too small, this returns GHOSTTY_OUT_OF_SPACE and stores the\n required capacity in out_written. A non-NULL undersized buffer may contain\n a partial snapshot prefix. On success, out_written receives the number of\n bytes encoded.\n\n A terminal can be encoded with tracking disabled when its VT parser and\n UTF-8 decoder are both at ground. If either is unfinished, tracking must\n have been enabled before the input that produced that state was written;\n otherwise this returns GHOSTTY_INVALID_VALUE.\n\n @param terminal Terminal to encode (must not be NULL)\n @param buf Destination buffer, or NULL when buf_len is zero\n @param buf_len Destination buffer capacity in bytes\n @param[out] out_written Bytes written, or required capacity on\n GHOSTTY_OUT_OF_SPACE (must not be NULL)\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_encode_buf( + terminal: GhosttyTerminal, + buf: *mut u8, + buf_len: usize, + out_written: *mut usize, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Encode a complete terminal snapshot to an allocated buffer.\n\n The returned buffer is allocated with allocator, or the default allocator\n when allocator is NULL. The caller must release it with ghostty_free(),\n passing the same allocator used here.\n\n A terminal can be encoded with tracking disabled when its VT parser and\n UTF-8 decoder are both at ground. If either is unfinished, tracking must\n have been enabled before the input that produced that state was written;\n otherwise this returns GHOSTTY_INVALID_VALUE.\n\n @param terminal Terminal to encode (must not be NULL)\n @param allocator Allocator for the output, or NULL for the default allocator\n @param[out] out_ptr Allocated snapshot bytes (must not be NULL)\n @param[out] out_len Number of allocated snapshot bytes (must not be NULL)\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_encode_alloc( + terminal: GhosttyTerminal, + allocator: *const GhosttyAllocator, + out_ptr: *mut *mut u8, + out_len: *mut usize, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Create a snapshot decoder that reads from a caller-provided reader.\n\n The decoder stores a copy of reader. Its read callback must not be NULL, and\n both the callback and its caller-owned context must remain valid until\n FINISH is reached or the decoder is freed. Reads are synchronous and occur\n only during ready, next, or decode calls. A zero-byte successful read is\n permanent end-of-file, not temporary starvation; nonblocking sources must\n wait outside the decoder or block in their callback. The read callback must\n not call APIs, including ghostty_snapshot_decoder_free(), on the decoder\n that owns it. Returning false reports GHOSTTY_IO_ERROR; returning true with\n zero bytes before a required marker reports truncated snapshot data as\n GHOSTTY_INVALID_VALUE.\n\n @param allocator Allocator for decoder and decoded terminal state, or NULL\n for the default allocator\n @param decoder Pointer to receive the decoder handle (must not be NULL)\n @param reader Snapshot source reader\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_decoder_new( + allocator: *const GhosttyAllocator, + decoder: *mut GhosttySnapshotDecoder, + reader: GhosttyReader, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Create a snapshot decoder over a borrowed byte buffer.\n\n The bytes are not copied. ptr must remain valid and immutable until FINISH\n is reached or the decoder is freed. Bytes after FINISH are not consumed;\n query GHOSTTY_SNAPSHOT_DECODER_DATA_SOURCE_OFFSET to locate them.\n\n @param allocator Allocator for decoder and decoded terminal state, or NULL\n for the default allocator\n @param decoder Pointer to receive the decoder handle (must not be NULL)\n @param ptr Snapshot source bytes\n @param len Number of source bytes\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_decoder_new_buf( + allocator: *const GhosttyAllocator, + decoder: *mut GhosttySnapshotDecoder, + ptr: *const u8, + len: usize, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Free a snapshot decoder.\n\n This does not release the caller's ownership of a terminal returned by\n ready or decode. Abandoning an incremental decode leaves that terminal\n usable with whatever history had already been restored.\n\n @param decoder Decoder to free (may be NULL)\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_decoder_free(decoder: GhosttySnapshotDecoder); +} +unsafe extern "C" { + #[doc = " Set a snapshot decoder option.\n\n The value pointer must have the type documented by option. Options may only\n be changed before decoding starts.\n\n @param decoder Decoder handle (must not be NULL)\n @param option Option to change\n @param value Pointer to the option value (must not be NULL)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if decoding has\n started or an argument is invalid, or another error code on failure\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_decoder_set( + decoder: GhosttySnapshotDecoder, + option: GhosttySnapshotDecoderOption, + value: *const ::std::os::raw::c_void, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Decode and validate the renderable snapshot prefix through READY.\n\n On success, terminal receives a caller-owned terminal with its persistent\n VT stream already restored from the snapshot continuation. The terminal is\n immediately usable for rendering and live input. Older scrollback remains\n to be restored with ghostty_snapshot_decoder_next().\n\n The restored parser state may be unfinished. By default, terminal\n continuation tracking is disabled and\n GHOSTTY_TERMINAL_DATA_CONTINUATION_MAX_BYTES returns zero. When\n GHOSTTY_SNAPSHOT_DECODER_OPT_RETAIN_CONTINUATION is true, the decoder's\n maximum continuation size is applied to the terminal, and the terminal\n continuation APIs export the exact current continuation when that limit is\n nonzero. Tracking remains enabled even if the exported continuation is\n empty. Callers that do not need ongoing tracking must set\n GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to zero after export and before\n writing any post-snapshot bytes, because later input may change it.\n\n The caller must keep the returned terminal alive until FINISH validates or\n the decoder is freed. The decoder borrows this terminal handle while it\n restores history; ghostty_snapshot_decoder_next() uses it automatically.\n\n This operation may only be called once and only before decoding starts.\n terminal is set to NULL on every error. A decoding, I/O, or allocation\n error after input consumption begins poisons the decoder, after which it\n must be freed. An invalid argument or lifecycle error detected before the\n operation consumes input does not poison it.\n\n @param decoder Decoder handle (must not be NULL)\n @param[out] terminal Pointer to receive the terminal (must not be NULL)\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_decoder_ready( + decoder: GhosttySnapshotDecoder, + terminal: *mut GhosttyTerminal, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Decode one history page into the terminal returned by READY.\n\n Each GHOSTTY_SUCCESS consumes and validates one PAGE record. Query the\n GHOSTTY_SNAPSHOT_DECODER_DATA_PROGRESS_* values before calling next again.\n GHOSTTY_NO_VALUE means FINISH was validated; repeated calls after FINISH\n also return GHOSTTY_NO_VALUE.\n\n The terminal may be rendered, resized, and fed live PTY input between calls.\n If a history page can no longer be applied safely, it is still consumed and\n validated and progress reports zero rows. The decoder applies history\n to the caller-owned terminal produced by its READY operation.\n\n A decoding error invalidates the decoder's source position. The terminal\n remains caller-owned and usable with its already-restored history, but only\n ghostty_snapshot_decoder_free() may subsequently be called on the decoder.\n\n @param decoder Decoder handle (must not be NULL)\n @return GHOSTTY_SUCCESS for one page, GHOSTTY_NO_VALUE after FINISH, or an\n error code on failure\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_decoder_next(decoder: GhosttySnapshotDecoder) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Decode and validate one complete snapshot.\n\n This is the one-shot form of READY followed by all history pages through\n FINISH. It may only be called before decoding starts. Bytes following FINISH\n are left unread. On success terminal receives a caller-owned terminal with\n its persistent VT stream restored. Continuation tracking on the returned\n terminal is disabled by default. When\n GHOSTTY_SNAPSHOT_DECODER_OPT_RETAIN_CONTINUATION is true, the decoder's\n maximum continuation size is applied to the terminal, and the terminal\n continuation APIs export the exact current continuation when that limit is\n nonzero. Tracking remains enabled even if the exported continuation is\n empty. Callers that do not need ongoing tracking must set\n GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to zero after export and before\n writing any post-snapshot bytes, because later input may change it.\n terminal is set to NULL on every error.\n A decoding, I/O, or allocation error after input consumption begins poisons\n the decoder, after which it must be freed. An invalid argument or\n lifecycle error detected before the operation consumes input does not\n poison it.\n\n @param decoder Decoder handle (must not be NULL)\n @param[out] terminal Pointer to receive the terminal (must not be NULL)\n @return GHOSTTY_SUCCESS on success, or an error code on failure\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_decoder_decode( + decoder: GhosttySnapshotDecoder, + terminal: *mut GhosttyTerminal, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Get typed data from a snapshot decoder.\n\n The output pointer must have the type documented by data. A phase-dependent\n value that is not currently available returns GHOSTTY_NO_VALUE.\n\n @param decoder Decoder handle (must not be NULL)\n @param data Data kind to query\n @param[out] out Pointer to receive the value (must not be NULL)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_NO_VALUE if the requested data\n is unavailable, or another error code on failure\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_decoder_get( + decoder: GhosttySnapshotDecoder, + data: GhosttySnapshotDecoderData, + out: *mut ::std::os::raw::c_void, + ) -> GhosttyResult; +} +unsafe extern "C" { + #[doc = " Get multiple snapshot decoder data fields in a single call.\n\n Each keys element selects a data kind and the corresponding values element\n points to storage of the documented output type. Processing stops at the\n first error. On success out_written is set to count; on error it is set to\n the number of values written before the failing key. Invalid array arguments\n report zero values written.\n\n @param decoder Decoder handle (must not be NULL)\n @param count Number of key/value pairs\n @param keys Array of data kinds to query\n @param values Array of output pointers corresponding to keys\n @param[out] out_written Number of successfully written values (may be NULL)\n @return GHOSTTY_SUCCESS if every query succeeds, or the first error\n\n @ingroup snapshot"] + pub fn ghostty_snapshot_decoder_get_multi( + decoder: GhosttySnapshotDecoder, + count: usize, + keys: *const GhosttySnapshotDecoderData, + values: *mut *mut ::std::os::raw::c_void, + out_written: *mut usize, + ) -> GhosttyResult; +} unsafe extern "C" { #[doc = " Returns the terminal display width of a Unicode codepoint in\n terminal grid cells: 0, 1, or 2.\n\n This is the same width table the terminal itself uses when laying\n out printed text, so callers can predict column layout (e.g. IME\n preedit overlays) that exactly matches what the terminal will do\n when the text is actually written to it.\n\n Semantics:\n - Returns 0 for zero-width codepoints: C0/C1 control characters,\n nonspacing and enclosing combining marks, default-ignorable\n codepoints (ZWJ, ZWNJ, variation selectors, etc.), and\n surrogate codepoints.\n - Returns 2 for wide codepoints: East Asian Wide/Fullwidth\n (including emoji with default emoji presentation) and regional\n indicators. Width is clamped to 2 (e.g. the three-em dash).\n - Returns 1 for everything else, including invalid codepoints\n beyond U+10FFFF (this function is total; it never fails).\n\n This operates on a single codepoint only and therefore cannot account\n for grapheme-cluster-level width rules (VS16 emoji presentation,\n combining sequences, etc.). For cluster-accurate widths, use\n ghostty_unicode_grapheme_width(). Summing per-codepoint widths is only\n correct when mode 2027 (grapheme clustering) is disabled.\n\n This function is pure, allocates nothing, and is thread-safe.\n\n @param cp The Unicode codepoint to measure\n @return Display width in cells: 0, 1, or 2"] pub fn ghostty_unicode_codepoint_width(cp: u32) -> u8; diff --git a/src/ghostty/mod.rs b/src/ghostty/mod.rs index cd774c6b..9ec9d324 100644 --- a/src/ghostty/mod.rs +++ b/src/ghostty/mod.rs @@ -146,12 +146,12 @@ pub const MOD_CTRL: u16 = ffi::GHOSTTY_MODS_CTRL as u16; pub const MOD_ALT: u16 = ffi::GHOSTTY_MODS_ALT as u16; pub const MOD_SUPER: u16 = ffi::GHOSTTY_MODS_SUPER as u16; -pub const KEY_ENTER: u32 = ffi::GhosttyKey_GHOSTTY_KEY_ENTER; -pub const KEY_UP: u32 = ffi::GhosttyKey_GHOSTTY_KEY_ARROW_UP; -pub const KEY_DOWN: u32 = ffi::GhosttyKey_GHOSTTY_KEY_ARROW_DOWN; -pub const KEY_LEFT: u32 = ffi::GhosttyKey_GHOSTTY_KEY_ARROW_LEFT; -pub const KEY_RIGHT: u32 = ffi::GhosttyKey_GHOSTTY_KEY_ARROW_RIGHT; -pub const KEY_A: u32 = ffi::GhosttyKey_GHOSTTY_KEY_A; +pub const KEY_ENTER: ffi::GhosttyKey = ffi::GhosttyKey_GHOSTTY_KEY_ENTER; +pub const KEY_UP: ffi::GhosttyKey = ffi::GhosttyKey_GHOSTTY_KEY_ARROW_UP; +pub const KEY_DOWN: ffi::GhosttyKey = ffi::GhosttyKey_GHOSTTY_KEY_ARROW_DOWN; +pub const KEY_LEFT: ffi::GhosttyKey = ffi::GhosttyKey_GHOSTTY_KEY_ARROW_LEFT; +pub const KEY_RIGHT: ffi::GhosttyKey = ffi::GhosttyKey_GHOSTTY_KEY_ARROW_RIGHT; +pub const KEY_A: ffi::GhosttyKey = ffi::GhosttyKey_GHOSTTY_KEY_A; pub const MOUSE_ACTION_PRESS: ffi::GhosttyMouseAction = ffi::GhosttyMouseAction_GHOSTTY_MOUSE_ACTION_PRESS; @@ -345,6 +345,14 @@ pub struct CursorViewport { pub wide_tail: bool, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct RenderCursor { + pub viewport: Option, + pub visible: bool, + pub blinking: bool, + pub visual_style: CursorVisualStyle, +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct RgbColor { pub r: u8, @@ -557,12 +565,25 @@ unsafe extern "C" fn clipboard_write_trampoline( _terminal: ffi::GhosttyTerminal, userdata: *mut c_void, write: *const ffi::GhosttyClipboardWrite, -) -> ffi::GhosttyClipboardWriteResult { - std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { +) { + if write.is_null() || unsafe { (*write).size } < mem::size_of::() { + return; + } + // The reply and request are borrowed only until this callback returns. + let Some(reply) = (unsafe { (*write).reply }) else { + return; + }; + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { // SAFETY: libghostty-vt owns these values for the synchronous callback. unsafe { capture_clipboard_write(userdata, write) } })) - .unwrap_or(ffi::GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_INVALID_DATA) + .unwrap_or(ffi::GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_INVALID_DATA); + let response = ffi::GhosttyClipboardWriteReply { + size: mem::size_of::(), + result, + remember: false, + }; + unsafe { reply(write, &response) }; } unsafe fn capture_clipboard_write( @@ -798,14 +819,9 @@ pub struct Terminal { impl Terminal { pub fn new(cols: u16, rows: u16, max_scrollback: usize) -> Result { let mut raw = ptr::null_mut(); - let options = ffi::GhosttyTerminalOptions { - cols, - rows, - max_scrollback, - }; - // SAFETY: valid out pointer and options, null allocator means default allocator. + // SAFETY: valid out pointer, null allocator means default allocator. unsafe { - ffi::ghostty_terminal_new(ptr::null(), &mut raw, options).into_result()?; + ffi::ghostty_terminal_new(ptr::null(), &mut raw, cols, rows).into_result()?; } let mut terminal = Self { @@ -826,7 +842,35 @@ impl Terminal { }; let userdata = (&mut *terminal.callback_state as *mut TerminalCallbackState).cast(); let glyph_protocol = false; + let terminfo_name = ffi::GhosttyString { + ptr: crate::pane::PANE_TERM.as_ptr().cast(), + len: crate::pane::PANE_TERM.len(), + }; + let grapheme_default = ffi::GhosttyTerminalModeConfig { + mode: MODE_GRAPHEME_CLUSTER, + value: true, + }; + let clipboard_callback: ffi::GhosttyTerminalClipboardWriteFn = + Some(clipboard_write_trampoline); unsafe { + ffi::ghostty_terminal_set( + terminal.raw, + ffi::GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_TERMINFO_NAME, + (&terminfo_name as *const ffi::GhosttyString).cast(), + ) + .into_result()?; + ffi::ghostty_terminal_set( + terminal.raw, + ffi::GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_SCROLLBACK_MAX_BYTES, + (&max_scrollback as *const usize).cast(), + ) + .into_result()?; + ffi::ghostty_terminal_set( + terminal.raw, + ffi::GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_MODE_DEFAULT, + (&grapheme_default as *const ffi::GhosttyTerminalModeConfig).cast(), + ) + .into_result()?; ffi::ghostty_terminal_set( terminal.raw, ffi::GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_USERDATA, @@ -854,7 +898,7 @@ impl Terminal { ffi::ghostty_terminal_set( terminal.raw, ffi::GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE, - (clipboard_write_trampoline as *const ()).cast(), + clipboard_callback.map_or(ptr::null(), |callback| (callback as *const ()).cast()), ) .into_result()?; ffi::ghostty_terminal_set( @@ -978,6 +1022,12 @@ impl Terminal { install_png_decoder_once(); let storage_limit = KITTY_IMAGE_STORAGE_LIMIT_BYTES; let enable_medium = true; + let temp_dir = std::env::temp_dir(); + let temp_dir = temp_dir.to_string_lossy(); + let temp_dir = ffi::GhosttyString { + ptr: temp_dir.as_ptr().cast(), + len: temp_dir.len(), + }; unsafe { ffi::ghostty_terminal_set( self.raw, @@ -994,7 +1044,7 @@ impl Terminal { ffi::ghostty_terminal_set( self.raw, ffi::GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_KITTY_IMAGE_MEDIUM_TEMP_FILE, - (&enable_medium as *const bool).cast(), + (&temp_dir as *const ffi::GhosttyString).cast(), ) .into_result()?; ffi::ghostty_terminal_set( @@ -1052,13 +1102,28 @@ impl Terminal { } pub fn mode_get(&self, mode: u16) -> Result { - let mut out = false; - unsafe { ffi::ghostty_terminal_mode_get(self.raw, mode, &mut out).into_result()? }; - Ok(out) + let mut config = ffi::GhosttyTerminalModeConfig { mode, value: false }; + unsafe { + ffi::ghostty_terminal_get( + self.raw, + ffi::GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_MODE, + (&mut config as *mut ffi::GhosttyTerminalModeConfig).cast(), + ) + .into_result()?; + } + Ok(config.value) } pub fn mode_set(&mut self, mode: u16, value: bool) -> Result<(), Error> { - unsafe { ffi::ghostty_terminal_mode_set(self.raw, mode, value).into_result() } + let config = ffi::GhosttyTerminalModeConfig { mode, value }; + unsafe { + ffi::ghostty_terminal_set( + self.raw, + ffi::GhosttyTerminalOption_GHOSTTY_TERMINAL_OPT_MODE, + (&config as *const ffi::GhosttyTerminalModeConfig).cast(), + ) + .into_result() + } } pub fn kitty_keyboard_flags(&self) -> Result { @@ -1282,64 +1347,6 @@ impl Terminal { ) } - pub fn keyboard_state_ansi(&self) -> Result { - self.format_keyboard_state_ansi(false) - } - - pub fn kitty_keyboard_state_ansi(&self) -> Result { - self.format_keyboard_state_ansi(true) - } - - fn format_keyboard_state_ansi(&self, kitty_keyboard: bool) -> Result { - let mut formatter: ffi::GhosttyFormatter = ptr::null_mut(); - let options = ffi::GhosttyFormatterTerminalOptions { - size: mem::size_of::(), - emit: FormatterFormat::Vt.as_raw(), - unwrap: false, - trim: false, - extra: ffi::GhosttyFormatterTerminalExtra { - size: mem::size_of::(), - keyboard: true, - screen: ffi::GhosttyFormatterScreenExtra { - size: mem::size_of::(), - kitty_keyboard, - ..Default::default() - }, - ..Default::default() - }, - selection: ptr::null(), - }; - unsafe { - ffi::ghostty_formatter_terminal_new(ptr::null(), &mut formatter, self.raw, options) - .into_result()?; - } - - let mut out_ptr = ptr::null_mut(); - let mut out_len = 0usize; - let result = unsafe { - ffi::ghostty_formatter_format_alloc(formatter, ptr::null(), &mut out_ptr, &mut out_len) - }; - unsafe { - ffi::ghostty_formatter_free(formatter); - } - result.into_result()?; - - let text = if out_len == 0 { - String::new() - } else { - let bytes = unsafe { slice::from_raw_parts(out_ptr.cast_const(), out_len) }; - String::from_utf8_lossy(bytes).into_owned() - }; - - if !out_ptr.is_null() { - unsafe { - ffi::ghostty_free(ptr::null(), out_ptr, out_len); - } - } - - Ok(text) - } - fn read_formatted_selection( &self, start: ffi::GhosttyPoint, @@ -2494,43 +2501,34 @@ impl RenderState { Ok(Dirty::from_raw(out)) } - pub fn cursor_visible(&self) -> Result { - self.get_bool(ffi::GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_CURSOR_VISIBLE) - } - - pub fn cursor_blinking(&self) -> Result { - self.get_bool(ffi::GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_CURSOR_BLINKING) - } - - pub fn cursor_visual_style(&self) -> Result { - let mut out: ffi::GhosttyRenderStateCursorVisualStyle = 0; - // SAFETY: out points to the matching enum storage for the requested data kind. + pub fn cursor(&self) -> Result { + let mut cursor = ffi::GhosttyRenderStateCursor { + size: mem::size_of::(), + ..Default::default() + }; unsafe { ffi::ghostty_render_state_get( self.raw, - ffi::GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_CURSOR_VISUAL_STYLE, - (&mut out as *mut ffi::GhosttyRenderStateCursorVisualStyle).cast(), + ffi::GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_CURSOR, + (&mut cursor as *mut ffi::GhosttyRenderStateCursor).cast(), ) .into_result()?; } - Ok(CursorVisualStyle::from_raw(out)) - } - - pub fn cursor_viewport(&self) -> Result, Error> { - if !self.get_bool( - ffi::GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_HAS_VALUE, - )? { - return Ok(None); - } - Ok(Some(CursorViewport { - x: self - .get_u16(ffi::GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_X)?, - y: self - .get_u16(ffi::GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_Y)?, - wide_tail: self.get_bool( - ffi::GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_WIDE_TAIL, - )?, - })) + Ok(RenderCursor { + // Upstream leaves these fields undefined when the cursor is offscreen. + viewport: if cursor.viewport_has_value { + Some(CursorViewport { + x: cursor.viewport_x, + y: cursor.viewport_y, + wide_tail: cursor.wide_tail, + }) + } else { + None + }, + visible: cursor.visible, + blinking: cursor.blinking, + visual_style: CursorVisualStyle::from_raw(cursor.visual_style), + }) } pub fn colors(&self) -> Result { @@ -2539,7 +2537,12 @@ impl RenderState { ..Default::default() }; unsafe { - ffi::ghostty_render_state_colors_get(self.raw, &mut colors).into_result()?; + ffi::ghostty_render_state_get( + self.raw, + ffi::GhosttyRenderStateData_GHOSTTY_RENDER_STATE_DATA_COLORS, + (&mut colors as *mut ffi::GhosttyRenderStateColors).cast(), + ) + .into_result()?; } Ok(RenderColors { background: colors.background.into(), @@ -2548,6 +2551,10 @@ impl RenderState { }) } + pub fn clean(&mut self) -> Result<(), Error> { + unsafe { ffi::ghostty_render_state_clean(self.raw).into_result() } + } + pub fn set_dirty(&mut self, dirty: Dirty) -> Result<(), Error> { let value = dirty.as_raw(); // SAFETY: value pointer matches the expected option type. @@ -2589,15 +2596,6 @@ impl RenderState { } Ok(out) } - - fn get_bool(&self, data: ffi::GhosttyRenderStateData) -> Result { - let mut out = false; - unsafe { - ffi::ghostty_render_state_get(self.raw, data, (&mut out as *mut bool).cast()) - .into_result()?; - } - Ok(out) - } } // SAFETY: these opaque handles are only used behind external synchronization in pane runtime. @@ -2627,7 +2625,7 @@ impl KeyEvent { unsafe { ffi::ghostty_key_event_set_action(self.raw, action) } } - pub fn set_key(&mut self, key: u32) { + pub fn set_key(&mut self, key: ffi::GhosttyKey) { unsafe { ffi::ghostty_key_event_set_key(self.raw, key) } } @@ -2846,6 +2844,14 @@ impl<'a> RowIter<'a> { unsafe { ffi::ghostty_render_state_row_iterator_next(self.iterator.raw) } } + pub fn next_dirty(&mut self) -> Option { + let mut y = 0u16; + // SAFETY: iterator is live and y matches the viewport-coordinate output type. + let advanced = + unsafe { ffi::ghostty_render_state_row_iterator_next_dirty(self.iterator.raw, &mut y) }; + advanced.then_some(y) + } + pub fn dirty(&self) -> Result { let mut dirty = false; // SAFETY: dirty output matches requested row data type. @@ -3294,6 +3300,7 @@ impl<'a> RowCellIter<'a> { #[cfg(test)] mod tests { use super::*; + use std::sync::Arc; fn write_numbered_lines(terminal: &mut Terminal, count: usize) { for i in 0..count { @@ -3413,8 +3420,8 @@ mod tests { .generation; assert_ne!(first_generation, 0); - // Same id and size, different pixels. - terminal.write(b"\x1b_Ga=t,f=32,t=d,i=7,s=1,v=1,q=2;AAAAAA==\x1b\\"); + // Retransmission removes old placements; transmit-and-display replaces it. + terminal.write(b"\x1b[H\x1b_Ga=T,f=32,t=d,i=7,p=3,s=1,v=1,c=10,r=5,q=2;AAAAAA==\x1b\\"); let second = terminal .kitty_image_placements_with_data_filter(|_| true) .unwrap(); @@ -3486,7 +3493,11 @@ mod tests { terminal.scroll_viewport_row(0); assert_eq!(terminal.kitty_image_placements().unwrap().len(), 1); + // Delete-visible must preserve images in scrollback, even while viewed. terminal.write(b"\x1b_Ga=d,d=A\x1b\\"); + assert_eq!(terminal.kitty_graphics_generation().unwrap(), placed); + assert_eq!(terminal.kitty_image_placements().unwrap().len(), 1); + terminal.write(b"\x1b_Ga=d,d=I,i=1\x1b\\"); let deleted = terminal.kitty_graphics_generation().unwrap(); assert_ne!(deleted, placed); assert!(terminal.kitty_graphics_may_have_placements().unwrap()); @@ -3540,9 +3551,20 @@ mod tests { assert!(terminal .get_bool(ffi::GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_KITTY_IMAGE_MEDIUM_FILE) .unwrap()); - assert!(terminal - .get_bool(ffi::GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_KITTY_IMAGE_MEDIUM_TEMP_FILE) - .unwrap()); + let mut temp_dir = ffi::GhosttyString::default(); + unsafe { + ffi::ghostty_terminal_get( + terminal.raw, + ffi::GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_KITTY_IMAGE_MEDIUM_TEMP_FILE, + (&mut temp_dir as *mut ffi::GhosttyString).cast(), + ) + .into_result() + .unwrap(); + assert_eq!( + borrowed_bytes(temp_dir).unwrap(), + std::env::temp_dir().to_string_lossy().as_bytes() + ); + } assert!(terminal .get_bool(ffi::GhosttyTerminalData_GHOSTTY_TERMINAL_DATA_KITTY_IMAGE_MEDIUM_SHARED_MEM) .unwrap()); @@ -3873,6 +3895,59 @@ mod tests { ); } + #[test] + fn raw_resize_preserves_content_without_replaying_terminal_effects() { + let mut terminal = Terminal::new(20, 6, 100_000).unwrap(); + terminal.write(b"header\r\n\x1b[6;1Htail\x1b[6;18H"); + for (cols, rows) in [(10, 3), (30, 8), (8, 4), (20, 6)] { + terminal.resize(cols, rows, 8, 16).unwrap(); + terminal.write(b"X"); + let text = terminal + .read_text_screen( + (0, 0), + (cols - 1, terminal.total_rows().unwrap() as u32 - 1), + false, + ) + .unwrap(); + assert!( + text.contains("tail"), + "lost tail after {cols}x{rows}: {text:?}" + ); + assert_eq!(text.matches("tail").count(), 1); + assert!(terminal.cursor_y().unwrap() < rows); + } + terminal.write(b"\x1b[2J\x1b[H"); + terminal.resize(12, 3, 8, 16).unwrap(); + assert!(terminal + .read_text_viewport((0, 0), (11, 2), false) + .unwrap() + .trim() + .is_empty()); + } + + #[test] + fn clipboard_queries_never_disclose_contents_and_split_writes_complete_once() { + for suffix in [b"\x07".as_slice(), b"\x1b\\".as_slice()] { + let bytes = [b"\x1b]52;c;YQBi".as_slice(), suffix].concat(); + for split in 0..=bytes.len() { + let mut terminal = Terminal::new(10, 3, 0).unwrap(); + let replies = Arc::new(Mutex::new(Vec::new())); + let captured = Arc::clone(&replies); + terminal + .set_write_pty_callback(move |bytes| { + captured.lock().unwrap().extend_from_slice(bytes) + }) + .unwrap(); + terminal.write(&bytes[..split]); + terminal.write(&bytes[split..]); + assert_eq!(terminal.take_clipboard_writes(), vec![b"a\0b".to_vec()]); + terminal.write(b"\x1b]52;c;?\x07\x1b]52;p;YQBi\x07"); + assert!(terminal.take_clipboard_writes().is_empty()); + assert!(replies.lock().unwrap().is_empty()); + } + } + } + #[test] fn active_screen_and_cursor_visibility_contract() { let mut terminal = Terminal::new(12, 3, 0).unwrap(); @@ -3886,10 +3961,10 @@ mod tests { ); render_state.update(&terminal).unwrap(); - assert!(render_state.cursor_visible().unwrap()); + assert!(render_state.cursor().unwrap().visible); terminal.write(b"\x1b[?25l"); render_state.update(&terminal).unwrap(); - assert!(!render_state.cursor_visible().unwrap()); + assert!(!render_state.cursor().unwrap().visible); terminal.write(b"\x1b[?1049h\x1b[HALT"); assert_eq!(terminal.active_screen().unwrap(), ActiveScreen::Alternate); @@ -3972,6 +4047,8 @@ mod tests { fn grapheme_cluster_mode_is_default_and_survives_full_reset() { let mut terminal = Terminal::new(80, 3, 100).unwrap(); assert!(terminal.mode_get(MODE_GRAPHEME_CLUSTER).unwrap()); + terminal.mode_set(MODE_GRAPHEME_CLUSTER, false).unwrap(); + assert!(!terminal.mode_get(MODE_GRAPHEME_CLUSTER).unwrap()); terminal.write(b"\x1bc"); @@ -4013,8 +4090,21 @@ mod tests { assert!(!rows.dirty().unwrap()); } } + { + let mut iterator = RowIterator::new().unwrap(); + let mut rows = render_state.populate_row_iterator(&mut iterator).unwrap(); + assert_eq!(rows.next_dirty(), Some(0)); + assert_eq!(rows.next_dirty(), Some(1)); + assert_eq!(rows.next_dirty(), Some(2)); + assert_eq!(rows.next_dirty(), None); + } render_state.set_dirty(Dirty::Clean).unwrap(); assert_eq!(render_state.dirty().unwrap(), Dirty::Clean); + { + let mut iterator = RowIterator::new().unwrap(); + let mut rows = render_state.populate_row_iterator(&mut iterator).unwrap(); + assert_eq!(rows.next_dirty(), None); + } terminal.write(b"A"); render_state.update(&terminal).unwrap(); @@ -4026,12 +4116,12 @@ mod tests { let mut rows = render_state .populate_row_iterator(&mut row_iterator) .unwrap(); - while rows.next() { - if rows.dirty().unwrap() { - dirty_rows += 1; - rows.clear_dirty().unwrap(); - assert!(!rows.dirty().unwrap()); - } + while let Some(y) = rows.next_dirty() { + assert_eq!(y, 0); + assert!(rows.dirty().unwrap()); + dirty_rows += 1; + rows.clear_dirty().unwrap(); + assert!(!rows.dirty().unwrap()); } } assert_eq!(dirty_rows, 1); @@ -4073,20 +4163,45 @@ mod tests { contents: &[ffi::GhosttyClipboardContent], size: usize, ) -> ffi::GhosttyClipboardWriteResult { + unsafe extern "C" fn reply( + request: *const ffi::GhosttyClipboardWrite, + response: *const ffi::GhosttyClipboardWriteReply, + ) { + let state = unsafe { + &mut *((*request).ctx as *mut (ffi::GhosttyClipboardWriteResult, bool, usize)) + }; + state.0 = unsafe { (*response).result }; + state.1 = unsafe { (*response).remember }; + state.2 += 1; + } + let mut response = ( + ffi::GhosttyClipboardWriteResult_GHOSTTY_CLIPBOARD_WRITE_RESULT_INVALID_DATA, + false, + 0usize, + ); let request = ffi::GhosttyClipboardWrite { size, location: ffi::GhosttyClipboardLocation_GHOSTTY_CLIPBOARD_LOCATION_STANDARD, contents: contents.as_ptr(), contents_len: contents.len(), + ctx: (&mut response as *mut (ffi::GhosttyClipboardWriteResult, bool, usize)).cast(), + reply: Some(reply), + ..Default::default() }; - // SAFETY: the request and its borrowed content live through this call. + // SAFETY: the request, reply state and borrowed content live through this call. unsafe { clipboard_write_trampoline( terminal.raw, (&mut *terminal.callback_state as *mut TerminalCallbackState).cast(), &request, - ) + ); } + assert_eq!( + response.2, + usize::from(size >= mem::size_of::()) + ); + assert!(!response.1, "migration must not create clipboard grants"); + response.0 } #[test] diff --git a/src/pane.rs b/src/pane.rs index aa6acb57..345a7513 100644 --- a/src/pane.rs +++ b/src/pane.rs @@ -55,7 +55,7 @@ pub use self::{ const RELEASE_REACQUIRE_SUPPRESSION: std::time::Duration = std::time::Duration::from_secs(1); const TERMINAL_COMPRESSION_IDLE: std::time::Duration = std::time::Duration::from_millis(250); const TERMINAL_COMPRESSION_STEP: std::time::Duration = std::time::Duration::from_millis(1); -const PANE_TERM: &str = "xterm-256color"; +pub(crate) const PANE_TERM: &str = "xterm-256color"; const PANE_COLORTERM: &str = "truecolor"; fn terminal_compression_permits() -> Arc { diff --git a/src/pane/input.rs b/src/pane/input.rs index 8de216e8..10900c94 100644 --- a/src/pane/input.rs +++ b/src/pane/input.rs @@ -218,7 +218,7 @@ fn ghostty_unshifted_codepoint(key: &crate::input::TerminalKey) -> Option { fn ghostty_key_from_crossterm_key_code( code: crossterm::event::KeyCode, shifted_codepoint: Option, -) -> Option { +) -> Option { use crate::ghostty::ffi; use crossterm::event::KeyCode; @@ -257,7 +257,10 @@ fn ghostty_key_from_crossterm_key_code( } } -fn ghostty_key_from_char(c: char, shifted_codepoint: Option) -> Option { +fn ghostty_key_from_char( + c: char, + shifted_codepoint: Option, +) -> Option { use crate::ghostty::ffi; let base = if let Some(shifted) = shifted_codepoint.and_then(char::from_u32) { diff --git a/src/pane/terminal.rs b/src/pane/terminal.rs index 1dc5a88d..071bb20a 100644 --- a/src/pane/terminal.rs +++ b/src/pane/terminal.rs @@ -16,6 +16,8 @@ use unicode_width::UnicodeWidthStr; use crate::layout::PaneId; use crate::protocol::CellData; +#[cfg(test)] +mod migration_tests; #[cfg(windows)] mod windows_recent_fallback; @@ -35,7 +37,7 @@ use super::{ AgentOscStateTracker, DefaultColorEvent, DefaultColorEventTracker, DefaultColorOscTracker, DefaultColorQuery, DefaultColorTrackedEvent, OscDebugTracker, }, - xtgettcap::{XtgettcapQueryTracker, XtgettcapResponse}, + xtgettcap::{C1XtgettcapQueryTracker, C1XtgettcapResponse}, }; const DEFAULT_DETECTION_ROWS: usize = 24; @@ -201,11 +203,11 @@ pub(crate) struct GhosttyPaneCore { pub transient_default_color_owner_pgid: Option, pub default_color_tracker: DefaultColorOscTracker, pub default_color_event_tracker: DefaultColorEventTracker, + c1_xtgettcap_tracker: C1XtgettcapQueryTracker, pub child_default_foreground_changed: bool, pub child_default_background_changed: bool, pub osc_debug_tracker: OscDebugTracker, pub agent_osc_state: AgentOscStateTracker, - pub xtgettcap_query_tracker: XtgettcapQueryTracker, decscusr_tracker: DecscusrTracker, cursor_settle_state: CursorPositionSettleState, windows_powershell_prompt_cwd_reporting: bool, @@ -1154,11 +1156,11 @@ impl GhosttyPaneTerminal { transient_default_color_owner_pgid: None, default_color_tracker: DefaultColorOscTracker::default(), default_color_event_tracker: DefaultColorEventTracker::default(), + c1_xtgettcap_tracker: C1XtgettcapQueryTracker::default(), child_default_foreground_changed: false, child_default_background_changed: false, osc_debug_tracker: OscDebugTracker::default(), agent_osc_state: AgentOscStateTracker::default(), - xtgettcap_query_tracker: XtgettcapQueryTracker::default(), decscusr_tracker: DecscusrTracker::default(), cursor_settle_state: CursorPositionSettleState::default(), windows_powershell_prompt_cwd_reporting: false, @@ -1384,19 +1386,18 @@ impl GhosttyPaneTerminal { let mut terminal_responses = Vec::new(); core.default_color_event_tracker .observe(filtered_bytes.as_ref()); - core.xtgettcap_query_tracker - .observe(filtered_bytes.as_ref()); + core.c1_xtgettcap_tracker.observe(filtered_bytes.as_ref()); + let c1_xtgettcap_responses = core.c1_xtgettcap_tracker.drain_pending(); core.decscusr_tracker.observe(filtered_bytes.as_ref()); let in_progress_default_color_event = core.default_color_event_tracker.in_progress_event(); let default_color_events = core.default_color_event_tracker.drain_pending(); - let xtgettcap_responses = core.xtgettcap_query_tracker.drain_pending(); let write_started = crate::render_prof::timer(); self.write_pty_bytes_with_ordered_responses( &mut core, filtered_bytes.as_ref(), default_color_events, in_progress_default_color_event, - xtgettcap_responses, + c1_xtgettcap_responses, &mut terminal_responses, ); let terminal_bells = core.terminal.take_bell_count(); @@ -1470,25 +1471,32 @@ impl GhosttyPaneTerminal { bytes: &[u8], default_color_events: Vec, in_progress_default_color_event: Option, - xtgettcap_responses: Vec, + c1_xtgettcap_responses: Vec, terminal_responses: &mut Vec, ) { - let mut events = Vec::with_capacity(default_color_events.len() + xtgettcap_responses.len()); - events.extend( - default_color_events - .into_iter() - .map(OrderedPtyResponseEvent::DefaultColor), - ); - events.extend( - xtgettcap_responses - .into_iter() - .map(OrderedPtyResponseEvent::Xtgettcap), - ); - events.sort_by_key(OrderedPtyResponseEvent::end_offset); - + // Only legacy C1 replies need merging; ordinary XTGETTCAP remains native. + let mut events: Vec<_> = default_color_events + .into_iter() + .map(OrderedColorOrC1Event::Color) + .chain( + c1_xtgettcap_responses + .into_iter() + .map(OrderedColorOrC1Event::C1), + ) + .collect(); + events.sort_by_key(OrderedColorOrC1Event::end_offset); let mut written = 0; for event in events { let end_offset = event.end_offset().min(bytes.len()); + if matches!(&event, OrderedColorOrC1Event::C1(response) if response.suppress_native) { + // Suppress only the unhook byte's replies, not earlier native queries. + let prefix_end = end_offset.saturating_sub(1).max(written); + if prefix_end > written { + core.terminal.write(&bytes[written..prefix_end]); + terminal_responses.extend(self.drain_pending_pty_responses()); + written = prefix_end; + } + } let mut libghostty_responses = Vec::new(); if end_offset > written { core.terminal.write(&bytes[written..end_offset]); @@ -1496,7 +1504,7 @@ impl GhosttyPaneTerminal { written = end_offset; } match event { - OrderedPtyResponseEvent::DefaultColor(event) => { + OrderedColorOrC1Event::Color(event) => { let replacement = respond_to_default_color_event(core, event.event); if replacement.is_some() { remove_last_matching_libghostty_color_reply( @@ -1507,9 +1515,16 @@ impl GhosttyPaneTerminal { terminal_responses.extend(libghostty_responses); terminal_responses.extend(replacement); } - OrderedPtyResponseEvent::Xtgettcap(response) => { + OrderedColorOrC1Event::C1(response) => { + if response.suppress_native { + libghostty_responses.retain(|reply| { + !reply.starts_with(b"\x1bP1+r") && !reply.starts_with(b"\x1bP0+r") + }); + } terminal_responses.extend(libghostty_responses); - terminal_responses.push(response.bytes); + if !response.suppress_native { + terminal_responses.push(response.bytes); + } } } } @@ -1648,6 +1663,8 @@ impl GhosttyPaneTerminal { cell_height_px: u32, ) -> Vec { if let Ok(mut core) = self.core.lock() { + #[cfg(windows)] + windows_recent_fallback::refresh_if_needed(&mut core); let offset_from_bottom = core .terminal .scrollbar() @@ -1675,6 +1692,12 @@ impl GhosttyPaneTerminal { None }; + #[cfg(windows)] + if core.recent_fallback.usable { + // Track the old viewport's start without pinning trailing blank rows. + core.terminal.track_row(0); + } + let _ = core .terminal .resize(cols, rows, cell_width_px, cell_height_px); @@ -2409,21 +2432,17 @@ fn cursor_state_from_render_state( render_state: &mut crate::ghostty::RenderState, decscusr_tracker: &DecscusrTracker, ) -> Option { - let cursor = render_state.cursor_viewport().ok()??; + let cursor = render_state.cursor().ok()?; + let viewport = cursor.viewport?; let shape = if decscusr_tracker.cursor_shape_overridden() { - render_state - .cursor_visual_style() - .ok() - .zip(render_state.cursor_blinking().ok()) - .map(|(style, blinking)| decscusr_cursor_shape(style, blinking)) - .unwrap_or(0) + decscusr_cursor_shape(cursor.visual_style, cursor.blinking) } else { 0 }; Some(TerminalCursorState { - x: cursor.x, - y: cursor.y, - visible: render_state.cursor_visible().ok()?, + x: viewport.x, + y: viewport.y, + visible: cursor.visible, shape, }) } @@ -2431,6 +2450,9 @@ fn cursor_state_from_render_state( type VisibleHyperlinks = Vec<((u16, u16), String, String)>; fn ghostty_clear_render_dirty(render_state: &mut crate::ghostty::RenderState, area_height: u16) { + if render_state.rows().is_ok_and(|rows| area_height >= rows) && render_state.clean().is_ok() { + return; + } let Ok(mut row_iterator) = crate::ghostty::RowIterator::new() else { return; }; @@ -2492,16 +2514,11 @@ fn ghostty_collect_dirty_patch( if render_state.update(terminal).is_err() { fallback!("render_state_update_error"); } - let collect_all_rows = match render_state.dirty() { + match render_state.dirty() { Ok(crate::ghostty::Dirty::Clean) => finish!(TerminalDirtyPatchOutcome::Clean), - Ok(crate::ghostty::Dirty::Partial) => false, - // A full dirty state means that every visible row may have changed. It - // is still safe to send this as a bounded patch: the client replaces - // only this pane's viewport, rather than falling back to the whole - // shell surface. - Ok(crate::ghostty::Dirty::Full) => true, + Ok(crate::ghostty::Dirty::Partial | crate::ghostty::Dirty::Full) => {} Err(_) => fallback!("dirty_read_error"), - }; + } let colors = render_state.colors().ok(); let default_bg = colors @@ -2527,77 +2544,73 @@ fn ghostty_collect_dirty_patch( let mut grapheme_bytes = Vec::new(); let mut symbol_scratch = String::new(); let mut patch_rows = Vec::new(); - let mut y = 0u16; - while y < area_height && rows.next() { - let Ok(dirty) = rows.dirty() else { - fallback!("row_dirty_read_error"); + while let Some(y) = rows.next_dirty() { + if y >= area_height { + break; + } + match rows.selection() { + Ok(None) => {} + Ok(Some(_)) => fallback!("row_selection_present"), + Err(_) => fallback!("row_selection_error"), + } + let Ok(mut cells) = rows.populate_cells(&mut row_cells) else { + fallback!("populate_cells_error"); }; - if collect_all_rows || dirty { - match rows.selection() { - Ok(None) => {} - Ok(Some(_)) => fallback!("row_selection_present"), - Err(_) => fallback!("row_selection_error"), - } - let Ok(mut cells) = rows.populate_cells(&mut row_cells) else { - fallback!("populate_cells_error"); + let mut patch_cells = Vec::with_capacity(usize::from(area_width)); + let mut x = 0u16; + while x < area_width && cells.next() { + let Ok(basic) = cells.basic_data() else { + fallback!("basic_data_error"); }; - let mut patch_cells = Vec::with_capacity(usize::from(area_width)); - let mut x = 0u16; - while x < area_width && cells.next() { - let Ok(basic) = cells.basic_data() else { - fallback!("basic_data_error"); - }; - if basic.has_hyperlink { - fallback!("hyperlink_present"); - } - let style = ghostty_cell_style( - &cells, - &basic, - default_fg, - default_bg, - resolved_fg, - resolved_bg, - palette_overrides.as_ref(), - ); - let symbol = match ghostty_buffer_symbol_into( - &cells, - basic.wide, - hide_kitty_placeholders, - &mut grapheme_bytes, - &mut symbol_scratch, - ) { - Ok(symbol) => symbol.to_owned(), - Err(_) => ghostty_blank_symbol_for_width(basic.wide).to_owned(), - }; - patch_cells.push(cell_data_from_style(symbol, style)); - x += 1; - } - while x < area_width { - patch_cells.push(blank_cell_data(default_fg, default_bg)); - x += 1; + if basic.has_hyperlink { + fallback!("hyperlink_present"); } - patch_rows.push((y, patch_cells)); + let style = ghostty_cell_style( + &cells, + &basic, + default_fg, + default_bg, + resolved_fg, + resolved_bg, + palette_overrides.as_ref(), + ); + let symbol = match ghostty_buffer_symbol_into( + &cells, + basic.wide, + hide_kitty_placeholders, + &mut grapheme_bytes, + &mut symbol_scratch, + ) { + Ok(symbol) => symbol.to_owned(), + Err(_) => ghostty_blank_symbol_for_width(basic.wide).to_owned(), + }; + patch_cells.push(cell_data_from_style(symbol, style)); + x += 1; } - y += 1; + while x < area_width { + patch_cells.push(blank_cell_data(default_fg, default_bg)); + x += 1; + } + patch_rows.push((y, patch_cells)); } // Nothing above mutates dirty state. Only clear it after every row has // been collected successfully, so a safety fallback leaves the next // collection with the same information. - let dirty_ys: std::collections::HashSet = patch_rows.iter().map(|(row, _)| *row).collect(); - if !dirty_ys.is_empty() { + if !patch_rows.is_empty() { let Ok(mut clear_row_iterator) = crate::ghostty::RowIterator::new() else { fallback!("clear_row_iterator_new_error"); }; let Ok(mut clear_rows) = render_state.populate_row_iterator(&mut clear_row_iterator) else { fallback!("clear_populate_rows_error"); }; - let mut clear_y = 0u16; - while clear_y < area_height && clear_rows.next() { - if dirty_ys.contains(&clear_y) && clear_rows.clear_dirty().is_err() { + while let Some(y) = clear_rows.next_dirty() { + if y >= area_height { + break; + } + if clear_rows.clear_dirty().is_err() { fallback!("clear_dirty_error"); } - clear_y += 1; } } if render_state @@ -3182,17 +3195,16 @@ fn ghostty_cell_style( style.add_modifier(modifiers) } -#[derive(Debug)] -enum OrderedPtyResponseEvent { - DefaultColor(DefaultColorTrackedEvent), - Xtgettcap(XtgettcapResponse), +enum OrderedColorOrC1Event { + Color(DefaultColorTrackedEvent), + C1(C1XtgettcapResponse), } -impl OrderedPtyResponseEvent { +impl OrderedColorOrC1Event { fn end_offset(&self) -> usize { match self { - Self::DefaultColor(event) => event.end_offset, - Self::Xtgettcap(response) => response.end_offset, + Self::Color(event) => event.end_offset, + Self::C1(response) => response.end_offset, } } } @@ -5920,6 +5932,55 @@ mod tests { assert!(rx.try_recv().is_err()); } + #[test] + fn process_pty_bytes_returns_fragmented_c1_xtgettcap_once_in_order() { + for query in [ + b"\x90+q5463;524742\x9c".as_slice(), + b"\x1bP+q5463;524742\x9c".as_slice(), + b"\x90+q5463;524742\x1b\\".as_slice(), + ] { + for fragmented in [false, true] { + let (tx, mut rx) = mpsc::channel(4); + let terminal = crate::ghostty::Terminal::new(20, 5, 0).unwrap(); + let pane = GhosttyPaneTerminal::new(terminal, tx.clone()).unwrap(); + let pane_id = PaneId::from_raw(1); + pane.apply_host_terminal_theme(crate::terminal_theme::TerminalTheme { + background: Some(crate::terminal_theme::RgbColor { + r: 0, + g: 0x2b, + b: 0x36, + }), + ..Default::default() + }); + let mut replies = pane + .process_pty_bytes(pane_id, 0, b"\x1b]11;?\x07", &tx) + .terminal_responses; + for chunk in query.chunks(if fragmented { 1 } else { query.len() }) { + replies.extend( + pane.process_pty_bytes(pane_id, 0, chunk, &tx) + .terminal_responses, + ); + } + replies.extend( + pane.process_pty_bytes(pane_id, 0, b"\x1b]11;?\x1b\\\x1bP+q5375\x1b\\", &tx) + .terminal_responses, + ); + assert_eq!( + replies, + vec![ + Bytes::from_static(b"\x1b]11;rgb:0000/2b2b/3636\x1b\\"), + expected_xtgettcap_response("5463", None), + expected_xtgettcap_response("524742", Some(b"8")), + Bytes::from_static(b"\x1b]11;rgb:0000/2b2b/3636\x1b\\"), + expected_xtgettcap_response("5375", None), + ], + "query={query:?}, fragmented={fragmented}" + ); + assert!(rx.try_recv().is_err()); + } + } + } + #[test] fn process_pty_bytes_returns_split_xtgettcap_query_response() { let (tx, mut rx) = mpsc::channel(4); @@ -5930,10 +5991,12 @@ mod tests { let result = pane.process_pty_bytes(pane_id, 0, b"\x1bP+q4", &tx); assert!(result.terminal_responses.is_empty()); assert!(rx.try_recv().is_err()); - let result = pane.process_pty_bytes(pane_id, 0, b"D73\x1b", &tx); + let result = pane.process_pty_bytes(pane_id, 0, b"d73", &tx); assert!(result.terminal_responses.is_empty()); assert!(rx.try_recv().is_err()); - let result = pane.process_pty_bytes(pane_id, 0, b"\\", &tx); + // libghostty unhooks DCS on ESC, before the final ST backslash. + // Splitting ST must not lose the reply or emit it again on completion. + let result = pane.process_pty_bytes(pane_id, 0, b"\x1b", &tx); assert_eq!( result.terminal_responses, @@ -5943,6 +6006,9 @@ mod tests { )] ); assert!(rx.try_recv().is_err()); + let result = pane.process_pty_bytes(pane_id, 0, b"\\", &tx); + assert!(result.terminal_responses.is_empty()); + assert!(rx.try_recv().is_err()); } #[test] @@ -6081,6 +6147,41 @@ mod tests { assert!(rx.try_recv().is_err()); } + #[test] + fn process_pty_bytes_orders_default_color_reset_reply_before_xtgettcap() { + let (tx, mut rx) = mpsc::channel(4); + let terminal = crate::ghostty::Terminal::new(20, 5, 0).unwrap(); + let pane = GhosttyPaneTerminal::new(terminal, tx.clone()).unwrap(); + let pane_id = PaneId::from_raw(1); + pane.apply_host_terminal_theme(crate::terminal_theme::TerminalTheme { + background: Some(crate::terminal_theme::RgbColor { + r: 0x00, + g: 0x2b, + b: 0x36, + }), + ..Default::default() + }); + + let result = pane.process_pty_bytes( + pane_id, + 0, + b"\x1b]11;#112233\x07\x1b]111\x07\x1b]11;?\x1b", + &tx, + ); + assert!(result.terminal_responses.is_empty()); + let result = pane.process_pty_bytes(pane_id, 0, b"\\\x1bP+q436f\x1b\\", &tx); + + assert_eq!( + result.terminal_responses, + vec![ + Bytes::from_static(b"\x1b]11;rgb:0000/2b2b/3636\x1b\\"), + // Co is provided by the native map, beyond our old eight keys. + expected_xtgettcap_response("436F", Some(b"256")), + ] + ); + assert!(rx.try_recv().is_err()); + } + #[test] fn process_pty_bytes_ignores_unknown_and_unsupported_xtgettcap_queries() { let (tx, mut rx) = mpsc::channel(4); diff --git a/src/pane/terminal/migration_tests.rs b/src/pane/terminal/migration_tests.rs new file mode 100644 index 00000000..94d78a77 --- /dev/null +++ b/src/pane/terminal/migration_tests.rs @@ -0,0 +1,382 @@ +//! Bounded semantic migration gates. No opaque IDs, timing, or render scheduling +//! decisions enter this oracle. Keep the same runner for old/candidate captures. +use super::*; + +struct Harness { + pane: PaneTerminal, + tx: mpsc::Sender, + width: u16, + height: u16, + effects: Effects, +} + +#[derive(Debug, Default, PartialEq, Eq)] +struct Effects { + replies: Vec, + clipboard: Vec>, + bells: u32, + cwd: Vec, +} + +#[derive(Debug, PartialEq, Eq)] +struct Observation { + geometry: (u16, u16), + cells: Vec, + text_rows: Vec, + links: Vec<((u16, u16), String, String)>, + cursor: TerminalCursorState, + input: InputState, + visible: String, + recent: TerminalReadSnapshot, + detection: String, + title: Option, +} + +impl Harness { + fn new(width: u16, height: u16) -> Self { + let (tx, _rx) = mpsc::channel(16); + let terminal = crate::ghostty::Terminal::new(width, height, 256).unwrap(); + Self { + pane: PaneTerminal::new(GhosttyPaneTerminal::new(terminal, tx.clone()).unwrap()), + tx, + width, + height, + effects: Effects::default(), + } + } + + fn write(&mut self, bytes: &[u8]) { + let result = self + .pane + .process_pty_bytes(PaneId::from_raw(1), 0, bytes, &self.tx); + for reply in result.terminal_responses { + self.effects.replies.extend_from_slice(&reply); + } + self.effects.clipboard.extend(result.clipboard_writes); + self.effects.bells += u32::from(result.terminal_bells); + self.effects.cwd.extend(result.reported_cwd); + } + + fn resize(&mut self, width: u16, height: u16) { + for reply in self.pane.resize(height, width, 8, 16) { + self.effects.replies.extend_from_slice(&reply); + } + self.width = width; + self.height = height; + } + + fn full_cells(&self) -> Vec { + // Read the frame buffer, not TestBackend's diff output (which may skip + // wide spacer cells). This is the independent full-render oracle. + let backend = ratatui::backend::TestBackend::new(self.width, self.height); + let mut terminal = ratatui::Terminal::new(backend).unwrap(); + let mut cells = Vec::new(); + terminal + .draw(|frame| { + self.pane + .render(frame, Rect::new(0, 0, self.width, self.height), false); + cells = frame + .buffer_mut() + .content + .iter() + .map(CellData::from_ratatui_cell) + .collect(); + }) + .unwrap(); + cells + } + + fn cursor(&self) -> Option { + // Compare terminal semantics, not Windows' time-based cursor settling policy. + current_cursor_state(&mut self.pane.ghostty.core.lock().unwrap()) + } + + fn observe(&self) -> Observation { + let (_, cols, text_rows) = self.pane.screen_text_snapshot().unwrap(); + assert_eq!(cols, self.width); + Observation { + geometry: (self.width, self.height), + cells: self.full_cells(), + text_rows, + links: self + .pane + .visible_hyperlinks(Rect::new(0, 0, self.width, self.height)), + cursor: self.cursor().unwrap(), + input: self.pane.input_state().unwrap(), + visible: self.pane.visible_text(), + recent: self.pane.recent_text_snapshot(32), + detection: self.pane.detection_text(), + title: self.pane.terminal_title(), + } + } +} + +#[test] +fn short_streams_are_invariant_at_every_byte_boundary() { + let fixtures: &[&[u8]] = &[ + "a界e\u{301}🇯🇵!".as_bytes(), + b"a\x1b[31;1mB\x1b[0m\x1b[2;3HZ\x1b[6n\x1b[?2004h", + b"\x1b]8;;https://example.test/a\x1b\\link\x1b]8;;\x1b\\!", + b"\x1b]52;c;aGk=\x07\x1b]2;migration\x1b\\\x07", + b"\x1bP+q5463\x1b\\\x1bP+q6E6F7065\x9c\x1b[6n", + ]; + for bytes in fixtures { + let mut whole = Harness::new(16, 4); + whole.write(bytes); + let expected = whole.observe(); + for split in 0..=bytes.len() { + let mut fragmented = Harness::new(16, 4); + fragmented.write(&bytes[..split]); + fragmented.write(&bytes[split..]); + assert_eq!( + fragmented.observe(), + expected, + "split {split}, bytes {bytes:?}" + ); + assert_eq!( + fragmented.effects, whole.effects, + "effects at split {split}" + ); + } + let mut bytewise = Harness::new(16, 4); + for byte in bytes.iter() { + bytewise.write(std::slice::from_ref(byte)); + } + assert_eq!(bytewise.observe(), expected); + assert_eq!(bytewise.effects, whole.effects); + } +} + +const MIXED: &str = "ab\x1b[1;38;2;12;34;56m界e\u{301}\x1b[0m\x1b]8;;https://example.test/reflow\x1b\\🇯🇵xyz\x1b]8;;\x1b\\\r\nnext カタカナ end"; + +#[test] +fn mixed_reflow_reads_are_stable_and_chunk_independent() { + let mut whole = Harness::new(12, 5); + let mut fragmented = Harness::new(12, 5); + whole.write(MIXED.as_bytes()); + for chunk in MIXED.as_bytes().chunks(3) { + fragmented.write(chunk); + } + for (width, height) in [(12, 5), (8, 4), (17, 6), (9, 5), (12, 5)] { + whole.resize(width, height); + fragmented.resize(width, height); + let expected = whole.observe(); + assert_eq!(whole.observe(), expected, "reads must not mutate semantics"); + assert_eq!(fragmented.observe(), expected); + assert!( + !expected.links.is_empty(), + "fixture must retain a visible link" + ); + } +} + +#[test] +fn incremental_rows_reconstruct_full_render() { + let mut incremental = Harness::new(12, 5); + let mut full = Harness::new(12, 5); + let mut retained = vec![CellData::from_ratatui_cell(&ratatui::buffer::Cell::default()); 60]; + // Independent terminals: full render must not consume incremental dirty state. + for bytes in [ + b"".as_slice(), + "ab\x1b[1;31m界e\u{301}\x1b[0m\r\nnext".as_bytes(), + b"\x1b[2;2HZ", + b"\x1b[1;1HA\x1b[5;8HB", + b"\x1b]4;1;rgb:12/34/56\x07", + b"\x1b[3;4H", + b"\x1b[?1049hALT", + b"\x1b[?1049l", + ] { + incremental.write(bytes); + full.write(bytes); + match incremental.pane.collect_dirty_patch(12, 5) { + TerminalDirtyPatchOutcome::Clean => {} + TerminalDirtyPatchOutcome::Patch(patch) => { + for (row, cells) in patch.rows { + assert_eq!(cells.len(), 12); + let start = usize::from(row) * 12; + retained[start..start + 12].clone_from_slice(&cells); + } + } + TerminalDirtyPatchOutcome::Fallback => { + panic!("bounded text fixture unexpectedly fell back") + } + } + assert_eq!(retained, full.full_cells(), "after {bytes:?}"); + assert_eq!(incremental.cursor(), full.cursor()); + } +} + +#[test] +fn sparse_dirty_patches_preserve_coordinates_and_clipped_rows() { + for height in [3, 6] { + let mut terminal = Harness::new(8, 6); + terminal.write(b"\x1b[2;3H"); + terminal.pane.collect_dirty_patch(8, 6); + assert!(matches!( + terminal.pane.collect_dirty_patch(8, 6), + TerminalDirtyPatchOutcome::Clean + )); + terminal.write(b"\x1b[2;3HX\x1b[5;4HY"); + let TerminalDirtyPatchOutcome::Patch(patch) = terminal.pane.collect_dirty_patch(8, height) + else { + panic!("expected sparse patch"); + }; + let expected_rows = if height == 3 { vec![1] } else { vec![1, 4] }; + assert_eq!( + patch.rows.iter().map(|(y, _)| *y).collect::>(), + expected_rows + ); + assert!(patch.rows.iter().all(|(_, cells)| cells.len() == 8)); + + let core = terminal.pane.ghostty.core.lock().unwrap(); + let mut iterator = crate::ghostty::RowIterator::new().unwrap(); + let mut rows = core + .render_state + .populate_row_iterator(&mut iterator) + .unwrap(); + let mut y = 0; + while rows.next() { + assert_eq!(rows.dirty().unwrap(), height == 3 && y == 4); + y += 1; + } + assert_eq!(y, 6); + } +} + +#[test] +fn dirty_patch_fallback_keeps_previously_collected_rows_dirty() { + let mut terminal = Harness::new(8, 6); + terminal.write(b"\x1b[2;3H"); + terminal.pane.collect_dirty_patch(8, 6); + terminal.write(b"\x1b[2;3HX\x1b[5;4H\x1b]8;;https://example.test\x1b\\Y\x1b]8;;\x1b\\"); + assert!(matches!( + terminal.pane.collect_dirty_patch(8, 6), + TerminalDirtyPatchOutcome::Fallback + )); + let core = terminal.pane.ghostty.core.lock().unwrap(); + let mut iterator = crate::ghostty::RowIterator::new().unwrap(); + let mut rows = core + .render_state + .populate_row_iterator(&mut iterator) + .unwrap(); + let mut dirty = Vec::new(); + let mut y = 0; + while rows.next() { + if rows.dirty().unwrap() { + dirty.push(y); + } + y += 1; + } + assert_eq!(dirty, vec![1, 4]); +} + +#[test] +fn complete_history_replay_supports_plain_append() { + // ANSI history is text restoration, not a parser/cursor snapshot. End at a + // non-wrapping printable cell with SGR and OSC8 closed; no pending tab/CSI. + let mut source = Harness::new(24, 4); + source.write(b"\x1b[31mred\x1b[0m\r\nplain"); + let ansi = source.pane.recent_unwrapped_ansi(32); + let mut restored = Harness::new(24, 4); + restored.pane.ghostty.seed_history_ansi(&ansi); + assert_eq!( + restored.pane.recent_text_snapshot(32), + source.pane.recent_text_snapshot(32) + ); + // Establish the documented live-output boundary explicitly instead of + // requiring history formatting to restore arbitrary cursor/SGR state. + for terminal in [&mut source, &mut restored] { + terminal.write(b"\x1b[0m\r\nappended"); + } + assert_eq!( + restored.pane.recent_text_snapshot(32), + source.pane.recent_text_snapshot(32) + ); + assert!(restored.effects.clipboard.is_empty()); + assert!(restored.effects.replies.is_empty()); +} + +#[test] +#[ignore = "non-gating release render scaling profile"] +fn render_scale_profile_sparse_dirty_patches() { + for count in [1, 15] { + let mut panes = (0..count).map(|_| Harness::new(80, 24)).collect::>(); + for pane in &mut panes { + for line in 0..40 { + pane.write(format!("{line:04} populated 界 terminal row\r\n").as_bytes()); + } + pane.write(b"\x1b[12;40H"); + pane.pane.collect_dirty_patch(80, 24); + } + for sparse in [false, true] { + let mut samples = Vec::new(); + for sample in 0..35 { + let mut elapsed = std::time::Duration::ZERO; + for iteration in 0..20 { + if sparse { + let bytes: &[u8] = if iteration % 2 == 0 { + b"\x1b[12;40HX" + } else { + b"\x1b[12;40HY" + }; + for pane in &panes { + pane.pane.ghostty.core.lock().unwrap().terminal.write(bytes); + } + } + let start = std::time::Instant::now(); + for pane in &panes { + let outcome = pane.pane.collect_dirty_patch(80, 24); + if sparse { + let TerminalDirtyPatchOutcome::Patch(ref patch) = outcome else { + panic!("expected sparse patch"); + }; + assert_eq!(patch.rows.len(), 1); + assert_eq!(patch.rows[0].0, 11); + } else { + assert!(matches!(outcome, TerminalDirtyPatchOutcome::Clean)); + } + std::hint::black_box(outcome); + } + elapsed += start.elapsed(); + } + if sample >= 5 { + samples.push(elapsed.as_nanos() / 20); + } + } + samples.sort_unstable(); + eprintln!( + "dirty_patch_scale panes={count} sparse={sparse} median_ns={} p95_ns={}", + samples[samples.len() / 2], + samples[samples.len() * 95 / 100] + ); + } + } +} + +#[test] +fn capture_bounded_migration_observations() { + let mut terminal = Harness::new(12, 5); + let mut observations = Vec::new(); + terminal.write(MIXED.as_bytes()); + observations.push(terminal.observe()); + for (width, height) in [(8, 4), (17, 6), (12, 5)] { + terminal.resize(width, height); + observations.push(terminal.observe()); + } + terminal.write(b"\x1b[6n\x1b[?2004h\x1b]52;c;aGk=\x07\x07"); + observations.push(terminal.observe()); + terminal.pane.scroll_up(2); + observations.push(terminal.observe()); + terminal.pane.scroll_reset(); + observations.push(terminal.observe()); + // An explicit path prevents fixtures from silently being regenerated. + // Compare old/new with diff; explain each difference, never bulk-bless it. + if let Some(path) = std::env::var_os("HERDR_MIGRATION_OBSERVATIONS") { + std::fs::write( + path, + format!("{observations:#?}\n{:#?}\n", terminal.effects), + ) + .unwrap(); + } + assert_eq!(observations.last().unwrap(), &terminal.observe()); +} diff --git a/src/pane/terminal/windows_recent_fallback.rs b/src/pane/terminal/windows_recent_fallback.rs index efb58b49..7f632c08 100644 --- a/src/pane/terminal/windows_recent_fallback.rs +++ b/src/pane/terminal/windows_recent_fallback.rs @@ -346,6 +346,20 @@ mod tests { #[test] fn deferred_repaint_survives_real_scrollback_pruning() { + assert_deferred_repaint_survives_real_scrollback_pruning(None); + } + + #[test] + fn deferred_repaint_survives_real_scrollback_pruning_resize_rows() { + assert_deferred_repaint_survives_real_scrollback_pruning(Some((2, 40))); + } + + #[test] + fn deferred_repaint_survives_real_scrollback_pruning_resize_both_axes() { + assert_deferred_repaint_survives_real_scrollback_pruning(Some((2, 20))); + } + + fn assert_deferred_repaint_survives_real_scrollback_pruning(resize: Option<(u16, u16)>) { let (tx, _rx) = mpsc::channel(4); let terminal = crate::ghostty::Terminal::new(40, 1, 1).unwrap(); let pane = GhosttyPaneTerminal::new(terminal, tx.clone()).unwrap(); @@ -387,6 +401,9 @@ mod tests { .collect::(); pane.process_pty_bytes(pane_id, 0, batch.as_bytes(), &tx); assert_eq!(state(), (before, true)); + if let Some((rows, cols)) = resize { + pane.resize(rows, cols, 8, 16); + } let mut core = pane.core.lock().unwrap(); let fallback = super::super::finish_recent_snapshot(&mut core, String::new(), CACHE_LINES, false); diff --git a/src/pane/xtgettcap.rs b/src/pane/xtgettcap.rs index 7d2dfc5d..4d8fa572 100644 --- a/src/pane/xtgettcap.rs +++ b/src/pane/xtgettcap.rs @@ -1,20 +1,26 @@ +// Compatibility for legacy raw-C1 XTGETTCAP only. Ordinary ESC P ... ESC \ +// requests are answered exclusively by libghostty. Keep bytes untouched: C1 +// normalization across the stream could corrupt UTF-8 or binary string payloads. use bytes::Bytes; #[derive(Debug, Default)] -pub(super) struct XtgettcapQueryTracker { - state: XtgettcapTrackerState, +pub(super) struct C1XtgettcapQueryTracker { + state: C1XtgettcapTrackerState, + raw_c1_intro: bool, + native_dcs_pending: bool, body: Vec, - pending: Vec, + pending: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] -pub(super) struct XtgettcapResponse { +pub(super) struct C1XtgettcapResponse { pub(super) end_offset: usize, pub(super) bytes: Bytes, + pub(super) suppress_native: bool, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] -enum XtgettcapTrackerState { +enum C1XtgettcapTrackerState { #[default] Ground, Escape, @@ -30,114 +36,133 @@ enum XtgettcapTrackerState { OversizedDcsEscape, } -impl XtgettcapQueryTracker { +impl C1XtgettcapQueryTracker { pub(super) fn observe(&mut self, bytes: &[u8]) { for (index, &byte) in bytes.iter().enumerate() { + // With a 7-bit intro and raw ST, the native parser still holds the + // DCS open. At its eventual unhook it can answer earlier keys in a + // multi-key request again. Discard only that dispatch's XTGETTCAP + // replies, not subsequent native requests or other response types. + if self.native_dcs_pending && matches!(byte, 0x1b | 0x18 | 0x1a) { + self.pending.push(C1XtgettcapResponse { + end_offset: index + 1, + bytes: Bytes::new(), + suppress_native: true, + }); + self.native_dcs_pending = false; + } match self.state { - XtgettcapTrackerState::Ground => { + C1XtgettcapTrackerState::Ground => { if byte == 0x1b { - self.state = XtgettcapTrackerState::Escape; + self.state = C1XtgettcapTrackerState::Escape; } else if byte == 0x90 { self.body.clear(); - self.state = XtgettcapTrackerState::DcsIntro; + self.raw_c1_intro = true; + self.state = C1XtgettcapTrackerState::DcsIntro; } else if byte == 0x9d { - self.state = XtgettcapTrackerState::IgnoreOsc; + self.state = C1XtgettcapTrackerState::IgnoreOsc; } else if matches!(byte, 0x98 | 0x9e | 0x9f) { - self.state = XtgettcapTrackerState::IgnoreString; + self.state = C1XtgettcapTrackerState::IgnoreString; } } - XtgettcapTrackerState::Escape => match byte { + C1XtgettcapTrackerState::Escape => match byte { b'P' => { + self.raw_c1_intro = false; self.body.clear(); - self.state = XtgettcapTrackerState::DcsIntro; + self.state = C1XtgettcapTrackerState::DcsIntro; } b']' => { self.body.clear(); - self.state = XtgettcapTrackerState::IgnoreOsc; + self.state = C1XtgettcapTrackerState::IgnoreOsc; } b'_' | b'^' | b'X' => { self.body.clear(); - self.state = XtgettcapTrackerState::IgnoreString; + self.state = C1XtgettcapTrackerState::IgnoreString; } - 0x1b => self.state = XtgettcapTrackerState::Escape, - _ => self.state = XtgettcapTrackerState::Ground, + 0x1b => self.state = C1XtgettcapTrackerState::Escape, + _ => self.state = C1XtgettcapTrackerState::Ground, }, - XtgettcapTrackerState::DcsIntro => match byte { - b'+' => self.state = XtgettcapTrackerState::DcsIntroPlus, - 0x1b => self.state = XtgettcapTrackerState::IgnoreStringEscape, - 0x9c => self.state = XtgettcapTrackerState::Ground, - _ => self.state = XtgettcapTrackerState::IgnoreString, + C1XtgettcapTrackerState::DcsIntro => match byte { + b'+' => self.state = C1XtgettcapTrackerState::DcsIntroPlus, + 0x1b => self.state = C1XtgettcapTrackerState::IgnoreStringEscape, + 0x9c => self.state = C1XtgettcapTrackerState::Ground, + _ => self.state = C1XtgettcapTrackerState::IgnoreString, }, - XtgettcapTrackerState::DcsIntroPlus => match byte { - b'q' => self.state = XtgettcapTrackerState::DcsBody, - 0x1b => self.state = XtgettcapTrackerState::IgnoreStringEscape, - 0x9c => self.state = XtgettcapTrackerState::Ground, - _ => self.state = XtgettcapTrackerState::IgnoreString, + C1XtgettcapTrackerState::DcsIntroPlus => match byte { + b'q' => self.state = C1XtgettcapTrackerState::DcsBody, + 0x1b => self.state = C1XtgettcapTrackerState::IgnoreStringEscape, + 0x9c => self.state = C1XtgettcapTrackerState::Ground, + _ => self.state = C1XtgettcapTrackerState::IgnoreString, }, - XtgettcapTrackerState::DcsBody => match byte { - 0x1b => self.state = XtgettcapTrackerState::DcsEscape, + C1XtgettcapTrackerState::DcsBody => match byte { + 0x1b => self.state = C1XtgettcapTrackerState::DcsEscape, 0x9c => { + self.native_dcs_pending |= !self.raw_c1_intro; self.finalize(index + 1); - self.state = XtgettcapTrackerState::Ground; + self.state = C1XtgettcapTrackerState::Ground; } _ => self.body.push(byte), }, - XtgettcapTrackerState::DcsEscape => { + C1XtgettcapTrackerState::DcsEscape => { if byte == b'\\' { - self.finalize(index + 1); - self.state = XtgettcapTrackerState::Ground; + if self.raw_c1_intro { + self.finalize(index + 1); + } else { + self.body.clear(); + } + self.state = C1XtgettcapTrackerState::Ground; } else if byte != 0x1b { self.body.clear(); - self.state = XtgettcapTrackerState::IgnoreString; + self.state = C1XtgettcapTrackerState::IgnoreString; } } - XtgettcapTrackerState::IgnoreOsc => { + C1XtgettcapTrackerState::IgnoreOsc => { if byte == 0x1b { - self.state = XtgettcapTrackerState::IgnoreOscEscape; + self.state = C1XtgettcapTrackerState::IgnoreOscEscape; } else if matches!(byte, 0x07 | 0x9c) { - self.state = XtgettcapTrackerState::Ground; + self.state = C1XtgettcapTrackerState::Ground; } } - XtgettcapTrackerState::IgnoreOscEscape => { + C1XtgettcapTrackerState::IgnoreOscEscape => { if byte == b'\\' { - self.state = XtgettcapTrackerState::Ground; + self.state = C1XtgettcapTrackerState::Ground; } else if byte != 0x1b { - self.state = XtgettcapTrackerState::IgnoreOsc; + self.state = C1XtgettcapTrackerState::IgnoreOsc; } } - XtgettcapTrackerState::IgnoreString => { + C1XtgettcapTrackerState::IgnoreString => { if byte == 0x1b { - self.state = XtgettcapTrackerState::IgnoreStringEscape; + self.state = C1XtgettcapTrackerState::IgnoreStringEscape; } else if byte == 0x9c { - self.state = XtgettcapTrackerState::Ground; + self.state = C1XtgettcapTrackerState::Ground; } } - XtgettcapTrackerState::IgnoreStringEscape => { + C1XtgettcapTrackerState::IgnoreStringEscape => { if byte == b'\\' { - self.state = XtgettcapTrackerState::Ground; + self.state = C1XtgettcapTrackerState::Ground; } else if byte != 0x1b { - self.state = XtgettcapTrackerState::IgnoreString; + self.state = C1XtgettcapTrackerState::IgnoreString; } } - XtgettcapTrackerState::OversizedDcs => { + C1XtgettcapTrackerState::OversizedDcs => { if byte == 0x1b { - self.state = XtgettcapTrackerState::OversizedDcsEscape; + self.state = C1XtgettcapTrackerState::OversizedDcsEscape; } else if byte == 0x9c { - self.state = XtgettcapTrackerState::Ground; + self.state = C1XtgettcapTrackerState::Ground; } } - XtgettcapTrackerState::OversizedDcsEscape => { + C1XtgettcapTrackerState::OversizedDcsEscape => { if byte == b'\\' { - self.state = XtgettcapTrackerState::Ground; + self.state = C1XtgettcapTrackerState::Ground; } else if byte != 0x1b { - self.state = XtgettcapTrackerState::OversizedDcs; + self.state = C1XtgettcapTrackerState::OversizedDcs; } } } if self.body.len() > 1024 { self.body.clear(); - self.state = XtgettcapTrackerState::OversizedDcs; + self.state = C1XtgettcapTrackerState::OversizedDcs; } } } @@ -145,13 +170,17 @@ impl XtgettcapQueryTracker { fn finalize(&mut self, end_offset: usize) { for cap_hex in self.body.split(|byte| *byte == b';') { if let Some(bytes) = xtgettcap_response(cap_hex) { - self.pending.push(XtgettcapResponse { end_offset, bytes }); + self.pending.push(C1XtgettcapResponse { + end_offset, + bytes, + suppress_native: false, + }); } } self.body.clear(); } - pub(super) fn drain_pending(&mut self) -> Vec { + pub(super) fn drain_pending(&mut self) -> Vec { std::mem::take(&mut self.pending) } } @@ -210,134 +239,3 @@ fn append_upper_hex(bytes: &[u8], output: &mut Vec) { output.push(HEX[usize::from(byte & 0x0f)]); } } - -#[cfg(test)] -mod tests { - use super::*; - - fn response_bytes(responses: Vec) -> Vec { - responses - .into_iter() - .map(|response| response.bytes) - .collect() - } - - #[test] - fn tracker_returns_multiple_capabilities_in_order() { - let mut tracker = XtgettcapQueryTracker::default(); - - tracker.observe(b"\x1bP+q5463;524742\x1b\\"); - - assert_eq!( - response_bytes(tracker.drain_pending()), - vec![ - Bytes::from_static(b"\x1bP1+r5463\x1b\\"), - Bytes::from_static(b"\x1bP1+r524742=38\x1b\\"), - ] - ); - } - - #[test] - fn tracker_normalizes_mixed_case_query_keys() { - let mut tracker = XtgettcapQueryTracker::default(); - - tracker.observe(b"\x1bP+q4d73\x1b\\"); - - assert_eq!( - response_bytes(tracker.drain_pending()), - vec![Bytes::from_static( - b"\x1bP1+r4D73=5C455D35323B25703125733B25703225735C303037\x1b\\" - )] - ); - } - - #[test] - fn tracker_ignores_unsupported_capabilities() { - let mut tracker = XtgettcapQueryTracker::default(); - - tracker.observe(b"\x1bP+q6E6F7065\x1b\\"); - - assert!(response_bytes(tracker.drain_pending()).is_empty()); - } - - #[test] - fn tracker_returns_underline_style_capability() { - let mut tracker = XtgettcapQueryTracker::default(); - - tracker.observe(b"\x1bP+q536D756C78\x1b\\"); - - assert_eq!( - response_bytes(tracker.drain_pending()), - vec![Bytes::from_static( - b"\x1bP1+r536D756C78=5C455B343A25703125646D\x1b\\" - )] - ); - } - - #[test] - fn tracker_keeps_split_query_until_string_terminator() { - let mut tracker = XtgettcapQueryTracker::default(); - - tracker.observe(b"\x1bP+q537"); - assert!(response_bytes(tracker.drain_pending()).is_empty()); - tracker.observe(b"5\x1b"); - assert!(response_bytes(tracker.drain_pending()).is_empty()); - tracker.observe(b"\\"); - - assert_eq!( - response_bytes(tracker.drain_pending()), - vec![Bytes::from_static(b"\x1bP1+r5375\x1b\\")] - ); - } - - #[test] - fn tracker_resumes_after_ignored_osc_bel_terminator() { - let mut tracker = XtgettcapQueryTracker::default(); - - tracker.observe(b"\x1b]0;title\x07\x1bP+q5463\x1b\\"); - - assert_eq!( - response_bytes(tracker.drain_pending()), - vec![Bytes::from_static(b"\x1bP1+r5463\x1b\\")] - ); - } - - #[test] - fn tracker_accepts_eight_bit_dcs_and_string_terminator() { - let mut tracker = XtgettcapQueryTracker::default(); - - tracker.observe(b"\x90+q5463\x9c"); - - assert_eq!( - response_bytes(tracker.drain_pending()), - vec![Bytes::from_static(b"\x1bP1+r5463\x1b\\")] - ); - } - - #[test] - fn tracker_ignores_xtgettcap_bytes_inside_eight_bit_osc() { - let mut tracker = XtgettcapQueryTracker::default(); - - tracker.observe(b"\x9dtitle\x1bP+q5463\x9c\x1bP+q5463\x1b\\"); - - assert_eq!( - response_bytes(tracker.drain_pending()), - vec![Bytes::from_static(b"\x1bP1+r5463\x1b\\")] - ); - } - - #[test] - fn tracker_reports_response_end_offsets() { - let mut tracker = XtgettcapQueryTracker::default(); - - tracker.observe(b"before\x1bP+q5463\x1b\\after"); - - assert_eq!( - tracker.drain_pending(), - vec![XtgettcapResponse { - end_offset: 16, - bytes: Bytes::from_static(b"\x1bP1+r5463\x1b\\"), - }] - ); - } -} diff --git a/src/server/headless/tests/pane_graphics.rs b/src/server/headless/tests/pane_graphics.rs index f8637e8f..0414b6b3 100644 --- a/src/server/headless/tests/pane_graphics.rs +++ b/src/server/headless/tests/pane_graphics.rs @@ -221,13 +221,26 @@ async fn retained_unicode_image_arrives_after_fragmented_upload_without_reupload }; assert_eq!(surface.graphics.placements.len(), 1); assert_eq!(surface.graphics.assets[0].data, [255, 0, 0, 255]); - // Replacing pixels under the same image ID must invalidate the delivered asset. + // Retransmission removes placements; recreating the virtual placement must + // invalidate the delivered asset without needing another text update. write_shared_test_pane( &mut server, pane_id, b"\x1b_Ga=t,f=32,t=d,i=1193046,s=1,v=1,q=2;AP8A/w==\x1b\\", ); assert!(server.render_retained_pane_surface_and_stream(&sources)); + let ServerMessage::PaneSurface(removed) = + read_server_message(receive_render(&client_rx, Duration::from_millis(100))) + else { + panic!("retransmission must remove the virtual placement"); + }; + assert!(removed.graphics.placements.is_empty()); + write_shared_test_pane( + &mut server, + pane_id, + b"\x1b_Ga=p,U=1,i=1193046,c=1,r=1,q=2\x1b\\", + ); + assert!(server.render_retained_pane_surface_and_stream(&sources)); let ServerMessage::PaneSurface(replaced) = read_server_message(receive_render(&client_rx, Duration::from_millis(100))) else { diff --git a/tests/live_handoff.rs b/tests/live_handoff.rs index 034e1e89..38e68a5a 100644 --- a/tests/live_handoff.rs +++ b/tests/live_handoff.rs @@ -985,7 +985,6 @@ fn live_handoff_preserves_pane_process_io() { &api_socket, serde_json::json!({"id":"test:handoff","method":"server.live_handoff","params":{}}), )); - drop(spawned); assert!( wait_for_message_variant( &mut client_stream, @@ -995,6 +994,7 @@ fn live_handoff_preserves_pane_process_io() { .unwrap(), "connected client shell should receive live-handoff shutdown" ); + drop(spawned); thread::sleep(Duration::from_millis(300)); wait_for_api(&api_socket, Duration::from_secs(10)); wait_for_socket(&client_socket, Duration::from_secs(5)); @@ -1359,7 +1359,7 @@ fn live_handoff_keeps_unmanaged_agent_name_bound_to_saved_session() { fs::write( &fake_pi, format!( - "#!/bin/sh\nexport HERDR_AGENT=pi\necho started > {}\nexec /bin/sleep 30\n", + "#!/bin/sh\nexport HERDR_AGENT=pi\necho started > {}\n/bin/sleep 30\n:\n", started_marker.display() ), ) diff --git a/tests/support/mod.rs b/tests/support/mod.rs index f4ccebe8..cc29afe9 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -444,9 +444,13 @@ pub fn wait_for_message_variants( timeout: Duration, variants: &[u32], ) -> Result { - stream - .set_read_timeout(Some(Duration::from_millis(200))) - .map_err(|e| e.to_string())?; + let read_timeout = Some(Duration::from_millis(200)); + // Darwin can reject resetting the timeout after peer closure with queued data. + if stream.read_timeout().map_err(|e| e.to_string())? != read_timeout { + stream + .set_read_timeout(read_timeout) + .map_err(|e| e.to_string())?; + } let deadline = Instant::now() + timeout; while Instant::now() < deadline { match read_server_message(stream) { diff --git a/vendor/libghostty-vt.patches.md b/vendor/libghostty-vt.patches.md index dff98533..40645acc 100644 --- a/vendor/libghostty-vt.patches.md +++ b/vendor/libghostty-vt.patches.md @@ -4,74 +4,88 @@ This file tracks intentional local changes applied on top of the vendored `libghostty-vt` source. Remove a patch only when the vendored source commit contains the upstream behavior and the listed verification still passes. -## 0001 default lib-vt panes to grapheme clustering +## 0002 expose modifyOtherKeys mode through terminal data status: active -patch: `vendor/patches/libghostty-vt/0001-default-grapheme-cluster-mode.patch` +patch: `vendor/patches/libghostty-vt/0002-expose-modify-other-keys-mode.patch` -herdr issue: https://github.com/herdrdev/herdr/issues/243 +herdr issue: none; fixes the performance regression exposed by +https://github.com/herdrdev/herdr/pull/2303 -upstream discussion: not opened; libghostty-vt currently exposes current mode mutation but no C API for configuring terminal default modes +upstream discussion: not opened upstream pr: not opened -vendored base: `c5a21edfcbc2d5b46540ad91b7980aca31f5f1f3` +vendored base: `44f2a44df7e8c4a0c6df3f7d872ef3d7ead88e51` local files: +- `vendor/libghostty-vt/include/ghostty/vt/terminal.h` - `vendor/libghostty-vt/src/terminal/c/terminal.zig` -reason: Herdr renders terminal cells directly and requires DEC private mode -2027 to store flags, ZWJ emoji, and other multi-codepoint grapheme clusters in -one cell. This patch makes clustering active for new terminals and keeps it as -the reset default so RIS (`ESC c`) does not disable it. +reason: Herdr must know whether xterm modifyOtherKeys mode 2 is active to +request printable key releases from the outer terminal. The formatter API can +recover this fact only by formatting the active screen and scrollback. A typed +terminal-data query exposes the authoritative scalar without formatting or +allocation. The local query uses value 41; upstream now owns the previous +local value 33 for VT processing errors. -remove when: libghostty-vt exposes a C API for setting default mode 2027, or -upstream makes grapheme clustering the lib-vt default, and the reset-survival -regression passes without this patch. +remove when: the vendored source exposes an equivalent scalar query for +modifyOtherKeys mode 2 and Herdr can use it without this patch. verification: ```sh -cargo nextest run --locked grapheme_cluster_mode_is_default_and_survives_full_reset -cargo nextest run --locked grapheme_cluster_mode_renders_flag_emoji_in_single_wide_cell -cargo nextest run --locked grapheme_cluster_mode_renders_zwj_family_in_single_wide_cell +just test-one modify_other_keys +just test-one host_report_all_supplies_printable_releases_for_event_type_only_panes +just maintenance-test +just ui-hot-path-architecture-test ``` -## 0002 expose modifyOtherKeys mode through terminal data +The former grapheme-default patch is replaced by upstream's public +`GHOSTTY_TERMINAL_OPT_MODE_DEFAULT` API. Herdr configures mode 2027 through that +API and tests that RIS restores it after a child disables it. The Wuffs C-only +mirror fix from Ghostty PR 13789 is also included in this vendored base. + +## 0004 fix hosted Wuffs builds status: active -patch: `vendor/patches/libghostty-vt/0002-expose-modify-other-keys-mode.patch` +patch: `vendor/patches/libghostty-vt/0004-fix-hosted-wuffs-builds.patch` -herdr issue: none; fixes the performance regression exposed by -https://github.com/herdrdev/herdr/pull/2303 +herdr issue: none; preserves Windows cross-compilation and non-SIMD hosted builds upstream discussion: not opened upstream pr: not opened -vendored base: `c5a21edfcbc2d5b46540ad91b7980aca31f5f1f3` +vendored base: `44f2a44df7e8c4a0c6df3f7d872ef3d7ead88e51` local files: -- `vendor/libghostty-vt/include/ghostty/vt/terminal.h` -- `vendor/libghostty-vt/src/terminal/c/terminal.zig` +- `vendor/libghostty-vt/pkg/wuffs/build.zig` +- `vendor/libghostty-vt/pkg/wuffs/src/main.zig` -reason: Herdr must know whether xterm modifyOtherKeys mode 2 is active to -request printable key releases from the outer terminal. The formatter API can -recover this fact only by formatting the active screen and scrollback. A typed -terminal-data query exposes the authoritative scalar without formatting or -allocation. +reason: Wuffs now needs MSVC libc headers when targeting Windows. Zig's +`--libc` configuration reaches C compilation, but the translate-c dependency +requires its own explicit configuration. Forward the same file so cross-builds +can use an actual Windows SDK instead of changing the target ABI or skipping +compilation. Native builds without a libc override are unchanged. -remove when: the vendored source exposes an equivalent scalar query for -modifyOtherKeys mode 2 and Herdr can use it without this patch. +The no-libc Wuffs module also exports hidden weak calloc/free stubs. On hosted +Linux with SIMD disabled, those definitions override the Rust executable's +libc allocator, causing immediate allocation failures. Limit the stubs to +freestanding targets; hosted embedders resolve these symbols through libc. + +remove when: upstream forwards the build's libc configuration to the Wuffs +translator and prevents hosted allocator interposition, and both Windows +cross-compilation and non-SIMD native tests pass without this patch. verification: ```sh -cargo nextest run --locked modify_other_keys_query_tracks_mode_two -cargo nextest run --locked host_report_all_supplies_printable_releases_for_event_type_only_panes -python3 -m unittest scripts.test_vendor_libghostty_vt scripts.test_ui_hot_path_architecture +LIBGHOSTTY_VT_WINDOWS_LIBC=/path/to/windows-libc.txt just windows-lint +LIBGHOSTTY_VT_SIMD=false just test-one ghostty +just maintenance-test ``` diff --git a/vendor/libghostty-vt.vendor.json b/vendor/libghostty-vt.vendor.json index 3dd123b2..ecc771f4 100644 --- a/vendor/libghostty-vt.vendor.json +++ b/vendor/libghostty-vt.vendor.json @@ -1,5 +1,5 @@ { - "source_commit": "c5a21edfcbc2d5b46540ad91b7980aca31f5f1f3", - "dist_archive": "libghostty-vt-1.3.2-HEAD-+c5a21edfc.tar.gz", - "extracted_dir": "libghostty-vt-1.3.2-HEAD-+c5a21edfc" + "source_commit": "44f2a44df7e8c4a0c6df3f7d872ef3d7ead88e51", + "dist_archive": "libghostty-vt-1.3.2-HEAD-+44f2a44df.tar.gz", + "extracted_dir": "libghostty-vt-1.3.2-HEAD-+44f2a44df" } diff --git a/vendor/libghostty-vt/.agents/skills/writing-commit-messages/SKILL.md b/vendor/libghostty-vt/.agents/skills/writing-commit-messages/SKILL.md index dedadbe5..fef12cd3 100644 --- a/vendor/libghostty-vt/.agents/skills/writing-commit-messages/SKILL.md +++ b/vendor/libghostty-vt/.agents/skills/writing-commit-messages/SKILL.md @@ -47,7 +47,7 @@ Write commit messages that follow commit style guidelines for the project. and **how the new behavior works** at a high level. - Use plain prose, not bullet points. Wrap lines at ~72 characters. - Focus on the _why_ and _how_ rather than restating the diff. -- Keep the tone direct and technical without no filler phrases. +- Keep the tone direct and technical without filler phrases. - Don't exceed a handful of paragraphs; less is more. ## Workflow diff --git a/vendor/libghostty-vt/.clang-format b/vendor/libghostty-vt/.clang-format index 55ee2979..0ca181e4 100644 --- a/vendor/libghostty-vt/.clang-format +++ b/vendor/libghostty-vt/.clang-format @@ -179,4 +179,3 @@ WhitespaceSensitiveMacros: - PP_STRINGIZE - BOOST_PP_STRINGIZE --- - diff --git a/vendor/libghostty-vt/.github/DISCUSSION_TEMPLATE/issue-triage.yml b/vendor/libghostty-vt/.github/DISCUSSION_TEMPLATE/issue-triage.yml index 270bb86f..a29e6f17 100644 --- a/vendor/libghostty-vt/.github/DISCUSSION_TEMPLATE/issue-triage.yml +++ b/vendor/libghostty-vt/.github/DISCUSSION_TEMPLATE/issue-triage.yml @@ -156,6 +156,8 @@ body: options: - label: I have reviewed the FAQ and confirm that my issue is NOT among them. required: true + - label: I have searched the Ghostty documentation and confirm there doesn't exist a configuration option that solves my issue. + required: true - label: I have searched the Ghostty repository (both open and closed Discussions and Issues) and confirm this is not a duplicate of an existing issue or discussion. required: true - label: I have checked the "Preview" tab on all text fields to ensure that everything looks right, and have wrapped all configuration and code in code blocks with a group of three backticks (` ``` `) on separate lines. diff --git a/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/config.yml b/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 9c4455c4..00000000 --- a/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,5 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: Features, Bug Reports, Questions - url: https://github.com/ghostty-org/ghostty/discussions/new/choose - about: Our preferred starting point if you have any questions or suggestions about configuration, features or behavior. diff --git a/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/preapproved.md b/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/preapproved.md deleted file mode 100644 index 485e727e..00000000 --- a/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/preapproved.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: Pre-Discussed and Approved Topics -about: |- - Only for topics already discussed and approved in the GitHub Discussions section. ---- - -**DO NOT OPEN A NEW ISSUE. PLEASE USE THE DISCUSSIONS SECTION.** - -**I DIDN'T READ THE ABOVE LINE. PLEASE CLOSE THIS ISSUE.** diff --git a/vendor/libghostty-vt/.github/VOUCHED.td b/vendor/libghostty-vt/.github/VOUCHED.td index e6d365c8..3c2c7e2c 100644 --- a/vendor/libghostty-vt/.github/VOUCHED.td +++ b/vendor/libghostty-vt/.github/VOUCHED.td @@ -23,8 +23,10 @@ 00jciv00 04cb 0xdvc +12ya -4rh1t3ct0r7 52dyd +a-lang aalhendi aaron-ang abdurrahmanski @@ -38,23 +40,29 @@ akimiojr alaasdk alanmoyano alaviss +alex19ep alexbathome alexfeijoo44 alexjuca alosarjos amadeus +and-rs andrejdaskalov anhthang anmitalidev anthonyzhoon +aprilnea +arneshbanerjee arvin7liu athaapa atomk +aurelleb aymanbagabas b0uks b1nar10 balazs-szucs barutsrb +basteez bch bennettp123 benodiwal @@ -64,9 +72,13 @@ bitigchi bkircher bleikurr bo2themax +bousii brentschroeter brianc442 +by-nelson c0x0o +carldaws +carlvillads cespare charliie-dev chernetskyi @@ -83,14 +95,20 @@ damyanbogoev danneu danulqua dariogriffo +dave92082 davidsanchez222 deblasis dervedro devsunb diaaeddin +-didouougha slingshotting LLM output +diego-moment +diegoarmstrong dkinzler dmehala +dmunozv04 dobbylee +dolzenko doprz douglance douglas @@ -99,6 +117,7 @@ drepper dzhlobo ekaterinepapava elias8 +elitex45 -enkr1 enzowilliam ephemera @@ -109,18 +128,23 @@ escalonc eunos-1128 exlee -f1813483-netizen +fallintoplace faukah +figelwump filip7 flou fornwall francescarpi fru1tworld +gadgetman6 gagbo ghokun gmile gordonbondon +gotenksin gpanders guilhermetk +-guysoft LLM communication (likely automated) h3nock hakonhagland halosatrio @@ -133,10 +157,12 @@ hulet i999rri icodesign illiakrauchanka +j-c-m j0hnm4r5 jacobsandlund jake-stewart -jamesarch +jakeriksen +-jamesarch Bad AI etiquette jamylak jarred-sumner jcollie @@ -150,6 +176,7 @@ josephmart jparise juniqlim justonia +jzillmann karesansui-u kataokatsuki kawarimidoll @@ -159,10 +186,12 @@ khipp kierancanter kirwiisp kjvdven +kleshzz kloneets knu -kody-w koranir +korikhin kostich kristina8888 kristofersoler @@ -173,6 +202,7 @@ lepips liby linustalacko lonsagisawa +lotheac louisunlimited luisnquin lynicis @@ -186,6 +216,7 @@ marrocco-simone masterflitzer matkotiric mattn +mgsloan micaeljarniac michielvk miguelelgallo @@ -209,6 +240,7 @@ mustafa0x nagato-yuzuru natesmyth neo773 +neoto neurosnap nicholas-ochoa nicosuave @@ -220,6 +252,7 @@ nolinmcfarland nouritsu nwehg ocean6954 +ollioddi oshdubh otomn paaloeye @@ -236,11 +269,15 @@ pluiedev pouwerkerk poweruser64 prakhar54-byte +preiter93 +prihlop priyans-hu +pssalman puzza007 qappell quinnypig qwerasd205 +ragnoroct raphamorim reo101 rewdy @@ -248,39 +285,59 @@ rgehan rhodes-b rightaditya rjwittams +rkoten rmengelbrecht rmunn rockorager +ronijacobson rpfaeffle ruoyouz +ruseel sahilkmishra samasaur1 sandydoo +sanjj1 -schickling-assistant NHITL secrus seruman seyoungjeong +sghng +shorsher silveirapf +simonbcn +slowdub slsrepo +steven-tk sunshine-syz +svector-anu +svmhdvn +tacherasasi +-tangivis tasselx tbrundige tdgroot tdslot thirstycrow +-thomas-trijindev No human in the loop thoutbeckers ticclick tnagatomi +tothedarktowercame trag1c tristan957 +tsacha +tuananh turbolent tweedbeetle uhojin unphased +unsaltedscholar uzaaft vancluever +vasilmytsyk vaughanandrews -vectorpeak Stupid bot cosplaying as a maintainer +vegerot viruslobster vlsi voidnv @@ -291,6 +348,8 @@ yak3d yamshta ydah -zaviro +zenangst zenyr zeshi09 +zlitus zubb diff --git a/vendor/libghostty-vt/.github/scripts/check-apple-libghostty-vt.nu b/vendor/libghostty-vt/.github/scripts/check-apple-libghostty-vt.nu new file mode 100755 index 00000000..9b3174d6 --- /dev/null +++ b/vendor/libghostty-vt/.github/scripts/check-apple-libghostty-vt.nu @@ -0,0 +1,131 @@ +#!/usr/bin/env nu + +def fail [message: string] { + print -e $message + exit 1 +} + +def main [ + binary: path + --expect-platform: int # LC_BUILD_VERSION platform value + --expect-arch: string # Mach-O architecture name + --expect-encryption # Require LC_ENCRYPTION_INFO_64 +] { + if not ($binary | path exists) { + fail $"dylib not found: ($binary)" + } + + # Verify the dylib contains exactly the architecture requested by the build + # matrix before interpreting any target-specific Mach-O load commands. + let actual_arch = (^lipo -archs $binary | str trim) + if $actual_arch != $expect_arch { + fail $"expected architecture ($expect_arch), found ($actual_arch)" + } + + # Framework consumers load this dylib through @rpath. Keep this stable even + # though the installed file also has versioned compatibility symlinks. + let install_names = (^otool -D $binary | lines | skip 1) + if ($install_names | length) != 1 { + fail "expected exactly one dylib install name" + } + + let install_name = ($install_names | first | str trim) + if $install_name != "@rpath/libghostty-vt.dylib" { + fail $"unexpected install name: ($install_name)" + } + + let load_command_lines = (^otool -l $binary | lines) + let command_names = ( + $load_command_lines + | parse --regex '^\s*cmd\s+(?\S+)$' + | get name + ) + + # LC_BUILD_VERSION distinguishes macOS, physical iOS, and the iOS Simulator. + # Checking the numeric platform value catches an SDK or target-triple mixup. + if ($command_names | where $it == "LC_BUILD_VERSION" | length) != 1 { + fail "expected exactly one LC_BUILD_VERSION load command" + } + + let platforms = ( + $load_command_lines + | parse --regex '^\s*platform\s+(?\d+)$' + | get value + ) + if ($platforms | length) != 1 { + fail "expected exactly one LC_BUILD_VERSION platform field" + } + + let actual_platform = ($platforms | first | into int) + if $actual_platform != $expect_platform { + fail $"expected platform ($expect_platform), found ($actual_platform)" + } + + let encryption_commands = ( + $command_names + | where { str starts-with "LC_ENCRYPTION_INFO" } + ) + + if $expect_encryption { + # App Store processing requires physical iOS dylibs to reserve an + # encryption range. cryptid remains zero until Apple encrypts the binary. + if $encryption_commands != ["LC_ENCRYPTION_INFO_64"] { + fail "missing or invalid LC_ENCRYPTION_INFO_64 load command" + } + + let encryption_fields = ( + $load_command_lines + | parse --regex '^\s*(?cryptoff|cryptsize|cryptid)\s+(?\d+)$' + ) + if ($encryption_fields | length) != 3 { + fail "missing or invalid LC_ENCRYPTION_INFO_64 fields" + } + + let cryptoff = ( + $encryption_fields + | where name == "cryptoff" + | get 0.value + | into int + ) + let cryptsize = ( + $encryption_fields + | where name == "cryptsize" + | get 0.value + | into int + ) + let cryptid = ( + $encryption_fields + | where name == "cryptid" + | get 0.value + | into int + ) + if $cryptoff <= 0 or $cryptsize <= 0 or $cryptid != 0 { + fail "missing or invalid LC_ENCRYPTION_INFO_64 fields" + } + } else { + # Apple does not emit an encryption load command for macOS or Simulator + # dylibs, so its presence would indicate the wrong platform was linked. + if not ($encryption_commands | is-empty) { + fail "unexpected LC_ENCRYPTION_INFO load command" + } + } + + # nm -gjU lists defined external symbols without addresses. The export list + # passed to Apple's linker should leave only libghostty-vt's public C API. + let exports = ( + ^nm -gjU $binary + | lines + | where { not ($in | is-empty) } + ) + if ($exports | is-empty) { + fail "dylib has no exported symbols" + } + + let unexpected_exports = ( + $exports + | where { not ($in | str starts-with "_ghostty_") } + ) + if not ($unexpected_exports | is-empty) { + fail $"unexpected exported symbols:\n($unexpected_exports | str join "\n")" + } +} diff --git a/vendor/libghostty-vt/.github/workflows/clean-artifacts.yml b/vendor/libghostty-vt/.github/workflows/clean-artifacts.yml index 69cb74ae..3290693f 100644 --- a/vendor/libghostty-vt/.github/workflows/clean-artifacts.yml +++ b/vendor/libghostty-vt/.github/workflows/clean-artifacts.yml @@ -10,7 +10,7 @@ jobs: timeout-minutes: 10 steps: - name: Remove old artifacts - uses: c-hive/gha-remove-artifacts@44fc7acaf1b3d0987da0e8d4707a989d80e9554b # v1.4.0 + uses: c-hive/gha-remove-artifacts@62c2fbea931baa7dd4a6b73ea5a799984a818f61 # v1.8.0 with: age: "1 week" skip-tags: true diff --git a/vendor/libghostty-vt/.github/workflows/flatpak.yml b/vendor/libghostty-vt/.github/workflows/flatpak.yml index da1e6653..b3cbc8e3 100644 --- a/vendor/libghostty-vt/.github/workflows/flatpak.yml +++ b/vendor/libghostty-vt/.github/workflows/flatpak.yml @@ -41,7 +41,7 @@ jobs: mkdir dist tar --verbose --extract --strip-components 1 --directory dist --file ghostty-source.tar.gz - - uses: flatpak/flatpak-github-actions/flatpak-builder@401fe28a8384095fc1531b9d320b292f0ee45adb # v6.7 + - uses: flatpak/flatpak-github-actions/flatpak-builder@79327416609af08178ad73b352877e51450790b3 # v6.8 with: bundle: com.mitchellh.ghostty manifest-path: dist/flatpak/com.mitchellh.ghostty.yml diff --git a/vendor/libghostty-vt/.github/workflows/milestone.yml b/vendor/libghostty-vt/.github/workflows/milestone.yml index 34e7652a..725c6642 100644 --- a/vendor/libghostty-vt/.github/workflows/milestone.yml +++ b/vendor/libghostty-vt/.github/workflows/milestone.yml @@ -18,7 +18,7 @@ jobs: name: Milestone Update steps: - name: Set Milestone for PR - uses: hustcer/milestone-action@ebed8d5daafd855a600d7e665c1b130f06d24130 # v3.1 + uses: hustcer/milestone-action@2f38355153344ccaaa44b5b5fcff9f604dff1b45 # v3.2 if: github.event.pull_request.merged == true && !contains(github.event.pull_request.title, 'VOUCHED') && !startsWith(github.event.pull_request.title, 'ci:') with: action: bind-pr # `bind-pr` is the default action @@ -26,7 +26,7 @@ jobs: # Bind milestone to closed issue that has a merged PR fix - name: Set Milestone for Issue - uses: hustcer/milestone-action@ebed8d5daafd855a600d7e665c1b130f06d24130 # v3.1 + uses: hustcer/milestone-action@2f38355153344ccaaa44b5b5fcff9f604dff1b45 # v3.2 if: github.event.issue.state == 'closed' with: action: bind-issue diff --git a/vendor/libghostty-vt/.github/workflows/nix.yml b/vendor/libghostty-vt/.github/workflows/nix.yml index 0a3ebdc5..3b481c29 100644 --- a/vendor/libghostty-vt/.github/workflows/nix.yml +++ b/vendor/libghostty-vt/.github/workflows/nix.yml @@ -39,18 +39,18 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - name: Setup Nix - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" diff --git a/vendor/libghostty-vt/.github/workflows/publish-tag.yml b/vendor/libghostty-vt/.github/workflows/publish-tag.yml index acb1ab1f..f9e19573 100644 --- a/vendor/libghostty-vt/.github/workflows/publish-tag.yml +++ b/vendor/libghostty-vt/.github/workflows/publish-tag.yml @@ -64,7 +64,7 @@ jobs: mkdir blob mv appcast.xml blob/appcast.xml - name: Upload Appcast to R2 - uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4 + uses: ryand56/r2-upload-action@33ebb7a494b3a8a3c5ed2ea6bbdc72e707090317 # v1.5 with: r2-account-id: ${{ secrets.CF_R2_RELEASE_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.CF_R2_RELEASE_AWS_KEY }} diff --git a/vendor/libghostty-vt/.github/workflows/release-tag.yml b/vendor/libghostty-vt/.github/workflows/release-tag.yml index 3fd92990..e8fa8e45 100644 --- a/vendor/libghostty-vt/.github/workflows/release-tag.yml +++ b/vendor/libghostty-vt/.github/workflows/release-tag.yml @@ -56,7 +56,7 @@ jobs: fi - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # Important so that build number generation works fetch-depth: 0 @@ -80,20 +80,20 @@ jobs: ZIG_LOCAL_CACHE_DIR: /zig/local-cache ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -134,10 +134,10 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: cache: | xcode @@ -147,20 +147,20 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main with: determinate: true - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - name: XCode Select - run: sudo xcode-select -s /Applications/Xcode_26.3.app + run: sudo xcode-select -s /Applications/Xcode_26.6.app - name: Xcode Version run: xcodebuild -version - name: Setup Sparkle env: - SPARKLE_VERSION: 2.9.0 + SPARKLE_VERSION: 2.9.6 run: | mkdir -p .action/sparkle cd .action/sparkle @@ -319,7 +319,7 @@ jobs: GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }} steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Download macOS Artifacts uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -328,7 +328,7 @@ jobs: - name: Setup Sparkle env: - SPARKLE_VERSION: 2.9.0 + SPARKLE_VERSION: 2.9.6 run: | mkdir -p .action/sparkle cd .action/sparkle @@ -400,7 +400,7 @@ jobs: mv Ghostty.dmg blob/${GHOSTTY_VERSION}/Ghostty.dmg mv appcast.xml blob/${GHOSTTY_VERSION}/appcast-staged.xml - name: Upload to R2 - uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4 + uses: ryand56/r2-upload-action@33ebb7a494b3a8a3c5ed2ea6bbdc72e707090317 # v1.5 with: r2-account-id: ${{ secrets.CF_R2_RELEASE_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.CF_R2_RELEASE_AWS_KEY }} diff --git a/vendor/libghostty-vt/.github/workflows/release-tip.yml b/vendor/libghostty-vt/.github/workflows/release-tip.yml index 721057a1..5201a29c 100644 --- a/vendor/libghostty-vt/.github/workflows/release-tip.yml +++ b/vendor/libghostty-vt/.github/workflows/release-tip.yml @@ -33,19 +33,19 @@ jobs: commit: ${{ steps.extract_build_info.outputs.commit }} commit_long: ${{ steps.extract_build_info.outputs.commit_long }} steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # Important so that build number generation works fetch-depth: 0 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -66,7 +66,7 @@ jobs: - name: Detect changes since last tip id: changes if: github.event_name == 'workflow_run' - uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2 + uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 with: token: "" base: tip @@ -119,7 +119,7 @@ jobs: needs: [setup, build-macos] if: needs.setup.outputs.should_skip != 'true' steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Tip Tag run: | git config user.name "github-actions[bot]" @@ -134,7 +134,7 @@ jobs: env: GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }} steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install sentry-cli run: | @@ -157,7 +157,7 @@ jobs: env: GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }} steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install sentry-cli run: | @@ -180,7 +180,7 @@ jobs: env: GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }} steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install sentry-cli run: | @@ -212,17 +212,17 @@ jobs: ZIG_LOCAL_CACHE_DIR: /zig/local-cache ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -239,7 +239,7 @@ jobs: nix develop -c minisign -S -m ghostty-source.tar.gz -s minisign.key < minisign.password - name: Update Release - uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: name: 'Ghostty Tip ("Nightly")' prerelease: true @@ -267,17 +267,17 @@ jobs: ZIG_LOCAL_CACHE_DIR: /zig/local-cache ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -294,7 +294,7 @@ jobs: nix develop -c minisign -S -m libghostty-vt-source.tar.gz -s minisign.key < minisign.password - name: Update Release - uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: name: 'Ghostty Tip ("Nightly")' prerelease: true @@ -310,7 +310,7 @@ jobs: mkdir -p blob/${GHOSTTY_COMMIT_LONG} cp libghostty-vt-source.tar.gz blob/${GHOSTTY_COMMIT_LONG}/libghostty-vt-source.tar.gz - name: Upload to R2 - uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4 + uses: ryand56/r2-upload-action@33ebb7a494b3a8a3c5ed2ea6bbdc72e707090317 # v1.5 with: r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }} @@ -342,10 +342,10 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: cache: | xcode @@ -356,13 +356,13 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main with: determinate: true - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - name: Xcode Select - run: sudo xcode-select -s /Applications/Xcode_26.3.app + run: sudo xcode-select -s /Applications/Xcode_26.6.app - name: Build XCFramework run: nix develop -c zig build -Demit-lib-vt -Doptimize=ReleaseFast @@ -379,7 +379,7 @@ jobs: nix develop -c minisign -S -m ghostty-vt.xcframework.zip -s minisign.key < minisign.password - name: Update Release - uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: name: 'Ghostty Tip ("Nightly")' prerelease: true @@ -395,7 +395,7 @@ jobs: mkdir -p blob/${GHOSTTY_COMMIT_LONG} cp ghostty-vt.xcframework.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-vt.xcframework.zip - name: Upload to R2 - uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4 + uses: ryand56/r2-upload-action@33ebb7a494b3a8a3c5ed2ea6bbdc72e707090317 # v1.5 with: r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }} @@ -409,6 +409,135 @@ jobs: echo "Release URLs:" echo " XCFramework: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-vt.xcframework.zip" + build-lib-vt-wasm: + needs: [setup] + if: | + needs.setup.outputs.should_skip != 'true' && + ( + github.event_name == 'workflow_dispatch' || + ( + github.repository_owner == 'ghostty-org' && + github.ref_name == 'main' + ) + ) + runs-on: namespace-profile-ghostty-sm + env: + GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }} + ZIG_LOCAL_CACHE_DIR: /zig/local-cache + ZIG_GLOBAL_CACHE_DIR: /zig/global-cache + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 + with: + path: | + /nix + /zig + + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 + with: + nix_path: nixpkgs=channel:nixos-unstable + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 + with: + name: ghostty + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Build ReleaseFast WASM + run: | + nix develop -c zig build \ + -Demit-lib-vt \ + -Dtarget=wasm32-freestanding \ + -Doptimize=ReleaseFast + + - name: Optimize ReleaseFast WASM + run: | + nix develop -c wasm-opt -O3 --strip-dwarf \ + --enable-simd \ + --enable-bulk-memory \ + --enable-sign-ext \ + --enable-nontrapping-float-to-int \ + --enable-multivalue \ + --enable-reference-types \ + zig-out/bin/ghostty-vt.wasm \ + -o ghostty-vt.wasm + + - name: Build ReleaseSmall WASM + run: | + nix develop -c zig build \ + -Demit-lib-vt \ + -Dtarget=wasm32-freestanding \ + -Doptimize=ReleaseSmall + + - name: Optimize ReleaseSmall WASM + run: | + nix develop -c wasm-opt -O3 \ + --enable-simd \ + --enable-bulk-memory \ + --enable-sign-ext \ + --enable-nontrapping-float-to-int \ + --enable-multivalue \ + --enable-reference-types \ + zig-out/bin/ghostty-vt.wasm \ + -o ghostty-vt-small.wasm + + - name: Verify WASM simd128 + run: | + # wasm-tools names the simd128 proposal "simd". The artifact must + # fail validation when that feature is disabled. + for artifact in ghostty-vt.wasm ghostty-vt-small.wasm; do + nix develop -c wasm-tools validate "${artifact}" + if nix develop -c wasm-tools validate \ + --features=-simd "${artifact}"; then + echo "${artifact} unexpectedly validates with simd128 disabled" >&2 + exit 1 + fi + echo "Verified ${artifact} requires simd128" + done + + - name: Sign WASM + run: | + echo -n "${{ secrets.MINISIGN_KEY }}" > minisign.key + echo -n "${{ secrets.MINISIGN_PASSWORD }}" > minisign.password + nix develop -c minisign -S -m ghostty-vt.wasm -s minisign.key < minisign.password + nix develop -c minisign -S -m ghostty-vt-small.wasm -s minisign.key < minisign.password + + - name: Update Release + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 + with: + name: 'Ghostty Tip ("Nightly")' + prerelease: true + tag_name: tip + target_commitish: ${{ github.sha }} + files: | + ghostty-vt.wasm + ghostty-vt.wasm.minisig + ghostty-vt-small.wasm + ghostty-vt-small.wasm.minisig + token: ${{ secrets.GH_RELEASE_TOKEN }} + + - name: Prep R2 Storage + run: | + mkdir -p blob/${GHOSTTY_COMMIT_LONG} + cp ghostty-vt.wasm blob/${GHOSTTY_COMMIT_LONG}/ghostty-vt.wasm + cp ghostty-vt-small.wasm blob/${GHOSTTY_COMMIT_LONG}/ghostty-vt-small.wasm + - name: Upload to R2 + uses: ryand56/r2-upload-action@33ebb7a494b3a8a3c5ed2ea6bbdc72e707090317 # v1.5 + with: + r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }} + r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }} + r2-secret-access-key: ${{ secrets.CF_R2_TIP_SECRET_KEY }} + r2-bucket: ghostty-tip + source-dir: blob + destination-dir: ./ + + - name: Echo Release URLs + run: | + echo "Release URLs:" + echo " WASM (ReleaseFast): https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-vt.wasm" + echo " WASM (ReleaseSmall): https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-vt-small.wasm" + build-macos: needs: [setup] if: | @@ -431,13 +560,13 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # Important so that build number generation works fetch-depth: 0 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: cache: | xcode @@ -448,13 +577,13 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main with: determinate: true - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - name: XCode Select - run: sudo xcode-select -s /Applications/Xcode_26.3.app + run: sudo xcode-select -s /Applications/Xcode_26.6.app - name: Xcode Version run: xcodebuild -version @@ -462,7 +591,7 @@ jobs: # Setup Sparkle - name: Setup Sparkle env: - SPARKLE_VERSION: 2.9.0 + SPARKLE_VERSION: 2.9.6 run: | mkdir -p .action/sparkle cd .action/sparkle @@ -581,7 +710,7 @@ jobs: # Update Release - name: Release - uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: name: 'Ghostty Tip ("Nightly")' prerelease: true @@ -616,7 +745,7 @@ jobs: cp Ghostty.dmg blob/${GHOSTTY_COMMIT_LONG}/Ghostty.dmg - name: Upload to R2 - uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4 + uses: ryand56/r2-upload-action@33ebb7a494b3a8a3c5ed2ea6bbdc72e707090317 # v1.5 with: r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }} @@ -640,7 +769,7 @@ jobs: if: | github.repository_owner == 'ghostty-org' && github.ref_name == 'main' - uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4 + uses: ryand56/r2-upload-action@33ebb7a494b3a8a3c5ed2ea6bbdc72e707090317 # v1.5 with: r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }} @@ -659,7 +788,7 @@ jobs: EOF - name: Upload Release URLs - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v6.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: release-urls-${{ inputs.pr || '0' }} path: release-urls.txt @@ -687,13 +816,13 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # Important so that build number generation works fetch-depth: 0 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: cache: | xcode @@ -704,13 +833,13 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main with: determinate: true - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - name: XCode Select - run: sudo xcode-select -s /Applications/Xcode_26.3.app + run: sudo xcode-select -s /Applications/Xcode_26.6.app - name: Xcode Version run: xcodebuild -version @@ -718,7 +847,7 @@ jobs: # Setup Sparkle - name: Setup Sparkle env: - SPARKLE_VERSION: 2.9.0 + SPARKLE_VERSION: 2.9.6 run: | mkdir -p .action/sparkle cd .action/sparkle @@ -830,7 +959,7 @@ jobs: # Update Release - name: Release - uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: name: 'Ghostty Tip ("Nightly")' prerelease: true @@ -847,7 +976,7 @@ jobs: cp ghostty-macos-universal-debug-slow.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow.zip cp ghostty-macos-universal-debug-slow-dsym.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow-dsym.zip - name: Upload to R2 - uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4 + uses: ryand56/r2-upload-action@33ebb7a494b3a8a3c5ed2ea6bbdc72e707090317 # v1.5 with: r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }} @@ -884,13 +1013,13 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # Important so that build number generation works fetch-depth: 0 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: cache: | xcode @@ -901,13 +1030,13 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main with: determinate: true - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - name: XCode Select - run: sudo xcode-select -s /Applications/Xcode_26.3.app + run: sudo xcode-select -s /Applications/Xcode_26.6.app - name: Xcode Version run: xcodebuild -version @@ -915,7 +1044,7 @@ jobs: # Setup Sparkle - name: Setup Sparkle env: - SPARKLE_VERSION: 2.9.0 + SPARKLE_VERSION: 2.9.6 run: | mkdir -p .action/sparkle cd .action/sparkle @@ -1027,7 +1156,7 @@ jobs: # Update Release - name: Release - uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: name: 'Ghostty Tip ("Nightly")' prerelease: true @@ -1044,7 +1173,7 @@ jobs: cp ghostty-macos-universal-debug-fast.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast.zip cp ghostty-macos-universal-debug-fast-dsym.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast-dsym.zip - name: Upload to R2 - uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4 + uses: ryand56/r2-upload-action@33ebb7a494b3a8a3c5ed2ea6bbdc72e707090317 # v1.5 with: r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }} diff --git a/vendor/libghostty-vt/.github/workflows/snap.yml b/vendor/libghostty-vt/.github/workflows/snap.yml index 3108d583..1deef5d1 100644 --- a/vendor/libghostty-vt/.github/workflows/snap.yml +++ b/vendor/libghostty-vt/.github/workflows/snap.yml @@ -38,7 +38,7 @@ jobs: tar --verbose --extract --strip-components 1 --directory dist --file ghostty-source.tar.gz - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix diff --git a/vendor/libghostty-vt/.github/workflows/test.yml b/vendor/libghostty-vt/.github/workflows/test.yml index 05787c18..45d2002e 100644 --- a/vendor/libghostty-vt/.github/workflows/test.yml +++ b/vendor/libghostty-vt/.github/workflows/test.yml @@ -30,8 +30,8 @@ jobs: zig: ${{ steps.filter_any.outputs.zig }} steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 id: filter_every with: token: "" @@ -40,7 +40,7 @@ jobs: code: - '**' - '!.github/VOUCHED.td' - - uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2 + - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 id: filter_any with: token: "" @@ -86,6 +86,7 @@ jobs: - build-bench - build-dist - build-dist-lib-vt + - build-example-zig-vt-macos-no-sdk - build-examples-zig - build-examples-cmake - build-examples-cmake-windows @@ -93,6 +94,9 @@ jobs: - build-cmake - build-flatpak - build-libghostty-vt + - build-libghostty-vt-freestanding + - build-libghostty-vt-wasm + - build-libghostty-vt-features - build-libghostty-vt-android - build-libghostty-vt-macos - build-libghostty-vt-windows @@ -102,6 +106,7 @@ jobs: - build-nix # - build-nix-macos - build-macos + - build-macos-xcode-27 - build-macos-freetype - build-snap - test @@ -110,6 +115,7 @@ jobs: - test-sentry-linux - test-i18n - test-fuzz-libghostty + - test-kaitai - test-lib-vt - test-lib-vt-pkgconfig - test-macos @@ -156,20 +162,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -187,7 +193,7 @@ jobs: swift: ${{ steps.list.outputs.swift }} steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - id: list name: List example directories run: | @@ -214,20 +220,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -237,6 +243,38 @@ jobs: cd example/${{ matrix.dir }} nix develop -c zig build + build-example-zig-vt-macos-no-sdk: + name: Example zig-vt (macOS, no SDK) + runs-on: namespace-profile-ghostty-macos-tahoe + needs: test + env: + ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache + ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 + with: + cache: | + xcode + path: | + /Users/runner/zig + + # TODO(tahoe): https://github.com/NixOS/nix/issues/13342 + - uses: DeterminateSystems/nix-installer-action@main + with: + determinate: true + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 + with: + name: ghostty + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Build Example without SDK + working-directory: example/zig-vt + run: nix develop -c env DEVELOPER_DIR=/nonexistent zig build + build-examples-cmake: strategy: fail-fast: false @@ -250,20 +288,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -290,7 +328,7 @@ jobs: needs: [test, list-examples] steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install zig uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 @@ -315,10 +353,10 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: cache: | xcode @@ -329,13 +367,13 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main with: determinate: true - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - name: Xcode Select - run: sudo xcode-select -s /Applications/Xcode_26.3.app + run: sudo xcode-select -s /Applications/Xcode_26.6.app - name: Build XCFramework run: nix develop -c zig build -Demit-lib-vt @@ -356,20 +394,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -394,20 +432,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -511,20 +549,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -545,20 +583,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -581,7 +619,6 @@ jobs: x86_64-windows-gnu, # doesn't work yet, we need a way to find msvc libc/c++ headers # x86_64-windows-msvc - wasm32-freestanding, ] runs-on: namespace-profile-ghostty-sm needs: test @@ -590,20 +627,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -613,11 +650,201 @@ jobs: nix develop -c zig build -Demit-lib-vt \ -Dtarget=${{ matrix.target }} + build-libghostty-vt-freestanding: + strategy: + matrix: + include: + - target: riscv32-freestanding-eabi + cpu: baseline + - target: thumb-freestanding-eabi + cpu: cortex_m4 + runs-on: namespace-profile-ghostty-sm + needs: test + env: + ZIG_LOCAL_CACHE_DIR: /zig/local-cache + ZIG_GLOBAL_CACHE_DIR: /zig/global-cache + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 + with: + path: | + /nix + /zig + + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 + with: + nix_path: nixpkgs=channel:nixos-unstable + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 + with: + name: ghostty + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Build + run: | + nix develop -c zig build -Demit-lib-vt \ + -Dtarget=${{ matrix.target }} \ + -Dcpu=${{ matrix.cpu }} \ + -Doptimize=ReleaseSafe + + build-libghostty-vt-wasm: + runs-on: namespace-profile-ghostty-sm + needs: test + env: + ZIG_LOCAL_CACHE_DIR: /zig/local-cache + ZIG_GLOBAL_CACHE_DIR: /zig/global-cache + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 + with: + path: | + /nix + /zig + + # Install Nix and use that to run our tests so our environment matches exactly. + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 + with: + nix_path: nixpkgs=channel:nixos-unstable + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 + with: + name: ghostty + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Build ReleaseFast WASM + run: | + nix develop -c zig build \ + -Demit-lib-vt \ + -Dtarget=wasm32-freestanding \ + -Doptimize=ReleaseFast + + - name: Optimize ReleaseFast WASM + run: | + nix develop -c wasm-opt -O3 --strip-dwarf \ + --enable-simd \ + --enable-bulk-memory \ + --enable-sign-ext \ + --enable-nontrapping-float-to-int \ + --enable-multivalue \ + --enable-reference-types \ + zig-out/bin/ghostty-vt.wasm \ + -o ghostty-vt.wasm + + - name: Build ReleaseSmall WASM + run: | + nix develop -c zig build \ + -Demit-lib-vt \ + -Dtarget=wasm32-freestanding \ + -Doptimize=ReleaseSmall + + - name: Validate WASM ABI manifest + run: | + nix develop -c zig build test-lib-vt-schema \ + -Dtarget=wasm32-freestanding \ + -Doptimize=ReleaseSmall + + - name: Optimize ReleaseSmall WASM + run: | + nix develop -c wasm-opt -O3 \ + --enable-simd \ + --enable-bulk-memory \ + --enable-sign-ext \ + --enable-nontrapping-float-to-int \ + --enable-multivalue \ + --enable-reference-types \ + zig-out/bin/ghostty-vt.wasm \ + -o ghostty-vt-small.wasm + + - name: Verify WASM simd128 + run: | + # wasm-tools names the simd128 proposal "simd". The artifact must + # fail validation when that feature is disabled. + for artifact in ghostty-vt.wasm ghostty-vt-small.wasm; do + nix develop -c wasm-tools validate "${artifact}" + if nix develop -c wasm-tools validate \ + --features=-simd "${artifact}"; then + echo "${artifact} unexpectedly validates with simd128 disabled" >&2 + exit 1 + fi + echo "Verified ${artifact} requires simd128" + done + + - name: Test WASM allocator + run: | + nix develop -c node test/wasm-alloc.mjs ghostty-vt.wasm + nix develop -c node test/wasm-alloc.mjs ghostty-vt-small.wasm + + # Compile-only checks for the -Dvt-features flags so that future changes + # don't regress any feature combination. + build-libghostty-vt-features: + runs-on: namespace-profile-ghostty-sm + needs: test + env: + ZIG_LOCAL_CACHE_DIR: /zig/local-cache + ZIG_GLOBAL_CACHE_DIR: /zig/global-cache + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 + with: + path: | + /nix + /zig + + # Install Nix and use that to run our tests so our environment matches exactly. + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 + with: + nix_path: nixpkgs=channel:nixos-unstable + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 + with: + name: ghostty + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Compile feature flag matrix + run: | + features="snapshot formatter selection render_state input_encode color grid_introspection glyph_protocol kitty_graphics" + configs="-all" + for f in $features; do configs="$configs -all,+$f"; done + + for cfg in $configs; do + echo "::group::-Dvt-features=$cfg" + # The wasm lib build compiles the C API export block; the + # test build compiles every module test without running any. + nix develop -c zig build -Demit-lib-vt \ + "-Dvt-features=$cfg" \ + -Dtarget=wasm32-freestanding + nix develop -c zig build test-lib-vt-build \ + "-Dvt-features=$cfg" + echo "::endgroup::" + done + # lib-vt requires macOS runner for macOS/iOS builds because it requires the `apple_sdk` path build-libghostty-vt-macos: strategy: matrix: - target: [aarch64-macos, x86_64-macos, aarch64-ios] + include: + - target: aarch64-macos + platform: 1 + arch: arm64 + expect_encryption: false + - target: x86_64-macos + platform: 1 + arch: x86_64 + expect_encryption: false + - target: aarch64-ios + platform: 2 + arch: arm64 + expect_encryption: true + - target: aarch64-ios-simulator + platform: 7 + arch: arm64 + expect_encryption: false runs-on: namespace-profile-ghostty-macos-tahoe needs: test env: @@ -625,10 +852,10 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: cache: | xcode @@ -639,19 +866,27 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main with: determinate: true - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - name: Xcode Select - run: sudo xcode-select -s /Applications/Xcode_26.3.app + run: sudo xcode-select -s /Applications/Xcode_26.6.app - name: Build run: | nix develop -c zig build -Demit-lib-vt \ -Dtarget=${{ matrix.target }} + - name: Verify Apple dylib + run: | + nix develop -c nu .github/scripts/check-apple-libghostty-vt.nu \ + zig-out/lib/libghostty-vt.dylib \ + --expect-platform ${{ matrix.platform }} \ + --expect-arch ${{ matrix.arch }} \ + ${{ matrix.expect_encryption && '--expect-encryption' || '' }} + # lib-vt requires the Android NDK for Android builds build-libghostty-vt-android: strategy: @@ -666,20 +901,20 @@ jobs: ANDROID_NDK_VERSION: r29 steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -706,7 +941,7 @@ jobs: needs: test steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Zig uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 @@ -717,13 +952,17 @@ jobs: - name: Build libghostty-vt run: zig build -Demit-lib-vt + - name: Test static linking + working-directory: example/c-vt-static + run: zig build + build-libghostty-windows-gnu: runs-on: namespace-profile-ghostty-windows timeout-minutes: 45 needs: test steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Zig uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 @@ -743,20 +982,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -772,20 +1011,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -805,20 +1044,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -887,20 +1126,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -927,20 +1166,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -967,7 +1206,7 @@ jobs: needs: [build-dist, build-snap] steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Trigger Snap workflow run: | @@ -985,7 +1224,7 @@ jobs: needs: [build-dist, build-flatpak] steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Trigger Flatpak workflow run: | @@ -1002,13 +1241,13 @@ jobs: # needs: test # steps: # - name: Checkout code - # uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + # uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # # Install Nix and use that to run our tests so our environment matches exactly. - # - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + # - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 # with: # nix_path: nixpkgs=channel:nixos-unstable - # - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + # - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 # with: # name: ghostty # authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1057,10 +1296,10 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: cache: | xcode @@ -1071,13 +1310,13 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main with: determinate: true - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - name: Xcode Select - run: sudo xcode-select -s /Applications/Xcode_26.3.app + run: sudo xcode-select -s /Applications/Xcode_26.6.app - name: Xcode Version run: xcodebuild -version @@ -1101,13 +1340,45 @@ jobs: COMPILATION_CACHE_CAS_PATH=/Users/runner/Library/Developer/Xcode/DerivedData/CompilationCache.noindex \ COMPILATION_CACHE_KEEP_CAS_DIRECTORY=YES - # Build the iOS target without code signing just to verify it works. - - name: Build Ghostty iOS - run: | - cd macos - xcodebuild -target Ghostty-iOS "CODE_SIGNING_ALLOWED=NO" \ - COMPILATION_CACHE_CAS_PATH=/Users/runner/Library/Developer/Xcode/DerivedData/CompilationCache.noindex \ - COMPILATION_CACHE_KEEP_CAS_DIRECTORY=YES + build-macos-xcode-27: + runs-on: namespace-profile-ghostty-macos-tahoe + needs: test + env: + ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache + ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 + with: + cache: | + xcode + path: | + /Users/runner/zig + + # TODO(tahoe): https://github.com/NixOS/nix/issues/13342 + - uses: DeterminateSystems/nix-installer-action@main + with: + determinate: true + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 + with: + name: ghostty + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Xcode Select + run: sudo xcode-select -s /Applications/Xcode_27.app + + - name: Xcode Version + run: xcodebuild -version + + - name: get the Zig deps + id: deps + run: nix build -L .#deps && echo "deps=$(readlink ./result)" >> $GITHUB_OUTPUT + + - name: Build with Xcode 27 + run: nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Demit-macos-app=false build-macos-freetype: runs-on: namespace-profile-ghostty-macos-tahoe @@ -1117,10 +1388,10 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: cache: | xcode @@ -1131,13 +1402,13 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main with: determinate: true - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - name: Xcode Select - run: sudo xcode-select -s /Applications/Xcode_26.3.app + run: sudo xcode-select -s /Applications/Xcode_26.6.app - name: Xcode Version run: xcodebuild -version @@ -1167,7 +1438,7 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Get required Zig version id: zig @@ -1175,17 +1446,17 @@ jobs: echo "version=$(sed -n -E 's/^\s*\.?minimum_zig_version\s*=\s*"([^"]+)".*/\1/p' build.zig.zon)" >> $GITHUB_OUTPUT - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1196,9 +1467,29 @@ jobs: - name: Test GTK Build run: nix develop -c zig build -Dapp-runtime=gtk -Demit-docs -Demit-webdata - # This relies on the cache being populated by the commands above. + # NOTE: This used to point to the Zig global cache directory before + # 0.16.0. Now, the cache directory exclusively stores "minified" + # archives of each dependency (i.e., only the paths defined in + # build.zig.zon), and an uncompressed, working copy is stored in + # PROJECT_ROOT/zig-pkg. The zig-pkg directory is warmed up during the + # regular fetching process from the global cache directory if + # possible. + # + # Nothing else should change; zon2nix's store path mimics what a + # zig-pkg directory should look like, so actual build steps should be + # fine, it's just here where we assume that all dependencies have been + # downloaded, and we want to test the validity of the package + # directory, do we need to have it pointing to zig-pkg and not the + # zon2nix store path. + # + # Note that this can also be attempted by running: + # zig build --fetch=needed + # + # Note that --system PKGDIR should not be added to this invocation as + # it disables fetching altogether (even, seemingly, from the local + # cache). - name: Test System Build - run: nix develop -c zig build --system ${ZIG_GLOBAL_CACHE_DIR}/p + run: nix develop -c zig build --system "$(realpath zig-pkg)" test-lib-vt: if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true' @@ -1209,20 +1500,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1230,6 +1521,34 @@ jobs: - name: Test run: nix develop -c zig build test-lib-vt + - name: Validate native ABI manifest + run: nix develop -c zig build test-lib-vt-schema + + test-kaitai: + if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true' + needs: skip + runs-on: namespace-profile-ghostty-xsm + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 + with: + path: /nix + + # Install Nix so the verifier uses the pinned compiler and runtimes. + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 + with: + nix_path: nixpkgs=channel:nixos-unstable + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 + with: + name: ghostty + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Verify Snapshot Kaitai Schema + run: nix develop -c src/terminal/snapshot/verify-kaitai.py + test-gtk: strategy: fail-fast: false @@ -1244,20 +1563,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1292,20 +1611,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1327,20 +1646,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1357,10 +1676,10 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: cache: | xcode @@ -1371,13 +1690,13 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main with: determinate: true - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - name: Xcode Select - run: sudo xcode-select -s /Applications/Xcode_26.3.app + run: sudo xcode-select -s /Applications/Xcode_26.6.app - name: Xcode Version run: xcodebuild -version @@ -1396,7 +1715,7 @@ jobs: timeout-minutes: 45 steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Zig uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 @@ -1417,20 +1736,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1448,20 +1767,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1493,17 +1812,17 @@ jobs: ZIG_LOCAL_CACHE_DIR: /zig/local-cache ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1524,17 +1843,17 @@ jobs: ZIG_LOCAL_CACHE_DIR: /zig/local-cache ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1554,17 +1873,17 @@ jobs: ZIG_LOCAL_CACHE_DIR: /zig/local-cache ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1579,10 +1898,10 @@ jobs: needs: skip timeout-minutes: 60 steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: cache: | xcode @@ -1593,7 +1912,7 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main with: determinate: true - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1612,17 +1931,17 @@ jobs: ZIG_LOCAL_CACHE_DIR: /zig/local-cache ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1640,17 +1959,17 @@ jobs: ZIG_LOCAL_CACHE_DIR: /zig/local-cache ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1668,17 +1987,17 @@ jobs: ZIG_LOCAL_CACHE_DIR: /zig/local-cache ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1701,17 +2020,17 @@ jobs: ZIG_LOCAL_CACHE_DIR: /zig/local-cache ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1729,17 +2048,17 @@ jobs: ZIG_LOCAL_CACHE_DIR: /zig/local-cache ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1763,20 +2082,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1825,20 +2144,20 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig # Install Nix and use that to run our tests so our environment matches exactly. - - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -1864,7 +2183,7 @@ jobs: # timeout-minutes: 10 # steps: # - name: Checkout Ghostty - # uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + # uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # # - name: Start SSH # run: | diff --git a/vendor/libghostty-vt/.github/workflows/update-colorschemes.yml b/vendor/libghostty-vt/.github/workflows/update-colorschemes.yml index 911768e5..dfdd58ab 100644 --- a/vendor/libghostty-vt/.github/workflows/update-colorschemes.yml +++ b/vendor/libghostty-vt/.github/workflows/update-colorschemes.yml @@ -17,22 +17,22 @@ jobs: ZIG_GLOBAL_CACHE_DIR: /zig/global-cache steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup Cache - uses: namespacelabs/nscloud-cache-action@58bf6e08898e88803c098e2b522668541cd3b2e3 # v1.6.0 + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 with: path: | /nix /zig - name: Setup Nix - uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7 + uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 with: name: ghostty authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" @@ -52,7 +52,7 @@ jobs: echo "filename=$FILENAME" >> $GITHUB_OUTPUT - name: Upload to R2 - uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4 + uses: ryand56/r2-upload-action@33ebb7a494b3a8a3c5ed2ea6bbdc72e707090317 # v1.5 with: r2-account-id: ${{ secrets.CF_R2_DEPS_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.CF_R2_DEPS_AWS_KEY }} diff --git a/vendor/libghostty-vt/.github/workflows/vouch-check-issue.yml b/vendor/libghostty-vt/.github/workflows/vouch-check-issue.yml index fb36bf88..b096a600 100644 --- a/vendor/libghostty-vt/.github/workflows/vouch-check-issue.yml +++ b/vendor/libghostty-vt/.github/workflows/vouch-check-issue.yml @@ -14,11 +14,11 @@ jobs: app-id: ${{ secrets.VOUCH_APP_ID }} private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }} - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: sparse-checkout: .github/issue-unvouched-message - - uses: mitchellh/vouch/action/check-issue@d66fa29a64600490892131ad87597c30c91fcac4 # unreleased main + - uses: mitchellh/vouch/action/check-issue@d66fa29a64600490892131ad87597c30c91fcac4 # v1.5.0 with: issue-number: ${{ github.event.issue.number }} auto-close: true diff --git a/vendor/libghostty-vt/.github/workflows/vouch-manage-by-discussion.yml b/vendor/libghostty-vt/.github/workflows/vouch-manage-by-discussion.yml index ec46fa26..c5c5abaf 100644 --- a/vendor/libghostty-vt/.github/workflows/vouch-manage-by-discussion.yml +++ b/vendor/libghostty-vt/.github/workflows/vouch-manage-by-discussion.yml @@ -18,7 +18,7 @@ jobs: app-id: ${{ secrets.VOUCH_APP_ID }} private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }} - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: token: ${{ steps.app-token.outputs.token }} diff --git a/vendor/libghostty-vt/.github/workflows/vouch-manage-by-issue.yml b/vendor/libghostty-vt/.github/workflows/vouch-manage-by-issue.yml index 631adcea..de0c0bfd 100644 --- a/vendor/libghostty-vt/.github/workflows/vouch-manage-by-issue.yml +++ b/vendor/libghostty-vt/.github/workflows/vouch-manage-by-issue.yml @@ -18,7 +18,7 @@ jobs: app-id: ${{ secrets.VOUCH_APP_ID }} private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }} - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: token: ${{ steps.app-token.outputs.token }} diff --git a/vendor/libghostty-vt/.github/workflows/vouch-sync-codeowners.yml b/vendor/libghostty-vt/.github/workflows/vouch-sync-codeowners.yml index b031f29f..311550a5 100644 --- a/vendor/libghostty-vt/.github/workflows/vouch-sync-codeowners.yml +++ b/vendor/libghostty-vt/.github/workflows/vouch-sync-codeowners.yml @@ -19,7 +19,7 @@ jobs: app-id: ${{ secrets.VOUCH_APP_ID }} private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }} - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: token: ${{ steps.app-token.outputs.token }} diff --git a/vendor/libghostty-vt/.gitignore b/vendor/libghostty-vt/.gitignore index 699ac9a5..bf57717b 100644 --- a/vendor/libghostty-vt/.gitignore +++ b/vendor/libghostty-vt/.gitignore @@ -9,11 +9,13 @@ .flatpak-builder/ zig-cache/ .zig-cache/ +zig-pkg/ zig-out/ +zig-pkg/ build-cmake/ CMakeCache.txt CMakeFiles/ -/build.zig.zon.bak +build.zig.zon.bak /result* /.nixos-test-history example/*.wasm @@ -29,3 +31,4 @@ glad.zip vgcore.* +/sprite_face_test* diff --git a/vendor/libghostty-vt/CODEOWNERS b/vendor/libghostty-vt/CODEOWNERS index ed121731..4fc08bc5 100644 --- a/vendor/libghostty-vt/CODEOWNERS +++ b/vendor/libghostty-vt/CODEOWNERS @@ -168,6 +168,7 @@ /po/be.po @ghostty-org/be_BY /po/bg.po @ghostty-org/bg_BG /po/ca.po @ghostty-org/ca_ES +/po/da.po @ghostty-org/da_DK /po/de.po @ghostty-org/de_DE /po/es_AR.po @ghostty-org/es_AR /po/es_BO.po @ghostty-org/es_BO @@ -191,6 +192,8 @@ /po/pl.po @ghostty-org/pl_PL /po/pt_BR.po @ghostty-org/pt_BR /po/ru.po @ghostty-org/ru_RU +/po/sr.po @ghostty-org/sr_RS +/po/sr@latin.po @ghostty-org/sr_RS /po/tr.po @ghostty-org/tr_TR /po/uk.po @ghostty-org/uk_UA /po/vi.po @ghostty-org/vi_VN diff --git a/vendor/libghostty-vt/Doxyfile b/vendor/libghostty-vt/Doxyfile index 1703e6fa..77eeb3d3 100644 --- a/vendor/libghostty-vt/Doxyfile +++ b/vendor/libghostty-vt/Doxyfile @@ -57,7 +57,8 @@ GENERATE_HTML = YES HTML_OUTPUT = zig-out/share/ghostty/doc/libghostty HTML_EXTRA_STYLESHEET = dist/doxygen/ghostty.css HTML_EXTRA_FILES = dist/doxygen/favicon.png \ - dist/doxygen/mobile-nav.js + dist/doxygen/mobile-nav.js \ + src/terminal/c/types.schema.json HTML_COLORSTYLE = DARK HTML_CODE_FOLDING = NO HTML_HEADER = dist/doxygen/header.html diff --git a/vendor/libghostty-vt/HACKING.md b/vendor/libghostty-vt/HACKING.md index 8a3c22f7..ed9c8459 100644 --- a/vendor/libghostty-vt/HACKING.md +++ b/vendor/libghostty-vt/HACKING.md @@ -40,17 +40,17 @@ here: ## Extra Dependencies +### Linux + Building Ghostty from a Git checkout on Linux requires some additional dependencies: - `blueprint-compiler` (version 0.16.0 or newer) -macOS users don't require any additional dependencies. - -## Xcode Version and SDKs +### macOS Building the Ghostty macOS app requires that Xcode, the macOS SDK, -the iOS SDK, and Metal Toolchain are all installed. +and Metal Toolchain are all installed. A common issue is that the incorrect version of Xcode is either installed or selected. Use the `xcode-select` command to @@ -67,14 +67,6 @@ sudo xcode-select --switch /Applications/Xcode.app > You do not need to be running on macOS 26 to build Ghostty, you can > still use Xcode 26 on macOS 15 stable. -> [!WARNING] -> -> Zig 0.15.x has a [known linking issue](https://codeberg.org/ziglang/zig/issues/31658) -> with **Xcode 26.4**. If you are on Xcode 26.4, you must use a -> Homebrew-installed Zig (`brew install zig@0.15`) or our Nix flake, -> both of which contain a patch that works around the issue. Alternatively, -> you can downgrade to **Xcode 26.3**. - ## AI and Agents If you're using AI assistance with Ghostty, Ghostty provides an diff --git a/vendor/libghostty-vt/PACKAGING.md b/vendor/libghostty-vt/PACKAGING.md index 1483b859..8cb42251 100644 --- a/vendor/libghostty-vt/PACKAGING.md +++ b/vendor/libghostty-vt/PACKAGING.md @@ -122,3 +122,56 @@ relevant to package maintainers: often necessary for system packages to specify a specific minimum Linux version, glibc, etc. Run `zig targets` to a get a full list of available targets. + +## WebAssembly (libghostty-vt) + +libghostty-vt can be built for WebAssembly for use in browsers and other +wasm runtimes: + +```sh +zig build -Demit-lib-vt -Dtarget=wasm32-freestanding -Doptimize=ReleaseSmall +``` + +This produces `zig-out/bin/ghostty-vt.wasm`. + +Some notes for packaging the wasm module: + +- The build enables the `simd128` feature by default. Every browser engine + has supported it for years (Chrome 91, Firefox 89, Safari 16.4) and it is + a large performance win for VT parsing. If you target an unusual runtime + without SIMD support, opt out with `-Dcpu=generic`. + +- Optional feature areas can be compiled out with `-Dvt-features` to + significantly reduce binary size. The flag takes comma-separated + modifications applied to the default all-enabled feature set, + `-Dcpu`-style: `+feature` (or bare `feature`) enables, `-feature` + disables, and the special name `all` refers to every feature. Hyphens + and underscores are interchangeable in feature names. For example, a + read-only terminal viewer only needs the render state API: + + ```sh + zig build -Demit-lib-vt -Dtarget=wasm32-freestanding \ + -Doptimize=ReleaseSmall -Dvt-features=-all,+render-state + ``` + + This roughly halves the compressed module size versus the default + build. An interactive terminal typically wants + `-Dvt-features=-all,+render-state,+input-encode,+selection,+color`. + Disabled features drop both their C API exports and any escape + sequence handling (the sequences are still consumed and safely + ignored). See the `Features` struct in `src/terminal/build_options.zig` + for the full list of features and what each one covers. + +- `ReleaseSmall` is the recommended optimization mode for the web. Running + the result through [Binaryen's](https://github.com/WebAssembly/binaryen) + `wasm-opt -O3` shrinks it by roughly a further 10% without hurting + performance. + +- `ReleaseFast` measures 10-20% faster than `ReleaseSmall` on escape-heavy + terminal workloads, but the artifact is dominated by DWARF debug info. + If you want the speed, strip it: `wasm-opt -O3 --strip-dwarf` reduces a + ReleaseFast build from over 5MB to roughly 1.1MB (versus roughly 0.8MB + for ReleaseSmall). When invoking `wasm-opt`, pass the feature flags for + what the module uses, e.g. `--enable-simd --enable-bulk-memory +--enable-sign-ext --enable-nontrapping-float-to-int --enable-multivalue +--enable-reference-types`. diff --git a/vendor/libghostty-vt/VERSION b/vendor/libghostty-vt/VERSION index 0b50d7c6..56aeaf37 100644 --- a/vendor/libghostty-vt/VERSION +++ b/vendor/libghostty-vt/VERSION @@ -1 +1 @@ -1.3.2-HEAD-+c5a21edfc \ No newline at end of file +1.3.2-HEAD-+44f2a44df \ No newline at end of file diff --git a/vendor/libghostty-vt/build.zig b/vendor/libghostty-vt/build.zig index 8ef7701e..5204b3d8 100644 --- a/vendor/libghostty-vt/build.zig +++ b/vendor/libghostty-vt/build.zig @@ -25,9 +25,10 @@ pub fn build(b: *std.Build) !void { // use that as the version source of truth. Otherwise we fall back // to what is in the build.zig.zon. const file_version: ?[]const u8 = if (b.build_root.handle.readFileAlloc( - b.allocator, + b.graph.io, "VERSION", - 128, + b.allocator, + .limited(128), )) |content| std.mem.trim( u8, content, @@ -68,6 +69,14 @@ pub fn build(b: *std.Build) !void { "test-lib-vt", "Run libghostty-vt tests", ); + const test_lib_vt_build_step = b.step( + "test-lib-vt-build", + "Build libghostty-vt tests without running them (compile check)", + ); + const test_lib_vt_schema_step = b.step( + "test-lib-vt-schema", + "Validate the libghostty-vt ABI type manifest", + ); const test_valgrind_step = b.step( "test-valgrind", "Run tests under valgrind", @@ -100,8 +109,10 @@ pub fn build(b: *std.Build) !void { if (config.emit_webdata) webdata.install(); // Ghostty bench tools - const bench = try buildpkg.GhosttyBench.init(b, &deps); - if (config.emit_bench) bench.install(); + if (config.emit_bench) { + const bench = try buildpkg.GhosttyBench.init(b, &deps); + bench.install(); + } // Ghostty dist tarball const dist = try buildpkg.GhosttyDist.init(b, &config); @@ -114,20 +125,36 @@ pub fn build(b: *std.Build) !void { } // libghostty-vt - const libghostty_vt_shared = shared: { + const native_freestanding = config.target.result.os.tag == .freestanding and + !config.target.result.cpu.arch.isWasm(); + const libghostty_vt_shared: ?buildpkg.GhosttyLibVt = shared: { if (config.target.result.cpu.arch.isWasm()) { break :shared try buildpkg.GhosttyLibVt.initWasm( b, &mod, ); } + if (native_freestanding) break :shared null; break :shared try buildpkg.GhosttyLibVt.initShared( b, &mod, ); }; - libghostty_vt_shared.install(b.getInstallStep()); + if (libghostty_vt_shared) |shared| { + shared.install(b.getInstallStep()); + + const type_schema_test = b.addSystemCommand(&.{"python3"}); + type_schema_test.addFileArg(b.path("src/terminal/c/types-schema-verify.py")); + type_schema_test.addFileArg(b.path("src/terminal/c/types.schema.json")); + type_schema_test.addFileArg(shared.output); + test_lib_vt_schema_step.dependOn(&type_schema_test.step); + } else { + try test_lib_vt_schema_step.addError( + "cannot execute the ABI manifest for a native freestanding target", + .{}, + ); + } // libghostty-vt static lib const libghostty_vt_static = try buildpkg.GhosttyLibVt.initStatic( @@ -150,6 +177,15 @@ pub fn build(b: *std.Build) !void { libghostty_vt_static.output, static_lib_name, ).step); + + if (native_freestanding) { + b.getInstallStep().dependOn(&b.addInstallDirectory(.{ + .source_dir = b.path("include/ghostty"), + .install_dir = .header, + .install_subdir = "ghostty", + .include_extensions = &.{".h"}, + }).step); + } } // libghostty-vt xcframework (Apple only, universal binary). @@ -298,7 +334,7 @@ pub fn build(b: *std.Build) !void { // We need to rebuild Ghostty with a baseline CPU target. const valgrind_exe = exe: { var valgrind_config = config; - valgrind_config.target = valgrind_config.baselineTarget(); + valgrind_config.target = valgrind_config.baselineTarget(b.graph.io); break :exe try buildpkg.GhosttyExe.init( b, &valgrind_config, @@ -309,6 +345,7 @@ pub fn build(b: *std.Build) !void { const run_cmd = b.addSystemCommand(&.{ "valgrind", "--leak-check=full", + "--error-exitcode=1", "--num-callers=50", b.fmt("--suppressions={s}", .{b.pathFromRoot("valgrind.supp")}), "--gen-suppressions=all", @@ -326,6 +363,7 @@ pub fn build(b: *std.Build) !void { }); const mod_vt_test_run = b.addRunArtifact(mod_vt_test); test_lib_vt_step.dependOn(&mod_vt_test_run.step); + test_lib_vt_build_step.dependOn(&mod_vt_test.step); const mod_vt_c_test = b.addTest(.{ .root_module = mod.vt_c, @@ -333,6 +371,7 @@ pub fn build(b: *std.Build) !void { }); const mod_vt_c_test_run = b.addRunArtifact(mod_vt_c_test); test_lib_vt_step.dependOn(&mod_vt_c_test_run.step); + test_lib_vt_build_step.dependOn(&mod_vt_c_test.step); } // Tests (skip when building libghostty-vt) @@ -343,7 +382,7 @@ pub fn build(b: *std.Build) !void { .filters = test_filters, .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), - .target = config.baselineTarget(), + .target = config.baselineTarget(b.graph.io), .optimize = .Debug, .strip = false, .omit_frame_pointer = false, @@ -352,19 +391,18 @@ pub fn build(b: *std.Build) !void { // Crash on x86_64 without this .use_llvm = true, }); - if (config.emit_test_exe) b.installArtifact(test_exe); + if (config.emit_test_exe) { + const test_exe_install = b.addInstallArtifact(test_exe, .{}); + config.addPatchElf(test_exe, &test_exe_install.step); + test_step.dependOn(&test_exe_install.step); + } _ = try deps.add(test_exe); - // Verify our internal libghostty header. - const ghostty_h = b.addTranslateC(.{ - .root_source_file = b.path("include/ghostty.h"), - .target = config.baselineTarget(), - .optimize = .Debug, - }); - test_exe.root_module.addImport("ghostty.h", ghostty_h.createModule()); + addGhosttyH(b, test_exe.root_module, config.baselineTarget(b.graph.io), .Debug); // Normal test running const test_run = b.addRunArtifact(test_exe); + config.addPatchElf(test_exe, &test_run.step); test_step.dependOn(&test_run.step); // Normal tests always test our libghostty modules @@ -374,11 +412,13 @@ pub fn build(b: *std.Build) !void { const valgrind_run = b.addSystemCommand(&.{ "valgrind", "--leak-check=full", + "--error-exitcode=1", "--num-callers=50", b.fmt("--suppressions={s}", .{b.pathFromRoot("valgrind.supp")}), "--gen-suppressions=all", }); valgrind_run.addArtifactArg(test_exe); + config.addPatchElf(test_exe, &valgrind_run.step); test_valgrind_step.dependOn(&valgrind_run.step); } @@ -390,3 +430,28 @@ pub fn build(b: *std.Build) !void { try translations_step.addError("cannot update translations when i18n is disabled", .{}); } } + +fn addGhosttyH( + b: *std.Build, + module: *std.Build.Module, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, +) void { + const translate_c = b.lazyImport(@This(), "translate_c") orelse return; + const translate_c_dep = b.lazyDependency("translate_c", .{}) orelse return; + + const translated: translate_c.Translator = .init(translate_c_dep, .{ + .c_source_file = b.addWriteFiles().add( + "hb_c.h", + \\#include + , + ), + .target = target, + .optimize = optimize, + .link_libc = true, + }); + + translated.addSystemIncludePath(b.path("include")); + + module.addImport("ghostty.h", translated.mod); +} diff --git a/vendor/libghostty-vt/build.zig.zon b/vendor/libghostty-vt/build.zig.zon index 7925f0d5..1c299c4b 100644 --- a/vendor/libghostty-vt/build.zig.zon +++ b/vendor/libghostty-vt/build.zig.zon @@ -3,62 +3,71 @@ .version = "1.3.2-dev", .paths = .{""}, .fingerprint = 0x64407a2a0b4147e5, - .minimum_zig_version = "0.15.2", + .minimum_zig_version = "0.16.0", .dependencies = .{ - // Zig libs + // External translate-c + // NOTE: We might not need to keep this around forever, but we need it + // for at least the 0.16.0 release cycle since we need fixes in + // Aro/translate-c itself. + .translate_c = .{ + .lazy = true, + .url = "https://codeberg.org/vancluever/translate-c/archive/4e879eb8aba615de112eabd1231ea6e01920cead.tar.gz", + .hash = "translate_c-0.0.0-Q_BUWhVNBwDOEcIqub4VFPJPB6D9dgwzUMHTX5KWr8Xr", + }, + // Zig libs .libxev = .{ // mitchellh/libxev - .url = "https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz", - .hash = "libxev-0.0.0-86vtc4IcEwCqEYxEYoN_3KXmc6A9VLcm22aVImfvecYs", + .url = "https://deps.files.ghostty.org/libxev-9ce8e8e6ff89e583258a7f8e7adeeeaeae8611bf.tar.gz", + .hash = "libxev-0.0.0-86vtcwIRFADbH4hk-EjROXxlrKIRPQdA41XiTSytYO-F", .lazy = true, }, .vaxis = .{ // rockorager/libvaxis - .url = "https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz", - .hash = "vaxis-0.5.1-BWNV_LosCQAGmCCNOLljCIw6j6-yt53tji6n6rwJ2BhS", + .url = "https://deps.files.ghostty.org/vaxis-1dbbe575dff4586fe51e3217aa5c3fecdcbb6089.tar.gz", + .hash = "vaxis-0.6.0-BWNV_CrbCQCscGpzsAlR402rYQ_tV3aAl081c2iRRkka", .lazy = true, }, .z2d = .{ // vancluever/z2d - .url = "https://deps.files.ghostty.org/z2d-0.10.0-j5P_Hu-6FgBsZNgwphIqh17jDnj8_yPtD8yzjO6PpHRQ.tar.gz", - .hash = "z2d-0.10.0-j5P_Hu-6FgBsZNgwphIqh17jDnj8_yPtD8yzjO6PpHRQ", + .url = "https://deps.files.ghostty.org/z2d-7dbae85c81784dba9988320bf9543ed9a81350c8.tar.gz", + .hash = "z2d-0.12.1-j5P_Hsw8EQAKyZTQICCQnAH2xYkLDW8k9uefbsYdfPZ-", .lazy = true, }, .zig_objc = .{ // mitchellh/zig-objc - .url = "https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz", - .hash = "zig_objc-0.0.0-Ir_Sp5gTAQCvxxR7oVIrPXxXwsfKgVP7_wqoOQrZjFeK", + .url = "https://deps.files.ghostty.org/zig_objc-c8de82ff80281215ad92900866dab7103a8efa8b.tar.gz", + .hash = "zig_objc-0.0.0-Ir_Sp9gsAQCPAJc0oF5xoWePHWP6Y6tCphDeyNUThJoi", .lazy = true, }, .zig_js = .{ // mitchellh/zig-js - .url = "https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz", - .hash = "zig_js-0.0.0-rjCAV-6GAADxFug7rDmPH-uM_XcnJ5NmuAMJCAscMjhi", + .url = "https://deps.files.ghostty.org/zig_js-3c23860e47fdcdc5af805efb7fd0bdac5fd3e9bc.tar.gz", + .hash = "zig_js-0.0.0-rjCAV7-GAADvMTBL7lPMuvDk7xgS9PCMIZWiOUXLZSlj", .lazy = true, }, .uucode = .{ // jacobsandlund/uucode - .url = "https://deps.files.ghostty.org/uucode-0.2.0-ZZjBPqZVVABQepOqZHR7vV_NcaN-wats0IB6o-Exj6m9.tar.gz", - .hash = "uucode-0.2.0-ZZjBPqZVVABQepOqZHR7vV_NcaN-wats0IB6o-Exj6m9", + .url = "https://deps.files.ghostty.org/uucode-2826a37a4562284fdacd8fa029d49509cc9bffcd.tar.gz", + .hash = "uucode-0.2.0-ZZjBPlK5VADj7fdoq7G8LIHzD5o6FSkcBXXrRWr4jnrA", }, .zig_wayland = .{ // codeberg ifreund/zig-wayland - .url = "https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz", - .hash = "wayland-0.5.0-dev-lQa1khrMAQDJDwYFKpdH3HizherB7sHo5dKMECfvxQHe", + .url = "https://deps.files.ghostty.org/wayland-0.6.0-lQa1kqz8AQADQmdNJsNhLoNHcnEGEUjrOaPV-dtEnEmX.tar.gz", + .hash = "wayland-0.6.0-lQa1kqz8AQADQmdNJsNhLoNHcnEGEUjrOaPV-dtEnEmX", .lazy = true, }, .zf = .{ // natecraddock/zf - .url = "https://deps.files.ghostty.org/zf-3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz", - .hash = "zf-0.10.3-OIRy8RuJAACKA3Lohoumrt85nRbHwbpMcUaLES8vxDnh", + .url = "https://deps.files.ghostty.org/zf-c35c421f84895193246db06c40683c1a30e616ef.tar.gz", + .hash = "zf-0.11.0-OIRy8X-RAAAwaRXHMYpj2uvBnuGTZWEE_3V7acqHQNtW", .lazy = true, }, .gobject = .{ // https://github.com/ghostty-org/zig-gobject based on zig_gobject // Temporary until we generate them at build time automatically. - .url = "https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst", - .hash = "gobject-0.3.0-Skun7ANLnwDvEfIpVmohcppXgOvg_I6YOJFmPIsKfXk-", + .url = "https://deps.files.ghostty.org/gobject-2026-07-28-36-1.tar.zst", + .hash = "gobject-0.3.2-Skun7F6HogCMynX2JqeSHS7xr-8pK4ob-qRFIcEasVi3", .lazy = true, }, @@ -90,7 +99,7 @@ .lazy = true, }, .wayland_protocols = .{ - .url = "https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/1.47/wayland-protocols-1.47.tar.gz", + .url = "https://deps.files.ghostty.org/N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA.tar.gz", .hash = "N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA", .lazy = true, }, @@ -116,8 +125,8 @@ .apple_sdk = .{ .path = "./pkg/apple-sdk" }, .android_ndk = .{ .path = "./pkg/android-ndk" }, .iterm2_themes = .{ - .url = "https://deps.files.ghostty.org/ghostty-themes-release-20260629-161812-8c97c3c.tgz", - .hash = "N-V-__8AAAYpBACKY0n8sQbPfzY47xFRRtjXiF766UVF5ZyD", + .url = "https://deps.files.ghostty.org/ghostty-themes-release-20260831-151010-752a9c0.tgz", + .hash = "N-V-__8AAEFmBABuDGOKxAI6VMg41b9euMZ-z7HS9EcUdaor", .lazy = true, }, }, diff --git a/vendor/libghostty-vt/build.zig.zon.json b/vendor/libghostty-vt/build.zig.zon.json index 63d5fd61..4b206b2f 100644 --- a/vendor/libghostty-vt/build.zig.zon.json +++ b/vendor/libghostty-vt/build.zig.zon.json @@ -1,4 +1,9 @@ { + "aro-0.0.0-JSD1Qk6lNgDdcDV4Vh7Sfy-34m2TluIVOdPzMmj_0BjX": { + "name": "aro", + "url": "https://github.com/vancluever/arocc/archive/f97cdfc3779aec4b242299e2fc9a1c828c3547c6.tar.gz", + "hash": "sha256-G/NNgk7KhJSLdy17ip1igIzpYhAUlzO7ef8r3/iCv/s=" + }, "N-V-__8AANT61wB--nJ95Gj_ctmzAtcjloZ__hRqNw5lC1Kr": { "name": "bindings", "url": "https://deps.files.ghostty.org/DearBindings_v0.17_ImGui_v1.92.5-docking.tar.gz", @@ -9,10 +14,10 @@ "url": "https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz", "hash": "sha256-bMqYlD0amQdmzvYQd8Ca/1k4Bj/heh7+EijlQSttatk=" }, - "N-V-__8AAIrfdwARSa-zMmxWwFuwpXf1T3asIN7s5jqi9c1v": { + "N-V-__8AAOgqbADacob-q2_DMQlmgaG4xKHRuW-6PJ4oJzMZ": { "name": "fontconfig", - "url": "https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz", - "hash": "sha256-O6LdkhWHGKzsXKrxpxYEO1qgVcJ7CB2RSvPMtA3OilU=" + "url": "https://gitlab.freedesktop.org/api/v4/projects/890/packages/generic/fontconfig/2.18.3/fontconfig-2.18.3.tar.xz", + "hash": "sha256-T3tVSjjN94wDP2ZsiHHzdJ4UoJT2Wgf2MMke0LQ9NeM=" }, "N-V-__8AAKLKpwC4H27Ps_0iL3bPkQb-z6ZVSrB-x_3EEkub": { "name": "freetype", @@ -29,10 +34,10 @@ "url": "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz", "hash": "sha256-FKLtu1Ccs+UamlPj9eQ12/WXFgS0uDPmPmB26MCpl7U=" }, - "gobject-0.3.0-Skun7ANLnwDvEfIpVmohcppXgOvg_I6YOJFmPIsKfXk-": { + "gobject-0.3.2-Skun7F6HogCMynX2JqeSHS7xr-8pK4ob-qRFIcEasVi3": { "name": "gobject", - "url": "https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst", - "hash": "sha256-OxS9/XC5aMJj1KhOcFP1ZZN7PI4ADw4f7ocx6V64mOc=" + "url": "https://deps.files.ghostty.org/gobject-2026-07-28-36-1.tar.zst", + "hash": "sha256-dyCfm2XjiAk30zccjD6AgKFBdE7IRsJuoqnscfvnWSQ=" }, "N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr": { "name": "gtk4_layer_shell", @@ -51,13 +56,13 @@ }, "N-V-__8AAEbOfQBnvcFcCX2W5z7tDaN8vaNZGamEQtNOe0UI": { "name": "imgui", - "url": "https://github.com/ocornut/imgui/archive/refs/tags/v1.92.5-docking.tar.gz", + "url": "https://deps.files.ghostty.org/N-V-__8AAEbOfQBnvcFcCX2W5z7tDaN8vaNZGamEQtNOe0UI.tar.gz", "hash": "sha256-yBbCDox18+Fa6Gc1DnmSVQLRpqhZOLsac7iSfl8x+cs=" }, - "N-V-__8AAAYpBACKY0n8sQbPfzY47xFRRtjXiF766UVF5ZyD": { + "N-V-__8AAEFmBABuDGOKxAI6VMg41b9euMZ-z7HS9EcUdaor": { "name": "iterm2_themes", - "url": "https://deps.files.ghostty.org/ghostty-themes-release-20260629-161812-8c97c3c.tgz", - "hash": "sha256-quMCPsbVIeLqzIV2okjRDZTKxA6YdkUSYuxmBHf3xMg=" + "url": "https://deps.files.ghostty.org/ghostty-themes-release-20260831-151010-752a9c0.tgz", + "hash": "sha256-g2U+uDe661v8fVDJG31EdyeW4IwcJDE04Rxe32yNFcU=" }, "N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x": { "name": "jetbrains_mono", @@ -69,10 +74,10 @@ "url": "https://deps.files.ghostty.org/libpng-1220aa013f0c83da3fb64ea6d327f9173fa008d10e28bc9349eac3463457723b1c66.tar.gz", "hash": "sha256-/syVtGzwXo4/yKQUdQ4LparQDYnp/fF16U/wQcrxoDo=" }, - "libxev-0.0.0-86vtc4IcEwCqEYxEYoN_3KXmc6A9VLcm22aVImfvecYs": { + "libxev-0.0.0-86vtcwIRFADbH4hk-EjROXxlrKIRPQdA41XiTSytYO-F": { "name": "libxev", - "url": "https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz", - "hash": "sha256-1B9oJExVyOWRj+Y9d9eHkOBTlOYuEkcwGBUKdlgRhkg=" + "url": "https://deps.files.ghostty.org/libxev-9ce8e8e6ff89e583258a7f8e7adeeeaeae8611bf.tar.gz", + "hash": "sha256-fOU1oxIxfoEgoLuWz7fVX6M+zmqpo7gqZObWiH/aDE0=" }, "N-V-__8AAG3RoQEyRC2Vw7Qoro5SYBf62IHn3HjqtNVY6aWK": { "name": "libxml2", @@ -109,70 +114,75 @@ "url": "https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz", "hash": "sha256-tStvz8Ref6abHwahNiwVVHNETizAmZVVaxVsU7pmV+M=" }, - "uucode-0.1.0-ZZjBPj96QADXyt5sqwBJUnhaDYs_qBeeKijZvlRa0eqM": { - "name": "uucode", - "url": "git+https://github.com/jacobsandlund/uucode#5f05f8f83a75caea201f12cc8ea32a2d82ea9732", - "hash": "sha256-sHPh+TQSdUGus/QTbj7KSJJkTuNTrK4VNmQDjS30Lf8=" + "translate_c-0.0.0-Q_BUWhVNBwDOEcIqub4VFPJPB6D9dgwzUMHTX5KWr8Xr": { + "name": "translate_c", + "url": "https://codeberg.org/vancluever/translate-c/archive/4e879eb8aba615de112eabd1231ea6e01920cead.tar.gz", + "hash": "sha256-/sT7W8Kp+O11xaFBgpb/kDiWzfQ0MuXk/d/TuGq1Am8=" }, - "uucode-0.2.0-ZZjBPqZVVABQepOqZHR7vV_NcaN-wats0IB6o-Exj6m9": { + "uucode-0.2.0-ZZjBPlK5VADj7fdoq7G8LIHzD5o6FSkcBXXrRWr4jnrA": { "name": "uucode", - "url": "https://deps.files.ghostty.org/uucode-0.2.0-ZZjBPqZVVABQepOqZHR7vV_NcaN-wats0IB6o-Exj6m9.tar.gz", - "hash": "sha256-jLrhrmCXQ1T+LQP1JTBBB3Jn+1hCZfODbC4SdlfNdKg=" + "url": "https://deps.files.ghostty.org/uucode-2826a37a4562284fdacd8fa029d49509cc9bffcd.tar.gz", + "hash": "sha256-R5RXW5tWIaDq5JOF2+oWd5YOYOyns6WH7f687WE+b20=" + }, + "vaxis-0.6.0-BWNV_MjFCQCs9UDHiRkrgw_ayeiPkzOe4xVbaAqXkUWW": { + "name": "vaxis", + "url": "git+https://github.com/rockorager/libvaxis.git#c1e1f23be38951c425cdf31af455ba23ef178940", + "hash": "sha256-bIXu8lGwGo42QbItC0jOi/eN7u+f4snknBexw7dc0DI=" }, - "vaxis-0.5.1-BWNV_LosCQAGmCCNOLljCIw6j6-yt53tji6n6rwJ2BhS": { + "vaxis-0.6.0-BWNV_CrbCQCscGpzsAlR402rYQ_tV3aAl081c2iRRkka": { "name": "vaxis", - "url": "https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz", - "hash": "sha256-zTyrZrIffM+GJIt973tKDeWHmOCwbn7KLDdQxSiK00Y=" + "url": "https://deps.files.ghostty.org/vaxis-1dbbe575dff4586fe51e3217aa5c3fecdcbb6089.tar.gz", + "hash": "sha256-z3J3w+oYapfAZZR+MvWXwg+th1hePDA1TptnKFO4r+M=" }, "N-V-__8AAKrHGAAs2shYq8UkE6bGcR1QJtLTyOE_lcosMn6t": { "name": "wayland", "url": "https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz", "hash": "sha256-6kGR1o5DdnflHzqs3ieCmBAUTpMdOXoyfcYDXiw5xQ0=" }, + "N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA": { + "name": "wayland_protocols", + "url": "https://deps.files.ghostty.org/N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA.tar.gz", + "hash": "sha256-3S3xSrX0EDgleq7cxLX7msDuAY8/D5SvkJcCjmDTMiM=" + }, "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S": { "name": "wayland_protocols", "url": "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz", "hash": "sha256-XO3K3egbdeYPI+XoO13SuOtO+5+Peb16NH0UiusFMPg=" }, - "N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA": { - "name": "wayland_protocols", - "url": "https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/1.47/wayland-protocols-1.47.tar.gz", - "hash": "sha256-3S3xSrX0EDgleq7cxLX7msDuAY8/D5SvkJcCjmDTMiM=" - }, - "N-V-__8AAAzZywE3s51XfsLbP9eyEw57ae9swYB9aGB6fCMs": { + "N-V-__8AAP5JWgCGP_AD0teWpa4krRvE9VPZzvviGdbmN4jI": { "name": "wuffs", - "url": "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz", - "hash": "sha256-nkzSCr6W5sTG7enDBXEIhgEm574uLD41UVR2wlC+HBM=" + "url": "https://deps.files.ghostty.org/wuffs-7411f488fe2e2c205c3d3b3d28638b7356522930.tar.gz", + "hash": "sha256-F4d9NG95iGUdbGLkWy47BchoCaZELF40YSN0sqlxmhw=" }, - "z2d-0.10.0-j5P_Hu-6FgBsZNgwphIqh17jDnj8_yPtD8yzjO6PpHRQ": { + "z2d-0.12.1-j5P_Hsw8EQAKyZTQICCQnAH2xYkLDW8k9uefbsYdfPZ-": { "name": "z2d", - "url": "https://deps.files.ghostty.org/z2d-0.10.0-j5P_Hu-6FgBsZNgwphIqh17jDnj8_yPtD8yzjO6PpHRQ.tar.gz", - "hash": "sha256-qD+XexnAjSanRAwr5ZIaPY1aQhNW5DFVJ4PYLwhIr2E=" + "url": "https://deps.files.ghostty.org/z2d-7dbae85c81784dba9988320bf9543ed9a81350c8.tar.gz", + "hash": "sha256-Fjr1ORn0ozxU7QY09o2ZOZQHIJsXfVw0UCdZxTKmZJ0=" }, - "zf-0.10.3-OIRy8RuJAACKA3Lohoumrt85nRbHwbpMcUaLES8vxDnh": { + "zf-0.11.0-OIRy8X-RAAAwaRXHMYpj2uvBnuGTZWEE_3V7acqHQNtW": { "name": "zf", - "url": "https://deps.files.ghostty.org/zf-3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz", - "hash": "sha256-BfAZILill3I/nBf1oWwol77N34Jcpm4hudC+XSeMgZY=" + "url": "https://deps.files.ghostty.org/zf-c35c421f84895193246db06c40683c1a30e616ef.tar.gz", + "hash": "sha256-LHurWwqK8jhP8AZd/CXrMJNeVsKftRCTN31/EgEgKaA=" }, - "zig_js-0.0.0-rjCAV-6GAADxFug7rDmPH-uM_XcnJ5NmuAMJCAscMjhi": { + "zig_js-0.0.0-rjCAV7-GAADvMTBL7lPMuvDk7xgS9PCMIZWiOUXLZSlj": { "name": "zig_js", - "url": "https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz", - "hash": "sha256-r6GdXwrv+jTu0AkTlyN/FuO+N4X+l20gsbS59wrE7V4=" + "url": "https://deps.files.ghostty.org/zig_js-3c23860e47fdcdc5af805efb7fd0bdac5fd3e9bc.tar.gz", + "hash": "sha256-Q1643wb/MCX0QkPa9QEY9xeQbqpC2IOrjER0ZyL3mH0=" }, - "zig_objc-0.0.0-Ir_Sp5gTAQCvxxR7oVIrPXxXwsfKgVP7_wqoOQrZjFeK": { + "zig_objc-0.0.0-Ir_Sp9gsAQCPAJc0oF5xoWePHWP6Y6tCphDeyNUThJoi": { "name": "zig_objc", - "url": "https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz", - "hash": "sha256-jWFQ5BrV880qqa9KypltWuRLqNSh21rDxt6Jxp0EoMM=" + "url": "https://deps.files.ghostty.org/zig_objc-c8de82ff80281215ad92900866dab7103a8efa8b.tar.gz", + "hash": "sha256-t8cTTJm0crcoGAyOqXO0wB2w7Yit80J2Orwr6prd/G0=" }, - "wayland-0.5.0-dev-lQa1khrMAQDJDwYFKpdH3HizherB7sHo5dKMECfvxQHe": { + "wayland-0.6.0-lQa1kqz8AQADQmdNJsNhLoNHcnEGEUjrOaPV-dtEnEmX": { "name": "zig_wayland", - "url": "https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz", - "hash": "sha256-1wRkixysjdFMyrATxlXdukAc34MwfNj0B6ydYVn+UKw=" + "url": "https://deps.files.ghostty.org/wayland-0.6.0-lQa1kqz8AQADQmdNJsNhLoNHcnEGEUjrOaPV-dtEnEmX.tar.gz", + "hash": "sha256-3m/ITNhZUJ/5uD/Tqm+0uZSktGoYgWF5oldOqOCUkIE=" }, - "zigimg-0.1.0-8_eo2vHnEwCIVW34Q14Ec-xUlzIoVg86-7FU2ypPtxms": { + "zigimg-0.1.0-8_eo2oyaFwBZwJpmqPkCfVXWBrHcqbYwmrp1I6bTD3lI": { "name": "zigimg", - "url": "https://github.com/ivanstepanovftw/zigimg/archive/d7b7ab0ba0899643831ef042bd73289510b39906.tar.gz", - "hash": "sha256-vkcTloGX+vRw7e6GYJLO9eocYaEOYjXYE0dT7jscZ4A=" + "url": "git+https://github.com/zigimg/zigimg#d695acd97c02e57bb151e8f659d1280f5cd6ca70", + "hash": "sha256-0IYATQldT6eJxRR2T/2CsIYZuzomqjvmdVyjmsjguyE=" }, "N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o": { "name": "zlib", diff --git a/vendor/libghostty-vt/build.zig.zon.nix b/vendor/libghostty-vt/build.zig.zon.nix index 2b05dd1b..ddfa5d28 100644 --- a/vendor/libghostty-vt/build.zig.zon.nix +++ b/vendor/libghostty-vt/build.zig.zon.nix @@ -6,7 +6,7 @@ fetchurl, fetchgit, runCommandLocal, - zig_0_15, + zig_0_16, zstd, name ? "zig-packages", }: let @@ -16,12 +16,16 @@ }: runCommandLocal name { - nativeBuildInputs = [zig_0_15]; + nativeBuildInputs = [zig_0_16]; } '' - hash="$(cd "$TMPDIR" && zig fetch --global-cache-dir "$TMPDIR" ${artifact})" - mv "$TMPDIR/p/$hash" "$out" - chmod 755 "$out" + # workaround https://codeberg.org/ziglang/zig/issues/31866 + # https://github.com/Cloudef/zig2nix/issues/54 + mkdir "$TMPDIR/src" "$TMPDIR/cache" + touch "$TMPDIR/src/build.zig" + hash="$(cd "$TMPDIR/src" && zig fetch --global-cache-dir "$TMPDIR/cache" ${artifact})" + mkdir "$out" + tar zxvf "$TMPDIR/cache/p/$hash.tar.gz" --directory "$out/" --strip-components=1 ''; fetchZig = { @@ -93,6 +97,15 @@ fetcher.${proto}; in linkFarm name [ + { + name = "aro-0.0.0-JSD1Qk6lNgDdcDV4Vh7Sfy-34m2TluIVOdPzMmj_0BjX"; + path = fetchZigArtifact { + name = "aro"; + url = "https://github.com/vancluever/arocc/archive/f97cdfc3779aec4b242299e2fc9a1c828c3547c6.tar.gz"; + hash = "sha256-G/NNgk7KhJSLdy17ip1igIzpYhAUlzO7ef8r3/iCv/s="; + unpack = true; + }; + } { name = "N-V-__8AANT61wB--nJ95Gj_ctmzAtcjloZ__hRqNw5lC1Kr"; path = fetchZigArtifact { @@ -112,11 +125,11 @@ in }; } { - name = "N-V-__8AAIrfdwARSa-zMmxWwFuwpXf1T3asIN7s5jqi9c1v"; + name = "N-V-__8AAOgqbADacob-q2_DMQlmgaG4xKHRuW-6PJ4oJzMZ"; path = fetchZigArtifact { name = "fontconfig"; - url = "https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz"; - hash = "sha256-O6LdkhWHGKzsXKrxpxYEO1qgVcJ7CB2RSvPMtA3OilU="; + url = "https://gitlab.freedesktop.org/api/v4/projects/890/packages/generic/fontconfig/2.18.3/fontconfig-2.18.3.tar.xz"; + hash = "sha256-T3tVSjjN94wDP2ZsiHHzdJ4UoJT2Wgf2MMke0LQ9NeM="; unpack = false; }; } @@ -148,11 +161,11 @@ in }; } { - name = "gobject-0.3.0-Skun7ANLnwDvEfIpVmohcppXgOvg_I6YOJFmPIsKfXk-"; + name = "gobject-0.3.2-Skun7F6HogCMynX2JqeSHS7xr-8pK4ob-qRFIcEasVi3"; path = fetchZigArtifact { name = "gobject"; - url = "https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst"; - hash = "sha256-OxS9/XC5aMJj1KhOcFP1ZZN7PI4ADw4f7ocx6V64mOc="; + url = "https://deps.files.ghostty.org/gobject-2026-07-28-36-1.tar.zst"; + hash = "sha256-dyCfm2XjiAk30zccjD6AgKFBdE7IRsJuoqnscfvnWSQ="; unpack = true; }; } @@ -187,17 +200,17 @@ in name = "N-V-__8AAEbOfQBnvcFcCX2W5z7tDaN8vaNZGamEQtNOe0UI"; path = fetchZigArtifact { name = "imgui"; - url = "https://github.com/ocornut/imgui/archive/refs/tags/v1.92.5-docking.tar.gz"; + url = "https://deps.files.ghostty.org/N-V-__8AAEbOfQBnvcFcCX2W5z7tDaN8vaNZGamEQtNOe0UI.tar.gz"; hash = "sha256-yBbCDox18+Fa6Gc1DnmSVQLRpqhZOLsac7iSfl8x+cs="; unpack = false; }; } { - name = "N-V-__8AAAYpBACKY0n8sQbPfzY47xFRRtjXiF766UVF5ZyD"; + name = "N-V-__8AAEFmBABuDGOKxAI6VMg41b9euMZ-z7HS9EcUdaor"; path = fetchZigArtifact { name = "iterm2_themes"; - url = "https://deps.files.ghostty.org/ghostty-themes-release-20260629-161812-8c97c3c.tgz"; - hash = "sha256-quMCPsbVIeLqzIV2okjRDZTKxA6YdkUSYuxmBHf3xMg="; + url = "https://deps.files.ghostty.org/ghostty-themes-release-20260831-151010-752a9c0.tgz"; + hash = "sha256-g2U+uDe661v8fVDJG31EdyeW4IwcJDE04Rxe32yNFcU="; unpack = false; }; } @@ -220,11 +233,11 @@ in }; } { - name = "libxev-0.0.0-86vtc4IcEwCqEYxEYoN_3KXmc6A9VLcm22aVImfvecYs"; + name = "libxev-0.0.0-86vtcwIRFADbH4hk-EjROXxlrKIRPQdA41XiTSytYO-F"; path = fetchZigArtifact { name = "libxev"; - url = "https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz"; - hash = "sha256-1B9oJExVyOWRj+Y9d9eHkOBTlOYuEkcwGBUKdlgRhkg="; + url = "https://deps.files.ghostty.org/libxev-9ce8e8e6ff89e583258a7f8e7adeeeaeae8611bf.tar.gz"; + hash = "sha256-fOU1oxIxfoEgoLuWz7fVX6M+zmqpo7gqZObWiH/aDE0="; unpack = true; }; } @@ -292,29 +305,38 @@ in }; } { - name = "uucode-0.1.0-ZZjBPj96QADXyt5sqwBJUnhaDYs_qBeeKijZvlRa0eqM"; + name = "translate_c-0.0.0-Q_BUWhVNBwDOEcIqub4VFPJPB6D9dgwzUMHTX5KWr8Xr"; path = fetchZigArtifact { - name = "uucode"; - url = "git+https://github.com/jacobsandlund/uucode#5f05f8f83a75caea201f12cc8ea32a2d82ea9732"; - hash = "sha256-sHPh+TQSdUGus/QTbj7KSJJkTuNTrK4VNmQDjS30Lf8="; + name = "translate_c"; + url = "https://codeberg.org/vancluever/translate-c/archive/4e879eb8aba615de112eabd1231ea6e01920cead.tar.gz"; + hash = "sha256-/sT7W8Kp+O11xaFBgpb/kDiWzfQ0MuXk/d/TuGq1Am8="; unpack = true; }; } { - name = "uucode-0.2.0-ZZjBPqZVVABQepOqZHR7vV_NcaN-wats0IB6o-Exj6m9"; + name = "uucode-0.2.0-ZZjBPlK5VADj7fdoq7G8LIHzD5o6FSkcBXXrRWr4jnrA"; path = fetchZigArtifact { name = "uucode"; - url = "https://deps.files.ghostty.org/uucode-0.2.0-ZZjBPqZVVABQepOqZHR7vV_NcaN-wats0IB6o-Exj6m9.tar.gz"; - hash = "sha256-jLrhrmCXQ1T+LQP1JTBBB3Jn+1hCZfODbC4SdlfNdKg="; + url = "https://deps.files.ghostty.org/uucode-2826a37a4562284fdacd8fa029d49509cc9bffcd.tar.gz"; + hash = "sha256-R5RXW5tWIaDq5JOF2+oWd5YOYOyns6WH7f687WE+b20="; + unpack = true; + }; + } + { + name = "vaxis-0.6.0-BWNV_MjFCQCs9UDHiRkrgw_ayeiPkzOe4xVbaAqXkUWW"; + path = fetchZigArtifact { + name = "vaxis"; + url = "git+https://github.com/rockorager/libvaxis.git#c1e1f23be38951c425cdf31af455ba23ef178940"; + hash = "sha256-bIXu8lGwGo42QbItC0jOi/eN7u+f4snknBexw7dc0DI="; unpack = true; }; } { - name = "vaxis-0.5.1-BWNV_LosCQAGmCCNOLljCIw6j6-yt53tji6n6rwJ2BhS"; + name = "vaxis-0.6.0-BWNV_CrbCQCscGpzsAlR402rYQ_tV3aAl081c2iRRkka"; path = fetchZigArtifact { name = "vaxis"; - url = "https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz"; - hash = "sha256-zTyrZrIffM+GJIt973tKDeWHmOCwbn7KLDdQxSiK00Y="; + url = "https://deps.files.ghostty.org/vaxis-1dbbe575dff4586fe51e3217aa5c3fecdcbb6089.tar.gz"; + hash = "sha256-z3J3w+oYapfAZZR+MvWXwg+th1hePDA1TptnKFO4r+M="; unpack = true; }; } @@ -328,83 +350,83 @@ in }; } { - name = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S"; + name = "N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA"; path = fetchZigArtifact { name = "wayland_protocols"; - url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz"; - hash = "sha256-XO3K3egbdeYPI+XoO13SuOtO+5+Peb16NH0UiusFMPg="; + url = "https://deps.files.ghostty.org/N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA.tar.gz"; + hash = "sha256-3S3xSrX0EDgleq7cxLX7msDuAY8/D5SvkJcCjmDTMiM="; unpack = false; }; } { - name = "N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA"; + name = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S"; path = fetchZigArtifact { name = "wayland_protocols"; - url = "https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/1.47/wayland-protocols-1.47.tar.gz"; - hash = "sha256-3S3xSrX0EDgleq7cxLX7msDuAY8/D5SvkJcCjmDTMiM="; + url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz"; + hash = "sha256-XO3K3egbdeYPI+XoO13SuOtO+5+Peb16NH0UiusFMPg="; unpack = false; }; } { - name = "N-V-__8AAAzZywE3s51XfsLbP9eyEw57ae9swYB9aGB6fCMs"; + name = "N-V-__8AAP5JWgCGP_AD0teWpa4krRvE9VPZzvviGdbmN4jI"; path = fetchZigArtifact { name = "wuffs"; - url = "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz"; - hash = "sha256-nkzSCr6W5sTG7enDBXEIhgEm574uLD41UVR2wlC+HBM="; + url = "https://deps.files.ghostty.org/wuffs-7411f488fe2e2c205c3d3b3d28638b7356522930.tar.gz"; + hash = "sha256-F4d9NG95iGUdbGLkWy47BchoCaZELF40YSN0sqlxmhw="; unpack = false; }; } { - name = "z2d-0.10.0-j5P_Hu-6FgBsZNgwphIqh17jDnj8_yPtD8yzjO6PpHRQ"; + name = "z2d-0.12.1-j5P_Hsw8EQAKyZTQICCQnAH2xYkLDW8k9uefbsYdfPZ-"; path = fetchZigArtifact { name = "z2d"; - url = "https://deps.files.ghostty.org/z2d-0.10.0-j5P_Hu-6FgBsZNgwphIqh17jDnj8_yPtD8yzjO6PpHRQ.tar.gz"; - hash = "sha256-qD+XexnAjSanRAwr5ZIaPY1aQhNW5DFVJ4PYLwhIr2E="; + url = "https://deps.files.ghostty.org/z2d-7dbae85c81784dba9988320bf9543ed9a81350c8.tar.gz"; + hash = "sha256-Fjr1ORn0ozxU7QY09o2ZOZQHIJsXfVw0UCdZxTKmZJ0="; unpack = true; }; } { - name = "zf-0.10.3-OIRy8RuJAACKA3Lohoumrt85nRbHwbpMcUaLES8vxDnh"; + name = "zf-0.11.0-OIRy8X-RAAAwaRXHMYpj2uvBnuGTZWEE_3V7acqHQNtW"; path = fetchZigArtifact { name = "zf"; - url = "https://deps.files.ghostty.org/zf-3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz"; - hash = "sha256-BfAZILill3I/nBf1oWwol77N34Jcpm4hudC+XSeMgZY="; + url = "https://deps.files.ghostty.org/zf-c35c421f84895193246db06c40683c1a30e616ef.tar.gz"; + hash = "sha256-LHurWwqK8jhP8AZd/CXrMJNeVsKftRCTN31/EgEgKaA="; unpack = true; }; } { - name = "zig_js-0.0.0-rjCAV-6GAADxFug7rDmPH-uM_XcnJ5NmuAMJCAscMjhi"; + name = "zig_js-0.0.0-rjCAV7-GAADvMTBL7lPMuvDk7xgS9PCMIZWiOUXLZSlj"; path = fetchZigArtifact { name = "zig_js"; - url = "https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz"; - hash = "sha256-r6GdXwrv+jTu0AkTlyN/FuO+N4X+l20gsbS59wrE7V4="; + url = "https://deps.files.ghostty.org/zig_js-3c23860e47fdcdc5af805efb7fd0bdac5fd3e9bc.tar.gz"; + hash = "sha256-Q1643wb/MCX0QkPa9QEY9xeQbqpC2IOrjER0ZyL3mH0="; unpack = true; }; } { - name = "zig_objc-0.0.0-Ir_Sp5gTAQCvxxR7oVIrPXxXwsfKgVP7_wqoOQrZjFeK"; + name = "zig_objc-0.0.0-Ir_Sp9gsAQCPAJc0oF5xoWePHWP6Y6tCphDeyNUThJoi"; path = fetchZigArtifact { name = "zig_objc"; - url = "https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz"; - hash = "sha256-jWFQ5BrV880qqa9KypltWuRLqNSh21rDxt6Jxp0EoMM="; + url = "https://deps.files.ghostty.org/zig_objc-c8de82ff80281215ad92900866dab7103a8efa8b.tar.gz"; + hash = "sha256-t8cTTJm0crcoGAyOqXO0wB2w7Yit80J2Orwr6prd/G0="; unpack = true; }; } { - name = "wayland-0.5.0-dev-lQa1khrMAQDJDwYFKpdH3HizherB7sHo5dKMECfvxQHe"; + name = "wayland-0.6.0-lQa1kqz8AQADQmdNJsNhLoNHcnEGEUjrOaPV-dtEnEmX"; path = fetchZigArtifact { name = "zig_wayland"; - url = "https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz"; - hash = "sha256-1wRkixysjdFMyrATxlXdukAc34MwfNj0B6ydYVn+UKw="; + url = "https://deps.files.ghostty.org/wayland-0.6.0-lQa1kqz8AQADQmdNJsNhLoNHcnEGEUjrOaPV-dtEnEmX.tar.gz"; + hash = "sha256-3m/ITNhZUJ/5uD/Tqm+0uZSktGoYgWF5oldOqOCUkIE="; unpack = true; }; } { - name = "zigimg-0.1.0-8_eo2vHnEwCIVW34Q14Ec-xUlzIoVg86-7FU2ypPtxms"; + name = "zigimg-0.1.0-8_eo2oyaFwBZwJpmqPkCfVXWBrHcqbYwmrp1I6bTD3lI"; path = fetchZigArtifact { name = "zigimg"; - url = "https://github.com/ivanstepanovftw/zigimg/archive/d7b7ab0ba0899643831ef042bd73289510b39906.tar.gz"; - hash = "sha256-vkcTloGX+vRw7e6GYJLO9eocYaEOYjXYE0dT7jscZ4A="; + url = "git+https://github.com/zigimg/zigimg#d695acd97c02e57bb151e8f659d1280f5cd6ca70"; + hash = "sha256-0IYATQldT6eJxRR2T/2CsIYZuzomqjvmdVyjmsjguyE="; unpack = true; }; } diff --git a/vendor/libghostty-vt/build.zig.zon.txt b/vendor/libghostty-vt/build.zig.zon.txt index 02da0630..e1dd4b64 100644 --- a/vendor/libghostty-vt/build.zig.zon.txt +++ b/vendor/libghostty-vt/build.zig.zon.txt @@ -1,36 +1,38 @@ -git+https://github.com/jacobsandlund/uucode#5f05f8f83a75caea201f12cc8ea32a2d82ea9732 +git+https://github.com/rockorager/libvaxis.git#c1e1f23be38951c425cdf31af455ba23ef178940 +git+https://github.com/zigimg/zigimg#d695acd97c02e57bb151e8f659d1280f5cd6ca70 +https://codeberg.org/vancluever/translate-c/archive/4e879eb8aba615de112eabd1231ea6e01920cead.tar.gz https://deps.files.ghostty.org/DearBindings_v0.17_ImGui_v1.92.5-docking.tar.gz https://deps.files.ghostty.org/JetBrainsMono-2.304.tar.gz +https://deps.files.ghostty.org/N-V-__8AAEbOfQBnvcFcCX2W5z7tDaN8vaNZGamEQtNOe0UI.tar.gz +https://deps.files.ghostty.org/N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA.tar.gz https://deps.files.ghostty.org/NerdFontsSymbolsOnly-3.4.0.tar.gz https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz -https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz https://deps.files.ghostty.org/freetype-1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d.tar.gz https://deps.files.ghostty.org/gettext-0.24.tar.gz -https://deps.files.ghostty.org/ghostty-themes-release-20260629-161812-8c97c3c.tgz +https://deps.files.ghostty.org/ghostty-themes-release-20260831-151010-752a9c0.tgz https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz -https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst +https://deps.files.ghostty.org/gobject-2026-07-28-36-1.tar.zst https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz https://deps.files.ghostty.org/harfbuzz-11.0.0.tar.xz https://deps.files.ghostty.org/highway-66486a10623fa0d72fe91260f96c892e41aceb06.tar.gz https://deps.files.ghostty.org/libpng-1220aa013f0c83da3fb64ea6d327f9173fa008d10e28bc9349eac3463457723b1c66.tar.gz -https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz +https://deps.files.ghostty.org/libxev-9ce8e8e6ff89e583258a7f8e7adeeeaeae8611bf.tar.gz https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz https://deps.files.ghostty.org/oniguruma-1220c15e72eadd0d9085a8af134904d9a0f5dfcbed5f606ad60edc60ebeccd9706bb.tar.gz https://deps.files.ghostty.org/pixels-12207ff340169c7d40c570b4b6a97db614fe47e0d83b5801a932dcd44917424c8806.tar.gz https://deps.files.ghostty.org/plasma_wayland_protocols-12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566.tar.gz https://deps.files.ghostty.org/sentry-1220446be831adcca918167647c06c7b825849fa3fba5f22da394667974537a9c77e.tar.gz https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz -https://deps.files.ghostty.org/uucode-0.2.0-ZZjBPqZVVABQepOqZHR7vV_NcaN-wats0IB6o-Exj6m9.tar.gz -https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz +https://deps.files.ghostty.org/uucode-2826a37a4562284fdacd8fa029d49509cc9bffcd.tar.gz +https://deps.files.ghostty.org/vaxis-1dbbe575dff4586fe51e3217aa5c3fecdcbb6089.tar.gz +https://deps.files.ghostty.org/wayland-0.6.0-lQa1kqz8AQADQmdNJsNhLoNHcnEGEUjrOaPV-dtEnEmX.tar.gz https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz -https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz -https://deps.files.ghostty.org/z2d-0.10.0-j5P_Hu-6FgBsZNgwphIqh17jDnj8_yPtD8yzjO6PpHRQ.tar.gz -https://deps.files.ghostty.org/zf-3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz -https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz -https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz -https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz +https://deps.files.ghostty.org/wuffs-7411f488fe2e2c205c3d3b3d28638b7356522930.tar.gz +https://deps.files.ghostty.org/z2d-7dbae85c81784dba9988320bf9543ed9a81350c8.tar.gz +https://deps.files.ghostty.org/zf-c35c421f84895193246db06c40683c1a30e616ef.tar.gz +https://deps.files.ghostty.org/zig_js-3c23860e47fdcdc5af805efb7fd0bdac5fd3e9bc.tar.gz +https://deps.files.ghostty.org/zig_objc-c8de82ff80281215ad92900866dab7103a8efa8b.tar.gz https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz -https://github.com/ivanstepanovftw/zigimg/archive/d7b7ab0ba0899643831ef042bd73289510b39906.tar.gz -https://github.com/ocornut/imgui/archive/refs/tags/v1.92.5-docking.tar.gz -https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/1.47/wayland-protocols-1.47.tar.gz +https://github.com/vancluever/arocc/archive/f97cdfc3779aec4b242299e2fc9a1c828c3547c6.tar.gz +https://gitlab.freedesktop.org/api/v4/projects/890/packages/generic/fontconfig/2.18.3/fontconfig-2.18.3.tar.xz diff --git a/vendor/libghostty-vt/flake.lock b/vendor/libghostty-vt/flake.lock index 41063278..305cb2e4 100644 --- a/vendor/libghostty-vt/flake.lock +++ b/vendor/libghostty-vt/flake.lock @@ -3,11 +3,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1761588595, - "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", + "lastModified": 1767039857, + "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", "owner": "edolstra", "repo": "flake-compat", - "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", + "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", "type": "github" }, "original": { @@ -23,11 +23,11 @@ ] }, "locked": { - "lastModified": 1770586272, - "narHash": "sha256-Ucci8mu8QfxwzyfER2DQDbvW9t1BnTUJhBmY7ybralo=", + "lastModified": 1787661347, + "narHash": "sha256-THmnBAdAIV+jT348f3r/vyoeb6ilhcVLwVXkBU7Pai8=", "owner": "nix-community", "repo": "home-manager", - "rev": "b1f916ba052341edc1f80d4b2399f1092a4873ca", + "rev": "52c3a5881c821ad7367bbde075e52b76cdb378ab", "type": "github" }, "original": { @@ -38,15 +38,15 @@ }, "nixpkgs": { "locked": { - "lastModified": 1770537093, - "narHash": "sha256-XV30uo8tXuxdzuV8l3sojmlPRLd/8tpMsOp4lNzLGUo=", - "rev": "fef9403a3e4d31b0a23f0bacebbec52c248fbb51", + "lastModified": 1787424095, + "narHash": "sha256-SpMiSe9OSfWseGAupsdcED3He9mTYTbGMtWb7EVt6pE=", + "rev": "174eb786fb68e3a13e4e535a3deea479a0c07a6a", "type": "tarball", - "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre942631.fef9403a3e4d/nixexprs.tar.xz" + "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1059855.174eb786fb68/nixexprs.tar.zst" }, "original": { "type": "tarball", - "url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz" + "url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.zst" } }, "root": { @@ -88,11 +88,11 @@ ] }, "locked": { - "lastModified": 1776789209, - "narHash": "sha256-G6B7Q4TXn7MZ1mB+f9rymjsYF5PLWoSvmbxijb/99bw=", + "lastModified": 1787617283, + "narHash": "sha256-jiM1glpDL5ASrqvcWyacI+c1wZo3g6AUhdo6M09AoiY=", "owner": "mitchellh", "repo": "zig-overlay", - "rev": "14fe971844e841297ddd2ce9783d6892b467af39", + "rev": "da55b9fe9260fb3eb1456c3ee6064b8f738e4ba9", "type": "github" }, "original": { @@ -101,40 +101,18 @@ "type": "github" } }, - "zig_2": { - "inputs": { - "nixpkgs": [ - "zon2nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1777234348, - "narHash": "sha256-fKw44a4qbUuI5eTG8k0gPbqMV5TOrjYF35PBzsYgd2U=", - "ref": "refs/heads/main", - "rev": "2c781c0609ecda600ab98f98cca417bbd981bd53", - "revCount": 1677, - "type": "git", - "url": "https://codeberg.org/jcollie/zig-overlay.git" - }, - "original": { - "type": "git", - "url": "https://codeberg.org/jcollie/zig-overlay.git" - } - }, "zon2nix": { "inputs": { "nixpkgs": [ "nixpkgs" - ], - "zig": "zig_2" + ] }, "locked": { - "lastModified": 1777314365, - "narHash": "sha256-eLxQaD0wc96Neqkln8wHS0rNq/chPODifFkhwrwilEU=", + "lastModified": 1784080626, + "narHash": "sha256-Hvnmnuu0VpHiZl+8z+UkMoxC7JZJvRYBqu2Asb0ZJOE=", "owner": "jcollie", "repo": "zon2nix", - "rev": "a5a1d412ad1ab6305511997bbc92b3a9dd6cb784", + "rev": "776b5f6864a607c141d7966421b433fa1657ba9a", "type": "github" }, "original": { diff --git a/vendor/libghostty-vt/flake.nix b/vendor/libghostty-vt/flake.nix index 0a4e5340..f951b132 100644 --- a/vendor/libghostty-vt/flake.nix +++ b/vendor/libghostty-vt/flake.nix @@ -6,10 +6,10 @@ # glibc versions used by our dependencies from Nix are compatible with the # system glibc that the user is building for. # - # We are currently on nixpkgs-unstable to get Zig 0.15 for our package.nix and - # Gnome 49/Gtk 4.20. + # We are currently on nixpkgs-unstable to get Zig 0.16 for our package.nix, + # Gnome 50/Gtk 4.22, and fontconfig 2.18. # - nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"; + nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.zst"; # Used for shell.nix flake-compat = { @@ -74,23 +74,22 @@ }; in { devShells = forAllPlatforms (pkgs: { - default = pkgs.callPackage ./nix/devShell.nix { - zig = - if pkgs.stdenv.hostPlatform.isDarwin - then zig.packages.${pkgs.stdenv.hostPlatform.system}.brew."0.15.2" - else zig.packages.${pkgs.stdenv.hostPlatform.system}."0.15.2"; - wraptest = pkgs.callPackage ./nix/pkgs/wraptest.nix {}; - zon2nix = zon2nix; - - python3 = pkgs.python3.override { - self = pkgs.python3; - packageOverrides = pyfinal: pyprev: { - blessed = pyfinal.callPackage ./nix/pkgs/blessed.nix {}; - ucs-detect = pyfinal.callPackage ./nix/pkgs/ucs-detect.nix {}; - wcwidth = pyfinal.callPackage ./nix/pkgs/wcwidth.nix {}; + default = + pkgs.callPackage ./nix/devShell.nix + { + zig = zig.packages.${pkgs.stdenv.hostPlatform.system}."0.16.0"; + wraptest = pkgs.callPackage ./nix/pkgs/wraptest.nix {}; + zon2nix = zon2nix; + + python3 = pkgs.python3.override { + self = pkgs.python3; + packageOverrides = pyfinal: pyprev: { + blessed = pyfinal.callPackage ./nix/pkgs/blessed.nix {}; + ucs-detect = pyfinal.callPackage ./nix/pkgs/ucs-detect.nix {}; + wcwidth = pyfinal.callPackage ./nix/pkgs/wcwidth.nix {}; + }; }; }; - }; }); packages = diff --git a/vendor/libghostty-vt/include/ghostty.h b/vendor/libghostty-vt/include/ghostty.h index 72bbb57a..518af3ff 100644 --- a/vendor/libghostty-vt/include/ghostty.h +++ b/vendor/libghostty-vt/include/ghostty.h @@ -1,10 +1,14 @@ -// Ghostty embedding API. The documentation for the embedding API is -// only within the Zig source files that define the implementations. This -// isn't meant to be a general purpose embedding API (yet) so there hasn't -// been documentation or example work beyond that. +// Ghostty's internal embedder API, a.k.a. "libghostty-internal". // -// The only consumer of this API is the macOS app, but the API is built to -// be more general purpose. +// The only consumer of this API is the macOS app, and while it is fairly +// comprehensive, it is tailored to the needs of the macOS app and not designed +// for external use, hence why most functions are undocumented and some are +// macOS-specific (e.g. ones dealing with the Metal graphics API). +// +// External embedders should instead use `libghostty-vt` or other related +// packages, which are extensively documented and designed from the ground up +// to be used in other software. Header files for which can be found in +// `include/ghostty/`. #ifndef GHOSTTY_H #define GHOSTTY_H @@ -71,19 +75,56 @@ typedef enum { typedef enum { GHOSTTY_CLIPBOARD_STANDARD, GHOSTTY_CLIPBOARD_SELECTION, + GHOSTTY_CLIPBOARD_PRIMARY, } ghostty_clipboard_e; +// One representation of clipboard contents. The data is binary-safe with +// an explicit length; it is not necessarily null-terminated. typedef struct { const char *mime; const char *data; + size_t len; } ghostty_clipboard_content_s; +// The payload for completing a clipboard read request. See +// ghostty_surface_complete_clipboard_request. +typedef struct { + const ghostty_clipboard_content_s *contents; + size_t contents_len; + const char *const *available; + size_t available_len; + bool confirmed; + bool remember; +} ghostty_clipboard_complete_s; + +// The payload of a clipboard read confirmation request: the would-be +// completion contents plus the information shown in the permission +// prompt. See ghostty_runtime_confirm_read_clipboard_cb. +typedef struct { + const ghostty_clipboard_content_s *contents; + size_t contents_len; + const char *const *available; + size_t available_len; + const char *name; + bool can_remember; +} ghostty_clipboard_confirm_s; + typedef enum { GHOSTTY_CLIPBOARD_REQUEST_PASTE, GHOSTTY_CLIPBOARD_REQUEST_OSC_52_READ, GHOSTTY_CLIPBOARD_REQUEST_OSC_52_WRITE, + GHOSTTY_CLIPBOARD_REQUEST_KITTY_READ, + GHOSTTY_CLIPBOARD_REQUEST_KITTY_WRITE, + GHOSTTY_CLIPBOARD_REQUEST_LIST, } ghostty_clipboard_request_e; +// apprt.ClipboardReadResult +typedef enum { + GHOSTTY_CLIPBOARD_READ_STARTED, + GHOSTTY_CLIPBOARD_READ_UNAVAILABLE, + GHOSTTY_CLIPBOARD_READ_UNSUPPORTED, +} ghostty_clipboard_read_result_e; + typedef enum { GHOSTTY_MOUSE_RELEASE, GHOSTTY_MOUSE_PRESS, @@ -645,6 +686,12 @@ typedef enum { GHOSTTY_INSPECTOR_HIDE, } ghostty_action_inspector_e; +// apprt.action.ExportTerminalIO.C +typedef struct { + const char* contents; + size_t len; +} ghostty_action_export_terminal_io_s; + // apprt.action.QuitTimer typedef enum { GHOSTTY_QUIT_TIMER_START, @@ -672,6 +719,7 @@ typedef struct { typedef enum { GHOSTTY_PROMPT_TITLE_SURFACE, GHOSTTY_PROMPT_TITLE_TAB, + GHOSTTY_PROMPT_TITLE_WINDOW, } ghostty_action_prompt_title_e; // apprt.action.Pwd.C @@ -679,6 +727,14 @@ typedef struct { const char* pwd; } ghostty_action_pwd_s; +// apprt.action.OpenConfig +typedef enum { + // Open the config in the OS default editor. + GHOSTTY_ACTION_OPEN_CONFIG_OS_OPEN, + // Open the config in a new window using $EDITOR or $VISUAL + GHOSTTY_ACTION_OPEN_CONFIG_NEW_WINDOW, +} ghostty_action_open_config_e; + // terminal.MouseShape typedef enum { GHOSTTY_MOUSE_SHAPE_DEFAULT, @@ -812,6 +868,7 @@ typedef enum { GHOSTTY_ACTION_OPEN_URL_KIND_UNKNOWN, GHOSTTY_ACTION_OPEN_URL_KIND_TEXT, GHOSTTY_ACTION_OPEN_URL_KIND_HTML, + GHOSTTY_ACTION_OPEN_URL_KIND_OSC8, } ghostty_action_open_url_kind_e; // apprt.action.OpenUrl.C @@ -914,9 +971,11 @@ typedef enum { GHOSTTY_ACTION_INSPECTOR, GHOSTTY_ACTION_SHOW_GTK_INSPECTOR, GHOSTTY_ACTION_RENDER_INSPECTOR, + GHOSTTY_ACTION_EXPORT_TERMINAL_IO, GHOSTTY_ACTION_DESKTOP_NOTIFICATION, GHOSTTY_ACTION_SET_TITLE, GHOSTTY_ACTION_SET_TAB_TITLE, + GHOSTTY_ACTION_SET_WINDOW_TITLE, GHOSTTY_ACTION_PROMPT_TITLE, GHOSTTY_ACTION_PWD, GHOSTTY_ACTION_MOUSE_SHAPE, @@ -949,6 +1008,7 @@ typedef enum { GHOSTTY_ACTION_SEARCH_SELECTED, GHOSTTY_ACTION_READONLY, GHOSTTY_ACTION_COPY_TITLE_TO_CLIPBOARD, + GHOSTTY_ACTION_MOVE_TAB_TO_NEW_WINDOW, } ghostty_action_tag_e; typedef union { @@ -964,6 +1024,7 @@ typedef union { ghostty_action_cell_size_s cell_size; ghostty_action_scrollbar_s scrollbar; ghostty_action_inspector_e inspector; + ghostty_action_export_terminal_io_s export_terminal_io; ghostty_action_desktop_notification_s desktop_notification; ghostty_action_set_title_s set_title; ghostty_action_set_title_s set_tab_title; @@ -990,6 +1051,7 @@ typedef union { ghostty_action_search_total_s search_total; ghostty_action_search_selected_s search_selected; ghostty_action_readonly_e readonly; + ghostty_action_open_config_e open_config; } ghostty_action_u; typedef struct { @@ -998,12 +1060,16 @@ typedef struct { } ghostty_action_s; typedef void (*ghostty_runtime_wakeup_cb)(void*); -typedef bool (*ghostty_runtime_read_clipboard_cb)(void*, - ghostty_clipboard_e, - void*); +typedef ghostty_clipboard_read_result_e (*ghostty_runtime_read_clipboard_cb)( + void*, + ghostty_clipboard_e, + void*, + const char* const*, + size_t, + bool); typedef void (*ghostty_runtime_confirm_read_clipboard_cb)( void*, - const char*, + const ghostty_clipboard_confirm_s*, void*, ghostty_clipboard_request_e); typedef void (*ghostty_runtime_write_clipboard_cb)(void*, @@ -1055,6 +1121,7 @@ typedef union { // apprt.ipc.Action.Key typedef enum { GHOSTTY_IPC_ACTION_NEW_WINDOW, + GHOSTTY_IPC_ACTION_NEW_TAB, GHOSTTY_IPC_ACTION_TOGGLE_QUICK_TERMINAL, } ghostty_ipc_action_tag_e; @@ -1152,10 +1219,12 @@ GHOSTTY_API void ghostty_surface_split_resize(ghostty_surface_t, uint16_t); GHOSTTY_API void ghostty_surface_split_equalize(ghostty_surface_t); GHOSTTY_API bool ghostty_surface_binding_action(ghostty_surface_t, const char*, uintptr_t); -GHOSTTY_API void ghostty_surface_complete_clipboard_request(ghostty_surface_t, - const char*, - void*, - bool); +GHOSTTY_API void ghostty_surface_complete_clipboard_request( + ghostty_surface_t, + const ghostty_clipboard_complete_s*, + void*); +GHOSTTY_API void ghostty_surface_deny_clipboard_request(ghostty_surface_t, + void*); GHOSTTY_API bool ghostty_surface_has_selection(ghostty_surface_t); GHOSTTY_API bool ghostty_surface_read_selection(ghostty_surface_t, ghostty_text_s*); GHOSTTY_API bool ghostty_surface_read_text(ghostty_surface_t, diff --git a/vendor/libghostty-vt/include/ghostty/vt.h b/vendor/libghostty-vt/include/ghostty/vt.h index 5606f169..cfa1017e 100644 --- a/vendor/libghostty-vt/include/ghostty/vt.h +++ b/vendor/libghostty-vt/include/ghostty/vt.h @@ -31,12 +31,15 @@ * - @ref terminal "Terminal" - Complete terminal emulator state and rendering * - @ref render "Render State" - Incremental render state updates for custom renderers * - @ref formatter "Formatter" - Format terminal content as plain text, VT sequences, or HTML + * - @ref snapshot "Terminal Snapshot" - Encode and incrementally restore terminal state + * - @ref search "Search" - Search terminal contents, including scrollback * - @ref osc "OSC Parser" - Parse OSC (Operating System Command) sequences * - @ref sgr "SGR Parser" - Parse SGR (Select Graphic Rendition) sequences - * - @ref paste "Paste Utilities" - Validate paste data safety + * - @ref paste "Paste" - Paste into a terminal, validate and encode paste data * - @ref unicode "Unicode Utilities" - Codepoint properties for text layout * - @ref build_info "Build Info" - Query compile-time build configuration * - @ref allocator "Memory Management" - Memory management and custom allocators + * - @ref io "Byte-stream I/O" - Reusable synchronous reader and writer callbacks * - @ref wasm "WebAssembly Utilities" - WebAssembly convenience functions * * Encoding related APIs: @@ -51,12 +54,13 @@ * - @ref c-vt/src/main.c - OSC parser example * - @ref c-vt-encode-key/src/main.c - Key encoding example * - @ref c-vt-encode-mouse/src/main.c - Mouse encoding example - * - @ref c-vt-paste/src/main.c - Paste safety check example + * - @ref c-vt-paste/src/main.c - Paste example * - @ref c-vt-sgr/src/main.c - SGR parser example * - @ref c-vt-formatter/src/main.c - Terminal formatter example * - @ref c-vt-grid-traverse/src/main.c - Grid traversal example using grid refs * - @ref c-vt-grid-ref-tracked/src/main.c - Tracked grid ref example * - @ref c-vt-compression/src/main.c - Idle scrollback compression example + * - @ref c-vt-search/src/main.c - Terminal search example * */ @@ -81,8 +85,10 @@ */ /** @example c-vt-paste/src/main.c - * This example demonstrates how to use the paste utilities to check if - * paste data is safe before sending it to the terminal. + * This example demonstrates how to paste into a terminal, including the + * unsafe-paste confirmation flow and Kitty clipboard protocol paste events + * (mode 5522), as well as the terminal-free paste safety and encoding + * utilities. */ /** @example c-vt-sgr/src/main.c @@ -121,6 +127,12 @@ * PNG decoder callback and send a Kitty Graphics Protocol image. */ +/** @example c-vt-search/src/main.c + * This example demonstrates how to search terminal contents for a + * string, navigate between the matches like a find bar, and read the + * viewport matches used to draw highlights. + */ + #ifndef GHOSTTY_VT_H #define GHOSTTY_VT_H @@ -140,6 +152,7 @@ extern "C" { #include #include #include +#include #include #include #include @@ -151,8 +164,10 @@ extern "C" { #include #include #include +#include #include #include +#include #include #include diff --git a/vendor/libghostty-vt/include/ghostty/vt/allocator.h b/vendor/libghostty-vt/include/ghostty/vt/allocator.h index 2e8685e8..f68ffa2f 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/allocator.h +++ b/vendor/libghostty-vt/include/ghostty/vt/allocator.h @@ -31,14 +31,17 @@ * function that accepts one,** and libghostty will use a default allocator. * The default allocator will be libc malloc/free if libc is linked. * Otherwise, a custom allocator is used (currently Zig's SMP allocator) - * that doesn't require any external dependencies. + * that doesn't require any external dependencies. On native freestanding + * targets, the default allocator always fails instead. * * ## Basic Usage * * For simple use cases, you can ignore this interface entirely by passing NULL * as the allocator parameter to functions that accept one. This will use the * default allocator (typically libc malloc/free, if libc is linked, but - * we provide our own default allocator if libc isn't linked). + * we provide our own default allocator if libc isn't linked). Native + * freestanding builds must provide a custom allocator for operations that + * allocate memory. * * To use a custom allocator: * 1. Implement the GhosttyAllocatorVtable function pointers @@ -76,7 +79,8 @@ * * If you're not going to use a custom allocator, you can ignore all of * this. All functions that take an allocator pointer allow NULL to use a - * default allocator. + * default allocator. Native freestanding builds must provide an allocator + * for operations that allocate memory. * * The interface is based on the Zig allocator interface. I'll say up front * that it is easy to look at this interface and think "wow, this is really @@ -183,7 +187,8 @@ typedef struct { * For functions that take an allocator pointer, a NULL pointer indicates * that the default allocator should be used. The default allocator will * be libc malloc/free if we're linking to libc. If libc isn't linked, - * a custom allocator is used (currently Zig's SMP allocator). + * a custom allocator is used (currently Zig's SMP allocator). On native + * freestanding targets, the default allocator always fails instead. * * @ingroup allocator * @@ -219,7 +224,8 @@ typedef struct GhosttyAllocator { * * @param allocator Pointer to the allocator to use, or NULL for the default * @param len Number of bytes to allocate - * @return Pointer to the allocated buffer, or NULL if allocation failed + * @return Pointer to the allocated buffer, or NULL if len is zero or + * allocation failed * * @ingroup allocator */ diff --git a/vendor/libghostty-vt/include/ghostty/vt/device.h b/vendor/libghostty-vt/include/ghostty/vt/device.h index 0a156728..419748a8 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/device.h +++ b/vendor/libghostty-vt/include/ghostty/vt/device.h @@ -11,6 +11,8 @@ #include #include +#include + /* DA1 conformance levels (Pp parameter). */ #define GHOSTTY_DA_CONFORMANCE_VT100 1 #define GHOSTTY_DA_CONFORMANCE_VT101 1 diff --git a/vendor/libghostty-vt/include/ghostty/vt/formatter.h b/vendor/libghostty-vt/include/ghostty/vt/formatter.h index 5cdcd11a..fd593b13 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/formatter.h +++ b/vendor/libghostty-vt/include/ghostty/vt/formatter.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -137,6 +138,30 @@ GHOSTTY_API GhosttyResult ghostty_formatter_terminal_new( GhosttyTerminal terminal, GhosttyFormatterTerminalOptions options); +/** + * Run the formatter and stream output to a writer. + * + * Each call formats the current terminal state and invokes the writer + * synchronously as output becomes available. The callback may be called more + * than once and must not call formatter or terminal APIs using the same + * formatter or its terminal. + * + * If an error occurs, the writer may already contain a partial formatted + * output. The operation cannot be resumed from that partial output. This + * function does not flush or make the caller's destination durable. + * + * @param formatter The formatter handle (must not be NULL) + * @param writer Destination writer whose write callback must not be NULL + * @return GHOSTTY_SUCCESS on success, GHOSTTY_IO_ERROR if the writer rejects + * output, GHOSTTY_LIMIT_EXCEEDED if output accounting overflows, or + * GHOSTTY_INVALID_VALUE if an argument is invalid + * + * @ingroup formatter + */ +GHOSTTY_API GhosttyResult ghostty_formatter_format( + GhosttyFormatter formatter, + GhosttyWriter writer); + /** * Run the formatter and produce output into the caller-provided buffer. * @@ -171,6 +196,8 @@ GHOSTTY_API GhosttyResult ghostty_formatter_format_buf(GhosttyFormatter formatte * The caller is responsible for freeing the returned buffer with * ghostty_free(), passing the same allocator (or NULL for the default) * that was used for the allocation. + * Empty output returns GHOSTTY_SUCCESS with *out_ptr set to NULL and + * *out_len set to zero. This result can be passed to ghostty_free(). * * @param formatter The formatter handle (must not be NULL) * @param allocator Pointer to allocator, or NULL to use the default allocator diff --git a/vendor/libghostty-vt/include/ghostty/vt/io.h b/vendor/libghostty-vt/include/ghostty/vt/io.h new file mode 100644 index 00000000..ad2c57ad --- /dev/null +++ b/vendor/libghostty-vt/include/ghostty/vt/io.h @@ -0,0 +1,151 @@ +/** + * @file io.h + * + * Generic IO callbacks for libghostty-vt. + */ + +#ifndef GHOSTTY_VT_IO_H +#define GHOSTTY_VT_IO_H + +#include +#include +#include +#include + +/** @defgroup io I/O + * + * Synchronous callback interfaces used by APIs that consume or produce byte + * streams. The callback and userdata pointers must remain valid for the full + * lifetime documented by the API receiving a GhosttyReader or GhosttyWriter. + * + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Read bytes from a source. + * + * The callback must set @p out_read to a value no greater than @p capacity + * when returning true. A positive value reports progress; it may be less than + * capacity and does not indicate end-of-file. A zero value is definitive + * end-of-file. It must not be used to report temporary input starvation or a + * would-block condition. + * + * Returning false reports a fatal read error and the value of @p out_read is + * ignored. The library does not inspect or modify errno. + * + * All pointer arguments are borrowed and valid only for the duration of the + * callback. The callback is invoked synchronously on the calling thread. + * + * @param userdata Opaque userdata from GhosttyReader + * @param buffer Destination for read bytes; always non-NULL + * @param capacity Writable capacity of @p buffer; always greater than zero + * @param[out] out_read Number of bytes read when returning true; non-NULL + * @return true for a successful read or end-of-file, false for a fatal error + */ +typedef bool (*GhosttyReaderFn)( + void* userdata, + uint8_t* buffer, + size_t capacity, + size_t* out_read); + +/** + * Write bytes to a destination. + * + * Returning true means all @p len bytes were accepted. Returning false + * reports a fatal write error. A callback wrapping an interface that permits + * partial writes must retry internally until the full slice is accepted or + * an error occurs. + * + * On failure, the destination may already contain a prefix of the bytes. The + * calling operation fails and must not be resumed from that partial output. + * The library does not inspect or modify errno. + * + * @p data is borrowed and valid only for the duration of the callback. The + * callback is invoked synchronously on the calling thread. Successful return + * means the bytes were handed to the destination; it does not imply that the + * destination was flushed or made durable. + * + * @param userdata Opaque userdata from GhosttyWriter + * @param data Source bytes; always non-NULL + * @param len Number of source bytes; always greater than zero + * @return true if the complete slice was accepted, false on fatal error + */ +typedef bool (*GhosttyWriterFn)( + void* userdata, + const uint8_t* data, + size_t len); + +/** + * A byte source callback and its opaque context. + * + * The struct is passed by value. @p read must be non-NULL. + */ +typedef struct { + GhosttyReaderFn read; + void* userdata; +} GhosttyReader; + +/** + * A byte destination callback and its opaque context. + * + * The struct is passed by value. @p write must be non-NULL. + */ +typedef struct { + GhosttyWriterFn write; + void* userdata; +} GhosttyWriter; + +/** + * Read one MIME-typed representation of some content, streaming its + * bytes to a writer. + * + * The library calls this with the MIME type of the representation it + * needs. The callback writes all of that representation's data to + * @p writer, in as many calls to `writer.write(writer.userdata, data, + * len)` as is convenient (one call with everything or many small + * pieces both work), and returns true. Nothing written is retained + * beyond each write call, so the data may be borrowed from anywhere: + * a pasteboard item, a file being read, a stream. + * + * Returning false reports that the data could not be read. If the + * writer refuses a write (returns false), stop and return false + * without writing more. + * + * All pointer arguments, the mime, and the writer are borrowed and + * valid only for the duration of the callback. The callback is + * invoked synchronously on the calling thread. The API receiving the + * GhosttyMimeReader defines which MIME types are requested, how many + * times, and any consistency requirements across repeated reads. + * + * @param userdata Opaque userdata from GhosttyMimeReader + * @param mime The MIME type of the representation to read + * @param writer Where to write the data; valid only during this call + * @return true once all the data was written, false if it could not + * be read or the writer refused a write + */ +typedef bool (*GhosttyMimeReaderFn)( + void* userdata, + GhosttyString mime, + GhosttyWriter writer); + +/** + * A MIME-typed content source callback and its opaque context. + * + * The struct is passed by value. @p read must be non-NULL. + */ +typedef struct { + GhosttyMimeReaderFn read; + void* userdata; +} GhosttyMimeReader; + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* GHOSTTY_VT_IO_H */ diff --git a/vendor/libghostty-vt/include/ghostty/vt/key.h b/vendor/libghostty-vt/include/ghostty/vt/key.h index 61b95475..517d0c30 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/key.h +++ b/vendor/libghostty-vt/include/ghostty/vt/key.h @@ -42,8 +42,7 @@ * @code{.c} * // Create a terminal and feed it some VT data that changes modes * GhosttyTerminal terminal; - * ghostty_terminal_new(NULL, &terminal, - * (GhosttyTerminalOptions){.cols = 80, .rows = 24, .max_scrollback = 0}); + * ghostty_terminal_new(NULL, &terminal, 80, 24); * * // Application might write data that enables Kitty keyboard protocol, etc. * ghostty_terminal_vt_write(terminal, vt_data, vt_len); diff --git a/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h b/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h index dda8b836..99cee60a 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h +++ b/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h @@ -390,7 +390,8 @@ typedef enum GHOSTTY_ENUM_TYPED { /** * Borrowed pointer to the raw pixel data. Valid as long as the - * underlying terminal is not mutated. + * underlying terminal is not mutated. Returns GHOSTTY_NO_VALUE when + * the image metadata is resident but its pixel payload is pending. * * The data is always fully decoded, uncompressed pixels in the * format reported by GHOSTTY_KITTY_IMAGE_DATA_FORMAT: zlib payloads @@ -398,13 +399,21 @@ typedef enum GHOSTTY_ENUM_TYPED { * time, before the image is stored. Consumers can upload this * directly to the GPU without any decode step. * + * For an animated image (Kitty graphics animation, actions a=f/a=a) + * this is the pixel data of the current animation frame. The + * image's GHOSTTY_KITTY_IMAGE_DATA_GENERATION changes whenever the + * current frame changes, so generation-keyed caches remain + * coherent. + * * Output type: const uint8_t ** */ GHOSTTY_KITTY_IMAGE_DATA_DATA_PTR = 7, /** * Length of the raw pixel data in bytes. Always equal to - * width * height * bytes-per-pixel for the reported format. + * width * height * bytes-per-pixel for the reported format. For a + * pending image, this is the expected length reserved against the + * storage limit even though DATA_PTR is not available yet. * * Output type: size_t * */ @@ -421,7 +430,10 @@ typedef enum GHOSTTY_ENUM_TYPED { * Stamps are unique and monotonically increasing process-wide and * are drawn from the same sequence as * GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION. Never zero for a stored - * image, so zero can be used as an "empty" sentinel by callers. + * image, so zero can be used as an "empty" sentinel by callers. Pending + * payload completion preserves this value to retain image age; consumers + * detect that completion through GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION + * and retry DATA_PTR. * * Output type: uint64_t * */ diff --git a/vendor/libghostty-vt/include/ghostty/vt/modes.h b/vendor/libghostty-vt/include/ghostty/vt/modes.h index 8e1fd911..6786f004 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/modes.h +++ b/vendor/libghostty-vt/include/ghostty/vt/modes.h @@ -92,7 +92,9 @@ extern "C" { #define GHOSTTY_MODE_SYNC_OUTPUT (ghostty_mode_new(2026, false)) /**< Synchronized output */ #define GHOSTTY_MODE_GRAPHEME_CLUSTER (ghostty_mode_new(2027, false)) /**< Grapheme cluster mode */ #define GHOSTTY_MODE_COLOR_SCHEME_REPORT (ghostty_mode_new(2031, false)) /**< Report color scheme */ +#define GHOSTTY_MODE_VISIBILITY_REPORT (ghostty_mode_new(2033, false)) /**< Report terminal visibility */ #define GHOSTTY_MODE_IN_BAND_RESIZE (ghostty_mode_new(2048, false)) /**< In-band size reports */ +#define GHOSTTY_MODE_PASTE_EVENTS (ghostty_mode_new(5522, false)) /**< Kitty clipboard protocol paste events */ /** @} */ /** diff --git a/vendor/libghostty-vt/include/ghostty/vt/mouse.h b/vendor/libghostty-vt/include/ghostty/vt/mouse.h index 4ba5f52e..4a582a23 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/mouse.h +++ b/vendor/libghostty-vt/include/ghostty/vt/mouse.h @@ -39,8 +39,7 @@ * @code{.c} * // Create a terminal and feed it some VT data that enables mouse tracking * GhosttyTerminal terminal; - * ghostty_terminal_new(NULL, &terminal, - * (GhosttyTerminalOptions){.cols = 80, .rows = 24, .max_scrollback = 0}); + * ghostty_terminal_new(NULL, &terminal, 80, 24); * * // Application might write data that enables mouse reporting, etc. * ghostty_terminal_vt_write(terminal, vt_data, vt_len); diff --git a/vendor/libghostty-vt/include/ghostty/vt/osc.h b/vendor/libghostty-vt/include/ghostty/vt/osc.h index 9409ebc7..7a681c3b 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/osc.h +++ b/vendor/libghostty-vt/include/ghostty/vt/osc.h @@ -63,6 +63,10 @@ typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_OSC_COMMAND_CONEMU_XTERM_EMULATION = 20, GHOSTTY_OSC_COMMAND_CONEMU_COMMENT = 21, GHOSTTY_OSC_COMMAND_KITTY_TEXT_SIZING = 22, + GHOSTTY_OSC_COMMAND_KITTY_CLIPBOARD_PROTOCOL = 23, + GHOSTTY_OSC_COMMAND_KITTY_DND_PROTOCOL = 24, + GHOSTTY_OSC_COMMAND_CONTEXT_SIGNAL = 25, + GHOSTTY_OSC_COMMAND_KITTY_DESKTOP_NOTIFICATION = 26, GHOSTTY_OSC_COMMAND_TYPE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyOscCommandType; diff --git a/vendor/libghostty-vt/include/ghostty/vt/paste.h b/vendor/libghostty-vt/include/ghostty/vt/paste.h index b3df5be4..4ba21a9a 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/paste.h +++ b/vendor/libghostty-vt/include/ghostty/vt/paste.h @@ -1,26 +1,67 @@ /** * @file paste.h * - * Paste utilities - validate and encode paste data for terminal input. + * Paste - paste into a terminal, and validate and encode paste data. */ #ifndef GHOSTTY_VT_PASTE_H #define GHOSTTY_VT_PASTE_H -/** @defgroup paste Paste Utilities - * - * Utilities for validating and encoding paste data for terminal input. - * - * ## Basic Usage - * - * Use ghostty_paste_is_safe() to check if paste data contains potentially - * dangerous sequences before sending it to the terminal. - * - * Use ghostty_paste_encode() to encode paste data for writing to the pty, +/** @defgroup paste Paste + * + * Pasting into a terminal, plus the terminal-free utilities for + * validating and encoding paste data. + * + * ## Pasting into a Terminal + * + * What a paste writes to the pty depends on the terminal's state, so + * the recommended way to paste is ghostty_terminal_paste(). The embedder + * hands over the MIME types the clipboard holds (just `text/plain` for + * an ordinary paste), a GhosttyMimeReader that produces the data of + * any one of them, and where the paste came from, and the terminal + * decides how its current modes apply: + * + * - If Kitty clipboard protocol paste events (mode 5522, + * GHOSTTY_MODE_PASTE_EVENTS) are enabled, the paste was user-initiated + * (GHOSTTY_PASTE_SOURCE_CLIPBOARD), and a clipboard_read callback is + * installed, the terminal sends the program a paste event listing the + * clipboard's MIME types with a one-time password instead of the data. + * The program then reads what it wants through the clipboard_read + * callback, which arrives with `granted` set so no permission prompt + * is needed. No data is read for the event. + * - Otherwise the first text representation is written: unsafe control + * bytes are replaced with spaces, and it is wrapped in bracketed paste + * sequences if mode 2004 (GHOSTTY_MODE_BRACKETED_PASTE) is enabled, or + * has its newlines converted to carriage returns if not. + * + * The data is pulled through GhosttyPaste::reader only when a + * representation is actually pasted (so a clipboard holding a large + * image next to some text costs nothing), and the encoded bytes + * stream to the write_pty callback (GHOSTTY_TERMINAL_OPT_WRITE_PTY) + * in chunks as they are produced, never in one piece. The callback + * may be invoked several times for a single paste; the pieces must be + * written to the pty in order. + * + * Text that could inject commands (a newline when unbracketed, or the + * bracketed paste terminator when bracketed) is refused with + * GHOSTTY_REJECTED and nothing written unless GhosttyPaste::allow_unsafe + * is set. The usual flow is to call once, confirm with the user on + * GHOSTTY_REJECTED, and call again with `allow_unsafe` set. Each call + * reads the text at most once and buffers it whole while the rule is + * applied, so the source needs no stability across reads (the + * confirmed retry simply pastes whatever the source holds then) and a + * refused or failed paste writes nothing at all. + * + * @snippet c-vt-paste/src/main.c terminal-paste + * + * ## Building Blocks + * + * For embedders that encode without a terminal, ghostty_paste_is_safe() + * checks if paste data contains potentially dangerous sequences + * (conservatively, regardless of terminal state) and + * ghostty_paste_encode() encodes paste data for writing to the pty, * including bracketed paste wrapping and unsafe byte stripping. * - * ## Examples - * * ### Safety Check * * @snippet c-vt-paste/src/main.c paste-safety @@ -35,11 +76,119 @@ #include #include #include +#include +#include #ifdef __cplusplus extern "C" { #endif +/** + * Why a paste happened. + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** The user pasted from a clipboard: keybind, menu, middle click. */ + GHOSTTY_PASTE_SOURCE_CLIPBOARD = 0, + + /** + * Text inserted some other way: IME commit, drag and drop, scripted + * input. Always written as text, never as a paste event, matching + * kitty. This is not a way to opt out of paste events; an embedder + * that doesn't want them doesn't install a clipboard_read callback. + */ + GHOSTTY_PASTE_SOURCE_TEXT = 1, + GHOSTTY_PASTE_SOURCE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttyPasteSource; + +/** + * A paste of clipboard contents into the terminal. + * + * This is a sized struct; set `size` to `sizeof(GhosttyPaste)`. The + * MIME type array and the strings it points to are borrowed only for + * the duration of the ghostty_terminal_paste() call, as is everything + * the reader produces. + */ +typedef struct { + /** Size of this struct in bytes. */ + size_t size; + + /** + * The clipboard the contents came from. Reported to the program on a + * paste event (the selection and primary locations are both reported + * as the primary selection, the protocol knows only two); no effect + * on a text paste. + */ + GhosttyClipboardLocation location; + + /** Why this paste happened. */ + GhosttyPasteSource source; + + /** + * Borrowed array of the MIME types of the representations available, + * in preferred order. A text paste reads and writes the first entry + * with a text MIME type such as "text/plain" and ignores the rest. A + * paste event lists every entry and reads none. May be NULL when + * mimes_len is zero, which is nothing to paste. + */ + const GhosttyString* mimes; + + /** Number of entries in mimes. */ + size_t mimes_len; + + /** + * Produces the data of a representation on demand. Required when + * mimes_len is nonzero. + * + * Called at most once per ghostty_terminal_paste() call: for the + * text representation being pasted, never for anything else and + * never for a paste event. The MIME type requested is always an + * entry of `mimes`, passed through exactly as given there (the same + * pointer and length), so the callback may identify the + * representation by pointer or by content. A false return fails the + * paste with GHOSTTY_IO_ERROR. + */ + GhosttyMimeReader reader; + + /** + * Write text that could inject commands. Call with false, confirm + * with the user on GHOSTTY_REJECTED, and call again with true. + */ + bool allow_unsafe; +} GhosttyPaste; + +/** + * Paste into the terminal according to its current state: a Kitty + * clipboard protocol paste event if mode 5522 is enabled and a + * clipboard_read callback is installed, otherwise the text framed per + * mode 2004. See the group documentation for the full behavior. Output + * streams through the write_pty callback in chunks. The viewport is not + * scrolled; that is up to the embedder, as for key input. + * + * A paste event records a session grant for its one-time password only + * once the event is written; a failed call never leaves a grant for an + * event that was never sent. + * + * @param terminal The terminal handle + * @param paste The paste request, borrowed for the duration of the call + * @param[out] out_written On success, whether anything was written to + * the pty (the encoded text or a paste event). False means + * there was nothing to paste: no non-empty text + * representation. May be NULL. + * @return GHOSTTY_SUCCESS on success (see @p out_written); + * GHOSTTY_REJECTED if the text could inject commands and + * GhosttyPaste::allow_unsafe is false (nothing was written); + * GHOSTTY_INVALID_VALUE for a NULL terminal or paste, MIME + * types without a reader, or when no write_pty callback is + * installed; GHOSTTY_OUT_OF_MEMORY; GHOSTTY_IO_ERROR if the + * reader failed or there is no secure entropy source to mint a + * paste event password (wasm32-freestanding without + * GHOSTTY_SYS_OPT_RANDOM_SECURE set). Errors write nothing. + */ +GHOSTTY_API GhosttyResult ghostty_terminal_paste( + GhosttyTerminal terminal, + const GhosttyPaste* paste, + bool* out_written); + /** * Check if paste data is safe to paste into the terminal. * @@ -49,7 +198,9 @@ extern "C" { * to exit bracketed paste mode and inject commands * * This check is conservative and considers data unsafe regardless of - * current terminal state. + * current terminal state. ghostty_terminal_paste() applies the + * terminal-state-aware rule itself (newlines are safe inside a + * bracketed paste); use this to apply the stricter rule on top. * * @param data The paste data to check (must not be NULL) * @param len The length of the data in bytes @@ -74,6 +225,9 @@ GHOSTTY_API bool ghostty_paste_is_safe(const char* data, size_t len); * GHOSTTY_OUT_OF_SPACE and sets the required size in @p out_written. * The caller can then retry with a sufficiently sized buffer. * + * This is the encoder ghostty_terminal_paste() uses for a text paste; + * use it directly when there is no terminal to paste into. + * * @param data The paste data to encode (modified in place, may be NULL) * @param data_len The length of the input data in bytes * @param bracketed Whether bracketed paste mode is active diff --git a/vendor/libghostty-vt/include/ghostty/vt/point.h b/vendor/libghostty-vt/include/ghostty/vt/point.h index 8b717f49..9cab2758 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/point.h +++ b/vendor/libghostty-vt/include/ghostty/vt/point.h @@ -9,6 +9,8 @@ #include +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/vendor/libghostty-vt/include/ghostty/vt/render.h b/vendor/libghostty-vt/include/ghostty/vt/render.h index 2e3f2f71..f6b5e222 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/render.h +++ b/vendor/libghostty-vt/include/ghostty/vt/render.h @@ -63,7 +63,10 @@ extern "C" { * tracking which rows in a partially dirty frame have changed. * * The user of the render state API is expected to unset both of these. - * The `update` call does not unset dirty state, it only updates it. + * The `update` call does not unset dirty state, it only updates it. After + * successfully rendering a complete frame, use ghostty_render_state_clean() + * to unset both layers in one call. The granular setters remain available + * for callers that only consume part of a frame. * * An extremely important detail: setting one dirty state doesn't unset * the other. For example, setting the global dirty state to false does not @@ -199,6 +202,14 @@ typedef enum GHOSTTY_ENUM_TYPED { /** Whether the cursor is on the tail of a wide character (bool). * Only valid when CURSOR_VIEWPORT_HAS_VALUE is true. */ GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_WIDE_TAIL = 17, + + /** All cursor state in one sized struct (GhosttyRenderStateCursor). + * Initialize the output with GHOSTTY_INIT_SIZED before querying. */ + GHOSTTY_RENDER_STATE_DATA_CURSOR = 18, + + /** All render-state colors in one sized struct (GhosttyRenderStateColors). + * Initialize the output with GHOSTTY_INIT_SIZED before querying. */ + GHOSTTY_RENDER_STATE_DATA_COLORS = 19, GHOSTTY_RENDER_STATE_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyRenderStateData; @@ -236,6 +247,22 @@ typedef enum GHOSTTY_ENUM_TYPED { /** Row-local selected cell range (GhosttyRenderStateRowSelection). */ GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION = 4, + + /** A borrowed view of the raw cell values for the current row + * (GhosttyCellsView). One value per column, identical to querying + * GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_RAW for each cell. The view + * is only valid as long as the underlying render state is not + * updated; it is unsafe to use after updating the render state. + * + * This is the bulk alternative to iterating cells one at a time. + * It lets callers with expensive call boundaries (e.g. WebAssembly + * embedders) read an entire row with a single call. + * + * Bit positions aren't protected by ABI, so callers should parse them + * out of the manifest from `ghostty_type_json`. Callers with access + * to the C header or without high FFI costs should use `ghostty_cell_get`. + */ + GHOSTTY_RENDER_STATE_ROW_DATA_CELLS_RAW = 5, GHOSTTY_RENDER_STATE_ROW_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyRenderStateRowData; @@ -273,17 +300,59 @@ typedef struct { uint16_t end_x; } GhosttyRenderStateRowSelection; +/** + * Render-state cursor information. + * + * This struct uses the sized-struct ABI pattern. Initialize with + * GHOSTTY_INIT_SIZED(GhosttyRenderStateCursor) before querying + * GHOSTTY_RENDER_STATE_DATA_CURSOR. + * + * When viewport_has_value is false, viewport_x, viewport_y, and wide_tail + * contain undefined data and must not be read. + * + * @ingroup render + */ +typedef struct { + /** Size of this struct in bytes. Must be set to sizeof(GhosttyRenderStateCursor). */ + size_t size; + + /** Whether the cursor is visible within the viewport. */ + bool viewport_has_value; + + /** Cursor viewport x position in cells. */ + uint16_t viewport_x; + + /** Cursor viewport y position in cells. */ + uint16_t viewport_y; + + /** Whether the cursor is on the tail of a wide character. */ + bool wide_tail; + + /** Whether the cursor is visible based on terminal modes. */ + bool visible; + + /** Whether the cursor should blink based on terminal modes. */ + bool blinking; + + /** Whether the cursor is at a password input field. */ + bool password_input; + + /** The visual style of the cursor. */ + GhosttyRenderStateCursorVisualStyle visual_style; +} GhosttyRenderStateCursor; + /** * Render-state color information. * * This struct uses the sized-struct ABI pattern. Initialize with - * GHOSTTY_INIT_SIZED(GhosttyRenderStateColors) before calling - * ghostty_render_state_colors_get(). + * GHOSTTY_INIT_SIZED(GhosttyRenderStateColors) before querying + * GHOSTTY_RENDER_STATE_DATA_COLORS. * * Example: * @code * GhosttyRenderStateColors colors = GHOSTTY_INIT_SIZED(GhosttyRenderStateColors); - * GhosttyResult result = ghostty_render_state_colors_get(state, &colors); + * GhosttyResult result = ghostty_render_state_get( + * state, GHOSTTY_RENDER_STATE_DATA_COLORS, &colors); * @endcode * * @ingroup render @@ -408,6 +477,23 @@ GHOSTTY_API GhosttyResult ghostty_render_state_begin_update(GhosttyRenderState s */ GHOSTTY_API GhosttyResult ghostty_render_state_end_update(GhosttyRenderState state); +/** + * Mark all dirty render-state data as consumed. + * + * This sets the global dirty state to GHOSTTY_RENDER_STATE_DIRTY_FALSE and + * clears every per-row dirty flag. It is idempotent and does not modify cell + * contents or dirty state owned by the terminal. Call this only after a + * complete frame has been rendered successfully; partial consumers should + * use ghostty_render_state_set() and ghostty_render_state_row_set() instead. + * + * @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE) + * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` is + * NULL + * + * @ingroup render + */ +GHOSTTY_API GhosttyResult ghostty_render_state_clean(GhosttyRenderState state); + /** * Get a value from a render state. * @@ -417,8 +503,9 @@ GHOSTTY_API GhosttyResult ghostty_render_state_end_update(GhosttyRenderState sta * @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE) * @param data The data kind to query * @param[out] out Pointer to receive the queried value - * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` is - * NULL or `data` is not a recognized enum value + * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` or + * `out` is NULL, `data` is not a recognized enum value, or a sized + * output struct is smaller than `sizeof(size_t)` * * @ingroup render */ @@ -473,24 +560,6 @@ GHOSTTY_API GhosttyResult ghostty_render_state_set(GhosttyRenderState state, GhosttyRenderStateOption option, const void* value); -/** - * Get the current color information from a render state. - * - * This writes as many fields as fit in the caller-provided sized struct. - * `out_colors->size` must be set by the caller (typically via - * GHOSTTY_INIT_SIZED(GhosttyRenderStateColors)). - * - * @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE) - * @param[out] out_colors Sized output struct to receive render-state colors - * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` or - * `out_colors` is NULL, or if `out_colors->size` is smaller than - * `sizeof(size_t)` - * - * @ingroup render - */ -GHOSTTY_API GhosttyResult ghostty_render_state_colors_get(GhosttyRenderState state, - GhosttyRenderStateColors* out_colors); - /** * Create a new row iterator instance. * @@ -521,7 +590,8 @@ GHOSTTY_API void ghostty_render_state_row_iterator_free(GhosttyRenderStateRowIte /** * Move a render-state row iterator to the next row. * - * Returns true if the iterator moved successfully and row data is + * Rows are visited contiguously in ascending viewport order, starting at + * y = 0. Returns true if the iterator moved successfully and row data is * available to read at the new position. * * @param iterator The iterator handle to advance (may be NULL) @@ -532,12 +602,36 @@ GHOSTTY_API void ghostty_render_state_row_iterator_free(GhosttyRenderStateRowIte */ GHOSTTY_API bool ghostty_render_state_row_iterator_next(GhosttyRenderStateRowIterator iterator); +/** + * Move a render-state row iterator to the next row requiring a redraw. + * + * If the global dirty state is GHOSTTY_RENDER_STATE_DIRTY_FALSE, this returns + * false. If it is GHOSTTY_RENDER_STATE_DIRTY_PARTIAL, clean rows are skipped. + * If it is GHOSTTY_RENDER_STATE_DIRTY_FULL, every remaining row is returned + * regardless of its per-row dirty flag. Rows are returned in ascending + * viewport order. This function does not clear any dirty state. + * + * @param iterator The iterator handle to advance (NULL returns false) + * @param[out] out_y Receives the viewport y coordinate when true is returned + * (NULL returns false); it is not modified when false is + * returned + * @return true if advanced to a row requiring a redraw, false if an argument + * is NULL or the iterator has reached the end of the effective dirty + * rows + * + * @ingroup render + */ +GHOSTTY_API bool ghostty_render_state_row_iterator_next_dirty( + GhosttyRenderStateRowIterator iterator, + uint16_t* out_y); + /** * Get a value from the current row in a render-state row iterator. * * The `out` pointer must point to a value of the type corresponding to the * requested data kind (see GhosttyRenderStateRowData). - * Call ghostty_render_state_row_iterator_next() at least once before + * Call ghostty_render_state_row_iterator_next() or + * ghostty_render_state_row_iterator_next_dirty() at least once before * calling this function. * * @param iterator The iterator handle to query (NULL returns GHOSTTY_INVALID_VALUE) @@ -586,7 +680,8 @@ GHOSTTY_API GhosttyResult ghostty_render_state_row_get_multi( * * The `value` pointer must point to a value of the type corresponding to the * requested option kind (see GhosttyRenderStateRowOption). - * Call ghostty_render_state_row_iterator_next() at least once before + * Call ghostty_render_state_row_iterator_next() or + * ghostty_render_state_row_iterator_next_dirty() at least once before * calling this function. * * @param iterator The iterator handle to update (NULL returns GHOSTTY_INVALID_VALUE) diff --git a/vendor/libghostty-vt/include/ghostty/vt/screen.h b/vendor/libghostty-vt/include/ghostty/vt/screen.h index 9f639b58..2899989d 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/screen.h +++ b/vendor/libghostty-vt/include/ghostty/vt/screen.h @@ -21,19 +21,21 @@ extern "C" { * Terminal screen cell and row types. * * These types represent the contents of a terminal screen. A GhosttyCell - * is a single grid cell and a GhosttyRow is a single row. Both are opaque - * values whose fields are accessed via ghostty_cell_get() and - * ghostty_row_get() respectively. + * is a single grid cell and a GhosttyRow is a single row. Cell fields can + * be accessed via ghostty_cell_get() or decoded from the packed layout in + * ghostty_type_json(). Rows are opaque and accessed via ghostty_row_get(). * * @{ */ /** - * Opaque cell value. + * Packed cell value. * - * Represents a single terminal cell. The internal layout is opaque and - * must be queried via ghostty_cell_get(). Obtain cell values from - * terminal query APIs. + * Represents a single terminal cell. Portable callers can query fields via + * ghostty_cell_get(). Boundary-sensitive callers can decode the packed value + * using the GhosttyCell descriptor returned by ghostty_type_json(). The + * manifest is authoritative for the linked build; hardcoding bit positions + * is unsupported. * * @ingroup screen */ @@ -50,6 +52,24 @@ typedef uint64_t GhosttyCell; */ typedef uint64_t GhosttyRow; +/** + * A borrowed view of contiguous raw cell values. + * + * The memory is not owned by this struct. The pointer is only valid + * for the lifetime documented by the API that produces it. Each value + * can be queried via ghostty_cell_get() or decoded using the GhosttyCell + * packed descriptor returned by ghostty_type_json(). + * + * @ingroup screen + */ +typedef struct { + /** Pointer to len contiguous cell values. */ + const GhosttyCell* ptr; + + /** Number of cells. */ + size_t len; +} GhosttyCellsView; + /** * Cell content tag. * diff --git a/vendor/libghostty-vt/include/ghostty/vt/search.h b/vendor/libghostty-vt/include/ghostty/vt/search.h new file mode 100644 index 00000000..68aebcc4 --- /dev/null +++ b/vendor/libghostty-vt/include/ghostty/vt/search.h @@ -0,0 +1,501 @@ +/** + * @file search.h + * + * Search terminal contents, including scrollback, for a string. + */ + +#ifndef GHOSTTY_VT_SEARCH_H +#define GHOSTTY_VT_SEARCH_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup search Search + * + * Search a terminal for a string, covering the active area and + * scrollback of both the primary and alternate screens. + * + * A GhosttySearch searches the terminal it was created with for a + * needle set with GHOSTTY_SEARCH_OPT_NEEDLE. It handles the hard + * parts of terminal search internally: results stay in sync with the + * live screens, survive primary/alternate screen switches (entering + * and leaving a fullscreen app such as vim does not restart a + * scrollback search), and recover from resize, reflow, resets, and + * scrollback pruning. + * + * A search starts idle. Setting the needle starts the search, + * changing it restarts the search from scratch, and clearing it + * returns the search to idle. Matching is byte-exact except ASCII + * letters, which compare case-insensitively. + * + * ## Driving a search + * + * Searching a large scrollback takes time, so the work is split into + * small steps the caller drives so that the caller can control + * performance more directly: + * + * - ghostty_search_tick() makes a bounded amount of progress on data + * the search has already copied. It never touches the terminal, + * meaning it can be safely called from a thread. + * - ghostty_search_feed() reads the terminal to copy in more data and + * pick up terminal changes. Feeding is the only way the search + * learns that the terminal changed, so keep feeding periodically + * while the search is in use. This requires exclusive terminal access. + * - ghostty_search_run() is a blocking convenience that feeds and + * ticks until the search is caught up. + * + * GHOSTTY_SEARCH_STATUS_COMPLETE means the search is caught up with + * the terminal as of the last feed. It never means finished forever, + * since later terminal writes require another feed to be seen. + * + * ## Matches are selections + * + * Every match is returned as a GhosttySelection snapshot with + * rectangle set to false, so the existing selection APIs all work on + * matches: ghostty_terminal_selection_format_buf() to copy the + * matched text, ghostty_terminal_point_from_grid_ref() with + * GHOSTTY_POINT_TAG_VIEWPORT to position highlight rectangles, + * ghostty_terminal_selection_contains() for hit testing, and + * ghostty_terminal_set() with GHOSTTY_TERMINAL_OPT_SELECTION to make + * a match the terminal's selection. + * + * Returned matches follow the usual snapshot lifetime rules: they are + * only valid until the next operation that modifies the terminal, + * including ghostty_terminal_vt_write(), resize, reset, and free. + * Read matches after a feed, use them before the terminal changes + * again, and re-read them rather than caching them. The selected + * match is kept accurate internally across terminal changes, so the + * safe way to follow a match is to re-read + * GHOSTTY_SEARCH_DATA_SELECTED_MATCH after each feed. + * + * ## Lifetime + * + * The search borrows the terminal it was created with and never frees + * it. Any number of searches, alongside other terminal readers such + * as formatters and render states, may share one terminal. + * + * The search and its terminal can be freed in either order. Freeing + * the search first releases tracked state it holds within the + * terminal. If the terminal is freed first, the search detects this: + * calls that need the terminal return GHOSTTY_INVALID_VALUE, reads + * return whatever the search last saw, and ghostty_search_free() + * releases only search-owned memory. A search cannot be rebound, so + * searching another terminal means creating a new search. + * + * ## Threading + * + * The library creates no threads. Calls on one GhosttySearch are not + * safe to make concurrently with each other, so the caller must + * serialize them. + * + * Functions that touch the terminal (ghostty_search_new(), + * ghostty_search_feed(), ghostty_search_run(), ghostty_search_set() + * with the needle and select options, and ghostty_search_free()) must + * also be serialized with all other access to the same terminal. + * + * Everything else (ghostty_search_tick(), ghostty_search_get(), and + * ghostty_search_get_multi()) only touches memory owned by the search + * and is safe to call while another thread modifies the terminal. + * This split is how Ghostty runs search on a background thread: tick + * freely, and take the terminal lock only to feed. Reading returned + * match values is always safe, but passing them to APIs that take the + * terminal follows the terminal serialization rule above. + * + * ## Example + * + * @snippet c-vt-search/src/main.c search-main + * + * @{ + */ + +/** + * Progress state of a search. + * + * @ingroup search + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** + * ghostty_search_tick() can make progress without terminal access. + */ + GHOSTTY_SEARCH_STATUS_RUNNING = 0, + + /** + * Blocked until ghostty_search_feed(). This is also the state right + * after a needle is set, since the search has not yet seen the + * terminal. + */ + GHOSTTY_SEARCH_STATUS_FEED_REQUIRED = 1, + + /** + * Caught up with the terminal state as of the last feed. This never + * means finished forever, since later terminal writes require + * another feed to be seen. A search with no needle set also reports + * complete, since there is nothing to look for. + */ + GHOSTTY_SEARCH_STATUS_COMPLETE = 2, + + GHOSTTY_SEARCH_STATUS_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttySearchStatus; + +/** + * Scroll policy applied when a match becomes selected via + * GHOSTTY_SEARCH_OPT_SELECT_NEXT or GHOSTTY_SEARCH_OPT_SELECT_PREV. + * + * @ingroup search + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** Scroll the viewport so the match is visible, only if it is not + * already visible. This is the default. */ + GHOSTTY_SEARCH_SCROLL_IF_NEEDED = 0, + + /** Never scroll the viewport. */ + GHOSTTY_SEARCH_SCROLL_NONE = 1, + + GHOSTTY_SEARCH_SCROLL_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttySearchScroll; + +/** + * Data fields readable with ghostty_search_get(). The output value + * type is documented per field. + * + * All reads reflect the terminal's active screen as of the last feed. + * When the running application switches to the alternate screen, the + * next feed switches counts, matches, and selection to that screen's + * results. Primary screen results, including completed scrollback + * searches, are retained and restored on the way back. + * + * @ingroup search + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** Current search status: GhosttySearchStatus*. */ + GHOSTTY_SEARCH_DATA_STATUS = 0, + + /** + * The needle this search is looking for: GhosttyString*. The bytes + * are borrowed from the search and remain valid until the needle is + * changed or the search is freed. Returns GHOSTTY_NO_VALUE when no + * needle is set. + */ + GHOSTTY_SEARCH_DATA_NEEDLE = 1, + + /** + * Total matches found so far on the active screen: size_t*. Zero + * until the first feed. + */ + GHOSTTY_SEARCH_DATA_TOTAL_MATCHES = 2, + + /** + * Index of the selected match: size_t*. This indexes the newest to + * oldest ordering of GHOSTTY_SEARCH_DATA_MATCHES, where 0 is the + * newest match, so a "k of n" find bar renders index + 1 of + * GHOSTTY_SEARCH_DATA_TOTAL_MATCHES. Returns GHOSTTY_NO_VALUE when + * nothing is selected. + */ + GHOSTTY_SEARCH_DATA_SELECTED_INDEX = 3, + + /** + * The selected match: GhosttySelection*. This is an untracked + * snapshot with standard GhosttySelection lifetime rules. Returns + * GHOSTTY_NO_VALUE when nothing is selected. + */ + GHOSTTY_SEARCH_DATA_SELECTED_MATCH = 4, + + /** + * All matches on the active screen, ordered newest to oldest, from + * the bottom of the active area up through scrollback: + * GhosttySelectionBuffer*. Set ptr to NULL with cap 0 to query the + * required capacity. An undersized buffer returns + * GHOSTTY_OUT_OF_SPACE with the required capacity in len. + */ + GHOSTTY_SEARCH_DATA_MATCHES = 5, + + /** + * Matches on the pages covering the viewport, for drawing highlight + * rectangles: GhosttySelectionBuffer*. The list is computed during + * feeds and cached, so it reflects the viewport as of the last + * feed. + * + * Matches are found a page at a time, so the list can include + * matches slightly outside the visible viewport when they share a + * page with it. Ghostty's own renderer behaves the same way. + * Converting each match to viewport coordinates with + * ghostty_terminal_point_from_grid_ref() clips this naturally: skip + * matches that fail the conversion or whose row is beyond the + * visible row count. + */ + GHOSTTY_SEARCH_DATA_VIEWPORT_MATCHES = 6, + + /** Current scroll policy: GhosttySearchScroll*. */ + GHOSTTY_SEARCH_DATA_SELECT_SCROLL = 7, + + GHOSTTY_SEARCH_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttySearchData; + +/** + * Options writable with ghostty_search_set(). The value type, and + * what a NULL value means, is documented per option. + * + * @ingroup search + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** + * Set the needle to search for: const GhosttyString*. The bytes are + * copied, so the caller's memory does not need to outlive the call. + * Matching is byte-exact except ASCII letters, which compare + * case-insensitively. + * + * Changing the needle restarts the search from scratch and drops + * all results. As an exception, setting a needle equal to the current + * one (compared the same way as matching) keeps existing results, + * so find bars can resubmit freely. A NULL or empty value clears + * the needle and returns the search to idle. + * + * Replacing or clearing a needle releases tracked state held + * within the terminal, so the caller must serialize this with all + * other access to the same terminal. Returns GHOSTTY_INVALID_VALUE + * after the terminal was freed. + */ + GHOSTTY_SEARCH_OPT_NEEDLE = 0, + + /** + * Select the next match, moving toward older content: from the + * bottom of the screen upward into history, the direction a search + * from the prompt usually wants. Wraps around past the oldest + * match. + * + * The value must be NULL. It is reserved for future use. + * + * This catches up with the terminal first, so it is safe to call at + * any time relative to feeds. The viewport scrolls to the newly + * selected match according to GHOSTTY_SEARCH_OPT_SELECT_SCROLL. + * This reads the terminal, so the caller must serialize it with all + * other access to the same terminal. Returns GHOSTTY_NO_VALUE when + * there are no matches. + */ + GHOSTTY_SEARCH_OPT_SELECT_NEXT = 1, + + /** + * Select the previous match, moving toward newer content, wrapping + * around past the newest match. Otherwise identical to + * GHOSTTY_SEARCH_OPT_SELECT_NEXT. + */ + GHOSTTY_SEARCH_OPT_SELECT_PREV = 2, + + /** + * Set the scroll policy applied by the select options: const + * GhosttySearchScroll*. The policy persists until changed. A NULL + * value resets it to GHOSTTY_SEARCH_SCROLL_IF_NEEDED. This only + * modifies search-owned state and never reads the terminal. + */ + GHOSTTY_SEARCH_OPT_SELECT_SCROLL = 3, + + GHOSTTY_SEARCH_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttySearchOption; + +/** + * Create a search bound to a terminal. + * + * The search borrows the terminal and never frees it. The search and + * the terminal can be freed in either order; see ghostty_search_free(). + * + * The search starts idle with no needle: it reports + * GHOSTTY_SEARCH_STATUS_COMPLETE and finds nothing. Set + * GHOSTTY_SEARCH_OPT_NEEDLE to start searching. + * + * Creation is cheap and does not read terminal contents, but it + * registers the search with the terminal so the two can be freed in + * any order. The caller must serialize this call with all other + * access to the same terminal. + * + * @param allocator Allocator, or NULL for the default allocator + * @param out_search Receives the created search handle + * @param terminal Terminal to bind the search to + * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if + * out_search or terminal is invalid, or GHOSTTY_OUT_OF_MEMORY + * if allocation fails + * + * @ingroup search + */ +GHOSTTY_API GhosttyResult ghostty_search_new( + const GhosttyAllocator* allocator, + GhosttySearch* out_search, + GhosttyTerminal terminal); + +/** + * Free a search. + * + * If the bound terminal is still alive, this releases tracked state + * the search holds within it, so the caller must serialize this call + * with all other access to the same terminal. If the terminal was + * already freed, the search has been detached and this releases only + * search-owned memory. Passing NULL is allowed and is a no-op. + * + * @param search Search handle to free + * + * @ingroup search + */ +GHOSTTY_API void ghostty_search_free(GhosttySearch search); + +/** + * Make a bounded amount of search progress. + * + * This only works on data the search has already copied and never + * reads the terminal, so it is safe to call while another thread + * modifies the terminal. Call it in a loop while the status is + * GHOSTTY_SEARCH_STATUS_RUNNING. When the status becomes + * GHOSTTY_SEARCH_STATUS_FEED_REQUIRED, call ghostty_search_feed() to + * unblock it. + * + * @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE) + * @param[out] out_status Receives the status after the tick (may be NULL) + * @return GHOSTTY_SUCCESS on success, or GHOSTTY_INVALID_VALUE if + * search is NULL + * + * @ingroup search + */ +GHOSTTY_API GhosttyResult ghostty_search_tick( + GhosttySearch search, + GhosttySearchStatus* out_status); + +/** + * Read the terminal to update the search. + * + * Each feed catches the search up with the terminal: it reconciles + * the tracked screens against the live ones, re-scans the active + * area, refreshes the viewport match list, gives the scrollback + * searcher its next chunk of data, and prunes results that scrollback + * eviction invalidated. Feeding is also the only way the search + * learns about terminal changes, so keep feeding periodically while + * the search is in use, even after it reports complete. + * + * This reads the terminal, so the caller must serialize it with all + * other access to the same terminal. Each call does a bounded amount + * of work so that any caller-held terminal lock is held only briefly. + * + * @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE) + * @return GHOSTTY_SUCCESS on success, or GHOSTTY_INVALID_VALUE if + * search is NULL or the terminal was freed + * + * @ingroup search + */ +GHOSTTY_API GhosttyResult ghostty_search_feed(GhosttySearch search); + +/** + * Feed and tick until the search is caught up with the terminal. + * + * This is a blocking convenience for one-shot and single-threaded + * embedders. It always performs at least one feed, so it also picks + * up any terminal changes since the last feed, then loops until the + * status is GHOSTTY_SEARCH_STATUS_COMPLETE. Searching a large + * scrollback can take a while, so interactive embedders should drive + * ghostty_search_tick() and ghostty_search_feed() themselves. + * + * This reads the terminal for the entire call, so the caller must + * serialize it with all other access to the same terminal. + * + * @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE) + * @return GHOSTTY_SUCCESS on success, or GHOSTTY_INVALID_VALUE if + * search is NULL or the terminal was freed + * + * @ingroup search + */ +GHOSTTY_API GhosttyResult ghostty_search_run(GhosttySearch search); + +/** + * Write an option to a search. + * + * The value type, and what a NULL value means, depends on the option + * and is documented by GhosttySearchOption. The needle and select + * options touch the terminal, so the caller must serialize those + * calls with all other access to the same terminal. + * GHOSTTY_SEARCH_OPT_SELECT_SCROLL only modifies search-owned state. + * + * @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE) + * @param option Option to write + * @param value Pointer to the input value for the option. The meaning + * of NULL is documented per option. + * @return GHOSTTY_SUCCESS on success, GHOSTTY_NO_VALUE if a select + * option found no matches, GHOSTTY_OUT_OF_MEMORY if + * allocation fails, or GHOSTTY_INVALID_VALUE if search, + * option, or value is invalid or the option needs a terminal + * that was already freed + * + * @ingroup search + */ +GHOSTTY_API GhosttyResult ghostty_search_set( + GhosttySearch search, + GhosttySearchOption option, + const void* value); + +/** + * Read a data field from a search. + * + * The output value type depends on data and is documented by + * GhosttySearchData. This never reads the terminal, so it is safe to + * call while another thread modifies the terminal. Returned + * selections are untracked snapshots with standard GhosttySelection + * lifetime rules. + * + * @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE) + * @param data Data field to read + * @param value Output pointer whose type depends on data + * @return GHOSTTY_SUCCESS on success, GHOSTTY_NO_VALUE if the + * requested data has no value, GHOSTTY_OUT_OF_SPACE if a + * provided GhosttySelectionBuffer is too small (required + * capacity in its len), GHOSTTY_OUT_OF_MEMORY if collecting + * viewport matches fails, or GHOSTTY_INVALID_VALUE if search, + * data, or value is invalid + * + * @ingroup search + */ +GHOSTTY_API GhosttyResult ghostty_search_get( + GhosttySearch search, + GhosttySearchData data, + void* value); + +/** + * Read multiple data fields from a search in a single call. + * + * This is an optimization over calling ghostty_search_get() multiple + * times. Each entry in values must point to storage of the type + * documented by the corresponding GhosttySearchData key. + * + * If any individual read fails, the function returns that error and + * writes the index of the failing key to out_written when out_written + * is non-NULL. Earlier keys have already been written. On success, + * out_written receives count when non-NULL. A too-small + * GhosttySelectionBuffer stops the batch with GHOSTTY_OUT_OF_SPACE at + * that key's index with the required capacity in its len, so order + * buffer-valued keys after scalar keys. + * + * @param search Search handle (NULL returns GHOSTTY_INVALID_VALUE) + * @param count Number of data fields to read + * @param keys Data fields to read (must not be NULL) + * @param values Output pointers corresponding to keys (must not be NULL) + * @param out_written Optional number of fields read, or failing index + * on error + * @return GHOSTTY_SUCCESS on success, or the first failing read's + * result + * + * @ingroup search + */ +GHOSTTY_API GhosttyResult ghostty_search_get_multi( + GhosttySearch search, + size_t count, + const GhosttySearchData* keys, + void** values, + size_t* out_written); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* GHOSTTY_VT_SEARCH_H */ diff --git a/vendor/libghostty-vt/include/ghostty/vt/selection.h b/vendor/libghostty-vt/include/ghostty/vt/selection.h index 3b926aab..0158965e 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/selection.h +++ b/vendor/libghostty-vt/include/ghostty/vt/selection.h @@ -116,6 +116,29 @@ typedef struct { bool rectangle; } GhosttySelection; +/** + * A caller-provided buffer of selections. + * + * This follows the same conventions as GhosttyBuffer: ptr may be NULL with + * cap 0 to query the required capacity. APIs that fill this type set len to + * the number of entries written on GHOSTTY_SUCCESS, or to the required entry + * capacity on GHOSTTY_OUT_OF_SPACE. + * + * @ingroup selection + */ +typedef struct { + /** Destination buffer for selections. May be NULL when cap is 0 to query + * the required capacity. */ + GhosttySelection* ptr; + + /** Capacity of ptr in entries. */ + size_t cap; + + /** Entries written on success, or required entry capacity on + * GHOSTTY_OUT_OF_SPACE. */ + size_t len; +} GhosttySelectionBuffer; + /** * Options for deriving a word selection from a terminal grid reference. * @@ -884,6 +907,8 @@ GHOSTTY_API GhosttyResult ghostty_terminal_selection_format_buf( * The returned buffer is allocated using allocator, or the default allocator * if NULL is passed. The caller owns the returned buffer and must free it with * ghostty_free(), passing the same allocator and returned length. + * Empty output returns GHOSTTY_SUCCESS with *out_ptr set to NULL and + * *out_len set to zero. This result can be passed to ghostty_free(). * * The returned bytes are not NUL-terminated. This supports plain text, VT, and * HTML uniformly as byte output. diff --git a/vendor/libghostty-vt/include/ghostty/vt/sgr.h b/vendor/libghostty-vt/include/ghostty/vt/sgr.h index 757c5aed..b8aecb64 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/sgr.h +++ b/vendor/libghostty-vt/include/ghostty/vt/sgr.h @@ -319,31 +319,6 @@ GHOSTTY_API GhosttySgrAttributeTag ghostty_sgr_attribute_tag(GhosttySgrAttribute GHOSTTY_API GhosttySgrAttributeValue* ghostty_sgr_attribute_value( GhosttySgrAttribute* attr); -#ifdef __wasm__ -/** - * Allocate memory for an SGR attribute (WebAssembly only). - * - * This is a convenience function for WebAssembly environments to allocate - * memory for an SGR attribute structure that can be passed to ghostty_sgr_next. - * - * @return Pointer to the allocated attribute structure - * - * @ingroup wasm - */ -GHOSTTY_API GhosttySgrAttribute* ghostty_wasm_alloc_sgr_attribute(void); - -/** - * Free memory for an SGR attribute (WebAssembly only). - * - * Frees memory allocated by ghostty_wasm_alloc_sgr_attribute. - * - * @param attr Pointer to the attribute structure to free - * - * @ingroup wasm - */ -GHOSTTY_API void ghostty_wasm_free_sgr_attribute(GhosttySgrAttribute* attr); -#endif - #ifdef __cplusplus } #endif diff --git a/vendor/libghostty-vt/include/ghostty/vt/snapshot.h b/vendor/libghostty-vt/include/ghostty/vt/snapshot.h new file mode 100644 index 00000000..89cb5398 --- /dev/null +++ b/vendor/libghostty-vt/include/ghostty/vt/snapshot.h @@ -0,0 +1,569 @@ +/** + * @file snapshot.h + * + * Encode and restore complete terminal snapshots. + */ + +#ifndef GHOSTTY_VT_SNAPSHOT_H +#define GHOSTTY_VT_SNAPSHOT_H + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup snapshot Terminal Snapshot + * + * Encode and restore the complete state of a terminal via a binary format. + * + * A snapshot is an ordered, CRC-protected record stream. Its READY marker + * follows enough state to render and resume the terminal, including any + * unfinished VT parser input. Older scrollback pages follow READY and the + * FINISH marker terminates the complete snapshot. + * + * End-of-file before an operation's required READY or FINISH marker is + * malformed, truncated snapshot data and returns GHOSTTY_INVALID_VALUE. + * GHOSTTY_IO_ERROR is reserved for a reader callback that returns false. + * + * ## Examples + * + * The complete working example is available in `example/c-vt-snapshot`. + * + * ### Encode a terminal and its unfinished VT continuation + * @snippet c-vt-snapshot/src/main.c snapshot-encode + * + * ### Restore a complete snapshot in one call + * @snippet c-vt-snapshot/src/main.c snapshot-decode + * + * ### Adapt a byte source to GhosttyReader + * @snippet c-vt-snapshot/src/main.c snapshot-buffer-reader + * + * ### Restore READY first, then incrementally prepend history + * @snippet c-vt-snapshot/src/main.c snapshot-incremental + * + * ## Format + * + * Every integer is unsigned and little-endian. The stream begins with this + * fixed ten-byte envelope: + * + * @code{.unparsed} + * byte 0 8 10 + * +---------------+--------+ + * | "GHOSTSNP" | version| + * | 8-byte magic | u16 | + * +---------------+--------+ + * @endcode + * + * The envelope is followed by independently checksummed records. A record's + * CRC32C covers its encoded tag and payload length followed by its payload; it + * does not cover the CRC field itself. + * + * @code{.unparsed} + * byte 0 2 6 10 10 + payload_len + * +-------+-------------+-----------+----------------+ + * | tag | payload_len | CRC32C | payload | + * | u16 | u32 | u32 | payload_len B | + * +-------+-------------+-----------+----------------+ + * \____________________/ \______________/ + * CRC prefix CRC suffix + * @endcode + * + * Record groups occur in this strict order. SCREEN and HISTORY groups contain + * one entry for each screen declared by TERMINAL. Each manifest is followed + * by the number of PAGE records it declares. Active SCREEN pages make the + * terminal renderable; HISTORY pages are older scrollback ordered newest to + * oldest so an incremental decoder can prepend them as they arrive. + * + * @code{.unparsed} + * +---------------- TERMINAL ----------------+ + * | terminal-wide state and screen count | + * +----------------- SCREEN -----------------+ repeated per screen + * | active-screen manifest | + * +------------------ PAGE ------------------+ repeated per manifest + * | active screen rows | + * +------------- CONTINUATION ---------------+ + * | unfinished VT/UTF-8 input, or ground | + * +------------------ READY -----------------+ + * | empty renderable-state marker | ready() returns here + * +----------------- HISTORY ----------------+ repeated per screen + * | scrollback manifest | + * +------------------ PAGE ------------------+ next() consumes one page + * | older screen rows | + * +------------------ FINISH ----------------+ + * | empty end-of-snapshot marker | next() returns NO_VALUE + * +------------------------------------------+ + * | trailing transport bytes (not consumed) | + * +------------------------------------------+ + * @endcode + * + * READY separates the renderable prefix through CONTINUATION from history. + * FINISH terminates the record sequence. Both are empty records protected by + * CRC32C, like every other record. Declared record counts, tags, and strict + * decoding enforce the stream's ordering and completeness. + * + * Snapshot format version 1 is a work in progress and does not yet carry a + * binary-compatibility guarantee. + * + * @see Snapshot format and Zig codec documentation + * + * @{ + */ + +/** + * Configurable snapshot decoder options. + * + * Options may only be changed before decoding starts. Calling + * ghostty_snapshot_decoder_set() after ghostty_snapshot_decoder_ready() or + * ghostty_snapshot_decoder_decode() returns GHOSTTY_INVALID_VALUE. + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** + * Largest non-ground continuation the decoder will accept. + * + * A value of zero accepts only snapshots whose VT parser is in the ground + * state. The decoder default matches the largest built-in APC protocol + * buffer limit, currently 65 MiB. + * + * This is primarily an input validation limit. When + * GHOSTTY_SNAPSHOT_DECODER_OPT_RETAIN_CONTINUATION is true, the same value + * also becomes the continuation tracking limit on the returned terminal. + * + * Input type: size_t * + */ + GHOSTTY_SNAPSHOT_DECODER_OPT_MAX_CONTINUATION_BYTES = 0, + + /** + * Retain the decoded continuation on the returned terminal. + * + * When true, terminals returned by ghostty_snapshot_decoder_ready() and + * ghostty_snapshot_decoder_decode() use + * GHOSTTY_SNAPSHOT_DECODER_OPT_MAX_CONTINUATION_BYTES as their continuation + * tracking limit. The existing ghostty_terminal_continuation_* APIs can then + * export the exact unfinished VT or UTF-8 input restored from the snapshot. + * + * This is false by default. A maximum continuation size of zero leaves + * tracking disabled. With a nonzero maximum, tracking remains enabled even + * when the decoded continuation is empty. Exporting an empty continuation + * does not disable it. Callers that do not need ongoing tracking must still + * set GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to zero after export and + * before writing post-snapshot input. + * + * Input type: bool * + */ + GHOSTTY_SNAPSHOT_DECODER_OPT_RETAIN_CONTINUATION = 1, + + GHOSTTY_SNAPSHOT_DECODER_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttySnapshotDecoderOption; + +/** + * Queryable snapshot decoder data. + * + * Each variant documents the output pointer type expected by + * ghostty_snapshot_decoder_get(). + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** Invalid data type. Never results in data extraction. */ + GHOSTTY_SNAPSHOT_DECODER_DATA_INVALID = 0, + + /** + * Current maximum accepted continuation size. + * + * This value is available in every non-failed decoder state. + * + * Output type: size_t * + */ + GHOSTTY_SNAPSHOT_DECODER_DATA_MAX_CONTINUATION_BYTES = 1, + + /** + * Number of snapshot source bytes consumed so far. + * + * At FINISH this identifies the first byte after the snapshot. Trailing + * bytes are not consumed. This value is unavailable after a decoding error, + * because the decoder can no longer guarantee its source position. + * + * Output type: size_t * + */ + GHOSTTY_SNAPSHOT_DECODER_DATA_SOURCE_OFFSET = 2, + + /** + * Advisory complete logical history extent for the primary screen. + * + * The value counts rows before the active area, including any resident + * overlap carried before READY. It becomes available after READY validates. + * + * Output type: uint64_t * + */ + GHOSTTY_SNAPSHOT_DECODER_DATA_HISTORY_ROWS_PRIMARY = 3, + + /** + * Advisory complete logical history extent for the alternate screen. + * + * The value has the same semantics and lifetime as + * GHOSTTY_SNAPSHOT_DECODER_DATA_HISTORY_ROWS_PRIMARY. Querying it returns + * GHOSTTY_NO_VALUE when the snapshot does not declare an alternate screen. + * + * Output type: uint64_t * + */ + GHOSTTY_SNAPSHOT_DECODER_DATA_HISTORY_ROWS_ALTERNATE = 4, + + /** + * Screen associated with the most recently decoded history page. + * + * This value is available only after ghostty_snapshot_decoder_next() + * returns GHOSTTY_SUCCESS. A later call to next replaces it or clears it + * when FINISH is reached or an error occurs. + * + * Output type: GhosttyTerminalScreen * + */ + GHOSTTY_SNAPSHOT_DECODER_DATA_PROGRESS_SCREEN = 5, + + /** + * Rows prepended by the most recently decoded history page. + * + * Zero means the page was consumed and validated but could not be + * applied to the live terminal. + * + * Output type: size_t * + */ + GHOSTTY_SNAPSHOT_DECODER_DATA_PROGRESS_ROWS = 6, + + /** + * Page records remaining in the same screen's HISTORY sequence. + * + * This is not a count of all pages remaining in the snapshot. + * + * Output type: uint32_t * + */ + GHOSTTY_SNAPSHOT_DECODER_DATA_PROGRESS_REMAINING = 7, + + /** + * Whether decoded continuation tracking is retained on returned terminals. + * + * This value is available in every non-failed decoder state. + * + * Output type: bool * + */ + GHOSTTY_SNAPSHOT_DECODER_DATA_RETAIN_CONTINUATION = 8, + + GHOSTTY_SNAPSHOT_DECODER_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttySnapshotDecoderData; + +/** + * Encode a complete terminal snapshot to a writer. + * + * The terminal's persistent VT stream supplies the continuation bytes needed + * to reconstruct unfinished parser state. The caller must prevent concurrent + * writes or other terminal mutation for the duration of this call. The writer + * callback must not call terminal APIs with the same terminal handle. + * A terminal can be encoded with tracking disabled when its VT parser and + * UTF-8 decoder are both at ground. If either is unfinished, tracking must + * have been enabled before the input that produced that state was written; + * otherwise this returns GHOSTTY_INVALID_VALUE. + * + * Encoding begins at the writer's current position. If an error occurs, the + * writer may contain a partial snapshot without a valid FINISH marker. + * Calls to the writer are synchronous; this function does not flush or make + * the caller's destination durable. + * + * @param terminal Terminal to encode (must not be NULL) + * @param writer Destination writer whose write callback must not be NULL + * @return GHOSTTY_SUCCESS on success, GHOSTTY_IO_ERROR if the writer rejects + * output, GHOSTTY_LIMIT_EXCEEDED if output accounting overflows, or + * another error code on failure + * + * @ingroup snapshot + */ +GHOSTTY_API GhosttyResult ghostty_snapshot_encode(GhosttyTerminal terminal, + GhosttyWriter writer); + +/** + * Encode a complete terminal snapshot to a caller-provided buffer. + * + * Pass NULL for buf with buf_len zero to query the required size. If the + * buffer is too small, this returns GHOSTTY_OUT_OF_SPACE and stores the + * required capacity in out_written. A non-NULL undersized buffer may contain + * a partial snapshot prefix. On success, out_written receives the number of + * bytes encoded. + * + * A terminal can be encoded with tracking disabled when its VT parser and + * UTF-8 decoder are both at ground. If either is unfinished, tracking must + * have been enabled before the input that produced that state was written; + * otherwise this returns GHOSTTY_INVALID_VALUE. + * + * @param terminal Terminal to encode (must not be NULL) + * @param buf Destination buffer, or NULL when buf_len is zero + * @param buf_len Destination buffer capacity in bytes + * @param[out] out_written Bytes written, or required capacity on + * GHOSTTY_OUT_OF_SPACE (must not be NULL) + * @return GHOSTTY_SUCCESS on success, or an error code on failure + * + * @ingroup snapshot + */ +GHOSTTY_API GhosttyResult ghostty_snapshot_encode_buf( + GhosttyTerminal terminal, + uint8_t* buf, + size_t buf_len, + size_t* out_written); + +/** + * Encode a complete terminal snapshot to an allocated buffer. + * + * The returned buffer is allocated with allocator, or the default allocator + * when allocator is NULL. The caller must release it with ghostty_free(), + * passing the same allocator used here. + * + * A terminal can be encoded with tracking disabled when its VT parser and + * UTF-8 decoder are both at ground. If either is unfinished, tracking must + * have been enabled before the input that produced that state was written; + * otherwise this returns GHOSTTY_INVALID_VALUE. + * + * @param terminal Terminal to encode (must not be NULL) + * @param allocator Allocator for the output, or NULL for the default allocator + * @param[out] out_ptr Allocated snapshot bytes (must not be NULL) + * @param[out] out_len Number of allocated snapshot bytes (must not be NULL) + * @return GHOSTTY_SUCCESS on success, or an error code on failure + * + * @ingroup snapshot + */ +GHOSTTY_API GhosttyResult ghostty_snapshot_encode_alloc( + GhosttyTerminal terminal, + const GhosttyAllocator* allocator, + uint8_t** out_ptr, + size_t* out_len); + +/** + * Create a snapshot decoder that reads from a caller-provided reader. + * + * The decoder stores a copy of reader. Its read callback must not be NULL, and + * both the callback and its caller-owned context must remain valid until + * FINISH is reached or the decoder is freed. Reads are synchronous and occur + * only during ready, next, or decode calls. A zero-byte successful read is + * permanent end-of-file, not temporary starvation; nonblocking sources must + * wait outside the decoder or block in their callback. The read callback must + * not call APIs, including ghostty_snapshot_decoder_free(), on the decoder + * that owns it. Returning false reports GHOSTTY_IO_ERROR; returning true with + * zero bytes before a required marker reports truncated snapshot data as + * GHOSTTY_INVALID_VALUE. + * + * @param allocator Allocator for decoder and decoded terminal state, or NULL + * for the default allocator + * @param decoder Pointer to receive the decoder handle (must not be NULL) + * @param reader Snapshot source reader + * @return GHOSTTY_SUCCESS on success, or an error code on failure + * + * @ingroup snapshot + */ +GHOSTTY_API GhosttyResult ghostty_snapshot_decoder_new( + const GhosttyAllocator* allocator, + GhosttySnapshotDecoder* decoder, + GhosttyReader reader); + +/** + * Create a snapshot decoder over a borrowed byte buffer. + * + * The bytes are not copied. ptr must remain valid and immutable until FINISH + * is reached or the decoder is freed. Bytes after FINISH are not consumed; + * query GHOSTTY_SNAPSHOT_DECODER_DATA_SOURCE_OFFSET to locate them. + * + * @param allocator Allocator for decoder and decoded terminal state, or NULL + * for the default allocator + * @param decoder Pointer to receive the decoder handle (must not be NULL) + * @param ptr Snapshot source bytes + * @param len Number of source bytes + * @return GHOSTTY_SUCCESS on success, or an error code on failure + * + * @ingroup snapshot + */ +GHOSTTY_API GhosttyResult ghostty_snapshot_decoder_new_buf( + const GhosttyAllocator* allocator, + GhosttySnapshotDecoder* decoder, + const uint8_t* ptr, + size_t len); + +/** + * Free a snapshot decoder. + * + * This does not release the caller's ownership of a terminal returned by + * ready or decode. Abandoning an incremental decode leaves that terminal + * usable with whatever history had already been restored. + * + * @param decoder Decoder to free (may be NULL) + * + * @ingroup snapshot + */ +GHOSTTY_API void ghostty_snapshot_decoder_free(GhosttySnapshotDecoder decoder); + +/** + * Set a snapshot decoder option. + * + * The value pointer must have the type documented by option. Options may only + * be changed before decoding starts. + * + * @param decoder Decoder handle (must not be NULL) + * @param option Option to change + * @param value Pointer to the option value (must not be NULL) + * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if decoding has + * started or an argument is invalid, or another error code on failure + * + * @ingroup snapshot + */ +GHOSTTY_API GhosttyResult ghostty_snapshot_decoder_set( + GhosttySnapshotDecoder decoder, + GhosttySnapshotDecoderOption option, + const void* value); + +/** + * Decode and validate the renderable snapshot prefix through READY. + * + * On success, terminal receives a caller-owned terminal with its persistent + * VT stream already restored from the snapshot continuation. The terminal is + * immediately usable for rendering and live input. Older scrollback remains + * to be restored with ghostty_snapshot_decoder_next(). + * + * The restored parser state may be unfinished. By default, terminal + * continuation tracking is disabled and + * GHOSTTY_TERMINAL_DATA_CONTINUATION_MAX_BYTES returns zero. When + * GHOSTTY_SNAPSHOT_DECODER_OPT_RETAIN_CONTINUATION is true, the decoder's + * maximum continuation size is applied to the terminal, and the terminal + * continuation APIs export the exact current continuation when that limit is + * nonzero. Tracking remains enabled even if the exported continuation is + * empty. Callers that do not need ongoing tracking must set + * GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to zero after export and before + * writing any post-snapshot bytes, because later input may change it. + * + * The caller must keep the returned terminal alive until FINISH validates or + * the decoder is freed. The decoder borrows this terminal handle while it + * restores history; ghostty_snapshot_decoder_next() uses it automatically. + * + * This operation may only be called once and only before decoding starts. + * terminal is set to NULL on every error. A decoding, I/O, or allocation + * error after input consumption begins poisons the decoder, after which it + * must be freed. An invalid argument or lifecycle error detected before the + * operation consumes input does not poison it. + * + * @param decoder Decoder handle (must not be NULL) + * @param[out] terminal Pointer to receive the terminal (must not be NULL) + * @return GHOSTTY_SUCCESS on success, or an error code on failure + * + * @ingroup snapshot + */ +GHOSTTY_API GhosttyResult ghostty_snapshot_decoder_ready( + GhosttySnapshotDecoder decoder, + GhosttyTerminal* terminal); + +/** + * Decode one history page into the terminal returned by READY. + * + * Each GHOSTTY_SUCCESS consumes and validates one PAGE record. Query the + * GHOSTTY_SNAPSHOT_DECODER_DATA_PROGRESS_* values before calling next again. + * GHOSTTY_NO_VALUE means FINISH was validated; repeated calls after FINISH + * also return GHOSTTY_NO_VALUE. + * + * The terminal may be rendered, resized, and fed live PTY input between calls. + * If a history page can no longer be applied safely, it is still consumed and + * validated and progress reports zero rows. The decoder applies history + * to the caller-owned terminal produced by its READY operation. + * + * A decoding error invalidates the decoder's source position. The terminal + * remains caller-owned and usable with its already-restored history, but only + * ghostty_snapshot_decoder_free() may subsequently be called on the decoder. + * + * @param decoder Decoder handle (must not be NULL) + * @return GHOSTTY_SUCCESS for one page, GHOSTTY_NO_VALUE after FINISH, or an + * error code on failure + * + * @ingroup snapshot + */ +GHOSTTY_API GhosttyResult ghostty_snapshot_decoder_next( + GhosttySnapshotDecoder decoder); + +/** + * Decode and validate one complete snapshot. + * + * This is the one-shot form of READY followed by all history pages through + * FINISH. It may only be called before decoding starts. Bytes following FINISH + * are left unread. On success terminal receives a caller-owned terminal with + * its persistent VT stream restored. Continuation tracking on the returned + * terminal is disabled by default. When + * GHOSTTY_SNAPSHOT_DECODER_OPT_RETAIN_CONTINUATION is true, the decoder's + * maximum continuation size is applied to the terminal, and the terminal + * continuation APIs export the exact current continuation when that limit is + * nonzero. Tracking remains enabled even if the exported continuation is + * empty. Callers that do not need ongoing tracking must set + * GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to zero after export and before + * writing any post-snapshot bytes, because later input may change it. + * terminal is set to NULL on every error. + * A decoding, I/O, or allocation error after input consumption begins poisons + * the decoder, after which it must be freed. An invalid argument or + * lifecycle error detected before the operation consumes input does not + * poison it. + * + * @param decoder Decoder handle (must not be NULL) + * @param[out] terminal Pointer to receive the terminal (must not be NULL) + * @return GHOSTTY_SUCCESS on success, or an error code on failure + * + * @ingroup snapshot + */ +GHOSTTY_API GhosttyResult ghostty_snapshot_decoder_decode( + GhosttySnapshotDecoder decoder, + GhosttyTerminal* terminal); + +/** + * Get typed data from a snapshot decoder. + * + * The output pointer must have the type documented by data. A phase-dependent + * value that is not currently available returns GHOSTTY_NO_VALUE. + * + * @param decoder Decoder handle (must not be NULL) + * @param data Data kind to query + * @param[out] out Pointer to receive the value (must not be NULL) + * @return GHOSTTY_SUCCESS on success, GHOSTTY_NO_VALUE if the requested data + * is unavailable, or another error code on failure + * + * @ingroup snapshot + */ +GHOSTTY_API GhosttyResult ghostty_snapshot_decoder_get( + GhosttySnapshotDecoder decoder, + GhosttySnapshotDecoderData data, + void* out); + +/** + * Get multiple snapshot decoder data fields in a single call. + * + * Each keys element selects a data kind and the corresponding values element + * points to storage of the documented output type. Processing stops at the + * first error. On success out_written is set to count; on error it is set to + * the number of values written before the failing key. Invalid array arguments + * report zero values written. + * + * @param decoder Decoder handle (must not be NULL) + * @param count Number of key/value pairs + * @param keys Array of data kinds to query + * @param values Array of output pointers corresponding to keys + * @param[out] out_written Number of successfully written values (may be NULL) + * @return GHOSTTY_SUCCESS if every query succeeds, or the first error + * + * @ingroup snapshot + */ +GHOSTTY_API GhosttyResult ghostty_snapshot_decoder_get_multi( + GhosttySnapshotDecoder decoder, + size_t count, + const GhosttySnapshotDecoderData* keys, + void** values, + size_t* out_written); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* GHOSTTY_VT_SNAPSHOT_H */ diff --git a/vendor/libghostty-vt/include/ghostty/vt/sys.h b/vendor/libghostty-vt/include/ghostty/vt/sys.h index ae905969..c5e5903b 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/sys.h +++ b/vendor/libghostty-vt/include/ghostty/vt/sys.h @@ -124,6 +124,24 @@ typedef bool (*GhosttySysDecodePngFn)( size_t data_len, GhosttySysImage* out); +/** + * Callback type for secure random bytes. + * + * Fills @p buf with @p len cryptographically secure random bytes. The + * library uses this for secrets, so it must be a real CSPRNG (getrandom, + * arc4random_buf, BCryptGenRandom, crypto.getRandomValues, ...); a + * predictable source is a security hole. + * + * @param userdata The userdata pointer set via GHOSTTY_SYS_OPT_USERDATA + * @param buf Buffer to fill + * @param len Number of bytes to fill + * @return true if the buffer was filled, false if no entropy is available + */ +typedef bool (*GhosttySysRandomSecureFn)( + void* userdata, + uint8_t* buf, + size_t len); + /** * System option identifiers for ghostty_sys_set(). */ @@ -165,6 +183,21 @@ typedef enum GHOSTTY_ENUM_TYPED { * Input type: GhosttySysLogFn (function pointer, or NULL) */ GHOSTTY_SYS_OPT_LOG = 2, + + /** + * Override the secure random source. + * + * By default the library draws secure random bytes from the + * platform (getrandom or arc4random_buf on POSIX, CNG on Windows). + * Targets without one, such as wasm32-freestanding, have no default + * and operations that need entropy fail with GHOSTTY_IO_ERROR until + * this is set. When set, + * it is used instead of the platform source on every target. When + * cleared (NULL value), the platform default is restored. + * + * Input type: GhosttySysRandomSecureFn (function pointer, or NULL) + */ + GHOSTTY_SYS_OPT_RANDOM_SECURE = 3, GHOSTTY_SYS_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttySysOption; diff --git a/vendor/libghostty-vt/include/ghostty/vt/terminal.h b/vendor/libghostty-vt/include/ghostty/vt/terminal.h index 9bb961d3..ad5eec54 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/terminal.h +++ b/vendor/libghostty-vt/include/ghostty/vt/terminal.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -53,17 +54,17 @@ extern "C" { * * ## Effects * - * By default, the terminal sequence processing with ghostty_terminal_vt_write() - * only process sequences that directly affect terminal state and + * By default, terminal sequence processing with the VT write functions only + * processes sequences that directly affect terminal state and * ignores sequences that have side effect behavior or require responses. * These sequences include things like bell characters, title changes, device * attributes queries, and more. To handle these sequences, the embedder * must configure "effects." * * Effects are callbacks that the terminal invokes in response to VT - * sequences processed during ghostty_terminal_vt_write(). They let the - * embedding application react to terminal-initiated events such as bell - * characters, title changes, device status report responses, and more. + * sequences processed during VT writes. They let the embedding application + * react to terminal-initiated events such as bell characters, title changes, + * device status report responses, and more. * * Each effect is registered with ghostty_terminal_set() using the * corresponding `GhosttyTerminalOption` identifier. A `NULL` value @@ -74,9 +75,10 @@ extern "C" { * back to their own application state without global variables. * You cannot specify different userdata for different callbacks. * - * All callbacks are invoked synchronously during - * ghostty_terminal_vt_write(). Callbacks **must not** call - * ghostty_terminal_vt_write() on the same terminal (no reentrancy). + * All callbacks are invoked synchronously during VT writes. Callbacks + * **must not** call ghostty_terminal_vt_write() or + * ghostty_terminal_vt_write_until_ground() on the same terminal + * (no reentrancy). * And callbacks must be very careful to not block for too long or perform * expensive operations, since they are blocking further IO processing. * @@ -84,16 +86,20 @@ extern "C" { * * | Option | Callback Type | Trigger | * |-----------------------------------------|-----------------------------------|-------------------------------------------| - * | `GHOSTTY_TERMINAL_OPT_WRITE_PTY` | `GhosttyTerminalWritePtyFn` | Query responses written back to the pty | + * | `GHOSTTY_TERMINAL_OPT_WRITE_PTY` | `GhosttyTerminalWritePtyFn` | VT query and mode reports written back to the PTY | * | `GHOSTTY_TERMINAL_OPT_BELL` | `GhosttyTerminalBellFn` | BEL character (0x07) | * | `GHOSTTY_TERMINAL_OPT_TITLE_CHANGED` | `GhosttyTerminalTitleChangedFn` | Title change via OSC 0 / OSC 2 | * | `GHOSTTY_TERMINAL_OPT_PWD_CHANGED` | `GhosttyTerminalPwdChangedFn` | Pwd change via OSC 7 / OSC 9 / OSC 1337 | * | `GHOSTTY_TERMINAL_OPT_ENQUIRY` | `GhosttyTerminalEnquiryFn` | ENQ character (0x05) | * | `GHOSTTY_TERMINAL_OPT_XTVERSION` | `GhosttyTerminalXtversionFn` | XTVERSION query (CSI > q) | - * | `GHOSTTY_TERMINAL_OPT_SIZE` | `GhosttyTerminalSizeFn` | XTWINOPS size query (CSI 14/16/18 t) | + * | `GHOSTTY_TERMINAL_OPT_SIZE` | `GhosttyTerminalSizeFn` | XTWINOPS query (CSI 14/16/18 t) or mode 2048 enable | * | `GHOSTTY_TERMINAL_OPT_COLOR_SCHEME` | `GhosttyTerminalColorSchemeFn` | Color scheme query (CSI ? 996 n) | * | `GHOSTTY_TERMINAL_OPT_DEVICE_ATTRIBUTES`| `GhosttyTerminalDeviceAttributesFn`| Device attributes query (CSI c / > c / = c)| - * | `GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE` | `GhosttyTerminalClipboardWriteFn` | Clipboard write via OSC 52 / OSC 1337 | + * | `GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE` | `GhosttyTerminalClipboardWriteFn` | Clipboard write via OSC 52 / OSC 1337 / OSC 5522 | + * | `GHOSTTY_TERMINAL_OPT_CLIPBOARD_READ` | `GhosttyTerminalClipboardReadFn` | Clipboard read via OSC 52 "?" / OSC 5522 | + * | `GHOSTTY_TERMINAL_OPT_DESKTOP_NOTIFICATION`| `GhosttyTerminalDesktopNotificationFn` | Desktop notification via OSC 9 / OSC 777 | + * | `GHOSTTY_TERMINAL_OPT_PROGRESS_REPORT` | `GhosttyTerminalProgressReportFn` | Progress report via OSC 9;4 | + * | `GHOSTTY_TERMINAL_OPT_UNKNOWN_SEQUENCE` | `GhosttyTerminalUnknownSequenceFn` | Unsupported sequence identifier | * * ### Defining a write_pty callback * @snippet c-vt-effects/src/main.c effects-write-pty @@ -107,6 +113,12 @@ extern "C" { * ### Defining a clipboard_write callback * @snippet c-vt-effects/src/main.c effects-clipboard-write * + * ### Defining a clipboard_read callback + * @snippet c-vt-effects/src/main.c effects-clipboard-read + * + * ### Defining an unknown_sequence callback + * @snippet c-vt-effects/src/main.c effects-unknown-sequence + * * ### Registering effects and processing VT data * @snippet c-vt-effects/src/main.c effects-register * @@ -172,26 +184,6 @@ extern "C" { * @{ */ -/** - * Terminal initialization options. - * - * @ingroup terminal - */ -typedef struct { - /** Terminal width in cells. Must be greater than zero. */ - uint16_t cols; - - /** Terminal height in cells. Must be greater than zero. */ - uint16_t rows; - - /** Maximum number of lines to keep in scrollback history. */ - size_t max_scrollback; - - // TODO: Consider ABI compatibility implications of this struct. - // We may want to artificially pad it significantly to support - // future options. -} GhosttyTerminalOptions; - /** * Amount of compression work to perform before returning. * @@ -348,6 +340,88 @@ typedef struct { typedef void (*GhosttyTerminalBellFn)(GhosttyTerminal terminal, void* userdata); +/** + * Unsupported terminal sequence tags. + * + * Only APC sequences are currently reported. Additional sequence types may + * be added without changing the callback shape. + * + * @ingroup terminal + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** Application Program Command (APC). */ + GHOSTTY_TERMINAL_UNKNOWN_SEQUENCE_APC = 0, + GHOSTTY_TERMINAL_UNKNOWN_SEQUENCE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttyTerminalUnknownSequenceTag; + +/** + * An unsupported string terminal sequence. + * + * The content is borrowed and valid only for the callback duration. It + * contains the bytes between the sequence introducer and terminator, may + * contain arbitrary binary data, and is not null-terminated. + * + * @ingroup terminal + */ +typedef struct { + /** Whether content was shortened by the byte limit or allocation failure. */ + bool truncated; + + /** Retained sequence content. */ + GhosttyString content; +} GhosttyTerminalUnknownStringSequence; + +/** + * Unsupported terminal sequence value. + * + * @ingroup terminal + */ +typedef union { + /** Application Program Command (APC). */ + GhosttyTerminalUnknownStringSequence apc; + + /** + * Padding for ABI compatibility. Do not use. + * + * 128 bytes leaves room for future structured sequence payloads, such as + * CSI with borrowed parameter, separator, and intermediate arrays, without + * changing the tagged union's ABI. + */ + uint64_t _padding[16]; +} GhosttyTerminalUnknownSequenceValue; + +/** + * An unsupported terminal sequence. + * + * @ingroup terminal + */ +typedef struct { + GhosttyTerminalUnknownSequenceTag tag; + GhosttyTerminalUnknownSequenceValue value; +} GhosttyTerminalUnknownSequence; + +/** + * Callback function type for unsupported terminal sequences. + * + * Called synchronously for normally terminated sequences whose identifier is + * not supported by the active terminal handler. Aborted sequences, malformed + * recognized commands, and explicitly disabled known protocols are ignored. + * + * Capture must also be enabled with a nonzero + * GHOSTTY_TERMINAL_OPT_UNKNOWN_MAX_BYTES value. Installing this callback alone + * does not retain sequence content or allocate memory. + * + * @param terminal The terminal handle + * @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA + * @param sequence Borrowed unsupported sequence + * + * @ingroup terminal + */ +typedef void (*GhosttyTerminalUnknownSequenceFn)( + GhosttyTerminal terminal, + void* userdata, + const GhosttyTerminalUnknownSequence* sequence); + /** * Clipboard destination for a clipboard write. * @@ -389,7 +463,78 @@ typedef struct { } GhosttyClipboardContent; /** - * A semantic, atomic clipboard write. + * Result of a clipboard write reply. + * + * @ingroup terminal + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** The clipboard write completed successfully. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_SUCCESS = 0, + + /** The clipboard write was denied by policy or the user. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_DENIED = 1, + + /** The destination or one or more representations are unsupported. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_UNSUPPORTED = 2, + + /** The clipboard is temporarily unavailable. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_BUSY = 3, + + /** One or more representations contain invalid data. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_INVALID_DATA = 4, + + /** The clipboard write failed due to an I/O error. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_IO_ERROR = 5, + GHOSTTY_CLIPBOARD_WRITE_RESULT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttyClipboardWriteResult; + +/** + * The reply to a clipboard write request. + * + * This is a sized struct; set `size` to `sizeof(GhosttyClipboardWriteReply)`. + * The reply is borrowed only for the duration of the reply call and may be + * freed as soon as it returns. + * + * The result answers the program with the matching protocol status for + * protocols with a write acknowledgement (OSC 5522: DONE, EPERM, ENOSYS, + * EBUSY, EINVAL, EIO); protocols without one (OSC 52, OSC 1337 Copy) + * discard the reply. `remember` is ignored on any result other than + * GHOSTTY_CLIPBOARD_WRITE_RESULT_SUCCESS. + * + * @ingroup terminal + */ +typedef struct { + /** Size of this struct in bytes. */ + size_t size; + + /** Outcome of the write. */ + GhosttyClipboardWriteResult result; + + /** + * Record a session grant so future requests from the same program skip + * the permission prompt. Only honored on success when + * GhosttyClipboardWrite::can_remember is set. + */ + bool remember; +} GhosttyClipboardWriteReply; + +typedef struct GhosttyClipboardWrite GhosttyClipboardWrite; + +/** + * Function type used to answer a clipboard write request. Obtained from + * GhosttyClipboardWrite::reply; see that struct for the contract. + * + * @param write The request being answered + * @param reply The reply, borrowed only for the duration of this call + * + * @ingroup terminal + */ +typedef void (*GhosttyClipboardWriteReplyFn)( + const GhosttyClipboardWrite* write, + const GhosttyClipboardWriteReply* reply); + +/** + * A synchronous request to write clipboard contents. * * This is a sized struct. The callback must only access fields present in the * size reported by `size`. The request, contents array, MIME strings, and @@ -400,9 +545,15 @@ typedef struct { * the destination be cleared. This is distinct from a content entry whose data * has zero length. * + * The write is answered by calling `reply` with this request and a + * GhosttyClipboardWriteReply. This must happen within the clipboard write + * request callback. This struct is only valid during that time. Calling + * `reply` more than once is safely ignored. Returning without replying + * denies the write. + * * @ingroup terminal */ -typedef struct { +struct GhosttyClipboardWrite { /** Size of this struct in bytes. */ size_t size; @@ -414,58 +565,351 @@ typedef struct { /** Number of entries in contents; zero means clear the destination. */ size_t contents_len; -} GhosttyClipboardWrite; + + /** + * Name of the writing program for permission prompts, if the protocol + * carries one. Empty otherwise. + */ + GhosttyString name; + + /** + * True if the terminal already holds a session grant for this request + * The embedder should skip any permission prompt and perform the write. + */ + bool granted; + + /** + * True if the program supplied a session password, so the embedder may + * offer to remember the user's decision through + * GhosttyClipboardWriteReply::remember. When false, remember is ignored. + */ + bool can_remember; + + /** Terminal-owned reply state. Do not access. */ + const void* ctx; + + /** Answer the write; see the struct documentation. */ + GhosttyClipboardWriteReplyFn reply; +}; /** - * Result of a clipboard write callback. + * Callback function type for clipboard_write. * - * Protocols without write acknowledgements, including OSC 52 and iTerm2 - * OSC 1337 Copy, ignore this result. + * The embedder may ask for permission to write or perform the write + * async, but the callback itself is synchronous and the reply function + * must be called during the lifetime of this function. While this callback + * is active the VT stream is paused. + * + * Answer by calling `write->reply(write, &reply)` before returning. See + * GhosttyClipboardWrite for the full contract. + * + * The request may carry an optional program name requesting the write + * and the state of prior permission granted. If `can_remember` is set + * the response may set the `remember` flag and future requests from this + * same program will be "granted" and the embedder can skip permission + * requests. + * + * Clipboard read requests (OSC 52 "?" and OSC 5522 reads) are delivered + * to GhosttyTerminalClipboardReadFn instead. + * + * @param terminal The terminal handle + * @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA + * @param write Borrowed atomic clipboard write request + * + * @ingroup terminal + */ +typedef void (*GhosttyTerminalClipboardWriteFn)( + GhosttyTerminal terminal, + void* userdata, + const GhosttyClipboardWrite* write); + +/** + * Result of a clipboard read reply. * * @ingroup terminal */ typedef enum GHOSTTY_ENUM_TYPED { - /** The clipboard write completed successfully. */ - GHOSTTY_CLIPBOARD_WRITE_RESULT_SUCCESS = 0, + /** The clipboard was read; the reply carries its contents. */ + GHOSTTY_CLIPBOARD_READ_RESULT_SUCCESS = 0, - /** The clipboard write was denied by policy or the user. */ - GHOSTTY_CLIPBOARD_WRITE_RESULT_DENIED = 1, + /** The clipboard read was denied by policy or the user. */ + GHOSTTY_CLIPBOARD_READ_RESULT_DENIED = 1, - /** The destination or one or more representations are unsupported. */ - GHOSTTY_CLIPBOARD_WRITE_RESULT_UNSUPPORTED = 2, + /** The embedder cannot read this clipboard. */ + GHOSTTY_CLIPBOARD_READ_RESULT_UNSUPPORTED = 2, /** The clipboard is temporarily unavailable. */ - GHOSTTY_CLIPBOARD_WRITE_RESULT_BUSY = 3, + GHOSTTY_CLIPBOARD_READ_RESULT_BUSY = 3, - /** One or more representations contain invalid data. */ - GHOSTTY_CLIPBOARD_WRITE_RESULT_INVALID_DATA = 4, + /** Reading the clipboard failed due to an I/O error. */ + GHOSTTY_CLIPBOARD_READ_RESULT_IO_ERROR = 4, + GHOSTTY_CLIPBOARD_READ_RESULT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttyClipboardReadResult; - /** The clipboard write failed due to an I/O error. */ - GHOSTTY_CLIPBOARD_WRITE_RESULT_IO_ERROR = 5, - GHOSTTY_CLIPBOARD_WRITE_RESULT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, -} GhosttyClipboardWriteResult; +/** + * The reply to a clipboard read request. + * + * This is a sized struct; set `size` to `sizeof(GhosttyClipboardReadReply)`. + * All arrays and the strings they point to are borrowed only for the + * duration of the reply call and may be freed as soon as it returns. + * + * Any result other than GHOSTTY_CLIPBOARD_READ_RESULT_SUCCESS answers the + * program with an empty clipboard (OSC 52) or the matching protocol status + * (OSC 5522: EPERM, ENOSYS, EBUSY, EIO); the other fields are ignored in + * that case. On success, `contents` should carry one representation per + * requested MIME type (GhosttyClipboardRead::mimes) that the clipboard + * has; unrequested representations are ignored. Protocols that carry a + * single text value (OSC 52) use the first entry with a text MIME type + * such as "text/plain". + * + * @ingroup terminal + */ +typedef struct { + /** Size of this struct in bytes. */ + size_t size; + + /** Outcome of the read. */ + GhosttyClipboardReadResult result; + + /** Borrowed array of MIME representations of the clipboard contents. */ + const GhosttyClipboardContent* contents; + + /** Number of entries in contents. */ + size_t contents_len; + + /** + * Borrowed array of all MIME types available on the clipboard. Only + * used when GhosttyClipboardRead::list is set; may be NULL otherwise. + */ + const GhosttyString* available; + + /** Number of entries in available. */ + size_t available_len; + + /** + * Record a session grant so future requests from the same program skip + * the permission prompt. Only honored on success when + * GhosttyClipboardRead::can_remember is set. + */ + bool remember; +} GhosttyClipboardReadReply; + +typedef struct GhosttyClipboardRead GhosttyClipboardRead; /** - * Callback function type for clipboard_write. + * Function type used to answer a clipboard read request. Obtained from + * GhosttyClipboardRead::reply; see that struct for the contract. + * + * @param read The request being answered + * @param reply The reply, borrowed only for the duration of this call + * + * @ingroup terminal + */ +typedef void (*GhosttyClipboardReadReplyFn)( + const GhosttyClipboardRead* read, + const GhosttyClipboardReadReply* reply); + +/** + * A synchronous request to read clipboard contents. * - * Called synchronously for a complete logical clipboard write. Protocol - * details such as OSC 52 selectors, base64 encoding, multipart chunks, - * aliases, and terminators are normalized before this callback is invoked. - * OSC 52 and iTerm2 OSC 1337 Copy writes therefore use the same callback - * shape. OSC 52 clipboard read requests ("?") are always ignored and never - * forwarded to this callback. + * This is a sized struct. The callback must only access fields present in the + * size reported by `size`. The request is borrowed and valid only for the + * callback duration. + * + * The read is answered by calling `reply` with this request and a + * GhosttyClipboardReadReply. This must happen before the callback returns; + * the request is invalid afterwards. Calling `reply` more than once is + * ignored. Returning without replying answers the program with an empty + * clipboard (OSC 52) or EPERM (OSC 5522). + * + * @ingroup terminal + */ +struct GhosttyClipboardRead { + /** Size of this struct in bytes. */ + size_t size; + + /** Clipboard to read. */ + GhosttyClipboardLocation location; + + /** + * Borrowed array of the MIME types the program wants, in order of + * preference. Protocols that only carry text (OSC 52) request + * "text/plain". NULL when mimes_len is zero. + */ + const GhosttyString* mimes; + + /** Number of entries in mimes. */ + size_t mimes_len; + + /** + * True if the program also wants the list of MIME types available on the + * clipboard, delivered through GhosttyClipboardReadReply::available. + */ + bool list; + + /** + * Name of the requesting program for permission prompts, if the protocol + * carries one. Empty otherwise. + */ + GhosttyString name; + + /** + * True if the terminal already holds a session grant for this request + * (kitty clipboard protocol passwords). The embedder should skip any + * permission prompt and serve the read. + * + * Always false when mimes_len is zero: such a request is served + * without a prompt (see the callback docs), so the terminal never + * consults grants for it and a one-time password is preserved for + * the follow-up data read. + */ + bool granted; + + /** + * True if the program supplied a session password, so the embedder may + * offer to remember the user's decision through + * GhosttyClipboardReadReply::remember. When false, remember is ignored. + */ + bool can_remember; + + /** Terminal-owned reply state. Do not access. */ + const void* ctx; + + /** Answer the read; see the struct documentation. */ + GhosttyClipboardReadReplyFn reply; +}; + +/** + * Callback function type for clipboard_read. + * + * Called synchronously when the running program requests clipboard contents + * via OSC 52 with a "?" payload or a Kitty clipboard (OSC 5522) read. + * Answering lets the program read the user's clipboard, so the embedder is + * expected to mediate consent. Because the read is synchronous, an embedder + * that needs to ask the user must block (for example by running a modal + * prompt) until it has an answer; the VT stream waits until the callback + * returns. + * + * Answer by calling `read->reply(read, &reply)` before returning. See + * GhosttyClipboardRead for the full contract. + * + * OSC 5522 requests carry the program's MIME list, name, and password grant + * state; a reply that sets `remember` records a session grant so later + * requests with the same password arrive with `granted` set. Kitty itself + * serves a request for only the targets listing (`list` with no `mimes`) + * without prompting, and embedders are expected to do the same; the + * terminal never consults grants for such requests (`granted` is false + * and one-time passwords are not consumed). + * + * Installing this callback also enables Kitty paste events (mode 5522): + * ghostty_terminal_paste() sends the program an event instead of the text, + * and the program's follow-up read arrives here with `granted` set since + * the user already pasted. See ghostty_terminal_paste(). * * @param terminal The terminal handle * @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA - * @param write Borrowed atomic clipboard write request - * @return The result of attempting the clipboard write + * @param read Borrowed clipboard read request * * @ingroup terminal */ -typedef GhosttyClipboardWriteResult (*GhosttyTerminalClipboardWriteFn)( +typedef void (*GhosttyTerminalClipboardReadFn)( GhosttyTerminal terminal, void* userdata, - const GhosttyClipboardWrite* write); + const GhosttyClipboardRead* read); + +/** + * A request to show a desktop notification. + * + * This is a sized struct. The callback must only access fields present in the + * size reported by `size`. Both strings are borrowed and valid only for the + * duration of the callback. + * + * @ingroup terminal + */ +typedef struct { + /** Size of this struct in bytes. */ + size_t size; + + /** Notification title, or an empty string when the protocol omits it. */ + GhosttyString title; + + /** Notification body. */ + GhosttyString body; +} GhosttyTerminalDesktopNotification; + +/** + * Callback function type for desktop notifications. + * + * Called synchronously when the terminal receives OSC 9 or OSC 777. + * + * @param terminal The terminal handle + * @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA + * @param notification Borrowed desktop notification request + * + * @ingroup terminal + */ +typedef void (*GhosttyTerminalDesktopNotificationFn)( + GhosttyTerminal terminal, + void* userdata, + const GhosttyTerminalDesktopNotification* notification); + +/** + * State of a terminal progress report. + * + * @ingroup terminal + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** Remove any visible progress indication. */ + GHOSTTY_TERMINAL_PROGRESS_STATE_REMOVE = 0, + + /** Show determinate progress. */ + GHOSTTY_TERMINAL_PROGRESS_STATE_SET = 1, + + /** Show a failed progress state. */ + GHOSTTY_TERMINAL_PROGRESS_STATE_ERROR = 2, + + /** Show indeterminate progress. */ + GHOSTTY_TERMINAL_PROGRESS_STATE_INDETERMINATE = 3, + + /** Show paused progress. */ + GHOSTTY_TERMINAL_PROGRESS_STATE_PAUSE = 4, + GHOSTTY_TERMINAL_PROGRESS_STATE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttyTerminalProgressState; + +/** + * A progress report emitted by the running program. + * + * This is a sized struct. The callback must only access fields present in the + * size reported by `size`. + * + * @ingroup terminal + */ +typedef struct { + /** Size of this struct in bytes. */ + size_t size; + + /** Literal progress state reported by the running program. */ + GhosttyTerminalProgressState state; + + /** Progress percentage from 0 through 100, or -1 when omitted. */ + int8_t progress; +} GhosttyTerminalProgressReport; + +/** + * Callback function type for progress reports. + * + * Called synchronously when the terminal receives OSC 9;4. + * + * @param terminal The terminal handle + * @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA + * @param report Borrowed progress report + * + * @ingroup terminal + */ +typedef void (*GhosttyTerminalProgressReportFn)( + GhosttyTerminal terminal, + void* userdata, + const GhosttyTerminalProgressReport* report); /** * Callback function type for color scheme queries (CSI ? 996 n). @@ -524,16 +968,18 @@ typedef GhosttyString (*GhosttyTerminalEnquiryFn)(GhosttyTerminal terminal, void* userdata); /** - * Callback function type for size queries (XTWINOPS). + * Callback function type for terminal size reports. * - * Called in response to XTWINOPS size queries (CSI 14/16/18 t). + * Called in response to XTWINOPS size queries (CSI 14/16/18 t) and when VT + * input enables in-band size reports (mode 2048). * Return true and fill *out_size with the current terminal geometry, - * or return false to silently ignore the query. + * or return false to suppress the report. * * @param terminal The terminal handle * @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA * @param[out] out_size Pointer to store the terminal size information - * @return true if size was filled, false to ignore the query + * @return true if size was filled, false to suppress the XTWINOPS response or + * mode 2048 report * * @ingroup terminal */ @@ -585,9 +1031,9 @@ typedef void (*GhosttyTerminalPwdChangedFn)(GhosttyTerminal terminal, * Callback function type for write_pty. * * Called when the terminal needs to write data back to the pty, for - * example in response to a device status report or mode query. The - * data is only valid for the duration of the call; callers must copy - * it if it needs to persist. + * example in response to a device status report, mode query, or VT-driven + * mode 2048 enable. The data is only valid for the duration of the call; + * callers must copy it if it needs to persist. * * @param terminal The terminal handle * @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA @@ -618,6 +1064,24 @@ typedef void (*GhosttyTerminalWritePtyFn)(GhosttyTerminal terminal, typedef GhosttyString (*GhosttyTerminalXtversionFn)(GhosttyTerminal terminal, void* userdata); +/** + * A terminal mode and boolean value used for mode configuration and queries. + * + * For GHOSTTY_TERMINAL_DATA_MODE, initialize `mode` before calling + * ghostty_terminal_get(). On success, `value` contains the current mode value. + * + * This struct has a frozen layout and will not gain fields in future versions. + * + * @ingroup terminal + */ +typedef struct { + /** Mode to configure or query. */ + GhosttyMode mode; + + /** Value to set, or the current value returned by a query. */ + bool value; +} GhosttyTerminalModeConfig; + /** * Terminal option identifiers. * @@ -636,8 +1100,9 @@ typedef enum GHOSTTY_ENUM_TYPED { /** * Callback invoked when the terminal needs to write data back - * to the pty (e.g. in response to a DECRQM query or device - * status report). Set to NULL to ignore such sequences. + * to the pty (e.g. in response to a DECRQM query, device status + * report, or VT-driven mode 2048 enable). Set to NULL to ignore such + * sequences. * * Input type: GhosttyTerminalWritePtyFn */ @@ -785,12 +1250,13 @@ typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_TERMINAL_OPT_KITTY_IMAGE_MEDIUM_FILE = 16, /** - * Enable or disable Kitty image loading via the temporary file medium. + * Enable Kitty image loading via the temporary file medium, restricted to + * the provided directory. The string data is copied into the terminal. * - * A NULL value pointer is a no-op. Has no effect when Kitty graphics - * are disabled at build time. + * A NULL value pointer disables the temporary file medium. Has no effect + * when Kitty graphics are disabled at build time. * - * Input type: bool* + * Input type: GhosttyString* */ GHOSTTY_TERMINAL_OPT_KITTY_IMAGE_MEDIUM_TEMP_FILE = 17, @@ -879,14 +1345,206 @@ typedef enum GHOSTTY_ENUM_TYPED { /** * Callback invoked when the running program performs a clipboard write. - * OSC 52 and iTerm2 OSC 1337 Copy writes are normalized to an atomic set - * of decoded MIME representations. Set to NULL to ignore clipboard writes. - * Clipboard read requests are always ignored; see - * GhosttyTerminalClipboardWriteFn. + * OSC 52, iTerm2 OSC 1337 Copy, and Kitty clipboard (OSC 5522) writes + * are normalized to an atomic set of decoded MIME representations. Set + * to NULL to ignore clipboard writes (Kitty clipboard writes are then + * refused with ENOSYS). Clipboard read requests are delivered to + * GHOSTTY_TERMINAL_OPT_CLIPBOARD_READ instead. * * Input type: GhosttyTerminalClipboardWriteFn */ GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE = 26, + + /** + * Set the maximum scrollback allocation in bytes. + * + * This is an estimate. Internally, libghostty only prunes bytes up + * to a "page"-granularity. A page is the minimum allocated unit of + * grid space within Ghostty. A page at the time of writing these docs + * is about 400KB, so the byte limit will be within this delta. + * + * This works alongside the line limit configuration. If both are set, + * the first-reached limit is used first. Both limits are dependent + * on external state (byte limit can be reached with less lines if + * more styles are used for example, line limit can be reached with + * a narrower terminal viewport). So, they are useful together. + * + * Lowering the limit immediately removes eligible complete historical + * pages. A value of zero disables scrollback and erases retained history. + * A NULL value pointer removes the byte limit. + * + * Input type: size_t* + */ + GHOSTTY_TERMINAL_OPT_SCROLLBACK_MAX_BYTES = 27, + + /** + * Set the maximum number of physical lines retained in scrollback. + * + * This is an estimate. Internally, libghostty only prunes lines up + * to a "page"-granularity. A page is the minimum allocated unit of + * grid space within Ghostty. As a result, the actual available scrollback + * lines will almost always be higher than configured. The magnitude + * of the difference depends on the number of used styles, graphemes, etc. + * since the row-count in a page is dynamic based on that. In general, + * it ranges from dozens to a hundred or so lines. + * + * This works alongside the line limit configuration. If both are set, + * the first-reached limit is used first. Both limits are dependent + * on external state (byte limit can be reached with less lines if + * more styles are used for example, line limit can be reached with + * a narrower terminal viewport). So, they are useful together. + * + * Lowering the limit immediately removes eligible complete historical + * pages. A NULL value pointer removes the line limit. + * + * Input type: size_t* + */ + GHOSTTY_TERMINAL_OPT_SCROLLBACK_MAX_LINES = 28, + + /** + * Callback invoked when the running program requests a desktop + * notification via OSC 9 or OSC 777. Set to NULL to ignore desktop + * notification requests. + * + * Input type: GhosttyTerminalDesktopNotificationFn + */ + GHOSTTY_TERMINAL_OPT_DESKTOP_NOTIFICATION = 29, + + /** + * Callback invoked when the running program reports progress via OSC 9;4. + * Set to NULL to ignore progress reports. + * + * Input type: GhosttyTerminalProgressReportFn + */ + GHOSTTY_TERMINAL_OPT_PROGRESS_REPORT = 30, + + /** + * Set the maximum number of replay-safe VT continuation bytes retained. + * + * Continuation bytes reconstruct an escape sequence or UTF-8 codepoint + * which was unfinished at the end of the most recent + * VT write call. They are used automatically by terminal snapshots and may + * also be exported directly with the continuation APIs. + * + * Tracking is disabled by default. A nonzero value enables tracking and + * sets its byte limit. Passing NULL or a pointer to zero disables tracking. + * Lowering the limit below an already-retained + * continuation, or enabling tracking while the parser is already + * unfinished, makes the current continuation unavailable because earlier + * bytes cannot be reconstructed. Tracking recovers automatically after a + * later write reaches the ground state or contains a fresh replay start. + * + * Input type: size_t* + */ + GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES = 31, + + /** + * Enable window title reports in response to CSI 21 t. + * + * This is disabled by default because a running program can set a title and + * query it back into the pty input stream, potentially injecting commands + * that execute after user interaction. Passing NULL or a pointer to false + * disables title reporting. + * + * Input type: bool* + */ + GHOSTTY_TERMINAL_OPT_TITLE_REPORT = 32, + + /** + * Set the reset default for a terminal mode. + * + * This unconditionally updates both the current value and the value restored + * by a full terminal reset (RIS). + * + * Some recognized modes represent transitions or mirror additional terminal + * state and cannot safely be configured as reset defaults. Those modes return + * GHOSTTY_INVALID_VALUE. A NULL value pointer also returns + * GHOSTTY_INVALID_VALUE. + * + * Input type: GhosttyTerminalModeConfig* + */ + GHOSTTY_TERMINAL_OPT_MODE_DEFAULT = 33, + + /** + * Set the current value of a terminal mode. + * + * This does not change the value restored by a full terminal reset (RIS). + * A NULL value pointer or unknown mode returns GHOSTTY_INVALID_VALUE. + * + * Input type: GhosttyTerminalModeConfig* + */ + GHOSTTY_TERMINAL_OPT_MODE = 34, + + /** + * Callback invoked for unsupported terminal sequence identifiers. Set to + * NULL to ignore unsupported sequences. Capture must also be enabled with + * GHOSTTY_TERMINAL_OPT_UNKNOWN_MAX_BYTES. + * + * Input type: GhosttyTerminalUnknownSequenceFn + */ + GHOSTTY_TERMINAL_OPT_UNKNOWN_SEQUENCE = 35, + + /** + * Set the maximum content bytes retained for each unsupported terminal + * sequence. A NULL value pointer or zero disables capture and prevents + * unknown-sequence callbacks. + * + * When this limit is hit, the unknown sequence callback will still + * be invoked but `truncated` will be set to true. + * + * Input type: size_t* + */ + GHOSTTY_TERMINAL_OPT_UNKNOWN_MAX_BYTES = 36, + + /** + * Set the name of the terminfo entry this terminal runs as, reported + * in response to an XTGETTCAP query for "TN" (e.g. "xterm-256color"). + * + * The string data is copied into the terminal. A NULL value pointer + * clears the name (equivalent to setting an empty string). A name + * longer than 128 bytes returns GHOSTTY_INVALID_VALUE. + * + * If this is unset then we don't report anything for an XTGETTCAP + * TN query, because we don't know what the embedding terminal around + * libghostty is advertising itself as. + * + * Input type: GhosttyString* + */ + GHOSTTY_TERMINAL_OPT_TERMINFO_NAME = 37, + + /** + * Callback invoked when the running program requests clipboard contents + * via OSC 52 with a "?" payload or a Kitty clipboard (OSC 5522) read. The + * read is synchronous and must be answered before the callback returns. + * Set to NULL (the default) to ignore OSC 52 read requests and refuse + * OSC 5522 reads with EPERM. + * + * Input type: GhosttyTerminalClipboardReadFn + */ + GHOSTTY_TERMINAL_OPT_CLIPBOARD_READ = 38, + + /** + * Set the maximum total decoded bytes a single Kitty clipboard protocol + * (OSC 5522) write transaction may accumulate. The limit is captured + * when a transaction begins; an in-flight transaction keeps the limit + * it started with. + * + * Data beyond the limit fails the whole transaction with EFBIG. The + * transaction is discarded, later write-related packets are ignored + * until a new write begins, and nothing reaches the clipboard write + * callback. + * + * Transactions are buffered in memory, so this limit bounds how much + * memory a single write can make the terminal allocate. Pass SIZE_MAX + * to remove the limit. A NULL value pointer reverts to the built-in + * default of 64MiB, the minimum required by the protocol. + * + * This limit doesn't apply to OSC 52 writes, which are bounded by the + * maximum length of an escape sequence instead. + * + * Input type: size_t* + */ + GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE_MAX_BYTES = 39, GHOSTTY_TERMINAL_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyTerminalOption; @@ -998,9 +1656,9 @@ typedef enum GHOSTTY_ENUM_TYPED { /** * The terminal title as set by escape sequences (e.g. OSC 0/2). * - * Returns a borrowed string. The pointer is valid until the next call - * to ghostty_terminal_vt_write() or ghostty_terminal_reset(). An empty - * string (len=0) is returned when no title has been set. + * Returns a borrowed string. The pointer is valid until the next mutating + * terminal call. An empty string (len=0) is returned when no title has been + * set. * * Output type: GhosttyString * */ @@ -1010,9 +1668,9 @@ typedef enum GHOSTTY_ENUM_TYPED { * The terminal's current working directory as set by escape sequences * (e.g. OSC 7). * - * Returns a borrowed string. The pointer is valid until the next call - * to ghostty_terminal_vt_write() or ghostty_terminal_reset(). An empty - * string (len=0) is returned when no pwd has been set. + * Returns a borrowed string. The pointer is valid until the next mutating + * terminal call. An empty string (len=0) is returned when no pwd has been + * set. * * Output type: GhosttyString * */ @@ -1139,12 +1797,13 @@ typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_TERMINAL_DATA_KITTY_IMAGE_MEDIUM_FILE = 27, /** - * Whether the temporary file medium is enabled for Kitty image loading - * on the active screen. + * The directory allowed for Kitty image loading via the temporary file + * medium on the active screen. The string is empty when the medium is + * disabled. * * Returns GHOSTTY_NO_VALUE when Kitty graphics are disabled at build time. * - * Output type: bool * + * Output type: GhosttyString * */ GHOSTTY_TERMINAL_DATA_KITTY_IMAGE_MEDIUM_TEMP_FILE = 28, @@ -1198,28 +1857,130 @@ typedef enum GHOSTTY_ENUM_TYPED { */ GHOSTTY_TERMINAL_DATA_VIEWPORT_ACTIVE = 32, + /** + * Whether VT processing encountered a non-gracefully handled error that may + * have prevented a terminal-owned semantic update. + * + * Processing remains best-effort, and ghostty_terminal_reset() does not + * clear it. Gracefully handled protocol failures, configured limits, + * malformed or unsupported input, and failures limited to external effects + * or query responses do not set it. + * + * This can't currently be unset. This is purely informational to consumers + * if there was some error that happened at some point during VT processing. + * + * Output type: bool * + */ + GHOSTTY_TERMINAL_DATA_VT_PROCESSING_ERROR = 33, + + /** + * The configured maximum scrollback allocation in bytes. + * + * This always reports the primary screen's configured value, including + * while an alternate screen is active. Returns GHOSTTY_NO_VALUE when the + * configured byte limit is unlimited. + * + * Output type: size_t * + */ + GHOSTTY_TERMINAL_DATA_SCROLLBACK_MAX_BYTES = 34, + + /** + * The configured maximum number of physical scrollback lines. + * + * This always reports the primary screen's configured value, including + * while an alternate screen is active. Returns GHOSTTY_NO_VALUE when the + * configured line limit is unlimited. + * + * Output type: size_t * + */ + GHOSTTY_TERMINAL_DATA_SCROLLBACK_MAX_LINES = 35, + + /** + * The configured maximum retained VT continuation size in bytes. + * + * A value of zero means continuation tracking is disabled. This reports the + * configured limit even when a current unfinished continuation is + * temporarily unavailable. + * + * Output type: size_t * + */ + GHOSTTY_TERMINAL_DATA_CONTINUATION_MAX_BYTES = 36, + + /** + * Get the current value of a terminal mode. + * + * The caller must initialize the `mode` field. On success, the `value` field + * is updated with the current value. A NULL pointer or unknown mode returns + * GHOSTTY_INVALID_VALUE. + * + * Input/output type: GhosttyTerminalModeConfig * + */ + GHOSTTY_TERMINAL_DATA_MODE = 37, + + /** + * Whether VT processing is at ground. + * + * Ground is when the stream isn't in the middle of any type of sequence: + * UTF-8, ESC, CSI, OSC, etc. It is the stateless point of the stream. + * + * This is useful to know because it is a point at which you can + * safely insert out-of-band VT sequences. For example, while reading + * from a pty if you want to make your own changes, you can wait until + * the pty input reaches ground, then write yours. + * + * Output type: bool * + */ + GHOSTTY_TERMINAL_DATA_VT_GROUND = 38, + + /** + * Whether the cursor is currently at a semantic shell prompt or input area. + * + * This depends on semantic prompt markers such as OSC 133. Returns false + * when semantic prompt information is unavailable or the alternate screen + * is active. + * + * Output type: bool * + */ + GHOSTTY_TERMINAL_DATA_CURSOR_AT_PROMPT = 39, + + /** + * The configured maximum decoded bytes per Kitty clipboard protocol + * (OSC 5522) write transaction. See + * GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE_MAX_BYTES. + * + * Output type: size_t * + */ + GHOSTTY_TERMINAL_DATA_CLIPBOARD_WRITE_MAX_BYTES = 40, + /** * Whether xterm modifyOtherKeys mode 2 is enabled. * * Output type: bool * */ - GHOSTTY_TERMINAL_DATA_MODIFY_OTHER_KEYS = 33, + GHOSTTY_TERMINAL_DATA_MODIFY_OTHER_KEYS = 41, + GHOSTTY_TERMINAL_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyTerminalData; /** * Create a new terminal instance. * + * The terminal starts with various reasonable defaults e.g. around + * scrollback limits. Use ghostty_terminal_set() to change any options + * prior to using the terminal. + * * @param allocator Pointer to allocator, or NULL to use the default allocator * @param terminal Pointer to store the created terminal handle - * @param options Terminal initialization options + * @param cols Terminal width in cells (must be greater than zero) + * @param rows Terminal height in cells (must be greater than zero) * @return GHOSTTY_SUCCESS on success, or an error code on failure * * @ingroup terminal */ GHOSTTY_API GhosttyResult ghostty_terminal_new(const GhosttyAllocator* allocator, - GhosttyTerminal* terminal, - GhosttyTerminalOptions options); + GhosttyTerminal* terminal, + uint16_t cols, + uint16_t rows); /** * Free a terminal instance. @@ -1280,11 +2041,13 @@ GHOSTTY_API GhosttyResult ghostty_terminal_resize(GhosttyTerminal terminal, * write_pty callback and userdata pointer. The value is passed * directly for pointer types (callbacks, userdata) or as a pointer * to the value for non-pointer types (e.g. GhosttyString*). - * NULL clears the option to its default. + * The behavior of a NULL value is specific to each option and is + * documented by the corresponding GhosttyTerminalOption value. * - * Callbacks are invoked synchronously during ghostty_terminal_vt_write(). - * Callbacks must not call ghostty_terminal_vt_write() on the same - * terminal (no reentrancy). + * Callbacks are invoked synchronously during VT writes. Callbacks must not + * call ghostty_terminal_vt_write() or + * ghostty_terminal_vt_write_until_ground() on the same terminal + * (no reentrancy). * * @param terminal The terminal handle (may be NULL, in which case this is a no-op) * @param option The option to set @@ -1322,6 +2085,130 @@ GHOSTTY_API void ghostty_terminal_vt_write(GhosttyTerminal terminal, const uint8_t* data, size_t len); +/** + * Write VT-encoded data, but only the shortest prefix needed to reach ground. + * + * Ground is when the stream isn't in the middle of any type of sequence: + * UTF-8, ESC, CSI, OSC, etc. It is the stateless point of the stream. + * + * This is useful to know because it is a point at which you can + * safely insert out-of-band VT sequences. For example, while reading + * from a pty if you want to make your own changes, you can wait until + * the pty input reaches ground, then write yours. + * + * If the stream is already at ground then this consumes nothing and returns + * GHOSTTY_SUCCESS. On success, out_consumed is the number of bytes consumed + * before reaching ground, including the byte that reaches it. + * GHOSTTY_NO_VALUE means the full slice was consumed without reaching ground. + * + * @param terminal The terminal handle (must not be NULL) + * @param data Pointer to the data to write, or NULL when len is zero + * @param len Length of the data in bytes + * @param[out] out_consumed Number of bytes consumed (must not be NULL) + * @return GHOSTTY_SUCCESS if ground was reached, GHOSTTY_NO_VALUE if all input + * was consumed without reaching ground, or GHOSTTY_INVALID_VALUE if + * an argument is invalid + * + * @ingroup terminal + */ +GHOSTTY_API GhosttyResult ghostty_terminal_vt_write_until_ground( + GhosttyTerminal terminal, + const uint8_t* data, + size_t len, + size_t* out_consumed); + +/** + * Write the terminal's replay-safe VT continuation to a callback writer. + * + * The continuation is the exact byte suffix needed to reconstruct unfinished + * VT parser or UTF-8 decoder state in an equivalent terminal. It is empty + * when the stream is at ground. The callback is invoked synchronously and + * may be called more than once. It must not call terminal APIs with the same + * terminal handle. + * + * Continuation tracking must have been enabled by setting + * GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to a nonzero value before the + * input that produced the continuation was written. + * + * The caller must serialize this operation with both VT write functions and + * all other access to the same terminal. + * + * @param terminal Terminal to read from (must not be NULL) + * @param writer Destination writer whose write callback must not be NULL + * @return GHOSTTY_SUCCESS on success, GHOSTTY_IO_ERROR if the callback rejects + * a write, GHOSTTY_LIMIT_EXCEEDED if output accounting overflows, or + * GHOSTTY_INVALID_VALUE if an argument is invalid, tracking is + * disabled, or the current continuation is unavailable + * + * @ingroup terminal + */ +GHOSTTY_API GhosttyResult ghostty_terminal_continuation_write( + GhosttyTerminal terminal, + GhosttyWriter writer); + +/** + * Copy the terminal's replay-safe VT continuation into a caller buffer. + * + * Pass NULL for buf with buf_len zero to query the required size. A size query + * returns GHOSTTY_OUT_OF_SPACE and stores the required size in out_written, + * including zero when the stream is at ground. If a non-NULL buffer is too + * small, the function has the same result and reports the full required size. + * Continuation tracking must have been enabled by setting + * GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to a nonzero value before the + * input that produced the continuation was written. + * + * The caller must serialize this operation with all other access to the same + * terminal. + * + * @param terminal Terminal to read from (must not be NULL) + * @param buf Destination buffer, or NULL when buf_len is zero + * @param buf_len Destination buffer capacity in bytes + * @param[out] out_written Bytes written, or required size on + * GHOSTTY_OUT_OF_SPACE (must not be NULL) + * @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE for a size query or + * insufficient buffer, or GHOSTTY_INVALID_VALUE if an argument is + * invalid, tracking is disabled, or the current continuation is + * unavailable + * + * @ingroup terminal + */ +GHOSTTY_API GhosttyResult ghostty_terminal_continuation_buf( + GhosttyTerminal terminal, + uint8_t* buf, + size_t buf_len, + size_t* out_written); + +/** + * Return an allocated copy of the terminal's replay-safe VT continuation. + * + * The returned bytes are allocated with allocator, or the default allocator + * when allocator is NULL. The caller must release them with ghostty_free(), + * passing the same allocator and returned length. An empty continuation is a + * successful result with *out_ptr set to NULL and *out_len set to zero, + * which can also be passed to ghostty_free(). + * Continuation tracking must have been enabled by setting + * GHOSTTY_TERMINAL_OPT_CONTINUATION_MAX_BYTES to a nonzero value before the + * input that produced the continuation was written. + * + * The caller must serialize this operation with all other access to the same + * terminal. + * + * @param terminal Terminal to read from (must not be NULL) + * @param allocator Allocator for the output, or NULL for the default allocator + * @param[out] out_ptr Allocated continuation bytes (must not be NULL) + * @param[out] out_len Number of continuation bytes (must not be NULL) + * @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation + * failure, or GHOSTTY_INVALID_VALUE if an argument is invalid, + * tracking is disabled, or the current continuation is unavailable + * + * @ingroup terminal + */ +GHOSTTY_API GhosttyResult ghostty_terminal_continuation_alloc( + GhosttyTerminal terminal, + const GhosttyAllocator* allocator, + uint8_t** out_ptr, + size_t* out_len); + /** * Scroll the terminal viewport. * @@ -1395,41 +2282,6 @@ GHOSTTY_API GhosttyResult ghostty_terminal_compress( GhosttyTerminalCompressionMode mode, GhosttyTerminalCompressionResult* out_result); -/** - * Get the current value of a terminal mode. - * - * Returns the value of the mode identified by the given mode. - * - * @param terminal The terminal handle (NULL returns GHOSTTY_INVALID_VALUE) - * @param mode The mode identifying the mode to query - * @param[out] out_value On success, set to true if the mode is set, false - * if it is reset - * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the terminal - * is NULL or the mode does not correspond to a known mode - * - * @ingroup terminal - */ -GHOSTTY_API GhosttyResult ghostty_terminal_mode_get(GhosttyTerminal terminal, - GhosttyMode mode, - bool* out_value); - -/** - * Set the value of a terminal mode. - * - * Sets the mode identified by the given mode to the specified value. - * - * @param terminal The terminal handle (NULL returns GHOSTTY_INVALID_VALUE) - * @param mode The mode identifying the mode to set - * @param value true to set the mode, false to reset it - * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the terminal - * is NULL or the mode does not correspond to a known mode - * - * @ingroup terminal - */ -GHOSTTY_API GhosttyResult ghostty_terminal_mode_set(GhosttyTerminal terminal, - GhosttyMode mode, - bool value); - /** * Get data from a terminal instance. * diff --git a/vendor/libghostty-vt/include/ghostty/vt/types.h b/vendor/libghostty-vt/include/ghostty/vt/types.h index 214d2822..059bc5c8 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/types.h +++ b/vendor/libghostty-vt/include/ghostty/vt/types.h @@ -39,18 +39,21 @@ * The Zig side backs all C enums with c_int, so the C declarations * must use int as their underlying type to maintain ABI compatibility. * - * C23 (detected via __STDC_VERSION__ >= 202311L) supports explicit - * enum underlying types with `enum : int { ... }`. For pre-C23 - * compilers, which are free to choose any type that can represent - * all values (C11 §6.7.2.2), we add an INT_MAX sentinel as the last - * entry to force the compiler to use int. + * C++11 and C23 support explicit enum underlying types with + * `enum : int { ... }`. Clang and GCC 13+ also support this syntax as + * an extension in older C language modes, so use it when available. + * + * Other pre-C23 C compilers are free to choose any type that can + * represent all values (C11 §6.7.2.2). For those compilers, we add an + * INT_MAX sentinel as the last entry so the compatible type must be + * able to represent INT_MAX. The exact compatible type and its + * signedness remain implementation-defined in this fallback. * * INT_MAX is used rather than a fixed constant like 0xFFFFFFFF - * because enum constants must have type int (which is signed). - * Values above INT_MAX overflow signed int and are a constraint - * violation in standard C; compilers that accept them interpret them - * as negative values via two's complement, which can collide with - * legitimate negative enum values. + * because enum constants must have type int in pre-C23 C. Values above + * INT_MAX are a constraint violation there; compilers that accept them + * may interpret them as negative values via two's complement, which can + * collide with legitimate negative enum values. * * Usage: * @code @@ -61,7 +64,18 @@ * } Foo; * @endcode */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L +#if defined(__cplusplus) && \ + (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1700)) +#define GHOSTTY_ENUM_TYPED : int +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L +#define GHOSTTY_ENUM_TYPED : int +#elif defined(__clang__) + #if __has_extension(c_fixed_enum) + #define GHOSTTY_ENUM_TYPED : int + #else + #define GHOSTTY_ENUM_TYPED + #endif +#elif defined(__GNUC__) && __GNUC__ >= 13 #define GHOSTTY_ENUM_TYPED : int #else #define GHOSTTY_ENUM_TYPED @@ -82,6 +96,16 @@ typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_OUT_OF_SPACE = -3, /** The requested value has no value */ GHOSTTY_NO_VALUE = -4, + /** Operation failed while reading from or writing to external I/O */ + GHOSTTY_IO_ERROR = -5, + /** Operation failed because encoded input exceeded a configured limit */ + GHOSTTY_LIMIT_EXCEEDED = -6, + /** + * Operation was rejected by a safety check (e.g. pasted text that could + * inject commands). Nothing was done. Confirm with the user and retry + * with the operation's allow flag set. + */ + GHOSTTY_REJECTED = -7, GHOSTTY_RESULT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyResult; @@ -94,6 +118,13 @@ typedef enum GHOSTTY_ENUM_TYPED { */ typedef struct GhosttyTerminalImpl* GhosttyTerminal; +/** + * Opaque handle to an incremental terminal snapshot decoder. + * + * @ingroup snapshot + */ +typedef struct GhosttySnapshotDecoderImpl* GhosttySnapshotDecoder; + /** * Opaque handle to a tracked grid reference. * @@ -157,6 +188,19 @@ typedef struct GhosttyRenderStateRowIteratorImpl* GhosttyRenderStateRowIterator; */ typedef struct GhosttyRenderStateRowCellsImpl* GhosttyRenderStateRowCells; +/** + * Opaque handle to a terminal search. + * + * A search is bound to the terminal it was created with. It borrows the + * terminal, so it never frees it, and the search must be freed with + * ghostty_search_free(). If the terminal is freed first, the search + * detects this: calls that need the terminal fail cleanly and the + * search can still be freed. + * + * @ingroup search + */ +typedef struct GhosttySearchImpl* GhosttySearch; + /** * Opaque handle to an SGR parser instance. * @@ -218,6 +262,8 @@ typedef enum GHOSTTY_ENUM_TYPED { * * The memory is not owned by this struct. The pointer is only valid * for the lifetime documented by the API that produces or consumes it. + * Empty strings produced by the library have a non-NULL pointer to valid + * storage. */ typedef struct { /** Pointer to the string bytes. */ @@ -294,33 +340,64 @@ typedef struct { * opts.trim = true; * @endcode */ +#ifdef __cplusplus +#define GHOSTTY_INIT_SIZED(type) \ + ([]() noexcept { \ + type value{}; \ + value.size = sizeof(value); \ + return value; \ + }()) +#else #define GHOSTTY_INIT_SIZED(type) \ ((type){ .size = sizeof(type) }) +#endif /** - * Return a pointer to a null-terminated JSON string describing the - * layout of every C API struct for the current target. + * Return the versioned libghostty-vt C type manifest for the current target. + * + * The manifest defines all the public types available in the linked + * build. The types contain their layouts, enum values, union fields, and more. + * + * Language bindings, such as WebAssembly hosts, should obtain offsets, + * sizes, alignments, array shapes, enum constants, and tagged-union arms from + * this manifest rather than hardcoding them. Consumers should reject unknown + * schema versions and verify the descriptors they require at initialization. + * + * Packed type descriptors define fields using `lsb` and `width`. `lsb` is + * relative to bit zero of the containing numerical value; for nested packed + * layouts it is relative to the immediate containing field. Tagged packed + * unions select an inline arm layout using the named tag field. These layouts + * describe the current linked build and are not a cross-version stability + * promise. * - * This is primarily useful for language bindings that can't easily - * set C struct fields and need to do so via byte offsets. For example, - * WebAssembly modules can't share struct definitions with the host. + * The formal format is defined by the + * libghostty-vt ABI manifest JSON Schema. * * Example (abbreviated): * @code{.json} * { - * "GhosttyMouseEncoderSize": { - * "size": 40, - * "align": 8, - * "fields": { - * "size": { "offset": 0, "size": 8, "type": "u64" }, - * "screen_width": { "offset": 8, "size": 4, "type": "u32" }, - * "screen_height": { "offset": 12, "size": 4, "type": "u32" }, - * "cell_width": { "offset": 16, "size": 4, "type": "u32" }, - * "cell_height": { "offset": 20, "size": 4, "type": "u32" }, - * "padding_top": { "offset": 24, "size": 4, "type": "u32" }, - * "padding_bottom": { "offset": 28, "size": 4, "type": "u32" }, - * "padding_right": { "offset": 32, "size": 4, "type": "u32" }, - * "padding_left": { "offset": 36, "size": 4, "type": "u32" } + * "schema": 1, + * "abi": { + * "target": "wasm32", "os": "freestanding", "environment": "none", + * "pointer_size": 4, "usize_size": 4, "max_alignment": 16, + * "endian": "little" + * }, + * "types": { + * "GhosttyRenderStateData": { + * "kind": "enum", "size": 4, "align": 4, + * "underlying": "i32", "prefix": "GHOSTTY_RENDER_STATE_DATA_", + * "values": { "INVALID": 0, "DIRTY": 3, "MAX_VALUE": 2147483647 } + * }, + * "GhosttyStyleColor": { + * "kind": "struct", "size": 16, "align": 8, + * "fields": { + * "tag": { "offset": 0, "size": 4, + * "type": "GhosttyStyleColorTag" }, + * "value": { "offset": 8, "size": 8, + * "type": "GhosttyStyleColorValue", "tag": "tag", + * "arms": { "NONE": null, "PALETTE": "palette", + * "RGB": "rgb" } } + * } * } * } * } diff --git a/vendor/libghostty-vt/include/ghostty/vt/wasm.h b/vendor/libghostty-vt/include/ghostty/vt/wasm.h index e2b63e2c..2f9ff5df 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/wasm.h +++ b/vendor/libghostty-vt/include/ghostty/vt/wasm.h @@ -10,12 +10,12 @@ #ifdef __wasm__ #include -#include #include /** @defgroup wasm WebAssembly Utilities * - * Convenience functions for allocating various types in WebAssembly builds. + * Convenience functions for working with the low-level C ABI in WebAssembly + * builds. * **These are only available the libghostty-vt wasm module.** * * Ghostty relies on pointers to various types for ABI compatibility, and @@ -28,37 +28,64 @@ * your custom allocator. This is a very rare use case in the WebAssembly * world so these are optimized for simplicity. * + * Use ghostty_wasm_alloc() and ghostty_wasm_free() for host-owned scratch + * buffers and ABI values. Dynamic-language hosts can use ghostty_type_json() + * to discover pointer and size_t widths, maximum alignment, byte order, and + * the size and alignment of public C structs. Do not mix allocation families: + * buffers returned by libghostty-vt allocating APIs must still be released + * with ghostty_free(), and opaque handles must be released with their + * type-specific destructor. + * + * ## Memory growth + * + * An exported function may grow Wasm linear memory when it allocates. Numeric + * pointers and handles remain valid, but JavaScript ArrayBuffer, DataView, and + * typed-array objects created before the growth may no longer cover the live + * memory. Reacquire `exports.memory.buffer` immediately before every host-side + * memory access. A host that caches views should recreate them whenever either + * the buffer identity or its byte length changes. + * * ## Example Usage * - * Here's a simple example of using the Wasm utilities with the key encoder: + * Here's a simple example that creates a terminal, writes bytes, and safely + * handles memory growth: * * @code * const { exports } = wasmInstance; - * const view = new DataView(wasmMemory.buffer); - * - * // Create key encoder - * const encoderPtr = exports.ghostty_wasm_alloc_opaque(); - * exports.ghostty_key_encoder_new(null, encoderPtr); - * const encoder = view.getUint32(encoder, true); - * - * // Configure encoder with Kitty protocol flags - * const flagsPtr = exports.ghostty_wasm_alloc_u8(); - * view.setUint8(flagsPtr, 0x1F); - * exports.ghostty_key_encoder_setopt(encoder, 5, flagsPtr); - * - * // Allocate output buffer and size pointer - * const bufferSize = 32; - * const bufPtr = exports.ghostty_wasm_alloc_u8_array(bufferSize); - * const writtenPtr = exports.ghostty_wasm_alloc_usize(); - * - * // Encode the key event - * exports.ghostty_key_encoder_encode( - * encoder, eventPtr, bufPtr, bufferSize, writtenPtr - * ); - * - * // Read encoded output - * const bytesWritten = view.getUint32(writtenPtr, true); - * const encoded = new Uint8Array(wasmMemory.buffer, bufPtr, bytesWritten); + * const memory = exports.memory; + * let cachedBuffer = null; + * let cachedLength = 0; + * let cachedBytes = null; + * + * function bytes() { + * const buffer = memory.buffer; + * if (buffer !== cachedBuffer || buffer.byteLength !== cachedLength) { + * cachedBuffer = buffer; + * cachedLength = buffer.byteLength; + * cachedBytes = new Uint8Array(buffer); + * } + * return cachedBytes; + * } + * + * function check(result) { + * if (result !== 0) throw new Error(`libghostty-vt error: ${result}`); + * } + * + * // One slot can be reused for every opaque-handle constructor. + * const slot = exports.ghostty_wasm_alloc_opaque(); + * if (slot === 0) throw new Error("out of memory"); + * check(exports.ghostty_terminal_new(0, slot, 80, 24)); + * const terminal = exports.ghostty_wasm_take_opaque(slot); + * + * const input = new TextEncoder().encode("Hello, world!"); + * const inputPtr = exports.ghostty_wasm_alloc(input.length); + * if (inputPtr === 0) throw new Error("out of memory"); + * bytes().set(input, inputPtr); // Acquires the current memory after alloc. + * exports.ghostty_terminal_vt_write(terminal, inputPtr, input.length); + * + * exports.ghostty_wasm_free(inputPtr, input.length); + * exports.ghostty_terminal_free(terminal); + * exports.ghostty_wasm_free_opaque(slot); * @endcode * * @remark The code above is pretty ugly! This is the lowest level interface @@ -69,89 +96,62 @@ */ /** - * Allocate an opaque pointer. This can be used for any opaque pointer - * types such as GhosttyKeyEncoder, GhosttyKeyEvent, etc. - * - * @return Pointer to allocated opaque pointer, or NULL if allocation failed - * @ingroup wasm - */ -GHOSTTY_API void** ghostty_wasm_alloc_opaque(void); - -/** - * Free an opaque pointer allocated by ghostty_wasm_alloc_opaque(). - * - * @param ptr Pointer to free, or NULL (NULL is safely ignored) - * @ingroup wasm - */ -GHOSTTY_API void ghostty_wasm_free_opaque(void **ptr); - -/** - * Allocate an array of uint8_t values. + * Allocate caller-owned storage for a Wasm ABI value or scratch buffer. * - * @param len Number of uint8_t elements to allocate - * @return Pointer to allocated array, or NULL if allocation failed - * @ingroup wasm - */ -GHOSTTY_API uint8_t* ghostty_wasm_alloc_u8_array(size_t len); - -/** - * Free an array allocated by ghostty_wasm_alloc_u8_array(). + * The returned address is aligned to the target's maximum C ABI alignment, + * reported as `abi.max_alignment` by ghostty_type_json(). The memory is + * uninitialized. A zero-length request returns NULL. * - * @param ptr Pointer to the array to free, or NULL (NULL is safely ignored) - * @param len Length of the array (must match the length passed to alloc) - * @ingroup wasm - */ -GHOSTTY_API void ghostty_wasm_free_u8_array(uint8_t *ptr, size_t len); - -/** - * Allocate an array of uint16_t values. + * The returned pointer must be released with ghostty_wasm_free() using the + * exact same length. * - * @param len Number of uint16_t elements to allocate - * @return Pointer to allocated array, or NULL if allocation failed + * @param len Number of bytes to allocate + * @return Pointer to allocated storage, or NULL if len is zero or allocation + * failed * @ingroup wasm */ -GHOSTTY_API uint16_t* ghostty_wasm_alloc_u16_array(size_t len); +GHOSTTY_API void* ghostty_wasm_alloc(size_t len); /** - * Free an array allocated by ghostty_wasm_alloc_u16_array(). + * Free storage allocated by ghostty_wasm_alloc(). * - * @param ptr Pointer to the array to free, or NULL (NULL is safely ignored) - * @param len Length of the array (must match the length passed to alloc) + * @param ptr Pointer to free, or NULL (NULL is safely ignored) + * @param len Original allocation length passed to ghostty_wasm_alloc() * @ingroup wasm */ -GHOSTTY_API void ghostty_wasm_free_u16_array(uint16_t *ptr, size_t len); +GHOSTTY_API void ghostty_wasm_free(void *ptr, size_t len); /** - * Allocate a single uint8_t value. + * Allocate an opaque pointer. This can be used for any opaque pointer + * types such as GhosttyKeyEncoder, GhosttyKeyEvent, etc. The allocated slot + * is initialized to NULL and may be reused across constructors. * - * @return Pointer to allocated uint8_t, or NULL if allocation failed + * @return Pointer to allocated opaque pointer, or NULL if allocation failed * @ingroup wasm */ -GHOSTTY_API uint8_t* ghostty_wasm_alloc_u8(void); +GHOSTTY_API void** ghostty_wasm_alloc_opaque(void); /** - * Free a uint8_t allocated by ghostty_wasm_alloc_u8(). + * Free an opaque pointer allocated by ghostty_wasm_alloc_opaque(). * * @param ptr Pointer to free, or NULL (NULL is safely ignored) * @ingroup wasm */ -GHOSTTY_API void ghostty_wasm_free_u8(uint8_t *ptr); +GHOSTTY_API void ghostty_wasm_free_opaque(void **ptr); /** - * Allocate a single size_t value. + * Take an opaque handle from an out-parameter slot. * - * @return Pointer to allocated size_t, or NULL if allocation failed - * @ingroup wasm - */ -GHOSTTY_API size_t* ghostty_wasm_alloc_usize(void); - -/** - * Free a size_t allocated by ghostty_wasm_alloc_usize(). + * Returns the handle currently stored in @p slot and resets the slot to NULL. + * This function does not allocate, free the returned handle, or free the slot. + * Always check the GhosttyResult returned by the function that populated the + * slot before calling this function. * - * @param ptr Pointer to free, or NULL (NULL is safely ignored) + * @param slot Pointer to an opaque out-parameter slot, or NULL + * @return Stored opaque handle, or NULL if slot or its value is NULL * @ingroup wasm */ -GHOSTTY_API void ghostty_wasm_free_usize(size_t *ptr); +GHOSTTY_API void* ghostty_wasm_take_opaque(void **slot); /** @} */ diff --git a/vendor/libghostty-vt/nix/build-support/check-zig-cache.sh b/vendor/libghostty-vt/nix/build-support/check-zig-cache.sh index 9a392784..52ab1b17 100755 --- a/vendor/libghostty-vt/nix/build-support/check-zig-cache.sh +++ b/vendor/libghostty-vt/nix/build-support/check-zig-cache.sh @@ -79,7 +79,7 @@ elif [ "$1" != "--update" ]; then exit 1 fi -zon2nix "$BUILD_ZIG_ZON" --15 --nix "$WORK_DIR/build.zig.zon.nix" --txt "$WORK_DIR/build.zig.zon.txt" --json "$WORK_DIR/build.zig.zon.json" --flatpak "$WORK_DIR/zig-packages.json" +zon2nix "$BUILD_ZIG_ZON" --16 --nix "$WORK_DIR/build.zig.zon.nix" --txt "$WORK_DIR/build.zig.zon.txt" --json "$WORK_DIR/build.zig.zon.json" --flatpak "$WORK_DIR/zig-packages.json" alejandra --quiet "$WORK_DIR/build.zig.zon.nix" prettier --log-level warn --write "$WORK_DIR/build.zig.zon.json" prettier --log-level warn --write "$WORK_DIR/zig-packages.json" diff --git a/vendor/libghostty-vt/nix/build-support/update-mirror.nu b/vendor/libghostty-vt/nix/build-support/update-mirror.nu index 8571ddea..974e9d0f 100755 --- a/vendor/libghostty-vt/nix/build-support/update-mirror.nu +++ b/vendor/libghostty-vt/nix/build-support/update-mirror.nu @@ -2,23 +2,65 @@ # This script downloads external dependencies from build.zig.zon.json that # are not already mirrored at deps.files.ghostty.org, saves them to a local -# directory, and updates build.zig.zon to point to the new mirror URLs. +# directory, and updates the build.zig.zon files (the root one as well as +# every pkg/*/build.zig.zon) to point to the new mirror URLs. # -# The downloaded files are unmodified so their checksums and content hashes -# will match the originals. +# HTTP files are downloaded unmodified. Git dependencies use Zig's normalized +# cache archive so their content hashes match the originals. # # After running this script, the files in the output directory can be uploaded -# to blob storage, and build.zig.zon will already be updated with the new URLs. +# to blob storage, and the build.zig.zon files will already be updated with +# the new URLs. +def download-git-package [url: string, expected_hash: string, destination: string] { + let cache_dir = (mktemp --directory) + let result = (do { ^zig fetch --global-cache-dir $cache_dir $url } | complete) + + if $result.exit_code != 0 { + rm --recursive $cache_dir + error make { + msg: $"zig fetch failed for ($url): ($result.stderr | str trim)" + } + } + + let actual_hash = ($result.stdout | str trim) + if $actual_hash != $expected_hash { + rm --recursive $cache_dir + error make { + msg: $"zig fetch hash mismatch for ($url): expected ($expected_hash), got ($actual_hash)" + } + } + + let archive = ($cache_dir | path join "p" $"($actual_hash).tar.gz") + if not ($archive | path exists) { + rm --recursive $cache_dir + error make { + msg: $"zig fetch did not produce a cache archive for ($url)" + } + } + + cp $archive $destination + rm --recursive $cache_dir +} + def main [ --output: string = "tmp-mirror", # Output directory for the mirrored files --prefix: string = "https://deps.files.ghostty.org/", # Final URL prefix to ignore --dry-run, # Print what would be downloaded without downloading ] { let script_dir = ($env.CURRENT_FILE | path dirname) - let input_file = ($script_dir | path join ".." ".." "build.zig.zon.json") - let zon_file = ($script_dir | path join ".." ".." "build.zig.zon") + let root_dir = ($script_dir | path join ".." ".." | path expand) + let input_file = ($root_dir | path join "build.zig.zon.json") let output_dir = $output + # All build.zig.zon files that may reference external URLs: the root + # one plus every package under pkg/. build.zig.zon.json is generated + # from the full dependency tree so it covers all of these. + let zon_files = ( + [($root_dir | path join "build.zig.zon")] + | append (glob ($root_dir | path join "pkg" "*" "build.zig.zon")) + | sort + ) + # Ensure the output directory exists mkdir $output_dir @@ -34,8 +76,11 @@ def main [ let name = $entry.value.name let url = $entry.value.url - # Skip URLs that don't start with http(s) - if not ($url | str starts-with "http") { + let is_git_url = ($url | str starts-with "git+http") + let is_http_url = ($url | str starts-with "http") + + # Skip URLs that aren't HTTP downloads or HTTP-backed Git repositories. + if not ($is_http_url or $is_git_url) { continue } @@ -44,8 +89,13 @@ def main [ continue } - # Extract the file extension from the URL - let extension = ($url | parse -r '(\.[a-z0-9]+(?:\.[a-z0-9]+)?)$' | get -o capture0.0 | default "") + # Git dependencies are mirrored using an archive of the normalized package + # tree produced by Zig. Fetching it over HTTP produces the same package hash. + let extension = if $is_git_url { + ".tar.gz" + } else { + $url | parse -r '(\.[a-z0-9]+(?:\.[a-z0-9]+)?)$' | get -o capture0.0 | default "" + } # Try to extract commit hash (40 hex chars) from URL let commit_hash = ($url | parse -r '([a-f0-9]{40})' | get -o capture0.0 | default "") @@ -69,28 +119,45 @@ def main [ # Download the file if not $dry_run { - http get $url | save -f ($output_dir | path join $filename) + let destination = ($output_dir | path join $filename) + if $is_git_url { + download-git-package $url $key $destination + } else { + http get $url | save -f $destination + } } } if $dry_run { print "Dry run complete - no files were downloaded\n" - print $"Would update ($url_replacements | length) URLs in build.zig.zon" } else { print "All dependencies downloaded successfully\n" - print $"Updating ($zon_file)..." - - # Backup the old file - let backup_file = $"($zon_file).bak" - cp $zon_file $backup_file - print $"Backed up to ($backup_file)" - - mut zon_content = (open $zon_file) + } + + # Apply the URL replacements to every build.zig.zon that references them. + for zon_file in $zon_files { + mut zon_content = (open --raw $zon_file) + mut count = 0 for replacement in $url_replacements { - $zon_content = ($zon_content | str replace $replacement.old $replacement.new) + if ($zon_content | str contains $replacement.old) { + $zon_content = ($zon_content | str replace --all $replacement.old $replacement.new) + $count = $count + 1 + } + } + + if $count == 0 { + continue } - $zon_content | save -f $zon_file - print $"Updated ($url_replacements | length) URLs in build.zig.zon" + let relative_path = ($zon_file | path relative-to $root_dir) + if $dry_run { + print $"Would update ($count) URLs in ($relative_path)" + } else { + # Backup the old file + let backup_file = $"($zon_file).bak" + cp $zon_file $backup_file + $zon_content | save -f $zon_file + print $"Updated ($count) URLs in ($relative_path), backup at ($relative_path).bak" + } } } diff --git a/vendor/libghostty-vt/nix/devShell.nix b/vendor/libghostty-vt/nix/devShell.nix index b530c56c..fba128a2 100644 --- a/vendor/libghostty-vt/nix/devShell.nix +++ b/vendor/libghostty-vt/nix/devShell.nix @@ -24,10 +24,13 @@ #, vulkan-loader # unused vttest, wabt, + wasm-tools, wasmtime, + binaryen, + twiggy, + wizer, wraptest, zig, - zig_0_15, zip, llvmPackages_latest, bzip2, @@ -60,6 +63,7 @@ zlib, alejandra, jq, + kaitai-struct-compiler, minisign, pandoc, pinact, @@ -86,6 +90,12 @@ gi_typelib_path = import ./build-support/gi-typelib-path.nix { inherit pkgs lib stdenv; }; + python = python3.withPackages (python-pkgs: [ + python-pkgs.jsonschema + python-pkgs.kaitaistruct + python-pkgs.ucs-detect + python-pkgs.wasmtime + ]); in mkShell { name = "ghostty"; @@ -117,13 +127,18 @@ in # Testing parallel - python3 + python vttest hyperfine + kaitai-struct-compiler # wasm + binaryen + twiggy wabt + wasm-tools wasmtime + wizer # Localization gettext @@ -139,11 +154,6 @@ in blueprint-compiler libadwaita gtk4 - - # Python packages - (python3.withPackages (python-pkgs: [ - python-pkgs.ucs-detect - ])) ] ++ lib.optionals stdenv.hostPlatform.isLinux [ # My nix shell environment installs the non-interactive version @@ -222,8 +232,7 @@ in '') + (lib.optionalString stdenv.hostPlatform.isDarwin '' # On macOS, we unset the macOS SDK env vars that Nix sets up because - # we rely on a system installation. Nix only provides a macOS SDK - # and we need iOS too. + # we rely on a system installation. Nix only provides a macOS SDK. unset SDKROOT unset DEVELOPER_DIR @@ -243,6 +252,6 @@ in # We need to remove "xcrun" from the PATH. It is injected by # some dependency but we need to rely on system Xcode tools export PATH=$(echo "$PATH" | awk -v RS=: -v ORS=: '$0 !~ /xcrun/ || $0 == "/usr/bin" {print}' | sed 's/:$//') - export PATH="/opt/homebrew/opt/llvm/bin:/opt/homebrew/bin:/usr/local/opt/llvm/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH" + export PATH="${python}/bin:/opt/homebrew/opt/llvm/bin:/opt/homebrew/bin:/usr/local/opt/llvm/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH" ''); } diff --git a/vendor/libghostty-vt/nix/libghostty-vt.nix b/vendor/libghostty-vt/nix/libghostty-vt.nix index 2b67fc83..78072ed1 100644 --- a/vendor/libghostty-vt/nix/libghostty-vt.nix +++ b/vendor/libghostty-vt/nix/libghostty-vt.nix @@ -11,7 +11,7 @@ versionCheckHook, darwin, xcbuild, - zig_0_15, + zig_0_16, revision ? "dirty", optimize ? "Debug", simd ? true, @@ -59,7 +59,7 @@ stdenv.mkDerivation (finalAttrs: { [ git pkg-config - zig_0_15 + zig_0_16 ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ darwin.cctools @@ -264,7 +264,7 @@ stdenv.mkDerivation (finalAttrs: { meta = { homepage = "https://ghostty.org"; license = lib.licenses.mit; - platforms = zig_0_15.meta.platforms; + platforms = zig_0_16.meta.platforms; pkgConfigModules = [ "libghostty-vt" "libghostty-vt-static" diff --git a/vendor/libghostty-vt/nix/package.nix b/vendor/libghostty-vt/nix/package.nix index fd952c9d..31db683c 100644 --- a/vendor/libghostty-vt/nix/package.nix +++ b/vendor/libghostty-vt/nix/package.nix @@ -10,7 +10,7 @@ git, ncurses, pkg-config, - zig_0_15, + zig_0_16, pandoc, revision ? "dirty", optimize ? "Debug", @@ -63,7 +63,7 @@ in ncurses pandoc pkg-config - zig_0_15 + zig_0_16 gobject-introspection wrapGAppsHook4 blueprint-compiler diff --git a/vendor/libghostty-vt/pkg/afl++/build.zig b/vendor/libghostty-vt/pkg/afl++/build.zig index 9f6f70e9..42e514a0 100644 --- a/vendor/libghostty-vt/pkg/afl++/build.zig +++ b/vendor/libghostty-vt/pkg/afl++/build.zig @@ -9,11 +9,6 @@ pub fn addInstrumentedExe( b: *std.Build, obj: *std.Build.Step.Compile, ) std.Build.LazyPath { - // Force the build system to produce the binary artifact even though we - // only consume the LLVM bitcode below. Without this, the dependency - // tracking doesn't wire up correctly. - _ = obj.getEmittedBin(); - const pkg = b.dependencyFromBuildZig( @This(), .{}, @@ -34,6 +29,25 @@ pub fn addInstrumentedExe( const fuzz_exe = afl_cc.addOutputFileArg(obj.name); afl_cc.addFileArg(pkg.path("afl.c")); afl_cc.addFileArg(obj.getEmittedLlvmBc()); + + // The LLVM bitcode only contains the Zig code in the compilation. + // C source files in the module graph are compiled to native objects + // that live only in the static archive, so link the archive after + // the bitcode to resolve those symbols. The archive members holding + // the Zig code are never pulled in (and so can't conflict) because + // the bitcode object already defines every symbol they provide. + // Those C objects are built with UBSan in debug modes and we link + // with an external compiler that doesn't provide Zig's ubsan + // runtime, so it must be bundled. The ubsan runtime uses f128 + // conversion builtins that the external compiler's runtime may not + // provide (e.g. Apple's), so Zig's compiler-rt must be bundled too. + // The archive members must also be built as PIC since external + // compilers typically default to PIE executables. + obj.bundle_ubsan_rt = true; + obj.bundle_compiler_rt = true; + obj.root_module.pic = true; + afl_cc.addFileArg(obj.getEmittedBin()); + return fuzz_exe; } diff --git a/vendor/libghostty-vt/pkg/android-ndk/build.zig b/vendor/libghostty-vt/pkg/android-ndk/build.zig index 5b005665..10501700 100644 --- a/vendor/libghostty-vt/pkg/android-ndk/build.zig +++ b/vendor/libghostty-vt/pkg/android-ndk/build.zig @@ -118,16 +118,16 @@ pub fn addPaths(b: *std.Build, step: *std.Build.Step.Compile) !void { fn findNDKPath(b: *std.Build) ?[]const u8 { // Check if user has set the environment variable for the NDK path. - if (std.process.getEnvVarOwned(b.allocator, "ANDROID_NDK_HOME") catch null) |value| { + if (b.graph.environ_map.get("ANDROID_NDK_HOME")) |value| { if (value.len == 0) return null; - var dir = std.fs.openDirAbsolute(value, .{}) catch return null; - defer dir.close(); + var dir = std.Io.Dir.openDirAbsolute(b.graph.io, value, .{}) catch return null; + defer dir.close(b.graph.io); return value; } // Check the common environment variables for the Android SDK path and look for the NDK inside it. inline for (.{ "ANDROID_HOME", "ANDROID_SDK_ROOT" }) |env| { - if (std.process.getEnvVarOwned(b.allocator, env) catch null) |sdk| { + if (b.graph.environ_map.get(env)) |sdk| { if (sdk.len > 0) { if (findLatestNDK(b, sdk)) |ndk| return ndk; } @@ -135,18 +135,16 @@ fn findNDKPath(b: *std.Build) ?[]const u8 { } // As a fallback, we assume the most common/default SDK path based on the OS. - const home = std.process.getEnvVarOwned( - b.allocator, + const home = b.graph.environ_map.get( if (builtin.os.tag == .windows) "LOCALAPPDATA" else "HOME", - ) catch return null; + ) orelse return null; const default_sdk_path = b.pathJoin( &.{ home, switch (builtin.os.tag) { - .linux => "Android/sdk", + .linux, .windows => "Android/Sdk", .macos => "Library/Android/Sdk", - .windows => "Android/Sdk", else => return null, }, }, @@ -157,8 +155,8 @@ fn findNDKPath(b: *std.Build) ?[]const u8 { fn findLatestNDK(b: *std.Build, sdk_path: []const u8) ?[]const u8 { const ndk_dir = b.pathJoin(&.{ sdk_path, "ndk" }); - var dir = std.fs.openDirAbsolute(ndk_dir, .{ .iterate = true }) catch return null; - defer dir.close(); + var dir = std.Io.Dir.openDirAbsolute(b.graph.io, ndk_dir, .{ .iterate = true }) catch return null; + defer dir.close(b.graph.io); var latest_: ?struct { name: []const u8, @@ -166,7 +164,7 @@ fn findLatestNDK(b: *std.Build, sdk_path: []const u8) ?[]const u8 { } = null; var iterator = dir.iterate(); - while (iterator.next() catch null) |file| { + while (iterator.next(b.graph.io) catch null) |file| { if (file.kind != .directory) continue; const version = std.SemanticVersion.parse(file.name) catch continue; if (latest_) |latest| { diff --git a/vendor/libghostty-vt/pkg/apple-sdk/build.zig b/vendor/libghostty-vt/pkg/apple-sdk/build.zig index f897919f..3f76c0bf 100644 --- a/vendor/libghostty-vt/pkg/apple-sdk/build.zig +++ b/vendor/libghostty-vt/pkg/apple-sdk/build.zig @@ -1,6 +1,34 @@ const std = @import("std"); const builtin = @import("builtin"); +/// Helpers for linking Mach-O artifacts with Apple's native toolchain. +pub const nativeLink = @import("native_link.zig"); + +// The cache. This always uses b.allocator and never frees memory +// (which is idiomatic for a Zig build exe). We cache the libc txt +// file we create because it is expensive to generate (subprocesses). +pub const Cache = struct { + const Key = struct { + arch: std.Target.Cpu.Arch, + os: std.Target.Os.Tag, + abi: std.Target.Abi, + }; + + pub const Value = union(enum) { + native: struct { + libc: std.Build.LazyPath, + framework: []const u8, + system_include: []const u8, + library: []const u8, + }, + cross: struct { + libc: std.Build.LazyPath, + }, + }; + + var map: std.AutoHashMapUnmanaged(Key, ?Value) = .{}; +}; + pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); @@ -8,40 +36,11 @@ pub fn build(b: *std.Build) !void { _ = optimize; } -/// Setup the step to point to the proper Apple SDK for libc and +/// Fetch or load the paths for the proper Apple SDK for libc and /// frameworks. When running on a Darwin host, this uses the native /// SDK installed on the system via `xcrun`. When cross-compiling from /// a non-Darwin host, it falls back to Zig's bundled Darwin headers. -pub fn addPaths( - b: *std.Build, - step: *std.Build.Step.Compile, -) !void { - // The cache. This always uses b.allocator and never frees memory - // (which is idiomatic for a Zig build exe). We cache the libc txt - // file we create because it is expensive to generate (subprocesses). - const Cache = struct { - const Key = struct { - arch: std.Target.Cpu.Arch, - os: std.Target.Os.Tag, - abi: std.Target.Abi, - }; - - const Value = union(enum) { - native: struct { - libc: std.Build.LazyPath, - framework: []const u8, - system_include: []const u8, - library: []const u8, - }, - cross: struct { - libc: std.Build.LazyPath, - }, - }; - - var map: std.AutoHashMapUnmanaged(Key, ?Value) = .{}; - }; - - const target = step.rootModuleTarget(); +pub fn pathsForTarget(b: *std.Build, target: std.Target) !Cache.Value { const gop = try Cache.map.getOrPut(b.allocator, .{ .arch = target.cpu.arch, .os = target.os.tag, @@ -53,14 +52,32 @@ pub fn addPaths( // Detect our SDK using the "findNative" Zig stdlib function. // This is really important because it forces using `xcrun` to // find the SDK path. - const libc = std.zig.LibCInstallation.findNative(.{ - .allocator = b.allocator, - .target = &step.rootModuleTarget(), - .verbose = false, - }) catch break :darwin; + var libc = std.zig.LibCInstallation.findNative( + b.allocator, + b.graph.io, + .{ + .environ_map = &b.graph.environ_map, + .target = &target, + .verbose = false, + }, + ) catch break :darwin; + + // Xcode 27's math.h requests infinity and NaN definitions from + // Clang's float.h using the __need_infinity_nan protocol. Zig + // 0.16's bundled Clang resource headers predate that protocol, so + // compiling Zig's bundled libc++ against the new SDK fails. + // + // Put our compatibility include directory between Zig's resource + // headers and the selected SDK headers. Its math.h forwards to the + // SDK with #include_next, then supplies the definitions missing + // from Zig's float.h. This can be removed once Zig's bundled Clang + // headers implement __need_infinity_nan. + libc.include_dir = b.dependency("apple_sdk", .{}) + .path("include") + .getPath(b); // Render the file compatible with the `--libc` Zig flag. - var stream: std.io.Writer.Allocating = .init(b.allocator); + var stream: std.Io.Writer.Allocating = .init(b.allocator); defer stream.deinit(); try libc.render(&stream.writer); @@ -112,7 +129,7 @@ pub fn addPaths( // Fall back to Zig's bundled Darwin headers for libc resolution. const zig_lib_path = b.graph.zig_lib_directory.path.?; const include_dir = b.pathJoin(&.{ - zig_lib_path, "libc", "include", "any-macos-any", + zig_lib_path, "libc", "include", "any-darwin-any", }); const wf = b.addWriteFiles(); @@ -129,7 +146,7 @@ pub fn addPaths( gop.value_ptr.* = .{ .cross = .{ .libc = path } }; } - const value = gop.value_ptr.* orelse return switch (target.os.tag) { + return gop.value_ptr.* orelse return switch (target.os.tag) { // Return a more descriptive error. Before we just returned the // generic error but this was confusing a lot of community members. // It costs us nothing in the build script to return something better. @@ -139,8 +156,42 @@ pub fn addPaths( .watchos => error.XcodeWatchOSSDKNotFound, else => error.XcodeAppleSDKNotFound, }; +} + +/// Setup the step to point to the proper Apple SDK for libc and +/// frameworks. When running on a Darwin host, this uses the native +/// SDK installed on the system via `xcrun`. When cross-compiling from +/// a non-Darwin host, it falls back to Zig's bundled Darwin headers. +pub fn addPaths( + b: *std.Build, + step: *std.Build.Step.Compile, +) !void { + const target = step.rootModuleTarget(); - switch (value) { + // A three paragraph comment to describe a single C macro. Strap in. + // + // Zig uses its own libc++ headers when compiling C++. In Zig 0.16, + // `__config` skips `__config_site`, the file that normally contains + // platform settings, and expects those settings as `-D` flags: + // https://codeberg.org/ziglang/zig/src/tag/0.16.0/lib/libcxx/include/__config#L13 + // + // This macro enables Apple's availability checks. Without them, libc++ + // assumes every symbol declared by these newer headers also exists in the + // target's runtime library: + // https://github.com/llvm/llvm-project/blob/llvmorg-21.1.0/libcxx/include/__configuration/availability.h#L63-L125 + // + // For example, `hash.h` either calls `std::__hash_memory` from the runtime + // library or compiles an inline fallback: + // https://github.com/llvm/llvm-project/blob/llvmorg-21.1.0/libcxx/include/__functional/hash.h#L244-L250 + // Without the checks, it chooses the runtime symbol. Older macOS versions + // don't have that symbol, so dyld aborts at launch: + // https://github.com/llvm/llvm-project/issues/155531 + step.root_module.addCMacro( + "_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS", + "1", + ); + + switch (try pathsForTarget(b, target)) { .native => |native| { step.setLibCFile(native.libc); diff --git a/vendor/libghostty-vt/pkg/apple-sdk/include/math.h b/vendor/libghostty-vt/pkg/apple-sdk/include/math.h new file mode 100644 index 00000000..507c3c70 --- /dev/null +++ b/vendor/libghostty-vt/pkg/apple-sdk/include/math.h @@ -0,0 +1,21 @@ +#ifndef GHOSTTY_APPLE_SDK_MATH_H +#define GHOSTTY_APPLE_SDK_MATH_H + +// Resume the header search after this compatibility directory so we include +// the selected Xcode SDK's math.h. A regular #include would find this +// wrapper again and loop forever. This is a Clang extension but Zig uses +// Clang so we good. +#include_next + +// Xcode 27's math.h expects Clang's float.h to define these when requested +// with __need_infinity_nan. Zig 0.16's bundled float.h predates that protocol; +// remove these fallbacks once Zig's bundled Clang headers implement it. +#ifndef INFINITY +#define INFINITY (__builtin_inff()) +#endif + +#ifndef NAN +#define NAN (__builtin_nanf("")) +#endif + +#endif diff --git a/vendor/libghostty-vt/pkg/apple-sdk/native_link.zig b/vendor/libghostty-vt/pkg/apple-sdk/native_link.zig new file mode 100644 index 00000000..46ceeb76 --- /dev/null +++ b/vendor/libghostty-vt/pkg/apple-sdk/native_link.zig @@ -0,0 +1,85 @@ +//! Helpers for invoking Apple's native linker through the target SDK. +//! +//! Callers provide all artifact-specific flags, inputs, and outputs. + +const std = @import("std"); +const builtin = @import("builtin"); +const RunStep = std.Build.Step.Run; + +/// Returns true when the host Apple toolchain can link the target. +/// +/// This is limited to targets covered by the SDK and target-triple mappings +/// below. Add other Darwin platforms alongside support for those mappings. +pub fn available(target: std.Build.ResolvedTarget) bool { + if (!builtin.os.tag.isDarwin()) return false; + + return switch (target.result.os.tag) { + .macos, .ios => true, + else => false, + }; +} + +/// Create an Apple Clang link command configured for the target SDK and +/// deployment version. The caller supplies the artifact-specific link flags, +/// inputs, and output. +pub fn addCommand( + b: *std.Build, + name: []const u8, + target: std.Build.ResolvedTarget, +) !*RunStep { + if (!available(target)) return error.AppleNativeLinkerUnavailable; + + const run = RunStep.create(b, name); + run.addArgs(&.{ + "/usr/bin/xcrun", + "--sdk", + try sdkName(target), + "clang", + "-fuse-ld=ld", + "-target", + try clangTarget(b, target), + }); + return run; +} + +fn sdkName(target: std.Build.ResolvedTarget) ![]const u8 { + return switch (target.result.os.tag) { + .macos => "macosx", + .ios => switch (target.result.abi) { + .simulator => "iphonesimulator", + else => "iphoneos", + }, + else => error.UnsupportedAppleTarget, + }; +} + +fn clangTarget( + b: *std.Build, + target: std.Build.ResolvedTarget, +) ![]const u8 { + const arch = switch (target.result.cpu.arch) { + .aarch64 => "arm64", + .x86_64 => "x86_64", + else => return error.UnsupportedAppleArchitecture, + }; + const minimum = target.query.os_version_min orelse + return error.AppleDeploymentTargetMissing; + + return switch (target.result.os.tag) { + .macos => b.fmt( + "{s}-apple-macosx{f}", + .{ arch, minimum.semver }, + ), + .ios => switch (target.result.abi) { + .simulator => b.fmt( + "{s}-apple-ios{f}-simulator", + .{ arch, minimum.semver }, + ), + else => b.fmt( + "{s}-apple-ios{f}", + .{ arch, minimum.semver }, + ), + }, + else => error.UnsupportedAppleTarget, + }; +} diff --git a/vendor/libghostty-vt/pkg/breakpad/build.zig b/vendor/libghostty-vt/pkg/breakpad/build.zig index 56d51b15..ce02b34f 100644 --- a/vendor/libghostty-vt/pkg/breakpad/build.zig +++ b/vendor/libghostty-vt/pkg/breakpad/build.zig @@ -9,11 +9,11 @@ pub fn build(b: *std.Build) !void { .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libcpp = true, }), .linkage = .static, }); - lib.linkLibCpp(); - lib.addIncludePath(b.path("vendor")); + lib.root_module.addIncludePath(b.path("vendor")); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); try apple_sdk.addPaths(b, lib); @@ -23,20 +23,20 @@ pub fn build(b: *std.Build) !void { defer flags.deinit(b.allocator); if (b.lazyDependency("breakpad", .{})) |upstream| { - lib.addIncludePath(upstream.path("src")); - lib.addCSourceFiles(.{ + lib.root_module.addIncludePath(upstream.path("src")); + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = common, .flags = flags.items, }); if (target.result.os.tag.isDarwin()) { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = common_apple, .flags = flags.items, }); - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = client_apple, .flags = flags.items, @@ -44,19 +44,19 @@ pub fn build(b: *std.Build) !void { switch (target.result.os.tag) { .macos => { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = common_mac, .flags = flags.items, }); - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = client_mac, .flags = flags.items, }); }, - .ios => lib.addCSourceFiles(.{ + .ios => lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = client_ios, .flags = flags.items, @@ -67,12 +67,12 @@ pub fn build(b: *std.Build) !void { } if (target.result.os.tag == .linux) { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = common_linux, .flags = flags.items, }); - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = client_linux, .flags = flags.items, diff --git a/vendor/libghostty-vt/pkg/dcimgui/build.zig b/vendor/libghostty-vt/pkg/dcimgui/build.zig index 924e7c93..f74d3673 100644 --- a/vendor/libghostty-vt/pkg/dcimgui/build.zig +++ b/vendor/libghostty-vt/pkg/dcimgui/build.zig @@ -22,18 +22,16 @@ pub fn build(b: *std.Build) !void { .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, + // On MSVC, we must not use linkLibCpp because Zig unconditionally + // passes -nostdinc++ and then adds its bundled libc++/libc++abi + // include paths, which conflict with MSVC's own C++ runtime + // headers. The MSVC SDK include directories (added via linkLibC) + // contain both C and C++ headers, so linkLibCpp is not needed. + .link_libcpp = target.result.abi != .msvc, }), .linkage = .static, }); - lib.linkLibC(); - // On MSVC, we must not use linkLibCpp because Zig unconditionally - // passes -nostdinc++ and then adds its bundled libc++/libc++abi - // include paths, which conflict with MSVC's own C++ runtime headers. - // The MSVC SDK include directories (added via linkLibC) contain - // both C and C++ headers, so linkLibCpp is not needed. - if (target.result.abi != .msvc) { - lib.linkLibCpp(); - } b.installArtifact(lib); // Zig module @@ -87,8 +85,8 @@ pub fn build(b: *std.Build) !void { // Add the core Dear Imgui source files if (b.lazyDependency("imgui", .{})) |upstream| { - lib.addIncludePath(upstream.path("")); - lib.addCSourceFiles(.{ + lib.root_module.addIncludePath(upstream.path("")); + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "imgui_demo.cpp", @@ -107,20 +105,20 @@ pub fn build(b: *std.Build) !void { ); if (freetype) { - lib.addCSourceFile(.{ + lib.root_module.addCSourceFile(.{ .file = upstream.path("misc/freetype/imgui_freetype.cpp"), .flags = flags.items, }); if (b.systemIntegrationOption("freetype", .{})) { - lib.linkSystemLibrary2("freetype2", dynamic_link_opts); + lib.root_module.linkSystemLibrary("freetype2", dynamic_link_opts); } else { const freetype_dep = b.dependency("freetype", .{ .target = target, .optimize = optimize, .@"enable-libpng" = true, }); - lib.linkLibrary(freetype_dep.artifact("freetype")); + lib.root_module.linkLibrary(freetype_dep.artifact("freetype")); if (freetype_dep.builder.lazyDependency( "freetype", .{}, @@ -131,7 +129,7 @@ pub fn build(b: *std.Build) !void { } if (backend_metal) { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path("backends"), .files = &.{"imgui_impl_metal.mm"}, .flags = flags.items, @@ -143,7 +141,7 @@ pub fn build(b: *std.Build) !void { ); } if (backend_osx) { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path("backends"), .files = &.{"imgui_impl_osx.mm"}, .flags = flags.items, @@ -155,7 +153,7 @@ pub fn build(b: *std.Build) !void { ); } if (backend_opengl3) { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path("backends"), .files = &.{"imgui_impl_opengl3.cpp"}, .flags = flags.items, @@ -170,8 +168,8 @@ pub fn build(b: *std.Build) !void { // Add the C bindings if (b.lazyDependency("bindings", .{})) |upstream| { - lib.addIncludePath(upstream.path("")); - lib.addCSourceFiles(.{ + lib.root_module.addIncludePath(upstream.path("")); + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "dcimgui.cpp", @@ -179,7 +177,7 @@ pub fn build(b: *std.Build) !void { }, .flags = flags.items, }); - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = b.path(""), .files = &.{"ext.cpp"}, .flags = flags.items, @@ -201,7 +199,7 @@ pub fn build(b: *std.Build) !void { }), }); test_exe.root_module.addOptions("build_options", options); - test_exe.linkLibrary(lib); + test_exe.root_module.linkLibrary(lib); const tests_run = b.addRunArtifact(test_exe); const test_step = b.step("test", "Run tests"); test_step.dependOn(&tests_run.step); diff --git a/vendor/libghostty-vt/pkg/dcimgui/build.zig.zon b/vendor/libghostty-vt/pkg/dcimgui/build.zig.zon index 95d0120e..c488e612 100644 --- a/vendor/libghostty-vt/pkg/dcimgui/build.zig.zon +++ b/vendor/libghostty-vt/pkg/dcimgui/build.zig.zon @@ -15,7 +15,7 @@ .imgui = .{ // https://github.com/ocornut/imgui - .url = "https://github.com/ocornut/imgui/archive/refs/tags/v1.92.5-docking.tar.gz", + .url = "https://deps.files.ghostty.org/N-V-__8AAEbOfQBnvcFcCX2W5z7tDaN8vaNZGamEQtNOe0UI.tar.gz", .hash = "N-V-__8AAEbOfQBnvcFcCX2W5z7tDaN8vaNZGamEQtNOe0UI", .lazy = true, }, diff --git a/vendor/libghostty-vt/pkg/fontconfig/build.zig b/vendor/libghostty-vt/pkg/fontconfig/build.zig index 7c87d1f2..a1f43eac 100644 --- a/vendor/libghostty-vt/pkg/fontconfig/build.zig +++ b/vendor/libghostty-vt/pkg/fontconfig/build.zig @@ -1,6 +1,49 @@ const std = @import("std"); +const build_zon = @import("build.zig.zon"); const NativeTargetInfo = std.zig.system.NativeTargetInfo; +// NOTE: This build is becoming more and more complex; we need to continually +// extract the correct options from fontconfig build process (although this +// part has been reasonably manageable for now); more concerning is the fact +// that we also need to now extract more generated files as fontconfig is +// leaning on generation more during their own Autoconf/Meson toolchain. +// Additionally, the Autoconf process (which incidentally is what Nix uses as +// well) has been deprecated since 2.18.3 (based on tracking the contents of +// the INSTALL file), which means we will need to lean on Meson more and more +// for this data. +// +// For now, autoconf still seems to work and can get us the files we need. +// +// If this build fails for any reason during update, you will need to inspect +// the build logs and extract any possible missing headers. These can be +// fetched through the following: +// +// * Set yourself up a Nix flake or build environment otherwise with the +// following deps (note: these were extracted from the Nix package itself): +// +// autoconf +// automake +// expat +// freetype +// gettext +// gperf +// libtool +// libxslt +// pkg-config +// python3 +// +// * Fetch the fontconfig source and extract it in this environment. +// +// * In the source root, run "./autogen.sh" followed by "make". (Don't run +// "make install"). +// +// * You should now have a reasonable set of files that you can use to hunt for +// any missing auto-generated headers and plumb through errors otherwise. +// +// * Make sure when you copy includes and what not into the "override" tree, +// that you preserve directory structure. This will help us keep track of what +// we need and where it specifically came from. + pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); @@ -41,7 +84,7 @@ pub fn build(b: *std.Build) !void { if (b.systemIntegrationOption("fontconfig", .{})) { module.linkSystemLibrary("fontconfig", dynamic_link_opts); - test_exe.linkSystemLibrary2("fontconfig", dynamic_link_opts); + test_exe.root_module.linkSystemLibrary("fontconfig", dynamic_link_opts); } else { const lib = try buildLib(b, module, .{ .target = target, @@ -54,7 +97,7 @@ pub fn build(b: *std.Build) !void { .dynamic_link_opts = dynamic_link_opts, }); - test_exe.linkLibrary(lib); + test_exe.root_module.linkLibrary(lib); } } @@ -71,19 +114,43 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, }), .linkage = .static, }); - lib.linkLibC(); + + const dynamic_link_opts = options.dynamic_link_opts; + if (target.result.os.tag != .windows) { - lib.linkSystemLibrary("pthread"); + lib.root_module.linkSystemLibrary("pthread", dynamic_link_opts); } - lib.addIncludePath(b.path("override/include")); - module.addIncludePath(b.path("override/include")); + // NOTE: The following directories are present in override but don't need + // to be added here: + // + // override/fc-case + // + inline for (.{ + "override", + "override/fc-const", + "override/fc-genericfamily", + "override/fc-lang", + "override/src", + }) |override_dir| { + lib.root_module.addIncludePath(b.path(override_dir)); + module.addIncludePath(b.path(override_dir)); + } var flags: std.ArrayList([]const u8) = .empty; defer flags.deinit(b.allocator); + + const version = try std.SemanticVersion.parse(build_zon.version); + try flags.appendSlice(b.allocator, &.{ + b.fmt("-DFC_VERSION_MAJOR={d}", .{version.major}), + b.fmt("-DFC_VERSION_MINOR={d}", .{version.minor}), + b.fmt("-DFC_VERSION_MICRO={d}", .{version.patch}), + }); + try flags.appendSlice(b.allocator, &.{ "-DHAVE_DIRENT_H", "-DHAVE_FCNTL_H", @@ -98,6 +165,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu "-DHAVE_RAND", //"-DHAVE_RANDOM_R", "-DHAVE_VPRINTF", + "-DHAVE_VSNPRINTF", "-DHAVE_FT_GET_BDF_PROPERTY", "-DHAVE_FT_GET_PS_FONT_INFO", @@ -165,6 +233,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu "-DHAVE_RANDOM", "-DHAVE_RAND_R", "-DHAVE_READLINK", + "-DHAVE_USELOCALE", "-DHAVE_SYS_MOUNT_H", "-DHAVE_SYS_STATVFS_H", @@ -194,19 +263,19 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu } } - const dynamic_link_opts = options.dynamic_link_opts; - // Freetype2 _ = b.systemIntegrationOption("freetype", .{}); // So it shows up in help if (freetype_enabled) { + // Value-tested (#if/#elif) by upstream so it must be =1. + try flags.append(b.allocator, "-DENABLE_FREETYPE=1"); if (b.systemIntegrationOption("freetype", .{})) { - lib.linkSystemLibrary2("freetype2", dynamic_link_opts); + lib.root_module.linkSystemLibrary("freetype2", dynamic_link_opts); } else { if (b.lazyDependency( "freetype", .{ .target = target, .optimize = optimize }, )) |freetype_dep| { - lib.linkLibrary(freetype_dep.artifact("freetype")); + lib.root_module.linkLibrary(freetype_dep.artifact("freetype")); } } } @@ -227,22 +296,22 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu } if (b.systemIntegrationOption("libxml2", .{})) { - lib.linkSystemLibrary2("libxml-2.0", dynamic_link_opts); + lib.root_module.linkSystemLibrary("libxml-2.0", dynamic_link_opts); } else { if (b.lazyDependency("libxml2", .{ .target = target, .optimize = optimize, .iconv = libxml2_iconv_enabled, })) |libxml2_dep| { - lib.linkLibrary(libxml2_dep.artifact("xml2")); + lib.root_module.linkLibrary(libxml2_dep.artifact("xml2")); } } } if (b.lazyDependency("fontconfig", .{})) |upstream| { - lib.addIncludePath(upstream.path("")); + lib.root_module.addIncludePath(upstream.path("")); module.addIncludePath(upstream.path("")); - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = srcs, .flags = flags.items, @@ -253,6 +322,18 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu "fontconfig", .{ .include_extensions = &.{".h"} }, ); + + // Upstream only ships fontconfig.h.in; we generate fontconfig.h into + // our override directory. + // + // TODO: I'm not too sure if this is fully needed - testing the build + // with both system integration on and off seems to be not break with + // this missing (and for that matter, all of the header install stuff + // we do, funny enough). + lib.installHeader( + b.path("override/fontconfig/fontconfig.h"), + "fontconfig/fontconfig.h", + ); } b.installArtifact(lib); @@ -260,12 +341,6 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu return lib; } -const headers = &.{ - "fontconfig/fontconfig.h", - "fontconfig/fcprivate.h", - "fontconfig/fcfreetype.h", -}; - const srcs: []const []const u8 = &.{ "src/fcatomic.c", "src/fccache.c", @@ -278,6 +353,7 @@ const srcs: []const []const u8 = &.{ "src/fcformat.c", "src/fcfreetype.c", "src/fcfs.c", + "src/fcgenericalias.c", "src/fcptrlist.c", "src/fchash.c", "src/fcinit.c", diff --git a/vendor/libghostty-vt/pkg/fontconfig/build.zig.zon b/vendor/libghostty-vt/pkg/fontconfig/build.zig.zon index b1387b87..5249219c 100644 --- a/vendor/libghostty-vt/pkg/fontconfig/build.zig.zon +++ b/vendor/libghostty-vt/pkg/fontconfig/build.zig.zon @@ -5,8 +5,8 @@ .paths = .{""}, .dependencies = .{ .fontconfig = .{ - .url = "https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz", - .hash = "N-V-__8AAIrfdwARSa-zMmxWwFuwpXf1T3asIN7s5jqi9c1v", + .url = "https://gitlab.freedesktop.org/api/v4/projects/890/packages/generic/fontconfig/2.18.3/fontconfig-2.18.3.tar.xz", + .hash = "N-V-__8AAOgqbADacob-q2_DMQlmgaG4xKHRuW-6PJ4oJzMZ", .lazy = true, }, diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/fc-case/fccase.h b/vendor/libghostty-vt/pkg/fontconfig/override/fc-case/fccase.h new file mode 100644 index 00000000..68d019ce --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/fc-case/fccase.h @@ -0,0 +1,354 @@ +/* + * This file was generated against CaseFolding.txt from Unicode.org. + * All the data in array is a part of them and licensed under a terms of use: + * https://www.unicode.org/terms_of_use.html + */ + +#define FC_NUM_CASE_FOLD 306 +#define FC_NUM_CASE_FOLD_CHARS 471 +#define FC_MAX_CASE_FOLD_CHARS 6 +#define FC_MAX_CASE_FOLD_EXPAND 4 +#define FC_MIN_FOLD_CHAR 0x00000041 +#define FC_MAX_FOLD_CHAR 0x0001e921 + +static const FcCaseFold fcCaseFold[FC_NUM_CASE_FOLD] = { + { 0x00000041, FC_CASE_FOLD_RANGE, 0x001a, 32 }, + { 0x000000b5, FC_CASE_FOLD_RANGE, 0x0001, 775 }, + { 0x000000c0, FC_CASE_FOLD_RANGE, 0x0017, 32 }, + { 0x000000d8, FC_CASE_FOLD_RANGE, 0x0007, 32 }, + { 0x000000df, FC_CASE_FOLD_FULL, 0x0002, 0 }, + { 0x00000100, FC_CASE_FOLD_EVEN_ODD, 0x002f, 1 }, + { 0x00000130, FC_CASE_FOLD_FULL, 0x0003, 2 }, + { 0x00000132, FC_CASE_FOLD_EVEN_ODD, 0x0005, 1 }, + { 0x00000139, FC_CASE_FOLD_EVEN_ODD, 0x000f, 1 }, + { 0x00000149, FC_CASE_FOLD_FULL, 0x0003, 5 }, + { 0x0000014a, FC_CASE_FOLD_EVEN_ODD, 0x002d, 1 }, + { 0x00000178, FC_CASE_FOLD_RANGE, 0x0001, -121 }, + { 0x00000179, FC_CASE_FOLD_EVEN_ODD, 0x0005, 1 }, + { 0x0000017f, FC_CASE_FOLD_RANGE, 0x0001, -268 }, + { 0x00000181, FC_CASE_FOLD_RANGE, 0x0001, 210 }, + { 0x00000182, FC_CASE_FOLD_EVEN_ODD, 0x0003, 1 }, + { 0x00000186, FC_CASE_FOLD_RANGE, 0x0001, 206 }, + { 0x00000187, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x00000189, FC_CASE_FOLD_RANGE, 0x0002, 205 }, + { 0x0000018b, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x0000018e, FC_CASE_FOLD_RANGE, 0x0001, 79 }, + { 0x0000018f, FC_CASE_FOLD_RANGE, 0x0001, 202 }, + { 0x00000190, FC_CASE_FOLD_RANGE, 0x0001, 203 }, + { 0x00000191, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x00000193, FC_CASE_FOLD_RANGE, 0x0001, 205 }, + { 0x00000194, FC_CASE_FOLD_RANGE, 0x0001, 207 }, + { 0x00000196, FC_CASE_FOLD_RANGE, 0x0001, 211 }, + { 0x00000197, FC_CASE_FOLD_RANGE, 0x0001, 209 }, + { 0x00000198, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x0000019c, FC_CASE_FOLD_RANGE, 0x0001, 211 }, + { 0x0000019d, FC_CASE_FOLD_RANGE, 0x0001, 213 }, + { 0x0000019f, FC_CASE_FOLD_RANGE, 0x0001, 214 }, + { 0x000001a0, FC_CASE_FOLD_EVEN_ODD, 0x0005, 1 }, + { 0x000001a6, FC_CASE_FOLD_RANGE, 0x0001, 218 }, + { 0x000001a7, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x000001a9, FC_CASE_FOLD_RANGE, 0x0001, 218 }, + { 0x000001ac, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x000001ae, FC_CASE_FOLD_RANGE, 0x0001, 218 }, + { 0x000001af, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x000001b1, FC_CASE_FOLD_RANGE, 0x0002, 217 }, + { 0x000001b3, FC_CASE_FOLD_EVEN_ODD, 0x0003, 1 }, + { 0x000001b7, FC_CASE_FOLD_RANGE, 0x0001, 219 }, + { 0x000001b8, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x000001bc, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x000001c4, FC_CASE_FOLD_RANGE, 0x0001, 2 }, + { 0x000001c5, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x000001c7, FC_CASE_FOLD_RANGE, 0x0001, 2 }, + { 0x000001c8, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x000001ca, FC_CASE_FOLD_RANGE, 0x0001, 2 }, + { 0x000001cb, FC_CASE_FOLD_EVEN_ODD, 0x0011, 1 }, + { 0x000001de, FC_CASE_FOLD_EVEN_ODD, 0x0011, 1 }, + { 0x000001f0, FC_CASE_FOLD_FULL, 0x0003, 8 }, + { 0x000001f1, FC_CASE_FOLD_RANGE, 0x0001, 2 }, + { 0x000001f2, FC_CASE_FOLD_EVEN_ODD, 0x0003, 1 }, + { 0x000001f6, FC_CASE_FOLD_RANGE, 0x0001, -97 }, + { 0x000001f7, FC_CASE_FOLD_RANGE, 0x0001, -56 }, + { 0x000001f8, FC_CASE_FOLD_EVEN_ODD, 0x0027, 1 }, + { 0x00000220, FC_CASE_FOLD_RANGE, 0x0001, -130 }, + { 0x00000222, FC_CASE_FOLD_EVEN_ODD, 0x0011, 1 }, + { 0x0000023a, FC_CASE_FOLD_RANGE, 0x0001, 10795 }, + { 0x0000023b, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x0000023d, FC_CASE_FOLD_RANGE, 0x0001, -163 }, + { 0x0000023e, FC_CASE_FOLD_RANGE, 0x0001, 10792 }, + { 0x00000241, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x00000243, FC_CASE_FOLD_RANGE, 0x0001, -195 }, + { 0x00000244, FC_CASE_FOLD_RANGE, 0x0001, 69 }, + { 0x00000245, FC_CASE_FOLD_RANGE, 0x0001, 71 }, + { 0x00000246, FC_CASE_FOLD_EVEN_ODD, 0x0009, 1 }, + { 0x00000345, FC_CASE_FOLD_RANGE, 0x0001, 116 }, + { 0x00000370, FC_CASE_FOLD_EVEN_ODD, 0x0003, 1 }, + { 0x00000376, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x0000037f, FC_CASE_FOLD_RANGE, 0x0001, 116 }, + { 0x00000386, FC_CASE_FOLD_RANGE, 0x0001, 38 }, + { 0x00000388, FC_CASE_FOLD_RANGE, 0x0003, 37 }, + { 0x0000038c, FC_CASE_FOLD_RANGE, 0x0001, 64 }, + { 0x0000038e, FC_CASE_FOLD_RANGE, 0x0002, 63 }, + { 0x00000390, FC_CASE_FOLD_FULL, 0x0006, 11 }, + { 0x00000391, FC_CASE_FOLD_RANGE, 0x0011, 32 }, + { 0x000003a3, FC_CASE_FOLD_RANGE, 0x0009, 32 }, + { 0x000003b0, FC_CASE_FOLD_FULL, 0x0006, 17 }, + { 0x000003c2, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x000003cf, FC_CASE_FOLD_RANGE, 0x0001, 8 }, + { 0x000003d0, FC_CASE_FOLD_RANGE, 0x0001, -30 }, + { 0x000003d1, FC_CASE_FOLD_RANGE, 0x0001, -25 }, + { 0x000003d5, FC_CASE_FOLD_RANGE, 0x0001, -15 }, + { 0x000003d6, FC_CASE_FOLD_RANGE, 0x0001, -22 }, + { 0x000003d8, FC_CASE_FOLD_EVEN_ODD, 0x0017, 1 }, + { 0x000003f0, FC_CASE_FOLD_RANGE, 0x0001, -54 }, + { 0x000003f1, FC_CASE_FOLD_RANGE, 0x0001, -48 }, + { 0x000003f4, FC_CASE_FOLD_RANGE, 0x0001, -60 }, + { 0x000003f5, FC_CASE_FOLD_RANGE, 0x0001, -64 }, + { 0x000003f7, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x000003f9, FC_CASE_FOLD_RANGE, 0x0001, -7 }, + { 0x000003fa, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x000003fd, FC_CASE_FOLD_RANGE, 0x0003, -130 }, + { 0x00000400, FC_CASE_FOLD_RANGE, 0x0010, 80 }, + { 0x00000410, FC_CASE_FOLD_RANGE, 0x0020, 32 }, + { 0x00000460, FC_CASE_FOLD_EVEN_ODD, 0x0021, 1 }, + { 0x0000048a, FC_CASE_FOLD_EVEN_ODD, 0x0035, 1 }, + { 0x000004c0, FC_CASE_FOLD_RANGE, 0x0001, 15 }, + { 0x000004c1, FC_CASE_FOLD_EVEN_ODD, 0x000d, 1 }, + { 0x000004d0, FC_CASE_FOLD_EVEN_ODD, 0x005f, 1 }, + { 0x00000531, FC_CASE_FOLD_RANGE, 0x0026, 48 }, + { 0x00000587, FC_CASE_FOLD_FULL, 0x0004, 23 }, + { 0x000010a0, FC_CASE_FOLD_RANGE, 0x0026, 7264 }, + { 0x000010c7, FC_CASE_FOLD_RANGE, 0x0001, 7264 }, + { 0x000010cd, FC_CASE_FOLD_RANGE, 0x0001, 7264 }, + { 0x000013f8, FC_CASE_FOLD_RANGE, 0x0006, -8 }, + { 0x00001c80, FC_CASE_FOLD_RANGE, 0x0001, -6222 }, + { 0x00001c81, FC_CASE_FOLD_RANGE, 0x0001, -6221 }, + { 0x00001c82, FC_CASE_FOLD_RANGE, 0x0001, -6212 }, + { 0x00001c83, FC_CASE_FOLD_RANGE, 0x0002, -6210 }, + { 0x00001c85, FC_CASE_FOLD_RANGE, 0x0001, -6211 }, + { 0x00001c86, FC_CASE_FOLD_RANGE, 0x0001, -6204 }, + { 0x00001c87, FC_CASE_FOLD_RANGE, 0x0001, -6180 }, + { 0x00001c88, FC_CASE_FOLD_RANGE, 0x0001, -30269 }, + { 0x00001c89, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x00001c90, FC_CASE_FOLD_RANGE, 0x002b, -3008 }, + { 0x00001cbd, FC_CASE_FOLD_RANGE, 0x0003, -3008 }, + { 0x00001e00, FC_CASE_FOLD_EVEN_ODD, 0x0095, 1 }, + { 0x00001e96, FC_CASE_FOLD_FULL, 0x0003, 27 }, + { 0x00001e97, FC_CASE_FOLD_FULL, 0x0003, 30 }, + { 0x00001e98, FC_CASE_FOLD_FULL, 0x0003, 33 }, + { 0x00001e99, FC_CASE_FOLD_FULL, 0x0003, 36 }, + { 0x00001e9a, FC_CASE_FOLD_FULL, 0x0003, 39 }, + { 0x00001e9b, FC_CASE_FOLD_RANGE, 0x0001, -58 }, + { 0x00001e9e, FC_CASE_FOLD_FULL, 0x0002, 42 }, + { 0x00001ea0, FC_CASE_FOLD_EVEN_ODD, 0x005f, 1 }, + { 0x00001f08, FC_CASE_FOLD_RANGE, 0x0008, -8 }, + { 0x00001f18, FC_CASE_FOLD_RANGE, 0x0006, -8 }, + { 0x00001f28, FC_CASE_FOLD_RANGE, 0x0008, -8 }, + { 0x00001f38, FC_CASE_FOLD_RANGE, 0x0008, -8 }, + { 0x00001f48, FC_CASE_FOLD_RANGE, 0x0006, -8 }, + { 0x00001f50, FC_CASE_FOLD_FULL, 0x0004, 44 }, + { 0x00001f52, FC_CASE_FOLD_FULL, 0x0006, 48 }, + { 0x00001f54, FC_CASE_FOLD_FULL, 0x0006, 54 }, + { 0x00001f56, FC_CASE_FOLD_FULL, 0x0006, 60 }, + { 0x00001f59, FC_CASE_FOLD_RANGE, 0x0001, -8 }, + { 0x00001f5b, FC_CASE_FOLD_RANGE, 0x0001, -8 }, + { 0x00001f5d, FC_CASE_FOLD_RANGE, 0x0001, -8 }, + { 0x00001f5f, FC_CASE_FOLD_RANGE, 0x0001, -8 }, + { 0x00001f68, FC_CASE_FOLD_RANGE, 0x0008, -8 }, + { 0x00001f80, FC_CASE_FOLD_FULL, 0x0005, 66 }, + { 0x00001f81, FC_CASE_FOLD_FULL, 0x0005, 71 }, + { 0x00001f82, FC_CASE_FOLD_FULL, 0x0005, 76 }, + { 0x00001f83, FC_CASE_FOLD_FULL, 0x0005, 81 }, + { 0x00001f84, FC_CASE_FOLD_FULL, 0x0005, 86 }, + { 0x00001f85, FC_CASE_FOLD_FULL, 0x0005, 91 }, + { 0x00001f86, FC_CASE_FOLD_FULL, 0x0005, 96 }, + { 0x00001f87, FC_CASE_FOLD_FULL, 0x0005, 101 }, + { 0x00001f88, FC_CASE_FOLD_FULL, 0x0005, 106 }, + { 0x00001f89, FC_CASE_FOLD_FULL, 0x0005, 111 }, + { 0x00001f8a, FC_CASE_FOLD_FULL, 0x0005, 116 }, + { 0x00001f8b, FC_CASE_FOLD_FULL, 0x0005, 121 }, + { 0x00001f8c, FC_CASE_FOLD_FULL, 0x0005, 126 }, + { 0x00001f8d, FC_CASE_FOLD_FULL, 0x0005, 131 }, + { 0x00001f8e, FC_CASE_FOLD_FULL, 0x0005, 136 }, + { 0x00001f8f, FC_CASE_FOLD_FULL, 0x0005, 141 }, + { 0x00001f90, FC_CASE_FOLD_FULL, 0x0005, 146 }, + { 0x00001f91, FC_CASE_FOLD_FULL, 0x0005, 151 }, + { 0x00001f92, FC_CASE_FOLD_FULL, 0x0005, 156 }, + { 0x00001f93, FC_CASE_FOLD_FULL, 0x0005, 161 }, + { 0x00001f94, FC_CASE_FOLD_FULL, 0x0005, 166 }, + { 0x00001f95, FC_CASE_FOLD_FULL, 0x0005, 171 }, + { 0x00001f96, FC_CASE_FOLD_FULL, 0x0005, 176 }, + { 0x00001f97, FC_CASE_FOLD_FULL, 0x0005, 181 }, + { 0x00001f98, FC_CASE_FOLD_FULL, 0x0005, 186 }, + { 0x00001f99, FC_CASE_FOLD_FULL, 0x0005, 191 }, + { 0x00001f9a, FC_CASE_FOLD_FULL, 0x0005, 196 }, + { 0x00001f9b, FC_CASE_FOLD_FULL, 0x0005, 201 }, + { 0x00001f9c, FC_CASE_FOLD_FULL, 0x0005, 206 }, + { 0x00001f9d, FC_CASE_FOLD_FULL, 0x0005, 211 }, + { 0x00001f9e, FC_CASE_FOLD_FULL, 0x0005, 216 }, + { 0x00001f9f, FC_CASE_FOLD_FULL, 0x0005, 221 }, + { 0x00001fa0, FC_CASE_FOLD_FULL, 0x0005, 226 }, + { 0x00001fa1, FC_CASE_FOLD_FULL, 0x0005, 231 }, + { 0x00001fa2, FC_CASE_FOLD_FULL, 0x0005, 236 }, + { 0x00001fa3, FC_CASE_FOLD_FULL, 0x0005, 241 }, + { 0x00001fa4, FC_CASE_FOLD_FULL, 0x0005, 246 }, + { 0x00001fa5, FC_CASE_FOLD_FULL, 0x0005, 251 }, + { 0x00001fa6, FC_CASE_FOLD_FULL, 0x0005, 256 }, + { 0x00001fa7, FC_CASE_FOLD_FULL, 0x0005, 261 }, + { 0x00001fa8, FC_CASE_FOLD_FULL, 0x0005, 266 }, + { 0x00001fa9, FC_CASE_FOLD_FULL, 0x0005, 271 }, + { 0x00001faa, FC_CASE_FOLD_FULL, 0x0005, 276 }, + { 0x00001fab, FC_CASE_FOLD_FULL, 0x0005, 281 }, + { 0x00001fac, FC_CASE_FOLD_FULL, 0x0005, 286 }, + { 0x00001fad, FC_CASE_FOLD_FULL, 0x0005, 291 }, + { 0x00001fae, FC_CASE_FOLD_FULL, 0x0005, 296 }, + { 0x00001faf, FC_CASE_FOLD_FULL, 0x0005, 301 }, + { 0x00001fb2, FC_CASE_FOLD_FULL, 0x0005, 306 }, + { 0x00001fb3, FC_CASE_FOLD_FULL, 0x0004, 311 }, + { 0x00001fb4, FC_CASE_FOLD_FULL, 0x0004, 315 }, + { 0x00001fb6, FC_CASE_FOLD_FULL, 0x0004, 319 }, + { 0x00001fb7, FC_CASE_FOLD_FULL, 0x0006, 323 }, + { 0x00001fb8, FC_CASE_FOLD_RANGE, 0x0002, -8 }, + { 0x00001fba, FC_CASE_FOLD_RANGE, 0x0002, -74 }, + { 0x00001fbc, FC_CASE_FOLD_FULL, 0x0004, 329 }, + { 0x00001fbe, FC_CASE_FOLD_RANGE, 0x0001, -7173 }, + { 0x00001fc2, FC_CASE_FOLD_FULL, 0x0005, 333 }, + { 0x00001fc3, FC_CASE_FOLD_FULL, 0x0004, 338 }, + { 0x00001fc4, FC_CASE_FOLD_FULL, 0x0004, 342 }, + { 0x00001fc6, FC_CASE_FOLD_FULL, 0x0004, 346 }, + { 0x00001fc7, FC_CASE_FOLD_FULL, 0x0006, 350 }, + { 0x00001fc8, FC_CASE_FOLD_RANGE, 0x0004, -86 }, + { 0x00001fcc, FC_CASE_FOLD_FULL, 0x0004, 356 }, + { 0x00001fd2, FC_CASE_FOLD_FULL, 0x0006, 360 }, + { 0x00001fd3, FC_CASE_FOLD_FULL, 0x0006, 366 }, + { 0x00001fd6, FC_CASE_FOLD_FULL, 0x0004, 372 }, + { 0x00001fd7, FC_CASE_FOLD_FULL, 0x0006, 376 }, + { 0x00001fd8, FC_CASE_FOLD_RANGE, 0x0002, -8 }, + { 0x00001fda, FC_CASE_FOLD_RANGE, 0x0002, -100 }, + { 0x00001fe2, FC_CASE_FOLD_FULL, 0x0006, 382 }, + { 0x00001fe3, FC_CASE_FOLD_FULL, 0x0006, 388 }, + { 0x00001fe4, FC_CASE_FOLD_FULL, 0x0004, 394 }, + { 0x00001fe6, FC_CASE_FOLD_FULL, 0x0004, 398 }, + { 0x00001fe7, FC_CASE_FOLD_FULL, 0x0006, 402 }, + { 0x00001fe8, FC_CASE_FOLD_RANGE, 0x0002, -8 }, + { 0x00001fea, FC_CASE_FOLD_RANGE, 0x0002, -112 }, + { 0x00001fec, FC_CASE_FOLD_RANGE, 0x0001, -7 }, + { 0x00001ff2, FC_CASE_FOLD_FULL, 0x0005, 408 }, + { 0x00001ff3, FC_CASE_FOLD_FULL, 0x0004, 413 }, + { 0x00001ff4, FC_CASE_FOLD_FULL, 0x0004, 417 }, + { 0x00001ff6, FC_CASE_FOLD_FULL, 0x0004, 421 }, + { 0x00001ff7, FC_CASE_FOLD_FULL, 0x0006, 425 }, + { 0x00001ff8, FC_CASE_FOLD_RANGE, 0x0002, -128 }, + { 0x00001ffa, FC_CASE_FOLD_RANGE, 0x0002, -126 }, + { 0x00001ffc, FC_CASE_FOLD_FULL, 0x0004, 431 }, + { 0x00002126, FC_CASE_FOLD_RANGE, 0x0001, -7517 }, + { 0x0000212a, FC_CASE_FOLD_RANGE, 0x0001, -8383 }, + { 0x0000212b, FC_CASE_FOLD_RANGE, 0x0001, -8262 }, + { 0x00002132, FC_CASE_FOLD_RANGE, 0x0001, 28 }, + { 0x00002160, FC_CASE_FOLD_RANGE, 0x0010, 16 }, + { 0x00002183, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x000024b6, FC_CASE_FOLD_RANGE, 0x001a, 26 }, + { 0x00002c00, FC_CASE_FOLD_RANGE, 0x0030, 48 }, + { 0x00002c60, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x00002c62, FC_CASE_FOLD_RANGE, 0x0001, -10743 }, + { 0x00002c63, FC_CASE_FOLD_RANGE, 0x0001, -3814 }, + { 0x00002c64, FC_CASE_FOLD_RANGE, 0x0001, -10727 }, + { 0x00002c67, FC_CASE_FOLD_EVEN_ODD, 0x0005, 1 }, + { 0x00002c6d, FC_CASE_FOLD_RANGE, 0x0001, -10780 }, + { 0x00002c6e, FC_CASE_FOLD_RANGE, 0x0001, -10749 }, + { 0x00002c6f, FC_CASE_FOLD_RANGE, 0x0001, -10783 }, + { 0x00002c70, FC_CASE_FOLD_RANGE, 0x0001, -10782 }, + { 0x00002c72, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x00002c75, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x00002c7e, FC_CASE_FOLD_RANGE, 0x0002, -10815 }, + { 0x00002c80, FC_CASE_FOLD_EVEN_ODD, 0x0063, 1 }, + { 0x00002ceb, FC_CASE_FOLD_EVEN_ODD, 0x0003, 1 }, + { 0x00002cf2, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x0000a640, FC_CASE_FOLD_EVEN_ODD, 0x002d, 1 }, + { 0x0000a680, FC_CASE_FOLD_EVEN_ODD, 0x001b, 1 }, + { 0x0000a722, FC_CASE_FOLD_EVEN_ODD, 0x000d, 1 }, + { 0x0000a732, FC_CASE_FOLD_EVEN_ODD, 0x003d, 1 }, + { 0x0000a779, FC_CASE_FOLD_EVEN_ODD, 0x0003, 1 }, + { 0x0000a77d, FC_CASE_FOLD_RANGE, 0x0001, 30204 }, + { 0x0000a77e, FC_CASE_FOLD_EVEN_ODD, 0x0009, 1 }, + { 0x0000a78b, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x0000a78d, FC_CASE_FOLD_RANGE, 0x0001, 23256 }, + { 0x0000a790, FC_CASE_FOLD_EVEN_ODD, 0x0003, 1 }, + { 0x0000a796, FC_CASE_FOLD_EVEN_ODD, 0x0013, 1 }, + { 0x0000a7aa, FC_CASE_FOLD_RANGE, 0x0001, 23228 }, + { 0x0000a7ab, FC_CASE_FOLD_RANGE, 0x0001, 23217 }, + { 0x0000a7ac, FC_CASE_FOLD_RANGE, 0x0001, 23221 }, + { 0x0000a7ad, FC_CASE_FOLD_RANGE, 0x0001, 23231 }, + { 0x0000a7ae, FC_CASE_FOLD_RANGE, 0x0001, 23228 }, + { 0x0000a7b0, FC_CASE_FOLD_RANGE, 0x0001, 23278 }, + { 0x0000a7b1, FC_CASE_FOLD_RANGE, 0x0001, 23254 }, + { 0x0000a7b2, FC_CASE_FOLD_RANGE, 0x0001, 23275 }, + { 0x0000a7b3, FC_CASE_FOLD_RANGE, 0x0001, 928 }, + { 0x0000a7b4, FC_CASE_FOLD_EVEN_ODD, 0x000f, 1 }, + { 0x0000a7c4, FC_CASE_FOLD_RANGE, 0x0001, -48 }, + { 0x0000a7c5, FC_CASE_FOLD_RANGE, 0x0001, 23229 }, + { 0x0000a7c6, FC_CASE_FOLD_RANGE, 0x0001, 30152 }, + { 0x0000a7c7, FC_CASE_FOLD_EVEN_ODD, 0x0003, 1 }, + { 0x0000a7cb, FC_CASE_FOLD_RANGE, 0x0001, 23193 }, + { 0x0000a7cc, FC_CASE_FOLD_EVEN_ODD, 0x000f, 1 }, + { 0x0000a7dc, FC_CASE_FOLD_RANGE, 0x0001, 22975 }, + { 0x0000a7f5, FC_CASE_FOLD_EVEN_ODD, 0x0001, 1 }, + { 0x0000ab70, FC_CASE_FOLD_RANGE, 0x0050, 26672 }, + { 0x0000fb00, FC_CASE_FOLD_FULL, 0x0002, 435 }, + { 0x0000fb01, FC_CASE_FOLD_FULL, 0x0002, 437 }, + { 0x0000fb02, FC_CASE_FOLD_FULL, 0x0002, 439 }, + { 0x0000fb03, FC_CASE_FOLD_FULL, 0x0003, 441 }, + { 0x0000fb04, FC_CASE_FOLD_FULL, 0x0003, 444 }, + { 0x0000fb05, FC_CASE_FOLD_FULL, 0x0002, 447 }, + { 0x0000fb06, FC_CASE_FOLD_FULL, 0x0002, 449 }, + { 0x0000fb13, FC_CASE_FOLD_FULL, 0x0004, 451 }, + { 0x0000fb14, FC_CASE_FOLD_FULL, 0x0004, 455 }, + { 0x0000fb15, FC_CASE_FOLD_FULL, 0x0004, 459 }, + { 0x0000fb16, FC_CASE_FOLD_FULL, 0x0004, 463 }, + { 0x0000fb17, FC_CASE_FOLD_FULL, 0x0004, 467 }, + { 0x0000ff21, FC_CASE_FOLD_RANGE, 0x001a, 32 }, + { 0x00010400, FC_CASE_FOLD_RANGE, 0x0028, 40 }, + { 0x000104b0, FC_CASE_FOLD_RANGE, 0x0024, 40 }, + { 0x00010570, FC_CASE_FOLD_RANGE, 0x000b, 39 }, + { 0x0001057c, FC_CASE_FOLD_RANGE, 0x000f, 39 }, + { 0x0001058c, FC_CASE_FOLD_RANGE, 0x0007, 39 }, + { 0x00010594, FC_CASE_FOLD_RANGE, 0x0002, 39 }, + { 0x00010c80, FC_CASE_FOLD_RANGE, 0x0033, 64 }, + { 0x00010d50, FC_CASE_FOLD_RANGE, 0x0016, 32 }, + { 0x000118a0, FC_CASE_FOLD_RANGE, 0x0020, 32 }, + { 0x00016e40, FC_CASE_FOLD_RANGE, 0x0020, 32 }, + { 0x00016ea0, FC_CASE_FOLD_RANGE, 0x0019, 27 }, + { 0x0001e900, FC_CASE_FOLD_RANGE, 0x0022, 34 }, +}; + +static const FcChar8 fcCaseFoldChars[FC_NUM_CASE_FOLD_CHARS] = { +0x73,0x73,0x69,0xcc,0x87,0xca,0xbc,0x6e,0x6a,0xcc,0x8c,0xce,0xb9,0xcc,0x88,0xcc, +0x81,0xcf,0x85,0xcc,0x88,0xcc,0x81,0xd5,0xa5,0xd6,0x82,0x68,0xcc,0xb1,0x74,0xcc, +0x88,0x77,0xcc,0x8a,0x79,0xcc,0x8a,0x61,0xca,0xbe,0x73,0x73,0xcf,0x85,0xcc,0x93, +0xcf,0x85,0xcc,0x93,0xcc,0x80,0xcf,0x85,0xcc,0x93,0xcc,0x81,0xcf,0x85,0xcc,0x93, +0xcd,0x82,0xe1,0xbc,0x80,0xce,0xb9,0xe1,0xbc,0x81,0xce,0xb9,0xe1,0xbc,0x82,0xce, +0xb9,0xe1,0xbc,0x83,0xce,0xb9,0xe1,0xbc,0x84,0xce,0xb9,0xe1,0xbc,0x85,0xce,0xb9, +0xe1,0xbc,0x86,0xce,0xb9,0xe1,0xbc,0x87,0xce,0xb9,0xe1,0xbc,0x80,0xce,0xb9,0xe1, +0xbc,0x81,0xce,0xb9,0xe1,0xbc,0x82,0xce,0xb9,0xe1,0xbc,0x83,0xce,0xb9,0xe1,0xbc, +0x84,0xce,0xb9,0xe1,0xbc,0x85,0xce,0xb9,0xe1,0xbc,0x86,0xce,0xb9,0xe1,0xbc,0x87, +0xce,0xb9,0xe1,0xbc,0xa0,0xce,0xb9,0xe1,0xbc,0xa1,0xce,0xb9,0xe1,0xbc,0xa2,0xce, +0xb9,0xe1,0xbc,0xa3,0xce,0xb9,0xe1,0xbc,0xa4,0xce,0xb9,0xe1,0xbc,0xa5,0xce,0xb9, +0xe1,0xbc,0xa6,0xce,0xb9,0xe1,0xbc,0xa7,0xce,0xb9,0xe1,0xbc,0xa0,0xce,0xb9,0xe1, +0xbc,0xa1,0xce,0xb9,0xe1,0xbc,0xa2,0xce,0xb9,0xe1,0xbc,0xa3,0xce,0xb9,0xe1,0xbc, +0xa4,0xce,0xb9,0xe1,0xbc,0xa5,0xce,0xb9,0xe1,0xbc,0xa6,0xce,0xb9,0xe1,0xbc,0xa7, +0xce,0xb9,0xe1,0xbd,0xa0,0xce,0xb9,0xe1,0xbd,0xa1,0xce,0xb9,0xe1,0xbd,0xa2,0xce, +0xb9,0xe1,0xbd,0xa3,0xce,0xb9,0xe1,0xbd,0xa4,0xce,0xb9,0xe1,0xbd,0xa5,0xce,0xb9, +0xe1,0xbd,0xa6,0xce,0xb9,0xe1,0xbd,0xa7,0xce,0xb9,0xe1,0xbd,0xa0,0xce,0xb9,0xe1, +0xbd,0xa1,0xce,0xb9,0xe1,0xbd,0xa2,0xce,0xb9,0xe1,0xbd,0xa3,0xce,0xb9,0xe1,0xbd, +0xa4,0xce,0xb9,0xe1,0xbd,0xa5,0xce,0xb9,0xe1,0xbd,0xa6,0xce,0xb9,0xe1,0xbd,0xa7, +0xce,0xb9,0xe1,0xbd,0xb0,0xce,0xb9,0xce,0xb1,0xce,0xb9,0xce,0xac,0xce,0xb9,0xce, +0xb1,0xcd,0x82,0xce,0xb1,0xcd,0x82,0xce,0xb9,0xce,0xb1,0xce,0xb9,0xe1,0xbd,0xb4, +0xce,0xb9,0xce,0xb7,0xce,0xb9,0xce,0xae,0xce,0xb9,0xce,0xb7,0xcd,0x82,0xce,0xb7, +0xcd,0x82,0xce,0xb9,0xce,0xb7,0xce,0xb9,0xce,0xb9,0xcc,0x88,0xcc,0x80,0xce,0xb9, +0xcc,0x88,0xcc,0x81,0xce,0xb9,0xcd,0x82,0xce,0xb9,0xcc,0x88,0xcd,0x82,0xcf,0x85, +0xcc,0x88,0xcc,0x80,0xcf,0x85,0xcc,0x88,0xcc,0x81,0xcf,0x81,0xcc,0x93,0xcf,0x85, +0xcd,0x82,0xcf,0x85,0xcc,0x88,0xcd,0x82,0xe1,0xbd,0xbc,0xce,0xb9,0xcf,0x89,0xce, +0xb9,0xcf,0x8e,0xce,0xb9,0xcf,0x89,0xcd,0x82,0xcf,0x89,0xcd,0x82,0xce,0xb9,0xcf, +0x89,0xce,0xb9,0x66,0x66,0x66,0x69,0x66,0x6c,0x66,0x66,0x69,0x66,0x66,0x6c,0x73, +0x74,0x73,0x74,0xd5,0xb4,0xd5,0xb6,0xd5,0xb4,0xd5,0xa5,0xd5,0xb4,0xd5,0xab,0xd5, +0xbe,0xd5,0xb6,0xd5,0xb4,0xd5,0xad +}; diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/fc-const/fcconst.h b/vendor/libghostty-vt/pkg/fontconfig/override/fc-const/fcconst.h new file mode 100644 index 00000000..d0f9dce0 --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/fc-const/fcconst.h @@ -0,0 +1,700 @@ +/* Copyright (C) 2025 fontconfig Authors */ +/* SPDX-License-Identifier: HPND */ + +typedef struct _FcConstIndex { + FcObject object; + int idx_obj; + int idx_variant; +} FcConstIndex; + +typedef struct _FcConstSymbolMap { + const FcChar8 *name; + FcConstIndex values[3]; +} FcConstSymbolMap; + +static const FcConstSymbolMap _FcBaseConstantSymbols[] = { + { + (const FcChar8 *) "antialias", + { + { FC_ANTIALIAS_OBJECT, 15, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "autohint", + { + { FC_AUTOHINT_OBJECT, 19, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "bgr", + { + { FC_RGBA_OBJECT, 27, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "black", + { + { FC_WEIGHT_OBJECT, 8, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "bold", + { + { FC_WEIGHT_OBJECT, 8, 1 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "book", + { + { FC_WEIGHT_OBJECT, 8, 2 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "charcell", + { + { FC_SPACING_OBJECT, 13, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "condensed", + { + { FC_WIDTH_OBJECT, 9, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "cursive", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "decorative", + { + { FC_DECORATIVE_OBJECT, 40, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "demibold", + { + { FC_WEIGHT_OBJECT, 8, 3 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "demilight", + { + { FC_WEIGHT_OBJECT, 8, 4 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "dual", + { + { FC_SPACING_OBJECT, 13, 1 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "embeddedbitmap", + { + { FC_EMBEDDED_BITMAP_OBJECT, 39, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "embolden", + { + { FC_EMBOLDEN_OBJECT, 38, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "emoji", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 1 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "expanded", + { + { FC_WIDTH_OBJECT, 9, 1 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "extrablack", + { + { FC_WEIGHT_OBJECT, 8, 5 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "extrabold", + { + { FC_WEIGHT_OBJECT, 8, 6 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "extracondensed", + { + { FC_WIDTH_OBJECT, 9, 2 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "extraexpanded", + { + { FC_WIDTH_OBJECT, 9, 3 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "extralight", + { + { FC_WEIGHT_OBJECT, 8, 7 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "fangsong", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 2 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "fantasy", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 3 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "globaladvance", + { + { FC_GLOBAL_ADVANCE_OBJECT, 20, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "heavy", + { + { FC_WEIGHT_OBJECT, 8, 8 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "hintfull", + { + { FC_HINT_STYLE_OBJECT, 16, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "hinting", + { + { FC_HINTING_OBJECT, 17, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "hintmedium", + { + { FC_HINT_STYLE_OBJECT, 16, 1 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "hintnone", + { + { FC_HINT_STYLE_OBJECT, 16, 2 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "hintslight", + { + { FC_HINT_STYLE_OBJECT, 16, 3 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "italic", + { + { FC_SLANT_OBJECT, 7, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "lcddefault", + { + { FC_LCD_FILTER_OBJECT, 41, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "lcdlegacy", + { + { FC_LCD_FILTER_OBJECT, 41, 1 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "lcdlight", + { + { FC_LCD_FILTER_OBJECT, 41, 2 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "lcdnone", + { + { FC_LCD_FILTER_OBJECT, 41, 3 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "light", + { + { FC_WEIGHT_OBJECT, 8, 9 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "math", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 4 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "medium", + { + { FC_WEIGHT_OBJECT, 8, 10 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "minspace", + { + { FC_MINSPACE_OBJECT, 29, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "mono", + { + { FC_SPACING_OBJECT, 13, 2 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "monospace", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 5 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "none", + { + { FC_RGBA_OBJECT, 27, 1 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "normal", + { + { FC_WEIGHT_OBJECT, 8, 11 }, + { FC_WIDTH_OBJECT, 9, 4 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "oblique", + { + { FC_SLANT_OBJECT, 7, 1 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "outline", + { + { FC_OUTLINE_OBJECT, 24, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "proportional", + { + { FC_SPACING_OBJECT, 13, 3 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "regular", + { + { FC_WEIGHT_OBJECT, 8, 12 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "rgb", + { + { FC_RGBA_OBJECT, 27, 2 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "roman", + { + { FC_SLANT_OBJECT, 7, 2 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "sans-serif", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 6 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "scalable", + { + { FC_SCALABLE_OBJECT, 25, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "semibold", + { + { FC_WEIGHT_OBJECT, 8, 13 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "semicondensed", + { + { FC_WIDTH_OBJECT, 9, 5 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "semiexpanded", + { + { FC_WIDTH_OBJECT, 9, 6 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "semilight", + { + { FC_WEIGHT_OBJECT, 8, 14 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "serif", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 7 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "system-ui", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 8 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "thin", + { + { FC_WEIGHT_OBJECT, 8, 15 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "ui-monospace", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 9 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "ui-rounded", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 10 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "ui-sans-serif", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 11 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "ui-serif", + { + { FC_GENERIC_FAMILY_OBJECT, 56, 12 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "ultrablack", + { + { FC_WEIGHT_OBJECT, 8, 16 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "ultrabold", + { + { FC_WEIGHT_OBJECT, 8, 17 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "ultracondensed", + { + { FC_WIDTH_OBJECT, 9, 7 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "ultraexpanded", + { + { FC_WIDTH_OBJECT, 9, 8 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "ultralight", + { + { FC_WEIGHT_OBJECT, 8, 18 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "unknown", + { + { FC_RGBA_OBJECT, 27, 3 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "vbgr", + { + { FC_RGBA_OBJECT, 27, 4 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "verticallayout", + { + { FC_VERTICAL_LAYOUT_OBJECT, 18, 0 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, + { + (const FcChar8 *) "vrgb", + { + { FC_RGBA_OBJECT, 27, 5 }, + { FC_INVALID_OBJECT, 0, 0 }, + }, + }, +}; + +#define NUM_FC_CONST_SYMBOLS (sizeof (_FcBaseConstantSymbols) / sizeof (_FcBaseConstantSymbols[0])) + +typedef struct _fcConstObjects { + FcConstant values[20]; +} FcConstantObjects; + +static const FcConstantObjects _FcBaseConstantObjects[FC_MAX_BASE_OBJECT+1] = { + {{{ NULL, NULL, 0 }}} /* FC_INVALID_OBJECT */, + {{{ NULL, NULL, 0 }}} /* FC_FAMILY */, + {{{ NULL, NULL, 0 }}} /* FC_FAMILYLANG */, + {{{ NULL, NULL, 0 }}} /* FC_STYLE */, + {{{ NULL, NULL, 0 }}} /* FC_STYLELANG */, + {{{ NULL, NULL, 0 }}} /* FC_FULLNAME */, + {{{ NULL, NULL, 0 }}} /* FC_FULLNAMELANG */, + {{ + { (const FcChar8 *) "italic", FC_SLANT, FC_SLANT_ITALIC}, + { (const FcChar8 *) "oblique", FC_SLANT, FC_SLANT_OBLIQUE}, + { (const FcChar8 *) "roman", FC_SLANT, FC_SLANT_ROMAN}, + { NULL, NULL, 0 }, + }}, + {{ + { (const FcChar8 *) "black", FC_WEIGHT, FC_WEIGHT_BLACK}, + { (const FcChar8 *) "bold", FC_WEIGHT, FC_WEIGHT_BOLD}, + { (const FcChar8 *) "book", FC_WEIGHT, FC_WEIGHT_BOOK}, + { (const FcChar8 *) "demibold", FC_WEIGHT, FC_WEIGHT_DEMIBOLD}, + { (const FcChar8 *) "demilight", FC_WEIGHT, FC_WEIGHT_DEMILIGHT}, + { (const FcChar8 *) "extrablack", FC_WEIGHT, FC_WEIGHT_EXTRABLACK}, + { (const FcChar8 *) "extrabold", FC_WEIGHT, FC_WEIGHT_EXTRABOLD}, + { (const FcChar8 *) "extralight", FC_WEIGHT, FC_WEIGHT_EXTRALIGHT}, + { (const FcChar8 *) "heavy", FC_WEIGHT, FC_WEIGHT_HEAVY}, + { (const FcChar8 *) "light", FC_WEIGHT, FC_WEIGHT_LIGHT}, + { (const FcChar8 *) "medium", FC_WEIGHT, FC_WEIGHT_MEDIUM}, + { (const FcChar8 *) "normal", FC_WEIGHT, FC_WEIGHT_NORMAL}, + { (const FcChar8 *) "regular", FC_WEIGHT, FC_WEIGHT_REGULAR}, + { (const FcChar8 *) "semibold", FC_WEIGHT, FC_WEIGHT_DEMIBOLD}, + { (const FcChar8 *) "semilight", FC_WEIGHT, FC_WEIGHT_DEMILIGHT}, + { (const FcChar8 *) "thin", FC_WEIGHT, FC_WEIGHT_THIN}, + { (const FcChar8 *) "ultrablack", FC_WEIGHT, FC_WEIGHT_ULTRABLACK}, + { (const FcChar8 *) "ultrabold", FC_WEIGHT, FC_WEIGHT_EXTRABOLD}, + { (const FcChar8 *) "ultralight", FC_WEIGHT, FC_WEIGHT_EXTRALIGHT}, + { NULL, NULL, 0 }, + }}, + {{ + { (const FcChar8 *) "condensed", FC_WIDTH, FC_WIDTH_CONDENSED}, + { (const FcChar8 *) "expanded", FC_WIDTH, FC_WIDTH_EXPANDED}, + { (const FcChar8 *) "extracondensed", FC_WIDTH, FC_WIDTH_EXTRACONDENSED}, + { (const FcChar8 *) "extraexpanded", FC_WIDTH, FC_WIDTH_EXTRAEXPANDED}, + { (const FcChar8 *) "normal", FC_WIDTH, FC_WIDTH_NORMAL}, + { (const FcChar8 *) "semicondensed", FC_WIDTH, FC_WIDTH_SEMICONDENSED}, + { (const FcChar8 *) "semiexpanded", FC_WIDTH, FC_WIDTH_SEMIEXPANDED}, + { (const FcChar8 *) "ultracondensed", FC_WIDTH, FC_WIDTH_ULTRACONDENSED}, + { (const FcChar8 *) "ultraexpanded", FC_WIDTH, FC_WIDTH_ULTRAEXPANDED}, + { NULL, NULL, 0 }, + }}, + {{{ NULL, NULL, 0 }}} /* FC_SIZE */, + {{{ NULL, NULL, 0 }}} /* FC_ASPECT */, + {{{ NULL, NULL, 0 }}} /* FC_PIXEL_SIZE */, + {{ + { (const FcChar8 *) "charcell", FC_SPACING, FC_SPACING_CHARCELL}, + { (const FcChar8 *) "dual", FC_SPACING, FC_SPACING_DUAL}, + { (const FcChar8 *) "mono", FC_SPACING, FC_SPACING_MONO}, + { (const FcChar8 *) "proportional", FC_SPACING, FC_SPACING_PROPORTIONAL}, + { NULL, NULL, 0 }, + }}, + {{{ NULL, NULL, 0 }}} /* FC_FOUNDRY */, + {{ + { (const FcChar8 *) "antialias", FC_ANTIALIAS, FcTrue}, + { NULL, NULL, 0 }, + }}, + {{ + { (const FcChar8 *) "hintfull", FC_HINT_STYLE, FC_HINT_FULL}, + { (const FcChar8 *) "hintmedium", FC_HINT_STYLE, FC_HINT_MEDIUM}, + { (const FcChar8 *) "hintnone", FC_HINT_STYLE, FC_HINT_NONE}, + { (const FcChar8 *) "hintslight", FC_HINT_STYLE, FC_HINT_SLIGHT}, + { NULL, NULL, 0 }, + }}, + {{ + { (const FcChar8 *) "hinting", FC_HINTING, FcTrue}, + { NULL, NULL, 0 }, + }}, + {{ + { (const FcChar8 *) "verticallayout", FC_VERTICAL_LAYOUT, FcTrue}, + { NULL, NULL, 0 }, + }}, + {{ + { (const FcChar8 *) "autohint", FC_AUTOHINT, FcTrue}, + { NULL, NULL, 0 }, + }}, + {{ + { (const FcChar8 *) "globaladvance", FC_GLOBAL_ADVANCE, FcTrue}, + { NULL, NULL, 0 }, + }}, + {{{ NULL, NULL, 0 }}} /* FC_FILE */, + {{{ NULL, NULL, 0 }}} /* FC_INDEX */, + {{{ NULL, NULL, 0 }}} /* FC_RASTERIZER */, + {{ + { (const FcChar8 *) "outline", FC_OUTLINE, FcTrue}, + { NULL, NULL, 0 }, + }}, + {{ + { (const FcChar8 *) "scalable", FC_SCALABLE, FcTrue}, + { NULL, NULL, 0 }, + }}, + {{{ NULL, NULL, 0 }}} /* FC_DPI */, + {{ + { (const FcChar8 *) "bgr", FC_RGBA, FC_RGBA_BGR}, + { (const FcChar8 *) "none", FC_RGBA, FC_RGBA_NONE}, + { (const FcChar8 *) "rgb", FC_RGBA, FC_RGBA_RGB}, + { (const FcChar8 *) "unknown", FC_RGBA, FC_RGBA_UNKNOWN}, + { (const FcChar8 *) "vbgr", FC_RGBA, FC_RGBA_VBGR}, + { (const FcChar8 *) "vrgb", FC_RGBA, FC_RGBA_VRGB}, + { NULL, NULL, 0 }, + }}, + {{{ NULL, NULL, 0 }}} /* FC_SCALE */, + {{ + { (const FcChar8 *) "minspace", FC_MINSPACE, FcTrue}, + { NULL, NULL, 0 }, + }}, + {{{ NULL, NULL, 0 }}} /* FC_CHARWIDTH */, + {{{ NULL, NULL, 0 }}} /* FC_CHAR_HEIGHT */, + {{{ NULL, NULL, 0 }}} /* FC_MATRIX */, + {{{ NULL, NULL, 0 }}} /* FC_CHARSET */, + {{{ NULL, NULL, 0 }}} /* FC_LANG */, + {{{ NULL, NULL, 0 }}} /* FC_FONTVERSION */, + {{{ NULL, NULL, 0 }}} /* FC_CAPABILITY */, + {{{ NULL, NULL, 0 }}} /* FC_FONTFORMAT */, + {{ + { (const FcChar8 *) "embolden", FC_EMBOLDEN, FcTrue}, + { NULL, NULL, 0 }, + }}, + {{ + { (const FcChar8 *) "embeddedbitmap", FC_EMBEDDED_BITMAP, FcTrue}, + { NULL, NULL, 0 }, + }}, + {{ + { (const FcChar8 *) "decorative", FC_DECORATIVE, FcTrue}, + { NULL, NULL, 0 }, + }}, + {{ + { (const FcChar8 *) "lcddefault", FC_LCD_FILTER, FC_LCD_DEFAULT}, + { (const FcChar8 *) "lcdlegacy", FC_LCD_FILTER, FC_LCD_LEGACY}, + { (const FcChar8 *) "lcdlight", FC_LCD_FILTER, FC_LCD_LIGHT}, + { (const FcChar8 *) "lcdnone", FC_LCD_FILTER, FC_LCD_NONE}, + { NULL, NULL, 0 }, + }}, + {{{ NULL, NULL, 0 }}} /* FC_NAMELANG */, + {{{ NULL, NULL, 0 }}} /* FC_FONT_FEATURES */, + {{{ NULL, NULL, 0 }}} /* FC_PRGNAME */, + {{{ NULL, NULL, 0 }}} /* FC_HASH */, + {{{ NULL, NULL, 0 }}} /* FC_POSTSCRIPT_NAME */, + {{{ NULL, NULL, 0 }}} /* FC_COLOR */, + {{{ NULL, NULL, 0 }}} /* FC_SYMBOL */, + {{{ NULL, NULL, 0 }}} /* FC_FONT_VARIATIONS */, + {{{ NULL, NULL, 0 }}} /* FC_VARIABLE */, + {{{ NULL, NULL, 0 }}} /* FC_FONT_HAS_HINT */, + {{{ NULL, NULL, 0 }}} /* FC_ORDER */, + {{{ NULL, NULL, 0 }}} /* FC_DESKTOP_NAME */, + {{{ NULL, NULL, 0 }}} /* FC_NAMED_INSTANCE */, + {{{ NULL, NULL, 0 }}} /* FC_FONT_WRAPPER */, + {{ + { (const FcChar8 *) "cursive", FC_GENERIC_FAMILY, FC_FAMILY_CURSIVE}, + { (const FcChar8 *) "emoji", FC_GENERIC_FAMILY, FC_FAMILY_EMOJI}, + { (const FcChar8 *) "fangsong", FC_GENERIC_FAMILY, FC_FAMILY_FANGSONG}, + { (const FcChar8 *) "fantasy", FC_GENERIC_FAMILY, FC_FAMILY_FANTASY}, + { (const FcChar8 *) "math", FC_GENERIC_FAMILY, FC_FAMILY_MATH}, + { (const FcChar8 *) "monospace", FC_GENERIC_FAMILY, FC_FAMILY_MONO}, + { (const FcChar8 *) "sans-serif", FC_GENERIC_FAMILY, FC_FAMILY_SANS}, + { (const FcChar8 *) "serif", FC_GENERIC_FAMILY, FC_FAMILY_SERIF}, + { (const FcChar8 *) "system-ui", FC_GENERIC_FAMILY, FC_FAMILY_SYSTEM_UI}, + { (const FcChar8 *) "ui-monospace", FC_GENERIC_FAMILY, FC_FAMILY_UI_MONO}, + { (const FcChar8 *) "ui-rounded", FC_GENERIC_FAMILY, FC_FAMILY_UI_ROUNDED}, + { (const FcChar8 *) "ui-sans-serif", FC_GENERIC_FAMILY, FC_FAMILY_UI_SANS}, + { (const FcChar8 *) "ui-serif", FC_GENERIC_FAMILY, FC_FAMILY_UI_SERIF}, + { NULL, NULL, 0 }, + }}, +}; + +#define NUM_FC_CONST_OBJS (sizeof (_FcBaseConstantObjects) / sizeof (_FcBaseConstantObjects[0])) diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/fc-genericfamily/fcgenericfamily.h b/vendor/libghostty-vt/pkg/fontconfig/override/fc-genericfamily/fcgenericfamily.h new file mode 100644 index 00000000..ed25cd45 --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/fc-genericfamily/fcgenericfamily.h @@ -0,0 +1,6963 @@ +/* ANSI-C code produced by gperf version 3.3 */ +/* Command-line: gperf --pic -m 100 fcgenericfamily.gperf */ +/* Computed positions: -k'1,3-5,8,10-18,20,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 5 "fcgenericfamily.gperf" + +#include +#include + +struct FcGenericFamilyEntry { + int name; + uint32_t classification; /* Bit field of FC_FAMILY_* values */ +}; +#line 26 "fcgenericfamily.gperf" +struct FcGenericFamilyEntry; +#include + +#define TOTAL_KEYWORDS 1219 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 34 +#define MIN_HASH_VALUE 93 +#define MAX_HASH_VALUE 12005 +/* maximum key range = 11913, duplicates = 0 */ + +#ifndef GPERF_DOWNCASE +#define GPERF_DOWNCASE 1 +static const unsigned char gperf_downcase[256] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 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, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 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, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255 + }; +#endif + +#ifndef GPERF_CASE_STRCMP +#define GPERF_CASE_STRCMP 1 +static int +gperf_case_strcmp (register const char *s1, register const char *s2) +{ + for (;;) + { + unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; + unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; + if (c1 != 0 && c1 == c2) + continue; + return (int)c1 - (int)c2; + } +} +#endif + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +fc_generic_family_hash (register const char *str, register size_t len) +{ + static const unsigned short asso_values[] = + { + 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, + 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, + 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, + 12006, 12006, 25, 12006, 12006, 12006, 12006, 12006, 12006, 12006, + 18, 18, 12006, 12006, 12006, 18, 12006, 18, 30, 19, + 32, 19, 23, 25, 12006, 22, 20, 19, 12006, 12006, + 12006, 12006, 12006, 12006, 12006, 20, 2827, 129, 264, 43, + 1384, 353, 788, 18, 1347, 733, 249, 26, 18, 23, + 2269, 22, 20, 31, 53, 776, 3005, 2024, 2042, 1815, + 200, 12006, 12006, 12006, 12006, 18, 12006, 20, 2827, 129, + 264, 43, 1384, 353, 788, 18, 1347, 733, 249, 26, + 18, 23, 2269, 22, 20, 31, 53, 776, 3005, 2024, + 2042, 1815, 200, 12006, 12006, 12006, 12006, 12006, 12006, 12006, + 18, 18, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, + 12006, 19, 19, 12006, 12006, 12006, 12006, 12006, 12006, 12006, + 12006, 12006, 12006, 12006, 12006, 12006, 19, 19, 12006, 12006, + 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 18, 12006, + 12006, 12006, 12006, 12006, 12006, 18, 12006, 12006, 12006, 12006, + 18, 12006, 12006, 18, 12006, 12006, 12006, 12006, 12006, 18, + 12006, 12006, 12006, 12006, 12006, 19, 12006, 12006, 12006, 12006, + 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, + 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, + 12006, 12006, 12006, 12006, 12006, 12006, 12006, 18, 12006, 12006, + 18, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 18, + 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, 12006, + 12006, 12006, 12006, 12006, 12006, 12006 + }; + register unsigned int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[19]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 19: + case 18: + hval += asso_values[(unsigned char)str[17]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 17: + hval += asso_values[(unsigned char)str[16]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 16: + hval += asso_values[(unsigned char)str[15]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 15: + hval += asso_values[(unsigned char)str[14]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 14: + hval += asso_values[(unsigned char)str[13]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 13: + hval += asso_values[(unsigned char)str[12]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 12: + hval += asso_values[(unsigned char)str[11]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 11: + hval += asso_values[(unsigned char)str[10]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 9: + case 8: + hval += asso_values[(unsigned char)str[7]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 7: + case 6: + case 5: + hval += asso_values[(unsigned char)str[4]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +struct FcConstFamilyNamePool_t + { + char FcConstFamilyNamePool_str93[sizeof("sina")]; + char FcConstFamilyNamePool_str95[sizeof("sora")]; + char FcConstFamilyNamePool_str99[sizeof("amiri")]; + char FcConstFamilyNamePool_str105[sizeof("raanana")]; + char FcConstFamilyNamePool_str107[sizeof("asea")]; + char FcConstFamilyNamePool_str108[sizeof("aroania")]; + char FcConstFamilyNamePool_str113[sizeof("norasi")]; + char FcConstFamilyNamePool_str115[sizeof("arimo")]; + char FcConstFamilyNamePool_str118[sizeof("nsimsun")]; + char FcConstFamilyNamePool_str120[sizeof("m+ 1mn")]; + char FcConstFamilyNamePool_str124[sizeof("nasim")]; + char FcConstFamilyNamePool_str125[sizeof("avenir")]; + char FcConstFamilyNamePool_str127[sizeof("m+ 1m")]; + char FcConstFamilyNamePool_str129[sizeof("mononoki")]; + char FcConstFamilyNamePool_str134[sizeof("meera")]; + char FcConstFamilyNamePool_str135[sizeof("sf mono")]; + char FcConstFamilyNamePool_str136[sizeof("nunito")]; + char FcConstFamilyNamePool_str137[sizeof("manrope")]; + char FcConstFamilyNamePool_str140[sizeof("m+ 2m")]; + char FcConstFamilyNamePool_str144[sizeof("mitra")]; + char FcConstFamilyNamePool_str146[sizeof("optima")]; + char FcConstFamilyNamePool_str150[sizeof("titr")]; + char FcConstFamilyNamePool_str154[sizeof("anorexia")]; + char FcConstFamilyNamePool_str155[sizeof("nirmala ui")]; + char FcConstFamilyNamePool_str156[sizeof("ibm 3270")]; + char FcConstFamilyNamePool_str159[sizeof("inter")]; + char FcConstFamilyNamePool_str160[sizeof("exo 2")]; + char FcConstFamilyNamePool_str161[sizeof("tinos")]; + char FcConstFamilyNamePool_str165[sizeof("shimenkan")]; + char FcConstFamilyNamePool_str167[sizeof("open sans")]; + char FcConstFamilyNamePool_str172[sizeof("mint mono")]; + char FcConstFamilyNamePool_str177[sizeof("noto sans")]; + char FcConstFamilyNamePool_str185[sizeof("miriam mono")]; + char FcConstFamilyNamePool_str187[sizeof("terminus")]; + char FcConstFamilyNamePool_str188[sizeof("noto emoji")]; + char FcConstFamilyNamePool_str189[sizeof("times")]; + char FcConstFamilyNamePool_str194[sizeof("smoothansi")]; + char FcConstFamilyNamePool_str196[sizeof("c059")]; + char FcConstFamilyNamePool_str198[sizeof("\357\275\215\357\275\223 \346\230\216\346\234\235")]; + char FcConstFamilyNamePool_str208[sizeof("mrs eaves")]; + char FcConstFamilyNamePool_str215[sizeof("museo sans")]; + char FcConstFamilyNamePool_str218[sizeof("cairo")]; + char FcConstFamilyNamePool_str222[sizeof("monaco")]; + char FcConstFamilyNamePool_str229[sizeof("nunito sans")]; + char FcConstFamilyNamePool_str230[sizeof("musica")]; + char FcConstFamilyNamePool_str233[sizeof("clean")]; + char FcConstFamilyNamePool_str239[sizeof("cure")]; + char FcConstFamilyNamePool_str243[sizeof("zar")]; + char FcConstFamilyNamePool_str246[sizeof("mint mono 35")]; + char FcConstFamilyNamePool_str249[sizeof("charter")]; + char FcConstFamilyNamePool_str251[sizeof("console")]; + char FcConstFamilyNamePool_str252[sizeof("operator mono")]; + char FcConstFamilyNamePool_str262[sizeof("clarendon")]; + char FcConstFamilyNamePool_str264[sizeof("montserrat")]; + char FcConstFamilyNamePool_str267[sizeof("noto sans mro")]; + char FcConstFamilyNamePool_str271[sizeof("consolas")]; + char FcConstFamilyNamePool_str272[sizeof("z003")]; + char FcConstFamilyNamePool_str273[sizeof("spacemono")]; + char FcConstFamilyNamePool_str274[sizeof("aharoniclm")]; + char FcConstFamilyNamePool_str275[sizeof("miriam clm")]; + char FcConstFamilyNamePool_str278[sizeof("cormorant")]; + char FcConstFamilyNamePool_str286[sizeof("noto sans miao")]; + char FcConstFamilyNamePool_str289[sizeof("noto sans mono")]; + char FcConstFamilyNamePool_str290[sizeof("\357\275\215\357\275\223 \343\202\264\343\202\267\343\203\203\343\202\257")]; + char FcConstFamilyNamePool_str297[sizeof("tiza")]; + char FcConstFamilyNamePool_str302[sizeof("space mono")]; + char FcConstFamilyNamePool_str304[sizeof("clear sans")]; + char FcConstFamilyNamePool_str306[sizeof("crimson pro")]; + char FcConstFamilyNamePool_str308[sizeof("eczar")]; + char FcConstFamilyNamePool_str313[sizeof("lora")]; + char FcConstFamilyNamePool_str315[sizeof("muli")]; + char FcConstFamilyNamePool_str319[sizeof("loma")]; + char FcConstFamilyNamePool_str330[sizeof("commissioner")]; + char FcConstFamilyNamePool_str331[sizeof("dror")]; + char FcConstFamilyNamePool_str334[sizeof("constantia")]; + char FcConstFamilyNamePool_str344[sizeof("menlo")]; + char FcConstFamilyNamePool_str348[sizeof("avdira")]; + char FcConstFamilyNamePool_str351[sizeof("madan")]; + char FcConstFamilyNamePool_str352[sizeof("lato")]; + char FcConstFamilyNamePool_str355[sizeof("monoid")]; + char FcConstFamilyNamePool_str357[sizeof("meslo")]; + char FcConstFamilyNamePool_str361[sizeof("times new roman")]; + char FcConstFamilyNamePool_str364[sizeof("monolisa")]; + char FcConstFamilyNamePool_str365[sizeof("lime")]; + char FcConstFamilyNamePool_str366[sizeof("madan2")]; + char FcConstFamilyNamePool_str369[sizeof("sharetechmono")]; + char FcConstFamilyNamePool_str377[sizeof("mnmlicons")]; + char FcConstFamilyNamePool_str378[sizeof("dm sans")]; + char FcConstFamilyNamePool_str380[sizeof("analecta")]; + char FcConstFamilyNamePool_str381[sizeof("noto sans armenian")]; + char FcConstFamilyNamePool_str382[sizeof("zysong18030")]; + char FcConstFamilyNamePool_str385[sizeof("lotoos")]; + char FcConstFamilyNamePool_str386[sizeof("smonohand")]; + char FcConstFamilyNamePool_str391[sizeof("itc stone sans")]; + char FcConstFamilyNamePool_str406[sizeof("notcouriersans")]; + char FcConstFamilyNamePool_str407[sizeof("noto sans samaritan")]; + char FcConstFamilyNamePool_str409[sizeof("molot")]; + char FcConstFamilyNamePool_str413[sizeof("literata")]; + char FcConstFamilyNamePool_str414[sizeof("noto sans masaram gondi")]; + char FcConstFamilyNamePool_str415[sizeof("thorndale")]; + char FcConstFamilyNamePool_str418[sizeof("noto music")]; + char FcConstFamilyNamePool_str420[sizeof("dustismo")]; + char FcConstFamilyNamePool_str421[sizeof("noto sans carian")]; + char FcConstFamilyNamePool_str427[sizeof("epilogue")]; + char FcConstFamilyNamePool_str439[sizeof("din next")]; + char FcConstFamilyNamePool_str441[sizeof("comic neue")]; + char FcConstFamilyNamePool_str446[sizeof("carlito")]; + char FcConstFamilyNamePool_str450[sizeof("irannastaliq")]; + char FcConstFamilyNamePool_str455[sizeof("cascadia mono")]; + char FcConstFamilyNamePool_str456[sizeof("caslon")]; + char FcConstFamilyNamePool_str457[sizeof("go mono")]; + char FcConstFamilyNamePool_str458[sizeof("candara")]; + char FcConstFamilyNamePool_str460[sizeof("aegean")]; + char FcConstFamilyNamePool_str462[sizeof("stsong")]; + char FcConstFamilyNamePool_str464[sizeof("cardo")]; + char FcConstFamilyNamePool_str469[sizeof("tunga")]; + char FcConstFamilyNamePool_str471[sizeof("simsong")]; + char FcConstFamilyNamePool_str479[sizeof("comic sans ms")]; + char FcConstFamilyNamePool_str480[sizeof("gfs olga")]; + char FcConstFamilyNamePool_str484[sizeof("alegreya")]; + char FcConstFamilyNamePool_str490[sizeof("noto sans lao")]; + char FcConstFamilyNamePool_str494[sizeof("segoe ui")]; + char FcConstFamilyNamePool_str499[sizeof("comicshannsmono")]; + char FcConstFamilyNamePool_str502[sizeof("awami nastaliq")]; + char FcConstFamilyNamePool_str506[sizeof("edges")]; + char FcConstFamilyNamePool_str508[sizeof("nazli")]; + char FcConstFamilyNamePool_str513[sizeof("geist")]; + char FcConstFamilyNamePool_str514[sizeof("code2001")]; + char FcConstFamilyNamePool_str519[sizeof("elliniaclm")]; + char FcConstFamilyNamePool_str522[sizeof("gfs ignacio")]; + char FcConstFamilyNamePool_str525[sizeof("noto sans modi")]; + char FcConstFamilyNamePool_str533[sizeof("intel one mono")]; + char FcConstFamilyNamePool_str534[sizeof("geist mono")]; + char FcConstFamilyNamePool_str536[sizeof("code2000")]; + char FcConstFamilyNamePool_str541[sizeof("inconsolata")]; + char FcConstFamilyNamePool_str550[sizeof("gfs ambrosia")]; + char FcConstFamilyNamePool_str553[sizeof("thorndale amt")]; + char FcConstFamilyNamePool_str555[sizeof("laconic")]; + char FcConstFamilyNamePool_str559[sizeof("gfs solomos")]; + char FcConstFamilyNamePool_str561[sizeof("arial")]; + char FcConstFamilyNamePool_str568[sizeof("codenewroman")]; + char FcConstFamilyNamePool_str570[sizeof("ipagothic")]; + char FcConstFamilyNamePool_str583[sizeof("ms gothic")]; + char FcConstFamilyNamePool_str587[sizeof("d-din")]; + char FcConstFamilyNamePool_str592[sizeof("gfs artemisia")]; + char FcConstFamilyNamePool_str600[sizeof("alegreya sans")]; + char FcConstFamilyNamePool_str603[sizeof("great vibes")]; + char FcConstFamilyNamePool_str606[sizeof("openmoji color")]; + char FcConstFamilyNamePool_str610[sizeof("latin modern roman")]; + char FcConstFamilyNamePool_str611[sizeof("gfs nicefore")]; + char FcConstFamilyNamePool_str613[sizeof("noto sans linear a")]; + char FcConstFamilyNamePool_str614[sizeof("ezra sil")]; + char FcConstFamilyNamePool_str621[sizeof("miriam mono clm")]; + char FcConstFamilyNamePool_str623[sizeof("terminal")]; + char FcConstFamilyNamePool_str624[sizeof("songti sc")]; + char FcConstFamilyNamePool_str629[sizeof("noto sans tai le")]; + char FcConstFamilyNamePool_str639[sizeof("noto sans meroitic")]; + char FcConstFamilyNamePool_str646[sizeof("songti tc")]; + char FcConstFamilyNamePool_str654[sizeof("andale mono")]; + char FcConstFamilyNamePool_str655[sizeof("material icons")]; + char FcConstFamilyNamePool_str657[sizeof("mingzat")]; + char FcConstFamilyNamePool_str661[sizeof("droid sans")]; + char FcConstFamilyNamePool_str662[sizeof("didot")]; + char FcConstFamilyNamePool_str668[sizeof("geeza pro")]; + char FcConstFamilyNamePool_str672[sizeof("mangal")]; + char FcConstFamilyNamePool_str675[sizeof("gfs theokritos")]; + char FcConstFamilyNamePool_str677[sizeof("gulim")]; + char FcConstFamilyNamePool_str684[sizeof("mints mild")]; + char FcConstFamilyNamePool_str689[sizeof("caladea")]; + char FcConstFamilyNamePool_str690[sizeof("noto sans osage")]; + char FcConstFamilyNamePool_str693[sizeof("noto sans tangsa")]; + char FcConstFamilyNamePool_str711[sizeof("sniglet")]; + char FcConstFamilyNamePool_str716[sizeof("domestic manners")]; + char FcConstFamilyNamePool_str726[sizeof("charis sil")]; + char FcConstFamilyNamePool_str727[sizeof("cantarell")]; + char FcConstFamilyNamePool_str729[sizeof("noto sans deseret")]; + char FcConstFamilyNamePool_str731[sizeof("gfs eustace")]; + char FcConstFamilyNamePool_str744[sizeof("montserrat alternates")]; + char FcConstFamilyNamePool_str757[sizeof("latin modern roman caps")]; + char FcConstFamilyNamePool_str758[sizeof("gfs didot")]; + char FcConstFamilyNamePool_str762[sizeof("spectral")]; + char FcConstFamilyNamePool_str763[sizeof("noto sans indic siyaq numbers")]; + char FcConstFamilyNamePool_str767[sizeof("gargi")]; + char FcConstFamilyNamePool_str768[sizeof("lalezar")]; + char FcConstFamilyNamePool_str773[sizeof("droid sans mono")]; + char FcConstFamilyNamePool_str776[sizeof("georgia")]; + char FcConstFamilyNamePool_str779[sizeof("noto sans sora sompeng")]; + char FcConstFamilyNamePool_str782[sizeof("noto sans adlam")]; + char FcConstFamilyNamePool_str792[sizeof("noto sans tamil")]; + char FcConstFamilyNamePool_str796[sizeof("nu")]; + char FcConstFamilyNamePool_str803[sizeof("noto sans mandaic")]; + char FcConstFamilyNamePool_str806[sizeof("leland")]; + char FcConstFamilyNamePool_str807[sizeof("gentium basic")]; + char FcConstFamilyNamePool_str814[sizeof("kinnari")]; + char FcConstFamilyNamePool_str820[sizeof("gfs gazis")]; + char FcConstFamilyNamePool_str823[sizeof("kamran")]; + char FcConstFamilyNamePool_str827[sizeof("stkaiti")]; + char FcConstFamilyNamePool_str836[sizeof("aqui")]; + char FcConstFamilyNamePool_str840[sizeof("arial unicode")]; + char FcConstFamilyNamePool_str844[sizeof("cascadia code")]; + char FcConstFamilyNamePool_str845[sizeof("kaiti")]; + char FcConstFamilyNamePool_str847[sizeof("droid sans armenian")]; + char FcConstFamilyNamePool_str848[sizeof("crete round")]; + char FcConstFamilyNamePool_str851[sizeof("kartika")]; + char FcConstFamilyNamePool_str853[sizeof("mukti")]; + char FcConstFamilyNamePool_str858[sizeof("homa")]; + char FcConstFamilyNamePool_str866[sizeof("khmer ui")]; + char FcConstFamilyNamePool_str873[sizeof("anaktoria")]; + char FcConstFamilyNamePool_str876[sizeof("gfs galatea")]; + char FcConstFamilyNamePool_str877[sizeof("hanamin")]; + char FcConstFamilyNamePool_str879[sizeof("latin modern roman demi")]; + char FcConstFamilyNamePool_str883[sizeof("arshia")]; + char FcConstFamilyNamePool_str888[sizeof("simsun")]; + char FcConstFamilyNamePool_str889[sizeof("comicshannsmono nerd font")]; + char FcConstFamilyNamePool_str892[sizeof("khmer os")]; + char FcConstFamilyNamePool_str895[sizeof("latin modern roman slanted")]; + char FcConstFamilyNamePool_str896[sizeof("kates")]; + char FcConstFamilyNamePool_str901[sizeof("harmattan")]; + char FcConstFamilyNamePool_str902[sizeof("ipamincho")]; + char FcConstFamilyNamePool_str904[sizeof("shruti")]; + char FcConstFamilyNamePool_str905[sizeof("stheiti")]; + char FcConstFamilyNamePool_str907[sizeof("noto sans old north arabian")]; + char FcConstFamilyNamePool_str908[sizeof("elham")]; + char FcConstFamilyNamePool_str911[sizeof("hermit")]; + char FcConstFamilyNamePool_str912[sizeof("simhei")]; + char FcConstFamilyNamePool_str913[sizeof("arial unicode ms")]; + char FcConstFamilyNamePool_str915[sizeof("ms mincho")]; + char FcConstFamilyNamePool_str916[sizeof("tahoma")]; + char FcConstFamilyNamePool_str917[sizeof("mukta vaani")]; + char FcConstFamilyNamePool_str919[sizeof("amiri quran")]; + char FcConstFamilyNamePool_str921[sizeof("leelawadee")]; + char FcConstFamilyNamePool_str922[sizeof("inconsolatago")]; + char FcConstFamilyNamePool_str923[sizeof("mukta malar")]; + char FcConstFamilyNamePool_str924[sizeof("noto sans sogdian")]; + char FcConstFamilyNamePool_str929[sizeof("noto sans mongolian")]; + char FcConstFamilyNamePool_str934[sizeof("gill sans")]; + char FcConstFamilyNamePool_str940[sizeof("mints strong")]; + char FcConstFamilyNamePool_str948[sizeof("inconsolata go")]; + char FcConstFamilyNamePool_str950[sizeof("noto sans nandinagari")]; + char FcConstFamilyNamePool_str955[sizeof("garamond")]; + char FcConstFamilyNamePool_str967[sizeof("noto sans canadian aboriginal")]; + char FcConstFamilyNamePool_str970[sizeof("courier")]; + char FcConstFamilyNamePool_str972[sizeof("noto sans nko")]; + char FcConstFamilyNamePool_str975[sizeof("rit rachana")]; + char FcConstFamilyNamePool_str984[sizeof("rachana")]; + char FcConstFamilyNamePool_str985[sizeof("archivo")]; + char FcConstFamilyNamePool_str986[sizeof("noto sans ui")]; + char FcConstFamilyNamePool_str987[sizeof("merriweather")]; + char FcConstFamilyNamePool_str990[sizeof("kacstpen")]; + char FcConstFamilyNamePool_str992[sizeof("mukta mahee")]; + char FcConstFamilyNamePool_str993[sizeof("kacstqurn")]; + char FcConstFamilyNamePool_str994[sizeof("kacst-qr")]; + char FcConstFamilyNamePool_str995[sizeof("kacstqura")]; + char FcConstFamilyNamePool_str1004[sizeof("cousine")]; + char FcConstFamilyNamePool_str1006[sizeof("codenewroman nerd font mono")]; + char FcConstFamilyNamePool_str1012[sizeof("kacstfarsi")]; + char FcConstFamilyNamePool_str1024[sizeof("eb garamond")]; + char FcConstFamilyNamePool_str1031[sizeof("codenewroman nerd font")]; + char FcConstFamilyNamePool_str1039[sizeof("noto sans takri")]; + char FcConstFamilyNamePool_str1040[sizeof("kacstone")]; + char FcConstFamilyNamePool_str1045[sizeof("kalinga")]; + char FcConstFamilyNamePool_str1046[sizeof("noto sans georgian")]; + char FcConstFamilyNamePool_str1047[sizeof("karla")]; + char FcConstFamilyNamePool_str1051[sizeof("manchu2005")]; + char FcConstFamilyNamePool_str1055[sizeof("ume mincho")]; + char FcConstFamilyNamePool_str1056[sizeof("kacstscreen")]; + char FcConstFamilyNamePool_str1060[sizeof("kacstart")]; + char FcConstFamilyNamePool_str1061[sizeof("andika")]; + char FcConstFamilyNamePool_str1066[sizeof("alkalami")]; + char FcConstFamilyNamePool_str1071[sizeof("kacstposter")]; + char FcConstFamilyNamePool_str1073[sizeof("noto sans thai")]; + char FcConstFamilyNamePool_str1075[sizeof("untaza")]; + char FcConstFamilyNamePool_str1081[sizeof("akkadian")]; + char FcConstFamilyNamePool_str1082[sizeof("lekton")]; + char FcConstFamilyNamePool_str1086[sizeof("tscu_paranar")]; + char FcConstFamilyNamePool_str1090[sizeof("dank mono")]; + char FcConstFamilyNamePool_str1093[sizeof("kacstletter")]; + char FcConstFamilyNamePool_str1095[sizeof("kacsttitle")]; + char FcConstFamilyNamePool_str1097[sizeof("lao ui")]; + char FcConstFamilyNamePool_str1098[sizeof("share tech mono")]; + char FcConstFamilyNamePool_str1105[sizeof("anka/coder")]; + char FcConstFamilyNamePool_str1107[sizeof("ipamonamincho")]; + char FcConstFamilyNamePool_str1112[sizeof("source sans 3")]; + char FcConstFamilyNamePool_str1113[sizeof("latin modern roman dunhill")]; + char FcConstFamilyNamePool_str1115[sizeof("noto sans hatran")]; + char FcConstFamilyNamePool_str1117[sizeof("noto sans thaana")]; + char FcConstFamilyNamePool_str1118[sizeof("mplus")]; + char FcConstFamilyNamePool_str1124[sizeof("nuosu sil")]; + char FcConstFamilyNamePool_str1127[sizeof("hasida")]; + char FcConstFamilyNamePool_str1128[sizeof("merriweather sans")]; + char FcConstFamilyNamePool_str1129[sizeof("ume mincho s3")]; + char FcConstFamilyNamePool_str1133[sizeof("silkscreen")]; + char FcConstFamilyNamePool_str1149[sizeof("undotum")]; + char FcConstFamilyNamePool_str1150[sizeof("dotum")]; + char FcConstFamilyNamePool_str1160[sizeof("noto sans armenian ui")]; + char FcConstFamilyNamePool_str1165[sizeof("noto sans cham")]; + char FcConstFamilyNamePool_str1178[sizeof("nanumgothic")]; + char FcConstFamilyNamePool_str1184[sizeof("titillium")]; + char FcConstFamilyNamePool_str1193[sizeof("quicksand")]; + char FcConstFamilyNamePool_str1209[sizeof("noto sans tai tham")]; + char FcConstFamilyNamePool_str1210[sizeof("lucida console")]; + char FcConstFamilyNamePool_str1221[sizeof("red hat mono")]; + char FcConstFamilyNamePool_str1223[sizeof("raghindi")]; + char FcConstFamilyNamePool_str1227[sizeof("gautami")]; + char FcConstFamilyNamePool_str1230[sizeof("grand hotel")]; + char FcConstFamilyNamePool_str1241[sizeof("noto sans marchen")]; + char FcConstFamilyNamePool_str1242[sizeof("arundina sans")]; + char FcConstFamilyNamePool_str1246[sizeof("gotham")]; + char FcConstFamilyNamePool_str1259[sizeof("khmer os content")]; + char FcConstFamilyNamePool_str1267[sizeof("noto sans runic")]; + char FcConstFamilyNamePool_str1273[sizeof("noto sans chorasmian")]; + char FcConstFamilyNamePool_str1276[sizeof("droid sans tamil")]; + char FcConstFamilyNamePool_str1280[sizeof("noto sans manichaean")]; + char FcConstFamilyNamePool_str1292[sizeof("noto sans kannada")]; + char FcConstFamilyNamePool_str1307[sizeof("noto sans lao ui")]; + char FcConstFamilyNamePool_str1316[sizeof("aurulentsansmono")]; + char FcConstFamilyNamePool_str1320[sizeof("uniol")]; + char FcConstFamilyNamePool_str1325[sizeof("ungraphic")]; + char FcConstFamilyNamePool_str1327[sizeof("sazanami mincho")]; + char FcConstFamilyNamePool_str1336[sizeof("noto sans kannada ui")]; + char FcConstFamilyNamePool_str1341[sizeof("noto sans old italic")]; + char FcConstFamilyNamePool_str1343[sizeof("noto sans sinhala")]; + char FcConstFamilyNamePool_str1348[sizeof("hiragino sans")]; + char FcConstFamilyNamePool_str1354[sizeof("arundina sans mono")]; + char FcConstFamilyNamePool_str1357[sizeof("noto sans multani")]; + char FcConstFamilyNamePool_str1359[sizeof("lohit assamese")]; + char FcConstFamilyNamePool_str1362[sizeof("noto sans sharada")]; + char FcConstFamilyNamePool_str1376[sizeof("noto sans caucasian albanian")]; + char FcConstFamilyNamePool_str1378[sizeof("mukta devanagari")]; + char FcConstFamilyNamePool_str1383[sizeof("noto sans tamil ui")]; + char FcConstFamilyNamePool_str1384[sizeof("inconsolatalgc")]; + char FcConstFamilyNamePool_str1387[sizeof("noto sans sinhala ui")]; + char FcConstFamilyNamePool_str1393[sizeof("noto sans mende kikakui")]; + char FcConstFamilyNamePool_str1410[sizeof("noto traditional nushu")]; + char FcConstFamilyNamePool_str1411[sizeof("jura")]; + char FcConstFamilyNamePool_str1413[sizeof("noto sans ogham")]; + char FcConstFamilyNamePool_str1419[sizeof("aurulentsansmono nerd font")]; + char FcConstFamilyNamePool_str1422[sizeof("lohit odia")]; + char FcConstFamilyNamePool_str1425[sizeof("noto sans sundanese")]; + char FcConstFamilyNamePool_str1429[sizeof("mingliu")]; + char FcConstFamilyNamePool_str1437[sizeof("lohit hindi")]; + char FcConstFamilyNamePool_str1439[sizeof("garuda")]; + char FcConstFamilyNamePool_str1440[sizeof("hadasim clm")]; + char FcConstFamilyNamePool_str1449[sizeof("inconsolatalgc nerd font")]; + char FcConstFamilyNamePool_str1453[sizeof("noto sans old sogdian")]; + char FcConstFamilyNamePool_str1456[sizeof("gfs decker")]; + char FcConstFamilyNamePool_str1457[sizeof("caladingsclm")]; + char FcConstFamilyNamePool_str1460[sizeof("nachlieli")]; + char FcConstFamilyNamePool_str1468[sizeof("lohit nepali")]; + char FcConstFamilyNamePool_str1471[sizeof("noto sans grantha")]; + char FcConstFamilyNamePool_str1474[sizeof("gfs didot classic")]; + char FcConstFamilyNamePool_str1478[sizeof("monofur")]; + char FcConstFamilyNamePool_str1479[sizeof("trade gothic")]; + char FcConstFamilyNamePool_str1483[sizeof("lohit kannada")]; + char FcConstFamilyNamePool_str1484[sizeof("shofar")]; + char FcConstFamilyNamePool_str1499[sizeof("fira mono")]; + char FcConstFamilyNamePool_str1501[sizeof("emoji one")]; + char FcConstFamilyNamePool_str1505[sizeof("ff meta")]; + char FcConstFamilyNamePool_str1507[sizeof("fira sans")]; + char FcConstFamilyNamePool_str1508[sizeof("\303\251colier court")]; + char FcConstFamilyNamePool_str1512[sizeof("droid sans georgian")]; + char FcConstFamilyNamePool_str1523[sizeof("fantezi")]; + char FcConstFamilyNamePool_str1525[sizeof("reem kufi")]; + char FcConstFamilyNamePool_str1529[sizeof("d-din condensed")]; + char FcConstFamilyNamePool_str1537[sizeof("outfit")]; + char FcConstFamilyNamePool_str1541[sizeof("kerkis")]; + char FcConstFamilyNamePool_str1550[sizeof("freemono")]; + char FcConstFamilyNamePool_str1551[sizeof("kacsttitlel")]; + char FcConstFamilyNamePool_str1555[sizeof("hiragino sans cns")]; + char FcConstFamilyNamePool_str1557[sizeof("droid sans thai")]; + char FcConstFamilyNamePool_str1560[sizeof("courier std")]; + char FcConstFamilyNamePool_str1563[sizeof("keter yg")]; + char FcConstFamilyNamePool_str1566[sizeof("gentium plus")]; + char FcConstFamilyNamePool_str1570[sizeof("ipamonagothic")]; + char FcConstFamilyNamePool_str1571[sizeof("freesans")]; + char FcConstFamilyNamePool_str1601[sizeof("artsounk")]; + char FcConstFamilyNamePool_str1603[sizeof("noto sans tagalog")]; + char FcConstFamilyNamePool_str1611[sizeof("comfortaa")]; + char FcConstFamilyNamePool_str1616[sizeof("noto sans siddham")]; + char FcConstFamilyNamePool_str1617[sizeof("ff scala")]; + char FcConstFamilyNamePool_str1621[sizeof("noto looped lao ui")]; + char FcConstFamilyNamePool_str1629[sizeof("fontawesome")]; + char FcConstFamilyNamePool_str1642[sizeof("latin modern roman unslanted")]; + char FcConstFamilyNamePool_str1643[sizeof("stam ashkenaz clm")]; + char FcConstFamilyNamePool_str1648[sizeof("farnaz")]; + char FcConstFamilyNamePool_str1654[sizeof("lohit devanagari")]; + char FcConstFamilyNamePool_str1655[sizeof("lohit tamil")]; + char FcConstFamilyNamePool_str1670[sizeof("heuristica")]; + char FcConstFamilyNamePool_str1671[sizeof("noto sans gothic")]; + char FcConstFamilyNamePool_str1672[sizeof("gfs g\303\266schen")]; + char FcConstFamilyNamePool_str1676[sizeof("noto sans old south arabian")]; + char FcConstFamilyNamePool_str1680[sizeof("darkgarden")]; + char FcConstFamilyNamePool_str1684[sizeof("asana math")]; + char FcConstFamilyNamePool_str1685[sizeof("amiri quran colored")]; + char FcConstFamilyNamePool_str1686[sizeof("3270 nerd font")]; + char FcConstFamilyNamePool_str1689[sizeof("noto sans thai looped")]; + char FcConstFamilyNamePool_str1692[sizeof("jomolhari")]; + char FcConstFamilyNamePool_str1694[sizeof("segoe ui historic")]; + char FcConstFamilyNamePool_str1696[sizeof("noto sans ugaritic")]; + char FcConstFamilyNamePool_str1706[sizeof("terminus (ttf)")]; + char FcConstFamilyNamePool_str1711[sizeof("kacstbook")]; + char FcConstFamilyNamePool_str1713[sizeof("san francisco")]; + char FcConstFamilyNamePool_str1715[sizeof("ff din")]; + char FcConstFamilyNamePool_str1716[sizeof("ferdosi")]; + char FcConstFamilyNamePool_str1718[sizeof("leelawadee ui")]; + char FcConstFamilyNamePool_str1719[sizeof("noto fangsong kss rotated")]; + char FcConstFamilyNamePool_str1720[sizeof("montserrat underline")]; + char FcConstFamilyNamePool_str1721[sizeof("noto sans nag mundari")]; + char FcConstFamilyNamePool_str1725[sizeof("noto fangsong kss vertical")]; + char FcConstFamilyNamePool_str1733[sizeof("lpfont")]; + char FcConstFamilyNamePool_str1738[sizeof("noto serif toto")]; + char FcConstFamilyNamePool_str1750[sizeof("noto serif armenian")]; + char FcConstFamilyNamePool_str1751[sizeof("minion math")]; + char FcConstFamilyNamePool_str1753[sizeof("3270 nerd font mono")]; + char FcConstFamilyNamePool_str1758[sizeof("noto sans glagolitic")]; + char FcConstFamilyNamePool_str1759[sizeof("kokila")]; + char FcConstFamilyNamePool_str1765[sizeof("fira code")]; + char FcConstFamilyNamePool_str1775[sizeof("jg laotimes")]; + char FcConstFamilyNamePool_str1777[sizeof("drift")]; + char FcConstFamilyNamePool_str1778[sizeof("lateef")]; + char FcConstFamilyNamePool_str1779[sizeof("koodak")]; + char FcConstFamilyNamePool_str1795[sizeof("sazanami gothic")]; + char FcConstFamilyNamePool_str1797[sizeof("android emoji")]; + char FcConstFamilyNamePool_str1807[sizeof("noto sans khmer")]; + char FcConstFamilyNamePool_str1822[sizeof("lohit bengali")]; + char FcConstFamilyNamePool_str1825[sizeof("noto sans georgian ui")]; + char FcConstFamilyNamePool_str1826[sizeof("noto sans kaithi")]; + char FcConstFamilyNamePool_str1836[sizeof("lisu")]; + char FcConstFamilyNamePool_str1841[sizeof("noto serif ottoman siyaq")]; + char FcConstFamilyNamePool_str1849[sizeof("space grotesk")]; + char FcConstFamilyNamePool_str1851[sizeof("noto sans math")]; + char FcConstFamilyNamePool_str1860[sizeof("figtree")]; + char FcConstFamilyNamePool_str1868[sizeof("noto sans hanunoo")]; + char FcConstFamilyNamePool_str1871[sizeof("noto sans adlam unjoined")]; + char FcConstFamilyNamePool_str1877[sizeof("noto serif lao")]; + char FcConstFamilyNamePool_str1879[sizeof("roya")]; + char FcConstFamilyNamePool_str1882[sizeof("kacstdigital")]; + char FcConstFamilyNamePool_str1890[sizeof("sparks dot large")]; + char FcConstFamilyNamePool_str1895[sizeof("noto sans thai ui")]; + char FcConstFamilyNamePool_str1896[sizeof("gfs garaldus")]; + char FcConstFamilyNamePool_str1900[sizeof("signfont")]; + char FcConstFamilyNamePool_str1901[sizeof("nachlieli clm")]; + char FcConstFamilyNamePool_str1904[sizeof("noto color emoji")]; + char FcConstFamilyNamePool_str1907[sizeof("comic neue angular")]; + char FcConstFamilyNamePool_str1908[sizeof("meiryo")]; + char FcConstFamilyNamePool_str1914[sizeof("noto sans chakma")]; + char FcConstFamilyNamePool_str1915[sizeof("source han mono")]; + char FcConstFamilyNamePool_str1927[sizeof("noto sans tirhuta")]; + char FcConstFamilyNamePool_str1944[sizeof("ms ui gothic")]; + char FcConstFamilyNamePool_str1951[sizeof("lohit konkani")]; + char FcConstFamilyNamePool_str1957[sizeof("segoe ui emoji")]; + char FcConstFamilyNamePool_str1959[sizeof("monoid nerd font")]; + char FcConstFamilyNamePool_str1961[sizeof("noto sans saurashtra")]; + char FcConstFamilyNamePool_str1965[sizeof("arimo nerd font")]; + char FcConstFamilyNamePool_str1969[sizeof("gf zemen unicode")]; + char FcConstFamilyNamePool_str1985[sizeof("lklug")]; + char FcConstFamilyNamePool_str1986[sizeof("sparks dot small")]; + char FcConstFamilyNamePool_str1998[sizeof("ungungseo")]; + char FcConstFamilyNamePool_str2003[sizeof("tinos nerd font")]; + char FcConstFamilyNamePool_str2005[sizeof("nafees nastaleeq")]; + char FcConstFamilyNamePool_str2018[sizeof("twitter color emoji")]; + char FcConstFamilyNamePool_str2022[sizeof("mononoki nerd font")]; + char FcConstFamilyNamePool_str2025[sizeof("noto sans yi")]; + char FcConstFamilyNamePool_str2026[sizeof("noto sans lisu")]; + char FcConstFamilyNamePool_str2030[sizeof("lohit kashmiri")]; + char FcConstFamilyNamePool_str2035[sizeof("inconsolata regular")]; + char FcConstFamilyNamePool_str2037[sizeof("ibm 3270 nerd font")]; + char FcConstFamilyNamePool_str2038[sizeof("lohit marathi")]; + char FcConstFamilyNamePool_str2040[sizeof("terminess nerd font")]; + char FcConstFamilyNamePool_str2045[sizeof("noto sans cherokee")]; + char FcConstFamilyNamePool_str2047[sizeof("lohit gujarati")]; + char FcConstFamilyNamePool_str2055[sizeof("lucida sans unicode")]; + char FcConstFamilyNamePool_str2058[sizeof("namdhinggo sil")]; + char FcConstFamilyNamePool_str2062[sizeof("notomono nerd font")]; + char FcConstFamilyNamePool_str2065[sizeof("gfs neohellenic")]; + char FcConstFamilyNamePool_str2069[sizeof("gfs orpheus")]; + char FcConstFamilyNamePool_str2093[sizeof("noto sans oriya")]; + char FcConstFamilyNamePool_str2094[sizeof("spark dot-line thin")]; + char FcConstFamilyNamePool_str2095[sizeof("source han sans cn")]; + char FcConstFamilyNamePool_str2126[sizeof("edwin")]; + char FcConstFamilyNamePool_str2133[sizeof("spacemono nerd font")]; + char FcConstFamilyNamePool_str2144[sizeof("noto sans myanmar")]; + char FcConstFamilyNamePool_str2152[sizeof("noto sans osmanya")]; + char FcConstFamilyNamePool_str2155[sizeof("century gothic")]; + char FcConstFamilyNamePool_str2159[sizeof("latin modern math")]; + char FcConstFamilyNamePool_str2161[sizeof("hasklig")]; + char FcConstFamilyNamePool_str2162[sizeof("jadid")]; + char FcConstFamilyNamePool_str2163[sizeof("sharetechmono nerd font")]; + char FcConstFamilyNamePool_str2165[sizeof("malayalam")]; + char FcConstFamilyNamePool_str2174[sizeof("anka/coder condensed")]; + char FcConstFamilyNamePool_str2178[sizeof("waree")]; + char FcConstFamilyNamePool_str2179[sizeof("noto serif tamil")]; + char FcConstFamilyNamePool_str2181[sizeof("noto sans ol chiki")]; + char FcConstFamilyNamePool_str2188[sizeof("noto sans myanmar ui")]; + char FcConstFamilyNamePool_str2189[sizeof("khmer os muol")]; + char FcConstFamilyNamePool_str2191[sizeof("noto looped thai ui")]; + char FcConstFamilyNamePool_str2192[sizeof("stfangsong")]; + char FcConstFamilyNamePool_str2197[sizeof("alexander")]; + char FcConstFamilyNamePool_str2199[sizeof("gfs orpheus sans")]; + char FcConstFamilyNamePool_str2206[sizeof("adwaita mono")]; + char FcConstFamilyNamePool_str2207[sizeof("meslo nerd font")]; + char FcConstFamilyNamePool_str2208[sizeof("yudit")]; + char FcConstFamilyNamePool_str2209[sizeof("source han mono sc")]; + char FcConstFamilyNamePool_str2210[sizeof("ipaex\346\230\216\346\234\235")]; + char FcConstFamilyNamePool_str2213[sizeof("nanumgothiccoding")]; + char FcConstFamilyNamePool_str2217[sizeof("terafik")]; + char FcConstFamilyNamePool_str2219[sizeof("adwaita sans")]; + char FcConstFamilyNamePool_str2225[sizeof("ume gothic o5")]; + char FcConstFamilyNamePool_str2226[sizeof("lohit sindhi")]; + char FcConstFamilyNamePool_str2229[sizeof("ume gothic s4")]; + char FcConstFamilyNamePool_str2231[sizeof("source han mono tc")]; + char FcConstFamilyNamePool_str2232[sizeof("nanumgothic_coding")]; + char FcConstFamilyNamePool_str2233[sizeof("ume gothic s5")]; + char FcConstFamilyNamePool_str2239[sizeof("fangsong ti")]; + char FcConstFamilyNamePool_str2242[sizeof("unjamosora")]; + char FcConstFamilyNamePool_str2249[sizeof("signfont z")]; + char FcConstFamilyNamePool_str2253[sizeof("ume gothic")]; + char FcConstFamilyNamePool_str2259[sizeof("futura")]; + char FcConstFamilyNamePool_str2261[sizeof("stam sefarad clm")]; + char FcConstFamilyNamePool_str2264[sizeof("noto serif dogra")]; + char FcConstFamilyNamePool_str2276[sizeof("avenir next")]; + char FcConstFamilyNamePool_str2278[sizeof("noto serif tamil slanted")]; + char FcConstFamilyNamePool_str2279[sizeof("frutiger")]; + char FcConstFamilyNamePool_str2281[sizeof("noto sans medefaidrin")]; + char FcConstFamilyNamePool_str2282[sizeof("ia writer mono")]; + char FcConstFamilyNamePool_str2286[sizeof("lohit maithili")]; + char FcConstFamilyNamePool_str2294[sizeof("gomono nerd font")]; + char FcConstFamilyNamePool_str2295[sizeof("emojione mozilla")]; + char FcConstFamilyNamePool_str2301[sizeof("noto sans newa")]; + char FcConstFamilyNamePool_str2320[sizeof("ipaex\343\202\264\343\202\267\343\203\203\343\202\257")]; + char FcConstFamilyNamePool_str2323[sizeof("news cycle")]; + char FcConstFamilyNamePool_str2326[sizeof("lucida math")]; + char FcConstFamilyNamePool_str2327[sizeof("ume gothic c4")]; + char FcConstFamilyNamePool_str2331[sizeof("ume gothic c5")]; + char FcConstFamilyNamePool_str2332[sizeof("noto sans rejang")]; + char FcConstFamilyNamePool_str2335[sizeof("oxygen mono")]; + char FcConstFamilyNamePool_str2336[sizeof("noto sans syriac eastern")]; + char FcConstFamilyNamePool_str2340[sizeof("noto sans syriac")]; + char FcConstFamilyNamePool_str2342[sizeof("sparks dot medium")]; + char FcConstFamilyNamePool_str2352[sizeof("go mono nerd font")]; + char FcConstFamilyNamePool_str2354[sizeof("spark dot-line medium")]; + char FcConstFamilyNamePool_str2356[sizeof("oxygen-sans")]; + char FcConstFamilyNamePool_str2362[sizeof("p052")]; + char FcConstFamilyNamePool_str2365[sizeof("geistmono nerd font")]; + char FcConstFamilyNamePool_str2372[sizeof("yu gothic")]; + char FcConstFamilyNamePool_str2373[sizeof("pt mono")]; + char FcConstFamilyNamePool_str2374[sizeof("sf pro")]; + char FcConstFamilyNamePool_str2381[sizeof("inconsolata nerd font")]; + char FcConstFamilyNamePool_str2382[sizeof("motoyalcedar")]; + char FcConstFamilyNamePool_str2383[sizeof("pt sans")]; + char FcConstFamilyNamePool_str2384[sizeof("luxi mono")]; + char FcConstFamilyNamePool_str2385[sizeof("plantin")]; + char FcConstFamilyNamePool_str2387[sizeof("hack")]; + char FcConstFamilyNamePool_str2392[sizeof("luxi sans")]; + char FcConstFamilyNamePool_str2394[sizeof("sampige")]; + char FcConstFamilyNamePool_str2405[sizeof("ubuntu")]; + char FcConstFamilyNamePool_str2409[sizeof("myriad pro")]; + char FcConstFamilyNamePool_str2410[sizeof("minion pro")]; + char FcConstFamilyNamePool_str2415[sizeof("noto serif georgian")]; + char FcConstFamilyNamePool_str2416[sizeof("unshinmun")]; + char FcConstFamilyNamePool_str2425[sizeof("overpass")]; + char FcConstFamilyNamePool_str2429[sizeof("sathu")]; + char FcConstFamilyNamePool_str2432[sizeof("crimson text")]; + char FcConstFamilyNamePool_str2438[sizeof("news gothic")]; + char FcConstFamilyNamePool_str2445[sizeof("noto sans lycian")]; + char FcConstFamilyNamePool_str2446[sizeof("noto serif ahom")]; + char FcConstFamilyNamePool_str2455[sizeof("noto sans mahajani")]; + char FcConstFamilyNamePool_str2456[sizeof("noto serif makasar")]; + char FcConstFamilyNamePool_str2460[sizeof("noto serif thai")]; + char FcConstFamilyNamePool_str2463[sizeof("ipaexgothic")]; + char FcConstFamilyNamePool_str2481[sizeof("fantasquesansmono")]; + char FcConstFamilyNamePool_str2492[sizeof("campania")]; + char FcConstFamilyNamePool_str2493[sizeof("prociono")]; + char FcConstFamilyNamePool_str2494[sizeof("source serif 4")]; + char FcConstFamilyNamePool_str2495[sizeof("impact")]; + char FcConstFamilyNamePool_str2499[sizeof("drugulinclm")]; + char FcConstFamilyNamePool_str2500[sizeof("fangsong")]; + char FcConstFamilyNamePool_str2507[sizeof("droidsansmono nerd font")]; + char FcConstFamilyNamePool_str2510[sizeof("tlwgmono")]; + char FcConstFamilyNamePool_str2512[sizeof("overpass mono")]; + char FcConstFamilyNamePool_str2518[sizeof("ipapmincho")]; + char FcConstFamilyNamePool_str2521[sizeof("abyssinica sil")]; + char FcConstFamilyNamePool_str2534[sizeof("perizia")]; + char FcConstFamilyNamePool_str2537[sizeof("tlwgtypo")]; + char FcConstFamilyNamePool_str2541[sizeof("droidsansm nerd font")]; + char FcConstFamilyNamePool_str2545[sizeof("jg lao old arial")]; + char FcConstFamilyNamePool_str2552[sizeof("accanthis adf std")]; + char FcConstFamilyNamePool_str2556[sizeof("kacstoffice")]; + char FcConstFamilyNamePool_str2559[sizeof("gfs jackson")]; + char FcConstFamilyNamePool_str2563[sizeof("kacstnaskh")]; + char FcConstFamilyNamePool_str2574[sizeof("ukij tuz")]; + char FcConstFamilyNamePool_str2580[sizeof("noto sans lydian")]; + char FcConstFamilyNamePool_str2583[sizeof("noto sans old turkic")]; + char FcConstFamilyNamePool_str2586[sizeof("oswald")]; + char FcConstFamilyNamePool_str2589[sizeof("fantasquesansmono nerd font")]; + char FcConstFamilyNamePool_str2605[sizeof("padmaa")]; + char FcConstFamilyNamePool_str2606[sizeof("din pro")]; + char FcConstFamilyNamePool_str2608[sizeof("noto sans elymaic")]; + char FcConstFamilyNamePool_str2617[sizeof("tlwgtypist")]; + char FcConstFamilyNamePool_str2618[sizeof("noto sans cuneiform")]; + char FcConstFamilyNamePool_str2622[sizeof("lexend")]; + char FcConstFamilyNamePool_str2624[sizeof("khmer os metal chrieng")]; + char FcConstFamilyNamePool_str2626[sizeof("noto sans malayalam")]; + char FcConstFamilyNamePool_str2627[sizeof("noto sans khmer ui")]; + char FcConstFamilyNamePool_str2636[sizeof("undinaru")]; + char FcConstFamilyNamePool_str2639[sizeof("petaluma")]; + char FcConstFamilyNamePool_str2645[sizeof("palatino")]; + char FcConstFamilyNamePool_str2646[sizeof("noto sans malayalam ui")]; + char FcConstFamilyNamePool_str2649[sizeof("old standard sfd")]; + char FcConstFamilyNamePool_str2658[sizeof("nanummyeongjo")]; + char FcConstFamilyNamePool_str2661[sizeof("kochi mincho")]; + char FcConstFamilyNamePool_str2667[sizeof("noto sans mono cjk sc")]; + char FcConstFamilyNamePool_str2674[sizeof("noto sans kharoshthi")]; + char FcConstFamilyNamePool_str2678[sizeof("gfs orpheus classic")]; + char FcConstFamilyNamePool_str2679[sizeof("noto serif kannada")]; + char FcConstFamilyNamePool_str2682[sizeof("meiryo ui")]; + char FcConstFamilyNamePool_str2683[sizeof("yudit unicode")]; + char FcConstFamilyNamePool_str2689[sizeof("noto sans mono cjk tc")]; + char FcConstFamilyNamePool_str2697[sizeof("gohu")]; + char FcConstFamilyNamePool_str2701[sizeof("noto sans cjk sc")]; + char FcConstFamilyNamePool_str2703[sizeof("source han sans kr")]; + char FcConstFamilyNamePool_str2704[sizeof("yu mincho")]; + char FcConstFamilyNamePool_str2707[sizeof("akzidenz grotesk")]; + char FcConstFamilyNamePool_str2709[sizeof("pigiarniq")]; + char FcConstFamilyNamePool_str2713[sizeof("ubuntu condensed")]; + char FcConstFamilyNamePool_str2714[sizeof("tlwgtypewriter")]; + char FcConstFamilyNamePool_str2716[sizeof("inconsolatago nerd font")]; + char FcConstFamilyNamePool_str2719[sizeof("noto sans old hungarian")]; + char FcConstFamilyNamePool_str2722[sizeof("conakry")]; + char FcConstFamilyNamePool_str2723[sizeof("noto sans cjk tc")]; + char FcConstFamilyNamePool_str2726[sizeof("hurmit nerd font")]; + char FcConstFamilyNamePool_str2730[sizeof("noto serif sinhala")]; + char FcConstFamilyNamePool_str2744[sizeof("unjamonovel")]; + char FcConstFamilyNamePool_str2748[sizeof("leland text")]; + char FcConstFamilyNamePool_str2749[sizeof("noto serif todhri")]; + char FcConstFamilyNamePool_str2751[sizeof("mgopen canonica")]; + char FcConstFamilyNamePool_str2755[sizeof("gfs porson")]; + char FcConstFamilyNamePool_str2759[sizeof("daddytimemono")]; + char FcConstFamilyNamePool_str2765[sizeof("pragmatapro")]; + char FcConstFamilyNamePool_str2766[sizeof("simple clm")]; + char FcConstFamilyNamePool_str2767[sizeof("kochi gothic")]; + char FcConstFamilyNamePool_str2769[sizeof("foundation icons")]; + char FcConstFamilyNamePool_str2777[sizeof("mgopen modata")]; + char FcConstFamilyNamePool_str2778[sizeof("tex gyre termes")]; + char FcConstFamilyNamePool_str2781[sizeof("gfs pyrsos")]; + char FcConstFamilyNamePool_str2787[sizeof("noto sans syloti nagri")]; + char FcConstFamilyNamePool_str2790[sizeof("noto sans inscriptional pahlavi")]; + char FcConstFamilyNamePool_str2791[sizeof("noto sans inscriptional parthian")]; + char FcConstFamilyNamePool_str2805[sizeof("noto sans gujarati")]; + char FcConstFamilyNamePool_str2824[sizeof("gfs fleischman")]; + char FcConstFamilyNamePool_str2835[sizeof("alef")]; + char FcConstFamilyNamePool_str2838[sizeof("rit keraleeyam")]; + char FcConstFamilyNamePool_str2858[sizeof("noto serif grantha")]; + char FcConstFamilyNamePool_str2860[sizeof("work sans")]; + char FcConstFamilyNamePool_str2863[sizeof("noto sans warang citi")]; + char FcConstFamilyNamePool_str2876[sizeof("noto sans tifinagh air")]; + char FcConstFamilyNamePool_str2878[sizeof("noto sans tifinagh adrar")]; + char FcConstFamilyNamePool_str2879[sizeof("cousine nerd font")]; + char FcConstFamilyNamePool_str2880[sizeof("noto sans tifinagh ahaggar")]; + char FcConstFamilyNamePool_str2881[sizeof("league gothic")]; + char FcConstFamilyNamePool_str2883[sizeof("noto sans tifinagh rhissa ixa")]; + char FcConstFamilyNamePool_str2884[sizeof("widelands")]; + char FcConstFamilyNamePool_str2886[sizeof("noto sans tifinagh agraw imazighen")]; + char FcConstFamilyNamePool_str2887[sizeof("malgun gothic")]; + char FcConstFamilyNamePool_str2891[sizeof("noto serif tangut")]; + char FcConstFamilyNamePool_str2893[sizeof("khmer os system")]; + char FcConstFamilyNamePool_str2900[sizeof("noto serif hentaigana")]; + char FcConstFamilyNamePool_str2901[sizeof("ms serif")]; + char FcConstFamilyNamePool_str2909[sizeof("noto sans tifinagh apt")]; + char FcConstFamilyNamePool_str2912[sizeof("freeserif")]; + char FcConstFamilyNamePool_str2913[sizeof("noto sans oriya ui")]; + char FcConstFamilyNamePool_str2914[sizeof("b612")]; + char FcConstFamilyNamePool_str2915[sizeof("opendyslexicmono")]; + char FcConstFamilyNamePool_str2917[sizeof("noto serif")]; + char FcConstFamilyNamePool_str2922[sizeof("sabon")]; + char FcConstFamilyNamePool_str2923[sizeof("infofont")]; + char FcConstFamilyNamePool_str2927[sizeof("opendyslexic")]; + char FcConstFamilyNamePool_str2928[sizeof("noto sans coptic")]; + char FcConstFamilyNamePool_str2930[sizeof("annapurna sil")]; + char FcConstFamilyNamePool_str2932[sizeof("lekton nerd font")]; + char FcConstFamilyNamePool_str2934[sizeof("symbola")]; + char FcConstFamilyNamePool_str2935[sizeof("noto sans psalter pahlavi")]; + char FcConstFamilyNamePool_str2936[sizeof("al bayan")]; + char FcConstFamilyNamePool_str2945[sizeof("unjamobatang")]; + char FcConstFamilyNamePool_str2950[sizeof("noto sans tifinagh tawellemmet")]; + char FcConstFamilyNamePool_str2952[sizeof("roboto")]; + char FcConstFamilyNamePool_str2953[sizeof("b612 mono")]; + char FcConstFamilyNamePool_str2957[sizeof("khmer mondulkiri")]; + char FcConstFamilyNamePool_str2960[sizeof("mplus nerd font")]; + char FcConstFamilyNamePool_str2963[sizeof("patrick hand")]; + char FcConstFamilyNamePool_str2965[sizeof("thonburi")]; + char FcConstFamilyNamePool_str2966[sizeof("source han mono hc")]; + char FcConstFamilyNamePool_str2977[sizeof("noto znamenny musical notation")]; + char FcConstFamilyNamePool_str2978[sizeof("noto sans mayan numerals")]; + char FcConstFamilyNamePool_str2986[sizeof("ipaexmincho")]; + char FcConstFamilyNamePool_str2989[sizeof("ms sans serif")]; + char FcConstFamilyNamePool_str2991[sizeof("tabassom")]; + char FcConstFamilyNamePool_str3000[sizeof("noto sans imperial aramaic")]; + char FcConstFamilyNamePool_str3001[sizeof("xits math")]; + char FcConstFamilyNamePool_str3002[sizeof("bitter")]; + char FcConstFamilyNamePool_str3009[sizeof("noto sans meetei mayek")]; + char FcConstFamilyNamePool_str3010[sizeof("dancing script")]; + char FcConstFamilyNamePool_str3018[sizeof("opendyslexicmono nerd font")]; + char FcConstFamilyNamePool_str3019[sizeof("hanyisong")]; + char FcConstFamilyNamePool_str3021[sizeof("albany amt")]; + char FcConstFamilyNamePool_str3024[sizeof("roboto mono")]; + char FcConstFamilyNamePool_str3027[sizeof("markazi text")]; + char FcConstFamilyNamePool_str3029[sizeof("cambria")]; + char FcConstFamilyNamePool_str3031[sizeof("unjamodotum")]; + char FcConstFamilyNamePool_str3033[sizeof("cooper std")]; + char FcConstFamilyNamePool_str3034[sizeof("noto sans gunjala gondi")]; + char FcConstFamilyNamePool_str3060[sizeof("avenir next condensed")]; + char FcConstFamilyNamePool_str3068[sizeof("itc bodoni")]; + char FcConstFamilyNamePool_str3074[sizeof("britannic")]; + char FcConstFamilyNamePool_str3075[sizeof("ume ui gothic o5")]; + char FcConstFamilyNamePool_str3083[sizeof("yu gothic ui")]; + char FcConstFamilyNamePool_str3086[sizeof("raavi")]; + char FcConstFamilyNamePool_str3087[sizeof("ume hy gothic o5")]; + char FcConstFamilyNamePool_str3089[sizeof("noto sans signwriting")]; + char FcConstFamilyNamePool_str3100[sizeof("beteckna")]; + char FcConstFamilyNamePool_str3103[sizeof("ume ui gothic")]; + char FcConstFamilyNamePool_str3110[sizeof("b compset")]; + char FcConstFamilyNamePool_str3114[sizeof("noto nastaliq urdu")]; + char FcConstFamilyNamePool_str3115[sizeof("ume hy gothic")]; + char FcConstFamilyNamePool_str3116[sizeof("noto sans tifinagh sil")]; + char FcConstFamilyNamePool_str3118[sizeof("letters laughing")]; + char FcConstFamilyNamePool_str3120[sizeof("bola")]; + char FcConstFamilyNamePool_str3124[sizeof("iosevka")]; + char FcConstFamilyNamePool_str3129[sizeof("unpen")]; + char FcConstFamilyNamePool_str3135[sizeof("badr")]; + char FcConstFamilyNamePool_str3136[sizeof("agave")]; + char FcConstFamilyNamePool_str3141[sizeof("itc stone serif")]; + char FcConstFamilyNamePool_str3145[sizeof("noto sans old persian")]; + char FcConstFamilyNamePool_str3152[sizeof("dubai")]; + char FcConstFamilyNamePool_str3156[sizeof("bodoni")]; + char FcConstFamilyNamePool_str3162[sizeof("ia writer quattro")]; + char FcConstFamilyNamePool_str3169[sizeof("vemana2000")]; + char FcConstFamilyNamePool_str3170[sizeof("agbalumo")]; + char FcConstFamilyNamePool_str3185[sizeof("noto sans cjk kr")]; + char FcConstFamilyNamePool_str3193[sizeof("unyetgul")]; + char FcConstFamilyNamePool_str3194[sizeof("noto serif khmer")]; + char FcConstFamilyNamePool_str3195[sizeof("input mono")]; + char FcConstFamilyNamePool_str3198[sizeof("fontawesome 7 free")]; + char FcConstFamilyNamePool_str3203[sizeof("noto sans wancho")]; + char FcConstFamilyNamePool_str3204[sizeof("noto sans telugu")]; + char FcConstFamilyNamePool_str3205[sizeof("gfs philostratos")]; + char FcConstFamilyNamePool_str3212[sizeof("charis sil compact")]; + char FcConstFamilyNamePool_str3220[sizeof("noto sans nabataean")]; + char FcConstFamilyNamePool_str3227[sizeof("cascadia mono pl")]; + char FcConstFamilyNamePool_str3228[sizeof("noto sans new tai lue")]; + char FcConstFamilyNamePool_str3229[sizeof("libertinus")]; + char FcConstFamilyNamePool_str3233[sizeof("iosevkaterm")]; + char FcConstFamilyNamePool_str3236[sizeof("noto sans vai")]; + char FcConstFamilyNamePool_str3243[sizeof("noto sans tifinagh ghat")]; + char FcConstFamilyNamePool_str3246[sizeof("cascadia mono nf")]; + char FcConstFamilyNamePool_str3248[sizeof("calibri")]; + char FcConstFamilyNamePool_str3249[sizeof("iosevka term")]; + char FcConstFamilyNamePool_str3250[sizeof("noto sans telugu ui")]; + char FcConstFamilyNamePool_str3254[sizeof("ia writer duo")]; + char FcConstFamilyNamePool_str3257[sizeof("elephant")]; + char FcConstFamilyNamePool_str3260[sizeof("noto sans mono cjk kr")]; + char FcConstFamilyNamePool_str3263[sizeof("pothana2000")]; + char FcConstFamilyNamePool_str3272[sizeof("infofont z")]; + char FcConstFamilyNamePool_str3274[sizeof("corbel")]; + char FcConstFamilyNamePool_str3277[sizeof("batang")]; + char FcConstFamilyNamePool_str3279[sizeof("opendyslexic nerd font")]; + char FcConstFamilyNamePool_str3286[sizeof("noto sans hanifi rohingya")]; + char FcConstFamilyNamePool_str3289[sizeof("victormono")]; + char FcConstFamilyNamePool_str3305[sizeof("gfs bodoni")]; + char FcConstFamilyNamePool_str3311[sizeof("victor mono")]; + char FcConstFamilyNamePool_str3312[sizeof("noto serif khitan small script")]; + char FcConstFamilyNamePool_str3314[sizeof("proggyclean")]; + char FcConstFamilyNamePool_str3319[sizeof("lohit malayalam")]; + char FcConstFamilyNamePool_str3323[sizeof("vazirmatn")]; + char FcConstFamilyNamePool_str3325[sizeof("red hat text")]; + char FcConstFamilyNamePool_str3328[sizeof("liberation mono")]; + char FcConstFamilyNamePool_str3331[sizeof("vrinda")]; + char FcConstFamilyNamePool_str3336[sizeof("verdana")]; + char FcConstFamilyNamePool_str3341[sizeof("noto sans arabic")]; + char FcConstFamilyNamePool_str3346[sizeof("liberation sans")]; + char FcConstFamilyNamePool_str3356[sizeof("linux libertine")]; + char FcConstFamilyNamePool_str3359[sizeof("noto sans old permic")]; + char FcConstFamilyNamePool_str3360[sizeof("unpilgia")]; + char FcConstFamilyNamePool_str3368[sizeof("inter variable")]; + char FcConstFamilyNamePool_str3375[sizeof("bellota")]; + char FcConstFamilyNamePool_str3376[sizeof("monofur nerd font")]; + char FcConstFamilyNamePool_str3385[sizeof("source han mono k")]; + char FcConstFamilyNamePool_str3387[sizeof("noto sans avestan")]; + char FcConstFamilyNamePool_str3392[sizeof("firamono nerd font")]; + char FcConstFamilyNamePool_str3398[sizeof("spark dot-line extrathin")]; + char FcConstFamilyNamePool_str3402[sizeof("gb_ss_gb18030")]; + char FcConstFamilyNamePool_str3405[sizeof("noto sans elbasan")]; + char FcConstFamilyNamePool_str3409[sizeof("droid serif")]; + char FcConstFamilyNamePool_str3412[sizeof("rockwell")]; + char FcConstFamilyNamePool_str3413[sizeof("stevehand")]; + char FcConstFamilyNamePool_str3429[sizeof("noto sans nko unjoined")]; + char FcConstFamilyNamePool_str3432[sizeof("khmer os muol light")]; + char FcConstFamilyNamePool_str3438[sizeof("linux libertine mono")]; + char FcConstFamilyNamePool_str3462[sizeof("sakkal majalla")]; + char FcConstFamilyNamePool_str3466[sizeof("tex gyre heros")]; + char FcConstFamilyNamePool_str3468[sizeof("noto sans tai viet")]; + char FcConstFamilyNamePool_str3472[sizeof("noto sans balinese")]; + char FcConstFamilyNamePool_str3473[sizeof("liberationmono nerd font")]; + char FcConstFamilyNamePool_str3474[sizeof("source han serif cn")]; + char FcConstFamilyNamePool_str3475[sizeof("urdu nastaliq unicode")]; + char FcConstFamilyNamePool_str3480[sizeof("noto serif oriya")]; + char FcConstFamilyNamePool_str3487[sizeof("emoji two")]; + char FcConstFamilyNamePool_str3497[sizeof("ubuntu nerd font")]; + char FcConstFamilyNamePool_str3500[sizeof("cumberland amt")]; + char FcConstFamilyNamePool_str3505[sizeof("digna's handwriting")]; + char FcConstFamilyNamePool_str3507[sizeof("new athena unicode")]; + char FcConstFamilyNamePool_str3515[sizeof("firacode nerd font")]; + char FcConstFamilyNamePool_str3516[sizeof("firacode nerd font mono")]; + char FcConstFamilyNamePool_str3524[sizeof("noto sans phoenician")]; + char FcConstFamilyNamePool_str3526[sizeof("motoyalmaru")]; + char FcConstFamilyNamePool_str3531[sizeof("noto serif myanmar")]; + char FcConstFamilyNamePool_str3532[sizeof("gohu nerd font")]; + char FcConstFamilyNamePool_str3543[sizeof("spark dot-line thick")]; + char FcConstFamilyNamePool_str3550[sizeof("tex gyre cursor")]; + char FcConstFamilyNamePool_str3562[sizeof("vl gothic")]; + char FcConstFamilyNamePool_str3581[sizeof("noto sans zanabazar square")]; + char FcConstFamilyNamePool_str3583[sizeof("cumberland")]; + char FcConstFamilyNamePool_str3584[sizeof("noto sans gujarati ui")]; + char FcConstFamilyNamePool_str3591[sizeof("noto sans lao looped")]; + char FcConstFamilyNamePool_str3593[sizeof("unifrakturmaguntia")]; + char FcConstFamilyNamePool_str3596[sizeof("cascadia code pl")]; + char FcConstFamilyNamePool_str3597[sizeof("ubuntumono nerd font")]; + char FcConstFamilyNamePool_str3615[sizeof("cascadia code nf")]; + char FcConstFamilyNamePool_str3620[sizeof("noto sans tifinagh")]; + char FcConstFamilyNamePool_str3628[sizeof("tex gyre heros cn")]; + char FcConstFamilyNamePool_str3648[sizeof("noto sans tifinagh azawagh")]; + char FcConstFamilyNamePool_str3650[sizeof("noto sans ethiopic")]; + char FcConstFamilyNamePool_str3656[sizeof("proggysquarettsz")]; + char FcConstFamilyNamePool_str3664[sizeof("delphine")]; + char FcConstFamilyNamePool_str3681[sizeof("franklin gothic")]; + char FcConstFamilyNamePool_str3683[sizeof("unbom")]; + char FcConstFamilyNamePool_str3688[sizeof("noto sans gurmukhi")]; + char FcConstFamilyNamePool_str3690[sizeof("apparatus sil")]; + char FcConstFamilyNamePool_str3694[sizeof("tai heritage pro")]; + char FcConstFamilyNamePool_str3696[sizeof("noto sans lepcha")]; + char FcConstFamilyNamePool_str3700[sizeof("tajawal")]; + char FcConstFamilyNamePool_str3708[sizeof("noto sans tamil supplement")]; + char FcConstFamilyNamePool_str3712[sizeof("khmer os fasthand")]; + char FcConstFamilyNamePool_str3714[sizeof("khmer os freehand")]; + char FcConstFamilyNamePool_str3716[sizeof("ipapgothic")]; + char FcConstFamilyNamePool_str3725[sizeof("noto sans bengali")]; + char FcConstFamilyNamePool_str3726[sizeof("hasklug nerd font")]; + char FcConstFamilyNamePool_str3728[sizeof("andika compact")]; + char FcConstFamilyNamePool_str3737[sizeof("dai banna sil")]; + char FcConstFamilyNamePool_str3748[sizeof("nimbus mono")]; + char FcConstFamilyNamePool_str3753[sizeof("pcfont")]; + char FcConstFamilyNamePool_str3759[sizeof("profont")]; + char FcConstFamilyNamePool_str3761[sizeof("nimbus roman")]; + char FcConstFamilyNamePool_str3767[sizeof("source code pro")]; + char FcConstFamilyNamePool_str3769[sizeof("nimbus sans")]; + char FcConstFamilyNamePool_str3771[sizeof("noto sans bengali ui")]; + char FcConstFamilyNamePool_str3778[sizeof("bauer bodoni")]; + char FcConstFamilyNamePool_str3791[sizeof("tex gyre schola")]; + char FcConstFamilyNamePool_str3799[sizeof("itc bookman")]; + char FcConstFamilyNamePool_str3803[sizeof("fixedsys")]; + char FcConstFamilyNamePool_str3827[sizeof("stix two math")]; + char FcConstFamilyNamePool_str3835[sizeof("david clm")]; + char FcConstFamilyNamePool_str3838[sizeof("noto sans khojki")]; + char FcConstFamilyNamePool_str3844[sizeof("lohit telugu")]; + char FcConstFamilyNamePool_str3849[sizeof("vazirmatn nl")]; + char FcConstFamilyNamePool_str3853[sizeof("traditional arabic")]; + char FcConstFamilyNamePool_str3866[sizeof("noto sans kayah li")]; + char FcConstFamilyNamePool_str3867[sizeof("trebuchet ms")]; + char FcConstFamilyNamePool_str3878[sizeof("noto sans bamum")]; + char FcConstFamilyNamePool_str3880[sizeof("univers")]; + char FcConstFamilyNamePool_str3881[sizeof("vazirmatn rd")]; + char FcConstFamilyNamePool_str3890[sizeof("noto sans tifinagh hawad")]; + char FcConstFamilyNamePool_str3895[sizeof("noto sans brahmi")]; + char FcConstFamilyNamePool_str3900[sizeof("sparks dot extrasmall")]; + char FcConstFamilyNamePool_str3901[sizeof("zapfino")]; + char FcConstFamilyNamePool_str3927[sizeof("yehudaclm")]; + char FcConstFamilyNamePool_str3937[sizeof("gillius adf")]; + char FcConstFamilyNamePool_str3939[sizeof("ethiopic washra")]; + char FcConstFamilyNamePool_str3941[sizeof("noto serif yezidi")]; + char FcConstFamilyNamePool_str3943[sizeof("ar pl new sung mono")]; + char FcConstFamilyNamePool_str3961[sizeof("noto sans devanagari")]; + char FcConstFamilyNamePool_str3963[sizeof("unpenheulim")]; + char FcConstFamilyNamePool_str3964[sizeof("noto sans devanagari ui")]; + char FcConstFamilyNamePool_str3992[sizeof("arundina serif")]; + char FcConstFamilyNamePool_str3998[sizeof("baskerville")]; + char FcConstFamilyNamePool_str4002[sizeof("fixed")]; + char FcConstFamilyNamePool_str4005[sizeof("droid sans ethiopic")]; + char FcConstFamilyNamePool_str4008[sizeof("sf pro rounded")]; + char FcConstFamilyNamePool_str4010[sizeof("sparks dot extralarge")]; + char FcConstFamilyNamePool_str4013[sizeof("roboto condensed")]; + char FcConstFamilyNamePool_str4019[sizeof("noto serif malayalam")]; + char FcConstFamilyNamePool_str4028[sizeof("noto sans mono cjk hk")]; + char FcConstFamilyNamePool_str4034[sizeof("noto sans arabic ui")]; + char FcConstFamilyNamePool_str4054[sizeof("keyfont v2")]; + char FcConstFamilyNamePool_str4056[sizeof("gfs bodoni classic")]; + char FcConstFamilyNamePool_str4063[sizeof("bpg utf8 m")]; + char FcConstFamilyNamePool_str4064[sizeof("saysettha unicode")]; + char FcConstFamilyNamePool_str4068[sizeof("padauk")]; + char FcConstFamilyNamePool_str4072[sizeof("navilu")]; + char FcConstFamilyNamePool_str4078[sizeof("noto naskh arabic ui")]; + char FcConstFamilyNamePool_str4080[sizeof("source han serif kr")]; + char FcConstFamilyNamePool_str4088[sizeof("noto serif cjk sc")]; + char FcConstFamilyNamePool_str4091[sizeof("unvada")]; + char FcConstFamilyNamePool_str4097[sizeof("noto sans shavian")]; + char FcConstFamilyNamePool_str4102[sizeof("pcfont z")]; + char FcConstFamilyNamePool_str4106[sizeof("ume p mincho")]; + char FcConstFamilyNamePool_str4110[sizeof("noto serif cjk tc")]; + char FcConstFamilyNamePool_str4114[sizeof("spark dot-line extrathick")]; + char FcConstFamilyNamePool_str4137[sizeof("stix")]; + char FcConstFamilyNamePool_str4141[sizeof("gentium plus compact")]; + char FcConstFamilyNamePool_str4143[sizeof("noto naskh arabic")]; + char FcConstFamilyNamePool_str4145[sizeof("vazirmatn ui")]; + char FcConstFamilyNamePool_str4158[sizeof("raleway")]; + char FcConstFamilyNamePool_str4161[sizeof("vazirmatn rd nl")]; + char FcConstFamilyNamePool_str4164[sizeof("apple color emoji")]; + char FcConstFamilyNamePool_str4174[sizeof("noto serif gujarati")]; + char FcConstFamilyNamePool_str4176[sizeof("ar pl new sung")]; + char FcConstFamilyNamePool_str4178[sizeof("inconsolata bold")]; + char FcConstFamilyNamePool_str4180[sizeof("ume p mincho s3")]; + char FcConstFamilyNamePool_str4184[sizeof("ume p gothic o5")]; + char FcConstFamilyNamePool_str4188[sizeof("ume p gothic s4")]; + char FcConstFamilyNamePool_str4189[sizeof("haettenschweiler")]; + char FcConstFamilyNamePool_str4192[sizeof("ume p gothic s5")]; + char FcConstFamilyNamePool_str4201[sizeof("krungthep")]; + char FcConstFamilyNamePool_str4209[sizeof("entypo")]; + char FcConstFamilyNamePool_str4212[sizeof("ume p gothic")]; + char FcConstFamilyNamePool_str4218[sizeof("pmingliu")]; + char FcConstFamilyNamePool_str4225[sizeof("brandon grotesque")]; + char FcConstFamilyNamePool_str4228[sizeof("frank ruehl")]; + char FcConstFamilyNamePool_str4230[sizeof("linux biolinum")]; + char FcConstFamilyNamePool_str4234[sizeof("urw gothic")]; + char FcConstFamilyNamePool_str4243[sizeof("helvetica")]; + char FcConstFamilyNamePool_str4248[sizeof("ar pl zenkai uni")]; + char FcConstFamilyNamePool_str4250[sizeof("nimbus mono l")]; + char FcConstFamilyNamePool_str4257[sizeof("lohit gurmukhi")]; + char FcConstFamilyNamePool_str4259[sizeof("noto sans pau cin hau")]; + char FcConstFamilyNamePool_str4263[sizeof("nimbus sans l")]; + char FcConstFamilyNamePool_str4280[sizeof("vollkorn")]; + char FcConstFamilyNamePool_str4286[sizeof("ume p gothic c4")]; + char FcConstFamilyNamePool_str4290[sizeof("ume p gothic c5")]; + char FcConstFamilyNamePool_str4291[sizeof("rit meera new")]; + char FcConstFamilyNamePool_str4292[sizeof("kacstdecorative")]; + char FcConstFamilyNamePool_str4305[sizeof("overpass nerd font")]; + char FcConstFamilyNamePool_str4307[sizeof("antykwatorunska")]; + char FcConstFamilyNamePool_str4317[sizeof("noto sans syriac western")]; + char FcConstFamilyNamePool_str4318[sizeof("noto sans ethiopic ui")]; + char FcConstFamilyNamePool_str4324[sizeof("microsoft yahei")]; + char FcConstFamilyNamePool_str4329[sizeof("tex gyre chorus")]; + char FcConstFamilyNamePool_str4332[sizeof("noto sans buginese")]; + char FcConstFamilyNamePool_str4336[sizeof("rubik")]; + char FcConstFamilyNamePool_str4337[sizeof("apple sd gothic neo")]; + char FcConstFamilyNamePool_str4357[sizeof("nimbus roman no9 l")]; + char FcConstFamilyNamePool_str4361[sizeof("im writing nerd font mono")]; + char FcConstFamilyNamePool_str4381[sizeof("biaukai")]; + char FcConstFamilyNamePool_str4386[sizeof("im writing nerd font")]; + char FcConstFamilyNamePool_str4390[sizeof("unbatang")]; + char FcConstFamilyNamePool_str4396[sizeof("stix two text")]; + char FcConstFamilyNamePool_str4417[sizeof("jetbrains mono")]; + char FcConstFamilyNamePool_str4427[sizeof("droid sans devanagari")]; + char FcConstFamilyNamePool_str4432[sizeof("antykwatorunska medium")]; + char FcConstFamilyNamePool_str4438[sizeof("frank ruehl clm")]; + char FcConstFamilyNamePool_str4443[sizeof("gentium book basic")]; + char FcConstFamilyNamePool_str4448[sizeof("armnet helvetica")]; + char FcConstFamilyNamePool_str4455[sizeof("droid sans japanese")]; + char FcConstFamilyNamePool_str4457[sizeof("vazirmatn rd ui")]; + char FcConstFamilyNamePool_str4461[sizeof("lilex nerd font")]; + char FcConstFamilyNamePool_str4467[sizeof("noto sans gurmukhi ui")]; + char FcConstFamilyNamePool_str4473[sizeof("arial hebrew")]; + char FcConstFamilyNamePool_str4477[sizeof("gfs complutum")]; + char FcConstFamilyNamePool_str4483[sizeof("tobecontinued")]; + char FcConstFamilyNamePool_str4485[sizeof("baekmuk batang")]; + char FcConstFamilyNamePool_str4486[sizeof("gelly")]; + char FcConstFamilyNamePool_str4500[sizeof("ibmplexmono nerd font")]; + char FcConstFamilyNamePool_str4506[sizeof("ibm plex mono")]; + char FcConstFamilyNamePool_str4507[sizeof("cordia new")]; + char FcConstFamilyNamePool_str4511[sizeof("book antiqua")]; + char FcConstFamilyNamePool_str4513[sizeof("khmer os bokor")]; + char FcConstFamilyNamePool_str4516[sizeof("umeplus gothic")]; + char FcConstFamilyNamePool_str4519[sizeof("antykwatorunskacond medium")]; + char FcConstFamilyNamePool_str4524[sizeof("ibm plex sans")]; + char FcConstFamilyNamePool_str4527[sizeof("aegyptus")]; + char FcConstFamilyNamePool_str4528[sizeof("goudy bookletter 1911")]; + char FcConstFamilyNamePool_str4544[sizeof("khmer os muol pali")]; + char FcConstFamilyNamePool_str4545[sizeof("antykwatorunskacond light")]; + char FcConstFamilyNamePool_str4550[sizeof("noto sans cypro minoan")]; + char FcConstFamilyNamePool_str4553[sizeof("daddytimemono nerd font")]; + char FcConstFamilyNamePool_str4557[sizeof("sf pro text")]; + char FcConstFamilyNamePool_str4559[sizeof("noto sans cypriot")]; + char FcConstFamilyNamePool_str4563[sizeof("noto sans batak")]; + char FcConstFamilyNamePool_str4569[sizeof("new peninim mt")]; + char FcConstFamilyNamePool_str4571[sizeof("baekmuk dotum")]; + char FcConstFamilyNamePool_str4572[sizeof("noto serif cjk kr")]; + char FcConstFamilyNamePool_str4576[sizeof("hiragino mincho pron")]; + char FcConstFamilyNamePool_str4591[sizeof("noto serif telugu")]; + char FcConstFamilyNamePool_str4593[sizeof("snap")]; + char FcConstFamilyNamePool_str4614[sizeof("fontawesome 7 brands")]; + char FcConstFamilyNamePool_str4616[sizeof("noto serif tibetan")]; + char FcConstFamilyNamePool_str4630[sizeof("lilex")]; + char FcConstFamilyNamePool_str4646[sizeof("umpush")]; + char FcConstFamilyNamePool_str4649[sizeof("perpetua")]; + char FcConstFamilyNamePool_str4666[sizeof("noto sans cjk hk")]; + char FcConstFamilyNamePool_str4671[sizeof("vazirmatn ui nl")]; + char FcConstFamilyNamePool_str4677[sizeof("pingfang sc")]; + char FcConstFamilyNamePool_str4684[sizeof("noto sans palmyrene")]; + char FcConstFamilyNamePool_str4688[sizeof("cambria math")]; + char FcConstFamilyNamePool_str4692[sizeof("hoefler text")]; + char FcConstFamilyNamePool_str4699[sizeof("pingfang tc")]; + char FcConstFamilyNamePool_str4706[sizeof("albany")]; + char FcConstFamilyNamePool_str4707[sizeof("noto kufi arabic")]; + char FcConstFamilyNamePool_str4725[sizeof("antykwatorunskacond")]; + char FcConstFamilyNamePool_str4732[sizeof("lucidatypewriter")]; + char FcConstFamilyNamePool_str4750[sizeof("noto sans javanese")]; + char FcConstFamilyNamePool_str4758[sizeof("dejavu sans")]; + char FcConstFamilyNamePool_str4762[sizeof("baekmuk gulim")]; + char FcConstFamilyNamePool_str4765[sizeof("lucida bright")]; + char FcConstFamilyNamePool_str4785[sizeof("anonymicepro nerd font mono")]; + char FcConstFamilyNamePool_str4810[sizeof("anonymicepro nerd font")]; + char FcConstFamilyNamePool_str4814[sizeof("petalumatext")]; + char FcConstFamilyNamePool_str4816[sizeof("noto serif balinese")]; + char FcConstFamilyNamePool_str4821[sizeof("biz udmincho")]; + char FcConstFamilyNamePool_str4833[sizeof("openmoji black")]; + char FcConstFamilyNamePool_str4846[sizeof("tagmukay")]; + char FcConstFamilyNamePool_str4848[sizeof("biz udpmincho")]; + char FcConstFamilyNamePool_str4849[sizeof("noto sans limbu")]; + char FcConstFamilyNamePool_str4870[sizeof("dejavu sans mono")]; + char FcConstFamilyNamePool_str4872[sizeof("sparks bar medium")]; + char FcConstFamilyNamePool_str4884[sizeof("d-din exp")]; + char FcConstFamilyNamePool_str4896[sizeof("umeplus p gothic")]; + char FcConstFamilyNamePool_str4897[sizeof("robotomono nerd font")]; + char FcConstFamilyNamePool_str4908[sizeof("noto serif ethiopic")]; + char FcConstFamilyNamePool_str4909[sizeof("bpg glaho international")]; + char FcConstFamilyNamePool_str4927[sizeof("biz udgothic")]; + char FcConstFamilyNamePool_str4931[sizeof("twentieth century")]; + char FcConstFamilyNamePool_str4945[sizeof("glisp")]; + char FcConstFamilyNamePool_str4953[sizeof("mukti narrow")]; + char FcConstFamilyNamePool_str4966[sizeof("agave nerd font")]; + char FcConstFamilyNamePool_str4970[sizeof("noto sans soyombo")]; + char FcConstFamilyNamePool_str4983[sizeof("vazirmatn rd ui nl")]; + char FcConstFamilyNamePool_str4985[sizeof("dejavusansmono nerd font")]; + char FcConstFamilyNamePool_str4986[sizeof("hiragino kaku gothic")]; + char FcConstFamilyNamePool_str5022[sizeof("iosevka nerd font")]; + char FcConstFamilyNamePool_str5025[sizeof("anonymous pro")]; + char FcConstFamilyNamePool_str5028[sizeof("bauhaus std")]; + char FcConstFamilyNamePool_str5038[sizeof("agave nerd font mono")]; + char FcConstFamilyNamePool_str5041[sizeof("microsoft jhenghei")]; + char FcConstFamilyNamePool_str5045[sizeof("iosevka nerd font mono")]; + char FcConstFamilyNamePool_str5057[sizeof("noto serif gurmukhi")]; + char FcConstFamilyNamePool_str5064[sizeof("envycoder")]; + char FcConstFamilyNamePool_str5067[sizeof("iosevkaterm nerd font")]; + char FcConstFamilyNamePool_str5070[sizeof("courier new")]; + char FcConstFamilyNamePool_str5081[sizeof("itc zapf chancery std")]; + char FcConstFamilyNamePool_str5087[sizeof("noto serif np hmong")]; + char FcConstFamilyNamePool_str5088[sizeof("noto sans khudawadi")]; + char FcConstFamilyNamePool_str5096[sizeof("vdrsymbols sans")]; + char FcConstFamilyNamePool_str5112[sizeof("noto serif bengali")]; + char FcConstFamilyNamePool_str5114[sizeof("noto sans buhid")]; + char FcConstFamilyNamePool_str5115[sizeof("applemyungjo")]; + char FcConstFamilyNamePool_str5132[sizeof("luxi serif")]; + char FcConstFamilyNamePool_str5138[sizeof("rit tn joy")]; + char FcConstFamilyNamePool_str5144[sizeof("pt serif")]; + char FcConstFamilyNamePool_str5146[sizeof("microsoft yahei ui")]; + char FcConstFamilyNamePool_str5149[sizeof("barlow")]; + char FcConstFamilyNamePool_str5156[sizeof("proggyclean nerd font")]; + char FcConstFamilyNamePool_str5164[sizeof("sourcecodepro nerd font")]; + char FcConstFamilyNamePool_str5167[sizeof("petalumascript")]; + char FcConstFamilyNamePool_str5176[sizeof("helvetica neue")]; + char FcConstFamilyNamePool_str5184[sizeof("victormono nerd font")]; + char FcConstFamilyNamePool_str5194[sizeof("helvetica lt std")]; + char FcConstFamilyNamePool_str5199[sizeof("petaluma script")]; + char FcConstFamilyNamePool_str5207[sizeof("youyuan")]; + char FcConstFamilyNamePool_str5212[sizeof("noto sans symbols")]; + char FcConstFamilyNamePool_str5225[sizeof("noto serif khojki")]; + char FcConstFamilyNamePool_str5240[sizeof("noto sans symbols 2")]; + char FcConstFamilyNamePool_str5253[sizeof("ar pl uming hk")]; + char FcConstFamilyNamePool_str5266[sizeof("anka/coder narrow")]; + char FcConstFamilyNamePool_str5311[sizeof("biz udpgothic")]; + char FcConstFamilyNamePool_str5330[sizeof("noto serif devanagari")]; + char FcConstFamilyNamePool_str5356[sizeof("new york")]; + char FcConstFamilyNamePool_str5382[sizeof("proggytinyttsz")]; + char FcConstFamilyNamePool_str5404[sizeof("source han serif tw")]; + char FcConstFamilyNamePool_str5426[sizeof("antykwatorunska light")]; + char FcConstFamilyNamePool_str5429[sizeof("liberation sans narrow")]; + char FcConstFamilyNamePool_str5485[sizeof("public sans")]; + char FcConstFamilyNamePool_str5535[sizeof("noto sans tagbanwa")]; + char FcConstFamilyNamePool_str5594[sizeof("laconic-shadow")]; + char FcConstFamilyNamePool_str5599[sizeof("adobe caslon pro")]; + char FcConstFamilyNamePool_str5600[sizeof("noto sans egyptian hieroglyphs")]; + char FcConstFamilyNamePool_str5606[sizeof("ar pl ukai hk")]; + char FcConstFamilyNamePool_str5609[sizeof("khmer os siemreap")]; + char FcConstFamilyNamePool_str5611[sizeof("noto sans vithkuqi")]; + char FcConstFamilyNamePool_str5624[sizeof("profont nerd font")]; + char FcConstFamilyNamePool_str5632[sizeof("noto sans duployan")]; + char FcConstFamilyNamePool_str5662[sizeof("adobe garamond pro")]; + char FcConstFamilyNamePool_str5698[sizeof("beteckna lower case")]; + char FcConstFamilyNamePool_str5703[sizeof("segoe ui symbol")]; + char FcConstFamilyNamePool_str5709[sizeof("saab")]; + char FcConstFamilyNamePool_str5710[sizeof("heavydata")]; + char FcConstFamilyNamePool_str5729[sizeof("tribun adf std")]; + char FcConstFamilyNamePool_str5731[sizeof("goudy old style")]; + char FcConstFamilyNamePool_str5735[sizeof("libre caslon text")]; + char FcConstFamilyNamePool_str5738[sizeof("joypixels")]; + char FcConstFamilyNamePool_str5755[sizeof("tex gyre pagella")]; + char FcConstFamilyNamePool_str5789[sizeof("wenquanyi micro hei")]; + char FcConstFamilyNamePool_str5820[sizeof("microsoft jhenghei ui")]; + char FcConstFamilyNamePool_str5824[sizeof("wenquanyi micro hei mono")]; + char FcConstFamilyNamePool_str5850[sizeof("wenquanyi zen hei")]; + char FcConstFamilyNamePool_str5870[sizeof("noto serif old uyghur")]; + char FcConstFamilyNamePool_str5887[sizeof("paktype tehreer")]; + char FcConstFamilyNamePool_str5900[sizeof("ar pl shanheisun uni")]; + char FcConstFamilyNamePool_str5925[sizeof("fkp")]; + char FcConstFamilyNamePool_str5936[sizeof("caskaydiacove nerd font mono")]; + char FcConstFamilyNamePool_str5961[sizeof("caskaydiacove nerd font")]; + char FcConstFamilyNamePool_str5975[sizeof("noto sans phags pa")]; + char FcConstFamilyNamePool_str5982[sizeof("yanone kaffeesatz")]; + char FcConstFamilyNamePool_str5984[sizeof("droid arabic naskh")]; + char FcConstFamilyNamePool_str5999[sizeof("tex gyre adventor")]; + char FcConstFamilyNamePool_str6031[sizeof("source han sans tw")]; + char FcConstFamilyNamePool_str6038[sizeof("sophia nubian")]; + char FcConstFamilyNamePool_str6048[sizeof("gubbi")]; + char FcConstFamilyNamePool_str6053[sizeof("noto serif cjk hk")]; + char FcConstFamilyNamePool_str6062[sizeof("simplified arabic")]; + char FcConstFamilyNamePool_str6083[sizeof("sparks bar wide")]; + char FcConstFamilyNamePool_str6084[sizeof("nimbus mono ps")]; + char FcConstFamilyNamePool_str6096[sizeof("liberation serif")]; + char FcConstFamilyNamePool_str6108[sizeof("gb_ss_gb18030_extended")]; + char FcConstFamilyNamePool_str6112[sizeof("silkscreen expanded")]; + char FcConstFamilyNamePool_str6123[sizeof("noto sans mono cjk jp")]; + char FcConstFamilyNamePool_str6125[sizeof("noto sans bhaiksuki")]; + char FcConstFamilyNamePool_str6127[sizeof("lohit punjabi")]; + char FcConstFamilyNamePool_str6140[sizeof("beteckna small caps")]; + char FcConstFamilyNamePool_str6147[sizeof("scheherazade new")]; + char FcConstFamilyNamePool_str6176[sizeof("b davat")]; + char FcConstFamilyNamePool_str6185[sizeof("jetbrainsmono nerd font")]; + char FcConstFamilyNamePool_str6190[sizeof("arabic typesetting")]; + char FcConstFamilyNamePool_str6226[sizeof("tex gyre bonum")]; + char FcConstFamilyNamePool_str6227[sizeof("noto sans linear b")]; + char FcConstFamilyNamePool_str6241[sizeof("bitstream vera sans")]; + char FcConstFamilyNamePool_str6263[sizeof("bitstream vera sans mono")]; + char FcConstFamilyNamePool_str6272[sizeof("andika new basic")]; + char FcConstFamilyNamePool_str6275[sizeof("droid sans fallback")]; + char FcConstFamilyNamePool_str6300[sizeof("bitstreamverasansmono nerd font")]; + char FcConstFamilyNamePool_str6316[sizeof("pt serif caption")]; + char FcConstFamilyNamePool_str6333[sizeof("inter display")]; + char FcConstFamilyNamePool_str6452[sizeof("urw bookman")]; + char FcConstFamilyNamePool_str6456[sizeof("tuffy")]; + char FcConstFamilyNamePool_str6512[sizeof("zilla slab highlight")]; + char FcConstFamilyNamePool_str6534[sizeof("droid arabic kufi")]; + char FcConstFamilyNamePool_str6553[sizeof("ar pl mingti2l big5")]; + char FcConstFamilyNamePool_str6557[sizeof("paktype naqsh")]; + char FcConstFamilyNamePool_str6578[sizeof("gb_ss_gb18030_extendedk")]; + char FcConstFamilyNamePool_str6584[sizeof("dejavusansm nerd font")]; + char FcConstFamilyNamePool_str6631[sizeof("zilla slab")]; + char FcConstFamilyNamePool_str6642[sizeof("pingfang hk")]; + char FcConstFamilyNamePool_str6655[sizeof("bravura")]; + char FcConstFamilyNamePool_str6660[sizeof("noto sans display")]; + char FcConstFamilyNamePool_str6708[sizeof("vl pgothic")]; + char FcConstFamilyNamePool_str6745[sizeof("noto sans hebrew ui")]; + char FcConstFamilyNamePool_str6761[sizeof("copperplate gothic std")]; + char FcConstFamilyNamePool_str6863[sizeof("poppins")]; + char FcConstFamilyNamePool_str6924[sizeof("bigblueterminal")]; + char FcConstFamilyNamePool_str6927[sizeof("envycoder nerd font")]; + char FcConstFamilyNamePool_str6943[sizeof("source han serif jp")]; + char FcConstFamilyNamePool_str6948[sizeof("noto sans bassa vah")]; + char FcConstFamilyNamePool_str6980[sizeof("noto serif vithkuqi")]; + char FcConstFamilyNamePool_str7088[sizeof("bigblueterminal nerd font")]; + char FcConstFamilyNamePool_str7089[sizeof("khmer os battambang")]; + char FcConstFamilyNamePool_str7100[sizeof("ar pl uming tw")]; + char FcConstFamilyNamePool_str7162[sizeof("palatino linotype")]; + char FcConstFamilyNamePool_str7204[sizeof("source code vf")]; + char FcConstFamilyNamePool_str7274[sizeof("ibm plex serif")]; + char FcConstFamilyNamePool_str7282[sizeof("noto sans pahawh hmong")]; + char FcConstFamilyNamePool_str7352[sizeof("hiragino sans gb")]; + char FcConstFamilyNamePool_str7354[sizeof("red hat display")]; + char FcConstFamilyNamePool_str7405[sizeof("ektype baloo 2")]; + char FcConstFamilyNamePool_str7415[sizeof("bonvenocf")]; + char FcConstFamilyNamePool_str7453[sizeof("ar pl ukai tw")]; + char FcConstFamilyNamePool_str7457[sizeof("proxima nova")]; + char FcConstFamilyNamePool_str7485[sizeof("dejavu serif")]; + char FcConstFamilyNamePool_str7556[sizeof("ektype baloo tamma 2")]; + char FcConstFamilyNamePool_str7573[sizeof("heavydata nerd font")]; + char FcConstFamilyNamePool_str7579[sizeof("libre baskerville")]; + char FcConstFamilyNamePool_str7611[sizeof("gfs baskerville")]; + char FcConstFamilyNamePool_str7656[sizeof("padauk book")]; + char FcConstFamilyNamePool_str7717[sizeof("ektype baloo da 2")]; + char FcConstFamilyNamePool_str7815[sizeof("source han sans jp")]; + char FcConstFamilyNamePool_str7842[sizeof("sparks bar narrow")]; + char FcConstFamilyNamePool_str7947[sizeof("noto sans hebrew")]; + char FcConstFamilyNamePool_str7958[sizeof("sparks bar extranarrow")]; + char FcConstFamilyNamePool_str7979[sizeof("noto rashi hebrew")]; + char FcConstFamilyNamePool_str8002[sizeof("sparks bar extrawide")]; + char FcConstFamilyNamePool_str8036[sizeof("unikurd web")]; + char FcConstFamilyNamePool_str8047[sizeof("noto serif display")]; + char FcConstFamilyNamePool_str8146[sizeof("hapax berb\303\250re")]; + char FcConstFamilyNamePool_str8174[sizeof("source han code jp")]; + char FcConstFamilyNamePool_str8293[sizeof("be vietnam pro")]; + char FcConstFamilyNamePool_str8297[sizeof("noto sans cjk jp")]; + char FcConstFamilyNamePool_str8431[sizeof("droid sans hebrew")]; + char FcConstFamilyNamePool_str8465[sizeof("ektype baloo chettan 2")]; + char FcConstFamilyNamePool_str8639[sizeof("roboto slab")]; + char FcConstFamilyNamePool_str8822[sizeof("sf pro display")]; + char FcConstFamilyNamePool_str8840[sizeof("bravuratext")]; + char FcConstFamilyNamePool_str8911[sizeof("finale broadway text")]; + char FcConstFamilyNamePool_str8920[sizeof("wenquanyi zen hei sharp")]; + char FcConstFamilyNamePool_str9004[sizeof("bitstream vera serif")]; + char FcConstFamilyNamePool_str9058[sizeof("ektype baloo tammudu 2")]; + char FcConstFamilyNamePool_str9334[sizeof("noto serif hebrew")]; + char FcConstFamilyNamePool_str9480[sizeof("paktype naskh basic wide")]; + char FcConstFamilyNamePool_str9485[sizeof("paktype naskh basic semi wide")]; + char FcConstFamilyNamePool_str9536[sizeof("paktype naskh basic")]; + char FcConstFamilyNamePool_str9684[sizeof("noto serif cjk jp")]; + char FcConstFamilyNamePool_str10060[sizeof("ar pl sungtil gb")]; + char FcConstFamilyNamePool_str10341[sizeof("wenquanyi bitmap song")]; + char FcConstFamilyNamePool_str10494[sizeof("finale broadway")]; + char FcConstFamilyNamePool_str10575[sizeof("m yuppy gb")]; + char FcConstFamilyNamePool_str11056[sizeof("ektype baloo bhai 2")]; + char FcConstFamilyNamePool_str11076[sizeof("ektype baloo bhaina 2")]; + char FcConstFamilyNamePool_str11085[sizeof("ektype baloo paaji 2")]; + char FcConstFamilyNamePool_str11119[sizeof("ektype baloo thambi 2")]; + char FcConstFamilyNamePool_str12005[sizeof("playfair display")]; + }; +static const struct FcConstFamilyNamePool_t FcConstFamilyNamePool_contents = + { + "sina", + "sora", + "amiri", + "raanana", + "asea", + "aroania", + "norasi", + "arimo", + "nsimsun", + "m+ 1mn", + "nasim", + "avenir", + "m+ 1m", + "mononoki", + "meera", + "sf mono", + "nunito", + "manrope", + "m+ 2m", + "mitra", + "optima", + "titr", + "anorexia", + "nirmala ui", + "ibm 3270", + "inter", + "exo 2", + "tinos", + "shimenkan", + "open sans", + "mint mono", + "noto sans", + "miriam mono", + "terminus", + "noto emoji", + "times", + "smoothansi", + "c059", + "\357\275\215\357\275\223 \346\230\216\346\234\235", + "mrs eaves", + "museo sans", + "cairo", + "monaco", + "nunito sans", + "musica", + "clean", + "cure", + "zar", + "mint mono 35", + "charter", + "console", + "operator mono", + "clarendon", + "montserrat", + "noto sans mro", + "consolas", + "z003", + "spacemono", + "aharoniclm", + "miriam clm", + "cormorant", + "noto sans miao", + "noto sans mono", + "\357\275\215\357\275\223 \343\202\264\343\202\267\343\203\203\343\202\257", + "tiza", + "space mono", + "clear sans", + "crimson pro", + "eczar", + "lora", + "muli", + "loma", + "commissioner", + "dror", + "constantia", + "menlo", + "avdira", + "madan", + "lato", + "monoid", + "meslo", + "times new roman", + "monolisa", + "lime", + "madan2", + "sharetechmono", + "mnmlicons", + "dm sans", + "analecta", + "noto sans armenian", + "zysong18030", + "lotoos", + "smonohand", + "itc stone sans", + "notcouriersans", + "noto sans samaritan", + "molot", + "literata", + "noto sans masaram gondi", + "thorndale", + "noto music", + "dustismo", + "noto sans carian", + "epilogue", + "din next", + "comic neue", + "carlito", + "irannastaliq", + "cascadia mono", + "caslon", + "go mono", + "candara", + "aegean", + "stsong", + "cardo", + "tunga", + "simsong", + "comic sans ms", + "gfs olga", + "alegreya", + "noto sans lao", + "segoe ui", + "comicshannsmono", + "awami nastaliq", + "edges", + "nazli", + "geist", + "code2001", + "elliniaclm", + "gfs ignacio", + "noto sans modi", + "intel one mono", + "geist mono", + "code2000", + "inconsolata", + "gfs ambrosia", + "thorndale amt", + "laconic", + "gfs solomos", + "arial", + "codenewroman", + "ipagothic", + "ms gothic", + "d-din", + "gfs artemisia", + "alegreya sans", + "great vibes", + "openmoji color", + "latin modern roman", + "gfs nicefore", + "noto sans linear a", + "ezra sil", + "miriam mono clm", + "terminal", + "songti sc", + "noto sans tai le", + "noto sans meroitic", + "songti tc", + "andale mono", + "material icons", + "mingzat", + "droid sans", + "didot", + "geeza pro", + "mangal", + "gfs theokritos", + "gulim", + "mints mild", + "caladea", + "noto sans osage", + "noto sans tangsa", + "sniglet", + "domestic manners", + "charis sil", + "cantarell", + "noto sans deseret", + "gfs eustace", + "montserrat alternates", + "latin modern roman caps", + "gfs didot", + "spectral", + "noto sans indic siyaq numbers", + "gargi", + "lalezar", + "droid sans mono", + "georgia", + "noto sans sora sompeng", + "noto sans adlam", + "noto sans tamil", + "nu", + "noto sans mandaic", + "leland", + "gentium basic", + "kinnari", + "gfs gazis", + "kamran", + "stkaiti", + "aqui", + "arial unicode", + "cascadia code", + "kaiti", + "droid sans armenian", + "crete round", + "kartika", + "mukti", + "homa", + "khmer ui", + "anaktoria", + "gfs galatea", + "hanamin", + "latin modern roman demi", + "arshia", + "simsun", + "comicshannsmono nerd font", + "khmer os", + "latin modern roman slanted", + "kates", + "harmattan", + "ipamincho", + "shruti", + "stheiti", + "noto sans old north arabian", + "elham", + "hermit", + "simhei", + "arial unicode ms", + "ms mincho", + "tahoma", + "mukta vaani", + "amiri quran", + "leelawadee", + "inconsolatago", + "mukta malar", + "noto sans sogdian", + "noto sans mongolian", + "gill sans", + "mints strong", + "inconsolata go", + "noto sans nandinagari", + "garamond", + "noto sans canadian aboriginal", + "courier", + "noto sans nko", + "rit rachana", + "rachana", + "archivo", + "noto sans ui", + "merriweather", + "kacstpen", + "mukta mahee", + "kacstqurn", + "kacst-qr", + "kacstqura", + "cousine", + "codenewroman nerd font mono", + "kacstfarsi", + "eb garamond", + "codenewroman nerd font", + "noto sans takri", + "kacstone", + "kalinga", + "noto sans georgian", + "karla", + "manchu2005", + "ume mincho", + "kacstscreen", + "kacstart", + "andika", + "alkalami", + "kacstposter", + "noto sans thai", + "untaza", + "akkadian", + "lekton", + "tscu_paranar", + "dank mono", + "kacstletter", + "kacsttitle", + "lao ui", + "share tech mono", + "anka/coder", + "ipamonamincho", + "source sans 3", + "latin modern roman dunhill", + "noto sans hatran", + "noto sans thaana", + "mplus", + "nuosu sil", + "hasida", + "merriweather sans", + "ume mincho s3", + "silkscreen", + "undotum", + "dotum", + "noto sans armenian ui", + "noto sans cham", + "nanumgothic", + "titillium", + "quicksand", + "noto sans tai tham", + "lucida console", + "red hat mono", + "raghindi", + "gautami", + "grand hotel", + "noto sans marchen", + "arundina sans", + "gotham", + "khmer os content", + "noto sans runic", + "noto sans chorasmian", + "droid sans tamil", + "noto sans manichaean", + "noto sans kannada", + "noto sans lao ui", + "aurulentsansmono", + "uniol", + "ungraphic", + "sazanami mincho", + "noto sans kannada ui", + "noto sans old italic", + "noto sans sinhala", + "hiragino sans", + "arundina sans mono", + "noto sans multani", + "lohit assamese", + "noto sans sharada", + "noto sans caucasian albanian", + "mukta devanagari", + "noto sans tamil ui", + "inconsolatalgc", + "noto sans sinhala ui", + "noto sans mende kikakui", + "noto traditional nushu", + "jura", + "noto sans ogham", + "aurulentsansmono nerd font", + "lohit odia", + "noto sans sundanese", + "mingliu", + "lohit hindi", + "garuda", + "hadasim clm", + "inconsolatalgc nerd font", + "noto sans old sogdian", + "gfs decker", + "caladingsclm", + "nachlieli", + "lohit nepali", + "noto sans grantha", + "gfs didot classic", + "monofur", + "trade gothic", + "lohit kannada", + "shofar", + "fira mono", + "emoji one", + "ff meta", + "fira sans", + "\303\251colier court", + "droid sans georgian", + "fantezi", + "reem kufi", + "d-din condensed", + "outfit", + "kerkis", + "freemono", + "kacsttitlel", + "hiragino sans cns", + "droid sans thai", + "courier std", + "keter yg", + "gentium plus", + "ipamonagothic", + "freesans", + "artsounk", + "noto sans tagalog", + "comfortaa", + "noto sans siddham", + "ff scala", + "noto looped lao ui", + "fontawesome", + "latin modern roman unslanted", + "stam ashkenaz clm", + "farnaz", + "lohit devanagari", + "lohit tamil", + "heuristica", + "noto sans gothic", + "gfs g\303\266schen", + "noto sans old south arabian", + "darkgarden", + "asana math", + "amiri quran colored", + "3270 nerd font", + "noto sans thai looped", + "jomolhari", + "segoe ui historic", + "noto sans ugaritic", + "terminus (ttf)", + "kacstbook", + "san francisco", + "ff din", + "ferdosi", + "leelawadee ui", + "noto fangsong kss rotated", + "montserrat underline", + "noto sans nag mundari", + "noto fangsong kss vertical", + "lpfont", + "noto serif toto", + "noto serif armenian", + "minion math", + "3270 nerd font mono", + "noto sans glagolitic", + "kokila", + "fira code", + "jg laotimes", + "drift", + "lateef", + "koodak", + "sazanami gothic", + "android emoji", + "noto sans khmer", + "lohit bengali", + "noto sans georgian ui", + "noto sans kaithi", + "lisu", + "noto serif ottoman siyaq", + "space grotesk", + "noto sans math", + "figtree", + "noto sans hanunoo", + "noto sans adlam unjoined", + "noto serif lao", + "roya", + "kacstdigital", + "sparks dot large", + "noto sans thai ui", + "gfs garaldus", + "signfont", + "nachlieli clm", + "noto color emoji", + "comic neue angular", + "meiryo", + "noto sans chakma", + "source han mono", + "noto sans tirhuta", + "ms ui gothic", + "lohit konkani", + "segoe ui emoji", + "monoid nerd font", + "noto sans saurashtra", + "arimo nerd font", + "gf zemen unicode", + "lklug", + "sparks dot small", + "ungungseo", + "tinos nerd font", + "nafees nastaleeq", + "twitter color emoji", + "mononoki nerd font", + "noto sans yi", + "noto sans lisu", + "lohit kashmiri", + "inconsolata regular", + "ibm 3270 nerd font", + "lohit marathi", + "terminess nerd font", + "noto sans cherokee", + "lohit gujarati", + "lucida sans unicode", + "namdhinggo sil", + "notomono nerd font", + "gfs neohellenic", + "gfs orpheus", + "noto sans oriya", + "spark dot-line thin", + "source han sans cn", + "edwin", + "spacemono nerd font", + "noto sans myanmar", + "noto sans osmanya", + "century gothic", + "latin modern math", + "hasklig", + "jadid", + "sharetechmono nerd font", + "malayalam", + "anka/coder condensed", + "waree", + "noto serif tamil", + "noto sans ol chiki", + "noto sans myanmar ui", + "khmer os muol", + "noto looped thai ui", + "stfangsong", + "alexander", + "gfs orpheus sans", + "adwaita mono", + "meslo nerd font", + "yudit", + "source han mono sc", + "ipaex\346\230\216\346\234\235", + "nanumgothiccoding", + "terafik", + "adwaita sans", + "ume gothic o5", + "lohit sindhi", + "ume gothic s4", + "source han mono tc", + "nanumgothic_coding", + "ume gothic s5", + "fangsong ti", + "unjamosora", + "signfont z", + "ume gothic", + "futura", + "stam sefarad clm", + "noto serif dogra", + "avenir next", + "noto serif tamil slanted", + "frutiger", + "noto sans medefaidrin", + "ia writer mono", + "lohit maithili", + "gomono nerd font", + "emojione mozilla", + "noto sans newa", + "ipaex\343\202\264\343\202\267\343\203\203\343\202\257", + "news cycle", + "lucida math", + "ume gothic c4", + "ume gothic c5", + "noto sans rejang", + "oxygen mono", + "noto sans syriac eastern", + "noto sans syriac", + "sparks dot medium", + "go mono nerd font", + "spark dot-line medium", + "oxygen-sans", + "p052", + "geistmono nerd font", + "yu gothic", + "pt mono", + "sf pro", + "inconsolata nerd font", + "motoyalcedar", + "pt sans", + "luxi mono", + "plantin", + "hack", + "luxi sans", + "sampige", + "ubuntu", + "myriad pro", + "minion pro", + "noto serif georgian", + "unshinmun", + "overpass", + "sathu", + "crimson text", + "news gothic", + "noto sans lycian", + "noto serif ahom", + "noto sans mahajani", + "noto serif makasar", + "noto serif thai", + "ipaexgothic", + "fantasquesansmono", + "campania", + "prociono", + "source serif 4", + "impact", + "drugulinclm", + "fangsong", + "droidsansmono nerd font", + "tlwgmono", + "overpass mono", + "ipapmincho", + "abyssinica sil", + "perizia", + "tlwgtypo", + "droidsansm nerd font", + "jg lao old arial", + "accanthis adf std", + "kacstoffice", + "gfs jackson", + "kacstnaskh", + "ukij tuz", + "noto sans lydian", + "noto sans old turkic", + "oswald", + "fantasquesansmono nerd font", + "padmaa", + "din pro", + "noto sans elymaic", + "tlwgtypist", + "noto sans cuneiform", + "lexend", + "khmer os metal chrieng", + "noto sans malayalam", + "noto sans khmer ui", + "undinaru", + "petaluma", + "palatino", + "noto sans malayalam ui", + "old standard sfd", + "nanummyeongjo", + "kochi mincho", + "noto sans mono cjk sc", + "noto sans kharoshthi", + "gfs orpheus classic", + "noto serif kannada", + "meiryo ui", + "yudit unicode", + "noto sans mono cjk tc", + "gohu", + "noto sans cjk sc", + "source han sans kr", + "yu mincho", + "akzidenz grotesk", + "pigiarniq", + "ubuntu condensed", + "tlwgtypewriter", + "inconsolatago nerd font", + "noto sans old hungarian", + "conakry", + "noto sans cjk tc", + "hurmit nerd font", + "noto serif sinhala", + "unjamonovel", + "leland text", + "noto serif todhri", + "mgopen canonica", + "gfs porson", + "daddytimemono", + "pragmatapro", + "simple clm", + "kochi gothic", + "foundation icons", + "mgopen modata", + "tex gyre termes", + "gfs pyrsos", + "noto sans syloti nagri", + "noto sans inscriptional pahlavi", + "noto sans inscriptional parthian", + "noto sans gujarati", + "gfs fleischman", + "alef", + "rit keraleeyam", + "noto serif grantha", + "work sans", + "noto sans warang citi", + "noto sans tifinagh air", + "noto sans tifinagh adrar", + "cousine nerd font", + "noto sans tifinagh ahaggar", + "league gothic", + "noto sans tifinagh rhissa ixa", + "widelands", + "noto sans tifinagh agraw imazighen", + "malgun gothic", + "noto serif tangut", + "khmer os system", + "noto serif hentaigana", + "ms serif", + "noto sans tifinagh apt", + "freeserif", + "noto sans oriya ui", + "b612", + "opendyslexicmono", + "noto serif", + "sabon", + "infofont", + "opendyslexic", + "noto sans coptic", + "annapurna sil", + "lekton nerd font", + "symbola", + "noto sans psalter pahlavi", + "al bayan", + "unjamobatang", + "noto sans tifinagh tawellemmet", + "roboto", + "b612 mono", + "khmer mondulkiri", + "mplus nerd font", + "patrick hand", + "thonburi", + "source han mono hc", + "noto znamenny musical notation", + "noto sans mayan numerals", + "ipaexmincho", + "ms sans serif", + "tabassom", + "noto sans imperial aramaic", + "xits math", + "bitter", + "noto sans meetei mayek", + "dancing script", + "opendyslexicmono nerd font", + "hanyisong", + "albany amt", + "roboto mono", + "markazi text", + "cambria", + "unjamodotum", + "cooper std", + "noto sans gunjala gondi", + "avenir next condensed", + "itc bodoni", + "britannic", + "ume ui gothic o5", + "yu gothic ui", + "raavi", + "ume hy gothic o5", + "noto sans signwriting", + "beteckna", + "ume ui gothic", + "b compset", + "noto nastaliq urdu", + "ume hy gothic", + "noto sans tifinagh sil", + "letters laughing", + "bola", + "iosevka", + "unpen", + "badr", + "agave", + "itc stone serif", + "noto sans old persian", + "dubai", + "bodoni", + "ia writer quattro", + "vemana2000", + "agbalumo", + "noto sans cjk kr", + "unyetgul", + "noto serif khmer", + "input mono", + "fontawesome 7 free", + "noto sans wancho", + "noto sans telugu", + "gfs philostratos", + "charis sil compact", + "noto sans nabataean", + "cascadia mono pl", + "noto sans new tai lue", + "libertinus", + "iosevkaterm", + "noto sans vai", + "noto sans tifinagh ghat", + "cascadia mono nf", + "calibri", + "iosevka term", + "noto sans telugu ui", + "ia writer duo", + "elephant", + "noto sans mono cjk kr", + "pothana2000", + "infofont z", + "corbel", + "batang", + "opendyslexic nerd font", + "noto sans hanifi rohingya", + "victormono", + "gfs bodoni", + "victor mono", + "noto serif khitan small script", + "proggyclean", + "lohit malayalam", + "vazirmatn", + "red hat text", + "liberation mono", + "vrinda", + "verdana", + "noto sans arabic", + "liberation sans", + "linux libertine", + "noto sans old permic", + "unpilgia", + "inter variable", + "bellota", + "monofur nerd font", + "source han mono k", + "noto sans avestan", + "firamono nerd font", + "spark dot-line extrathin", + "gb_ss_gb18030", + "noto sans elbasan", + "droid serif", + "rockwell", + "stevehand", + "noto sans nko unjoined", + "khmer os muol light", + "linux libertine mono", + "sakkal majalla", + "tex gyre heros", + "noto sans tai viet", + "noto sans balinese", + "liberationmono nerd font", + "source han serif cn", + "urdu nastaliq unicode", + "noto serif oriya", + "emoji two", + "ubuntu nerd font", + "cumberland amt", + "digna's handwriting", + "new athena unicode", + "firacode nerd font", + "firacode nerd font mono", + "noto sans phoenician", + "motoyalmaru", + "noto serif myanmar", + "gohu nerd font", + "spark dot-line thick", + "tex gyre cursor", + "vl gothic", + "noto sans zanabazar square", + "cumberland", + "noto sans gujarati ui", + "noto sans lao looped", + "unifrakturmaguntia", + "cascadia code pl", + "ubuntumono nerd font", + "cascadia code nf", + "noto sans tifinagh", + "tex gyre heros cn", + "noto sans tifinagh azawagh", + "noto sans ethiopic", + "proggysquarettsz", + "delphine", + "franklin gothic", + "unbom", + "noto sans gurmukhi", + "apparatus sil", + "tai heritage pro", + "noto sans lepcha", + "tajawal", + "noto sans tamil supplement", + "khmer os fasthand", + "khmer os freehand", + "ipapgothic", + "noto sans bengali", + "hasklug nerd font", + "andika compact", + "dai banna sil", + "nimbus mono", + "pcfont", + "profont", + "nimbus roman", + "source code pro", + "nimbus sans", + "noto sans bengali ui", + "bauer bodoni", + "tex gyre schola", + "itc bookman", + "fixedsys", + "stix two math", + "david clm", + "noto sans khojki", + "lohit telugu", + "vazirmatn nl", + "traditional arabic", + "noto sans kayah li", + "trebuchet ms", + "noto sans bamum", + "univers", + "vazirmatn rd", + "noto sans tifinagh hawad", + "noto sans brahmi", + "sparks dot extrasmall", + "zapfino", + "yehudaclm", + "gillius adf", + "ethiopic washra", + "noto serif yezidi", + "ar pl new sung mono", + "noto sans devanagari", + "unpenheulim", + "noto sans devanagari ui", + "arundina serif", + "baskerville", + "fixed", + "droid sans ethiopic", + "sf pro rounded", + "sparks dot extralarge", + "roboto condensed", + "noto serif malayalam", + "noto sans mono cjk hk", + "noto sans arabic ui", + "keyfont v2", + "gfs bodoni classic", + "bpg utf8 m", + "saysettha unicode", + "padauk", + "navilu", + "noto naskh arabic ui", + "source han serif kr", + "noto serif cjk sc", + "unvada", + "noto sans shavian", + "pcfont z", + "ume p mincho", + "noto serif cjk tc", + "spark dot-line extrathick", + "stix", + "gentium plus compact", + "noto naskh arabic", + "vazirmatn ui", + "raleway", + "vazirmatn rd nl", + "apple color emoji", + "noto serif gujarati", + "ar pl new sung", + "inconsolata bold", + "ume p mincho s3", + "ume p gothic o5", + "ume p gothic s4", + "haettenschweiler", + "ume p gothic s5", + "krungthep", + "entypo", + "ume p gothic", + "pmingliu", + "brandon grotesque", + "frank ruehl", + "linux biolinum", + "urw gothic", + "helvetica", + "ar pl zenkai uni", + "nimbus mono l", + "lohit gurmukhi", + "noto sans pau cin hau", + "nimbus sans l", + "vollkorn", + "ume p gothic c4", + "ume p gothic c5", + "rit meera new", + "kacstdecorative", + "overpass nerd font", + "antykwatorunska", + "noto sans syriac western", + "noto sans ethiopic ui", + "microsoft yahei", + "tex gyre chorus", + "noto sans buginese", + "rubik", + "apple sd gothic neo", + "nimbus roman no9 l", + "im writing nerd font mono", + "biaukai", + "im writing nerd font", + "unbatang", + "stix two text", + "jetbrains mono", + "droid sans devanagari", + "antykwatorunska medium", + "frank ruehl clm", + "gentium book basic", + "armnet helvetica", + "droid sans japanese", + "vazirmatn rd ui", + "lilex nerd font", + "noto sans gurmukhi ui", + "arial hebrew", + "gfs complutum", + "tobecontinued", + "baekmuk batang", + "gelly", + "ibmplexmono nerd font", + "ibm plex mono", + "cordia new", + "book antiqua", + "khmer os bokor", + "umeplus gothic", + "antykwatorunskacond medium", + "ibm plex sans", + "aegyptus", + "goudy bookletter 1911", + "khmer os muol pali", + "antykwatorunskacond light", + "noto sans cypro minoan", + "daddytimemono nerd font", + "sf pro text", + "noto sans cypriot", + "noto sans batak", + "new peninim mt", + "baekmuk dotum", + "noto serif cjk kr", + "hiragino mincho pron", + "noto serif telugu", + "snap", + "fontawesome 7 brands", + "noto serif tibetan", + "lilex", + "umpush", + "perpetua", + "noto sans cjk hk", + "vazirmatn ui nl", + "pingfang sc", + "noto sans palmyrene", + "cambria math", + "hoefler text", + "pingfang tc", + "albany", + "noto kufi arabic", + "antykwatorunskacond", + "lucidatypewriter", + "noto sans javanese", + "dejavu sans", + "baekmuk gulim", + "lucida bright", + "anonymicepro nerd font mono", + "anonymicepro nerd font", + "petalumatext", + "noto serif balinese", + "biz udmincho", + "openmoji black", + "tagmukay", + "biz udpmincho", + "noto sans limbu", + "dejavu sans mono", + "sparks bar medium", + "d-din exp", + "umeplus p gothic", + "robotomono nerd font", + "noto serif ethiopic", + "bpg glaho international", + "biz udgothic", + "twentieth century", + "glisp", + "mukti narrow", + "agave nerd font", + "noto sans soyombo", + "vazirmatn rd ui nl", + "dejavusansmono nerd font", + "hiragino kaku gothic", + "iosevka nerd font", + "anonymous pro", + "bauhaus std", + "agave nerd font mono", + "microsoft jhenghei", + "iosevka nerd font mono", + "noto serif gurmukhi", + "envycoder", + "iosevkaterm nerd font", + "courier new", + "itc zapf chancery std", + "noto serif np hmong", + "noto sans khudawadi", + "vdrsymbols sans", + "noto serif bengali", + "noto sans buhid", + "applemyungjo", + "luxi serif", + "rit tn joy", + "pt serif", + "microsoft yahei ui", + "barlow", + "proggyclean nerd font", + "sourcecodepro nerd font", + "petalumascript", + "helvetica neue", + "victormono nerd font", + "helvetica lt std", + "petaluma script", + "youyuan", + "noto sans symbols", + "noto serif khojki", + "noto sans symbols 2", + "ar pl uming hk", + "anka/coder narrow", + "biz udpgothic", + "noto serif devanagari", + "new york", + "proggytinyttsz", + "source han serif tw", + "antykwatorunska light", + "liberation sans narrow", + "public sans", + "noto sans tagbanwa", + "laconic-shadow", + "adobe caslon pro", + "noto sans egyptian hieroglyphs", + "ar pl ukai hk", + "khmer os siemreap", + "noto sans vithkuqi", + "profont nerd font", + "noto sans duployan", + "adobe garamond pro", + "beteckna lower case", + "segoe ui symbol", + "saab", + "heavydata", + "tribun adf std", + "goudy old style", + "libre caslon text", + "joypixels", + "tex gyre pagella", + "wenquanyi micro hei", + "microsoft jhenghei ui", + "wenquanyi micro hei mono", + "wenquanyi zen hei", + "noto serif old uyghur", + "paktype tehreer", + "ar pl shanheisun uni", + "fkp", + "caskaydiacove nerd font mono", + "caskaydiacove nerd font", + "noto sans phags pa", + "yanone kaffeesatz", + "droid arabic naskh", + "tex gyre adventor", + "source han sans tw", + "sophia nubian", + "gubbi", + "noto serif cjk hk", + "simplified arabic", + "sparks bar wide", + "nimbus mono ps", + "liberation serif", + "gb_ss_gb18030_extended", + "silkscreen expanded", + "noto sans mono cjk jp", + "noto sans bhaiksuki", + "lohit punjabi", + "beteckna small caps", + "scheherazade new", + "b davat", + "jetbrainsmono nerd font", + "arabic typesetting", + "tex gyre bonum", + "noto sans linear b", + "bitstream vera sans", + "bitstream vera sans mono", + "andika new basic", + "droid sans fallback", + "bitstreamverasansmono nerd font", + "pt serif caption", + "inter display", + "urw bookman", + "tuffy", + "zilla slab highlight", + "droid arabic kufi", + "ar pl mingti2l big5", + "paktype naqsh", + "gb_ss_gb18030_extendedk", + "dejavusansm nerd font", + "zilla slab", + "pingfang hk", + "bravura", + "noto sans display", + "vl pgothic", + "noto sans hebrew ui", + "copperplate gothic std", + "poppins", + "bigblueterminal", + "envycoder nerd font", + "source han serif jp", + "noto sans bassa vah", + "noto serif vithkuqi", + "bigblueterminal nerd font", + "khmer os battambang", + "ar pl uming tw", + "palatino linotype", + "source code vf", + "ibm plex serif", + "noto sans pahawh hmong", + "hiragino sans gb", + "red hat display", + "ektype baloo 2", + "bonvenocf", + "ar pl ukai tw", + "proxima nova", + "dejavu serif", + "ektype baloo tamma 2", + "heavydata nerd font", + "libre baskerville", + "gfs baskerville", + "padauk book", + "ektype baloo da 2", + "source han sans jp", + "sparks bar narrow", + "noto sans hebrew", + "sparks bar extranarrow", + "noto rashi hebrew", + "sparks bar extrawide", + "unikurd web", + "noto serif display", + "hapax berb\303\250re", + "source han code jp", + "be vietnam pro", + "noto sans cjk jp", + "droid sans hebrew", + "ektype baloo chettan 2", + "roboto slab", + "sf pro display", + "bravuratext", + "finale broadway text", + "wenquanyi zen hei sharp", + "bitstream vera serif", + "ektype baloo tammudu 2", + "noto serif hebrew", + "paktype naskh basic wide", + "paktype naskh basic semi wide", + "paktype naskh basic", + "noto serif cjk jp", + "ar pl sungtil gb", + "wenquanyi bitmap song", + "finale broadway", + "m yuppy gb", + "ektype baloo bhai 2", + "ektype baloo bhaina 2", + "ektype baloo paaji 2", + "ektype baloo thambi 2", + "playfair display" + }; +#define FcConstFamilyNamePool ((const char *) &FcConstFamilyNamePool_contents) +const struct FcGenericFamilyEntry * +fc_generic_family_lookup (register const char *str, register size_t len) +{ +#if (defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 6) > 4) || (defined __clang__ && __clang_major__ >= 3) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + static const struct FcGenericFamilyEntry wordlist[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 1049 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str93, 0x00000002}, + {-1}, +#line 1057 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str95, 0x00000002}, + {-1}, {-1}, {-1}, +#line 53 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str99, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 994 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str105, 0x00000002}, + {-1}, +#line 108 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str107, 0x00000001}, +#line 101 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str108, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 675 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str113, 0x00000001}, + {-1}, +#line 98 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str115, 0x00000002}, + {-1}, {-1}, +#line 928 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str118, 0x00000004}, + {-1}, +#line 581 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str120, 0x00000004}, + {-1}, {-1}, {-1}, +#line 659 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str124, 0x00000002}, +#line 112 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str125, 0x00000002}, + {-1}, +#line 580 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str127, 0x00000004}, + {-1}, +#line 626 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str129, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 592 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str134, 0x00000006}, +#line 1029 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str135, 0x00000004}, +#line 930 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str136, 0x00000002}, +#line 589 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str137, 0x00000002}, + {-1}, {-1}, +#line 582 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str140, 0x00000004}, + {-1}, {-1}, {-1}, +#line 617 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str144, 0x00000001}, + {-1}, +#line 942 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str146, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1135 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str150, 0x00000001}, + {-1}, {-1}, {-1}, +#line 70 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str154, 0x00000002}, +#line 674 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str155, 0x00000020}, +#line 409 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str156, 0x00000004}, + {-1}, {-1}, +#line 431 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str159, 0x00000002}, +#line 284 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str160, 0x00000002}, +#line 1132 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str161, 0x00000001}, + {-1}, {-1}, {-1}, +#line 1037 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str165, 0x00000002}, + {-1}, +#line 934 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str167, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 610 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str172, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 689 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str177, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 615 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str185, 0x00000004}, + {-1}, +#line 1116 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str187, 0x00000004}, +#line 678 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str188, 0x00000400}, +#line 1130 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str189, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 1051 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str194, 0x00000002}, + {-1}, +#line 156 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str196, 0x00000001}, + {-1}, +#line 1246 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str198, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 635 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str208, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 648 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str215, 0x00000002}, + {-1}, {-1}, +#line 157 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str218, 0x00000002}, + {-1}, {-1}, {-1}, +#line 620 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str222, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 931 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str229, 0x00000002}, +#line 649 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str230, 0x00000001}, + {-1}, {-1}, +#line 182 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str233, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 215 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str239, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1240 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str243, 0x00000001}, + {-1}, {-1}, +#line 611 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str246, 0x00000004}, + {-1}, {-1}, +#line 180 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str249, 0x00000001}, + {-1}, +#line 198 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str251, 0x00000004}, +#line 941 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str252, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 181 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str262, 0x00000001}, + {-1}, +#line 628 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str264, 0x00000002}, + {-1}, {-1}, +#line 794 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str267, 0x00000002}, + {-1}, {-1}, {-1}, +#line 197 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str271, 0x00000004}, +#line 1238 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str272, 0x00000001}, +#line 1079 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str273, 0x00000004}, +#line 42 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str274, 0x00000002}, +#line 614 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str275, 0x00000002}, + {-1}, {-1}, +#line 204 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str278, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 785 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str286, 0x00000002}, + {-1}, {-1}, +#line 788 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str289, 0x00000004}, +#line 1245 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str290, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1136 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str297, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, +#line 1078 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str302, 0x00000004}, + {-1}, +#line 183 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str304, 0x00000002}, + {-1}, +#line 211 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str306, 0x00000001}, + {-1}, +#line 261 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str308, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 568 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str313, 0x00000001}, + {-1}, +#line 647 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str315, 0x00000002}, + {-1}, {-1}, {-1}, +#line 567 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str319, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 195 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str330, 0x00000002}, +#line 256 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str331, 0x00000001}, + {-1}, {-1}, +#line 199 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str334, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 595 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str344, 0x00000004}, + {-1}, {-1}, {-1}, +#line 111 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str348, 0x00000001}, + {-1}, {-1}, +#line 583 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str351, 0x00000002}, +#line 522 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str352, 0x00000002}, + {-1}, {-1}, +#line 623 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str355, 0x00000004}, + {-1}, +#line 598 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str357, 0x00000004}, + {-1}, {-1}, {-1}, +#line 1131 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str361, 0x00000001}, + {-1}, {-1}, +#line 625 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str364, 0x00000004}, +#line 542 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str365, 0x00000002}, +#line 584 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str366, 0x00000002}, + {-1}, {-1}, +#line 1035 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str369, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 618 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str377, 0x00000010}, +#line 236 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str378, 0x00000002}, + {-1}, +#line 57 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str380, 0x00000010}, +#line 694 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str381, 0x00000002}, +#line 1243 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str382, 0x00000005}, + {-1}, {-1}, +#line 569 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str385, 0x00000001}, +#line 1050 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str386, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, +#line 453 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str391, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 676 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str406, 0x00000004}, +#line 827 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str407, 0x00000002}, + {-1}, +#line 619 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str409, 0x00000002}, + {-1}, {-1}, {-1}, +#line 547 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str413, 0x00000001}, +#line 778 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str414, 0x00000002}, +#line 1128 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str415, 0x00000001}, + {-1}, {-1}, +#line 684 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str418, 0x00000800}, + {-1}, +#line 259 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str420, 0x00000003}, +#line 708 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str421, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 282 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str427, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 234 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str439, 0x00000002}, + {-1}, +#line 190 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str441, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 167 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str446, 0x00000002}, + {-1}, {-1}, {-1}, +#line 450 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str450, 0x00000008}, + {-1}, {-1}, {-1}, {-1}, +#line 171 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str455, 0x00000004}, +#line 176 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str456, 0x00000001}, +#line 369 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str457, 0x00000004}, +#line 164 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str458, 0x00000002}, + {-1}, +#line 36 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str460, 0x00000010}, + {-1}, +#line 1106 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str462, 0x00000001}, + {-1}, +#line 166 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str464, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 1148 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str469, 0x00000002}, + {-1}, +#line 1047 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str471, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 192 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str479, 0x00000008}, +#line 357 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str480, 0x00000010}, + {-1}, {-1}, {-1}, +#line 49 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str484, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 762 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str490, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1025 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str494, 0x00000022}, + {-1}, {-1}, {-1}, {-1}, +#line 193 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str499, 0x00000004}, + {-1}, {-1}, +#line 115 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str502, 0x00000001}, + {-1}, {-1}, {-1}, +#line 262 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str506, 0x00000002}, + {-1}, +#line 661 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str508, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 328 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str513, 0x00000002}, +#line 185 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str514, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 275 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str519, 0x00000002}, + {-1}, {-1}, +#line 353 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str522, 0x00000010}, + {-1}, {-1}, +#line 786 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str525, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 430 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str533, 0x00000004}, +#line 329 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str534, 0x00000004}, + {-1}, +#line 184 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str536, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 418 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str541, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 338 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str550, 0x00000010}, + {-1}, {-1}, +#line 1129 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str553, 0x00000001}, + {-1}, +#line 510 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str555, 0x00000002}, + {-1}, {-1}, {-1}, +#line 364 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str559, 0x00000010}, + {-1}, +#line 94 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str561, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 186 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str568, 0x00000004}, + {-1}, +#line 444 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str570, 0x00000006}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 636 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str583, 0x00000006}, + {-1}, {-1}, {-1}, +#line 216 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str587, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 339 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str592, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 50 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str600, 0x00000002}, + {-1}, {-1}, +#line 378 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str603, 0x00000008}, + {-1}, {-1}, +#line 940 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str606, 0x00000400}, + {-1}, {-1}, {-1}, +#line 516 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str610, 0x00000001}, +#line 356 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str611, 0x00000010}, + {-1}, +#line 767 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str613, 0x00000002}, +#line 285 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str614, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 616 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str621, 0x00000004}, + {-1}, +#line 1114 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str623, 0x00000004}, +#line 1054 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str624, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 847 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str629, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 784 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str639, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1055 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str646, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 58 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str654, 0x00000004}, +#line 591 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str655, 0x00000010}, + {-1}, +#line 607 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str657, 0x00000002}, + {-1}, {-1}, {-1}, +#line 242 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str661, 0x00000002}, +#line 232 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str662, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 327 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str668, 0x00000002}, + {-1}, {-1}, {-1}, +#line 588 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str672, 0x00000002}, + {-1}, {-1}, +#line 365 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str675, 0x00000010}, + {-1}, +#line 380 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str677, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 612 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str684, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 158 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str689, 0x00000001}, +#line 817 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str690, 0x00000002}, + {-1}, {-1}, +#line 854 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str693, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1053 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str711, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, +#line 237 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str716, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 178 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str726, 0x00000001}, +#line 165 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str727, 0x00000020}, + {-1}, +#line 723 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str729, 0x00000002}, + {-1}, +#line 347 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str731, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 629 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str744, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 517 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str757, 0x00000001}, +#line 345 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str758, 0x00000001}, + {-1}, {-1}, {-1}, +#line 1096 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str762, 0x00000001}, +#line 749 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str763, 0x00000002}, + {-1}, {-1}, {-1}, +#line 321 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str767, 0x00000002}, +#line 512 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str768, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 250 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str773, 0x00000004}, + {-1}, {-1}, +#line 336 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str776, 0x00000001}, + {-1}, {-1}, +#line 836 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str779, 0x00000002}, + {-1}, {-1}, +#line 690 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str782, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 851 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str792, 0x00000002}, + {-1}, {-1}, {-1}, +#line 929 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str796, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 775 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str803, 0x00000002}, + {-1}, {-1}, +#line 528 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str806, 0x00000010}, +#line 332 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str807, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 504 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str814, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 351 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str820, 0x00000010}, + {-1}, {-1}, +#line 483 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str823, 0x00000010}, + {-1}, {-1}, {-1}, +#line 1105 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str827, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 81 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str836, 0x00000002}, + {-1}, {-1}, {-1}, +#line 96 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str840, 0x00000002}, + {-1}, {-1}, {-1}, +#line 168 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str844, 0x00000004}, +#line 481 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str845, 0x00000001}, + {-1}, +#line 243 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str847, 0x00000002}, +#line 210 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str848, 0x00000001}, + {-1}, {-1}, +#line 485 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str851, 0x00000002}, + {-1}, +#line 645 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str853, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 404 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str858, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 503 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str866, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 56 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str873, 0x00000001}, + {-1}, {-1}, +#line 349 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str876, 0x00000001}, +#line 384 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str877, 0x00000001}, + {-1}, +#line 518 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str879, 0x00000001}, + {-1}, {-1}, {-1}, +#line 102 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str883, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 1048 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str888, 0x00000001}, +#line 194 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str889, 0x00000004}, + {-1}, {-1}, +#line 491 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str892, 0x00000003}, + {-1}, {-1}, +#line 520 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str895, 0x00000001}, +#line 486 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str896, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 387 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str901, 0x00000002}, +#line 445 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str902, 0x00000001}, + {-1}, +#line 1039 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str904, 0x00000002}, +#line 1101 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str905, 0x00000002}, + {-1}, +#line 809 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str907, 0x00000002}, +#line 274 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str908, 0x00000002}, + {-1}, {-1}, +#line 396 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str911, 0x00000004}, +#line 1044 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str912, 0x00000002}, +#line 97 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str913, 0x00000002}, + {-1}, +#line 637 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str915, 0x00000001}, +#line 1110 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str916, 0x00000002}, +#line 644 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str917, 0x00000001}, + {-1}, +#line 54 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str919, 0x00000001}, + {-1}, +#line 524 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str921, 0x00000002}, +#line 423 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str922, 0x00000004}, +#line 643 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str923, 0x00000001}, +#line 835 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str924, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 787 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str929, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 366 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str934, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 613 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str940, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 420 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str948, 0x00000004}, + {-1}, +#line 800 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str950, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 320 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str955, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 707 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str967, 0x00000002}, + {-1}, {-1}, +#line 205 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str970, 0x00000004}, + {-1}, +#line 803 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str972, 0x00000002}, + {-1}, {-1}, +#line 1005 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str975, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 996 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str984, 0x00000001}, +#line 93 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str985, 0x00000002}, +#line 875 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str986, 0x00000020}, +#line 596 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str987, 0x00000001}, + {-1}, {-1}, +#line 474 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str990, 0x00000002}, + {-1}, +#line 642 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str992, 0x00000001}, +#line 477 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str993, 0x00000002}, +#line 464 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str994, 0x00000003}, +#line 476 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str995, 0x00000003}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 208 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1004, 0x00000004}, + {-1}, +#line 188 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1006, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 469 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1012, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 260 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1024, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 187 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1031, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 850 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1039, 0x00000002}, +#line 473 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1040, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 482 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1045, 0x00000002}, +#line 733 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1046, 0x00000002}, +#line 484 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1047, 0x00000002}, + {-1}, {-1}, {-1}, +#line 587 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1051, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1164 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1055, 0x00000001}, +#line 478 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1056, 0x00000002}, + {-1}, {-1}, {-1}, +#line 465 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1060, 0x00000001}, +#line 59 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1061, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 52 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1066, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 475 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1071, 0x00000002}, + {-1}, +#line 858 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1073, 0x00000002}, + {-1}, +#line 1197 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1075, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 43 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1081, 0x00000010}, +#line 526 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1082, 0x00000004}, + {-1}, {-1}, {-1}, +#line 1146 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1086, 0x00000002}, + {-1}, {-1}, {-1}, +#line 223 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1090, 0x00000004}, + {-1}, {-1}, +#line 470 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1093, 0x00000002}, + {-1}, +#line 479 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1095, 0x00000002}, + {-1}, +#line 513 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1097, 0x00000020}, +#line 1034 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1098, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 63 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1105, 0x00000004}, + {-1}, +#line 447 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1107, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 1074 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1112, 0x00000002}, +#line 519 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1113, 0x00000001}, + {-1}, +#line 745 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1115, 0x00000002}, + {-1}, +#line 857 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1117, 0x00000002}, +#line 633 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1118, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 932 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1124, 0x00000002}, + {-1}, {-1}, +#line 388 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1127, 0x00000004}, +#line 597 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1128, 0x00000002}, +#line 1165 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1129, 0x00000001}, + {-1}, {-1}, {-1}, +#line 1042 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1133, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1182 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1149, 0x00000002}, +#line 238 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1150, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 695 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1160, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, +#line 711 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1165, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 655 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1178, 0x00000006}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1134 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1184, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 993 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1193, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 848 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1209, 0x00000002}, +#line 572 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1210, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 1000 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1221, 0x00000004}, + {-1}, +#line 997 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1223, 0x00000003}, + {-1}, {-1}, {-1}, +#line 323 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1227, 0x00000002}, + {-1}, {-1}, +#line 377 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1230, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 777 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1241, 0x00000002}, +#line 104 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1242, 0x00000002}, + {-1}, {-1}, {-1}, +#line 374 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1246, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 494 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1259, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 826 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1267, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 713 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1273, 0x00000002}, + {-1}, {-1}, +#line 251 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1276, 0x00000002}, + {-1}, {-1}, {-1}, +#line 776 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1280, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 754 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1292, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 764 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1307, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 109 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1316, 0x00000004}, + {-1}, {-1}, {-1}, +#line 1187 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1320, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 1183 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1325, 0x00000002}, + {-1}, +#line 1023 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1327, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 755 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1336, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, +#line 808 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1341, 0x00000002}, + {-1}, +#line 833 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1343, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 400 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1348, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 105 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1354, 0x00000004}, + {-1}, {-1}, +#line 795 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1357, 0x00000002}, + {-1}, +#line 549 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1359, 0x00000002}, + {-1}, {-1}, +#line 829 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1362, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 709 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1376, 0x00000002}, + {-1}, +#line 641 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1378, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 853 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1383, 0x00000020}, +#line 425 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1384, 0x00000004}, + {-1}, {-1}, +#line 834 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1387, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 783 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1393, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 925 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1410, 0x00000008}, +#line 463 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1411, 0x00000002}, + {-1}, +#line 805 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1413, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 110 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1419, 0x00000004}, + {-1}, {-1}, +#line 562 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1422, 0x00000007}, + {-1}, {-1}, +#line 838 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1425, 0x00000002}, + {-1}, {-1}, {-1}, +#line 606 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1429, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 554 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1437, 0x00000007}, + {-1}, +#line 322 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1439, 0x00000002}, +#line 382 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1440, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 426 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1449, 0x00000004}, + {-1}, {-1}, {-1}, +#line 812 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1453, 0x00000002}, + {-1}, {-1}, +#line 344 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1456, 0x00000002}, +#line 159 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1457, 0x00000010}, + {-1}, {-1}, +#line 651 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1460, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 561 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1468, 0x00000007}, + {-1}, {-1}, +#line 737 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1471, 0x00000002}, + {-1}, {-1}, +#line 346 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1474, 0x00000001}, + {-1}, {-1}, {-1}, +#line 621 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1478, 0x00000004}, +#line 1142 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1479, 0x00000002}, + {-1}, {-1}, {-1}, +#line 555 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1483, 0x00000007}, +#line 1038 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1484, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 300 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1499, 0x00000004}, + {-1}, +#line 276 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1501, 0x00000400}, + {-1}, {-1}, {-1}, +#line 294 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1505, 0x00000002}, + {-1}, +#line 301 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1507, 0x00000002}, +#line 1244 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1508, 0x00000008}, + {-1}, {-1}, {-1}, +#line 247 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1512, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 290 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1523, 0x00000010}, + {-1}, +#line 1002 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1525, 0x00000002}, + {-1}, {-1}, {-1}, +#line 217 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1529, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 944 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1537, 0x00000002}, + {-1}, {-1}, {-1}, +#line 487 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1541, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 315 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1550, 0x00000004}, +#line 480 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1551, 0x00000002}, + {-1}, {-1}, {-1}, +#line 401 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1555, 0x00000002}, + {-1}, +#line 252 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1557, 0x00000002}, + {-1}, {-1}, +#line 207 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1560, 0x00000004}, + {-1}, {-1}, +#line 488 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1563, 0x00000002}, + {-1}, {-1}, +#line 334 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1566, 0x00000001}, + {-1}, {-1}, {-1}, +#line 446 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1570, 0x00000006}, +#line 316 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1571, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 103 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1601, 0x00000003}, + {-1}, +#line 845 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1603, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 189 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1611, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 831 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1616, 0x00000002}, +#line 295 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1617, 0x00000001}, + {-1}, {-1}, {-1}, +#line 682 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1621, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 308 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1629, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 521 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1642, 0x00000001}, +#line 1097 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1643, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 291 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1648, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 551 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1654, 0x00000006}, +#line 565 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1655, 0x00000007}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 397 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1670, 0x00000001}, +#line 736 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1671, 0x00000002}, +#line 352 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1672, 0x00000001}, + {-1}, {-1}, {-1}, +#line 813 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1676, 0x00000002}, + {-1}, {-1}, {-1}, +#line 224 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1680, 0x00000002}, + {-1}, {-1}, {-1}, +#line 107 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1684, 0x00000801}, +#line 55 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1685, 0x00000001}, +#line 28 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1686, 0x00000004}, + {-1}, {-1}, +#line 859 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1689, 0x00000002}, + {-1}, {-1}, +#line 461 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1692, 0x00000001}, + {-1}, +#line 1027 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1694, 0x00000020}, + {-1}, +#line 874 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1696, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1117 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1706, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 466 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1711, 0x00000002}, + {-1}, +#line 1019 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1713, 0x00000002}, + {-1}, +#line 293 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1715, 0x00000002}, +#line 292 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1716, 0x00000001}, + {-1}, +#line 525 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1718, 0x00000020}, +#line 679 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1719, 0x00001000}, +#line 630 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1720, 0x00000002}, +#line 799 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1721, 0x00000002}, + {-1}, {-1}, {-1}, +#line 680 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1725, 0x00001000}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 570 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1733, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 922 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1738, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 884 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1750, 0x00000001}, +#line 608 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1751, 0x00000800}, + {-1}, +#line 29 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1753, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 735 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1758, 0x00000002}, +#line 507 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1759, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 299 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1765, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 460 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1775, 0x00000001}, + {-1}, +#line 239 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1777, 0x00000002}, +#line 514 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1778, 0x00000001}, +#line 508 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1779, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1022 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1795, 0x00000002}, + {-1}, +#line 62 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1797, 0x00000400}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 758 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1807, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 550 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1822, 0x00000007}, + {-1}, {-1}, +#line 734 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1825, 0x00000020}, +#line 753 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1826, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 546 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1836, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 913 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1841, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1077 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1849, 0x00000002}, + {-1}, +#line 779 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1851, 0x00000800}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 296 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1860, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 744 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1868, 0x00000002}, + {-1}, {-1}, +#line 691 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1871, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 906 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1877, 0x00000001}, + {-1}, +#line 1013 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1879, 0x00000002}, + {-1}, {-1}, +#line 468 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1882, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1093 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1890, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 860 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1895, 0x00000020}, +#line 350 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1896, 0x00000010}, + {-1}, {-1}, {-1}, +#line 1040 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1900, 0x00000002}, +#line 652 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1901, 0x00000002}, + {-1}, {-1}, +#line 677 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1904, 0x00000400}, + {-1}, {-1}, +#line 191 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1907, 0x00000002}, +#line 593 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1908, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 710 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1914, 0x00000002}, +#line 1061 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1915, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 873 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1927, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 640 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1944, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 557 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1951, 0x00000007}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1026 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1957, 0x00000400}, + {-1}, +#line 624 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1959, 0x00000004}, + {-1}, +#line 828 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1961, 0x00000002}, + {-1}, {-1}, {-1}, +#line 99 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1965, 0x00000004}, + {-1}, {-1}, {-1}, +#line 337 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1969, 0x00000006}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 548 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1985, 0x00000007}, +#line 1095 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1986, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 1184 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str1998, 0x00000008}, + {-1}, {-1}, {-1}, {-1}, +#line 1133 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2003, 0x00000005}, + {-1}, +#line 653 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2005, 0x00000008}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 1150 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2018, 0x00000400}, + {-1}, {-1}, {-1}, +#line 627 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2022, 0x00000004}, + {-1}, {-1}, +#line 880 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2025, 0x00000002}, +#line 769 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2026, 0x00000002}, + {-1}, {-1}, {-1}, +#line 556 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2030, 0x00000007}, + {-1}, {-1}, {-1}, {-1}, +#line 422 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2035, 0x00000004}, + {-1}, +#line 410 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2037, 0x00000004}, +#line 560 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2038, 0x00000007}, + {-1}, +#line 1115 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2040, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 712 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2045, 0x00000002}, + {-1}, +#line 552 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2047, 0x00000007}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 574 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2055, 0x00000002}, + {-1}, {-1}, +#line 654 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2058, 0x00000001}, + {-1}, {-1}, {-1}, +#line 927 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2062, 0x00000004}, + {-1}, {-1}, +#line 355 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2065, 0x00000002}, + {-1}, {-1}, {-1}, +#line 358 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2069, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 815 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2093, 0x00000002}, +#line 1085 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2094, 0x00000002}, +#line 1066 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2095, 0x00000006}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 263 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2126, 0x00000003}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1080 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2133, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 796 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2144, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 818 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2152, 0x00000002}, + {-1}, {-1}, +#line 177 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2155, 0x00000002}, + {-1}, {-1}, {-1}, +#line 515 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2159, 0x00000800}, + {-1}, +#line 389 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2161, 0x00000004}, +#line 456 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2162, 0x00000001}, +#line 1036 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2163, 0x00000004}, + {-1}, +#line 585 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2165, 0x00000003}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 64 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2174, 0x00000004}, + {-1}, {-1}, {-1}, +#line 1221 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2178, 0x00000002}, +#line 915 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2179, 0x00000001}, + {-1}, +#line 806 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2181, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 797 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2188, 0x00000020}, +#line 498 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2189, 0x00000004}, + {-1}, +#line 683 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2191, 0x00000020}, +#line 1100 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2192, 0x00001000}, + {-1}, {-1}, {-1}, {-1}, +#line 51 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2197, 0x00000001}, + {-1}, +#line 360 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2199, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 34 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2206, 0x00000004}, +#line 599 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2207, 0x00000004}, +#line 1236 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2208, 0x00000002}, +#line 1064 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2209, 0x00000004}, +#line 443 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2210, 0x00000001}, + {-1}, {-1}, +#line 657 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2213, 0x00000004}, + {-1}, {-1}, {-1}, +#line 1113 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2217, 0x00000002}, + {-1}, +#line 35 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2219, 0x00000022}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1159 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2225, 0x00000002}, +#line 564 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2226, 0x00000007}, + {-1}, {-1}, +#line 1160 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2229, 0x00000002}, + {-1}, +#line 1065 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2231, 0x00000004}, +#line 656 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2232, 0x00000004}, +#line 1161 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2233, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 287 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2239, 0x00000004}, + {-1}, {-1}, +#line 1192 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2242, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1041 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2249, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1156 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2253, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 319 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2259, 0x00000002}, + {-1}, +#line 1098 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2261, 0x00000001}, + {-1}, {-1}, +#line 894 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2264, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 113 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2276, 0x00000002}, + {-1}, +#line 916 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2278, 0x00000001}, +#line 318 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2279, 0x00000002}, + {-1}, +#line 781 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2281, 0x00000002}, +#line 407 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2282, 0x00000004}, + {-1}, {-1}, {-1}, +#line 558 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2286, 0x00000007}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 373 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2294, 0x00000004}, +#line 278 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2295, 0x00000400}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 802 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2301, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 442 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2320, 0x00000002}, + {-1}, {-1}, +#line 665 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2323, 0x00000002}, + {-1}, {-1}, +#line 573 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2326, 0x00000800}, +#line 1157 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2327, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1158 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2331, 0x00000002}, +#line 825 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2332, 0x00000002}, + {-1}, {-1}, +#line 948 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2335, 0x00000004}, +#line 843 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2336, 0x00000002}, + {-1}, {-1}, {-1}, +#line 842 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2340, 0x00000002}, + {-1}, +#line 1094 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2342, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 370 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2352, 0x00000004}, + {-1}, +#line 1083 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2354, 0x00000002}, + {-1}, +#line 949 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2356, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 950 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2362, 0x00000001}, + {-1}, {-1}, +#line 330 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2365, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1233 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2372, 0x00000002}, +#line 988 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2373, 0x00000004}, +#line 1030 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2374, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 421 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2381, 0x00000004}, +#line 631 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2382, 0x00000004}, +#line 989 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2383, 0x00000002}, +#line 576 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2384, 0x00000004}, +#line 974 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2385, 0x00000001}, + {-1}, +#line 381 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2387, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 577 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2392, 0x00000002}, + {-1}, +#line 1018 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2394, 0x00000003}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 1151 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2405, 0x00000002}, + {-1}, {-1}, {-1}, +#line 650 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2409, 0x00000002}, +#line 609 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2410, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 896 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2415, 0x00000001}, +#line 1196 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2416, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 945 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2425, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1020 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2429, 0x00000002}, + {-1}, {-1}, +#line 212 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2432, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 666 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2438, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 770 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2445, 0x00000002}, +#line 883 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2446, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 772 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2455, 0x00000002}, +#line 907 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2456, 0x00000001}, + {-1}, {-1}, {-1}, +#line 919 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2460, 0x00000001}, + {-1}, {-1}, +#line 440 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2463, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 288 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2481, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 163 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2492, 0x00000010}, +#line 980 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2493, 0x00000001}, +#line 1075 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2494, 0x00000001}, +#line 417 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2495, 0x00000010}, + {-1}, {-1}, {-1}, +#line 257 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2499, 0x00000001}, +#line 286 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2500, 0x00001000}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 255 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2507, 0x00000004}, + {-1}, {-1}, +#line 1137 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2510, 0x00000004}, + {-1}, +#line 946 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2512, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 449 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2518, 0x00000001}, + {-1}, {-1}, +#line 30 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2521, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 964 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2534, 0x00000010}, + {-1}, {-1}, +#line 1140 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2537, 0x00000004}, + {-1}, {-1}, {-1}, +#line 254 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2541, 0x00000004}, + {-1}, {-1}, {-1}, +#line 459 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2545, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 31 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2552, 0x00000001}, + {-1}, {-1}, {-1}, +#line 472 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2556, 0x00000002}, + {-1}, {-1}, +#line 354 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2559, 0x00000010}, + {-1}, {-1}, {-1}, +#line 471 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2563, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 1155 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2574, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 771 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2580, 0x00000002}, + {-1}, {-1}, +#line 814 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2583, 0x00000002}, + {-1}, {-1}, +#line 943 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2586, 0x00000002}, + {-1}, {-1}, +#line 289 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2589, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 953 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2605, 0x00000003}, +#line 235 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2606, 0x00000002}, + {-1}, +#line 730 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2608, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1139 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2617, 0x00000004}, +#line 720 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2618, 0x00000002}, + {-1}, {-1}, {-1}, +#line 531 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2622, 0x00000002}, + {-1}, +#line 497 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2624, 0x00000010}, + {-1}, +#line 773 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2626, 0x00000002}, +#line 759 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2627, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1181 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2636, 0x00000010}, + {-1}, {-1}, +#line 966 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2639, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 959 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2645, 0x00000001}, +#line 774 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2646, 0x00000020}, + {-1}, {-1}, +#line 933 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2649, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 658 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2658, 0x00000001}, + {-1}, {-1}, +#line 506 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2661, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 792 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2667, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 757 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2674, 0x00000002}, + {-1}, {-1}, {-1}, +#line 359 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2678, 0x00000001}, +#line 902 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2679, 0x00000001}, + {-1}, {-1}, +#line 594 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2682, 0x00000020}, +#line 1237 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2683, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 793 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2689, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 371 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2697, 0x00000004}, + {-1}, {-1}, {-1}, +#line 717 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2701, 0x00000002}, + {-1}, +#line 1068 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2703, 0x00000002}, +#line 1235 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2704, 0x00000001}, + {-1}, {-1}, +#line 44 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2707, 0x00000002}, + {-1}, +#line 970 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2709, 0x00000003}, + {-1}, {-1}, {-1}, +#line 1152 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2713, 0x00000002}, +#line 1138 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2714, 0x00000004}, + {-1}, +#line 424 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2716, 0x00000004}, + {-1}, {-1}, +#line 807 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2719, 0x00000002}, + {-1}, {-1}, +#line 196 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2722, 0x00000001}, +#line 718 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2723, 0x00000002}, + {-1}, {-1}, +#line 405 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2726, 0x00000004}, + {-1}, {-1}, {-1}, +#line 914 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2730, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 1191 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2744, 0x00000010}, + {-1}, {-1}, {-1}, +#line 529 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2748, 0x00000002}, +#line 921 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2749, 0x00000001}, + {-1}, +#line 600 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2751, 0x00000001}, + {-1}, {-1}, {-1}, +#line 362 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2755, 0x00000010}, + {-1}, {-1}, {-1}, +#line 219 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2759, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 979 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2765, 0x00000004}, +#line 1045 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2766, 0x00000002}, +#line 505 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2767, 0x00000002}, + {-1}, +#line 311 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2769, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 601 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2777, 0x00000002}, +#line 1126 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2778, 0x00000001}, + {-1}, {-1}, +#line 363 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2781, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 839 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2787, 0x00000002}, + {-1}, {-1}, +#line 750 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2790, 0x00000002}, +#line 751 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2791, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 738 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2805, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 348 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2824, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 48 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2835, 0x00000002}, + {-1}, {-1}, +#line 1003 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2838, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 897 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2858, 0x00000001}, + {-1}, +#line 1228 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2860, 0x00000002}, + {-1}, {-1}, +#line 879 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2863, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 865 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2876, 0x00000002}, + {-1}, +#line 862 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2878, 0x00000002}, +#line 209 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2879, 0x00000004}, +#line 864 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2880, 0x00000002}, +#line 523 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2881, 0x00000002}, + {-1}, +#line 870 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2883, 0x00000002}, +#line 1227 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2884, 0x00000010}, + {-1}, +#line 863 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2886, 0x00000002}, +#line 586 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2887, 0x00000002}, + {-1}, {-1}, {-1}, +#line 917 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2891, 0x00000001}, + {-1}, +#line 502 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2893, 0x00000024}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 901 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2900, 0x00000001}, +#line 639 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2901, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 866 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2909, 0x00000002}, + {-1}, {-1}, +#line 317 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2912, 0x00000001}, +#line 816 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2913, 0x00000020}, +#line 118 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2914, 0x00000002}, +#line 937 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2915, 0x00000004}, + {-1}, +#line 882 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2917, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 1016 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2922, 0x00000001}, +#line 427 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2923, 0x00000002}, + {-1}, {-1}, {-1}, +#line 935 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2927, 0x00000006}, +#line 719 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2928, 0x00000002}, + {-1}, +#line 66 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2930, 0x00000001}, + {-1}, +#line 527 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2932, 0x00000004}, + {-1}, +#line 1107 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2934, 0x00000001}, +#line 824 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2935, 0x00000002}, +#line 45 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2936, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1189 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2945, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, +#line 872 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2950, 0x00000002}, + {-1}, +#line 1007 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2952, 0x00000002}, +#line 119 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2953, 0x00000004}, + {-1}, {-1}, {-1}, +#line 490 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2957, 0x00000001}, + {-1}, {-1}, +#line 634 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2960, 0x00000004}, + {-1}, {-1}, +#line 961 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2963, 0x00000010}, + {-1}, +#line 1127 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2965, 0x00000002}, +#line 1062 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2966, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 926 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2977, 0x00000800}, +#line 780 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2978, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 441 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2986, 0x00000001}, + {-1}, {-1}, +#line 638 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2989, 0x00000002}, + {-1}, +#line 1108 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str2991, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 748 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3000, 0x00000002}, +#line 1229 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3001, 0x00000800}, +#line 141 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3002, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 782 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3009, 0x00000002}, +#line 222 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3010, 0x00000008}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 938 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3018, 0x00000004}, +#line 385 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3019, 0x00000005}, + {-1}, +#line 47 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3021, 0x00000002}, + {-1}, {-1}, +#line 1009 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3024, 0x00000004}, + {-1}, {-1}, +#line 590 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3027, 0x00000001}, + {-1}, +#line 161 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3029, 0x00000001}, + {-1}, +#line 1190 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3031, 0x00000010}, + {-1}, +#line 200 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3033, 0x00000010}, +#line 740 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3034, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 114 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3060, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 451 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3068, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 155 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3074, 0x00000002}, +#line 1175 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3075, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1234 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3083, 0x00000020}, + {-1}, {-1}, +#line 995 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3086, 0x00000002}, +#line 1163 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3087, 0x00000002}, + {-1}, +#line 832 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3089, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 131 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3100, 0x00000010}, + {-1}, {-1}, +#line 1174 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3103, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 116 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3110, 0x00000003}, + {-1}, {-1}, {-1}, +#line 687 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3114, 0x00000008}, +#line 1162 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3115, 0x00000002}, +#line 871 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3116, 0x00000002}, + {-1}, +#line 530 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3118, 0x00000010}, + {-1}, +#line 147 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3120, 0x00000010}, + {-1}, {-1}, {-1}, +#line 434 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3124, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 1193 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3129, 0x00000008}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 120 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3135, 0x00000001}, +#line 38 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3136, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 454 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3141, 0x00000001}, + {-1}, {-1}, {-1}, +#line 811 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3145, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 258 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3152, 0x00000002}, + {-1}, {-1}, {-1}, +#line 146 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3156, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 408 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3162, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1212 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3169, 0x00000002}, +#line 41 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3170, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 716 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3185, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1199 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3193, 0x00000010}, +#line 904 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3194, 0x00000001}, +#line 429 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3195, 0x00000004}, + {-1}, {-1}, +#line 310 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3198, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, +#line 878 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3203, 0x00000002}, +#line 855 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3204, 0x00000002}, +#line 361 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3205, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 179 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3212, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 798 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3220, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 173 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3227, 0x00000004}, +#line 801 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3228, 0x00000002}, +#line 537 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3229, 0x00000001}, + {-1}, {-1}, {-1}, +#line 438 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3233, 0x00000004}, + {-1}, {-1}, +#line 876 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3236, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 868 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3243, 0x00000002}, + {-1}, {-1}, +#line 172 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3246, 0x00000004}, + {-1}, +#line 160 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3248, 0x00000002}, +#line 437 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3249, 0x00000004}, +#line 856 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3250, 0x00000020}, + {-1}, {-1}, {-1}, +#line 406 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3254, 0x00000004}, + {-1}, {-1}, +#line 273 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3257, 0x00000001}, + {-1}, {-1}, +#line 791 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3260, 0x00000004}, + {-1}, {-1}, +#line 978 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3263, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 428 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3272, 0x00000002}, + {-1}, +#line 202 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3274, 0x00000002}, + {-1}, {-1}, +#line 126 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3277, 0x00000001}, + {-1}, +#line 936 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3279, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 743 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3286, 0x00000002}, + {-1}, {-1}, +#line 1215 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3289, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 341 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3305, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1214 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3311, 0x00000004}, +#line 903 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3312, 0x00000001}, + {-1}, +#line 983 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3314, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 559 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3319, 0x00000007}, + {-1}, {-1}, {-1}, +#line 1203 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3323, 0x00000006}, + {-1}, +#line 1001 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3325, 0x00000002}, + {-1}, {-1}, +#line 532 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3328, 0x00000004}, + {-1}, {-1}, +#line 1220 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3331, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 1213 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3336, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 692 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3341, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 533 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3346, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 544 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3356, 0x00000001}, + {-1}, {-1}, +#line 810 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3359, 0x00000002}, +#line 1195 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3360, 0x00000008}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 433 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3368, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 130 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3375, 0x00000010}, +#line 622 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3376, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1063 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3385, 0x00000004}, + {-1}, +#line 696 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3387, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 304 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3392, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1082 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3398, 0x00000002}, + {-1}, {-1}, {-1}, +#line 324 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3402, 0x00000001}, + {-1}, {-1}, +#line 729 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3405, 0x00000002}, + {-1}, {-1}, {-1}, +#line 253 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3409, 0x00000001}, + {-1}, {-1}, +#line 1012 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3412, 0x00000001}, +#line 1099 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3413, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 804 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3429, 0x00000002}, + {-1}, {-1}, +#line 499 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3432, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 545 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3438, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1017 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3462, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1122 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3466, 0x00000002}, + {-1}, +#line 849 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3468, 0x00000002}, + {-1}, {-1}, {-1}, +#line 697 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3472, 0x00000002}, +#line 536 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3473, 0x00000004}, +#line 1070 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3474, 0x00000001}, +#line 1200 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3475, 0x00000003}, + {-1}, {-1}, {-1}, {-1}, +#line 912 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3480, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 277 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3487, 0x00000400}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1153 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3497, 0x00000006}, + {-1}, {-1}, +#line 214 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3500, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 233 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3505, 0x00000010}, + {-1}, +#line 662 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3507, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 302 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3515, 0x00000004}, +#line 303 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3516, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 823 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3524, 0x00000002}, + {-1}, +#line 632 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3526, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 909 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3531, 0x00000001}, +#line 372 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3532, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 1084 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3543, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1121 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3550, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 1217 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3562, 0x00000006}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 881 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3581, 0x00000002}, + {-1}, +#line 213 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3583, 0x00000004}, +#line 739 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3584, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 763 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3591, 0x00000002}, + {-1}, +#line 1185 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3593, 0x00000010}, + {-1}, {-1}, +#line 170 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3596, 0x00000004}, +#line 1154 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3597, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 169 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3615, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 861 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3620, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1123 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3628, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 867 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3648, 0x00000002}, + {-1}, +#line 731 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3650, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 985 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3656, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 231 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3664, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 314 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3681, 0x00000002}, + {-1}, +#line 1180 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3683, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, +#line 741 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3688, 0x00000002}, + {-1}, +#line 77 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3690, 0x00000001}, + {-1}, {-1}, {-1}, +#line 1111 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3694, 0x00000001}, + {-1}, +#line 765 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3696, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1112 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3700, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 852 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3708, 0x00000002}, + {-1}, {-1}, {-1}, +#line 495 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3712, 0x00000010}, + {-1}, +#line 496 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3714, 0x00000010}, + {-1}, +#line 448 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3716, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 701 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3725, 0x00000002}, +#line 390 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3726, 0x00000004}, + {-1}, +#line 60 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3728, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 221 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3737, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 667 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3748, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 962 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3753, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 981 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3759, 0x00000004}, + {-1}, +#line 670 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3761, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1058 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3767, 0x00000004}, + {-1}, +#line 672 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3769, 0x00000002}, + {-1}, +#line 702 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3771, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 127 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3778, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 1125 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3791, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 452 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3799, 0x00000001}, + {-1}, {-1}, {-1}, +#line 306 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3803, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1103 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3827, 0x00000800}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 225 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3835, 0x00000001}, + {-1}, {-1}, +#line 760 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3838, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 566 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3844, 0x00000007}, + {-1}, {-1}, {-1}, {-1}, +#line 1204 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3849, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1143 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3853, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 756 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3866, 0x00000002}, +#line 1144 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3867, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 698 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3878, 0x00000002}, + {-1}, +#line 1188 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3880, 0x00000002}, +#line 1205 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3881, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 869 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3890, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 704 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3895, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 1092 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3900, 0x00000002}, +#line 1239 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3901, 0x00000008}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1231 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3927, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 367 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3937, 0x00000002}, + {-1}, +#line 283 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3939, 0x00000001}, + {-1}, +#line 924 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3941, 0x00000001}, + {-1}, +#line 84 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3943, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 724 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3961, 0x00000002}, + {-1}, +#line 1194 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3963, 0x00000008}, +#line 725 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3964, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 106 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3992, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 125 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str3998, 0x00000001}, + {-1}, {-1}, {-1}, +#line 305 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4002, 0x00000004}, + {-1}, {-1}, +#line 245 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4005, 0x00000002}, + {-1}, {-1}, +#line 1032 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4008, 0x00000002}, + {-1}, +#line 1091 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4010, 0x00000002}, + {-1}, {-1}, +#line 1008 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4013, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 908 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4019, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 789 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4028, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 693 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4034, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 489 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4054, 0x00000002}, + {-1}, +#line 342 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4056, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 151 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4063, 0x00000003}, +#line 1021 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4064, 0x00000003}, + {-1}, {-1}, {-1}, +#line 951 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4068, 0x00000006}, + {-1}, {-1}, {-1}, +#line 660 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4072, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 686 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4078, 0x00000020}, + {-1}, +#line 1072 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4080, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 890 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4088, 0x00000001}, + {-1}, {-1}, +#line 1198 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4091, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 830 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4097, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 963 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4102, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1172 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4106, 0x00000001}, + {-1}, {-1}, {-1}, +#line 891 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4110, 0x00000001}, + {-1}, {-1}, {-1}, +#line 1081 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4114, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 1102 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4137, 0x00000001}, + {-1}, {-1}, {-1}, +#line 335 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4141, 0x00000001}, + {-1}, +#line 685 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4143, 0x00000001}, + {-1}, +#line 1209 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4145, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 998 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4158, 0x00000002}, + {-1}, {-1}, +#line 1206 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4161, 0x00000002}, + {-1}, {-1}, +#line 78 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4164, 0x00000400}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 898 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4174, 0x00000001}, + {-1}, +#line 83 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4176, 0x00000001}, + {-1}, +#line 419 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4178, 0x00000004}, + {-1}, +#line 1173 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4180, 0x00000001}, + {-1}, {-1}, {-1}, +#line 1169 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4184, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1170 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4188, 0x00000002}, +#line 383 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4189, 0x00000002}, + {-1}, {-1}, +#line 1171 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4192, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 509 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4201, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 279 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4209, 0x00000010}, + {-1}, {-1}, +#line 1166 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4212, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 976 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4218, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 152 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4225, 0x00000002}, + {-1}, {-1}, +#line 312 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4228, 0x00000001}, + {-1}, +#line 543 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4230, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1202 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4234, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 393 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4243, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 91 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4248, 0x00000001}, + {-1}, +#line 668 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4250, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 553 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4257, 0x00000002}, + {-1}, +#line 821 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4259, 0x00000002}, + {-1}, {-1}, {-1}, +#line 673 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4263, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1219 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4280, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1167 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4286, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1168 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4290, 0x00000002}, +#line 1004 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4291, 0x00000006}, +#line 467 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4292, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 947 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4305, 0x00000004}, + {-1}, +#line 71 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4307, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 844 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4317, 0x00000002}, +#line 732 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4318, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 604 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4324, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 1120 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4329, 0x00000008}, + {-1}, {-1}, +#line 705 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4332, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1014 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4336, 0x00000002}, +#line 79 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4337, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 671 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4357, 0x00000001}, + {-1}, {-1}, {-1}, +#line 416 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4361, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 134 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4381, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 415 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4386, 0x00000004}, + {-1}, {-1}, {-1}, +#line 1179 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4390, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1104 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4396, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 457 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4417, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 244 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4427, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 73 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4432, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 313 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4438, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 333 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4443, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 100 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4448, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 249 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4455, 0x00000002}, + {-1}, +#line 1207 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4457, 0x00000020}, + {-1}, {-1}, {-1}, +#line 541 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4461, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 742 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4467, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 95 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4473, 0x00000002}, + {-1}, {-1}, {-1}, +#line 343 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4477, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1141 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4483, 0x00000010}, + {-1}, +#line 121 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4485, 0x00000001}, +#line 331 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4486, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 414 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4500, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 411 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4506, 0x00000004}, +#line 203 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4507, 0x00000002}, + {-1}, {-1}, {-1}, +#line 149 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4511, 0x00000001}, + {-1}, +#line 493 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4513, 0x00000004}, + {-1}, {-1}, +#line 1176 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4516, 0x00000004}, + {-1}, {-1}, +#line 76 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4519, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 412 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4524, 0x00000002}, + {-1}, {-1}, +#line 37 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4527, 0x00000010}, +#line 375 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4528, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 500 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4544, 0x00000004}, +#line 75 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4545, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 722 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4550, 0x00000002}, + {-1}, {-1}, +#line 220 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4553, 0x00000004}, + {-1}, {-1}, {-1}, +#line 1033 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4557, 0x00000002}, + {-1}, +#line 721 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4559, 0x00000002}, + {-1}, {-1}, {-1}, +#line 700 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4563, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 663 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4569, 0x00000002}, + {-1}, +#line 122 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4571, 0x00000002}, +#line 889 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4572, 0x00000001}, + {-1}, {-1}, {-1}, +#line 399 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4576, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 918 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4591, 0x00000001}, + {-1}, +#line 1052 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4593, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 309 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4614, 0x00000010}, + {-1}, +#line 920 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4616, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 540 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4630, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1178 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4646, 0x00000002}, + {-1}, {-1}, +#line 965 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4649, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 714 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4666, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 1210 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4671, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 972 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4677, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 820 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4684, 0x00000002}, + {-1}, {-1}, {-1}, +#line 162 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4688, 0x00000800}, + {-1}, {-1}, {-1}, +#line 403 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4692, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 973 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4699, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 46 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4706, 0x00000002}, +#line 681 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4707, 0x0000000a}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 74 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4725, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 575 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4732, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 752 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4750, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 226 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4758, 0x00000002}, + {-1}, {-1}, {-1}, +#line 123 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4762, 0x00000004}, + {-1}, {-1}, +#line 571 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4765, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 68 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4785, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 67 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4810, 0x00000004}, + {-1}, {-1}, {-1}, +#line 969 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4814, 0x00000002}, + {-1}, +#line 885 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4816, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 143 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4821, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 939 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4833, 0x00000400}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 1109 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4846, 0x00000001}, + {-1}, +#line 145 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4848, 0x00000001}, +#line 766 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4849, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 227 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4870, 0x00000004}, + {-1}, +#line 1088 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4872, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 218 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4884, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 1177 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4896, 0x00000002}, +#line 1011 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4897, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 895 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4908, 0x00000001}, +#line 150 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4909, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 142 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4927, 0x00000002}, + {-1}, {-1}, {-1}, +#line 1149 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4931, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 368 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4945, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 646 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4953, 0x00000003}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 39 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4966, 0x00000004}, + {-1}, {-1}, {-1}, +#line 837 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4970, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 1208 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4983, 0x00000020}, + {-1}, +#line 230 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4985, 0x00000004}, +#line 398 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str4986, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 435 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5022, 0x00000004}, + {-1}, {-1}, +#line 69 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5025, 0x00000004}, + {-1}, {-1}, +#line 128 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5028, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 40 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5038, 0x00000004}, + {-1}, {-1}, +#line 602 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5041, 0x00000002}, + {-1}, {-1}, {-1}, +#line 436 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5045, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 899 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5057, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 280 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5064, 0x00000004}, + {-1}, {-1}, +#line 439 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5067, 0x00000004}, + {-1}, {-1}, +#line 206 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5070, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 455 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5081, 0x00000008}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 910 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5087, 0x00000001}, +#line 761 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5088, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1211 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5096, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 886 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5112, 0x00000001}, + {-1}, +#line 706 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5114, 0x00000002}, +#line 80 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5115, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 578 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5132, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1006 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5138, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 990 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5144, 0x00000001}, + {-1}, +#line 605 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5146, 0x00000020}, + {-1}, {-1}, +#line 124 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5149, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 984 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5156, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1076 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5164, 0x00000004}, + {-1}, {-1}, +#line 968 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5167, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 395 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5176, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1216 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5184, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 394 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5194, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 967 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5199, 0x00000008}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1232 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5207, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, +#line 840 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5212, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 905 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5225, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 841 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5240, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 89 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5253, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 65 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5266, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 144 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5311, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 892 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5330, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 664 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5356, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 986 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5382, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 1073 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5404, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 72 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5426, 0x00000001}, + {-1}, {-1}, +#line 534 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5429, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 992 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5485, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 846 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5535, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 511 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5594, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, +#line 32 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5599, 0x00000001}, +#line 728 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5600, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 87 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5606, 0x00000005}, + {-1}, {-1}, +#line 501 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5609, 0x00000004}, + {-1}, +#line 877 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5611, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 982 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5624, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 727 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5632, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 33 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5662, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 132 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5698, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, +#line 1028 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5703, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1015 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5709, 0x00000001}, +#line 391 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5710, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1145 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5729, 0x00000001}, + {-1}, +#line 376 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5731, 0x00000001}, + {-1}, {-1}, {-1}, +#line 539 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5735, 0x00000001}, + {-1}, {-1}, +#line 462 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5738, 0x00000400}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1124 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5755, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1223 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5789, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 603 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5820, 0x00000020}, + {-1}, {-1}, {-1}, +#line 1224 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5824, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1225 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5850, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 911 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5870, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 958 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5887, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 85 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5900, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 307 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5925, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 175 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5936, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 174 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5961, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 822 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5975, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1230 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5982, 0x00000010}, + {-1}, +#line 241 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5984, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1118 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str5999, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 1069 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6031, 0x00000006}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1056 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6038, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 379 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6048, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 887 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6053, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1046 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6062, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 1090 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6083, 0x00000002}, +#line 669 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6084, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 535 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6096, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 325 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6108, 0x00000001}, + {-1}, {-1}, {-1}, +#line 1043 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6112, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 790 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6123, 0x00000004}, + {-1}, +#line 703 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6125, 0x00000002}, + {-1}, +#line 563 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6127, 0x00000007}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 133 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6140, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1024 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6147, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 117 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6176, 0x00000003}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 458 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6185, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, +#line 92 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6190, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1119 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6226, 0x00000001}, +#line 768 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6227, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 137 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6241, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 138 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6263, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 61 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6272, 0x00000002}, + {-1}, {-1}, +#line 246 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6275, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 140 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6300, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 991 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6316, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 432 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6333, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 1201 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6452, 0x00000001}, + {-1}, {-1}, {-1}, +#line 1147 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6456, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 1242 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6512, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 240 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6534, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 82 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6553, 0x00000001}, + {-1}, {-1}, {-1}, +#line 954 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6557, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 326 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6578, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 229 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6584, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 1241 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6631, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 971 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6642, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 153 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6655, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, +#line 726 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6660, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 1218 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6708, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 747 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6745, 0x00000020}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 201 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6761, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 977 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6863, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 135 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6924, 0x00000004}, + {-1}, {-1}, +#line 281 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6927, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1071 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6943, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 699 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6948, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 923 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str6980, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 136 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7088, 0x00000004}, +#line 492 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7089, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 90 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7100, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 960 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7162, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1059 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7204, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 413 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7274, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 819 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7282, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 402 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7352, 0x00000002}, + {-1}, +#line 999 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7354, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 264 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7405, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 148 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7415, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 88 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7453, 0x00000005}, + {-1}, {-1}, {-1}, +#line 987 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7457, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 228 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7485, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 270 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7556, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 392 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7573, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 538 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7579, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 340 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7611, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 952 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7656, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 268 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7717, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1067 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7815, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1089 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7842, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 746 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7947, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 1086 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7958, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 688 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str7979, 0x00000009}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 1087 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8002, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1186 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8036, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 893 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8047, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 386 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8146, 0x00000007}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1060 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8174, 0x00000004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 129 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8293, 0x00000002}, + {-1}, {-1}, {-1}, +#line 715 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8297, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 248 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8431, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 267 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8465, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 1010 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8639, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 1031 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8822, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 154 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8840, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 298 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8911, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 1226 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str8920, 0x00000007}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 139 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str9004, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 271 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str9058, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 900 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str9334, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 957 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str9480, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, +#line 956 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str9485, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 955 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str9536, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 888 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str9684, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 86 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str10060, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 1222 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str10341, 0x00000001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 297 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str10494, 0x00000010}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 579 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str10575, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 265 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str11056, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 266 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str11076, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 269 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str11085, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 272 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str11119, 0x00000002}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 975 "fcgenericfamily.gperf" + {(int)(size_t)&((struct FcConstFamilyNamePool_t *)0)->FcConstFamilyNamePool_str12005, 0x00000001} + }; +#if (defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 6) > 4) || (defined __clang__ && __clang_major__ >= 3) +#pragma GCC diagnostic pop +#endif + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register unsigned int key = fc_generic_family_hash (str, len); + + if (key <= MAX_HASH_VALUE) + { + register int o = wordlist[key].name; + if (o >= 0) + { + register const char *s = o + FcConstFamilyNamePool; + + if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strcmp (str, s)) + return &wordlist[key]; + } + } + } + return (struct FcGenericFamilyEntry *) 0; +} +#line 1247 "fcgenericfamily.gperf" + diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/fc-lang/fclang.h b/vendor/libghostty-vt/pkg/fontconfig/override/fc-lang/fclang.h new file mode 100644 index 00000000..dbe2a885 --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/fc-lang/fclang.h @@ -0,0 +1,5586 @@ +/* + * fontconfig/fc-lang/fclang.tmpl.h + * + * Copyright © 2002 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* total size: 1768 unique leaves: 804 */ + +#define LEAF0 (339 * sizeof (FcLangCharSet)) +#define OFF0 (LEAF0 + 804 * sizeof (FcCharLeaf)) +#define NUM0 (OFF0 + 987 * sizeof (uintptr_t)) +#define SET(n) (n * sizeof (FcLangCharSet) + offsetof (FcLangCharSet, charset)) +#define OFF(s,o) (OFF0 + o * sizeof (uintptr_t) - SET(s)) +#define NUM(s,n) (NUM0 + n * sizeof (FcChar16) - SET(s)) +#define LEAF(o,l) (LEAF0 + l * sizeof (FcCharLeaf) - (OFF0 + o * sizeof (intptr_t))) +#define fcLangCharSets (fcLangData.langCharSets) +#define fcLangCharSetIndices (fcLangData.langIndices) +#define fcLangCharSetIndicesInv (fcLangData.langIndicesInv) + +static const struct { + FcLangCharSet langCharSets[339]; + FcCharLeaf leaves[804]; + uintptr_t leaf_offsets[987]; + FcChar16 numbers[987]; + FcChar16 langIndices[339]; + FcChar16 langIndicesInv[339]; +} fcLangData = { +{ + { "aa", { FC_REF_CONSTANT, 1, OFF(0,0), NUM(0,0) } }, /* 0 */ + { "ab", { FC_REF_CONSTANT, 1, OFF(1,1), NUM(1,1) } }, /* 1 */ + { "ae", { FC_REF_CONSTANT, 1, OFF(2,2), NUM(2,2) } }, /* 2 */ + { "af", { FC_REF_CONSTANT, 2, OFF(3,3), NUM(3,3) } }, /* 3 */ + { "agr", { FC_REF_CONSTANT, 1, OFF(4,5), NUM(4,5) } }, /* 4 */ + { "aho", { FC_REF_CONSTANT, 1, OFF(5,6), NUM(5,6) } }, /* 5 */ + { "ak", { FC_REF_CONSTANT, 5, OFF(6,7), NUM(6,7) } }, /* 6 */ + { "akk", { FC_REF_CONSTANT, 6, OFF(7,12), NUM(7,12) } }, /* 7 */ + { "am", { FC_REF_CONSTANT, 2, OFF(8,18), NUM(8,18) } }, /* 8 */ + { "an", { FC_REF_CONSTANT, 1, OFF(9,20), NUM(9,20) } }, /* 9 */ + { "anp", { FC_REF_CONSTANT, 1, OFF(10,21), NUM(10,21) } }, /* 10 */ + { "ar", { FC_REF_CONSTANT, 1, OFF(11,22), NUM(11,22) } }, /* 11 */ + { "arc", { FC_REF_CONSTANT, 1, OFF(12,23), NUM(12,23) } }, /* 12 */ + { "as", { FC_REF_CONSTANT, 1, OFF(13,24), NUM(13,24) } }, /* 13 */ + { "ast", { FC_REF_CONSTANT, 2, OFF(14,25), NUM(14,25) } }, /* 14 */ + { "av", { FC_REF_CONSTANT, 1, OFF(15,27), NUM(15,27) } }, /* 15 */ + { "ay", { FC_REF_CONSTANT, 1, OFF(16,28), NUM(16,28) } }, /* 16 */ + { "ayc", { FC_REF_CONSTANT, 1, OFF(17,29), NUM(17,29) } }, /* 17 */ + { "az-az", { FC_REF_CONSTANT, 3, OFF(18,30), NUM(18,30) } }, /* 18 */ + { "az-ir", { FC_REF_CONSTANT, 1, OFF(19,33), NUM(19,33) } }, /* 19 */ + { "ba", { FC_REF_CONSTANT, 1, OFF(20,34), NUM(20,34) } }, /* 20 */ + { "ban", { FC_REF_CONSTANT, 1, OFF(21,35), NUM(21,35) } }, /* 21 */ + { "bax", { FC_REF_CONSTANT, 1, OFF(22,36), NUM(22,36) } }, /* 22 */ + { "be", { FC_REF_CONSTANT, 1, OFF(23,37), NUM(23,37) } }, /* 23 */ + { "bem", { FC_REF_CONSTANT, 1, OFF(24,38), NUM(24,38) } }, /* 24 */ + { "ber-dz", { FC_REF_CONSTANT, 4, OFF(25,39), NUM(25,39) } }, /* 25 */ + { "ber-ma", { FC_REF_CONSTANT, 1, OFF(26,43), NUM(26,43) } }, /* 26 */ + { "bg", { FC_REF_CONSTANT, 1, OFF(27,44), NUM(27,44) } }, /* 27 */ + { "bh", { FC_REF_CONSTANT, 1, OFF(28,21), NUM(28,21) } }, /* 28 */ + { "bhb", { FC_REF_CONSTANT, 1, OFF(29,21), NUM(29,21) } }, /* 29 */ + { "bho", { FC_REF_CONSTANT, 1, OFF(30,21), NUM(30,21) } }, /* 30 */ + { "bi", { FC_REF_CONSTANT, 1, OFF(31,45), NUM(31,45) } }, /* 31 */ + { "bin", { FC_REF_CONSTANT, 3, OFF(32,46), NUM(32,46) } }, /* 32 */ + { "bku", { FC_REF_CONSTANT, 1, OFF(33,49), NUM(33,49) } }, /* 33 */ + { "blt", { FC_REF_CONSTANT, 1, OFF(34,50), NUM(34,50) } }, /* 34 */ + { "bm", { FC_REF_CONSTANT, 3, OFF(35,51), NUM(35,51) } }, /* 35 */ + { "bn", { FC_REF_CONSTANT, 1, OFF(36,54), NUM(36,54) } }, /* 36 */ + { "bo", { FC_REF_CONSTANT, 1, OFF(37,55), NUM(37,55) } }, /* 37 */ + { "br", { FC_REF_CONSTANT, 1, OFF(38,56), NUM(38,56) } }, /* 38 */ + { "brx", { FC_REF_CONSTANT, 1, OFF(39,57), NUM(39,57) } }, /* 39 */ + { "bs", { FC_REF_CONSTANT, 2, OFF(40,58), NUM(40,58) } }, /* 40 */ + { "bua", { FC_REF_CONSTANT, 1, OFF(41,60), NUM(41,60) } }, /* 41 */ + { "byn", { FC_REF_CONSTANT, 2, OFF(42,61), NUM(42,61) } }, /* 42 */ + { "ca", { FC_REF_CONSTANT, 2, OFF(43,63), NUM(43,63) } }, /* 43 */ + { "ccp", { FC_REF_CONSTANT, 1, OFF(44,65), NUM(44,65) } }, /* 44 */ + { "ce", { FC_REF_CONSTANT, 1, OFF(45,27), NUM(45,27) } }, /* 45 */ + { "ch", { FC_REF_CONSTANT, 1, OFF(46,66), NUM(46,66) } }, /* 46 */ + { "chm", { FC_REF_CONSTANT, 1, OFF(47,67), NUM(47,67) } }, /* 47 */ + { "chr", { FC_REF_CONSTANT, 1, OFF(48,68), NUM(48,68) } }, /* 48 */ + { "cjm", { FC_REF_CONSTANT, 1, OFF(49,69), NUM(49,69) } }, /* 49 */ + { "ckb", { FC_REF_CONSTANT, 1, OFF(50,70), NUM(50,70) } }, /* 50 */ + { "cmn", { FC_REF_CONSTANT, 83, OFF(51,71), NUM(51,71) } }, /* 51 */ + { "co", { FC_REF_CONSTANT, 2, OFF(52,154), NUM(52,154) } }, /* 52 */ + { "cop", { FC_REF_CONSTANT, 2, OFF(53,156), NUM(53,156) } }, /* 53 */ + { "crh", { FC_REF_CONSTANT, 2, OFF(54,158), NUM(54,158) } }, /* 54 */ + { "cs", { FC_REF_CONSTANT, 2, OFF(55,160), NUM(55,160) } }, /* 55 */ + { "csb", { FC_REF_CONSTANT, 2, OFF(56,162), NUM(56,162) } }, /* 56 */ + { "cu", { FC_REF_CONSTANT, 1, OFF(57,164), NUM(57,164) } }, /* 57 */ + { "cv", { FC_REF_CONSTANT, 2, OFF(58,165), NUM(58,165) } }, /* 58 */ + { "cy", { FC_REF_CONSTANT, 3, OFF(59,167), NUM(59,167) } }, /* 59 */ + { "da", { FC_REF_CONSTANT, 1, OFF(60,170), NUM(60,170) } }, /* 60 */ + { "de", { FC_REF_CONSTANT, 1, OFF(61,171), NUM(61,171) } }, /* 61 */ + { "dmf", { FC_REF_CONSTANT, 1, OFF(62,172), NUM(62,172) } }, /* 62 */ + { "doi", { FC_REF_CONSTANT, 1, OFF(63,173), NUM(63,173) } }, /* 63 */ + { "dsb", { FC_REF_CONSTANT, 2, OFF(64,160), NUM(64,160) } }, /* 64 */ + { "dv", { FC_REF_CONSTANT, 1, OFF(65,174), NUM(65,174) } }, /* 65 */ + { "dz", { FC_REF_CONSTANT, 1, OFF(66,55), NUM(66,55) } }, /* 66 */ + { "ecy", { FC_REF_CONSTANT, 1, OFF(67,175), NUM(67,175) } }, /* 67 */ + { "ee", { FC_REF_CONSTANT, 4, OFF(68,176), NUM(68,176) } }, /* 68 */ + { "egy", { FC_REF_CONSTANT, 5, OFF(69,180), NUM(69,180) } }, /* 69 */ + { "eky", { FC_REF_CONSTANT, 1, OFF(70,185), NUM(70,185) } }, /* 70 */ + { "el", { FC_REF_CONSTANT, 1, OFF(71,186), NUM(71,186) } }, /* 71 */ + { "en", { FC_REF_CONSTANT, 1, OFF(72,187), NUM(72,187) } }, /* 72 */ + { "eo", { FC_REF_CONSTANT, 2, OFF(73,188), NUM(73,188) } }, /* 73 */ + { "es", { FC_REF_CONSTANT, 1, OFF(74,20), NUM(74,20) } }, /* 74 */ + { "et", { FC_REF_CONSTANT, 2, OFF(75,190), NUM(75,190) } }, /* 75 */ + { "ett", { FC_REF_CONSTANT, 1, OFF(76,192), NUM(76,192) } }, /* 76 */ + { "eu", { FC_REF_CONSTANT, 1, OFF(77,193), NUM(77,193) } }, /* 77 */ + { "fa", { FC_REF_CONSTANT, 1, OFF(78,33), NUM(78,33) } }, /* 78 */ + { "fat", { FC_REF_CONSTANT, 5, OFF(79,7), NUM(79,7) } }, /* 79 */ + { "ff", { FC_REF_CONSTANT, 3, OFF(80,194), NUM(80,194) } }, /* 80 */ + { "fi", { FC_REF_CONSTANT, 2, OFF(81,197), NUM(81,197) } }, /* 81 */ + { "fil", { FC_REF_CONSTANT, 1, OFF(82,199), NUM(82,199) } }, /* 82 */ + { "fj", { FC_REF_CONSTANT, 1, OFF(83,38), NUM(83,38) } }, /* 83 */ + { "fo", { FC_REF_CONSTANT, 1, OFF(84,200), NUM(84,200) } }, /* 84 */ + { "fr", { FC_REF_CONSTANT, 2, OFF(85,154), NUM(85,154) } }, /* 85 */ + { "fur", { FC_REF_CONSTANT, 1, OFF(86,201), NUM(86,201) } }, /* 86 */ + { "fy", { FC_REF_CONSTANT, 1, OFF(87,202), NUM(87,202) } }, /* 87 */ + { "ga", { FC_REF_CONSTANT, 3, OFF(88,203), NUM(88,203) } }, /* 88 */ + { "gd", { FC_REF_CONSTANT, 1, OFF(89,206), NUM(89,206) } }, /* 89 */ + { "gez", { FC_REF_CONSTANT, 2, OFF(90,207), NUM(90,207) } }, /* 90 */ + { "gl", { FC_REF_CONSTANT, 1, OFF(91,20), NUM(91,20) } }, /* 91 */ + { "gmy", { FC_REF_CONSTANT, 1, OFF(92,209), NUM(92,209) } }, /* 92 */ + { "gn", { FC_REF_CONSTANT, 3, OFF(93,210), NUM(93,210) } }, /* 93 */ + { "got", { FC_REF_CONSTANT, 1, OFF(94,213), NUM(94,213) } }, /* 94 */ + { "gu", { FC_REF_CONSTANT, 1, OFF(95,214), NUM(95,214) } }, /* 95 */ + { "gv", { FC_REF_CONSTANT, 1, OFF(96,215), NUM(96,215) } }, /* 96 */ + { "ha", { FC_REF_CONSTANT, 3, OFF(97,216), NUM(97,216) } }, /* 97 */ + { "hak", { FC_REF_CONSTANT, 83, OFF(98,71), NUM(98,71) } }, /* 98 */ + { "haw", { FC_REF_CONSTANT, 3, OFF(99,219), NUM(99,219) } }, /* 99 */ + { "he", { FC_REF_CONSTANT, 1, OFF(100,222), NUM(100,222) } }, /* 100 */ + { "hi", { FC_REF_CONSTANT, 1, OFF(101,21), NUM(101,21) } }, /* 101 */ + { "hif", { FC_REF_CONSTANT, 1, OFF(102,21), NUM(102,21) } }, /* 102 */ + { "hit", { FC_REF_CONSTANT, 6, OFF(103,12), NUM(103,12) } }, /* 103 */ + { "hlu", { FC_REF_CONSTANT, 3, OFF(104,223), NUM(104,223) } }, /* 104 */ + { "hmd", { FC_REF_CONSTANT, 1, OFF(105,226), NUM(105,226) } }, /* 105 */ + { "hne", { FC_REF_CONSTANT, 1, OFF(106,21), NUM(106,21) } }, /* 106 */ + { "hnn", { FC_REF_CONSTANT, 1, OFF(107,227), NUM(107,227) } }, /* 107 */ + { "ho", { FC_REF_CONSTANT, 1, OFF(108,38), NUM(108,38) } }, /* 108 */ + { "hoc", { FC_REF_CONSTANT, 1, OFF(109,228), NUM(109,228) } }, /* 109 */ + { "hr", { FC_REF_CONSTANT, 2, OFF(110,58), NUM(110,58) } }, /* 110 */ + { "hsb", { FC_REF_CONSTANT, 2, OFF(111,229), NUM(111,229) } }, /* 111 */ + { "ht", { FC_REF_CONSTANT, 1, OFF(112,231), NUM(112,231) } }, /* 112 */ + { "hu", { FC_REF_CONSTANT, 2, OFF(113,232), NUM(113,232) } }, /* 113 */ + { "hy", { FC_REF_CONSTANT, 1, OFF(114,234), NUM(114,234) } }, /* 114 */ + { "hz", { FC_REF_CONSTANT, 3, OFF(115,235), NUM(115,235) } }, /* 115 */ + { "ia", { FC_REF_CONSTANT, 1, OFF(116,38), NUM(116,38) } }, /* 116 */ + { "id", { FC_REF_CONSTANT, 1, OFF(117,238), NUM(117,238) } }, /* 117 */ + { "ie", { FC_REF_CONSTANT, 1, OFF(118,239), NUM(118,239) } }, /* 118 */ + { "ig", { FC_REF_CONSTANT, 2, OFF(119,240), NUM(119,240) } }, /* 119 */ + { "ii", { FC_REF_CONSTANT, 5, OFF(120,242), NUM(120,242) } }, /* 120 */ + { "ik", { FC_REF_CONSTANT, 1, OFF(121,247), NUM(121,247) } }, /* 121 */ + { "io", { FC_REF_CONSTANT, 1, OFF(122,38), NUM(122,38) } }, /* 122 */ + { "is", { FC_REF_CONSTANT, 1, OFF(123,248), NUM(123,248) } }, /* 123 */ + { "it", { FC_REF_CONSTANT, 1, OFF(124,249), NUM(124,249) } }, /* 124 */ + { "iu", { FC_REF_CONSTANT, 3, OFF(125,250), NUM(125,250) } }, /* 125 */ + { "ja", { FC_REF_CONSTANT, 83, OFF(126,253), NUM(126,253) } }, /* 126 */ + { "jv", { FC_REF_CONSTANT, 1, OFF(127,336), NUM(127,336) } }, /* 127 */ + { "ka", { FC_REF_CONSTANT, 1, OFF(128,337), NUM(128,337) } }, /* 128 */ + { "kaa", { FC_REF_CONSTANT, 1, OFF(129,338), NUM(129,338) } }, /* 129 */ + { "kab", { FC_REF_CONSTANT, 4, OFF(130,39), NUM(130,39) } }, /* 130 */ + { "kaw", { FC_REF_CONSTANT, 1, OFF(131,339), NUM(131,339) } }, /* 131 */ + { "khb", { FC_REF_CONSTANT, 1, OFF(132,340), NUM(132,340) } }, /* 132 */ + { "ki", { FC_REF_CONSTANT, 2, OFF(133,341), NUM(133,341) } }, /* 133 */ + { "kj", { FC_REF_CONSTANT, 1, OFF(134,38), NUM(134,38) } }, /* 134 */ + { "kk", { FC_REF_CONSTANT, 1, OFF(135,343), NUM(135,343) } }, /* 135 */ + { "kl", { FC_REF_CONSTANT, 2, OFF(136,344), NUM(136,344) } }, /* 136 */ + { "km", { FC_REF_CONSTANT, 1, OFF(137,346), NUM(137,346) } }, /* 137 */ + { "kn", { FC_REF_CONSTANT, 1, OFF(138,347), NUM(138,347) } }, /* 138 */ + { "ko", { FC_REF_CONSTANT, 45, OFF(139,348), NUM(139,348) } }, /* 139 */ + { "kok", { FC_REF_CONSTANT, 1, OFF(140,21), NUM(140,21) } }, /* 140 */ + { "kr", { FC_REF_CONSTANT, 3, OFF(141,393), NUM(141,393) } }, /* 141 */ + { "ks", { FC_REF_CONSTANT, 1, OFF(142,396), NUM(142,396) } }, /* 142 */ + { "ku-am", { FC_REF_CONSTANT, 2, OFF(143,397), NUM(143,397) } }, /* 143 */ + { "ku-iq", { FC_REF_CONSTANT, 1, OFF(144,70), NUM(144,70) } }, /* 144 */ + { "ku-ir", { FC_REF_CONSTANT, 1, OFF(145,70), NUM(145,70) } }, /* 145 */ + { "ku-tr", { FC_REF_CONSTANT, 2, OFF(146,399), NUM(146,399) } }, /* 146 */ + { "kum", { FC_REF_CONSTANT, 1, OFF(147,401), NUM(147,401) } }, /* 147 */ + { "kv", { FC_REF_CONSTANT, 1, OFF(148,402), NUM(148,402) } }, /* 148 */ + { "kw", { FC_REF_CONSTANT, 3, OFF(149,403), NUM(149,403) } }, /* 149 */ + { "kwm", { FC_REF_CONSTANT, 1, OFF(150,38), NUM(150,38) } }, /* 150 */ + { "ky", { FC_REF_CONSTANT, 1, OFF(151,406), NUM(151,406) } }, /* 151 */ + { "la", { FC_REF_CONSTANT, 2, OFF(152,407), NUM(152,407) } }, /* 152 */ + { "lah", { FC_REF_CONSTANT, 1, OFF(153,409), NUM(153,409) } }, /* 153 */ + { "lb", { FC_REF_CONSTANT, 1, OFF(154,410), NUM(154,410) } }, /* 154 */ + { "lep", { FC_REF_CONSTANT, 1, OFF(155,411), NUM(155,411) } }, /* 155 */ + { "lez", { FC_REF_CONSTANT, 1, OFF(156,27), NUM(156,27) } }, /* 156 */ + { "lg", { FC_REF_CONSTANT, 2, OFF(157,412), NUM(157,412) } }, /* 157 */ + { "li", { FC_REF_CONSTANT, 1, OFF(158,414), NUM(158,414) } }, /* 158 */ + { "lif", { FC_REF_CONSTANT, 1, OFF(159,415), NUM(159,415) } }, /* 159 */ + { "lij", { FC_REF_CONSTANT, 1, OFF(160,416), NUM(160,416) } }, /* 160 */ + { "lis", { FC_REF_CONSTANT, 1, OFF(161,417), NUM(161,417) } }, /* 161 */ + { "ln", { FC_REF_CONSTANT, 4, OFF(162,418), NUM(162,418) } }, /* 162 */ + { "lo", { FC_REF_CONSTANT, 1, OFF(163,422), NUM(163,422) } }, /* 163 */ + { "lt", { FC_REF_CONSTANT, 2, OFF(164,423), NUM(164,423) } }, /* 164 */ + { "lv", { FC_REF_CONSTANT, 2, OFF(165,425), NUM(165,425) } }, /* 165 */ + { "lzh", { FC_REF_CONSTANT, 83, OFF(166,71), NUM(166,71) } }, /* 166 */ + { "mag", { FC_REF_CONSTANT, 1, OFF(167,21), NUM(167,21) } }, /* 167 */ + { "mai", { FC_REF_CONSTANT, 1, OFF(168,21), NUM(168,21) } }, /* 168 */ + { "mfe", { FC_REF_CONSTANT, 2, OFF(169,154), NUM(169,154) } }, /* 169 */ + { "mg", { FC_REF_CONSTANT, 1, OFF(170,427), NUM(170,427) } }, /* 170 */ + { "mh", { FC_REF_CONSTANT, 2, OFF(171,428), NUM(171,428) } }, /* 171 */ + { "mhr", { FC_REF_CONSTANT, 1, OFF(172,401), NUM(172,401) } }, /* 172 */ + { "mi", { FC_REF_CONSTANT, 3, OFF(173,430), NUM(173,430) } }, /* 173 */ + { "mid", { FC_REF_CONSTANT, 1, OFF(174,433), NUM(174,433) } }, /* 174 */ + { "miq", { FC_REF_CONSTANT, 3, OFF(175,434), NUM(175,434) } }, /* 175 */ + { "mjw", { FC_REF_CONSTANT, 1, OFF(176,187), NUM(176,187) } }, /* 176 */ + { "mk", { FC_REF_CONSTANT, 1, OFF(177,437), NUM(177,437) } }, /* 177 */ + { "ml", { FC_REF_CONSTANT, 1, OFF(178,438), NUM(178,438) } }, /* 178 */ + { "mn-cn", { FC_REF_CONSTANT, 1, OFF(179,439), NUM(179,439) } }, /* 179 */ + { "mn-mn", { FC_REF_CONSTANT, 1, OFF(180,440), NUM(180,440) } }, /* 180 */ + { "mni", { FC_REF_CONSTANT, 2, OFF(181,441), NUM(181,441) } }, /* 181 */ + { "mnw", { FC_REF_CONSTANT, 1, OFF(182,443), NUM(182,443) } }, /* 182 */ + { "mo", { FC_REF_CONSTANT, 4, OFF(183,444), NUM(183,444) } }, /* 183 */ + { "mr", { FC_REF_CONSTANT, 1, OFF(184,21), NUM(184,21) } }, /* 184 */ + { "mro", { FC_REF_CONSTANT, 1, OFF(185,448), NUM(185,448) } }, /* 185 */ + { "ms", { FC_REF_CONSTANT, 1, OFF(186,38), NUM(186,38) } }, /* 186 */ + { "mt", { FC_REF_CONSTANT, 2, OFF(187,449), NUM(187,449) } }, /* 187 */ + { "my", { FC_REF_CONSTANT, 1, OFF(188,443), NUM(188,443) } }, /* 188 */ + { "na", { FC_REF_CONSTANT, 2, OFF(189,451), NUM(189,451) } }, /* 189 */ + { "nan", { FC_REF_CONSTANT, 84, OFF(190,453), NUM(190,453) } }, /* 190 */ + { "nb", { FC_REF_CONSTANT, 1, OFF(191,537), NUM(191,537) } }, /* 191 */ + { "nds", { FC_REF_CONSTANT, 1, OFF(192,171), NUM(192,171) } }, /* 192 */ + { "ne", { FC_REF_CONSTANT, 1, OFF(193,538), NUM(193,538) } }, /* 193 */ + { "ng", { FC_REF_CONSTANT, 1, OFF(194,38), NUM(194,38) } }, /* 194 */ + { "nhn", { FC_REF_CONSTANT, 2, OFF(195,539), NUM(195,539) } }, /* 195 */ + { "niu", { FC_REF_CONSTANT, 2, OFF(196,541), NUM(196,541) } }, /* 196 */ + { "nl", { FC_REF_CONSTANT, 1, OFF(197,543), NUM(197,543) } }, /* 197 */ + { "nn", { FC_REF_CONSTANT, 1, OFF(198,544), NUM(198,544) } }, /* 198 */ + { "nnp", { FC_REF_CONSTANT, 1, OFF(199,545), NUM(199,545) } }, /* 199 */ + { "no", { FC_REF_CONSTANT, 1, OFF(200,537), NUM(200,537) } }, /* 200 */ + { "nqo", { FC_REF_CONSTANT, 1, OFF(201,546), NUM(201,546) } }, /* 201 */ + { "nr", { FC_REF_CONSTANT, 1, OFF(202,38), NUM(202,38) } }, /* 202 */ + { "nso", { FC_REF_CONSTANT, 2, OFF(203,547), NUM(203,547) } }, /* 203 */ + { "nv", { FC_REF_CONSTANT, 4, OFF(204,549), NUM(204,549) } }, /* 204 */ + { "ny", { FC_REF_CONSTANT, 2, OFF(205,553), NUM(205,553) } }, /* 205 */ + { "oc", { FC_REF_CONSTANT, 1, OFF(206,555), NUM(206,555) } }, /* 206 */ + { "om", { FC_REF_CONSTANT, 1, OFF(207,38), NUM(207,38) } }, /* 207 */ + { "or", { FC_REF_CONSTANT, 1, OFF(208,556), NUM(208,556) } }, /* 208 */ + { "os", { FC_REF_CONSTANT, 1, OFF(209,401), NUM(209,401) } }, /* 209 */ + { "osa", { FC_REF_CONSTANT, 1, OFF(210,557), NUM(210,557) } }, /* 210 */ + { "ota", { FC_REF_CONSTANT, 1, OFF(211,558), NUM(211,558) } }, /* 211 */ + { "otk", { FC_REF_CONSTANT, 1, OFF(212,559), NUM(212,559) } }, /* 212 */ + { "oui", { FC_REF_CONSTANT, 1, OFF(213,560), NUM(213,560) } }, /* 213 */ + { "pa", { FC_REF_CONSTANT, 1, OFF(214,561), NUM(214,561) } }, /* 214 */ + { "pa-pk", { FC_REF_CONSTANT, 1, OFF(215,409), NUM(215,409) } }, /* 215 */ + { "pal", { FC_REF_CONSTANT, 1, OFF(216,562), NUM(216,562) } }, /* 216 */ + { "pap-an", { FC_REF_CONSTANT, 1, OFF(217,563), NUM(217,563) } }, /* 217 */ + { "pap-aw", { FC_REF_CONSTANT, 1, OFF(218,564), NUM(218,564) } }, /* 218 */ + { "peo", { FC_REF_CONSTANT, 1, OFF(219,565), NUM(219,565) } }, /* 219 */ + { "pgd", { FC_REF_CONSTANT, 1, OFF(220,566), NUM(220,566) } }, /* 220 */ + { "pgl", { FC_REF_CONSTANT, 1, OFF(221,567), NUM(221,567) } }, /* 221 */ + { "phn", { FC_REF_CONSTANT, 1, OFF(222,568), NUM(222,568) } }, /* 222 */ + { "pl", { FC_REF_CONSTANT, 2, OFF(223,569), NUM(223,569) } }, /* 223 */ + { "ps-af", { FC_REF_CONSTANT, 1, OFF(224,571), NUM(224,571) } }, /* 224 */ + { "ps-pk", { FC_REF_CONSTANT, 1, OFF(225,572), NUM(225,572) } }, /* 225 */ + { "pt", { FC_REF_CONSTANT, 1, OFF(226,573), NUM(226,573) } }, /* 226 */ + { "qu", { FC_REF_CONSTANT, 2, OFF(227,574), NUM(227,574) } }, /* 227 */ + { "quz", { FC_REF_CONSTANT, 2, OFF(228,574), NUM(228,574) } }, /* 228 */ + { "raj", { FC_REF_CONSTANT, 1, OFF(229,21), NUM(229,21) } }, /* 229 */ + { "rhg", { FC_REF_CONSTANT, 1, OFF(230,576), NUM(230,576) } }, /* 230 */ + { "rif", { FC_REF_CONSTANT, 4, OFF(231,577), NUM(231,577) } }, /* 231 */ + { "rm", { FC_REF_CONSTANT, 1, OFF(232,581), NUM(232,581) } }, /* 232 */ + { "rn", { FC_REF_CONSTANT, 1, OFF(233,38), NUM(233,38) } }, /* 233 */ + { "ro", { FC_REF_CONSTANT, 3, OFF(234,582), NUM(234,582) } }, /* 234 */ + { "ru", { FC_REF_CONSTANT, 1, OFF(235,401), NUM(235,401) } }, /* 235 */ + { "rw", { FC_REF_CONSTANT, 1, OFF(236,38), NUM(236,38) } }, /* 236 */ + { "sa", { FC_REF_CONSTANT, 1, OFF(237,21), NUM(237,21) } }, /* 237 */ + { "sah", { FC_REF_CONSTANT, 1, OFF(238,585), NUM(238,585) } }, /* 238 */ + { "sam", { FC_REF_CONSTANT, 1, OFF(239,586), NUM(239,586) } }, /* 239 */ + { "sat", { FC_REF_CONSTANT, 1, OFF(240,587), NUM(240,587) } }, /* 240 */ + { "sc", { FC_REF_CONSTANT, 1, OFF(241,588), NUM(241,588) } }, /* 241 */ + { "sco", { FC_REF_CONSTANT, 3, OFF(242,589), NUM(242,589) } }, /* 242 */ + { "sd", { FC_REF_CONSTANT, 1, OFF(243,592), NUM(243,592) } }, /* 243 */ + { "se", { FC_REF_CONSTANT, 2, OFF(244,593), NUM(244,593) } }, /* 244 */ + { "sel", { FC_REF_CONSTANT, 1, OFF(245,401), NUM(245,401) } }, /* 245 */ + { "sg", { FC_REF_CONSTANT, 1, OFF(246,595), NUM(246,595) } }, /* 246 */ + { "sgs", { FC_REF_CONSTANT, 3, OFF(247,596), NUM(247,596) } }, /* 247 */ + { "sh", { FC_REF_CONSTANT, 3, OFF(248,599), NUM(248,599) } }, /* 248 */ + { "shn", { FC_REF_CONSTANT, 1, OFF(249,443), NUM(249,443) } }, /* 249 */ + { "shs", { FC_REF_CONSTANT, 2, OFF(250,602), NUM(250,602) } }, /* 250 */ + { "si", { FC_REF_CONSTANT, 1, OFF(251,604), NUM(251,604) } }, /* 251 */ + { "sid", { FC_REF_CONSTANT, 2, OFF(252,605), NUM(252,605) } }, /* 252 */ + { "sk", { FC_REF_CONSTANT, 2, OFF(253,607), NUM(253,607) } }, /* 253 */ + { "sl", { FC_REF_CONSTANT, 2, OFF(254,58), NUM(254,58) } }, /* 254 */ + { "sm", { FC_REF_CONSTANT, 2, OFF(255,609), NUM(255,609) } }, /* 255 */ + { "sma", { FC_REF_CONSTANT, 1, OFF(256,611), NUM(256,611) } }, /* 256 */ + { "smj", { FC_REF_CONSTANT, 1, OFF(257,612), NUM(257,612) } }, /* 257 */ + { "smn", { FC_REF_CONSTANT, 2, OFF(258,613), NUM(258,613) } }, /* 258 */ + { "sms", { FC_REF_CONSTANT, 3, OFF(259,615), NUM(259,615) } }, /* 259 */ + { "sn", { FC_REF_CONSTANT, 1, OFF(260,38), NUM(260,38) } }, /* 260 */ + { "so", { FC_REF_CONSTANT, 1, OFF(261,618), NUM(261,618) } }, /* 261 */ + { "sog", { FC_REF_CONSTANT, 1, OFF(262,619), NUM(262,619) } }, /* 262 */ + { "sq", { FC_REF_CONSTANT, 1, OFF(263,620), NUM(263,620) } }, /* 263 */ + { "sr", { FC_REF_CONSTANT, 1, OFF(264,621), NUM(264,621) } }, /* 264 */ + { "ss", { FC_REF_CONSTANT, 1, OFF(265,38), NUM(265,38) } }, /* 265 */ + { "st", { FC_REF_CONSTANT, 1, OFF(266,38), NUM(266,38) } }, /* 266 */ + { "su", { FC_REF_CONSTANT, 2, OFF(267,622), NUM(267,622) } }, /* 267 */ + { "sux", { FC_REF_CONSTANT, 6, OFF(268,12), NUM(268,12) } }, /* 268 */ + { "suz", { FC_REF_CONSTANT, 1, OFF(269,624), NUM(269,624) } }, /* 269 */ + { "sv", { FC_REF_CONSTANT, 1, OFF(270,625), NUM(270,625) } }, /* 270 */ + { "sw", { FC_REF_CONSTANT, 1, OFF(271,38), NUM(271,38) } }, /* 271 */ + { "syr", { FC_REF_CONSTANT, 1, OFF(272,626), NUM(272,626) } }, /* 272 */ + { "szl", { FC_REF_CONSTANT, 2, OFF(273,627), NUM(273,627) } }, /* 273 */ + { "ta", { FC_REF_CONSTANT, 1, OFF(274,629), NUM(274,629) } }, /* 274 */ + { "tbw", { FC_REF_CONSTANT, 1, OFF(275,630), NUM(275,630) } }, /* 275 */ + { "tcy", { FC_REF_CONSTANT, 1, OFF(276,347), NUM(276,347) } }, /* 276 */ + { "tdd", { FC_REF_CONSTANT, 1, OFF(277,631), NUM(277,631) } }, /* 277 */ + { "te", { FC_REF_CONSTANT, 1, OFF(278,632), NUM(278,632) } }, /* 278 */ + { "tg", { FC_REF_CONSTANT, 1, OFF(279,633), NUM(279,633) } }, /* 279 */ + { "th", { FC_REF_CONSTANT, 1, OFF(280,634), NUM(280,634) } }, /* 280 */ + { "the", { FC_REF_CONSTANT, 1, OFF(281,21), NUM(281,21) } }, /* 281 */ + { "ti-er", { FC_REF_CONSTANT, 2, OFF(282,61), NUM(282,61) } }, /* 282 */ + { "ti-et", { FC_REF_CONSTANT, 2, OFF(283,605), NUM(283,605) } }, /* 283 */ + { "tig", { FC_REF_CONSTANT, 2, OFF(284,635), NUM(284,635) } }, /* 284 */ + { "tk", { FC_REF_CONSTANT, 2, OFF(285,637), NUM(285,637) } }, /* 285 */ + { "tl", { FC_REF_CONSTANT, 1, OFF(286,639), NUM(286,639) } }, /* 286 */ + { "tn", { FC_REF_CONSTANT, 2, OFF(287,547), NUM(287,547) } }, /* 287 */ + { "to", { FC_REF_CONSTANT, 2, OFF(288,609), NUM(288,609) } }, /* 288 */ + { "tpi", { FC_REF_CONSTANT, 1, OFF(289,187), NUM(289,187) } }, /* 289 */ + { "tr", { FC_REF_CONSTANT, 2, OFF(290,640), NUM(290,640) } }, /* 290 */ + { "ts", { FC_REF_CONSTANT, 1, OFF(291,38), NUM(291,38) } }, /* 291 */ + { "tt", { FC_REF_CONSTANT, 1, OFF(292,642), NUM(292,642) } }, /* 292 */ + { "tw", { FC_REF_CONSTANT, 5, OFF(293,7), NUM(293,7) } }, /* 293 */ + { "txg", { FC_REF_CONSTANT, 28, OFF(294,643), NUM(294,643) } }, /* 294 */ + { "ty", { FC_REF_CONSTANT, 3, OFF(295,671), NUM(295,671) } }, /* 295 */ + { "tyv", { FC_REF_CONSTANT, 1, OFF(296,406), NUM(296,406) } }, /* 296 */ + { "ug", { FC_REF_CONSTANT, 1, OFF(297,674), NUM(297,674) } }, /* 297 */ + { "uga", { FC_REF_CONSTANT, 1, OFF(298,675), NUM(298,675) } }, /* 298 */ + { "uk", { FC_REF_CONSTANT, 1, OFF(299,676), NUM(299,676) } }, /* 299 */ + { "und-zmth", { FC_REF_CONSTANT, 12, OFF(300,677), NUM(300,677) } }, /* 300 */ + { "und-zsye", { FC_REF_CONSTANT, 12, OFF(301,689), NUM(301,689) } }, /* 301 */ + { "unm", { FC_REF_CONSTANT, 1, OFF(302,187), NUM(302,187) } }, /* 302 */ + { "ur", { FC_REF_CONSTANT, 1, OFF(303,409), NUM(303,409) } }, /* 303 */ + { "uz", { FC_REF_CONSTANT, 1, OFF(304,38), NUM(304,38) } }, /* 304 */ + { "vai", { FC_REF_CONSTANT, 2, OFF(305,701), NUM(305,701) } }, /* 305 */ + { "ve", { FC_REF_CONSTANT, 2, OFF(306,703), NUM(306,703) } }, /* 306 */ + { "vi", { FC_REF_CONSTANT, 4, OFF(307,705), NUM(307,705) } }, /* 307 */ + { "vo", { FC_REF_CONSTANT, 1, OFF(308,709), NUM(308,709) } }, /* 308 */ + { "vot", { FC_REF_CONSTANT, 2, OFF(309,710), NUM(309,710) } }, /* 309 */ + { "wa", { FC_REF_CONSTANT, 1, OFF(310,712), NUM(310,712) } }, /* 310 */ + { "wae", { FC_REF_CONSTANT, 1, OFF(311,171), NUM(311,171) } }, /* 311 */ + { "wal", { FC_REF_CONSTANT, 2, OFF(312,605), NUM(312,605) } }, /* 312 */ + { "wen", { FC_REF_CONSTANT, 2, OFF(313,713), NUM(313,713) } }, /* 313 */ + { "wo", { FC_REF_CONSTANT, 2, OFF(314,715), NUM(314,715) } }, /* 314 */ + { "xag", { FC_REF_CONSTANT, 1, OFF(315,717), NUM(315,717) } }, /* 315 */ + { "xco", { FC_REF_CONSTANT, 1, OFF(316,718), NUM(316,718) } }, /* 316 */ + { "xcr", { FC_REF_CONSTANT, 1, OFF(317,719), NUM(317,719) } }, /* 317 */ + { "xh", { FC_REF_CONSTANT, 1, OFF(318,38), NUM(318,38) } }, /* 318 */ + { "xlc", { FC_REF_CONSTANT, 1, OFF(319,720), NUM(319,720) } }, /* 319 */ + { "xld", { FC_REF_CONSTANT, 1, OFF(320,721), NUM(320,721) } }, /* 320 */ + { "xmr", { FC_REF_CONSTANT, 1, OFF(321,722), NUM(321,722) } }, /* 321 */ + { "xna", { FC_REF_CONSTANT, 1, OFF(322,723), NUM(322,723) } }, /* 322 */ + { "xpr", { FC_REF_CONSTANT, 1, OFF(323,724), NUM(323,724) } }, /* 323 */ + { "xsa", { FC_REF_CONSTANT, 1, OFF(324,725), NUM(324,725) } }, /* 324 */ + { "xzh", { FC_REF_CONSTANT, 1, OFF(325,726), NUM(325,726) } }, /* 325 */ + { "yap", { FC_REF_CONSTANT, 1, OFF(326,727), NUM(326,727) } }, /* 326 */ + { "yi", { FC_REF_CONSTANT, 1, OFF(327,222), NUM(327,222) } }, /* 327 */ + { "yo", { FC_REF_CONSTANT, 4, OFF(328,728), NUM(328,728) } }, /* 328 */ + { "yue", { FC_REF_CONSTANT, 171, OFF(329,732), NUM(329,732) } }, /* 329 */ + { "yuw", { FC_REF_CONSTANT, 1, OFF(330,187), NUM(330,187) } }, /* 330 */ + { "za", { FC_REF_CONSTANT, 1, OFF(331,38), NUM(331,38) } }, /* 331 */ + { "zh-cn", { FC_REF_CONSTANT, 82, OFF(332,903), NUM(332,903) } }, /* 332 */ + { "zh-hk", { FC_REF_CONSTANT, 171, OFF(333,732), NUM(333,732) } }, /* 333 */ + { "zh-mo", { FC_REF_CONSTANT, 171, OFF(334,732), NUM(334,732) } }, /* 334 */ + { "zh-sg", { FC_REF_CONSTANT, 82, OFF(335,903), NUM(335,903) } }, /* 335 */ + { "zh-tw", { FC_REF_CONSTANT, 83, OFF(336,71), NUM(336,71) } }, /* 336 */ + { "zkt", { FC_REF_CONSTANT, 2, OFF(337,985), NUM(337,985) } }, /* 337 */ + { "zu", { FC_REF_CONSTANT, 1, OFF(338,38), NUM(338,38) } }, /* 338 */ +}, +{ + { { /* 0 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x08104404, 0x08104404, + } }, + { { /* 1 */ + 0xffff8002, 0xffffffff, 0x8002ffff, 0x00000000, + 0xc0000000, 0xf0fc33c0, 0x03000000, 0x00000003, + } }, + { { /* 2 */ + 0xffffffff, 0xfe3fffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 3 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x0810cf00, 0x0810cf00, + } }, + { { /* 4 */ + 0x00000000, 0x00000000, 0x00000200, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 5 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00000000, 0x04000000, + } }, + { { /* 6 */ + 0xe7ffffff, 0xffff0fff, 0x0000007f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 7 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00220008, 0x00220008, + } }, + { { /* 8 */ + 0x00000000, 0x00000300, 0x00000000, 0x00000300, + 0x00010040, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 9 */ + 0x00000000, 0x00000000, 0x08100000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 10 */ + 0x00000048, 0x00000200, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 11 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x30000000, 0x00000000, 0x03000000, + } }, + { { /* 12 */ + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + } }, + { { /* 13 */ + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x03ffffff, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 14 */ + 0xffffffff, 0xffffffff, 0xffffffff, 0x001f7fff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + } }, + { { /* 15 */ + 0xffffffff, 0xffffffff, 0x0000000f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 16 */ + 0xff7fff7f, 0xff01ff7f, 0x00003d7f, 0xffff7fff, + 0xffff3d7f, 0x003d7fff, 0xff7f7f00, 0x00ff7fff, + } }, + { { /* 17 */ + 0x003d7fff, 0xffffffff, 0x007fff7f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 18 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x140a2202, 0x140a2202, + } }, + { { /* 19 */ + 0xffffffe0, 0x83ffffff, 0x00003fff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 20 */ + 0x00000000, 0x07fffffe, 0x000007fe, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 21 */ + 0x00000000, 0x00000000, 0xffbfffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 22 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xfff99fee, 0xd3c4fdff, 0xb000399f, 0x00030000, + } }, + { { /* 23 */ + 0x00000000, 0x00c00030, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 24 */ + 0xffff0042, 0xffffffff, 0x0002ffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 25 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x10028010, 0x10028010, + } }, + { { /* 26 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00000000, 0x10028010, + } }, + { { /* 27 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x10400080, 0x10400080, + } }, + { { /* 28 */ + 0xc0000000, 0x00030000, 0xc0000000, 0x00000000, + 0x00008000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 29 */ + 0x00000000, 0x00000000, 0x02000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 30 */ + 0x00000000, 0x07ffffde, 0x001009f6, 0x40000000, + 0x01000040, 0x00008200, 0x00001000, 0x00000000, + } }, + { { /* 31 */ + 0xffff0000, 0xffffffff, 0x0000ffff, 0x00000000, + 0x030c0000, 0x0c00cc0f, 0x03000000, 0x00000300, + } }, + { { /* 32 */ + 0xffffffff, 0xffffffff, 0xffff0fff, 0x1fffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 33 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x00ffffff, + } }, + { { /* 34 */ + 0xffff4040, 0xffffffff, 0x4040ffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 35 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 36 */ + 0x00003000, 0x00000000, 0x00000000, 0x00000000, + 0x00110000, 0x00000000, 0x00000000, 0x000000c0, + } }, + { { /* 37 */ + 0x00000000, 0x00000000, 0x08000000, 0x00000008, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 38 */ + 0x00003000, 0x00000030, 0x00000000, 0x0000300c, + 0x000c0000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 39 */ + 0x00000000, 0x3a8b0000, 0x9e78e6b9, 0x0000802e, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 40 */ + 0xffff0000, 0xffffd7ff, 0x0000d7ff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 41 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x10008200, 0x10008200, + } }, + { { /* 42 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x060c3303, 0x060c3303, + } }, + { { /* 43 */ + 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 44 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x03000000, 0x00003000, 0x00000000, + } }, + { { /* 45 */ + 0x00000000, 0x00000000, 0x000fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 46 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0xf8000007, 0x00000000, + } }, + { { /* 47 */ + 0x00000000, 0x00000000, 0x00000c00, 0x00000000, + 0x20010040, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 48 */ + 0x00000000, 0x00000000, 0x08100000, 0x00040000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 49 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xfff99fee, 0xd3c5fdff, 0xb000399f, 0x00000000, + } }, + { { /* 50 */ + 0x00000000, 0x00000000, 0xfffffeff, 0x3d7e03ff, + 0xfeff0003, 0x03ffffff, 0x00000000, 0x00000000, + } }, + { { /* 51 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x12120404, 0x12120404, + } }, + { { /* 52 */ + 0xfff99fee, 0xf3e5fdff, 0x0007399f, 0x0001ffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 53 */ + 0x000330c0, 0x00000000, 0x00000000, 0x60000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 54 */ + 0xffff0002, 0xffffffff, 0x0002ffff, 0x00000000, + 0x00000000, 0x0c00c000, 0x00000000, 0x00000000, + } }, + { { /* 55 */ + 0xff7fff7f, 0xff01ff00, 0x3d7f3d7f, 0xffff7fff, + 0xffff0000, 0x003d7fff, 0xff7f7f3d, 0x00ff7fff, + } }, + { { /* 56 */ + 0x003d7fff, 0xffffffff, 0x007fff00, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 57 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x140ca381, 0x140ca381, + } }, + { { /* 58 */ + 0x00000000, 0x80000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 59 */ + 0xffffffff, 0xffdfffff, 0x000000ff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 60 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x10020004, 0x10020004, + } }, + { { /* 61 */ + 0xffff0002, 0xffffffff, 0x0002ffff, 0x00000000, + 0x00000000, 0x00000030, 0x000c0000, 0x030300c0, + } }, + { { /* 62 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x001fffff, + } }, + { { /* 63 */ + 0xffffffff, 0x007fffff, 0xf3ff3fff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 64 */ + 0x00000000, 0x061ef5c0, 0x000001f6, 0x40000000, + 0x01040040, 0x00208210, 0x00005040, 0x00000000, + } }, + { { /* 65 */ + 0xc373ff8b, 0x1b0f6840, 0xf34ce9ac, 0xc0080200, + 0xca3e795c, 0x06487976, 0xf7f02fdf, 0xa8ff033a, + } }, + { { /* 66 */ + 0x233fef37, 0xfd59b004, 0xfffff3ca, 0xfff9de9f, + 0x7df7abff, 0x8eecc000, 0xffdbeebf, 0x45fad003, + } }, + { { /* 67 */ + 0xdffefae1, 0x10abbfef, 0xfcaaffeb, 0x24fdef3f, + 0x7f7678ad, 0xedfff00c, 0x2cfacff6, 0xeb6bf7f9, + } }, + { { /* 68 */ + 0x95bf1ffd, 0xbfbf6677, 0xfeb43bfb, 0x11e27bae, + 0x41bea681, 0x72c31435, 0x71917d70, 0x276b0003, + } }, + { { /* 69 */ + 0x70cf57cb, 0x0def4732, 0xfc747eda, 0xbdb4fe06, + 0x8bca3f9f, 0x58007e49, 0xebec228f, 0xddbb8a5c, + } }, + { { /* 70 */ + 0xb6e7ef60, 0xf293a40f, 0x549e37bb, 0x9bafd04b, + 0xf7d4c414, 0x0a1430b0, 0x88d02f08, 0x192fff7e, + } }, + { { /* 71 */ + 0xfb07ffda, 0x7beb7ff1, 0x0010c5ef, 0xfdff99ff, + 0x056779d7, 0xfdcbffe7, 0x4040c3ff, 0xbd8e6ff7, + } }, + { { /* 72 */ + 0x0497dffa, 0x5bfff4c0, 0xd0e7ed7b, 0xf8e0047e, + 0xb73eff9f, 0x882e7dfe, 0xbe7ffffd, 0xf6c483fe, + } }, + { { /* 73 */ + 0xb8fdf357, 0xef7dd680, 0x47885767, 0xc3dfff7d, + 0x37a9f0ff, 0x70fc7de0, 0xec9a3f6f, 0x86814cb3, + } }, + { { /* 74 */ + 0xdd5c3f9e, 0x4819f70d, 0x0007fea3, 0x38ffaf56, + 0xefb8980d, 0xb760403d, 0x9035d8ce, 0x3fff72bf, + } }, + { { /* 75 */ + 0x7a117ff7, 0xabfff7bb, 0x6fbeff00, 0xfe72a93c, + 0xf11bcfef, 0xf40adb6b, 0xef7ec3e6, 0xf6109b9c, + } }, + { { /* 76 */ + 0x16f4f048, 0x5182feb5, 0x15bbc7b1, 0xfbdf6e87, + 0x63cde43f, 0x7e7ec1ff, 0x7d5ffdeb, 0xfcfe777b, + } }, + { { /* 77 */ + 0xdbea960b, 0x53e86229, 0xfdef37df, 0xbd8136f5, + 0xfcbddc18, 0xffffd2e4, 0xffe03fd7, 0xabf87f6f, + } }, + { { /* 78 */ + 0x6ed99bae, 0xf115f5fb, 0xbdfb79a9, 0xadaf5a3c, + 0x1facdbba, 0x837971fc, 0xc35f7cf7, 0x0567dfff, + } }, + { { /* 79 */ + 0x8467ff9a, 0xdf8b1534, 0x3373f9f3, 0x5e1af7bd, + 0xa03fbf40, 0x01ebffff, 0xcfdddfc0, 0xabd37500, + } }, + { { /* 80 */ + 0xeed6f8c3, 0xb7ff43fd, 0x42275eaf, 0xf6869bac, + 0xf6bc27d7, 0x35b7f787, 0xe176aacd, 0xe29f49e7, + } }, + { { /* 81 */ + 0xaff2545c, 0x61d82b3f, 0xbbb8fc3b, 0x7b7dffcf, + 0x1ce0bf95, 0x43ff7dfd, 0xfffe5ff6, 0xc4ced3ef, + } }, + { { /* 82 */ + 0xadbc8db6, 0x11eb63dc, 0x23d0df59, 0xf3dbbeb4, + 0xdbc71fe7, 0xfae4ff63, 0x63f7b22b, 0xadbaed3b, + } }, + { { /* 83 */ + 0x7efffe01, 0x02bcfff7, 0xef3932ff, 0x8005fffc, + 0xbcf577fb, 0xfff7010d, 0xbf3afffb, 0xdfff0057, + } }, + { { /* 84 */ + 0xbd7def7b, 0xc8d4db88, 0xed7cfff3, 0x56ff5dee, + 0xac5f7e0d, 0xd57fff96, 0xc1403fee, 0xffe76ff9, + } }, + { { /* 85 */ + 0x8e77779b, 0xe45d6ebf, 0x5f1f6fcf, 0xfedfe07f, + 0x01fed7db, 0xfb7bff00, 0x1fdfffd4, 0xfffff800, + } }, + { { /* 86 */ + 0x007bfb8f, 0x7f5cbf00, 0x07f3ffff, 0x3de7eba0, + 0xfbd7f7bf, 0x6003ffbf, 0xbfedfffd, 0x027fefbb, + } }, + { { /* 87 */ + 0xddfdfe40, 0xe2f9fdff, 0xfb1f680b, 0xaffdfbe3, + 0xf7ed9fa4, 0xf80f7a7d, 0x0fd5eebe, 0xfd9fbb5d, + } }, + { { /* 88 */ + 0x3bf9f2db, 0xebccfe7f, 0x73fa876a, 0x9ffc95fc, + 0xfaf7109f, 0xbbcdddb7, 0xeccdf87e, 0x3c3ff366, + } }, + { { /* 89 */ + 0xb03ffffd, 0x067ee9f7, 0xfe0696ae, 0x5fd7d576, + 0xa3f33fd1, 0x6fb7cf07, 0x7f449fd1, 0xd3dd7b59, + } }, + { { /* 90 */ + 0xa9bdaf3b, 0xff3a7dcf, 0xf6ebfbe0, 0xffffb401, + 0xb7bf7afa, 0x0ffdc000, 0xff1fff7f, 0x95fffefc, + } }, + { { /* 91 */ + 0xb5dc0000, 0x3f3eef63, 0x001bfb7f, 0xfbf6e800, + 0xb8df9eef, 0x003fff9f, 0xf5ff7bd0, 0x3fffdfdb, + } }, + { { /* 92 */ + 0x00bffdf0, 0xbbbd8420, 0xffdedf37, 0x0ff3ff6d, + 0x5efb604c, 0xfafbfffb, 0x0219fe5e, 0xf9de79f4, + } }, + { { /* 93 */ + 0xebfaa7f7, 0xff3401eb, 0xef73ebd3, 0xc040afd7, + 0xdcff72bb, 0x2fd8f17f, 0xfe0bb8ec, 0x1f0bdda3, + } }, + { { /* 94 */ + 0x47cf8f1d, 0xffdeb12b, 0xda737fee, 0xcbc424ff, + 0xcbf2f75d, 0xb4edecfd, 0x4dddbff9, 0xfb8d99dd, + } }, + { { /* 95 */ + 0xaf7bbb7f, 0xc959ddfb, 0xfab5fc4f, 0x6d5fafe3, + 0x3f7dffff, 0xffdb7800, 0x7effb6ff, 0x022ffbaf, + } }, + { { /* 96 */ + 0xefc7ff9b, 0xffffffa5, 0xc7000007, 0xfff1f7ff, + 0x01bf7ffd, 0xfdbcdc00, 0xffffbff5, 0x3effff7f, + } }, + { { /* 97 */ + 0xbe000029, 0xff7ff9ff, 0xfd7e6efb, 0x039ecbff, + 0xfbdde300, 0xf6dfccff, 0x117fffff, 0xfbf6f800, + } }, + { { /* 98 */ + 0xd73ce7ef, 0xdfeffeef, 0xedbfc00b, 0xfdcdfedf, + 0x40fd7bf5, 0xb75fffff, 0xf930ffdf, 0xdc97fbdf, + } }, + { { /* 99 */ + 0xbff2fef3, 0xdfbf8fdf, 0xede6177f, 0x35530f7f, + 0x877e447c, 0x45bbfa12, 0x779eede0, 0xbfd98017, + } }, + { { /* 100 */ + 0xde897e55, 0x0447c16f, 0xf75d7ade, 0x290557ff, + 0xfe9586f7, 0xf32f97b3, 0x9f75cfff, 0xfb1771f7, + } }, + { { /* 101 */ + 0xee1934ee, 0xef6137cc, 0xef4c9fd6, 0xfbddd68f, + 0x6def7b73, 0xa431d7fe, 0x97d75e7f, 0xffd80f5b, + } }, + { { /* 102 */ + 0x7bce9d83, 0xdcff22ec, 0xef87763d, 0xfdeddfe7, + 0xa0fc4fff, 0xdbfc3b77, 0x7fdc3ded, 0xf5706fa9, + } }, + { { /* 103 */ + 0x2c403ffb, 0x847fff7f, 0xdeb7ec57, 0xf22fe69c, + 0xd5b50feb, 0xede7afeb, 0xfff08c2f, 0xe8f0537f, + } }, + { { /* 104 */ + 0xb5ffb99d, 0xe78fff66, 0xbe10d981, 0xe3c19c7c, + 0x27339cd1, 0xff6d0cbc, 0xefb7fcb7, 0xffffa0df, + } }, + { { /* 105 */ + 0xfe7bbf0b, 0x353fa3ff, 0x97cd13cc, 0xfb277637, + 0x7e6ccfd6, 0xed31ec50, 0xfc1c677c, 0x5fbff6fa, + } }, + { { /* 106 */ + 0xae2f0fba, 0x7ffea3ad, 0xde74fcf0, 0xf200ffef, + 0xfea2fbbf, 0xbcff3daf, 0x5fb9f694, 0x3f8ff3ad, + } }, + { { /* 107 */ + 0xa01ff26c, 0x01bfffef, 0x70057728, 0xda03ff35, + 0xc7fad2f9, 0x5c1d3fbf, 0xec33ff3a, 0xfe9cb7af, + } }, + { { /* 108 */ + 0x7a9f5236, 0xe722bffa, 0xfcff9ff7, 0xb61d2fbb, + 0x1dfded06, 0xefdf7dd7, 0xf166eb23, 0x0dc07ed9, + } }, + { { /* 109 */ + 0xdfbf3d3d, 0xba83c945, 0x9dd07dd1, 0xcf737b87, + 0xc3f59ff3, 0xc5fedf0d, 0x83020cb3, 0xaec0e879, + } }, + { { /* 110 */ + 0x6f0fc773, 0x093ffd7d, 0x0157fff1, 0x01ff62fb, + 0x3bf3fdb4, 0x43b2b013, 0xff305ed3, 0xeb9f0fff, + } }, + { { /* 111 */ + 0xf203feef, 0xfb893fef, 0x9e9937a9, 0xa72cdef9, + 0xc1f63733, 0xfe3e812e, 0xf2f75d20, 0x69d7d585, + } }, + { { /* 112 */ + 0xffffffff, 0xff6fdb07, 0xd97fc4ff, 0xbe0fefce, + 0xf05ef17b, 0xffb7f6cf, 0xef845ef7, 0x0edfd7cb, + } }, + { { /* 113 */ + 0xfcffff08, 0xffffee3f, 0xd7ff13ff, 0x7ffdaf0f, + 0x1ffabdc7, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 114 */ + 0x00000000, 0xe7400000, 0xf933bd38, 0xfeed7feb, + 0x7c767fe8, 0xffefb3f7, 0xd8b7feaf, 0xfbbfff6f, + } }, + { { /* 115 */ + 0xdbf7f8fb, 0xe2f91752, 0x754785c8, 0xe3ef9090, + 0x3f6d9ef4, 0x0536ee2e, 0x7ff3f7bc, 0x7f3fa07b, + } }, + { { /* 116 */ + 0xeb600567, 0x6601babe, 0x583ffcd8, 0x87dfcaf7, + 0xffa0bfcd, 0xfebf5bcd, 0xefa7b6fd, 0xdf9c77ef, + } }, + { { /* 117 */ + 0xf8773fb7, 0xb7fc9d27, 0xdfefcab5, 0xf1b6fb5a, + 0xef1fec39, 0x7ffbfbbf, 0xdafe000d, 0x4e7fbdfb, + } }, + { { /* 118 */ + 0x5ac033ff, 0x9ffebff5, 0x005fffbf, 0xfdf80000, + 0x6ffdffca, 0xa001cffd, 0xfbf2dfff, 0xff7fdfbf, + } }, + { { /* 119 */ + 0x080ffeda, 0xbfffba08, 0xeed77afd, 0x67f9fbeb, + 0xff93e044, 0x9f57df97, 0x08dffef7, 0xfedfdf80, + } }, + { { /* 120 */ + 0xf7feffc5, 0x6803fffb, 0x6bfa67fb, 0x5fe27fff, + 0xff73ffff, 0xe7fb87df, 0xf7a7ebfd, 0xefc7bf7e, + } }, + { { /* 121 */ + 0xdf821ef3, 0xdf7e76ff, 0xda7d79c9, 0x1e9befbe, + 0x77fb7ce0, 0xfffb87be, 0xffdb1bff, 0x4fe03f5c, + } }, + { { /* 122 */ + 0x5f0e7fff, 0xddbf77ff, 0xfffff04f, 0x0ff8ffff, + 0xfddfa3be, 0xfffdfc1c, 0xfb9e1f7d, 0xdedcbdff, + } }, + { { /* 123 */ + 0xbafb3f6f, 0xfbefdf7f, 0x2eec7d1b, 0xf2f7af8e, + 0xcfee7b0f, 0x77c61d96, 0xfff57e07, 0x7fdfd982, + } }, + { { /* 124 */ + 0xc7ff5ee6, 0x79effeee, 0xffcf9a56, 0xde5efe5f, + 0xf9e8896e, 0xe6c4f45e, 0xbe7c0001, 0xdddf3b7f, + } }, + { { /* 125 */ + 0xe9efd59d, 0xde5334ac, 0x4bf7f573, 0x9eff7b4f, + 0x476eb8fe, 0xff450dfb, 0xfbfeabfd, 0xddffe9d7, + } }, + { { /* 126 */ + 0x7fffedf7, 0x7eebddfd, 0xb7ffcfe7, 0xef91bde9, + 0xd77c5d75, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 127 */ + 0x00000000, 0xfa800000, 0xb4f1ffee, 0x2fefbf76, + 0x77bfb677, 0xfffd9fbf, 0xf6ae95bf, 0x7f3b75ff, + } }, + { { /* 128 */ + 0x0af9a7f5, 0x00000000, 0x00000000, 0x2bddfbd0, + 0x9a7ff633, 0xd6fcfdab, 0xbfebf9e6, 0xf41fdfdf, + } }, + { { /* 129 */ + 0xffffa6fd, 0xf37b4aff, 0xfef97fb7, 0x1d5cb6ff, + 0xe5ff7ff6, 0x24041f7b, 0xf99ebe05, 0xdff2dbe3, + } }, + { { /* 130 */ + 0xfdff6fef, 0xcbfcd679, 0xefffebfd, 0x0000001f, + 0x98000000, 0x8017e148, 0x00fe6a74, 0xfdf16d7f, + } }, + { { /* 131 */ + 0xfef3b87f, 0xf176e01f, 0x7b3fee96, 0xfffdeb8d, + 0xcbb3adff, 0xe17f84ef, 0xbff04daa, 0xfe3fbf3f, + } }, + { { /* 132 */ + 0xffd7ebff, 0xcf7fffdf, 0x85edfffb, 0x07bcd73f, + 0xfe0faeff, 0x76bffdaf, 0x37bbfaef, 0xa3ba7fdc, + } }, + { { /* 133 */ + 0x56f7b6ff, 0xe7df60f8, 0x4cdfff61, 0xff45b0fb, + 0x3ffa7ded, 0x18fc1fff, 0xe3afffff, 0xdf83c7d3, + } }, + { { /* 134 */ + 0xef7dfb57, 0x1378efff, 0x5ff7fec0, 0x5ee334bb, + 0xeff6f70d, 0x00bfd7fe, 0xf7f7f59d, 0xffe051de, + } }, + { { /* 135 */ + 0x037ffec9, 0xbfef5f01, 0x60a79ff1, 0xf1ffef1d, + 0x0000000f, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 136 */ + 0x00000000, 0x00000000, 0x00000000, 0x3c800000, + 0xd91ffb4d, 0xfee37b3a, 0xdc7f3fe9, 0x0000003f, + } }, + { { /* 137 */ + 0x50000000, 0xbe07f51f, 0xf91bfc1d, 0x71ffbc1e, + 0x5bbe6ff9, 0x9b1b5796, 0xfffc7fff, 0xafe7872e, + } }, + { { /* 138 */ + 0xf34febf5, 0xe725dffd, 0x5d440bdc, 0xfddd5747, + 0x7790ed3f, 0x8ac87d7f, 0xf3f9fafa, 0xef4b202a, + } }, + { { /* 139 */ + 0x79cff5ff, 0x0ba5abd3, 0xfb8ff77a, 0x001f8ebd, + 0x00000000, 0xfd4ef300, 0x88001a57, 0x7654aeac, + } }, + { { /* 140 */ + 0xcdff17ad, 0xf42fffb2, 0xdbff5baa, 0x00000002, + 0x73c00000, 0x2e3ff9ea, 0xbbfffa8e, 0xffd376bc, + } }, + { { /* 141 */ + 0x7e72eefe, 0xe7f77ebd, 0xcefdf77f, 0x00000ff5, + 0x00000000, 0xdb9ba900, 0x917fa4c7, 0x7ecef8ca, + } }, + { { /* 142 */ + 0xc7e77d7a, 0xdcaecbbd, 0x8f76fd7e, 0x7cf391d3, + 0x4c2f01e5, 0xa360ed77, 0x5ef807db, 0x21811df7, + } }, + { { /* 143 */ + 0x309c6be0, 0xfade3b3a, 0xc3f57f53, 0x07ba61cd, + 0x00000000, 0x00000000, 0x00000000, 0xbefe26e0, + } }, + { { /* 144 */ + 0xebb503f9, 0xe9cbe36d, 0xbfde9c2f, 0xabbf9f83, + 0xffd51ff7, 0xdffeb7df, 0xffeffdae, 0xeffdfb7e, + } }, + { { /* 145 */ + 0x6ebfaaff, 0x00000000, 0x00000000, 0xb6200000, + 0xbe9e7fcd, 0x58f162b3, 0xfd7bf10d, 0xbefde9f1, + } }, + { { /* 146 */ + 0x5f6dc6c3, 0x69ffff3d, 0xfbf4ffcf, 0x4ff7dcfb, + 0x11372000, 0x00000015, 0x00000000, 0x00000000, + } }, + { { /* 147 */ + 0x00003000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 148 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x1a10cfc5, 0x9a10cfc5, + } }, + { { /* 149 */ + 0x00000000, 0x00000000, 0x000c0000, 0x01000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 150 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x0000fffc, + } }, + { { /* 151 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0xffffffff, 0xfe0fffff, + } }, + { { /* 152 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x10420084, 0x10420084, + } }, + { { /* 153 */ + 0xc0000000, 0x00030000, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 154 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x24082202, 0x24082202, + } }, + { { /* 155 */ + 0x0c00f000, 0x00000000, 0x03000180, 0x6000c033, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 156 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x021c0a08, 0x021c0a08, + } }, + { { /* 157 */ + 0x00000030, 0x00000000, 0x0000001e, 0x18000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 158 */ + 0xfdffa966, 0xffffdfff, 0xa965dfff, 0x03ffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 159 */ + 0x0000000c, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 160 */ + 0xffff0002, 0xffffffff, 0x0002ffff, 0x00000000, + 0x00000000, 0x00000c00, 0x00c00000, 0x000c0000, + } }, + { { /* 161 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x0010c604, 0x8010c604, + } }, + { { /* 162 */ + 0x00000000, 0x00000000, 0x00000000, 0x01f00000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 163 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x0000003f, 0x00000000, 0x00000000, 0x000c0000, + } }, + { { /* 164 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x25082262, 0x25082262, + } }, + { { /* 165 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x90400010, 0x10400010, + } }, + { { /* 166 */ + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x07ffffff, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 167 */ + 0xfff99fec, 0xf3e5fdff, 0xf807399f, 0x0000ffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 168 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0x0001ffff, 0x00000000, 0x00000000, + } }, + { { /* 169 */ + 0xfffffd3f, 0x91bfffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 170 */ + 0x0c000000, 0x00000000, 0x00000c00, 0x00000000, + 0x00170240, 0x00040000, 0x001fe000, 0x00000000, + } }, + { { /* 171 */ + 0x00000000, 0x00000000, 0x08500000, 0x00000008, + 0x00000800, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 172 */ + 0x00001003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 173 */ + 0xffffffff, 0x0000ffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 174 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffd740, 0xfffffffb, 0x00007fff, 0x00000000, + } }, + { { /* 175 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00528f81, 0x00528f81, + } }, + { { /* 176 */ + 0x30000300, 0x00300030, 0x30000000, 0x00003000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 177 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x10600010, 0x10600010, + } }, + { { /* 178 */ + 0x00000000, 0x00000000, 0x00000000, 0x60000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 179 */ + 0xffffffff, 0x0000e00f, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 180 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x10020000, 0x10020000, + } }, + { { /* 181 */ + 0x00000000, 0x00000000, 0x00000c00, 0x00000000, + 0x20000402, 0x00180000, 0x00000000, 0x00000000, + } }, + { { /* 182 */ + 0x00000000, 0x00000000, 0x00880000, 0x00040000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 183 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00400030, 0x00400030, + } }, + { { /* 184 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x0e1e7707, 0x0e1e7707, + } }, + { { /* 185 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x25092042, 0x25092042, + } }, + { { /* 186 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x02041107, 0x02041107, + } }, + { { /* 187 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x9c508e14, 0x1c508e14, + } }, + { { /* 188 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x04082202, 0x04082202, + } }, + { { /* 189 */ + 0x00000c00, 0x00000003, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 190 */ + 0xc0000c0c, 0x00000000, 0x00c00003, 0x00000c03, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 191 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x020c1383, 0x020c1383, + } }, + { { /* 192 */ + 0xff7fff7f, 0xff01ff7f, 0x00003d7f, 0x00ff00ff, + 0x00ff3d7f, 0x003d7fff, 0xff7f7f00, 0x00ff7f00, + } }, + { { /* 193 */ + 0x003d7f00, 0xffff01ff, 0x007fff7f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 194 */ + 0xffffefff, 0xb7ffff7f, 0x3fff3fff, 0x00000000, + 0xffffffff, 0xffffffff, 0xffffffff, 0x07ffffff, + } }, + { { /* 195 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x040a2202, 0x042a220a, + } }, + { { /* 196 */ + 0x00000000, 0x00000200, 0x00000000, 0x00000200, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 197 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x20000000, 0x00000000, 0x02000000, + } }, + { { /* 198 */ + 0x00000000, 0xffff0000, 0x000007ff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 199 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xfffbafee, 0xf3edfdff, 0x00013bbf, 0x00000001, + } }, + { { /* 200 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00000080, 0x00000080, + } }, + { { /* 201 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x03000402, 0x00180000, 0x00000000, 0x00000000, + } }, + { { /* 202 */ + 0x00000000, 0x00000000, 0x00880000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 203 */ + 0x000c0003, 0x00000c00, 0x00003000, 0x00000c00, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 204 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x08000000, 0x00000000, 0x00000000, + } }, + { { /* 205 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffff0000, 0x000007ff, + } }, + { { /* 206 */ + 0xffffffff, 0xffffffff, 0x0000007f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 207 */ + 0xffffffff, 0xffffffff, 0xffff87ff, 0xffffffff, + 0xffff80ff, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 208 */ + 0x00000000, 0x007fffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 209 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x8007ffff, + } }, + { { /* 210 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00080000, 0x00080000, + } }, + { { /* 211 */ + 0x0c0030c0, 0x00000000, 0x0300001e, 0x66000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 212 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00040100, 0x00040100, + } }, + { { /* 213 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x14482202, 0x14482202, + } }, + { { /* 214 */ + 0x00000000, 0x00000000, 0x00030000, 0x00030000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 215 */ + 0x00000000, 0xfffe0000, 0x007fffff, 0xfffffffe, + 0x000000ff, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 216 */ + 0x00000000, 0x00008000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 217 */ + 0x000c0000, 0x00000000, 0x00000c00, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 218 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00000200, 0x00000200, + } }, + { { /* 219 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00003c00, 0x00000030, + } }, + { { /* 220 */ + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x00001fff, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 221 */ + 0xffff4002, 0xffffffff, 0x4002ffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 222 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x64092242, 0x64092242, + } }, + { { /* 223 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x060cb301, 0x060cb301, + } }, + { { /* 224 */ + 0x00000c7e, 0x031f8000, 0x0063f200, 0x000df840, + 0x00037e08, 0x08000dfa, 0x0df901bf, 0x5437e400, + } }, + { { /* 225 */ + 0x00000025, 0x40006fc0, 0x27f91be4, 0xdee00000, + 0x007ff83f, 0x00007f7f, 0x00000000, 0x00000000, + } }, + { { /* 226 */ + 0x00000000, 0x00000000, 0x00000000, 0x007f8000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 227 */ + 0x000000a7, 0x00000000, 0xfffffffe, 0xffffffff, + 0x780fffff, 0xfffffffe, 0xffffffff, 0x787fffff, + } }, + { { /* 228 */ + 0x03506f8b, 0x1b042042, 0x62808020, 0x400a0000, + 0x10341b41, 0x04003812, 0x03608c02, 0x08454038, + } }, + { { /* 229 */ + 0x2403c002, 0x15108000, 0x1229e040, 0x80280000, + 0x28002800, 0x8060c002, 0x2080040c, 0x05284002, + } }, + { { /* 230 */ + 0x82042a00, 0x02000818, 0x10008200, 0x20700020, + 0x03022000, 0x40a41000, 0x0420a020, 0x00000080, + } }, + { { /* 231 */ + 0x80040011, 0x00000400, 0x04012b78, 0x11a23920, + 0x02842460, 0x00c01021, 0x20002050, 0x07400042, + } }, + { { /* 232 */ + 0x208205c9, 0x0fc10230, 0x08402480, 0x00258018, + 0x88000080, 0x42120609, 0xa32002a8, 0x40040094, + } }, + { { /* 233 */ + 0x00c00024, 0x8e000001, 0x059e058a, 0x013b0001, + 0x85000010, 0x08080000, 0x02d07d04, 0x018d9838, + } }, + { { /* 234 */ + 0x8803f310, 0x03000840, 0x00000704, 0x30080500, + 0x00001000, 0x20040000, 0x00000003, 0x04040002, + } }, + { { /* 235 */ + 0x000100d0, 0x40028000, 0x00088040, 0x00000000, + 0x34000210, 0x00400e00, 0x00000020, 0x00000008, + } }, + { { /* 236 */ + 0x00000040, 0x00060000, 0x00000000, 0x00100100, + 0x00000080, 0x00000000, 0x4c000000, 0x240d0009, + } }, + { { /* 237 */ + 0x80048000, 0x00010180, 0x00020484, 0x00000400, + 0x00000804, 0x00000008, 0x80004800, 0x16800000, + } }, + { { /* 238 */ + 0x00200065, 0x00120410, 0x44920403, 0x40000200, + 0x10880008, 0x40080100, 0x00001482, 0x00074800, + } }, + { { /* 239 */ + 0x14608200, 0x00024e84, 0x00128380, 0x20184520, + 0x0240041c, 0x0a001120, 0x00180a00, 0x88000800, + } }, + { { /* 240 */ + 0x01000002, 0x00008001, 0x04000040, 0x80000040, + 0x08040000, 0x00000000, 0x00001202, 0x00000002, + } }, + { { /* 241 */ + 0x00000000, 0x00000004, 0x21910000, 0x00000858, + 0xbf8013a0, 0x8279401c, 0xa8041054, 0xc5004282, + } }, + { { /* 242 */ + 0x0402ce56, 0xfc020000, 0x40200d21, 0x00028030, + 0x00010000, 0x01081202, 0x00000000, 0x00410003, + } }, + { { /* 243 */ + 0x00404080, 0x00000200, 0x00010000, 0x00000000, + 0x00000000, 0x00000000, 0x60000000, 0x480241ea, + } }, + { { /* 244 */ + 0x2000104c, 0x2109a820, 0x00200020, 0x7b1c0008, + 0x10a0840a, 0x01c028c0, 0x00000608, 0x04c00000, + } }, + { { /* 245 */ + 0x80398412, 0x40a200e0, 0x02080000, 0x12030a04, + 0x008d1833, 0x02184602, 0x13803028, 0x00200801, + } }, + { { /* 246 */ + 0x20440000, 0x000005a1, 0x00050800, 0x0020a328, + 0x80100000, 0x10040649, 0x10020020, 0x00090180, + } }, + { { /* 247 */ + 0x8c008202, 0x00000000, 0x00205910, 0x0041410c, + 0x00004004, 0x40441290, 0x00010080, 0x01040000, + } }, + { { /* 248 */ + 0x04070000, 0x89108040, 0x00282a81, 0x82420000, + 0x51a20411, 0x32220800, 0x2b0d2220, 0x40c83003, + } }, + { { /* 249 */ + 0x82020082, 0x80008900, 0x10a00200, 0x08004100, + 0x09041108, 0x000405a6, 0x0c018000, 0x04104002, + } }, + { { /* 250 */ + 0x00002000, 0x44003000, 0x01000004, 0x00008200, + 0x00000008, 0x00044010, 0x00002002, 0x00001040, + } }, + { { /* 251 */ + 0x00000000, 0xca008000, 0x02828020, 0x00b1100c, + 0x12824280, 0x22013030, 0x00808820, 0x040013e4, + } }, + { { /* 252 */ + 0x801840c0, 0x1000a1a1, 0x00000004, 0x0050c200, + 0x00c20082, 0x00104840, 0x10400080, 0xa3140000, + } }, + { { /* 253 */ + 0xa8a02301, 0x24123d00, 0x80030200, 0xc0028022, + 0x34a10000, 0x00408005, 0x00190010, 0x882a0000, + } }, + { { /* 254 */ + 0x00080018, 0x33000402, 0x9002010a, 0x00000000, + 0x00800020, 0x00010100, 0x84040810, 0x04004000, + } }, + { { /* 255 */ + 0x10006020, 0x00000000, 0x00000000, 0x30a02000, + 0x00000004, 0x00000000, 0x01000800, 0x20000000, + } }, + { { /* 256 */ + 0x02000000, 0x02000602, 0x80000800, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 257 */ + 0x00000010, 0x44040083, 0x00081000, 0x0818824c, + 0x00400e00, 0x8c300000, 0x08146001, 0x00000000, + } }, + { { /* 258 */ + 0x00828000, 0x41900000, 0x84804006, 0x24010001, + 0x02400108, 0x9b080006, 0x00201602, 0x0009012e, + } }, + { { /* 259 */ + 0x40800800, 0x48000420, 0x10000032, 0x01904440, + 0x02000100, 0x10048000, 0x00020000, 0x08820802, + } }, + { { /* 260 */ + 0x08080ba0, 0x00009242, 0x00400000, 0xc0008080, + 0x20410001, 0x04400000, 0x60020820, 0x00100000, + } }, + { { /* 261 */ + 0x00108046, 0x01001805, 0x90100000, 0x00014010, + 0x00000010, 0x00000000, 0x0000000b, 0x00008800, + } }, + { { /* 262 */ + 0x00000000, 0x00001000, 0x00000000, 0x20018800, + 0x00004600, 0x06002000, 0x00000100, 0x00000000, + } }, + { { /* 263 */ + 0x00000000, 0x10400042, 0x02004000, 0x00004280, + 0x80000400, 0x00020000, 0x00000008, 0x00000020, + } }, + { { /* 264 */ + 0x00000040, 0x20600400, 0x0a000180, 0x02040280, + 0x00000000, 0x00409001, 0x02000004, 0x00003200, + } }, + { { /* 265 */ + 0x88000000, 0x80404800, 0x00000010, 0x00040008, + 0x00000a90, 0x00000200, 0x00002000, 0x40002001, + } }, + { { /* 266 */ + 0x00000048, 0x00100000, 0x00000000, 0x00000001, + 0x00000008, 0x20010080, 0x00000000, 0x00400040, + } }, + { { /* 267 */ + 0x85000000, 0x0c8f0108, 0x32129000, 0x80090420, + 0x00024000, 0x40040800, 0x092000a0, 0x00100204, + } }, + { { /* 268 */ + 0x00002000, 0x00000000, 0x00440004, 0x6c000000, + 0x000000d0, 0x80004000, 0x88800440, 0x41144018, + } }, + { { /* 269 */ + 0x80001a02, 0x14000001, 0x00000001, 0x0000004a, + 0x00000000, 0x00083000, 0x08000000, 0x0008a024, + } }, + { { /* 270 */ + 0x00300004, 0x00140000, 0x20000000, 0x00001800, + 0x00020002, 0x04000000, 0x00000002, 0x00000100, + } }, + { { /* 271 */ + 0x00004002, 0x54000000, 0x60400300, 0x00002120, + 0x0000a022, 0x00000000, 0x81060803, 0x08010200, + } }, + { { /* 272 */ + 0x04004800, 0xb0044000, 0x0000a005, 0x04500800, + 0x800c000a, 0x0000c000, 0x10000800, 0x02408021, + } }, + { { /* 273 */ + 0x08020000, 0x00001040, 0x00540a40, 0x00000000, + 0x00800880, 0x01020002, 0x00000211, 0x00000010, + } }, + { { /* 274 */ + 0x00000000, 0x80000002, 0x00002000, 0x00080001, + 0x09840a00, 0x40000080, 0x00400000, 0x49000080, + } }, + { { /* 275 */ + 0x0e102831, 0x06098807, 0x40011014, 0x02620042, + 0x06000000, 0x88062000, 0x04068400, 0x08108301, + } }, + { { /* 276 */ + 0x08000012, 0x40004840, 0x00300402, 0x00012000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 277 */ + 0x00000000, 0x00400000, 0x00000000, 0x00a54400, + 0x40004420, 0x20000310, 0x00041002, 0x18000000, + } }, + { { /* 278 */ + 0x00a1002a, 0x00080000, 0x40400000, 0x00900000, + 0x21401200, 0x04048626, 0x40005048, 0x21100000, + } }, + { { /* 279 */ + 0x040005a4, 0x000a0000, 0x00214000, 0x07010800, + 0x34000000, 0x00080100, 0x00080040, 0x10182508, + } }, + { { /* 280 */ + 0xc0805100, 0x02c01400, 0x00000080, 0x00448040, + 0x20000800, 0x210a8000, 0x08800000, 0x00020060, + } }, + { { /* 281 */ + 0x00004004, 0x00400100, 0x01040200, 0x00800000, + 0x00000000, 0x00000000, 0x10081400, 0x00008000, + } }, + { { /* 282 */ + 0x00004000, 0x20000000, 0x08800200, 0x00001000, + 0x00000000, 0x01000000, 0x00000810, 0x00000000, + } }, + { { /* 283 */ + 0x00020000, 0x20200000, 0x00000000, 0x00000000, + 0x00000010, 0x00001c40, 0x00002000, 0x08000210, + } }, + { { /* 284 */ + 0x00000000, 0x00000000, 0x54014000, 0x02000800, + 0x00200400, 0x00000000, 0x00002080, 0x00004000, + } }, + { { /* 285 */ + 0x10000004, 0x00000000, 0x00000000, 0x00000000, + 0x00002000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 286 */ + 0x00000000, 0x00000000, 0x28881041, 0x0081010a, + 0x00400800, 0x00000800, 0x10208026, 0x61000000, + } }, + { { /* 287 */ + 0x00050080, 0x00000000, 0x80000000, 0x80040000, + 0x044088c2, 0x00080480, 0x00040000, 0x00000048, + } }, + { { /* 288 */ + 0x8188410d, 0x141a2400, 0x40310000, 0x000f4249, + 0x41283280, 0x80053011, 0x00400880, 0x410060c0, + } }, + { { /* 289 */ + 0x2a004013, 0x02000002, 0x11000000, 0x00850040, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 290 */ + 0x00000000, 0x00800000, 0x04000440, 0x00000402, + 0x60001000, 0x99909f87, 0x5808049d, 0x10002445, + } }, + { { /* 291 */ + 0x00000100, 0x00000000, 0x00000000, 0x00910050, + 0x00000420, 0x00080008, 0x20000000, 0x00288002, + } }, + { { /* 292 */ + 0x00008400, 0x00000400, 0x00000000, 0x00100000, + 0x00002000, 0x00000800, 0x80043400, 0x21000004, + } }, + { { /* 293 */ + 0x20000208, 0x01000600, 0x00000010, 0x00000000, + 0x48000000, 0x14060008, 0x00124020, 0x20812800, + } }, + { { /* 294 */ + 0xa419804b, 0x01064009, 0x10386ca4, 0x85a0620b, + 0x00000010, 0x01000448, 0x00004400, 0x20a02102, + } }, + { { /* 295 */ + 0x00000000, 0x00000000, 0x00147000, 0x01a01404, + 0x10040000, 0x01000000, 0x3002f180, 0x00000008, + } }, + { { /* 296 */ + 0x00002000, 0x00100000, 0x08000010, 0x00020004, + 0x01000029, 0x00002000, 0x00000000, 0x10082000, + } }, + { { /* 297 */ + 0x00000000, 0x0004d041, 0x08000800, 0x00200000, + 0x00401000, 0x00004000, 0x00000000, 0x00000002, + } }, + { { /* 298 */ + 0x01000000, 0x00000000, 0x00020000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 299 */ + 0x00000000, 0x00000000, 0x00000000, 0x00800000, + 0x000a0a01, 0x0004002c, 0x01000080, 0x00000000, + } }, + { { /* 300 */ + 0x10000000, 0x08040400, 0x08012010, 0x2569043c, + 0x1a10c460, 0x08800009, 0x000210f0, 0x08c5050c, + } }, + { { /* 301 */ + 0x10000481, 0x00040080, 0x42040000, 0x00100204, + 0x00000000, 0x00000000, 0x00080000, 0x88080000, + } }, + { { /* 302 */ + 0x010f016c, 0x18002000, 0x41307000, 0x00000080, + 0x00000000, 0x00000100, 0x88000000, 0x70048004, + } }, + { { /* 303 */ + 0x00081420, 0x00000100, 0x00000000, 0x00000000, + 0x02400000, 0x00001000, 0x00050070, 0x00000000, + } }, + { { /* 304 */ + 0x000c4000, 0x00010000, 0x04000000, 0x00000000, + 0x00000000, 0x01000100, 0x01000010, 0x00000400, + } }, + { { /* 305 */ + 0x00000000, 0x10020000, 0x04100024, 0x00000000, + 0x00000000, 0x00004000, 0x00000000, 0x00000100, + } }, + { { /* 306 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00100020, + } }, + { { /* 307 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00008000, 0x00100000, 0x00000000, 0x00000000, + } }, + { { /* 308 */ + 0x00000000, 0x00000000, 0x00000000, 0x80000000, + 0x00880000, 0x0c000040, 0x02040010, 0x00000000, + } }, + { { /* 309 */ + 0x00080000, 0x08000000, 0x00000000, 0x00000004, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 310 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0xc3ff3fff, 0x00000000, + } }, + { { /* 311 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffff0000, 0x0001ffff, + } }, + { { /* 312 */ + 0xffff0002, 0xffffffff, 0x0002ffff, 0x00000000, + 0x0c0c0000, 0x000cc00c, 0x03000000, 0x00000000, + } }, + { { /* 313 */ + 0xfffdffff, 0xc7ffffff, 0x03ffffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 314 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffff0fff, 0xc7ff03ff, 0x00000000, + } }, + { { /* 315 */ + 0x00000000, 0x00000300, 0x00000000, 0x00000300, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 316 */ + 0xffff0000, 0xffffffff, 0x0040ffff, 0x00000000, + 0x0c0c0000, 0x0c00000c, 0x03000000, 0x00000300, + } }, + { { /* 317 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x0d10646e, 0x0d10646e, + } }, + { { /* 318 */ + 0x00000000, 0x01000300, 0x00000000, 0x00000300, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 319 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x9fffffff, 0xffcffee7, 0x0000003f, 0x00000000, + } }, + { { /* 320 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xfffddfec, 0xc3effdff, 0x40603ddf, 0x00000003, + } }, + { { /* 321 */ + 0x00000000, 0xfffe0000, 0xffffffff, 0xffffffef, + 0x00007fff, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 322 */ + 0x3eff0793, 0x1303b011, 0x11102801, 0x05930000, + 0xb0111e7b, 0x3b019703, 0x00a01112, 0x306b9593, + } }, + { { /* 323 */ + 0x1102b051, 0x11303201, 0x011102b0, 0xb879300a, + 0x30011306, 0x00800010, 0x100b0113, 0x93000011, + } }, + { { /* 324 */ + 0x00102b03, 0x05930000, 0xb051746b, 0x3b011323, + 0x00001030, 0x70000000, 0x1303b011, 0x11102900, + } }, + { { /* 325 */ + 0x00012180, 0xb0153000, 0x3001030e, 0x02000030, + 0x10230111, 0x13000000, 0x10106b81, 0x01130300, + } }, + { { /* 326 */ + 0x30111013, 0x00000100, 0x22b85530, 0x30000000, + 0x9702b011, 0x113afb07, 0x011303b0, 0x00000021, + } }, + { { /* 327 */ + 0x3b0d1b00, 0x03b01138, 0x11330113, 0x13000001, + 0x111c2b05, 0x00000100, 0xb0111000, 0x2a011300, + } }, + { { /* 328 */ + 0x02b01930, 0x10100001, 0x11000000, 0x10300301, + 0x07130230, 0x0011146b, 0x2b051300, 0x8fb8f974, + } }, + { { /* 329 */ + 0x103b0113, 0x00000000, 0xd9700000, 0x01134ab0, + 0x0011103b, 0x00001103, 0x2ab15930, 0x10000111, + } }, + { { /* 330 */ + 0x11010000, 0x00100b01, 0x01130000, 0x0000102b, + 0x20000101, 0x02a01110, 0x30210111, 0x0102b059, + } }, + { { /* 331 */ + 0x19300000, 0x011307b0, 0xb011383b, 0x00000003, + 0x00000000, 0x383b0d13, 0x0103b011, 0x00001000, + } }, + { { /* 332 */ + 0x01130000, 0x00101020, 0x00000100, 0x00000110, + 0x30000000, 0x00021811, 0x00100000, 0x01110000, + } }, + { { /* 333 */ + 0x00000023, 0x0b019300, 0x00301110, 0x302b0111, + 0x13c7b011, 0x01303b01, 0x00000280, 0xb0113000, + } }, + { { /* 334 */ + 0x2b011383, 0x03b01130, 0x300a0011, 0x1102b011, + 0x00002000, 0x01110100, 0xa011102b, 0x2b011302, + } }, + { { /* 335 */ + 0x01000010, 0x30000001, 0x13029011, 0x11302b01, + 0x000066b0, 0xb0113000, 0x6b07d302, 0x07b0113a, + } }, + { { /* 336 */ + 0x00200103, 0x13000000, 0x11386b05, 0x011303b0, + 0x000010b8, 0x2b051b00, 0x03000110, 0x10000000, + } }, + { { /* 337 */ + 0x1102a011, 0x79700a01, 0x0111a2b0, 0x0000100a, + 0x00011100, 0x00901110, 0x00090111, 0x93000000, + } }, + { { /* 338 */ + 0xf9f2bb05, 0x011322b0, 0x2001323b, 0x00000000, + 0x06b05930, 0x303b0193, 0x1123a011, 0x11700000, + } }, + { { /* 339 */ + 0x001102b0, 0x00001010, 0x03011301, 0x00000110, + 0x162b0793, 0x01010010, 0x11300000, 0x01110200, + } }, + { { /* 340 */ + 0xb0113029, 0x00000000, 0x0eb05130, 0x383b0513, + 0x0303b011, 0x00000100, 0x01930000, 0x00001039, + } }, + { { /* 341 */ + 0x3b000302, 0x00000000, 0x00230113, 0x00000000, + 0x00100000, 0x00010000, 0x90113020, 0x00000002, + } }, + { { /* 342 */ + 0x00000000, 0x10000000, 0x11020000, 0x00000301, + 0x01130000, 0xb079b02b, 0x3b011323, 0x02b01130, + } }, + { { /* 343 */ + 0xf0210111, 0x1343b0d9, 0x11303b01, 0x011103b0, + 0xb0517020, 0x20011322, 0x01901110, 0x300b0111, + } }, + { { /* 344 */ + 0x9302b011, 0x0016ab01, 0x01130100, 0xb0113021, + 0x29010302, 0x02b03130, 0x30000000, 0x1b42b819, + } }, + { { /* 345 */ + 0x11383301, 0x00000330, 0x00000020, 0x33051300, + 0x00001110, 0x00000000, 0x93000000, 0x01302305, + } }, + { { /* 346 */ + 0x00010100, 0x30111010, 0x00000100, 0x02301130, + 0x10100001, 0x11000000, 0x00000000, 0x85130200, + } }, + { { /* 347 */ + 0x10111003, 0x2b011300, 0x63b87730, 0x303b0113, + 0x11a2b091, 0x7b300201, 0x011357f0, 0xf0d1702b, + } }, + { { /* 348 */ + 0x1b0111e3, 0x0ab97130, 0x303b0113, 0x13029001, + 0x11302b01, 0x071302b0, 0x3011302b, 0x23011303, + } }, + { { /* 349 */ + 0x02b01130, 0x30ab0113, 0x11feb411, 0x71300901, + 0x05d347b8, 0xb011307b, 0x21015303, 0x00001110, + } }, + { { /* 350 */ + 0x306b0513, 0x1102b011, 0x00103301, 0x05130000, + 0xa01038eb, 0x30000102, 0x02b01110, 0x30200013, + } }, + { { /* 351 */ + 0x0102b071, 0x00101000, 0x01130000, 0x1011100b, + 0x2b011300, 0x00000000, 0x366b0593, 0x1303b095, + } }, + { { /* 352 */ + 0x01103b01, 0x00000200, 0xb0113000, 0x20000103, + 0x01000010, 0x30000000, 0x030ab011, 0x00101001, + } }, + { { /* 353 */ + 0x01110100, 0x00000003, 0x23011302, 0x03000010, + 0x10000000, 0x01000000, 0x00100000, 0x00000290, + } }, + { { /* 354 */ + 0x30113000, 0x7b015386, 0x03b01130, 0x00210151, + 0x13000000, 0x11303b01, 0x001102b0, 0x00011010, + } }, + { { /* 355 */ + 0x2b011302, 0x02001110, 0x10000000, 0x0102b011, + 0x11300100, 0x000102b0, 0x00011010, 0x2b011100, + } }, + { { /* 356 */ + 0x02101110, 0x002b0113, 0x93000000, 0x11302b03, + 0x011302b0, 0x0000303b, 0x00000002, 0x03b01930, + } }, + { { /* 357 */ + 0x102b0113, 0x0103b011, 0x11300000, 0x011302b0, + 0x00001021, 0x00010102, 0x00000010, 0x102b0113, + } }, + { { /* 358 */ + 0x01020011, 0x11302000, 0x011102b0, 0x30113001, + 0x00000002, 0x02b01130, 0x303b0313, 0x0103b011, + } }, + { { /* 359 */ + 0x00002000, 0x05130000, 0xb011303b, 0x10001102, + 0x00000110, 0x142b0113, 0x01000001, 0x01100000, + } }, + { { /* 360 */ + 0x00010280, 0xb0113000, 0x10000102, 0x00000010, + 0x10230113, 0x93021011, 0x11100b05, 0x01130030, + } }, + { { /* 361 */ + 0xb051702b, 0x3b011323, 0x00000030, 0x30000000, + 0x1303b011, 0x11102b01, 0x01010330, 0xb011300a, + } }, + { { /* 362 */ + 0x20000102, 0x00000000, 0x10000011, 0x9300a011, + 0x00102b05, 0x00000200, 0x90111000, 0x29011100, + } }, + { { /* 363 */ + 0x00b01110, 0x30000000, 0x1302b011, 0x11302b21, + 0x000103b0, 0x00000020, 0x2b051300, 0x02b01130, + } }, + { { /* 364 */ + 0x103b0113, 0x13002011, 0x11322b21, 0x00130280, + 0xa0113028, 0x0a011102, 0x02921130, 0x30210111, + } }, + { { /* 365 */ + 0x13020011, 0x11302b01, 0x03d30290, 0x3011122b, + 0x2b011302, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 366 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00004000, 0x00000000, 0x20000000, 0x00000000, + } }, + { { /* 367 */ + 0x00000000, 0x00000000, 0x00003000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 368 */ + 0x00000000, 0x040001df, 0x80800176, 0x420c0000, + 0x01020140, 0x44008200, 0x00041018, 0x00000000, + } }, + { { /* 369 */ + 0xffff0000, 0xffff27bf, 0x000027bf, 0x00000000, + 0x00000000, 0x0c000000, 0x03000000, 0x000000c0, + } }, + { { /* 370 */ + 0x3c000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 371 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x08004480, 0x08004480, + } }, + { { /* 372 */ + 0x00000000, 0x00000000, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 373 */ + 0xffff0002, 0xffffffff, 0x0002ffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 374 */ + 0xffff0042, 0xffffffff, 0x0042ffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x000000c0, + } }, + { { /* 375 */ + 0x00000000, 0x000c0000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 376 */ + 0xffff0002, 0xffffffff, 0x0002ffff, 0x00000000, + 0x00000000, 0x0000c00c, 0x00000000, 0x00000000, + } }, + { { /* 377 */ + 0x000c0003, 0x00003c00, 0x0000f000, 0x00003c00, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 378 */ + 0x00000000, 0x040001de, 0x00000176, 0x42000000, + 0x01020140, 0x44008200, 0x00041008, 0x00000000, + } }, + { { /* 379 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x98504f14, 0x18504f14, + } }, + { { /* 380 */ + 0xffffffff, 0xf8ffffff, 0x0000e3ff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 381 */ + 0x00000000, 0x00000000, 0x00000c00, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 382 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00480910, 0x00480910, + } }, + { { /* 383 */ + 0x7fffffff, 0x0fff0fff, 0x0000fff1, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 384 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x060cb301, 0x060eb3d5, + } }, + { { /* 385 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffff0000, 0xffffffff, + } }, + { { /* 386 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x0c186606, 0x0c186606, + } }, + { { /* 387 */ + 0x0c000000, 0x00000000, 0x00000000, 0x00000000, + 0x00010040, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 388 */ + 0x00001006, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 389 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xfef02596, 0x3bffecae, 0x30003f5f, 0x00000000, + } }, + { { /* 390 */ + 0x03c03030, 0x0000c000, 0x00000000, 0x600c0c03, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 391 */ + 0x000c3003, 0x18c00c0c, 0x00c03060, 0x60000c03, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 392 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00100002, 0x00100002, + } }, + { { /* 393 */ + 0x00000003, 0x18000000, 0x00003060, 0x00000c00, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 394 */ + 0x00000000, 0x00300000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 395 */ + 0x00000000, 0x00000000, 0x4fffffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 396 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x140a2202, 0x142a220a, + } }, + { { /* 397 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x20000000, 0x00000000, 0x00000000, + } }, + { { /* 398 */ + 0xfdffb729, 0x000001ff, 0xb7290000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 399 */ + 0xfffddfec, 0xc3fffdff, 0x00803dcf, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 400 */ + 0x00000000, 0xffffffff, 0xffffffff, 0x00ffffff, + 0xffffffff, 0x000003ff, 0x00000000, 0x00000000, + } }, + { { /* 401 */ + 0xffff0002, 0xffffffff, 0x0002ffff, 0x00000000, + 0x00000000, 0x0000c000, 0x00000000, 0x00000300, + } }, + { { /* 402 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x007fffff, + } }, + { { /* 403 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0x03ff37ff, + } }, + { { /* 404 */ + 0xffffffff, 0x0007f6fb, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 405 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00004004, 0x00004004, + } }, + { { /* 406 */ + 0x0f000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 407 */ + 0x00000000, 0x00000000, 0x7fffffff, 0x0000c3ff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 408 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x02045101, 0x02045101, + } }, + { { /* 409 */ + 0x00000c00, 0x000000c3, 0x00000000, 0x18000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 410 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000300, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 411 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x011c0661, 0x011c0661, + } }, + { { /* 412 */ + 0xfff98fee, 0xc3e5fdff, 0x0001398f, 0x0001fff0, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 413 */ + 0x00000002, 0x00000000, 0x00002000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 414 */ + 0x00080002, 0x00000800, 0x00002000, 0x00000800, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 415 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x1c58af16, 0x1c58af16, + } }, + { { /* 416 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x115c0671, 0x115c0671, + } }, + { { /* 417 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0x83ffffff, + } }, + { { /* 418 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0x07ffffff, + } }, + { { /* 419 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00100400, 0x00100400, + } }, + { { /* 420 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 421 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00082202, 0x00082202, + } }, + { { /* 422 */ + 0x03000030, 0x0000c000, 0x00000006, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000c00, + } }, + { { /* 423 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x10000000, 0x00000000, 0x00000000, + } }, + { { /* 424 */ + 0x00000002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 425 */ + 0x00000000, 0x00000000, 0x00000000, 0x00300000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 426 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x040c2383, 0x040c2383, + } }, + { { /* 427 */ + 0xfff99fee, 0xf3cdfdff, 0xb0c0398f, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 428 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffff0000, 0xff0fffff, 0x0fffffff, + } }, + { { /* 429 */ + 0x00000000, 0x07ffffc6, 0x000001fe, 0x40000000, + 0x01000040, 0x0000a000, 0x00001000, 0x00000000, + } }, + { { /* 430 */ + 0xffffffff, 0xffffffff, 0x000001ff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 431 */ + 0x00000000, 0x00000000, 0x00000000, 0xffff0000, + 0x000003ff, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 432 */ + 0xfff987e0, 0xd36dfdff, 0x1e003987, 0x001f0000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 433 */ + 0x00000000, 0x00000000, 0x00000000, 0xff07ffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 434 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x160e2302, 0x160e2302, + } }, + { { /* 435 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00020000, 0x00020000, + } }, + { { /* 436 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0x003fff0f, 0x00000000, + } }, + { { /* 437 */ + 0xfeeff06f, 0x873fffff, 0x01ff01ff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 438 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x1fffffff, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 439 */ + 0x8fffffff, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 440 */ + 0x030000f0, 0x00000000, 0x0c00001e, 0x1e000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 441 */ + 0x00000000, 0x07ffffde, 0x000005f6, 0x50000000, + 0x05480262, 0x10000a00, 0x00013000, 0x00000000, + } }, + { { /* 442 */ + 0x00000000, 0x07ffffde, 0x000005f6, 0x50000000, + 0x05480262, 0x10000a00, 0x00052000, 0x00000000, + } }, + { { /* 443 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x143c278f, 0x143c278f, + } }, + { { /* 444 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000100, 0x00000000, + } }, + { { /* 445 */ + 0xffffffff, 0x03ff00ff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 446 */ + 0x00002000, 0x00000000, 0x02000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000080, + } }, + { { /* 447 */ + 0x00002000, 0x00000020, 0x08000000, 0x00002008, + 0x00080000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 448 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x02045301, 0x02045301, + } }, + { { /* 449 */ + 0xffff0002, 0xffffffff, 0x0002ffff, 0x00000000, + 0x00300000, 0x0c00c030, 0x03000000, 0x00000000, + } }, + { { /* 450 */ + 0xffffffff, 0x7fff3fff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 451 */ + 0x00000000, 0x00000000, 0xffff0000, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 452 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x02041101, 0x02041101, + } }, + { { /* 453 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00800000, 0x00000000, 0x00000000, + } }, + { { /* 454 */ + 0x30000000, 0x00000000, 0x00000000, 0x00000000, + 0x00040000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 455 */ + 0x00000000, 0x07fffdd6, 0x000005f6, 0xec000000, + 0x0200b4d9, 0x480a8640, 0x00000000, 0x00000000, + } }, + { { /* 456 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00000002, 0x00000002, + } }, + { { /* 457 */ + 0x00033000, 0x00000000, 0x00000c00, 0x600000c3, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 458 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x1850cc14, 0x1850cc14, + } }, + { { /* 459 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00000000, 0x00200000, + } }, + { { /* 460 */ + 0x03c83032, 0x0000c800, 0x00002000, 0x600c0c03, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 461 */ + 0x00000010, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 462 */ + 0xffff8f04, 0xffffffff, 0x8f04ffff, 0x00000000, + 0x030c0000, 0x0c00cc0f, 0x03000000, 0x00000300, + } }, + { { /* 463 */ + 0x00000000, 0x00800000, 0x03bffbaa, 0x03bffbaa, + 0x00000000, 0x00000000, 0x00002202, 0x00002202, + } }, + { { /* 464 */ + 0x00080000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 465 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xfc7e3fec, 0x2ffbffbf, 0x7f5f847f, 0x00040000, + } }, + { { /* 466 */ + 0xff7fff7f, 0xff01ff7f, 0x3d7f3d7f, 0xffff7fff, + 0xffff3d7f, 0x003d7fff, 0xff7f7f3d, 0x00ff7fff, + } }, + { { /* 467 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x24182212, 0x24182212, + } }, + { { /* 468 */ + 0x0000f000, 0x66000000, 0x00300180, 0x60000033, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 469 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00408030, 0x00408030, + } }, + { { /* 470 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00020032, 0x00020032, + } }, + { { /* 471 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00000016, 0x00000016, + } }, + { { /* 472 */ + 0x00033000, 0x00000000, 0x00000c00, 0x60000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 473 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00200034, 0x00200034, + } }, + { { /* 474 */ + 0x00033000, 0x00000000, 0x00000c00, 0x60000003, + 0x00000000, 0x00800000, 0x00000000, 0x0000c3f0, + } }, + { { /* 475 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00040000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 476 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x3fffffff, 0x000003ff, 0x00000000, 0x00000000, + } }, + { { /* 477 */ + 0x00000000, 0xffff0000, 0x03ffffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 478 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00000880, 0x00000880, + } }, + { { /* 479 */ + 0xfdff8f04, 0xfdff01ff, 0x8f0401ff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 480 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + } }, + { { /* 481 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x000000ff, 0x00000000, + } }, + { { /* 482 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0x03ff0003, + } }, + { { /* 483 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x10400a33, 0x10400a33, + } }, + { { /* 484 */ + 0xffff0000, 0xffff1fff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 485 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00380008, 0x00080000, + } }, + { { /* 486 */ + 0x030000f0, 0x00000000, 0x0c00501e, 0x1e004000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 487 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xd63dc7e8, 0xc3bfc718, 0x00803dc7, 0x00000000, + } }, + { { /* 488 */ + 0x00000000, 0x00000000, 0x00000000, 0x000ddfff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 489 */ + 0x00000000, 0x00000000, 0xffff0000, 0x001f3fff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 490 */ + 0xfffddfee, 0xc3effdff, 0x00603ddf, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 491 */ + 0xffff0002, 0xffffffff, 0x0002ffff, 0x00000000, + 0x0c0c0000, 0x00cc0000, 0x00000000, 0x0000c00c, + } }, + { { /* 492 */ + 0xfffffffe, 0x87ffffff, 0x00007fff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 493 */ + 0xff7fff7f, 0xff01ff00, 0x00003d7f, 0xffff7fff, + 0x00ff0000, 0x003d7f7f, 0xff7f7f00, 0x00ff7f00, + } }, + { { /* 494 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x30400090, 0x30400090, + } }, + { { /* 495 */ + 0x00000000, 0x00000000, 0xc0000180, 0x60000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 496 */ + 0x803fffff, 0x00600000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 497 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x18404084, 0x18404084, + } }, + { { /* 498 */ + 0xffff0002, 0xffffffff, 0x0002ffff, 0x00000000, + 0x00c00000, 0x0c00c00c, 0x03000000, 0x00000000, + } }, + { { /* 499 */ + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0x00ffffff, + } }, + { { /* 500 */ + 0x000001ff, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 501 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00008000, 0x00008000, + } }, + { { /* 502 */ + 0x00000000, 0x041ed5c0, 0x0000077e, 0x40000000, + 0x01000040, 0x4000a000, 0x002109c0, 0x00000000, + } }, + { { /* 503 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xbfffffff, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 504 */ + 0xffff00d0, 0xffffffff, 0x00d0ffff, 0x00000000, + 0x00030000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 505 */ + 0x00000000, 0xffffff7b, 0x7fffffff, 0x7ffffffe, + 0x00000000, 0x80e310fe, 0x00800000, 0x00800000, + } }, + { { /* 506 */ + 0x00000000, 0x00020000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 507 */ + 0x00001500, 0x01000000, 0x00000000, 0x00000000, + 0xfffe0000, 0xfffe03db, 0x006003fb, 0x00030000, + } }, + { { /* 508 */ + 0x00400000, 0x00000047, 0x00800010, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, + } }, + { { /* 509 */ + 0x3f2fc004, 0x00000010, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 510 */ + 0xe3ffbfff, 0xfff007ff, 0x00000001, 0x00000000, + 0xfffff000, 0x0000003f, 0x0000e10f, 0x00000000, + } }, + { { /* 511 */ + 0x00000f00, 0x0000000c, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 512 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x00000000, + } }, + { { /* 513 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x000003c0, + } }, + { { /* 514 */ + 0xffffffff, 0xffffffff, 0xffdfffff, 0xffffffff, + 0xdfffffff, 0x00001e64, 0x00000000, 0x00000000, + } }, + { { /* 515 */ + 0x00000000, 0x78000000, 0x0001fc5f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 516 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000030, 0x00000000, 0x00000000, + } }, + { { /* 517 */ + 0x0c000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00091e00, + } }, + { { /* 518 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x60000000, + } }, + { { /* 519 */ + 0x00300000, 0x00000000, 0x000fff00, 0x80000000, + 0x00080000, 0x60000c02, 0x00104030, 0x242c0400, + } }, + { { /* 520 */ + 0x00000c20, 0x00000100, 0x00b85000, 0x00000000, + 0x00e00000, 0x80010000, 0x00000000, 0x00000000, + } }, + { { /* 521 */ + 0x18000000, 0x00000000, 0x00210000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 522 */ + 0x00000010, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00008000, 0x00000000, + } }, + { { /* 523 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x07fe4000, 0x00000000, 0x00000000, 0xffffffc0, + } }, + { { /* 524 */ + 0x04000002, 0x077c8000, 0x00030000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 525 */ + 0xffffffff, 0xffbf0001, 0xffffffff, 0x1fffffff, + 0x000fffff, 0xffffffff, 0x000007df, 0x0001ffff, + } }, + { { /* 526 */ + 0x00000000, 0x00000000, 0xfffffffd, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0x1effffff, + } }, + { { /* 527 */ + 0xffffffff, 0x3fffffff, 0xffff0000, 0x000000ff, + 0x00000000, 0x00000000, 0x00000000, 0xf8000000, + } }, + { { /* 528 */ + 0x755dfffe, 0xffef2f3f, 0x0000ffe1, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 529 */ + 0xffffffff, 0x00000fff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 530 */ + 0x000c0000, 0x30000000, 0x00000c30, 0x00030000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 531 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x263c370f, 0x263c370f, + } }, + { { /* 532 */ + 0x0003000c, 0x00000300, 0x00000000, 0x00000300, + 0x00000000, 0x00018003, 0x00000000, 0x00000000, + } }, + { { /* 533 */ + 0x0800024f, 0x00000008, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 534 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x03ffffff, + } }, + { { /* 535 */ + 0x00000000, 0x00000000, 0x077dfffe, 0x077dfffe, + 0x00000000, 0x00000000, 0x10400010, 0x10400010, + } }, + { { /* 536 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x10400010, 0x10400010, + } }, + { { /* 537 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x081047a4, 0x081047a4, + } }, + { { /* 538 */ + 0x0c0030c0, 0x00000000, 0x0f30001e, 0x66000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 539 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x000a0a09, 0x000a0a09, + } }, + { { /* 540 */ + 0x00000000, 0xffff0000, 0xffffffff, 0x0000800f, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 541 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffff0000, 0x00000fff, 0x00000000, + } }, + { { /* 542 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0x0001ffff, 0x00000000, + } }, + { { /* 543 */ + 0x00000000, 0x83ffffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 544 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xf0ffffff, 0xfffcffff, 0xffffffff, + } }, + { { /* 545 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 546 */ + 0x00000000, 0x00000000, 0xff3fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 547 */ + 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 548 */ + 0x00000000, 0x00000000, 0x00000000, 0xffff0000, + 0xfffcffff, 0x007ffeff, 0x00000000, 0x00000000, + } }, + { { /* 549 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x00400810, 0x00400810, + } }, + { { /* 550 */ + 0x00000000, 0x00000000, 0x07fffffe, 0x07fffffe, + 0x00000000, 0x00000000, 0x0e3c770f, 0x0e3c770f, + } }, + { { /* 551 */ + 0x0c000000, 0x00000300, 0x00000018, 0x00000300, + 0x00000000, 0x00000000, 0x001fe000, 0x03000000, + } }, + { { /* 552 */ + 0x0000100f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 553 */ + 0x00000000, 0xc0000000, 0x00000000, 0x0000000c, + 0x00000000, 0x33000000, 0x00003000, 0x00000000, + } }, + { { /* 554 */ + 0x00000080, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 555 */ + 0x00000000, 0x00000000, 0x00001000, 0x64080010, + 0x00480000, 0x10000020, 0x80000102, 0x08000010, + } }, + { { /* 556 */ + 0x00000040, 0x40000000, 0x00020000, 0x01852002, + 0x00800010, 0x80002022, 0x084444a2, 0x480e0000, + } }, + { { /* 557 */ + 0x04000200, 0x02202008, 0x80004380, 0x04000000, + 0x00000002, 0x12231420, 0x2058003a, 0x00200060, + } }, + { { /* 558 */ + 0x10002508, 0x040d0028, 0x00000009, 0x00008004, + 0x00800000, 0x42000001, 0x00000000, 0x09040000, + } }, + { { /* 559 */ + 0x02008000, 0x01402001, 0x00000000, 0x00000008, + 0x00000000, 0x00000001, 0x00021008, 0x04000000, + } }, + { { /* 560 */ + 0x00100100, 0x80040080, 0x00002000, 0x00000008, + 0x08040601, 0x01000012, 0x10000000, 0x49001024, + } }, + { { /* 561 */ + 0x0180004a, 0x00100600, 0x50840800, 0x000000c0, + 0x00800000, 0x20000800, 0x40000000, 0x08050000, + } }, + { { /* 562 */ + 0x02004000, 0x02000804, 0x01000004, 0x18060001, + 0x02400001, 0x40000002, 0x20800014, 0x000c1000, + } }, + { { /* 563 */ + 0x00222000, 0x00000000, 0x00100000, 0x00000000, + 0x00000000, 0x00000000, 0x10422800, 0x00000800, + } }, + { { /* 564 */ + 0x20080000, 0x00040000, 0x80025040, 0x20208604, + 0x00028020, 0x80102020, 0x080820c0, 0x10880800, + } }, + { { /* 565 */ + 0x00000000, 0x00000000, 0x00200109, 0x00100000, + 0x00000000, 0x81022700, 0x40c21404, 0x84010882, + } }, + { { /* 566 */ + 0x00004010, 0x00000000, 0x03000000, 0x00000008, + 0x00080000, 0x00000000, 0x10800001, 0x06002020, + } }, + { { /* 567 */ + 0x00000010, 0x02000000, 0x00880020, 0x00008424, + 0x00000000, 0x88000000, 0x81000100, 0x04000000, + } }, + { { /* 568 */ + 0x00004218, 0x00040000, 0x00000000, 0x80005080, + 0x00010000, 0x00040000, 0x08008000, 0x02008000, + } }, + { { /* 569 */ + 0x00020000, 0x00000000, 0x00000001, 0x04000401, + 0x00100000, 0x12200004, 0x00000000, 0x18100000, + } }, + { { /* 570 */ + 0x00000000, 0x00000800, 0x00000000, 0x00004000, + 0x00800000, 0x04000000, 0x82000002, 0x00042000, + } }, + { { /* 571 */ + 0x00080006, 0x00000000, 0x00000000, 0x04000000, + 0x80008000, 0x00810001, 0xa0000000, 0x00100410, + } }, + { { /* 572 */ + 0x00400218, 0x88084080, 0x00260008, 0x00800404, + 0x00000020, 0x00000000, 0x00000000, 0x00000200, + } }, + { { /* 573 */ + 0x00a08048, 0x00000000, 0x08000000, 0x04000000, + 0x00000000, 0x00000000, 0x00018000, 0x00200000, + } }, + { { /* 574 */ + 0x01000000, 0x00000000, 0x00000000, 0x10000000, + 0x00000000, 0x00000000, 0x00200000, 0x00102000, + } }, + { { /* 575 */ + 0x00000801, 0x00000000, 0x00000000, 0x00020000, + 0x08000000, 0x00002000, 0x20010000, 0x04002000, + } }, + { { /* 576 */ + 0x40000040, 0x50202400, 0x000a0020, 0x00040420, + 0x00000200, 0x00000080, 0x80000000, 0x00000020, + } }, + { { /* 577 */ + 0x20008000, 0x00200010, 0x00000000, 0x00000000, + 0x00400000, 0x01100000, 0x00020000, 0x80000010, + } }, + { { /* 578 */ + 0x02000000, 0x00801000, 0x00000000, 0x48058000, + 0x20c94000, 0x60000000, 0x00000001, 0x00000000, + } }, + { { /* 579 */ + 0x00004090, 0x48000000, 0x08000000, 0x28802000, + 0x00000002, 0x00014000, 0x00002000, 0x00002002, + } }, + { { /* 580 */ + 0x00010200, 0x00100000, 0x00000000, 0x00800000, + 0x10020000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 581 */ + 0x00000010, 0x00000402, 0x0c000000, 0x01000400, + 0x01000021, 0x00000000, 0x00004000, 0x00004000, + } }, + { { /* 582 */ + 0x00000000, 0x00800000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x02000020, + } }, + { { /* 583 */ + 0x00000100, 0x08000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00002000, 0x00000000, + } }, + { { /* 584 */ + 0x00006000, 0x00000000, 0x00000000, 0x00000400, + 0x04000040, 0x003c0180, 0x00000200, 0x00102000, + } }, + { { /* 585 */ + 0x00000800, 0x101000c0, 0x00800000, 0x00000000, + 0x00008000, 0x02200000, 0x00020020, 0x00000000, + } }, + { { /* 586 */ + 0x00000000, 0x01000000, 0x00000000, 0x20100000, + 0x00080000, 0x00000141, 0x02001002, 0x40400001, + } }, + { { /* 587 */ + 0x00580000, 0x00000002, 0x00003000, 0x00002400, + 0x00988000, 0x00040010, 0x00002800, 0x00000008, + } }, + { { /* 588 */ + 0x40080004, 0x00000020, 0x20080000, 0x02060a00, + 0x00010040, 0x14010200, 0x40800000, 0x08031000, + } }, + { { /* 589 */ + 0x40020020, 0x0000202c, 0x2014a008, 0x00000000, + 0x80040200, 0x82020012, 0x00400000, 0x20000000, + } }, + { { /* 590 */ + 0x00000000, 0x00000000, 0x00000004, 0x04000000, + 0x00000000, 0x00000000, 0x40800100, 0x00000000, + } }, + { { /* 591 */ + 0x00000008, 0x04000040, 0x00000001, 0x000c0200, + 0x00000000, 0x08000400, 0x00000000, 0x080c0001, + } }, + { { /* 592 */ + 0x00000400, 0x00000000, 0x00000000, 0x00200000, + 0x80000000, 0x00001000, 0x00000200, 0x01000800, + } }, + { { /* 593 */ + 0x00000000, 0x00000800, 0x00000000, 0x40000000, + 0x00000000, 0x00000000, 0x00000000, 0x04040000, + } }, + { { /* 594 */ + 0x00000000, 0x00000000, 0x00000040, 0x00002000, + 0xa0000000, 0x00000000, 0x08000008, 0x00080000, + } }, + { { /* 595 */ + 0x00000020, 0x00000000, 0x40000400, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00008000, + } }, + { { /* 596 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000800, 0x00000000, 0x00000000, 0x00200000, + } }, + { { /* 597 */ + 0x00000000, 0x00000000, 0x00000000, 0x04000000, + 0x00000008, 0x00000000, 0x00010000, 0x1b000000, + } }, + { { /* 598 */ + 0x00007000, 0x00000000, 0x10000000, 0x00000000, + 0x00000000, 0x00000080, 0x80000000, 0x00000000, + } }, + { { /* 599 */ + 0x00000000, 0x00020000, 0x00000000, 0x00200000, + 0x40000000, 0x00000010, 0x00800000, 0x00000008, + } }, + { { /* 600 */ + 0x00000000, 0x00000000, 0x02000000, 0x20000010, + 0x00000080, 0x00000000, 0x00010000, 0x00000000, + } }, + { { /* 601 */ + 0x00000000, 0x02000000, 0x00000000, 0x00000000, + 0x20000000, 0x00000040, 0x00200028, 0x00000000, + } }, + { { /* 602 */ + 0x00000000, 0x00020000, 0x00000000, 0x02000000, + 0x00000000, 0x02000000, 0x40020000, 0x51000040, + } }, + { { /* 603 */ + 0x00000080, 0x04040000, 0x00000000, 0x10000000, + 0x00022000, 0x00100000, 0x20000000, 0x00000082, + } }, + { { /* 604 */ + 0x40000000, 0x00010000, 0x00002000, 0x00000000, + 0x00000240, 0x00000000, 0x00000000, 0x00000008, + } }, + { { /* 605 */ + 0x00000000, 0x00010000, 0x00000810, 0x00080880, + 0x00004000, 0x00000000, 0x00000000, 0x00020000, + } }, + { { /* 606 */ + 0x00000000, 0x00400020, 0x00000000, 0x00000082, + 0x00000000, 0x00020001, 0x00000000, 0x00000000, + } }, + { { /* 607 */ + 0x40000018, 0x00000004, 0x00000000, 0x00000000, + 0x01000000, 0x00400000, 0x00000000, 0x00000000, + } }, + { { /* 608 */ + 0x00000001, 0x00400000, 0x00000000, 0x00080002, + 0x00000400, 0x00040000, 0x00000000, 0x00000000, + } }, + { { /* 609 */ + 0x00000800, 0x00000800, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000100, 0x00000000, + } }, + { { /* 610 */ + 0x00000000, 0x00200000, 0x00000000, 0x04108000, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, + } }, + { { /* 611 */ + 0x00000000, 0x02800000, 0x04000000, 0x00000000, + 0x00000000, 0x00000004, 0x00000000, 0x00000400, + } }, + { { /* 612 */ + 0x00000000, 0x00000000, 0x10000000, 0x00040000, + 0x00400000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 613 */ + 0x00200000, 0x00000200, 0x00000000, 0x10000000, + 0x00000000, 0x00000000, 0x2a000000, 0x00000000, + } }, + { { /* 614 */ + 0x00400000, 0x00000000, 0x00400000, 0x00000000, + 0x00000002, 0x40000000, 0x00000000, 0x00400000, + } }, + { { /* 615 */ + 0x40000000, 0x00001000, 0x00000000, 0x00000000, + 0x00000202, 0x02000000, 0x80000000, 0x00020000, + } }, + { { /* 616 */ + 0x00000020, 0x00000800, 0x00020421, 0x00020000, + 0x00000000, 0x00000000, 0x00000000, 0x00400000, + } }, + { { /* 617 */ + 0x00200000, 0x00000000, 0x00000001, 0x00000000, + 0x00000084, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 618 */ + 0x00000000, 0x00004400, 0x00000002, 0x00100000, + 0x00000000, 0x00000000, 0x00008200, 0x00000000, + } }, + { { /* 619 */ + 0x00000000, 0x12000000, 0x00000100, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 620 */ + 0x00000020, 0x08100000, 0x000a0400, 0x00000081, + 0x00006000, 0x00120000, 0x00000000, 0x00000000, + } }, + { { /* 621 */ + 0x00000004, 0x08000000, 0x00004000, 0x044000c0, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 622 */ + 0x40001000, 0x00000000, 0x01000001, 0x05000000, + 0x00080000, 0x02000000, 0x00000800, 0x00000000, + } }, + { { /* 623 */ + 0x00000100, 0x00000000, 0x00000000, 0x00000000, + 0x00002002, 0x01020000, 0x00800000, 0x00000000, + } }, + { { /* 624 */ + 0x00000040, 0x00004000, 0x01000000, 0x00000004, + 0x00020000, 0x00000000, 0x00000010, 0x00000000, + } }, + { { /* 625 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080000, 0x00010000, 0x30000300, 0x00000400, + } }, + { { /* 626 */ + 0x00000800, 0x02000000, 0x00000000, 0x00008000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 627 */ + 0x00200000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000040c0, 0x00002200, 0x12002000, + } }, + { { /* 628 */ + 0x00000000, 0x00000020, 0x20000000, 0x00000000, + 0x00000200, 0x00080800, 0x1000a000, 0x00000000, + } }, + { { /* 629 */ + 0x00000000, 0x00000000, 0x00000000, 0x00004000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 630 */ + 0x00000000, 0x00000000, 0x00004280, 0x01000000, + 0x00800000, 0x00000008, 0x00000000, 0x00000000, + } }, + { { /* 631 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000002, + 0x00000000, 0x20400000, 0x00000040, 0x00000000, + } }, + { { /* 632 */ + 0x00800080, 0x00800000, 0x00000000, 0x00000000, + 0x00000000, 0x00400020, 0x00000000, 0x00008000, + } }, + { { /* 633 */ + 0x01000000, 0x00000040, 0x00000000, 0x00400000, + 0x00000000, 0x00000440, 0x00000000, 0x00800000, + } }, + { { /* 634 */ + 0x01000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00080000, 0x00000000, + } }, + { { /* 635 */ + 0x01000000, 0x00000001, 0x00000000, 0x00020000, + 0x00000000, 0x20002000, 0x00000000, 0x00000004, + } }, + { { /* 636 */ + 0x00000008, 0x00100000, 0x00000000, 0x00010000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 637 */ + 0x00000004, 0x00008000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00008000, + } }, + { { /* 638 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000040, 0x00000000, 0x00004000, 0x00000000, + } }, + { { /* 639 */ + 0x00000010, 0x00002000, 0x40000040, 0x00000000, + 0x10000000, 0x00000000, 0x00008080, 0x00000000, + } }, + { { /* 640 */ + 0x00000000, 0x00000000, 0x00000080, 0x00000000, + 0x00100080, 0x000000a0, 0x00000000, 0x00000000, + } }, + { { /* 641 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00100000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 642 */ + 0x00000000, 0x00000000, 0x00001000, 0x00000000, + 0x0001000a, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 643 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x08002000, 0x00000000, + } }, + { { /* 644 */ + 0x00000808, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 645 */ + 0x00004000, 0x00002400, 0x00008000, 0x40000000, + 0x00000001, 0x00002000, 0x04000000, 0x00040004, + } }, + { { /* 646 */ + 0x00000000, 0x00002000, 0x00000000, 0x00000000, + 0x00000000, 0x1c200000, 0x00000000, 0x02000000, + } }, + { { /* 647 */ + 0x00000000, 0x00080000, 0x00400000, 0x00000002, + 0x00000000, 0x00000100, 0x00000000, 0x00000000, + } }, + { { /* 648 */ + 0x00000000, 0x00000000, 0x00000000, 0x00400000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 649 */ + 0x00004100, 0x00000400, 0x20200010, 0x00004004, + 0x00000000, 0x42000000, 0x00000000, 0x00000000, + } }, + { { /* 650 */ + 0x00000080, 0x00000000, 0x00000121, 0x00000200, + 0x000000b0, 0x80002000, 0x00000000, 0x00010000, + } }, + { { /* 651 */ + 0x00000010, 0x000000c0, 0x08100000, 0x00000020, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 652 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x02000000, 0x00000404, 0x00000000, 0x00000000, + } }, + { { /* 653 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00400000, 0x00000008, 0x00000000, 0x00000000, + } }, + { { /* 654 */ + 0x00000000, 0x00000002, 0x00020000, 0x00002000, + 0x00000000, 0x00000000, 0x00000000, 0x00204000, + } }, + { { /* 655 */ + 0x00000000, 0x00100000, 0x00000000, 0x00000000, + 0x00000000, 0x00800000, 0x00000100, 0x00000001, + } }, + { { /* 656 */ + 0x10000000, 0x01000000, 0x00002400, 0x00000004, + 0x00000000, 0x00000000, 0x00000020, 0x00000002, + } }, + { { /* 657 */ + 0x00010000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 658 */ + 0x00000000, 0x00002400, 0x00000000, 0x00000000, + 0x00004802, 0x00000000, 0x00000000, 0x80022000, + } }, + { { /* 659 */ + 0x00001004, 0x04208000, 0x20000020, 0x00040000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 660 */ + 0x00000000, 0x00100000, 0x40010000, 0x00000000, + 0x00080000, 0x00000000, 0x00100211, 0x00000000, + } }, + { { /* 661 */ + 0x00001400, 0x00000000, 0x00000000, 0x00000000, + 0x00610000, 0x80008c00, 0x00000000, 0x00000000, + } }, + { { /* 662 */ + 0x00000100, 0x00000040, 0x00000000, 0x00000004, + 0x00004000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 663 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000400, 0x00000000, + } }, + { { /* 664 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000210, 0x00000000, 0x00000000, + } }, + { { /* 665 */ + 0x00000000, 0x00000020, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 666 */ + 0x00004000, 0x00000000, 0x00000000, 0x02000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 667 */ + 0x00000000, 0x00000000, 0x00080002, 0x01000020, + 0x00400000, 0x00200000, 0x00008000, 0x00000000, + } }, + { { /* 668 */ + 0x00000000, 0x00020000, 0x00000000, 0xc0020000, + 0x10000000, 0x00000080, 0x00000000, 0x00000000, + } }, + { { /* 669 */ + 0x00000210, 0x00000000, 0x00001000, 0x04480000, + 0x20000000, 0x00000004, 0x00800000, 0x02000000, + } }, + { { /* 670 */ + 0x00000000, 0x08006000, 0x00001000, 0x00000000, + 0x00000000, 0x00100000, 0x00000000, 0x00000400, + } }, + { { /* 671 */ + 0x00100000, 0x00000000, 0x10000000, 0x08608000, + 0x00000000, 0x00000000, 0x00080002, 0x00000000, + } }, + { { /* 672 */ + 0x00000000, 0x20000000, 0x00008020, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 673 */ + 0x00000000, 0x00000000, 0x00000000, 0x10000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 674 */ + 0x00000000, 0x00100000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 675 */ + 0x00000000, 0x00000400, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 676 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x02000000, + } }, + { { /* 677 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000080, 0x00000000, + } }, + { { /* 678 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000000, 0x00000000, + } }, + { { /* 679 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00008000, 0x00000000, + } }, + { { /* 680 */ + 0x00000000, 0x00000000, 0x00000008, 0x00000000, + 0x00000000, 0x00000000, 0x00000400, 0x00000000, + } }, + { { /* 681 */ + 0x00000000, 0x00000000, 0x00220000, 0x00000004, + 0x00000000, 0x00040000, 0x00000004, 0x00000000, + } }, + { { /* 682 */ + 0x00000000, 0x00000000, 0x00001000, 0x00000080, + 0x00002000, 0x00000000, 0x00000000, 0x00004000, + } }, + { { /* 683 */ + 0x00000000, 0x00000000, 0x00000000, 0x00100000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 684 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00200000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 685 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x04000000, 0x00000000, 0x00000000, + } }, + { { /* 686 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000200, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 687 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 688 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00080000, 0x00000000, + } }, + { { /* 689 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x01000000, 0x00000000, 0x00000400, + } }, + { { /* 690 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000080, 0x00000000, 0x00000000, + } }, + { { /* 691 */ + 0x00000000, 0x00000800, 0x00000100, 0x40000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 692 */ + 0x00000000, 0x00200000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 693 */ + 0x00000000, 0x00000000, 0x01000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 694 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x04000000, 0x00000000, + } }, + { { /* 695 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00001000, 0x00000000, + } }, + { { /* 696 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 697 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x04040000, + } }, + { { /* 698 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000020, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 699 */ + 0x00000000, 0x00000000, 0x00800000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 700 */ + 0x00000000, 0x00200000, 0x40000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 701 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x20000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 702 */ + 0x00000000, 0x00000000, 0x00000000, 0x04000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, + } }, + { { /* 703 */ + 0x00000000, 0x40000000, 0x02000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 704 */ + 0x00000000, 0x00000000, 0x00000000, 0x00080000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 705 */ + 0x00000000, 0x00000010, 0x00000000, 0x00000000, + 0x00000000, 0x20000000, 0x00000000, 0x00000000, + } }, + { { /* 706 */ + 0x00000000, 0x00000000, 0x20000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 707 */ + 0x00000080, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000004, + } }, + { { /* 708 */ + 0x00000000, 0x00000000, 0x00000000, 0x00002000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 709 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x10000001, 0x00000000, + } }, + { { /* 710 */ + 0x00008000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 711 */ + 0x00000000, 0x00000000, 0x00004040, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 712 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00042400, 0x00000000, + } }, + { { /* 713 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x02000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 714 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000080, + } }, + { { /* 715 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000020, + } }, + { { /* 716 */ + 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 717 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00020000, 0x00000000, + } }, + { { /* 718 */ + 0x00000000, 0x00000000, 0x00002000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 719 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x01000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 720 */ + 0x00000000, 0x00040000, 0x08000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 721 */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000280, 0x00000000, + } }, + { { /* 722 */ + 0x7f7b7f8b, 0xef553db4, 0xf35dfba8, 0x400b0243, + 0x8d3efb40, 0x8c2c7bf7, 0xe3fa6eff, 0xa8ed1d3a, + } }, + { { /* 723 */ + 0xcf83e602, 0x35558cf5, 0xffabe048, 0xd85992b9, + 0x2892ab18, 0x8020d7e9, 0xf583c438, 0x450ae74a, + } }, + { { /* 724 */ + 0x9714b000, 0x54007762, 0x1420d188, 0xc8c01020, + 0x00002121, 0x0c0413a8, 0x04408000, 0x082870c0, + } }, + { { /* 725 */ + 0x000408c0, 0x80000002, 0x14722b7b, 0x3bfb7924, + 0x1ae43327, 0x38ef9835, 0x28029ad1, 0xbf69a813, + } }, + { { /* 726 */ + 0x2fc665cf, 0xafc96b11, 0x5053340f, 0xa00486a2, + 0xe8090106, 0xc00e3f0f, 0x81450a88, 0xc6010010, + } }, + { { /* 727 */ + 0x26e1a161, 0xce00444b, 0xd4eec7aa, 0x85bbcadf, + 0xa5203a74, 0x8840436c, 0x8bd23f06, 0x3befff79, + } }, + { { /* 728 */ + 0xe8eff75a, 0x5b36fbcb, 0x1bfd0d49, 0x39ee0154, + 0x2e75d855, 0xa91abfd8, 0xf6bff3d7, 0xb40c67e0, + } }, + { { /* 729 */ + 0x081382c2, 0xd08bd49d, 0x1061065a, 0x59e074f2, + 0xb3128f9f, 0x6aaa0080, 0xb05e3230, 0x60ac9d7a, + } }, + { { /* 730 */ + 0xc900d303, 0x8a563098, 0x13907000, 0x18421f14, + 0x0008c060, 0x10808008, 0xec900400, 0xe6332817, + } }, + { { /* 731 */ + 0x90000758, 0x4e09f708, 0xfc83f485, 0x18c8af53, + 0x080c187c, 0x01146adf, 0xa734c80c, 0x2710a011, + } }, + { { /* 732 */ + 0x422228c5, 0x00210413, 0x41123010, 0x40001820, + 0xc60c022b, 0x10000300, 0x00220022, 0x02495810, + } }, + { { /* 733 */ + 0x9670a094, 0x1792eeb0, 0x05f2cb96, 0x23580025, + 0x42cc25de, 0x4a04cf38, 0x359f0c40, 0x8a001128, + } }, + { { /* 734 */ + 0x910a13fa, 0x10560229, 0x04200641, 0x84f00484, + 0x0c040000, 0x412c0400, 0x11541206, 0x00020a4b, + } }, + { { /* 735 */ + 0x00c00200, 0x00940000, 0xbfbb0001, 0x242b167c, + 0x7fa89bbb, 0xe3790c7f, 0xe00d10f4, 0x9f014132, + } }, + { { /* 736 */ + 0x35728652, 0xff1210b4, 0x4223cf27, 0x8602c06b, + 0x1fd33106, 0xa1aa3a0c, 0x02040812, 0x08012572, + } }, + { { /* 737 */ + 0x485040cc, 0x601062d0, 0x29001c80, 0x00109a00, + 0x22000004, 0x00800000, 0x68002020, 0x609ecbe6, + } }, + { { /* 738 */ + 0x3f73916e, 0x398260c0, 0x48301034, 0xbd5c0006, + 0xd6fb8cd1, 0x43e820e1, 0x084e0600, 0xc4d00500, + } }, + { { /* 739 */ + 0x89aa8d1f, 0x1602a6e1, 0x21ed0001, 0x1a8b3656, + 0x13a51fb7, 0x30a06502, 0x23c7b278, 0xe9226c93, + } }, + { { /* 740 */ + 0x3a74e47f, 0x98208fe3, 0x2625280e, 0xbf49bf9c, + 0xac543218, 0x1916b949, 0xb5220c60, 0x0659fbc1, + } }, + { { /* 741 */ + 0x8420e343, 0x800008d9, 0x20225500, 0x00a10184, + 0x20104800, 0x40801380, 0x00160d04, 0x80200040, + } }, + { { /* 742 */ + 0x8de7fd40, 0xe0985436, 0x091e7b8b, 0xd249fec8, + 0x8dee0611, 0xba221937, 0x9fdd77f4, 0xf0daf3ec, + } }, + { { /* 743 */ + 0xec424386, 0x26048d3f, 0xc021fa6c, 0x0cc2628e, + 0x0145d785, 0x559977ad, 0x4045e250, 0xa154260b, + } }, + { { /* 744 */ + 0x58199827, 0xa4103443, 0x411405f2, 0x07002280, + 0x426600b4, 0x15a17210, 0x41856025, 0x00000054, + } }, + { { /* 745 */ + 0x01040201, 0xcb70c820, 0x6a629320, 0x0095184c, + 0x9a8b1880, 0x3201aab2, 0x00c4d87a, 0x04c3f3e5, + } }, + { { /* 746 */ + 0xa238d44d, 0x5072a1a1, 0x84fc980a, 0x44d1c152, + 0x20c21094, 0x42104180, 0x3a000000, 0xd29d0240, + } }, + { { /* 747 */ + 0xa8b12f01, 0x2432bd40, 0xd04bd34d, 0xd0ada723, + 0x75a10a92, 0x01e9adac, 0x771f801a, 0xa01b9225, + } }, + { { /* 748 */ + 0x20cadfa1, 0x738c0602, 0x003b577f, 0x00d00bff, + 0x0088806a, 0x0029a1c4, 0x05242a05, 0x16234009, + } }, + { { /* 749 */ + 0x80056822, 0xa2112011, 0x64900004, 0x13824849, + 0x193023d5, 0x08922980, 0x88115402, 0xa0042001, + } }, + { { /* 750 */ + 0x81800400, 0x60228502, 0x0b010090, 0x12020022, + 0x00834011, 0x00001a01, 0x00000000, 0x00000000, + } }, + { { /* 751 */ + 0x00000000, 0x4684009f, 0x020012c8, 0x1a0004fc, + 0x0c4c2ede, 0x80b80402, 0x0afca826, 0x22288c02, + } }, + { { /* 752 */ + 0x8f7ba0e0, 0x2135c7d6, 0xf8b106c7, 0x62550713, + 0x8a19936e, 0xfb0e6efa, 0x48f91630, 0x7debcd2f, + } }, + { { /* 753 */ + 0x4e845892, 0x7a2e4ca0, 0x561eedea, 0x1190c649, + 0xe83a5324, 0x8124cfdb, 0x634218f1, 0x1a8a5853, + } }, + { { /* 754 */ + 0x24d37420, 0x0514aa3b, 0x89586018, 0xc0004800, + 0x91018268, 0x2cd684a4, 0xc4ba8886, 0x02100377, + } }, + { { /* 755 */ + 0x00388244, 0x404aae11, 0x510028c0, 0x15146044, + 0x10007310, 0x02480082, 0x40060205, 0x0000c003, + } }, + { { /* 756 */ + 0x0c020000, 0x02200008, 0x40009000, 0xd161b800, + 0x32744621, 0x3b8af800, 0x8b00050f, 0x2280bbd0, + } }, + { { /* 757 */ + 0x07690600, 0x00438040, 0x50005420, 0x250c41d0, + 0x83108410, 0x02281101, 0x00304008, 0x020040a1, + } }, + { { /* 758 */ + 0x20000040, 0xabe31500, 0xaa443180, 0xc624c2c6, + 0x8004ac13, 0x03d1b000, 0x4285611e, 0x1d9ff303, + } }, + { { /* 759 */ + 0x78e8440a, 0xc3925e26, 0x00852000, 0x4000b001, + 0x88424a90, 0x0c8dca04, 0x4203a705, 0x000422a1, + } }, + { { /* 760 */ + 0x0c018668, 0x10795564, 0xdea00002, 0x40c12000, + 0x5001488b, 0x04000380, 0x50040000, 0x80d0c05d, + } }, + { { /* 761 */ + 0x970aa010, 0x4dafbb20, 0x1e10d921, 0x83140460, + 0xa6d68848, 0x733fd83b, 0x497427bc, 0x92130ddc, + } }, + { { /* 762 */ + 0x8ba1142b, 0xd1392e75, 0x50503009, 0x69008808, + 0x024a49d4, 0x80164010, 0x89d7e564, 0x5316c020, + } }, + { { /* 763 */ + 0x86002b92, 0x15e0a345, 0x0c03008b, 0xe200196e, + 0x80067031, 0xa82916a5, 0x18802000, 0xe1487aac, + } }, + { { /* 764 */ + 0xb5d63207, 0x5f9132e8, 0x20e550a1, 0x10807c00, + 0x9d8a7280, 0x421f00aa, 0x02310e22, 0x04941100, + } }, + { { /* 765 */ + 0x40080022, 0x5c100010, 0xfcc80343, 0x0580a1a5, + 0x04008433, 0x6e080080, 0x81262a4b, 0x2901aad8, + } }, + { { /* 766 */ + 0x4490684d, 0xba880009, 0x00820040, 0x87d10000, + 0xb1e6215b, 0x80083161, 0xc2400800, 0xa600a069, + } }, + { { /* 767 */ + 0x4a328d58, 0x550a5d71, 0x2d579aa0, 0x4aa64005, + 0x30b12021, 0x01123fc6, 0x260a10c2, 0x50824462, + } }, + { { /* 768 */ + 0x80409880, 0x810004c0, 0x00002003, 0x38180000, + 0xf1a60200, 0x720e4434, 0x92e035a2, 0x09008101, + } }, + { { /* 769 */ + 0x00000400, 0x00008885, 0x00000000, 0x00804000, + 0x00000000, 0x00004040, 0x00000000, 0x00000000, + } }, + { { /* 770 */ + 0x00000000, 0x08000000, 0x00000082, 0x00000000, + 0x88000004, 0xe7efbfff, 0xffbfffff, 0xfdffefef, + } }, + { { /* 771 */ + 0xbffefbff, 0x057fffff, 0x85b30034, 0x42164706, + 0xe4105402, 0xb3058092, 0x81305422, 0x180b4263, + } }, + { { /* 772 */ + 0x13f5387b, 0xa9ea07e5, 0x05143c4c, 0x80020600, + 0xbd481ad9, 0xf496ee37, 0x7ec0705f, 0x355fbfb2, + } }, + { { /* 773 */ + 0x455fe644, 0x41469000, 0x063b1d40, 0xfe1362a1, + 0x39028505, 0x0c080548, 0x0000144f, 0x58183488, + } }, + { { /* 774 */ + 0xd8153077, 0x4bfbbd0e, 0x85008a90, 0xe61dc100, + 0xb386ed14, 0x639bff72, 0xd9befd92, 0x0a92887b, + } }, + { { /* 775 */ + 0x1cb2d3fe, 0x177ab980, 0xdc1782c9, 0x3980fffb, + 0x590c4260, 0x37df0f01, 0xb15094a3, 0x23070623, + } }, + { { /* 776 */ + 0x3102f85a, 0x310201f0, 0x1e820040, 0x056a3a0a, + 0x12805b84, 0xa7148002, 0xa04b2612, 0x90011069, + } }, + { { /* 777 */ + 0x848a1000, 0x3f801802, 0x42400708, 0x4e140110, + 0x180080b0, 0x0281c510, 0x10298202, 0x88000210, + } }, + { { /* 778 */ + 0x00420020, 0x11000280, 0x4413e000, 0xfe025804, + 0x30283c07, 0x04739798, 0xcb13ced1, 0x431f6210, + } }, + { { /* 779 */ + 0x55ac278d, 0xc892422e, 0x02885380, 0x78514039, + 0x8088292c, 0x2428b900, 0x080e0c41, 0x42004421, + } }, + { { /* 780 */ + 0x08680408, 0x12040006, 0x02903031, 0xe0855b3e, + 0x10442936, 0x10822814, 0x83344266, 0x531b013c, + } }, + { { /* 781 */ + 0x0e0d0404, 0x00510c22, 0xc0000012, 0x88000040, + 0x0000004a, 0x00000000, 0x5447dff6, 0x00088868, + } }, + { { /* 782 */ + 0x00000081, 0x40000000, 0x00000100, 0x02000000, + 0x00080600, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 783 */ + 0x00000080, 0x00000040, 0x00000000, 0x00001040, + 0x00000000, 0xf7fdefff, 0xfffeff7f, 0xfffffbff, + } }, + { { /* 784 */ + 0xbffffdff, 0x00ffffff, 0x042012c2, 0x07080c06, + 0x01101624, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 785 */ + 0xe0000000, 0xfffffffe, 0x7f79ffff, 0x00f928df, + 0x80120c32, 0xd53a0008, 0xecc2d858, 0x2fa89d18, + } }, + { { /* 786 */ + 0xe0109620, 0x2622d60c, 0x02060f97, 0x9055b240, + 0x501180a2, 0x04049800, 0x00004000, 0x00000000, + } }, + { { /* 787 */ + 0x00000000, 0x00000000, 0x00000000, 0xfffffbc0, + 0xdffbeffe, 0x62430b08, 0xfb3b41b6, 0x23896f74, + } }, + { { /* 788 */ + 0xecd7ae7f, 0x5960e047, 0x098fa096, 0xa030612c, + 0x2aaa090d, 0x4f7bd44e, 0x388bc4b2, 0x6110a9c6, + } }, + { { /* 789 */ + 0x42000014, 0x0202800c, 0x6485fe48, 0xe3f7d63e, + 0x0c073aa0, 0x0430e40c, 0x1002f680, 0x00000000, + } }, + { { /* 790 */ + 0x00000000, 0x00000000, 0x00000000, 0x00100000, + 0x00004000, 0x00004000, 0x00000100, 0x00000000, + } }, + { { /* 791 */ + 0x00000000, 0x40000000, 0x00000000, 0x00000400, + 0x00008000, 0x00000000, 0x00400400, 0x00000000, + } }, + { { /* 792 */ + 0x00000000, 0x40000000, 0x00000000, 0x00000800, + 0xfebdffe0, 0xffffffff, 0xfbe77f7f, 0xf7ffffbf, + } }, + { { /* 793 */ + 0xefffffff, 0xdff7ff7e, 0xfbdff6f7, 0x804fbffe, + 0x00000000, 0x00000000, 0x00000000, 0x7fffef00, + } }, + { { /* 794 */ + 0xb6f7ff7f, 0xb87e4406, 0x88313bf5, 0x00f41796, + 0x1391a960, 0x72490080, 0x0024f2f3, 0x42c88701, + } }, + { { /* 795 */ + 0x5048e3d3, 0x43052400, 0x4a4c0000, 0x10580227, + 0x01162820, 0x0014a809, 0x00000000, 0x00683ec0, + } }, + { { /* 796 */ + 0x00000000, 0x00000000, 0x00000000, 0xffe00000, + 0xfddbb7ff, 0x000000f7, 0xc72e4000, 0x00000180, + } }, + { { /* 797 */ + 0x00012000, 0x00004000, 0x00300000, 0xb4f7ffa8, + 0x03ffadf3, 0x00000120, 0x00000000, 0x00000000, + } }, + { { /* 798 */ + 0x00000000, 0x00000000, 0x00000000, 0xfffbf000, + 0xfdcf9df7, 0x15c301bf, 0x810a1827, 0x0a00a842, + } }, + { { /* 799 */ + 0x80088108, 0x18048008, 0x0012a3be, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + } }, + { { /* 800 */ + 0x00000000, 0x00000000, 0x00000000, 0x90000000, + 0xdc3769e6, 0x3dff6bff, 0xf3f9fcf8, 0x00000004, + } }, + { { /* 801 */ + 0x80000000, 0xe7eebf6f, 0x5da2dffe, 0xc00b3fd8, + 0xa00c0984, 0x69100040, 0xb912e210, 0x5a0086a5, + } }, + { { /* 802 */ + 0x02896800, 0x6a809005, 0x00030010, 0x80000000, + 0x8e001ff9, 0x00000001, 0x00000000, 0x00000000, + } }, + { { /* 803 */ + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0x003fffff, 0x00000000, + } }, +}, +{ + /* aa */ + LEAF( 0, 0), + /* ab */ + LEAF( 1, 1), + /* ae */ + LEAF( 2, 2), + /* af */ + LEAF( 3, 3), LEAF( 3, 4), + /* agr */ + LEAF( 5, 5), + /* aho */ + LEAF( 6, 6), + /* ak */ + LEAF( 7, 7), LEAF( 7, 8), LEAF( 7, 9), LEAF( 7, 10), + LEAF( 7, 11), + /* akk */ + LEAF( 12, 12), LEAF( 12, 12), LEAF( 12, 12), LEAF( 12, 13), + LEAF( 12, 14), LEAF( 12, 15), + /* am */ + LEAF( 18, 16), LEAF( 18, 17), + /* an */ + LEAF( 20, 18), + /* anp */ + LEAF( 21, 19), + /* ar */ + LEAF( 22, 20), + /* arc */ + LEAF( 23, 21), + /* as */ + LEAF( 24, 22), + /* ast */ + LEAF( 25, 18), LEAF( 25, 23), + /* av */ + LEAF( 27, 24), + /* ay */ + LEAF( 28, 25), + /* ayc */ + LEAF( 29, 26), + /* az_az */ + LEAF( 30, 27), LEAF( 30, 28), LEAF( 30, 29), + /* az_ir */ + LEAF( 33, 30), + /* ba */ + LEAF( 34, 31), + /* ban */ + LEAF( 35, 32), + /* bax */ + LEAF( 36, 33), + /* be */ + LEAF( 37, 34), + /* bem */ + LEAF( 38, 35), + /* ber_dz */ + LEAF( 39, 35), LEAF( 39, 36), LEAF( 39, 37), LEAF( 39, 38), + /* ber_ma */ + LEAF( 43, 39), + /* bg */ + LEAF( 44, 40), + /* bi */ + LEAF( 45, 41), + /* bin */ + LEAF( 46, 42), LEAF( 46, 43), LEAF( 46, 44), + /* bku */ + LEAF( 49, 45), + /* blt */ + LEAF( 50, 46), + /* bm */ + LEAF( 51, 35), LEAF( 51, 47), LEAF( 51, 48), + /* bn */ + LEAF( 54, 49), + /* bo */ + LEAF( 55, 50), + /* br */ + LEAF( 56, 51), + /* brx */ + LEAF( 57, 52), + /* bs */ + LEAF( 58, 35), LEAF( 58, 53), + /* bua */ + LEAF( 60, 54), + /* byn */ + LEAF( 61, 55), LEAF( 61, 56), + /* ca */ + LEAF( 63, 57), LEAF( 63, 58), + /* ccp */ + LEAF( 65, 59), + /* ch */ + LEAF( 66, 60), + /* chm */ + LEAF( 67, 61), + /* chr */ + LEAF( 68, 62), + /* cjm */ + LEAF( 69, 63), + /* ckb */ + LEAF( 70, 64), + /* cmn */ + LEAF( 71, 65), LEAF( 71, 66), LEAF( 71, 67), LEAF( 71, 68), + LEAF( 71, 69), LEAF( 71, 70), LEAF( 71, 71), LEAF( 71, 72), + LEAF( 71, 73), LEAF( 71, 74), LEAF( 71, 75), LEAF( 71, 76), + LEAF( 71, 77), LEAF( 71, 78), LEAF( 71, 79), LEAF( 71, 80), + LEAF( 71, 81), LEAF( 71, 82), LEAF( 71, 83), LEAF( 71, 84), + LEAF( 71, 85), LEAF( 71, 86), LEAF( 71, 87), LEAF( 71, 88), + LEAF( 71, 89), LEAF( 71, 90), LEAF( 71, 91), LEAF( 71, 92), + LEAF( 71, 93), LEAF( 71, 94), LEAF( 71, 95), LEAF( 71, 96), + LEAF( 71, 97), LEAF( 71, 98), LEAF( 71, 99), LEAF( 71,100), + LEAF( 71,101), LEAF( 71,102), LEAF( 71,103), LEAF( 71,104), + LEAF( 71,105), LEAF( 71,106), LEAF( 71,107), LEAF( 71,108), + LEAF( 71,109), LEAF( 71,110), LEAF( 71,111), LEAF( 71,112), + LEAF( 71,113), LEAF( 71,114), LEAF( 71,115), LEAF( 71,116), + LEAF( 71,117), LEAF( 71,118), LEAF( 71,119), LEAF( 71,120), + LEAF( 71,121), LEAF( 71,122), LEAF( 71,123), LEAF( 71,124), + LEAF( 71,125), LEAF( 71,126), LEAF( 71,127), LEAF( 71,128), + LEAF( 71,129), LEAF( 71,130), LEAF( 71,131), LEAF( 71,132), + LEAF( 71,133), LEAF( 71,134), LEAF( 71,135), LEAF( 71,136), + LEAF( 71,137), LEAF( 71,138), LEAF( 71,139), LEAF( 71,140), + LEAF( 71,141), LEAF( 71,142), LEAF( 71,143), LEAF( 71,144), + LEAF( 71,145), LEAF( 71,146), LEAF( 71,147), + /* co */ + LEAF(154,148), LEAF(154,149), + /* cop */ + LEAF(156,150), LEAF(156,151), + /* crh */ + LEAF(158,152), LEAF(158,153), + /* cs */ + LEAF(160,154), LEAF(160,155), + /* csb */ + LEAF(162,156), LEAF(162,157), + /* cu */ + LEAF(164,158), + /* cv */ + LEAF(165,159), LEAF(165,160), + /* cy */ + LEAF(167,161), LEAF(167,162), LEAF(167,163), + /* da */ + LEAF(170,164), + /* de */ + LEAF(171,165), + /* dmf */ + LEAF(172,166), + /* doi */ + LEAF(173,167), + /* dv */ + LEAF(174,168), + /* ecy */ + LEAF(175,169), + /* ee */ + LEAF(176, 42), LEAF(176,170), LEAF(176,171), LEAF(176,172), + /* egy */ + LEAF(180, 12), LEAF(180, 12), LEAF(180, 12), LEAF(180, 12), + LEAF(180,173), + /* eky */ + LEAF(185,173), + /* el */ + LEAF(186,174), + /* en */ + LEAF(187,175), + /* eo */ + LEAF(188, 35), LEAF(188,176), + /* et */ + LEAF(190,177), LEAF(190,178), + /* ett */ + LEAF(192,179), + /* eu */ + LEAF(193,180), + /* ff */ + LEAF(194, 35), LEAF(194,181), LEAF(194,182), + /* fi */ + LEAF(197,183), LEAF(197,178), + /* fil */ + LEAF(199,184), + /* fo */ + LEAF(200,185), + /* fur */ + LEAF(201,186), + /* fy */ + LEAF(202,187), + /* ga */ + LEAF(203,188), LEAF(203,189), LEAF(203,190), + /* gd */ + LEAF(206,191), + /* gez */ + LEAF(207,192), LEAF(207,193), + /* gmy */ + LEAF(209,194), + /* gn */ + LEAF(210,195), LEAF(210,196), LEAF(210,197), + /* got */ + LEAF(213,198), + /* gu */ + LEAF(214,199), + /* gv */ + LEAF(215,200), + /* ha */ + LEAF(216, 35), LEAF(216,201), LEAF(216,202), + /* haw */ + LEAF(219, 35), LEAF(219,203), LEAF(219,204), + /* he */ + LEAF(222,205), + /* hlu */ + LEAF(223, 12), LEAF(223, 12), LEAF(223,206), + /* hmd */ + LEAF(226,207), + /* hnn */ + LEAF(227,208), + /* hoc */ + LEAF(228,209), + /* hsb */ + LEAF(229,210), LEAF(229,211), + /* ht */ + LEAF(231,212), + /* hu */ + LEAF(232,213), LEAF(232,214), + /* hy */ + LEAF(234,215), + /* hz */ + LEAF(235, 35), LEAF(235,216), LEAF(235,217), + /* id */ + LEAF(238,218), + /* ie */ + LEAF(239,154), + /* ig */ + LEAF(240, 35), LEAF(240,219), + /* ii */ + LEAF(242, 12), LEAF(242, 12), LEAF(242, 12), LEAF(242, 12), + LEAF(242,220), + /* ik */ + LEAF(247,221), + /* is */ + LEAF(248,222), + /* it */ + LEAF(249,223), + /* iu */ + LEAF(250,224), LEAF(250,225), LEAF(250,226), + /* ja */ + LEAF(253,227), LEAF(253,228), LEAF(253,229), LEAF(253,230), + LEAF(253,231), LEAF(253,232), LEAF(253,233), LEAF(253,234), + LEAF(253,235), LEAF(253,236), LEAF(253,237), LEAF(253,238), + LEAF(253,239), LEAF(253,240), LEAF(253,241), LEAF(253,242), + LEAF(253,243), LEAF(253,244), LEAF(253,245), LEAF(253,246), + LEAF(253,247), LEAF(253,248), LEAF(253,249), LEAF(253,250), + LEAF(253,251), LEAF(253,252), LEAF(253,253), LEAF(253,254), + LEAF(253,255), LEAF(253,256), LEAF(253,257), LEAF(253,258), + LEAF(253,259), LEAF(253,260), LEAF(253,261), LEAF(253,262), + LEAF(253,263), LEAF(253,264), LEAF(253,265), LEAF(253,266), + LEAF(253,267), LEAF(253,268), LEAF(253,269), LEAF(253,270), + LEAF(253,271), LEAF(253,272), LEAF(253,273), LEAF(253,274), + LEAF(253,275), LEAF(253,276), LEAF(253,277), LEAF(253,278), + LEAF(253,279), LEAF(253,280), LEAF(253,281), LEAF(253,282), + LEAF(253,283), LEAF(253,284), LEAF(253,285), LEAF(253,286), + LEAF(253,287), LEAF(253,288), LEAF(253,289), LEAF(253,290), + LEAF(253,291), LEAF(253,292), LEAF(253,293), LEAF(253,294), + LEAF(253,295), LEAF(253,296), LEAF(253,297), LEAF(253,298), + LEAF(253,299), LEAF(253,300), LEAF(253,301), LEAF(253,302), + LEAF(253,303), LEAF(253,304), LEAF(253,305), LEAF(253,306), + LEAF(253,307), LEAF(253,308), LEAF(253,309), + /* jv */ + LEAF(336,310), + /* ka */ + LEAF(337,311), + /* kaa */ + LEAF(338,312), + /* kaw */ + LEAF(339,313), + /* khb */ + LEAF(340,314), + /* ki */ + LEAF(341, 35), LEAF(341,315), + /* kk */ + LEAF(343,316), + /* kl */ + LEAF(344,317), LEAF(344,318), + /* km */ + LEAF(346,319), + /* kn */ + LEAF(347,320), + /* ko */ + LEAF(348,321), LEAF(348,322), LEAF(348,323), LEAF(348,324), + LEAF(348,325), LEAF(348,326), LEAF(348,327), LEAF(348,328), + LEAF(348,329), LEAF(348,330), LEAF(348,331), LEAF(348,332), + LEAF(348,333), LEAF(348,334), LEAF(348,335), LEAF(348,336), + LEAF(348,337), LEAF(348,338), LEAF(348,339), LEAF(348,340), + LEAF(348,341), LEAF(348,342), LEAF(348,343), LEAF(348,344), + LEAF(348,345), LEAF(348,346), LEAF(348,347), LEAF(348,348), + LEAF(348,349), LEAF(348,350), LEAF(348,351), LEAF(348,352), + LEAF(348,353), LEAF(348,354), LEAF(348,355), LEAF(348,356), + LEAF(348,357), LEAF(348,358), LEAF(348,359), LEAF(348,360), + LEAF(348,361), LEAF(348,362), LEAF(348,363), LEAF(348,364), + LEAF(348,365), + /* kr */ + LEAF(393, 35), LEAF(393,366), LEAF(393,367), + /* ks */ + LEAF(396,368), + /* ku_am */ + LEAF(397,369), LEAF(397,370), + /* ku_tr */ + LEAF(399,371), LEAF(399,372), + /* kum */ + LEAF(401,373), + /* kv */ + LEAF(402,374), + /* kw */ + LEAF(403, 35), LEAF(403,203), LEAF(403,375), + /* ky */ + LEAF(406,376), + /* la */ + LEAF(407, 35), LEAF(407,377), + /* lah */ + LEAF(409,378), + /* lb */ + LEAF(410,379), + /* lep */ + LEAF(411,380), + /* lg */ + LEAF(412, 35), LEAF(412,381), + /* li */ + LEAF(414,382), + /* lif */ + LEAF(415,383), + /* lij */ + LEAF(416,384), + /* lis */ + LEAF(417,385), + /* ln */ + LEAF(418,386), LEAF(418,387), LEAF(418, 9), LEAF(418,388), + /* lo */ + LEAF(422,389), + /* lt */ + LEAF(423, 35), LEAF(423,390), + /* lv */ + LEAF(425, 35), LEAF(425,391), + /* mg */ + LEAF(427,392), + /* mh */ + LEAF(428, 35), LEAF(428,393), + /* mi */ + LEAF(430, 35), LEAF(430,203), LEAF(430,394), + /* mid */ + LEAF(433,395), + /* miq */ + LEAF(434,396), LEAF(434,196), LEAF(434,397), + /* mk */ + LEAF(437,398), + /* ml */ + LEAF(438,399), + /* mn_cn */ + LEAF(439,400), + /* mn_mn */ + LEAF(440,401), + /* mni */ + LEAF(441,402), LEAF(441,403), + /* mnw */ + LEAF(443,404), + /* mo */ + LEAF(444,405), LEAF(444,159), LEAF(444,406), LEAF(444,373), + /* mro */ + LEAF(448,407), + /* mt */ + LEAF(449,408), LEAF(449,409), + /* na */ + LEAF(451, 7), LEAF(451,410), + /* nan */ + LEAF(453,175), LEAF(453, 65), LEAF(453, 66), LEAF(453, 67), + LEAF(453, 68), LEAF(453, 69), LEAF(453, 70), LEAF(453, 71), + LEAF(453, 72), LEAF(453, 73), LEAF(453, 74), LEAF(453, 75), + LEAF(453, 76), LEAF(453, 77), LEAF(453, 78), LEAF(453, 79), + LEAF(453, 80), LEAF(453, 81), LEAF(453, 82), LEAF(453, 83), + LEAF(453, 84), LEAF(453, 85), LEAF(453, 86), LEAF(453, 87), + LEAF(453, 88), LEAF(453, 89), LEAF(453, 90), LEAF(453, 91), + LEAF(453, 92), LEAF(453, 93), LEAF(453, 94), LEAF(453, 95), + LEAF(453, 96), LEAF(453, 97), LEAF(453, 98), LEAF(453, 99), + LEAF(453,100), LEAF(453,101), LEAF(453,102), LEAF(453,103), + LEAF(453,104), LEAF(453,105), LEAF(453,106), LEAF(453,107), + LEAF(453,108), LEAF(453,109), LEAF(453,110), LEAF(453,111), + LEAF(453,112), LEAF(453,113), LEAF(453,114), LEAF(453,115), + LEAF(453,116), LEAF(453,117), LEAF(453,118), LEAF(453,119), + LEAF(453,120), LEAF(453,121), LEAF(453,122), LEAF(453,123), + LEAF(453,124), LEAF(453,125), LEAF(453,126), LEAF(453,127), + LEAF(453,128), LEAF(453,129), LEAF(453,130), LEAF(453,131), + LEAF(453,132), LEAF(453,133), LEAF(453,134), LEAF(453,135), + LEAF(453,136), LEAF(453,137), LEAF(453,138), LEAF(453,139), + LEAF(453,140), LEAF(453,141), LEAF(453,142), LEAF(453,143), + LEAF(453,144), LEAF(453,145), LEAF(453,146), LEAF(453,147), + /* nb */ + LEAF(537,411), + /* ne */ + LEAF(538,412), + /* nhn */ + LEAF(539, 18), LEAF(539,413), + /* niu */ + LEAF(541,175), LEAF(541,414), + /* nl */ + LEAF(543,415), + /* nn */ + LEAF(544,416), + /* nnp */ + LEAF(545,417), + /* nqo */ + LEAF(546,418), + /* nso */ + LEAF(547,419), LEAF(547,420), + /* nv */ + LEAF(549,421), LEAF(549,422), LEAF(549,423), LEAF(549,424), + /* ny */ + LEAF(553, 35), LEAF(553,425), + /* oc */ + LEAF(555,426), + /* or */ + LEAF(556,427), + /* osa */ + LEAF(557,428), + /* ota */ + LEAF(558,429), + /* otk */ + LEAF(559,430), + /* oui */ + LEAF(560,431), + /* pa */ + LEAF(561,432), + /* pal */ + LEAF(562,433), + /* pap_an */ + LEAF(563,434), + /* pap_aw */ + LEAF(564,435), + /* peo */ + LEAF(565,436), + /* pgd */ + LEAF(566,437), + /* pgl */ + LEAF(567,438), + /* phn */ + LEAF(568,439), + /* pl */ + LEAF(569,210), LEAF(569,440), + /* ps_af */ + LEAF(571,441), + /* ps_pk */ + LEAF(572,442), + /* pt */ + LEAF(573,443), + /* qu */ + LEAF(574,435), LEAF(574,444), + /* rhg */ + LEAF(576,445), + /* rif */ + LEAF(577,175), LEAF(577,446), LEAF(577, 37), LEAF(577,447), + /* rm */ + LEAF(581,448), + /* ro */ + LEAF(582,405), LEAF(582,159), LEAF(582,406), + /* sah */ + LEAF(585,449), + /* sam */ + LEAF(586,450), + /* sat */ + LEAF(587,451), + /* sc */ + LEAF(588,452), + /* sco */ + LEAF(589, 35), LEAF(589,453), LEAF(589,454), + /* sd */ + LEAF(592,455), + /* se */ + LEAF(593,456), LEAF(593,457), + /* sg */ + LEAF(595,458), + /* sgs */ + LEAF(596,459), LEAF(596,460), LEAF(596,461), + /* sh */ + LEAF(599, 35), LEAF(599, 53), LEAF(599,462), + /* shs */ + LEAF(602,463), LEAF(602,464), + /* si */ + LEAF(604,465), + /* sid */ + LEAF(605,466), LEAF(605, 17), + /* sk */ + LEAF(607,467), LEAF(607,468), + /* sm */ + LEAF(609, 35), LEAF(609,204), + /* sma */ + LEAF(611,469), + /* smj */ + LEAF(612,470), + /* smn */ + LEAF(613,471), LEAF(613,472), + /* sms */ + LEAF(615,473), LEAF(615,474), LEAF(615,475), + /* so */ + LEAF(618,476), + /* sog */ + LEAF(619,477), + /* sq */ + LEAF(620,478), + /* sr */ + LEAF(621,479), + /* su */ + LEAF(622,480), LEAF(622,481), + /* suz */ + LEAF(624,482), + /* sv */ + LEAF(625,483), + /* syr */ + LEAF(626,484), + /* szl */ + LEAF(627,485), LEAF(627,486), + /* ta */ + LEAF(629,487), + /* tbw */ + LEAF(630,488), + /* tdd */ + LEAF(631,489), + /* te */ + LEAF(632,490), + /* tg */ + LEAF(633,491), + /* th */ + LEAF(634,492), + /* tig */ + LEAF(635,493), LEAF(635, 56), + /* tk */ + LEAF(637,494), LEAF(637,495), + /* tl */ + LEAF(639,496), + /* tr */ + LEAF(640,497), LEAF(640,153), + /* tt */ + LEAF(642,498), + /* txg */ + LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), + LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), + LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), + LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), + LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), + LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), LEAF(643,499), + LEAF(643, 12), LEAF(643, 12), LEAF(643, 12), LEAF(643,500), + /* ty */ + LEAF(671,501), LEAF(671,203), LEAF(671,423), + /* ug */ + LEAF(674,502), + /* uga */ + LEAF(675,503), + /* uk */ + LEAF(676,504), + /* und_zmth */ + LEAF(677,505), LEAF(677,506), LEAF(677,507), LEAF(677,508), + LEAF(677,509), LEAF(677,510), LEAF(677,511), LEAF(677,512), + LEAF(677,513), LEAF(677,514), LEAF(677,515), LEAF(677,516), + /* und_zsye */ + LEAF(689,517), LEAF(689,518), LEAF(689,519), LEAF(689,520), + LEAF(689,521), LEAF(689,522), LEAF(689,523), LEAF(689,524), + LEAF(689,525), LEAF(689,526), LEAF(689,527), LEAF(689,528), + /* vai */ + LEAF(701, 12), LEAF(701,529), + /* ve */ + LEAF(703, 35), LEAF(703,530), + /* vi */ + LEAF(705,531), LEAF(705,532), LEAF(705,533), LEAF(705,534), + /* vo */ + LEAF(709,535), + /* vot */ + LEAF(710,536), LEAF(710,178), + /* wa */ + LEAF(712,537), + /* wen */ + LEAF(713,210), LEAF(713,538), + /* wo */ + LEAF(715,539), LEAF(715,381), + /* xag */ + LEAF(717,540), + /* xco */ + LEAF(718,541), + /* xcr */ + LEAF(719,542), + /* xlc */ + LEAF(720,438), + /* xld */ + LEAF(721,543), + /* xmr */ + LEAF(722,544), + /* xna */ + LEAF(723,545), + /* xpr */ + LEAF(724,546), + /* xsa */ + LEAF(725,547), + /* xzh */ + LEAF(726,548), + /* yap */ + LEAF(727,549), + /* yo */ + LEAF(728,550), LEAF(728,551), LEAF(728,552), LEAF(728,553), + /* yue */ + LEAF(732,554), LEAF(732,555), LEAF(732,556), LEAF(732,557), + LEAF(732,558), LEAF(732,559), LEAF(732,560), LEAF(732,561), + LEAF(732,562), LEAF(732,563), LEAF(732,564), LEAF(732,565), + LEAF(732,566), LEAF(732,567), LEAF(732,568), LEAF(732,569), + LEAF(732,570), LEAF(732,571), LEAF(732,572), LEAF(732,573), + LEAF(732,574), LEAF(732,575), LEAF(732,576), LEAF(732,577), + LEAF(732,578), LEAF(732,579), LEAF(732,580), LEAF(732,581), + LEAF(732,582), LEAF(732,583), LEAF(732,584), LEAF(732,585), + LEAF(732,586), LEAF(732,587), LEAF(732,588), LEAF(732,589), + LEAF(732,590), LEAF(732,591), LEAF(732,592), LEAF(732,593), + LEAF(732,594), LEAF(732,595), LEAF(732,596), LEAF(732,597), + LEAF(732,598), LEAF(732,599), LEAF(732,600), LEAF(732,601), + LEAF(732,602), LEAF(732,603), LEAF(732,604), LEAF(732,605), + LEAF(732,606), LEAF(732,607), LEAF(732,608), LEAF(732,609), + LEAF(732,610), LEAF(732,611), LEAF(732,612), LEAF(732,613), + LEAF(732,614), LEAF(732,615), LEAF(732,616), LEAF(732,617), + LEAF(732,618), LEAF(732,619), LEAF(732,620), LEAF(732,621), + LEAF(732,622), LEAF(732,623), LEAF(732,624), LEAF(732,625), + LEAF(732,626), LEAF(732,627), LEAF(732,628), LEAF(732,629), + LEAF(732,630), LEAF(732,631), LEAF(732,632), LEAF(732,633), + LEAF(732,634), LEAF(732,635), LEAF(732,636), LEAF(732,637), + LEAF(732,638), LEAF(732,639), LEAF(732,640), LEAF(732,641), + LEAF(732,642), LEAF(732,643), LEAF(732,644), LEAF(732,645), + LEAF(732,646), LEAF(732,647), LEAF(732,648), LEAF(732,649), + LEAF(732,650), LEAF(732,651), LEAF(732,652), LEAF(732,653), + LEAF(732,654), LEAF(732,655), LEAF(732,656), LEAF(732,657), + LEAF(732,658), LEAF(732,659), LEAF(732,660), LEAF(732,661), + LEAF(732,662), LEAF(732,663), LEAF(732,664), LEAF(732,665), + LEAF(732,666), LEAF(732,667), LEAF(732,668), LEAF(732,669), + LEAF(732,670), LEAF(732,671), LEAF(732,672), LEAF(732,673), + LEAF(732,674), LEAF(732,675), LEAF(732,676), LEAF(732,677), + LEAF(732,678), LEAF(732,679), LEAF(732,680), LEAF(732,681), + LEAF(732,682), LEAF(732,683), LEAF(732,506), LEAF(732,684), + LEAF(732,685), LEAF(732,453), LEAF(732,686), LEAF(732,687), + LEAF(732,688), LEAF(732,689), LEAF(732,690), LEAF(732,691), + LEAF(732,692), LEAF(732, 4), LEAF(732,693), LEAF(732,694), + LEAF(732,695), LEAF(732,696), LEAF(732,697), LEAF(732,698), + LEAF(732,683), LEAF(732,699), LEAF(732,700), LEAF(732,701), + LEAF(732,702), LEAF(732,703), LEAF(732,704), LEAF(732,705), + LEAF(732,706), LEAF(732,707), LEAF(732,708), LEAF(732,709), + LEAF(732,710), LEAF(732,711), LEAF(732,712), LEAF(732,713), + LEAF(732,714), LEAF(732,715), LEAF(732,716), LEAF(732,717), + LEAF(732,718), LEAF(732,719), LEAF(732,720), + /* zh_cn */ + LEAF(903,721), LEAF(903,722), LEAF(903,723), LEAF(903,724), + LEAF(903,725), LEAF(903,726), LEAF(903,727), LEAF(903,728), + LEAF(903,729), LEAF(903,730), LEAF(903,731), LEAF(903,732), + LEAF(903,733), LEAF(903,734), LEAF(903,735), LEAF(903,736), + LEAF(903,737), LEAF(903,738), LEAF(903,739), LEAF(903,740), + LEAF(903,741), LEAF(903,742), LEAF(903,743), LEAF(903,744), + LEAF(903,745), LEAF(903,746), LEAF(903,747), LEAF(903,748), + LEAF(903,749), LEAF(903,750), LEAF(903,751), LEAF(903,752), + LEAF(903,753), LEAF(903,754), LEAF(903,755), LEAF(903,756), + LEAF(903,757), LEAF(903,758), LEAF(903,759), LEAF(903,760), + LEAF(903,761), LEAF(903,762), LEAF(903,763), LEAF(903,764), + LEAF(903,765), LEAF(903,766), LEAF(903,767), LEAF(903,768), + LEAF(903,769), LEAF(903,770), LEAF(903,771), LEAF(903,772), + LEAF(903,773), LEAF(903,774), LEAF(903,775), LEAF(903,776), + LEAF(903,777), LEAF(903,778), LEAF(903,779), LEAF(903,780), + LEAF(903,781), LEAF(903,782), LEAF(903,783), LEAF(903,784), + LEAF(903,785), LEAF(903,786), LEAF(903,787), LEAF(903,788), + LEAF(903,789), LEAF(903,790), LEAF(903,791), LEAF(903,792), + LEAF(903,793), LEAF(903,794), LEAF(903,795), LEAF(903,796), + LEAF(903,797), LEAF(903,798), LEAF(903,799), LEAF(903,800), + LEAF(903,801), LEAF(903,802), + /* zkt */ + LEAF(985, 12), LEAF(985,803), +}, +{ + /* aa */ + 0x0000, + /* ab */ + 0x0004, + /* ae */ + 0x010b, + /* af */ + 0x0000, 0x0001, + /* agr */ + 0x0000, + /* aho */ + 0x0117, + /* ak */ + 0x0000, 0x0001, 0x0002, 0x0003, 0x001e, + /* akk */ + 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, + /* am */ + 0x0012, 0x0013, + /* an */ + 0x0000, + /* anp */ + 0x0009, + /* ar */ + 0x0006, + /* arc */ + 0x0108, + /* as */ + 0x0009, + /* ast */ + 0x0000, 0x001e, + /* av */ + 0x0004, + /* ay */ + 0x0000, + /* ayc */ + 0x0000, + /* az_az */ + 0x0000, 0x0001, 0x0002, + /* az_ir */ + 0x0006, + /* ba */ + 0x0004, + /* ban */ + 0x001b, + /* bax */ + 0x00a6, + /* be */ + 0x0004, + /* bem */ + 0x0000, + /* ber_dz */ + 0x0000, 0x0001, 0x0002, 0x001e, + /* ber_ma */ + 0x002d, + /* bg */ + 0x0004, + /* bi */ + 0x0000, + /* bin */ + 0x0000, 0x0003, 0x001e, + /* bku */ + 0x0017, + /* blt */ + 0x00aa, + /* bm */ + 0x0000, 0x0001, 0x0002, + /* bn */ + 0x0009, + /* bo */ + 0x000f, + /* br */ + 0x0000, + /* brx */ + 0x0009, + /* bs */ + 0x0000, 0x0001, + /* bua */ + 0x0004, + /* byn */ + 0x0012, 0x0013, + /* ca */ + 0x0000, 0x0001, + /* ccp */ + 0x0111, + /* ch */ + 0x0000, + /* chm */ + 0x0004, + /* chr */ + 0x0013, + /* cjm */ + 0x00aa, + /* ckb */ + 0x0006, + /* cmn */ + 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, + 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, + 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, + 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, + 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, + 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, + 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, + 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, + 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, + 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, + 0x009e, 0x009f, 0x00fa, + /* co */ + 0x0000, 0x0001, + /* cop */ + 0x0003, 0x002c, + /* crh */ + 0x0000, 0x0001, + /* cs */ + 0x0000, 0x0001, + /* csb */ + 0x0000, 0x0001, + /* cu */ + 0x0004, + /* cv */ + 0x0001, 0x0004, + /* cy */ + 0x0000, 0x0001, 0x001e, + /* da */ + 0x0000, + /* de */ + 0x0000, + /* dmf */ + 0x016e, + /* doi */ + 0x0009, + /* dv */ + 0x0007, + /* ecy */ + 0x0108, + /* ee */ + 0x0000, 0x0001, 0x0002, 0x0003, + /* egy */ + 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, + /* eky */ + 0x00a9, + /* el */ + 0x0003, + /* en */ + 0x0000, + /* eo */ + 0x0000, 0x0001, + /* et */ + 0x0000, 0x0001, + /* ett */ + 0x0103, + /* eu */ + 0x0000, + /* ff */ + 0x0000, 0x0001, 0x0002, + /* fi */ + 0x0000, 0x0001, + /* fil */ + 0x0000, + /* fo */ + 0x0000, + /* fur */ + 0x0000, + /* fy */ + 0x0000, + /* ga */ + 0x0000, 0x0001, 0x001e, + /* gd */ + 0x0000, + /* gez */ + 0x0012, 0x0013, + /* gmy */ + 0x0100, + /* gn */ + 0x0000, 0x0001, 0x001e, + /* got */ + 0x0103, + /* gu */ + 0x000a, + /* gv */ + 0x0000, + /* ha */ + 0x0000, 0x0001, 0x0002, + /* haw */ + 0x0000, 0x0001, 0x0002, + /* he */ + 0x0005, + /* hlu */ + 0x0144, 0x0145, 0x0146, + /* hmd */ + 0x016f, + /* hnn */ + 0x0017, + /* hoc */ + 0x0118, + /* hsb */ + 0x0000, 0x0001, + /* ht */ + 0x0000, + /* hu */ + 0x0000, 0x0001, + /* hy */ + 0x0005, + /* hz */ + 0x0000, 0x0003, 0x001e, + /* id */ + 0x0000, + /* ie */ + 0x0000, + /* ig */ + 0x0000, 0x001e, + /* ii */ + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, + /* ik */ + 0x0004, + /* is */ + 0x0000, + /* it */ + 0x0000, + /* iu */ + 0x0014, 0x0015, 0x0016, + /* ja */ + 0x0030, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, + 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, + 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, + 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, + 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, + 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, + 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, + 0x009d, 0x009e, 0x009f, + /* jv */ + 0x00a9, + /* ka */ + 0x0010, + /* kaa */ + 0x0004, + /* kaw */ + 0x011f, + /* khb */ + 0x0019, + /* ki */ + 0x0000, 0x0001, + /* kk */ + 0x0004, + /* kl */ + 0x0000, 0x0001, + /* km */ + 0x0017, + /* kn */ + 0x000c, + /* ko */ + 0x0031, 0x00ac, 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, + 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, + 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, + 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, + 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1, 0x00d2, + 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + /* kr */ + 0x0000, 0x0001, 0x0002, + /* ks */ + 0x0006, + /* ku_am */ + 0x0004, 0x0005, + /* ku_tr */ + 0x0000, 0x0001, + /* kum */ + 0x0004, + /* kv */ + 0x0004, + /* kw */ + 0x0000, 0x0001, 0x0002, + /* ky */ + 0x0004, + /* la */ + 0x0000, 0x0001, + /* lah */ + 0x0006, + /* lb */ + 0x0000, + /* lep */ + 0x001c, + /* lg */ + 0x0000, 0x0001, + /* li */ + 0x0000, + /* lif */ + 0x0019, + /* lij */ + 0x0000, + /* lis */ + 0x00a4, + /* ln */ + 0x0000, 0x0001, 0x0002, 0x0003, + /* lo */ + 0x000e, + /* lt */ + 0x0000, 0x0001, + /* lv */ + 0x0000, 0x0001, + /* mg */ + 0x0000, + /* mh */ + 0x0000, 0x0001, + /* mi */ + 0x0000, 0x0001, 0x001e, + /* mid */ + 0x0008, + /* miq */ + 0x0000, 0x0001, 0x001e, + /* mk */ + 0x0004, + /* ml */ + 0x000d, + /* mn_cn */ + 0x0018, + /* mn_mn */ + 0x0004, + /* mni */ + 0x00aa, 0x00ab, + /* mnw */ + 0x0010, + /* mo */ + 0x0000, 0x0001, 0x0002, 0x0004, + /* mro */ + 0x016a, + /* mt */ + 0x0000, 0x0001, + /* na */ + 0x0000, 0x0001, + /* nan */ + 0x0000, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, + 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, + 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, + 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, + 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, + 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, + 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, + 0x009d, 0x009e, 0x009f, 0x00fa, + /* nb */ + 0x0000, + /* ne */ + 0x0009, + /* nhn */ + 0x0000, 0x0001, + /* niu */ + 0x0000, 0x0001, + /* nl */ + 0x0000, + /* nn */ + 0x0000, + /* nnp */ + 0x01e2, + /* nqo */ + 0x0007, + /* nso */ + 0x0000, 0x0001, + /* nv */ + 0x0000, 0x0001, 0x0002, 0x0003, + /* ny */ + 0x0000, 0x0001, + /* oc */ + 0x0000, + /* or */ + 0x000b, + /* osa */ + 0x0104, + /* ota */ + 0x0006, + /* otk */ + 0x010c, + /* oui */ + 0x010f, + /* pa */ + 0x000a, + /* pal */ + 0x010b, + /* pap_an */ + 0x0000, + /* pap_aw */ + 0x0000, + /* peo */ + 0x0103, + /* pgd */ + 0x010a, + /* pgl */ + 0x0016, + /* phn */ + 0x0109, + /* pl */ + 0x0000, 0x0001, + /* ps_af */ + 0x0006, + /* ps_pk */ + 0x0006, + /* pt */ + 0x0000, + /* qu */ + 0x0000, 0x0002, + /* rhg */ + 0x010d, + /* rif */ + 0x0000, 0x0001, 0x0002, 0x001e, + /* rm */ + 0x0000, + /* ro */ + 0x0000, 0x0001, 0x0002, + /* sah */ + 0x0004, + /* sam */ + 0x0008, + /* sat */ + 0x001c, + /* sc */ + 0x0000, + /* sco */ + 0x0000, 0x0001, 0x0002, + /* sd */ + 0x0006, + /* se */ + 0x0000, 0x0001, + /* sg */ + 0x0000, + /* sgs */ + 0x0000, 0x0001, 0x0003, + /* sh */ + 0x0000, 0x0001, 0x0004, + /* shs */ + 0x0000, 0x0003, + /* si */ + 0x000d, + /* sid */ + 0x0012, 0x0013, + /* sk */ + 0x0000, 0x0001, + /* sm */ + 0x0000, 0x0002, + /* sma */ + 0x0000, + /* smj */ + 0x0000, + /* smn */ + 0x0000, 0x0001, + /* sms */ + 0x0000, 0x0001, 0x0002, + /* so */ + 0x0104, + /* sog */ + 0x010f, + /* sq */ + 0x0000, + /* sr */ + 0x0004, + /* su */ + 0x001b, 0x001c, + /* suz */ + 0x011b, + /* sv */ + 0x0000, + /* syr */ + 0x0007, + /* szl */ + 0x0000, 0x0001, + /* ta */ + 0x000b, + /* tbw */ + 0x0017, + /* tdd */ + 0x0019, + /* te */ + 0x000c, + /* tg */ + 0x0004, + /* th */ + 0x000e, + /* tig */ + 0x0012, 0x0013, + /* tk */ + 0x0000, 0x0001, + /* tl */ + 0x0017, + /* tr */ + 0x0000, 0x0001, + /* tt */ + 0x0004, + /* txg */ + 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176, 0x0177, + 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, 0x017e, 0x017f, + 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, 0x0186, 0x0187, + 0x0188, 0x0189, 0x018a, 0x018d, + /* ty */ + 0x0000, 0x0001, 0x0002, + /* ug */ + 0x0006, + /* uga */ + 0x0103, + /* uk */ + 0x0004, + /* und_zmth */ + 0x0000, 0x0001, 0x0003, 0x0020, 0x0021, 0x0022, 0x0023, 0x0025, + 0x0027, 0x01d4, 0x01d5, 0x01d6, + /* und_zsye */ + 0x0023, 0x0025, 0x0026, 0x0027, 0x002b, 0x01f0, 0x01f1, 0x01f2, + 0x01f3, 0x01f4, 0x01f5, 0x01f6, + /* vai */ + 0x00a5, 0x00a6, + /* ve */ + 0x0000, 0x001e, + /* vi */ + 0x0000, 0x0001, 0x0003, 0x001e, + /* vo */ + 0x0000, + /* vot */ + 0x0000, 0x0001, + /* wa */ + 0x0000, + /* wen */ + 0x0000, 0x0001, + /* wo */ + 0x0000, 0x0001, + /* xag */ + 0x0105, + /* xco */ + 0x010f, + /* xcr */ + 0x0102, + /* xlc */ + 0x0102, + /* xld */ + 0x0109, + /* xmr */ + 0x0109, + /* xna */ + 0x010a, + /* xpr */ + 0x010b, + /* xsa */ + 0x010a, + /* xzh */ + 0x011c, + /* yap */ + 0x0000, + /* yo */ + 0x0000, 0x0001, 0x0003, 0x001e, + /* yue */ + 0x0030, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, + 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, + 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, + 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, + 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 0x0200, 0x0201, 0x0203, + 0x0207, 0x020c, 0x020d, 0x020e, 0x020f, 0x0210, 0x0211, 0x0219, + 0x021a, 0x021c, 0x021d, 0x0220, 0x0221, 0x022a, 0x022b, 0x022c, + 0x022d, 0x022f, 0x0232, 0x0235, 0x0236, 0x023c, 0x023e, 0x023f, + 0x0244, 0x024d, 0x024e, 0x0251, 0x0255, 0x025e, 0x0262, 0x0266, + 0x0267, 0x0268, 0x0269, 0x0272, 0x0275, 0x0276, 0x0277, 0x0278, + 0x0279, 0x027a, 0x027d, 0x0280, 0x0281, 0x0282, 0x0283, 0x0289, + 0x028a, 0x028b, 0x028c, 0x028d, 0x028e, 0x0294, 0x0297, 0x0298, + 0x029a, 0x029d, 0x02a6, + /* zh_cn */ + 0x0002, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, + 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, + 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, + 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, + 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, + 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, + 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, + 0x009e, 0x009f, + /* zkt */ + 0x018b, 0x018c, +}, +{ + 0, /* aa */ + 1, /* ab */ + 284, /* ae */ + 2, /* af */ + 252, /* agr */ + 285, /* aho */ + 190, /* ak */ + 333, /* akk */ + 3, /* am */ + 191, /* an */ + 246, /* anp */ + 4, /* ar */ + 286, /* arc */ + 5, /* as */ + 6, /* ast */ + 7, /* av */ + 8, /* ay */ + 253, /* ayc */ + 9, /* az_az */ + 10, /* az_ir */ + 11, /* ba */ + 282, /* ban */ + 283, /* bax */ + 13, /* be */ + 254, /* bem */ + 192, /* ber_dz */ + 193, /* ber_ma */ + 14, /* bg */ + 15, /* bh */ + 247, /* bhb */ + 16, /* bho */ + 17, /* bi */ + 18, /* bin */ + 287, /* bku */ + 288, /* blt */ + 12, /* bm */ + 19, /* bn */ + 20, /* bo */ + 21, /* br */ + 240, /* brx */ + 22, /* bs */ + 23, /* bua */ + 194, /* byn */ + 24, /* ca */ + 289, /* ccp */ + 25, /* ce */ + 26, /* ch */ + 27, /* chm */ + 28, /* chr */ + 290, /* cjm */ + 255, /* ckb */ + 256, /* cmn */ + 29, /* co */ + 280, /* cop */ + 195, /* crh */ + 30, /* cs */ + 196, /* csb */ + 31, /* cu */ + 32, /* cv */ + 33, /* cy */ + 34, /* da */ + 35, /* de */ + 291, /* dmf */ + 242, /* doi */ + 257, /* dsb */ + 197, /* dv */ + 36, /* dz */ + 338, /* ecy */ + 198, /* ee */ + 292, /* egy */ + 293, /* eky */ + 37, /* el */ + 38, /* en */ + 39, /* eo */ + 40, /* es */ + 41, /* et */ + 328, /* ett */ + 42, /* eu */ + 43, /* fa */ + 199, /* fat */ + 48, /* ff */ + 44, /* fi */ + 200, /* fil */ + 45, /* fj */ + 46, /* fo */ + 47, /* fr */ + 49, /* fur */ + 50, /* fy */ + 51, /* ga */ + 52, /* gd */ + 53, /* gez */ + 54, /* gl */ + 294, /* gmy */ + 55, /* gn */ + 279, /* got */ + 56, /* gu */ + 57, /* gv */ + 58, /* ha */ + 258, /* hak */ + 59, /* haw */ + 60, /* he */ + 61, /* hi */ + 248, /* hif */ + 335, /* hit */ + 337, /* hlu */ + 295, /* hmd */ + 201, /* hne */ + 296, /* hnn */ + 62, /* ho */ + 297, /* hoc */ + 63, /* hr */ + 202, /* hsb */ + 203, /* ht */ + 64, /* hu */ + 65, /* hy */ + 204, /* hz */ + 66, /* ia */ + 68, /* id */ + 69, /* ie */ + 67, /* ig */ + 205, /* ii */ + 70, /* ik */ + 71, /* io */ + 72, /* is */ + 73, /* it */ + 74, /* iu */ + 75, /* ja */ + 206, /* jv */ + 76, /* ka */ + 77, /* kaa */ + 207, /* kab */ + 329, /* kaw */ + 298, /* khb */ + 78, /* ki */ + 208, /* kj */ + 79, /* kk */ + 80, /* kl */ + 81, /* km */ + 82, /* kn */ + 83, /* ko */ + 84, /* kok */ + 209, /* kr */ + 85, /* ks */ + 86, /* ku_am */ + 210, /* ku_iq */ + 87, /* ku_ir */ + 211, /* ku_tr */ + 88, /* kum */ + 89, /* kv */ + 90, /* kw */ + 212, /* kwm */ + 91, /* ky */ + 92, /* la */ + 238, /* lah */ + 93, /* lb */ + 299, /* lep */ + 94, /* lez */ + 213, /* lg */ + 214, /* li */ + 300, /* lif */ + 259, /* lij */ + 301, /* lis */ + 95, /* ln */ + 96, /* lo */ + 97, /* lt */ + 98, /* lv */ + 260, /* lzh */ + 249, /* mag */ + 215, /* mai */ + 261, /* mfe */ + 99, /* mg */ + 100, /* mh */ + 262, /* mhr */ + 101, /* mi */ + 302, /* mid */ + 263, /* miq */ + 264, /* mjw */ + 102, /* mk */ + 103, /* ml */ + 104, /* mn_cn */ + 216, /* mn_mn */ + 243, /* mni */ + 265, /* mnw */ + 105, /* mo */ + 106, /* mr */ + 303, /* mro */ + 217, /* ms */ + 107, /* mt */ + 108, /* my */ + 218, /* na */ + 266, /* nan */ + 109, /* nb */ + 110, /* nds */ + 111, /* ne */ + 219, /* ng */ + 267, /* nhn */ + 268, /* niu */ + 112, /* nl */ + 113, /* nn */ + 304, /* nnp */ + 114, /* no */ + 239, /* nqo */ + 115, /* nr */ + 116, /* nso */ + 220, /* nv */ + 117, /* ny */ + 118, /* oc */ + 119, /* om */ + 120, /* or */ + 121, /* os */ + 305, /* osa */ + 221, /* ota */ + 306, /* otk */ + 307, /* oui */ + 122, /* pa */ + 222, /* pa_pk */ + 308, /* pal */ + 223, /* pap_an */ + 224, /* pap_aw */ + 309, /* peo */ + 330, /* pgd */ + 331, /* pgl */ + 310, /* phn */ + 123, /* pl */ + 124, /* ps_af */ + 125, /* ps_pk */ + 126, /* pt */ + 225, /* qu */ + 226, /* quz */ + 250, /* raj */ + 311, /* rhg */ + 269, /* rif */ + 127, /* rm */ + 227, /* rn */ + 128, /* ro */ + 129, /* ru */ + 228, /* rw */ + 130, /* sa */ + 131, /* sah */ + 312, /* sam */ + 241, /* sat */ + 229, /* sc */ + 132, /* sco */ + 230, /* sd */ + 133, /* se */ + 134, /* sel */ + 231, /* sg */ + 270, /* sgs */ + 135, /* sh */ + 271, /* shn */ + 136, /* shs */ + 137, /* si */ + 232, /* sid */ + 138, /* sk */ + 139, /* sl */ + 140, /* sm */ + 141, /* sma */ + 142, /* smj */ + 143, /* smn */ + 144, /* sms */ + 233, /* sn */ + 145, /* so */ + 313, /* sog */ + 146, /* sq */ + 147, /* sr */ + 148, /* ss */ + 149, /* st */ + 234, /* su */ + 334, /* sux */ + 281, /* suz */ + 150, /* sv */ + 151, /* sw */ + 152, /* syr */ + 272, /* szl */ + 153, /* ta */ + 314, /* tbw */ + 273, /* tcy */ + 315, /* tdd */ + 154, /* te */ + 155, /* tg */ + 156, /* th */ + 251, /* the */ + 157, /* ti_er */ + 158, /* ti_et */ + 159, /* tig */ + 160, /* tk */ + 161, /* tl */ + 162, /* tn */ + 163, /* to */ + 274, /* tpi */ + 164, /* tr */ + 165, /* ts */ + 166, /* tt */ + 167, /* tw */ + 316, /* txg */ + 235, /* ty */ + 168, /* tyv */ + 169, /* ug */ + 317, /* uga */ + 170, /* uk */ + 245, /* und_zmth */ + 244, /* und_zsye */ + 275, /* unm */ + 171, /* ur */ + 172, /* uz */ + 318, /* vai */ + 173, /* ve */ + 174, /* vi */ + 175, /* vo */ + 176, /* vot */ + 177, /* wa */ + 276, /* wae */ + 236, /* wal */ + 178, /* wen */ + 179, /* wo */ + 319, /* xag */ + 320, /* xco */ + 321, /* xcr */ + 180, /* xh */ + 322, /* xlc */ + 323, /* xld */ + 324, /* xmr */ + 336, /* xna */ + 325, /* xpr */ + 326, /* xsa */ + 332, /* xzh */ + 181, /* yap */ + 182, /* yi */ + 183, /* yo */ + 277, /* yue */ + 278, /* yuw */ + 237, /* za */ + 184, /* zh_cn */ + 185, /* zh_hk */ + 186, /* zh_mo */ + 187, /* zh_sg */ + 188, /* zh_tw */ + 327, /* zkt */ + 189, /* zu */ +}, +{ + 0, /* aa */ + 1, /* ab */ + 3, /* af */ + 8, /* am */ + 11, /* ar */ + 13, /* as */ + 14, /* ast */ + 15, /* av */ + 16, /* ay */ + 18, /* az_az */ + 19, /* az_ir */ + 20, /* ba */ + 35, /* bm */ + 23, /* be */ + 27, /* bg */ + 28, /* bh */ + 30, /* bho */ + 31, /* bi */ + 32, /* bin */ + 36, /* bn */ + 37, /* bo */ + 38, /* br */ + 40, /* bs */ + 41, /* bua */ + 43, /* ca */ + 45, /* ce */ + 46, /* ch */ + 47, /* chm */ + 48, /* chr */ + 52, /* co */ + 55, /* cs */ + 57, /* cu */ + 58, /* cv */ + 59, /* cy */ + 60, /* da */ + 61, /* de */ + 66, /* dz */ + 71, /* el */ + 72, /* en */ + 73, /* eo */ + 74, /* es */ + 75, /* et */ + 77, /* eu */ + 78, /* fa */ + 81, /* fi */ + 83, /* fj */ + 84, /* fo */ + 85, /* fr */ + 80, /* ff */ + 86, /* fur */ + 87, /* fy */ + 88, /* ga */ + 89, /* gd */ + 90, /* gez */ + 91, /* gl */ + 93, /* gn */ + 95, /* gu */ + 96, /* gv */ + 97, /* ha */ + 99, /* haw */ + 100, /* he */ + 101, /* hi */ + 108, /* ho */ + 110, /* hr */ + 113, /* hu */ + 114, /* hy */ + 116, /* ia */ + 119, /* ig */ + 117, /* id */ + 118, /* ie */ + 121, /* ik */ + 122, /* io */ + 123, /* is */ + 124, /* it */ + 125, /* iu */ + 126, /* ja */ + 128, /* ka */ + 129, /* kaa */ + 133, /* ki */ + 135, /* kk */ + 136, /* kl */ + 137, /* km */ + 138, /* kn */ + 139, /* ko */ + 140, /* kok */ + 142, /* ks */ + 143, /* ku_am */ + 145, /* ku_ir */ + 147, /* kum */ + 148, /* kv */ + 149, /* kw */ + 151, /* ky */ + 152, /* la */ + 154, /* lb */ + 156, /* lez */ + 162, /* ln */ + 163, /* lo */ + 164, /* lt */ + 165, /* lv */ + 170, /* mg */ + 171, /* mh */ + 173, /* mi */ + 177, /* mk */ + 178, /* ml */ + 179, /* mn_cn */ + 183, /* mo */ + 184, /* mr */ + 187, /* mt */ + 188, /* my */ + 191, /* nb */ + 192, /* nds */ + 193, /* ne */ + 197, /* nl */ + 198, /* nn */ + 200, /* no */ + 202, /* nr */ + 203, /* nso */ + 205, /* ny */ + 206, /* oc */ + 207, /* om */ + 208, /* or */ + 209, /* os */ + 214, /* pa */ + 223, /* pl */ + 224, /* ps_af */ + 225, /* ps_pk */ + 226, /* pt */ + 232, /* rm */ + 234, /* ro */ + 235, /* ru */ + 237, /* sa */ + 238, /* sah */ + 242, /* sco */ + 244, /* se */ + 245, /* sel */ + 248, /* sh */ + 250, /* shs */ + 251, /* si */ + 253, /* sk */ + 254, /* sl */ + 255, /* sm */ + 256, /* sma */ + 257, /* smj */ + 258, /* smn */ + 259, /* sms */ + 261, /* so */ + 263, /* sq */ + 264, /* sr */ + 265, /* ss */ + 266, /* st */ + 270, /* sv */ + 271, /* sw */ + 272, /* syr */ + 274, /* ta */ + 278, /* te */ + 279, /* tg */ + 280, /* th */ + 282, /* ti_er */ + 283, /* ti_et */ + 284, /* tig */ + 285, /* tk */ + 286, /* tl */ + 287, /* tn */ + 288, /* to */ + 290, /* tr */ + 291, /* ts */ + 292, /* tt */ + 293, /* tw */ + 296, /* tyv */ + 297, /* ug */ + 299, /* uk */ + 303, /* ur */ + 304, /* uz */ + 306, /* ve */ + 307, /* vi */ + 308, /* vo */ + 309, /* vot */ + 310, /* wa */ + 313, /* wen */ + 314, /* wo */ + 318, /* xh */ + 326, /* yap */ + 327, /* yi */ + 328, /* yo */ + 332, /* zh_cn */ + 333, /* zh_hk */ + 334, /* zh_mo */ + 335, /* zh_sg */ + 336, /* zh_tw */ + 338, /* zu */ + 6, /* ak */ + 9, /* an */ + 25, /* ber_dz */ + 26, /* ber_ma */ + 42, /* byn */ + 54, /* crh */ + 56, /* csb */ + 65, /* dv */ + 68, /* ee */ + 79, /* fat */ + 82, /* fil */ + 106, /* hne */ + 111, /* hsb */ + 112, /* ht */ + 115, /* hz */ + 120, /* ii */ + 127, /* jv */ + 130, /* kab */ + 134, /* kj */ + 141, /* kr */ + 144, /* ku_iq */ + 146, /* ku_tr */ + 150, /* kwm */ + 157, /* lg */ + 158, /* li */ + 168, /* mai */ + 180, /* mn_mn */ + 186, /* ms */ + 189, /* na */ + 194, /* ng */ + 204, /* nv */ + 211, /* ota */ + 215, /* pa_pk */ + 217, /* pap_an */ + 218, /* pap_aw */ + 227, /* qu */ + 228, /* quz */ + 233, /* rn */ + 236, /* rw */ + 241, /* sc */ + 243, /* sd */ + 246, /* sg */ + 252, /* sid */ + 260, /* sn */ + 267, /* su */ + 295, /* ty */ + 312, /* wal */ + 331, /* za */ + 153, /* lah */ + 201, /* nqo */ + 39, /* brx */ + 240, /* sat */ + 63, /* doi */ + 181, /* mni */ + 301, /* und_zsye */ + 300, /* und_zmth */ + 10, /* anp */ + 29, /* bhb */ + 102, /* hif */ + 167, /* mag */ + 229, /* raj */ + 281, /* the */ + 4, /* agr */ + 17, /* ayc */ + 24, /* bem */ + 50, /* ckb */ + 51, /* cmn */ + 64, /* dsb */ + 98, /* hak */ + 160, /* lij */ + 166, /* lzh */ + 169, /* mfe */ + 172, /* mhr */ + 175, /* miq */ + 176, /* mjw */ + 182, /* mnw */ + 190, /* nan */ + 195, /* nhn */ + 196, /* niu */ + 231, /* rif */ + 247, /* sgs */ + 249, /* shn */ + 273, /* szl */ + 276, /* tcy */ + 289, /* tpi */ + 302, /* unm */ + 311, /* wae */ + 329, /* yue */ + 330, /* yuw */ + 94, /* got */ + 53, /* cop */ + 269, /* suz */ + 21, /* ban */ + 22, /* bax */ + 2, /* ae */ + 5, /* aho */ + 12, /* arc */ + 33, /* bku */ + 34, /* blt */ + 44, /* ccp */ + 49, /* cjm */ + 62, /* dmf */ + 69, /* egy */ + 70, /* eky */ + 92, /* gmy */ + 105, /* hmd */ + 107, /* hnn */ + 109, /* hoc */ + 132, /* khb */ + 155, /* lep */ + 159, /* lif */ + 161, /* lis */ + 174, /* mid */ + 185, /* mro */ + 199, /* nnp */ + 210, /* osa */ + 212, /* otk */ + 213, /* oui */ + 216, /* pal */ + 219, /* peo */ + 222, /* phn */ + 230, /* rhg */ + 239, /* sam */ + 262, /* sog */ + 275, /* tbw */ + 277, /* tdd */ + 294, /* txg */ + 298, /* uga */ + 305, /* vai */ + 315, /* xag */ + 316, /* xco */ + 317, /* xcr */ + 319, /* xlc */ + 320, /* xld */ + 321, /* xmr */ + 323, /* xpr */ + 324, /* xsa */ + 337, /* zkt */ + 76, /* ett */ + 131, /* kaw */ + 220, /* pgd */ + 221, /* pgl */ + 325, /* xzh */ + 7, /* akk */ + 268, /* sux */ + 103, /* hit */ + 322, /* xna */ + 104, /* hlu */ + 67, /* ecy */ +} +}; + +#define NUM_LANG_CHAR_SET 339 +#define NUM_LANG_SET_MAP 11 + +static const FcChar32 fcLangCountrySets[][NUM_LANG_SET_MAP] = { + { 0x00000600, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, /* az */ + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, /* ber */ + { 0x00000000, 0x00000000, 0x00c00000, 0x00000000, 0x00000000, 0x00000000, 0x000c0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, /* ku */ + { 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0x00000000, 0x00000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, /* mn */ + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, /* pa */ + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, }, /* pap */ + { 0x00000000, 0x00000000, 0x00000000, 0x30000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, /* ps */ + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x60000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, /* ti */ + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00300000, 0x00000000, 0x00000000, 0x00000000, }, /* und */ + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1f000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, /* zh */ +}; + +#define NUM_COUNTRY_SET 10 + +static const FcLangCharSetRange fcLangCharSetRanges[] = { + + { 0, 19 }, /* a */ + { 20, 42 }, /* b */ + { 43, 59 }, /* c */ + { 60, 66 }, /* d */ + { 67, 77 }, /* e */ + { 78, 87 }, /* f */ + { 88, 96 }, /* g */ + { 97, 115 }, /* h */ + { 116, 125 }, /* i */ + { 126, 127 }, /* j */ + { 128, 151 }, /* k */ + { 152, 166 }, /* l */ + { 167, 188 }, /* m */ + { 189, 205 }, /* n */ + { 206, 213 }, /* o */ + { 214, 226 }, /* p */ + { 227, 228 }, /* q */ + { 229, 236 }, /* r */ + { 237, 273 }, /* s */ + { 274, 296 }, /* t */ + { 297, 304 }, /* u */ + { 305, 309 }, /* v */ + { 310, 314 }, /* w */ + { 315, 325 }, /* x */ + { 326, 330 }, /* y */ + { 331, 338 }, /* z */ +}; + diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/fontconfig/fontconfig.h b/vendor/libghostty-vt/pkg/fontconfig/override/fontconfig/fontconfig.h new file mode 100644 index 00000000..3c5cca57 --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/fontconfig/fontconfig.h @@ -0,0 +1,1245 @@ +/* + * fontconfig/fontconfig/fontconfig.h + * + * Copyright © 2001 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _FONTCONFIG_H_ +#define _FONTCONFIG_H_ + +#include +#include +#include +#include + +#if defined(__GNUC__) && (__GNUC__ >= 4) +# define FC_ATTRIBUTE_SENTINEL(x) __attribute__ ((__sentinel__ (0))) +# define FC_ATTRIBUTE_MAY_ALIAS __attribute__ ((may_alias)) +#else +# define FC_ATTRIBUTE_SENTINEL(x) +# define FC_ATTRIBUTE_MAY_ALIAS +#endif + +#ifndef FcPublic +# define FcPublic +#endif + +typedef unsigned char FcChar8; +typedef unsigned short FcChar16; +typedef unsigned int FcChar32; +typedef int FcBool; + +/* + * Current Fontconfig version number. This same number + * must appear in the fontconfig configure.in file. Yes, + * it'a a pain to synchronize version numbers like this. + */ + +#define FC_MAJOR 2 +#define FC_MINOR 18 +#define FC_REVISION 3 + +#define FC_VERSION ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION)) + +/* + * Current font cache file format version + * This is appended to the cache files so that multiple + * versions of the library will peacefully coexist + * + * Change this value whenever the disk format for the cache file + * changes in any non-compatible way. Try to avoid such changes as + * it means multiple copies of the font information. + */ + +#define FC_CACHE_VERSION_NUMBER 12 +#define FC_CACHE_SNAP_VERSION_NUMBER 0 +#define FC_NEXT_CACHE_VERSION_NUMBER 0 +#define FC_CACHE_MIN_COMPAT_VERSION 9 + +#define _FC_STRINGIFY_(s) #s +#define _FC_STRINGIFY(s) _FC_STRINGIFY_ (s) +#if FC_NEXT_CACHE_VERSION_NUMBER > 0 +# define FC_CACHE_VERSION _FC_STRINGIFY (FC_NEXT_CACHE_VERSION_NUMBER) "~snap" _FC_STRINGIFY (FC_CACHE_SNAP_VERSION_NUMBER) +#else +# define FC_CACHE_VERSION _FC_STRINGIFY (FC_CACHE_VERSION_NUMBER) +#endif + +#define FcFalse 0 +#define FcTrue 1 +#define FcDontCare 2 + +#define FC_FAMILY "family" /* String */ +#define FC_STYLE "style" /* String */ +#define FC_SLANT "slant" /* Int */ +#define FC_WEIGHT "weight" /* Int */ +#define FC_SIZE "size" /* Range (double) */ +#define FC_ASPECT "aspect" /* Double */ +#define FC_PIXEL_SIZE "pixelsize" /* Double */ +#define FC_SPACING "spacing" /* Int */ +#define FC_FOUNDRY "foundry" /* String */ +#define FC_ANTIALIAS "antialias" /* Bool (depends) */ +#define FC_HINTING "hinting" /* Bool (true) */ +#define FC_HINT_STYLE "hintstyle" /* Int */ +#define FC_VERTICAL_LAYOUT "verticallayout" /* Bool (false) */ +#define FC_AUTOHINT "autohint" /* Bool (false) */ +/* FC_GLOBAL_ADVANCE is deprecated. this is simply ignored on freetype 2.4.5 or later */ +#define FC_GLOBAL_ADVANCE "globaladvance" /* Bool (true) */ +#define FC_WIDTH "width" /* Int */ +#define FC_FILE "file" /* String */ +#define FC_INDEX "index" /* Int */ +#define FC_FT_FACE "ftface" /* FT_Face */ +#define FC_RASTERIZER "rasterizer" /* String (deprecated) */ +#define FC_OUTLINE "outline" /* Bool */ +#define FC_SCALABLE "scalable" /* Bool */ +#define FC_COLOR "color" /* Bool */ +#define FC_VARIABLE "variable" /* Bool */ +#define FC_SCALE "scale" /* double (deprecated) */ +#define FC_SYMBOL "symbol" /* Bool */ +#define FC_DPI "dpi" /* double */ +#define FC_RGBA "rgba" /* Int */ +#define FC_MINSPACE "minspace" /* Bool use minimum line spacing */ +#define FC_SOURCE "source" /* String (deprecated) */ +#define FC_CHARSET "charset" /* CharSet */ +#define FC_LANG "lang" /* LangSet Set of RFC 3066 langs */ +#define FC_FONTVERSION "fontversion" /* Int from 'head' table */ +#define FC_FULLNAME "fullname" /* String */ +#define FC_FAMILYLANG "familylang" /* String RFC 3066 langs */ +#define FC_STYLELANG "stylelang" /* String RFC 3066 langs */ +#define FC_FULLNAMELANG "fullnamelang" /* String RFC 3066 langs */ +#define FC_CAPABILITY "capability" /* String */ +#define FC_FONTFORMAT "fontformat" /* String */ +#define FC_EMBOLDEN "embolden" /* Bool - true if emboldening needed*/ +#define FC_EMBEDDED_BITMAP "embeddedbitmap" /* Bool - true to enable embedded bitmaps */ +#define FC_DECORATIVE "decorative" /* Bool - true if style is a decorative variant */ +#define FC_LCD_FILTER "lcdfilter" /* Int */ +#define FC_FONT_FEATURES "fontfeatures" /* String */ +#define FC_FONT_VARIATIONS "fontvariations" /* String */ +#define FC_NAMELANG "namelang" /* String RFC 3866 langs */ +#define FC_PRGNAME "prgname" /* String */ +#define FC_HASH "hash" /* String (deprecated) */ +#define FC_POSTSCRIPT_NAME "postscriptname" /* String */ +#define FC_FONT_HAS_HINT "fonthashint" /* Bool - true if font has hinting */ +#define FC_ORDER "order" /* Integer */ +#define FC_DESKTOP_NAME "desktop" /* String */ +#define FC_NAMED_INSTANCE "namedinstance" /* Bool - true if font is named instance */ +#define FC_FONT_WRAPPER "fontwrapper" /* String */ +#define FC_GENERIC_FAMILY "genericfamily" /* Integer */ + +#define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION +#define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION +#define FC_USER_CACHE_FILE ".fonts.cache-" FC_CACHE_VERSION + +/* Adjust outline rasterizer */ +#define FC_CHARWIDTH "charwidth" /* Int */ +#define FC_CHAR_WIDTH FC_CHARWIDTH +#define FC_CHAR_HEIGHT "charheight" /* Int */ +#define FC_MATRIX "matrix" /* FcMatrix */ + +#define FC_WEIGHT_THIN 0 +#define FC_WEIGHT_EXTRALIGHT 40 +#define FC_WEIGHT_ULTRALIGHT FC_WEIGHT_EXTRALIGHT +#define FC_WEIGHT_LIGHT 50 +#define FC_WEIGHT_DEMILIGHT 55 +#define FC_WEIGHT_SEMILIGHT FC_WEIGHT_DEMILIGHT +#define FC_WEIGHT_BOOK 75 +#define FC_WEIGHT_REGULAR 80 +#define FC_WEIGHT_NORMAL FC_WEIGHT_REGULAR +#define FC_WEIGHT_MEDIUM 100 +#define FC_WEIGHT_DEMIBOLD 180 +#define FC_WEIGHT_SEMIBOLD FC_WEIGHT_DEMIBOLD +#define FC_WEIGHT_BOLD 200 +#define FC_WEIGHT_EXTRABOLD 205 +#define FC_WEIGHT_ULTRABOLD FC_WEIGHT_EXTRABOLD +#define FC_WEIGHT_BLACK 210 +#define FC_WEIGHT_HEAVY FC_WEIGHT_BLACK +#define FC_WEIGHT_EXTRABLACK 215 +#define FC_WEIGHT_ULTRABLACK FC_WEIGHT_EXTRABLACK + +#define FC_SLANT_ROMAN 0 +#define FC_SLANT_ITALIC 100 +#define FC_SLANT_OBLIQUE 110 + +#define FC_WIDTH_ULTRACONDENSED 50 +#define FC_WIDTH_EXTRACONDENSED 63 +#define FC_WIDTH_CONDENSED 75 +#define FC_WIDTH_SEMICONDENSED 87 +#define FC_WIDTH_NORMAL 100 +#define FC_WIDTH_SEMIEXPANDED 113 +#define FC_WIDTH_EXPANDED 125 +#define FC_WIDTH_EXTRAEXPANDED 150 +#define FC_WIDTH_ULTRAEXPANDED 200 + +#define FC_SPACING_PROPORTIONAL 0 +#define FC_SPACING_DUAL 90 +#define FC_SPACING_MONO 100 +#define FC_SPACING_CHARCELL 110 +#define FC_PROPORTIONAL FC_SPACING_PROPORTIONAL +#define FC_DUAL FC_SPACING_DUAL +#define FC_MONO FC_SPACING_MONO +#define FC_CHARCELL FC_SPACING_CHARCELL + +/* sub-pixel order */ +#define FC_RGBA_UNKNOWN 0 +#define FC_RGBA_RGB 1 +#define FC_RGBA_BGR 2 +#define FC_RGBA_VRGB 3 +#define FC_RGBA_VBGR 4 +#define FC_RGBA_NONE 5 + +/* hinting style */ +#define FC_HINT_NONE 0 +#define FC_HINT_SLIGHT 1 +#define FC_HINT_MEDIUM 2 +#define FC_HINT_FULL 3 + +/* LCD filter */ +#define FC_LCD_NONE 0 +#define FC_LCD_DEFAULT 1 +#define FC_LCD_LIGHT 2 +#define FC_LCD_LEGACY 3 + +/* Generic family */ +#define FC_FAMILY_UNKNOWN 0 +#define FC_FAMILY_SERIF 1 +#define FC_FAMILY_SANS 2 +#define FC_FAMILY_MONO 3 +#define FC_FAMILY_CURSIVE 4 +#define FC_FAMILY_FANTASY 5 +#define FC_FAMILY_SYSTEM_UI 6 +#define FC_FAMILY_UI_SERIF 7 +#define FC_FAMILY_UI_SANS 8 +#define FC_FAMILY_UI_MONO 9 +#define FC_FAMILY_UI_ROUNDED 10 +#define FC_FAMILY_EMOJI 11 +#define FC_FAMILY_MATH 12 +#define FC_FAMILY_FANGSONG 13 + +/* Warnings */ +#define FC_WARN_INVALID_ATTR (1 << 0) + +typedef enum _FcType { + FcTypeUnknown = -1, + FcTypeVoid, + FcTypeInteger, + FcTypeDouble, + FcTypeString, + FcTypeBool, + FcTypeMatrix, + FcTypeCharSet, + FcTypeFTFace, + FcTypeLangSet, + FcTypeRange +} FcType; + +typedef int FcObject; + +typedef struct _FcMatrix { + double xx, xy, yx, yy; +} FcMatrix; + +#define FcMatrixInit(m) ((m)->xx = (m)->yy = 1, \ + (m)->xy = (m)->yx = 0) + +/* + * A data structure to represent the available glyphs in a font. + * This is represented as a sparse boolean btree. + */ + +typedef struct _FcCharSet FcCharSet; + +typedef struct _FcObjectType { + char *object; + FcType type; +} FcObjectType; + +typedef struct _FcConstant { + const FcChar8 *name; + const char *object; + int value; +} FcConstant; + +typedef enum _FcResult { + FcResultMatch, + FcResultNoMatch, + FcResultTypeMismatch, + FcResultNoId, + FcResultOutOfMemory +} FcResult; + +typedef enum _FcValueBinding { + FcValueBindingWeak, + FcValueBindingStrong, + FcValueBindingSame, + /* to make sure sizeof (FcValueBinding) == 4 even with -fshort-enums */ + FcValueBindingEnd = INT_MAX +} FcValueBinding; + +typedef struct _FcPattern FcPattern; + +typedef struct FC_ATTRIBUTE_MAY_ALIAS _FcPatternIter { + void *dummy1; + void *dummy2; +} FcPatternIter; + +typedef struct _FcLangSet FcLangSet; + +typedef struct _FcRange FcRange; + +typedef struct _FcValue { + FcType type; + union { + const FcChar8 *s; + int i; + FcBool b; + double d; + const FcMatrix *m; + const FcCharSet *c; + void *f; + const FcLangSet *l; + const FcRange *r; + } u; +} FcValue; + +typedef struct _FcFontSet { + int nfont; + int sfont; + FcPattern **fonts; +} FcFontSet; + +typedef struct _FcObjectSet { + int nobject; /* deprecated */ + int sobject; + const char **objects; /* deprecated */ + int nobjIds; + FcObject *objIds; +} FcObjectSet; + +typedef enum _FcMatchKind { + FcMatchPattern, + FcMatchFont, + FcMatchScan, + FcMatchKindEnd, + FcMatchKindBegin = FcMatchPattern +} FcMatchKind; + +typedef enum _FcLangResult { + FcLangEqual = 0, + FcLangDifferentCountry = 1, + FcLangDifferentTerritory = 1, + FcLangDifferentLang = 2 +} FcLangResult; + +typedef enum _FcSetName { + FcSetSystem = 0, + FcSetApplication = 1 +} FcSetName; + +typedef struct _FcConfigFileInfoIter { + void *dummy1; + void *dummy2; + void *dummy3; +} FcConfigFileInfoIter; + +typedef struct _FcAtomic FcAtomic; + +#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */ +# define _FCFUNCPROTOBEGIN extern "C" { /* do not leave open across includes */ +# define _FCFUNCPROTOEND } +#else +# define _FCFUNCPROTOBEGIN +# define _FCFUNCPROTOEND +#endif + +typedef enum { FcEndianBig, + FcEndianLittle } FcEndian; + +typedef struct _FcConfig FcConfig; + +typedef struct _FcGlobalCache FcFileCache; + +typedef struct _FcBlanks FcBlanks; + +typedef struct _FcStrList FcStrList; + +typedef struct _FcStrSet FcStrSet; + +typedef struct _FcCache FcCache; + +typedef void (*FcDestroyFunc) (void *data); +typedef FcBool (*FcFilterFontSetFunc) (const FcPattern *font, void *user_data); + +_FCFUNCPROTOBEGIN + +/* fcblanks.c */ +FcPublic FcBlanks * +FcBlanksCreate (void); + +FcPublic void +FcBlanksDestroy (FcBlanks *b); + +FcPublic FcBool +FcBlanksAdd (FcBlanks *b, FcChar32 ucs4); + +FcPublic FcBool +FcBlanksIsMember (FcBlanks *b, FcChar32 ucs4); + +/* fccache.c */ + +FcPublic const FcChar8 * +FcCacheDir (const FcCache *c); + +FcPublic FcFontSet * +FcCacheCopySet (const FcCache *c); + +FcPublic const FcChar8 * +FcCacheSubdir (const FcCache *c, int i); + +FcPublic int +FcCacheNumSubdir (const FcCache *c); + +FcPublic int +FcCacheNumFont (const FcCache *c); + +FcPublic FcBool +FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config); + +FcPublic FcBool +FcDirCacheValid (const FcChar8 *cache_file); + +FcPublic FcBool +FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose); + +FcPublic void +FcCacheCreateTagFile (FcConfig *config); + +FcPublic FcBool +FcDirCacheCreateUUID (FcChar8 *dir, + FcBool force, + FcConfig *config); + +FcPublic FcBool +FcDirCacheDeleteUUID (const FcChar8 *dir, + FcConfig *config); + +/* fccfg.c */ +FcPublic FcChar8 * +FcConfigHome (void); + +FcPublic FcBool +FcConfigEnableHome (FcBool enable); + +FcPublic FcChar8 * +FcConfigGetFilename (FcConfig *config, + const FcChar8 *url); + +FcPublic FcChar8 * +FcConfigFilename (const FcChar8 *url); + +FcPublic FcConfig * +FcConfigCreate (void); + +FcPublic FcConfig * +FcConfigReference (FcConfig *config); + +FcPublic void +FcConfigDestroy (FcConfig *config); + +FcPublic FcBool +FcConfigSetCurrent (FcConfig *config); + +FcPublic FcConfig * +FcConfigGetCurrent (void); + +FcPublic FcBool +FcConfigUptoDate (FcConfig *config); + +FcPublic FcBool +FcConfigBuildFonts (FcConfig *config); + +FcPublic FcStrList * +FcConfigGetFontDirs (FcConfig *config); + +FcPublic FcStrList * +FcConfigGetConfigDirs (FcConfig *config); + +FcPublic FcStrList * +FcConfigGetConfigFiles (FcConfig *config); + +FcPublic FcChar8 * +FcConfigGetCache (FcConfig *config); + +FcPublic FcBlanks * +FcConfigGetBlanks (FcConfig *config); + +FcPublic FcStrList * +FcConfigGetCacheDirs (FcConfig *config); + +FcPublic int +FcConfigGetRescanInterval (FcConfig *config); + +FcPublic FcBool +FcConfigSetRescanInterval (FcConfig *config, int rescanInterval); + +FcPublic FcFontSet * +FcConfigGetFonts (FcConfig *config, + FcSetName set); + +FcPublic FcBool +FcConfigAcceptFont (FcConfig *config, + const FcPattern *font); + +FcPublic FcBool +FcConfigAcceptFilename (FcConfig *config, + const FcChar8 *filename); + +FcPublic FcBool +FcConfigAcceptFilter (FcConfig *config, + const FcPattern *font); + +FcPublic FcBool +FcConfigAppFontAddFile (FcConfig *config, + const FcChar8 *file); + +FcPublic FcBool +FcConfigAppFontAddDir (FcConfig *config, + const FcChar8 *dir); + +FcPublic void +FcConfigAppFontClear (FcConfig *config); + +FcPublic void +FcConfigPreferAppFont (FcConfig *config, FcBool flag); + +FcPublic void +FcConfigSetWarningFlags (FcConfig *config, int warn, FcBool flag); + +FcPublic int +FcConfigGetWarningFlags (FcConfig *config); + +FcPublic FcBool +FcConfigSubstituteWithPat (FcConfig *config, + FcPattern *p, + FcPattern *p_pat, + FcMatchKind kind); + +FcPublic FcBool +FcConfigSubstitute (FcConfig *config, + FcPattern *p, + FcMatchKind kind); + +FcPublic const FcChar8 * +FcConfigGetSysRoot (const FcConfig *config); + +FcPublic void +FcConfigSetSysRoot (FcConfig *config, + const FcChar8 *sysroot); + +FcPublic FcConfig * +FcConfigSetFontSetFilter (FcConfig *config, + FcFilterFontSetFunc filter_func, + FcDestroyFunc destroy_data_func, + void *user_data); + +FcPublic void +FcConfigFileInfoIterInit (FcConfig *config, + FcConfigFileInfoIter *iter); + +FcPublic FcBool +FcConfigFileInfoIterNext (FcConfig *config, + FcConfigFileInfoIter *iter); + +FcPublic FcBool +FcConfigFileInfoIterGet (FcConfig *config, + FcConfigFileInfoIter *iter, + FcChar8 **name, + FcChar8 **description, + FcBool *enabled); + +/* fccharset.c */ +FcPublic FcCharSet * +FcCharSetCreate (void); + +/* deprecated alias for FcCharSetCreate */ +FcPublic FcCharSet * +FcCharSetNew (void); + +FcPublic void +FcCharSetDestroy (FcCharSet *fcs); + +FcPublic FcBool +FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4); + +FcPublic FcBool +FcCharSetDelChar (FcCharSet *fcs, FcChar32 ucs4); + +FcPublic FcCharSet * +FcCharSetCopy (FcCharSet *src); + +FcPublic FcBool +FcCharSetEqual (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcCharSet * +FcCharSetIntersect (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcCharSet * +FcCharSetUnion (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcCharSet * +FcCharSetSubtract (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcBool +FcCharSetMerge (FcCharSet *a, const FcCharSet *b, FcBool *changed); + +FcPublic FcBool +FcCharSetHasChar (const FcCharSet *fcs, FcChar32 ucs4); + +FcPublic FcChar32 +FcCharSetCount (const FcCharSet *a); + +FcPublic FcChar32 +FcCharSetIntersectCount (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcChar32 +FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcBool +FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b); + +#define FC_CHARSET_MAP_SIZE (256 / 32) +#define FC_CHARSET_DONE ((FcChar32) - 1) + +FcPublic FcChar32 +FcCharSetFirstPage (const FcCharSet *a, + FcChar32 map[FC_CHARSET_MAP_SIZE], + FcChar32 *next); + +FcPublic FcChar32 +FcCharSetNextPage (const FcCharSet *a, + FcChar32 map[FC_CHARSET_MAP_SIZE], + FcChar32 *next); + +/* + * old coverage API, rather hard to use correctly + */ + +FcPublic FcChar32 +FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result); + +/* fcdbg.c */ +FcPublic void +FcValuePrint (const FcValue v); + +FcPublic void +FcPatternPrint (const FcPattern *p); + +FcPublic void +FcFontSetPrint (const FcFontSet *s); + +/* fcdefault.c */ +FcPublic FcStrSet * +FcConfigGetDefaultLangs (FcConfig *config); + +FcPublic FcStrSet * +FcGetDefaultLangs (void); + +FcPublic void +FcConfigSetDefaultSubstitute (FcConfig *config, + FcPattern *pattern); + +FcPublic void +FcDefaultSubstitute (FcPattern *pattern); + +/* fcdir.c */ +FcPublic FcBool +FcFileIsDir (const FcChar8 *file); + +FcPublic FcBool +FcFileScan (FcFontSet *set, + FcStrSet *dirs, + FcFileCache *cache, + FcBlanks *blanks, + const FcChar8 *file, + FcBool force); + +FcPublic FcBool +FcDirScan (FcFontSet *set, + FcStrSet *dirs, + FcFileCache *cache, + FcBlanks *blanks, + const FcChar8 *dir, + FcBool force); + +FcPublic FcBool +FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir); + +FcPublic FcCache * +FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file); + +FcPublic FcCache * +FcDirCacheRescan (const FcChar8 *dir, FcConfig *config); + +FcPublic FcCache * +FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config); + +FcPublic FcCache * +FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat); + +FcPublic void +FcDirCacheUnload (FcCache *cache); + +/* fcfs.c */ + +FcPublic FcFontSet * +FcFontSetCreate (void); + +FcPublic void +FcFontSetDestroy (FcFontSet *s); + +FcPublic FcBool +FcFontSetAdd (FcFontSet *s, FcPattern *font); + +/* fcinit.c */ +FcPublic FcConfig * +FcInitLoadConfig (void); + +FcPublic FcConfig * +FcInitLoadConfigAndFonts (void); + +FcPublic FcBool +FcInit (void); + +FcPublic void +FcFini (void); + +FcPublic int +FcGetVersion (void); + +FcPublic FcBool +FcInitReinitialize (void); + +FcPublic FcBool +FcInitBringUptoDate (void); + +/* fclang.c */ +FcPublic FcStrSet * +FcGetLangs (void); + +FcPublic FcChar8 * +FcLangNormalize (const FcChar8 *lang); + +FcPublic const FcCharSet * +FcLangGetCharSet (const FcChar8 *lang); + +FcPublic FcLangSet * +FcLangSetCreate (void); + +FcPublic void +FcLangSetDestroy (FcLangSet *ls); + +FcPublic FcLangSet * +FcLangSetCopy (const FcLangSet *ls); + +FcPublic FcBool +FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang); + +FcPublic FcBool +FcLangSetDel (FcLangSet *ls, const FcChar8 *lang); + +FcPublic FcLangResult +FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang); + +FcPublic FcLangResult +FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb); + +FcPublic FcBool +FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb); + +FcPublic FcBool +FcLangSetEqual (const FcLangSet *lsa, const FcLangSet *lsb); + +FcPublic FcChar32 +FcLangSetHash (const FcLangSet *ls); + +FcPublic FcStrSet * +FcLangSetGetLangs (const FcLangSet *ls); + +FcPublic FcLangSet * +FcLangSetUnion (const FcLangSet *a, const FcLangSet *b); + +FcPublic FcLangSet * +FcLangSetSubtract (const FcLangSet *a, const FcLangSet *b); + +/* fclist.c */ +FcPublic FcObjectSet * +FcObjectSetCreate (void); + +FcPublic FcBool +FcObjectSetAdd (FcObjectSet *os, const char *object); + +FcPublic void +FcObjectSetDestroy (FcObjectSet *os); + +FcPublic FcObjectSet * +FcObjectSetVaBuild (const char *first, va_list va); + +FcPublic FcObjectSet * +FcObjectSetBuild (const char *first, ...) FC_ATTRIBUTE_SENTINEL (0); + +FcPublic FcFontSet * +FcFontSetList (FcConfig *config, + FcFontSet **sets, + int nsets, + FcPattern *p, + FcObjectSet *os); + +FcPublic FcFontSet * +FcFontList (FcConfig *config, + FcPattern *p, + FcObjectSet *os); + +/* fcatomic.c */ + +FcPublic FcAtomic * +FcAtomicCreate (const FcChar8 *file); + +FcPublic FcBool +FcAtomicLock (FcAtomic *atomic); + +FcPublic FcChar8 * +FcAtomicNewFile (FcAtomic *atomic); + +FcPublic FcChar8 * +FcAtomicOrigFile (FcAtomic *atomic); + +FcPublic FcBool +FcAtomicReplaceOrig (FcAtomic *atomic); + +FcPublic void +FcAtomicDeleteNew (FcAtomic *atomic); + +FcPublic void +FcAtomicUnlock (FcAtomic *atomic); + +FcPublic void +FcAtomicDestroy (FcAtomic *atomic); + +/* fcmatch.c */ +FcPublic FcPattern * +FcFontSetMatch (FcConfig *config, + FcFontSet **sets, + int nsets, + FcPattern *p, + FcResult *result); + +FcPublic FcPattern * +FcFontMatch (FcConfig *config, + FcPattern *p, + FcResult *result); + +FcPublic FcPattern * +FcFontRenderPrepare (FcConfig *config, + FcPattern *pat, + FcPattern *font); + +FcPublic FcFontSet * +FcFontSetSort (FcConfig *config, + FcFontSet **sets, + int nsets, + FcPattern *p, + FcBool trim, + FcCharSet **csp, + FcResult *result); + +FcPublic FcFontSet * +FcFontSort (FcConfig *config, + FcPattern *p, + FcBool trim, + FcCharSet **csp, + FcResult *result); + +FcPublic void +FcFontSetSortDestroy (FcFontSet *fs); + +/* fcmatrix.c */ +FcPublic FcMatrix * +FcMatrixCopy (const FcMatrix *mat); + +FcPublic FcBool +FcMatrixEqual (const FcMatrix *mat1, const FcMatrix *mat2); + +FcPublic void +FcMatrixMultiply (FcMatrix *result, const FcMatrix *a, const FcMatrix *b); + +FcPublic void +FcMatrixRotate (FcMatrix *m, double c, double s); + +FcPublic void +FcMatrixScale (FcMatrix *m, double sx, double sy); + +FcPublic void +FcMatrixShear (FcMatrix *m, double sh, double sv); + +/* fcname.c */ + +/* Deprecated. Does nothing. Returns FcFalse. */ +FcPublic FcBool +FcNameRegisterObjectTypes (const FcObjectType *types, int ntype); + +/* Deprecated. Does nothing. Returns FcFalse. */ +FcPublic FcBool +FcNameUnregisterObjectTypes (const FcObjectType *types, int ntype); + +FcPublic const FcObjectType * +FcNameGetObjectType (const char *object); + +/* Deprecated. Does nothing. Returns FcFalse. */ +FcPublic FcBool +FcNameRegisterConstants (const FcConstant *consts, int nconsts); + +/* Deprecated. Does nothing. Returns FcFalse. */ +FcPublic FcBool +FcNameUnregisterConstants (const FcConstant *consts, int nconsts); + +FcPublic const FcConstant * +FcNameGetConstant (const FcChar8 *string); + +FcPublic const FcConstant * +FcNameGetConstantFor (const FcChar8 *string, const char *object); + +FcPublic FcBool +FcNameConstant (const FcChar8 *string, int *result); + +FcPublic const FcChar8 * +FcNameGetConstantNameFrom (const char *object, int value); + +FcPublic FcPattern * +FcNameParse (const FcChar8 *name); + +FcPublic FcChar8 * +FcNameUnparse (FcPattern *pat); + +/* fcpat.c */ +FcPublic FcPattern * +FcPatternCreate (void); + +FcPublic FcPattern * +FcPatternDuplicate (const FcPattern *p); + +FcPublic void +FcPatternReference (FcPattern *p); + +FcPublic FcPattern * +FcPatternFilter (FcPattern *p, const FcObjectSet *os); + +FcPublic void +FcValueDestroy (FcValue v); + +FcPublic FcBool +FcValueEqual (FcValue va, FcValue vb); + +FcPublic FcValue +FcValueSave (FcValue v); + +FcPublic void +FcPatternDestroy (FcPattern *p); + +FcPublic int +FcPatternObjectCount (const FcPattern *pat); + +FcPublic FcBool +FcPatternEqual (const FcPattern *pa, const FcPattern *pb); + +FcPublic FcBool +FcPatternEqualSubset (const FcPattern *pa, const FcPattern *pb, const FcObjectSet *os); + +FcPublic FcChar32 +FcPatternHash (const FcPattern *p); + +FcPublic FcBool +FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append); + +FcPublic FcBool +FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append); + +FcPublic FcResult +FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v); + +FcPublic FcResult +FcPatternGetWithBinding (const FcPattern *p, const char *object, int id, FcValue *v, FcValueBinding *b); + +FcPublic FcBool +FcPatternDel (FcPattern *p, const char *object); + +FcPublic FcBool +FcPatternRemove (FcPattern *p, const char *object, int id); + +FcPublic FcBool +FcPatternAddInteger (FcPattern *p, const char *object, int i); + +FcPublic FcBool +FcPatternAddDouble (FcPattern *p, const char *object, double d); + +FcPublic FcBool +FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s); + +FcPublic FcBool +FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s); + +FcPublic FcBool +FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c); + +FcPublic FcBool +FcPatternAddBool (FcPattern *p, const char *object, FcBool b); + +FcPublic FcBool +FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls); + +FcPublic FcBool +FcPatternAddRange (FcPattern *p, const char *object, const FcRange *r); + +FcPublic FcResult +FcPatternGetInteger (const FcPattern *p, const char *object, int n, int *i); + +FcPublic FcResult +FcPatternGetDouble (const FcPattern *p, const char *object, int n, double *d); + +FcPublic FcResult +FcPatternGetString (const FcPattern *p, const char *object, int n, FcChar8 **s); + +FcPublic FcResult +FcPatternGetMatrix (const FcPattern *p, const char *object, int n, FcMatrix **s); + +FcPublic FcResult +FcPatternGetCharSet (const FcPattern *p, const char *object, int n, FcCharSet **c); + +FcPublic FcResult +FcPatternGetBool (const FcPattern *p, const char *object, int n, FcBool *b); + +FcPublic FcResult +FcPatternGetLangSet (const FcPattern *p, const char *object, int n, FcLangSet **ls); + +FcPublic FcResult +FcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r); + +FcPublic FcPattern * +FcPatternVaBuild (FcPattern *p, va_list va); + +FcPublic FcPattern * +FcPatternBuild (FcPattern *p, ...) FC_ATTRIBUTE_SENTINEL (0); + +FcPublic FcChar8 * +FcPatternFormat (FcPattern *pat, const FcChar8 *format); + +/* fcrange.c */ +FcPublic FcRange * +FcRangeCreateDouble (double begin, double end); + +FcPublic FcRange * +FcRangeCreateInteger (FcChar32 begin, FcChar32 end); + +FcPublic void +FcRangeDestroy (FcRange *range); + +FcPublic FcRange * +FcRangeCopy (const FcRange *r); + +FcPublic FcBool +FcRangeGetDouble (const FcRange *range, double *begin, double *end); + +FcPublic void +FcPatternIterStart (const FcPattern *pat, FcPatternIter *iter); + +FcPublic FcBool +FcPatternIterNext (const FcPattern *pat, FcPatternIter *iter); + +FcPublic FcBool +FcPatternIterEqual (const FcPattern *p1, FcPatternIter *i1, + const FcPattern *p2, FcPatternIter *i2); + +FcPublic FcBool +FcPatternFindIter (const FcPattern *pat, FcPatternIter *iter, const char *object); + +FcPublic FcBool +FcPatternIterIsValid (const FcPattern *pat, FcPatternIter *iter); + +FcPublic const char * +FcPatternIterGetObject (const FcPattern *pat, FcPatternIter *iter); + +FcPublic int +FcPatternIterValueCount (const FcPattern *pat, FcPatternIter *iter); + +FcPublic FcResult +FcPatternIterGetValue (const FcPattern *pat, FcPatternIter *iter, int id, FcValue *v, FcValueBinding *b); + +/* fcweight.c */ + +FcPublic int +FcWeightFromOpenType (int ot_weight); + +FcPublic double +FcWeightFromOpenTypeDouble (double ot_weight); + +FcPublic int +FcWeightToOpenType (int fc_weight); + +FcPublic double +FcWeightToOpenTypeDouble (double fc_weight); + +/* fcstr.c */ + +FcPublic FcChar8 * +FcStrCopy (const FcChar8 *s); + +FcPublic FcChar8 * +FcStrCopyFilename (const FcChar8 *s); + +FcPublic FcChar8 * +FcStrPlus (const FcChar8 *s1, const FcChar8 *s2); + +FcPublic void +FcStrFree (FcChar8 *s); + +/* These are ASCII only, suitable only for pattern element names */ +#define FcIsUpper(c) ((0101 <= (c) && (c) <= 0132)) +#define FcIsLower(c) ((0141 <= (c) && (c) <= 0172)) +#define FcToLower(c) (FcIsUpper (c) ? (c) - 0101 + 0141 : (c)) + +FcPublic FcChar8 * +FcStrDowncase (const FcChar8 *s); + +FcPublic int +FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2); + +FcPublic int +FcStrCmp (const FcChar8 *s1, const FcChar8 *s2); + +FcPublic const FcChar8 * +FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2); + +FcPublic const FcChar8 * +FcStrStr (const FcChar8 *s1, const FcChar8 *s2); + +FcPublic int +FcUtf8ToUcs4 (const FcChar8 *src_orig, + FcChar32 *dst, + int len); + +FcPublic FcBool +FcUtf8Len (const FcChar8 *string, + int len, + int *nchar, + int *wchar); + +#define FC_UTF8_MAX_LEN 6 + +FcPublic int +FcUcs4ToUtf8 (FcChar32 ucs4, + FcChar8 dest[FC_UTF8_MAX_LEN]); + +FcPublic int +FcUtf16ToUcs4 (const FcChar8 *src_orig, + FcEndian endian, + FcChar32 *dst, + int len); /* in bytes */ + +FcPublic FcBool +FcUtf16Len (const FcChar8 *string, + FcEndian endian, + int len, /* in bytes */ + int *nchar, + int *wchar); + +FcPublic FcChar8 * +FcStrBuildFilename (const FcChar8 *path, + ...); + +FcPublic FcChar8 * +FcStrDirname (const FcChar8 *file); + +FcPublic FcChar8 * +FcStrBasename (const FcChar8 *file); + +FcPublic FcStrSet * +FcStrSetCreate (void); + +FcPublic FcBool +FcStrSetMember (FcStrSet *set, const FcChar8 *s); + +FcPublic FcBool +FcStrSetEqual (FcStrSet *sa, FcStrSet *sb); + +FcPublic FcBool +FcStrSetAdd (FcStrSet *set, const FcChar8 *s); + +FcPublic FcBool +FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s); + +FcPublic FcBool +FcStrSetDel (FcStrSet *set, const FcChar8 *s); + +FcPublic void +FcStrSetDestroy (FcStrSet *set); + +FcPublic FcStrList * +FcStrListCreate (FcStrSet *set); + +FcPublic void +FcStrListFirst (FcStrList *list); + +FcPublic FcChar8 * +FcStrListNext (FcStrList *list); + +FcPublic void +FcStrListDone (FcStrList *list); + +/* fcxml.c */ +FcPublic FcBool +FcConfigParseAndLoad (FcConfig *config, const FcChar8 *file, FcBool complain); + +FcPublic FcBool +FcConfigParseAndLoadFromMemory (FcConfig *config, + const FcChar8 *buffer, + FcBool complain); + +/* fcconffile.c */ +FcPublic FcChar8 * +FcConfigFileGenerate (FcConfig *config, + FcPattern *pat, + const FcChar8 *font_path); + +_FCFUNCPROTOEND + +#undef FC_ATTRIBUTE_SENTINEL +#undef FC_ATTRIBUTE_MAY_ALIAS + +#ifndef _FCINT_H_ + +/* + * Deprecated functions are placed here to help users fix their code without + * digging through documentation + */ + +# define FcConfigGetRescanInverval FcConfigGetRescanInverval_REPLACE_BY_FcConfigGetRescanInterval +# define FcConfigSetRescanInverval FcConfigSetRescanInverval_REPLACE_BY_FcConfigSetRescanInterval + +#endif + +#endif /* _FONTCONFIG_H_ */ diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/include/fcalias.h b/vendor/libghostty-vt/pkg/fontconfig/override/include/fcalias.h deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/include/fcaliastail.h b/vendor/libghostty-vt/pkg/fontconfig/override/include/fcaliastail.h deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/include/fcftalias.h b/vendor/libghostty-vt/pkg/fontconfig/override/include/fcftalias.h deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/include/fcftaliastail.h b/vendor/libghostty-vt/pkg/fontconfig/override/include/fcftaliastail.h deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/include/fcobjshash.h b/vendor/libghostty-vt/pkg/fontconfig/override/include/fcobjshash.h deleted file mode 100644 index f06234ac..00000000 --- a/vendor/libghostty-vt/pkg/fontconfig/override/include/fcobjshash.h +++ /dev/null @@ -1,347 +0,0 @@ -/* ANSI-C code produced by gperf version 3.1 */ -/* Command-line: gperf --pic -m 100 fcobjshash.gperf */ -/* Computed positions: -k'3,5' */ - -#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) -/* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to ." -#endif - -#line 1 "fcobjshash.gperf" - -#line 13 "fcobjshash.gperf" -struct FcObjectTypeInfo { -int name; -int id; -}; -#include -/* maximum key range = 59, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -FcObjectTypeHash (register const char *str, register size_t len) -{ - static const unsigned char asso_values[] = - { - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 4, 10, 32, - 21, 29, 28, 49, 14, 4, 66, 66, 5, 31, - 18, 22, 27, 66, 15, 9, 8, 23, 23, 13, - 23, 16, 4, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66 - }; - register unsigned int hval = len; - - switch (hval) - { - default: - hval += asso_values[(unsigned char)str[4]]; - /*FALLTHROUGH*/ - case 4: - case 3: - hval += asso_values[(unsigned char)str[2]]; - break; - } - return hval; -} - -struct FcObjectTypeNamePool_t - { - char FcObjectTypeNamePool_str7[sizeof("dpi")]; - char FcObjectTypeNamePool_str8[sizeof("size")]; - char FcObjectTypeNamePool_str9[sizeof("file")]; - char FcObjectTypeNamePool_str13[sizeof("hash")]; - char FcObjectTypeNamePool_str14[sizeof("rgba")]; - char FcObjectTypeNamePool_str15[sizeof("spacing")]; - char FcObjectTypeNamePool_str16[sizeof("scalable")]; - char FcObjectTypeNamePool_str17[sizeof("slant")]; - char FcObjectTypeNamePool_str18[sizeof("matrix")]; - char FcObjectTypeNamePool_str19[sizeof("outline")]; - char FcObjectTypeNamePool_str20[sizeof("charset")]; - char FcObjectTypeNamePool_str21[sizeof("antialias")]; - char FcObjectTypeNamePool_str22[sizeof("lang")]; - char FcObjectTypeNamePool_str23[sizeof("embolden")]; - char FcObjectTypeNamePool_str24[sizeof("weight")]; - char FcObjectTypeNamePool_str25[sizeof("color")]; - char FcObjectTypeNamePool_str26[sizeof("charwidth")]; - char FcObjectTypeNamePool_str27[sizeof("variable")]; - char FcObjectTypeNamePool_str28[sizeof("charheight")]; - char FcObjectTypeNamePool_str29[sizeof("hinting")]; - char FcObjectTypeNamePool_str30[sizeof("autohint")]; - char FcObjectTypeNamePool_str31[sizeof("fullname")]; - char FcObjectTypeNamePool_str32[sizeof("postscriptname")]; - char FcObjectTypeNamePool_str33[sizeof("verticallayout")]; - char FcObjectTypeNamePool_str34[sizeof("lcdfilter")]; - char FcObjectTypeNamePool_str35[sizeof("fullnamelang")]; - char FcObjectTypeNamePool_str36[sizeof("hintstyle")]; - char FcObjectTypeNamePool_str37[sizeof("pixelsize")]; - char FcObjectTypeNamePool_str38[sizeof("scale")]; - char FcObjectTypeNamePool_str39[sizeof("globaladvance")]; - char FcObjectTypeNamePool_str40[sizeof("width")]; - char FcObjectTypeNamePool_str41[sizeof("order")]; - char FcObjectTypeNamePool_str42[sizeof("family")]; - char FcObjectTypeNamePool_str43[sizeof("fonthashint")]; - char FcObjectTypeNamePool_str44[sizeof("namelang")]; - char FcObjectTypeNamePool_str45[sizeof("embeddedbitmap")]; - char FcObjectTypeNamePool_str46[sizeof("familylang")]; - char FcObjectTypeNamePool_str47[sizeof("capability")]; - char FcObjectTypeNamePool_str48[sizeof("rasterizer")]; - char FcObjectTypeNamePool_str49[sizeof("index")]; - char FcObjectTypeNamePool_str50[sizeof("style")]; - char FcObjectTypeNamePool_str51[sizeof("foundry")]; - char FcObjectTypeNamePool_str52[sizeof("fontversion")]; - char FcObjectTypeNamePool_str53[sizeof("minspace")]; - char FcObjectTypeNamePool_str54[sizeof("stylelang")]; - char FcObjectTypeNamePool_str55[sizeof("fontvariations")]; - char FcObjectTypeNamePool_str56[sizeof("fontformat")]; - char FcObjectTypeNamePool_str57[sizeof("decorative")]; - char FcObjectTypeNamePool_str58[sizeof("fontfeatures")]; - char FcObjectTypeNamePool_str59[sizeof("symbol")]; - char FcObjectTypeNamePool_str60[sizeof("prgname")]; - char FcObjectTypeNamePool_str65[sizeof("aspect")]; - }; -static const struct FcObjectTypeNamePool_t FcObjectTypeNamePool_contents = - { - "dpi", - "size", - "file", - "hash", - "rgba", - "spacing", - "scalable", - "slant", - "matrix", - "outline", - "charset", - "antialias", - "lang", - "embolden", - "weight", - "color", - "charwidth", - "variable", - "charheight", - "hinting", - "autohint", - "fullname", - "postscriptname", - "verticallayout", - "lcdfilter", - "fullnamelang", - "hintstyle", - "pixelsize", - "scale", - "globaladvance", - "width", - "order", - "family", - "fonthashint", - "namelang", - "embeddedbitmap", - "familylang", - "capability", - "rasterizer", - "index", - "style", - "foundry", - "fontversion", - "minspace", - "stylelang", - "fontvariations", - "fontformat", - "decorative", - "fontfeatures", - "symbol", - "prgname", - "aspect" - }; -#define FcObjectTypeNamePool ((const char *) &FcObjectTypeNamePool_contents) -const struct FcObjectTypeInfo * -FcObjectTypeLookup (register const char *str, register size_t len) -{ - enum - { - TOTAL_KEYWORDS = 52, - MIN_WORD_LENGTH = 3, - MAX_WORD_LENGTH = 14, - MIN_HASH_VALUE = 7, - MAX_HASH_VALUE = 65 - }; - - static const struct FcObjectTypeInfo wordlist[] = - { - {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 43 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str7,FC_DPI_OBJECT}, -#line 27 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str8,FC_SIZE_OBJECT}, -#line 38 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str9,FC_FILE_OBJECT}, - {-1}, {-1}, {-1}, -#line 62 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str13,FC_HASH_OBJECT}, -#line 44 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str14,FC_RGBA_OBJECT}, -#line 30 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str15,FC_SPACING_OBJECT}, -#line 42 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str16,FC_SCALABLE_OBJECT}, -#line 24 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str17,FC_SLANT_OBJECT}, -#line 49 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str18,FC_MATRIX_OBJECT}, -#line 41 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str19,FC_OUTLINE_OBJECT}, -#line 50 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str20,FC_CHARSET_OBJECT}, -#line 32 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str21,FC_ANTIALIAS_OBJECT}, -#line 51 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str22,FC_LANG_OBJECT}, -#line 55 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str23,FC_EMBOLDEN_OBJECT}, -#line 25 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str24,FC_WEIGHT_OBJECT}, -#line 64 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str25,FC_COLOR_OBJECT}, -#line 47 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str26,FC_CHARWIDTH_OBJECT}, -#line 67 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str27,FC_VARIABLE_OBJECT}, -#line 48 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str28,FC_CHAR_HEIGHT_OBJECT}, -#line 34 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str29,FC_HINTING_OBJECT}, -#line 36 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str30,FC_AUTOHINT_OBJECT}, -#line 22 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str31,FC_FULLNAME_OBJECT}, -#line 63 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str32,FC_POSTSCRIPT_NAME_OBJECT}, -#line 35 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str33,FC_VERTICAL_LAYOUT_OBJECT}, -#line 58 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str34,FC_LCD_FILTER_OBJECT}, -#line 23 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str35,FC_FULLNAMELANG_OBJECT}, -#line 33 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str36,FC_HINT_STYLE_OBJECT}, -#line 29 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str37,FC_PIXEL_SIZE_OBJECT}, -#line 45 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str38,FC_SCALE_OBJECT}, -#line 37 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str39,FC_GLOBAL_ADVANCE_OBJECT}, -#line 26 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str40,FC_WIDTH_OBJECT}, -#line 69 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str41,FC_ORDER_OBJECT}, -#line 18 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str42,FC_FAMILY_OBJECT}, -#line 68 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str43,FC_FONT_HAS_HINT_OBJECT}, -#line 59 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str44,FC_NAMELANG_OBJECT}, -#line 56 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_EMBEDDED_BITMAP_OBJECT}, -#line 19 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str46,FC_FAMILYLANG_OBJECT}, -#line 53 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str47,FC_CAPABILITY_OBJECT}, -#line 40 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str48,FC_RASTERIZER_OBJECT}, -#line 39 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str49,FC_INDEX_OBJECT}, -#line 20 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str50,FC_STYLE_OBJECT}, -#line 31 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str51,FC_FOUNDRY_OBJECT}, -#line 52 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str52,FC_FONTVERSION_OBJECT}, -#line 46 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str53,FC_MINSPACE_OBJECT}, -#line 21 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str54,FC_STYLELANG_OBJECT}, -#line 66 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str55,FC_FONT_VARIATIONS_OBJECT}, -#line 54 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str56,FC_FONTFORMAT_OBJECT}, -#line 57 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str57,FC_DECORATIVE_OBJECT}, -#line 60 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str58,FC_FONT_FEATURES_OBJECT}, -#line 65 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str59,FC_SYMBOL_OBJECT}, -#line 61 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str60,FC_PRGNAME_OBJECT}, - {-1}, {-1}, {-1}, {-1}, -#line 28 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str65,FC_ASPECT_OBJECT} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register unsigned int key = FcObjectTypeHash (str, len); - - if (key <= MAX_HASH_VALUE) - { - register int o = wordlist[key].name; - if (o >= 0) - { - register const char *s = o + FcObjectTypeNamePool; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - } - return 0; -} diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/src/fcalias.h b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcalias.h new file mode 100644 index 00000000..8746ce57 --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcalias.h @@ -0,0 +1,472 @@ +extern __typeof (FcBlanksCreate) IA__FcBlanksCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcBlanksCreate IA__FcBlanksCreate +extern __typeof (FcBlanksDestroy) IA__FcBlanksDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcBlanksDestroy IA__FcBlanksDestroy +extern __typeof (FcBlanksAdd) IA__FcBlanksAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcBlanksAdd IA__FcBlanksAdd +extern __typeof (FcBlanksIsMember) IA__FcBlanksIsMember FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcBlanksIsMember IA__FcBlanksIsMember +extern __typeof (FcCacheCopySet) IA__FcCacheCopySet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCacheCopySet IA__FcCacheCopySet +extern __typeof (FcCacheNumSubdir) IA__FcCacheNumSubdir FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCacheNumSubdir IA__FcCacheNumSubdir +extern __typeof (FcCacheNumFont) IA__FcCacheNumFont FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCacheNumFont IA__FcCacheNumFont +extern __typeof (FcDirCacheUnlink) IA__FcDirCacheUnlink FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirCacheUnlink IA__FcDirCacheUnlink +extern __typeof (FcDirCacheValid) IA__FcDirCacheValid FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirCacheValid IA__FcDirCacheValid +extern __typeof (FcDirCacheClean) IA__FcDirCacheClean FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirCacheClean IA__FcDirCacheClean +extern __typeof (FcCacheCreateTagFile) IA__FcCacheCreateTagFile FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCacheCreateTagFile IA__FcCacheCreateTagFile +extern __typeof (FcDirCacheCreateUUID) IA__FcDirCacheCreateUUID FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirCacheCreateUUID IA__FcDirCacheCreateUUID +extern __typeof (FcDirCacheDeleteUUID) IA__FcDirCacheDeleteUUID FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirCacheDeleteUUID IA__FcDirCacheDeleteUUID +extern __typeof (FcConfigHome) IA__FcConfigHome FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigHome IA__FcConfigHome +extern __typeof (FcConfigEnableHome) IA__FcConfigEnableHome FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigEnableHome IA__FcConfigEnableHome +extern __typeof (FcConfigGetFilename) IA__FcConfigGetFilename FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetFilename IA__FcConfigGetFilename +extern __typeof (FcConfigFilename) IA__FcConfigFilename FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigFilename IA__FcConfigFilename +extern __typeof (FcConfigCreate) IA__FcConfigCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigCreate IA__FcConfigCreate +extern __typeof (FcConfigReference) IA__FcConfigReference FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigReference IA__FcConfigReference +extern __typeof (FcConfigDestroy) IA__FcConfigDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigDestroy IA__FcConfigDestroy +extern __typeof (FcConfigSetCurrent) IA__FcConfigSetCurrent FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigSetCurrent IA__FcConfigSetCurrent +extern __typeof (FcConfigGetCurrent) IA__FcConfigGetCurrent FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetCurrent IA__FcConfigGetCurrent +extern __typeof (FcConfigUptoDate) IA__FcConfigUptoDate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigUptoDate IA__FcConfigUptoDate +extern __typeof (FcConfigBuildFonts) IA__FcConfigBuildFonts FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigBuildFonts IA__FcConfigBuildFonts +extern __typeof (FcConfigGetFontDirs) IA__FcConfigGetFontDirs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetFontDirs IA__FcConfigGetFontDirs +extern __typeof (FcConfigGetConfigDirs) IA__FcConfigGetConfigDirs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetConfigDirs IA__FcConfigGetConfigDirs +extern __typeof (FcConfigGetConfigFiles) IA__FcConfigGetConfigFiles FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetConfigFiles IA__FcConfigGetConfigFiles +extern __typeof (FcConfigGetCache) IA__FcConfigGetCache FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetCache IA__FcConfigGetCache +extern __typeof (FcConfigGetBlanks) IA__FcConfigGetBlanks FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetBlanks IA__FcConfigGetBlanks +extern __typeof (FcConfigGetCacheDirs) IA__FcConfigGetCacheDirs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetCacheDirs IA__FcConfigGetCacheDirs +extern __typeof (FcConfigGetRescanInterval) IA__FcConfigGetRescanInterval FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetRescanInterval IA__FcConfigGetRescanInterval +extern __typeof (FcConfigSetRescanInterval) IA__FcConfigSetRescanInterval FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigSetRescanInterval IA__FcConfigSetRescanInterval +extern __typeof (FcConfigGetFonts) IA__FcConfigGetFonts FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetFonts IA__FcConfigGetFonts +extern __typeof (FcConfigAcceptFont) IA__FcConfigAcceptFont FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigAcceptFont IA__FcConfigAcceptFont +extern __typeof (FcConfigAcceptFilename) IA__FcConfigAcceptFilename FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigAcceptFilename IA__FcConfigAcceptFilename +extern __typeof (FcConfigAcceptFilter) IA__FcConfigAcceptFilter FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigAcceptFilter IA__FcConfigAcceptFilter +extern __typeof (FcConfigAppFontAddFile) IA__FcConfigAppFontAddFile FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigAppFontAddFile IA__FcConfigAppFontAddFile +extern __typeof (FcConfigAppFontAddDir) IA__FcConfigAppFontAddDir FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigAppFontAddDir IA__FcConfigAppFontAddDir +extern __typeof (FcConfigAppFontClear) IA__FcConfigAppFontClear FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigAppFontClear IA__FcConfigAppFontClear +extern __typeof (FcConfigPreferAppFont) IA__FcConfigPreferAppFont FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigPreferAppFont IA__FcConfigPreferAppFont +extern __typeof (FcConfigSetWarningFlags) IA__FcConfigSetWarningFlags FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigSetWarningFlags IA__FcConfigSetWarningFlags +extern __typeof (FcConfigGetWarningFlags) IA__FcConfigGetWarningFlags FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetWarningFlags IA__FcConfigGetWarningFlags +extern __typeof (FcConfigSubstituteWithPat) IA__FcConfigSubstituteWithPat FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigSubstituteWithPat IA__FcConfigSubstituteWithPat +extern __typeof (FcConfigSubstitute) IA__FcConfigSubstitute FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigSubstitute IA__FcConfigSubstitute +extern __typeof (FcConfigGetSysRoot) IA__FcConfigGetSysRoot FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetSysRoot IA__FcConfigGetSysRoot +extern __typeof (FcConfigSetSysRoot) IA__FcConfigSetSysRoot FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigSetSysRoot IA__FcConfigSetSysRoot +extern __typeof (FcConfigSetFontSetFilter) IA__FcConfigSetFontSetFilter FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigSetFontSetFilter IA__FcConfigSetFontSetFilter +extern __typeof (FcConfigFileInfoIterInit) IA__FcConfigFileInfoIterInit FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigFileInfoIterInit IA__FcConfigFileInfoIterInit +extern __typeof (FcConfigFileInfoIterNext) IA__FcConfigFileInfoIterNext FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigFileInfoIterNext IA__FcConfigFileInfoIterNext +extern __typeof (FcConfigFileInfoIterGet) IA__FcConfigFileInfoIterGet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigFileInfoIterGet IA__FcConfigFileInfoIterGet +extern __typeof (FcCharSetCreate) IA__FcCharSetCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetCreate IA__FcCharSetCreate +extern __typeof (FcCharSetNew) IA__FcCharSetNew FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetNew IA__FcCharSetNew +extern __typeof (FcCharSetDestroy) IA__FcCharSetDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetDestroy IA__FcCharSetDestroy +extern __typeof (FcCharSetAddChar) IA__FcCharSetAddChar FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetAddChar IA__FcCharSetAddChar +extern __typeof (FcCharSetDelChar) IA__FcCharSetDelChar FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetDelChar IA__FcCharSetDelChar +extern __typeof (FcCharSetCopy) IA__FcCharSetCopy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetCopy IA__FcCharSetCopy +extern __typeof (FcCharSetEqual) IA__FcCharSetEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetEqual IA__FcCharSetEqual +extern __typeof (FcCharSetIntersect) IA__FcCharSetIntersect FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetIntersect IA__FcCharSetIntersect +extern __typeof (FcCharSetUnion) IA__FcCharSetUnion FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetUnion IA__FcCharSetUnion +extern __typeof (FcCharSetSubtract) IA__FcCharSetSubtract FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetSubtract IA__FcCharSetSubtract +extern __typeof (FcCharSetMerge) IA__FcCharSetMerge FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetMerge IA__FcCharSetMerge +extern __typeof (FcCharSetHasChar) IA__FcCharSetHasChar FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetHasChar IA__FcCharSetHasChar +extern __typeof (FcCharSetCount) IA__FcCharSetCount FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetCount IA__FcCharSetCount +extern __typeof (FcCharSetIntersectCount) IA__FcCharSetIntersectCount FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetIntersectCount IA__FcCharSetIntersectCount +extern __typeof (FcCharSetSubtractCount) IA__FcCharSetSubtractCount FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetSubtractCount IA__FcCharSetSubtractCount +extern __typeof (FcCharSetIsSubset) IA__FcCharSetIsSubset FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetIsSubset IA__FcCharSetIsSubset +extern __typeof (FcCharSetFirstPage) IA__FcCharSetFirstPage FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetFirstPage IA__FcCharSetFirstPage +extern __typeof (FcCharSetNextPage) IA__FcCharSetNextPage FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetNextPage IA__FcCharSetNextPage +extern __typeof (FcCharSetCoverage) IA__FcCharSetCoverage FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcCharSetCoverage IA__FcCharSetCoverage +extern __typeof (FcValuePrint) IA__FcValuePrint FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcValuePrint IA__FcValuePrint +extern __typeof (FcPatternPrint) IA__FcPatternPrint FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternPrint IA__FcPatternPrint +extern __typeof (FcFontSetPrint) IA__FcFontSetPrint FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontSetPrint IA__FcFontSetPrint +extern __typeof (FcConfigGetDefaultLangs) IA__FcConfigGetDefaultLangs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetDefaultLangs IA__FcConfigGetDefaultLangs +extern __typeof (FcGetDefaultLangs) IA__FcGetDefaultLangs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcGetDefaultLangs IA__FcGetDefaultLangs +extern __typeof (FcConfigSetDefaultSubstitute) IA__FcConfigSetDefaultSubstitute FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigSetDefaultSubstitute IA__FcConfigSetDefaultSubstitute +extern __typeof (FcDefaultSubstitute) IA__FcDefaultSubstitute FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDefaultSubstitute IA__FcDefaultSubstitute +extern __typeof (FcFileIsDir) IA__FcFileIsDir FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFileIsDir IA__FcFileIsDir +extern __typeof (FcFileScan) IA__FcFileScan FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFileScan IA__FcFileScan +extern __typeof (FcDirScan) IA__FcDirScan FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirScan IA__FcDirScan +extern __typeof (FcDirSave) IA__FcDirSave FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirSave IA__FcDirSave +extern __typeof (FcDirCacheLoad) IA__FcDirCacheLoad FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirCacheLoad IA__FcDirCacheLoad +extern __typeof (FcDirCacheRescan) IA__FcDirCacheRescan FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirCacheRescan IA__FcDirCacheRescan +extern __typeof (FcDirCacheRead) IA__FcDirCacheRead FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirCacheRead IA__FcDirCacheRead +extern __typeof (FcDirCacheLoadFile) IA__FcDirCacheLoadFile FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirCacheLoadFile IA__FcDirCacheLoadFile +extern __typeof (FcDirCacheUnload) IA__FcDirCacheUnload FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcDirCacheUnload IA__FcDirCacheUnload +extern __typeof (FcFontSetCreate) IA__FcFontSetCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontSetCreate IA__FcFontSetCreate +extern __typeof (FcFontSetDestroy) IA__FcFontSetDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontSetDestroy IA__FcFontSetDestroy +extern __typeof (FcFontSetAdd) IA__FcFontSetAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontSetAdd IA__FcFontSetAdd +extern __typeof (FcInitLoadConfig) IA__FcInitLoadConfig FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcInitLoadConfig IA__FcInitLoadConfig +extern __typeof (FcInitLoadConfigAndFonts) IA__FcInitLoadConfigAndFonts FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcInitLoadConfigAndFonts IA__FcInitLoadConfigAndFonts +extern __typeof (FcInit) IA__FcInit FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcInit IA__FcInit +extern __typeof (FcFini) IA__FcFini FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFini IA__FcFini +extern __typeof (FcGetVersion) IA__FcGetVersion FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcGetVersion IA__FcGetVersion +extern __typeof (FcInitReinitialize) IA__FcInitReinitialize FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcInitReinitialize IA__FcInitReinitialize +extern __typeof (FcInitBringUptoDate) IA__FcInitBringUptoDate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcInitBringUptoDate IA__FcInitBringUptoDate +extern __typeof (FcGetLangs) IA__FcGetLangs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcGetLangs IA__FcGetLangs +extern __typeof (FcLangNormalize) IA__FcLangNormalize FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangNormalize IA__FcLangNormalize +extern __typeof (FcLangGetCharSet) IA__FcLangGetCharSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangGetCharSet IA__FcLangGetCharSet +extern __typeof (FcLangSetCreate) IA__FcLangSetCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetCreate IA__FcLangSetCreate +extern __typeof (FcLangSetDestroy) IA__FcLangSetDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetDestroy IA__FcLangSetDestroy +extern __typeof (FcLangSetCopy) IA__FcLangSetCopy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetCopy IA__FcLangSetCopy +extern __typeof (FcLangSetAdd) IA__FcLangSetAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetAdd IA__FcLangSetAdd +extern __typeof (FcLangSetDel) IA__FcLangSetDel FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetDel IA__FcLangSetDel +extern __typeof (FcLangSetHasLang) IA__FcLangSetHasLang FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetHasLang IA__FcLangSetHasLang +extern __typeof (FcLangSetCompare) IA__FcLangSetCompare FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetCompare IA__FcLangSetCompare +extern __typeof (FcLangSetContains) IA__FcLangSetContains FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetContains IA__FcLangSetContains +extern __typeof (FcLangSetEqual) IA__FcLangSetEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetEqual IA__FcLangSetEqual +extern __typeof (FcLangSetHash) IA__FcLangSetHash FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetHash IA__FcLangSetHash +extern __typeof (FcLangSetGetLangs) IA__FcLangSetGetLangs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetGetLangs IA__FcLangSetGetLangs +extern __typeof (FcLangSetUnion) IA__FcLangSetUnion FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetUnion IA__FcLangSetUnion +extern __typeof (FcLangSetSubtract) IA__FcLangSetSubtract FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcLangSetSubtract IA__FcLangSetSubtract +extern __typeof (FcObjectSetCreate) IA__FcObjectSetCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcObjectSetCreate IA__FcObjectSetCreate +extern __typeof (FcObjectSetAdd) IA__FcObjectSetAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcObjectSetAdd IA__FcObjectSetAdd +extern __typeof (FcObjectSetDestroy) IA__FcObjectSetDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcObjectSetDestroy IA__FcObjectSetDestroy +extern __typeof (FcObjectSetVaBuild) IA__FcObjectSetVaBuild FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcObjectSetVaBuild IA__FcObjectSetVaBuild +extern __typeof (FcObjectSetBuild) IA__FcObjectSetBuild FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcObjectSetBuild IA__FcObjectSetBuild +extern __typeof (FcFontSetList) IA__FcFontSetList FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontSetList IA__FcFontSetList +extern __typeof (FcFontList) IA__FcFontList FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontList IA__FcFontList +extern __typeof (FcAtomicCreate) IA__FcAtomicCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcAtomicCreate IA__FcAtomicCreate +extern __typeof (FcAtomicLock) IA__FcAtomicLock FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcAtomicLock IA__FcAtomicLock +extern __typeof (FcAtomicNewFile) IA__FcAtomicNewFile FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcAtomicNewFile IA__FcAtomicNewFile +extern __typeof (FcAtomicOrigFile) IA__FcAtomicOrigFile FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcAtomicOrigFile IA__FcAtomicOrigFile +extern __typeof (FcAtomicReplaceOrig) IA__FcAtomicReplaceOrig FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcAtomicReplaceOrig IA__FcAtomicReplaceOrig +extern __typeof (FcAtomicDeleteNew) IA__FcAtomicDeleteNew FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcAtomicDeleteNew IA__FcAtomicDeleteNew +extern __typeof (FcAtomicUnlock) IA__FcAtomicUnlock FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcAtomicUnlock IA__FcAtomicUnlock +extern __typeof (FcAtomicDestroy) IA__FcAtomicDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcAtomicDestroy IA__FcAtomicDestroy +extern __typeof (FcFontSetMatch) IA__FcFontSetMatch FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontSetMatch IA__FcFontSetMatch +extern __typeof (FcFontMatch) IA__FcFontMatch FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontMatch IA__FcFontMatch +extern __typeof (FcFontRenderPrepare) IA__FcFontRenderPrepare FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontRenderPrepare IA__FcFontRenderPrepare +extern __typeof (FcFontSetSort) IA__FcFontSetSort FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontSetSort IA__FcFontSetSort +extern __typeof (FcFontSort) IA__FcFontSort FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontSort IA__FcFontSort +extern __typeof (FcFontSetSortDestroy) IA__FcFontSetSortDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFontSetSortDestroy IA__FcFontSetSortDestroy +extern __typeof (FcMatrixCopy) IA__FcMatrixCopy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcMatrixCopy IA__FcMatrixCopy +extern __typeof (FcMatrixEqual) IA__FcMatrixEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcMatrixEqual IA__FcMatrixEqual +extern __typeof (FcMatrixMultiply) IA__FcMatrixMultiply FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcMatrixMultiply IA__FcMatrixMultiply +extern __typeof (FcMatrixRotate) IA__FcMatrixRotate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcMatrixRotate IA__FcMatrixRotate +extern __typeof (FcMatrixScale) IA__FcMatrixScale FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcMatrixScale IA__FcMatrixScale +extern __typeof (FcMatrixShear) IA__FcMatrixShear FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcMatrixShear IA__FcMatrixShear +extern __typeof (FcNameRegisterObjectTypes) IA__FcNameRegisterObjectTypes FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameRegisterObjectTypes IA__FcNameRegisterObjectTypes +extern __typeof (FcNameUnregisterObjectTypes) IA__FcNameUnregisterObjectTypes FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameUnregisterObjectTypes IA__FcNameUnregisterObjectTypes +extern __typeof (FcNameGetObjectType) IA__FcNameGetObjectType FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameGetObjectType IA__FcNameGetObjectType +extern __typeof (FcNameRegisterConstants) IA__FcNameRegisterConstants FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameRegisterConstants IA__FcNameRegisterConstants +extern __typeof (FcNameUnregisterConstants) IA__FcNameUnregisterConstants FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameUnregisterConstants IA__FcNameUnregisterConstants +extern __typeof (FcNameGetConstant) IA__FcNameGetConstant FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameGetConstant IA__FcNameGetConstant +extern __typeof (FcNameGetConstantFor) IA__FcNameGetConstantFor FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameGetConstantFor IA__FcNameGetConstantFor +extern __typeof (FcNameConstant) IA__FcNameConstant FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameConstant IA__FcNameConstant +extern __typeof (FcNameGetConstantNameFrom) IA__FcNameGetConstantNameFrom FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameGetConstantNameFrom IA__FcNameGetConstantNameFrom +extern __typeof (FcNameParse) IA__FcNameParse FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameParse IA__FcNameParse +extern __typeof (FcNameUnparse) IA__FcNameUnparse FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameUnparse IA__FcNameUnparse +extern __typeof (FcPatternCreate) IA__FcPatternCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternCreate IA__FcPatternCreate +extern __typeof (FcPatternDuplicate) IA__FcPatternDuplicate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternDuplicate IA__FcPatternDuplicate +extern __typeof (FcPatternReference) IA__FcPatternReference FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternReference IA__FcPatternReference +extern __typeof (FcPatternFilter) IA__FcPatternFilter FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternFilter IA__FcPatternFilter +extern __typeof (FcValueDestroy) IA__FcValueDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcValueDestroy IA__FcValueDestroy +extern __typeof (FcValueEqual) IA__FcValueEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcValueEqual IA__FcValueEqual +extern __typeof (FcValueSave) IA__FcValueSave FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcValueSave IA__FcValueSave +extern __typeof (FcPatternDestroy) IA__FcPatternDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternDestroy IA__FcPatternDestroy +extern __typeof (FcPatternObjectCount) IA__FcPatternObjectCount FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternObjectCount IA__FcPatternObjectCount +extern __typeof (FcPatternEqual) IA__FcPatternEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternEqual IA__FcPatternEqual +extern __typeof (FcPatternEqualSubset) IA__FcPatternEqualSubset FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternEqualSubset IA__FcPatternEqualSubset +extern __typeof (FcPatternHash) IA__FcPatternHash FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternHash IA__FcPatternHash +extern __typeof (FcPatternAdd) IA__FcPatternAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternAdd IA__FcPatternAdd +extern __typeof (FcPatternAddWeak) IA__FcPatternAddWeak FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternAddWeak IA__FcPatternAddWeak +extern __typeof (FcPatternGet) IA__FcPatternGet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternGet IA__FcPatternGet +extern __typeof (FcPatternGetWithBinding) IA__FcPatternGetWithBinding FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternGetWithBinding IA__FcPatternGetWithBinding +extern __typeof (FcPatternDel) IA__FcPatternDel FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternDel IA__FcPatternDel +extern __typeof (FcPatternRemove) IA__FcPatternRemove FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternRemove IA__FcPatternRemove +extern __typeof (FcPatternAddInteger) IA__FcPatternAddInteger FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternAddInteger IA__FcPatternAddInteger +extern __typeof (FcPatternAddDouble) IA__FcPatternAddDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternAddDouble IA__FcPatternAddDouble +extern __typeof (FcPatternAddString) IA__FcPatternAddString FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternAddString IA__FcPatternAddString +extern __typeof (FcPatternAddMatrix) IA__FcPatternAddMatrix FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternAddMatrix IA__FcPatternAddMatrix +extern __typeof (FcPatternAddCharSet) IA__FcPatternAddCharSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternAddCharSet IA__FcPatternAddCharSet +extern __typeof (FcPatternAddBool) IA__FcPatternAddBool FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternAddBool IA__FcPatternAddBool +extern __typeof (FcPatternAddLangSet) IA__FcPatternAddLangSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternAddLangSet IA__FcPatternAddLangSet +extern __typeof (FcPatternAddRange) IA__FcPatternAddRange FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternAddRange IA__FcPatternAddRange +extern __typeof (FcPatternGetInteger) IA__FcPatternGetInteger FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternGetInteger IA__FcPatternGetInteger +extern __typeof (FcPatternGetDouble) IA__FcPatternGetDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternGetDouble IA__FcPatternGetDouble +extern __typeof (FcPatternGetString) IA__FcPatternGetString FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternGetString IA__FcPatternGetString +extern __typeof (FcPatternGetMatrix) IA__FcPatternGetMatrix FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternGetMatrix IA__FcPatternGetMatrix +extern __typeof (FcPatternGetCharSet) IA__FcPatternGetCharSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternGetCharSet IA__FcPatternGetCharSet +extern __typeof (FcPatternGetBool) IA__FcPatternGetBool FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternGetBool IA__FcPatternGetBool +extern __typeof (FcPatternGetLangSet) IA__FcPatternGetLangSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternGetLangSet IA__FcPatternGetLangSet +extern __typeof (FcPatternGetRange) IA__FcPatternGetRange FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternGetRange IA__FcPatternGetRange +extern __typeof (FcPatternVaBuild) IA__FcPatternVaBuild FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternVaBuild IA__FcPatternVaBuild +extern __typeof (FcPatternBuild) IA__FcPatternBuild FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternBuild IA__FcPatternBuild +extern __typeof (FcPatternFormat) IA__FcPatternFormat FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternFormat IA__FcPatternFormat +extern __typeof (FcRangeCreateDouble) IA__FcRangeCreateDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcRangeCreateDouble IA__FcRangeCreateDouble +extern __typeof (FcRangeCreateInteger) IA__FcRangeCreateInteger FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcRangeCreateInteger IA__FcRangeCreateInteger +extern __typeof (FcRangeDestroy) IA__FcRangeDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcRangeDestroy IA__FcRangeDestroy +extern __typeof (FcRangeCopy) IA__FcRangeCopy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcRangeCopy IA__FcRangeCopy +extern __typeof (FcRangeGetDouble) IA__FcRangeGetDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcRangeGetDouble IA__FcRangeGetDouble +extern __typeof (FcPatternIterStart) IA__FcPatternIterStart FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternIterStart IA__FcPatternIterStart +extern __typeof (FcPatternIterNext) IA__FcPatternIterNext FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternIterNext IA__FcPatternIterNext +extern __typeof (FcPatternIterEqual) IA__FcPatternIterEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternIterEqual IA__FcPatternIterEqual +extern __typeof (FcPatternFindIter) IA__FcPatternFindIter FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternFindIter IA__FcPatternFindIter +extern __typeof (FcPatternIterIsValid) IA__FcPatternIterIsValid FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternIterIsValid IA__FcPatternIterIsValid +extern __typeof (FcPatternIterGetObject) IA__FcPatternIterGetObject FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternIterGetObject IA__FcPatternIterGetObject +extern __typeof (FcPatternIterValueCount) IA__FcPatternIterValueCount FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternIterValueCount IA__FcPatternIterValueCount +extern __typeof (FcPatternIterGetValue) IA__FcPatternIterGetValue FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternIterGetValue IA__FcPatternIterGetValue +extern __typeof (FcWeightFromOpenType) IA__FcWeightFromOpenType FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcWeightFromOpenType IA__FcWeightFromOpenType +extern __typeof (FcWeightFromOpenTypeDouble) IA__FcWeightFromOpenTypeDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcWeightFromOpenTypeDouble IA__FcWeightFromOpenTypeDouble +extern __typeof (FcWeightToOpenType) IA__FcWeightToOpenType FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcWeightToOpenType IA__FcWeightToOpenType +extern __typeof (FcWeightToOpenTypeDouble) IA__FcWeightToOpenTypeDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcWeightToOpenTypeDouble IA__FcWeightToOpenTypeDouble +extern __typeof (FcStrCopy) IA__FcStrCopy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrCopy IA__FcStrCopy +extern __typeof (FcStrCopyFilename) IA__FcStrCopyFilename FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrCopyFilename IA__FcStrCopyFilename +extern __typeof (FcStrPlus) IA__FcStrPlus FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrPlus IA__FcStrPlus +extern __typeof (FcStrFree) IA__FcStrFree FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrFree IA__FcStrFree +extern __typeof (FcStrDowncase) IA__FcStrDowncase FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrDowncase IA__FcStrDowncase +extern __typeof (FcStrCmpIgnoreCase) IA__FcStrCmpIgnoreCase FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrCmpIgnoreCase IA__FcStrCmpIgnoreCase +extern __typeof (FcStrCmp) IA__FcStrCmp FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrCmp IA__FcStrCmp +extern __typeof (FcStrStrIgnoreCase) IA__FcStrStrIgnoreCase FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrStrIgnoreCase IA__FcStrStrIgnoreCase +extern __typeof (FcStrStr) IA__FcStrStr FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrStr IA__FcStrStr +extern __typeof (FcUtf8ToUcs4) IA__FcUtf8ToUcs4 FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcUtf8ToUcs4 IA__FcUtf8ToUcs4 +extern __typeof (FcUtf8Len) IA__FcUtf8Len FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcUtf8Len IA__FcUtf8Len +extern __typeof (FcUcs4ToUtf8) IA__FcUcs4ToUtf8 FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcUcs4ToUtf8 IA__FcUcs4ToUtf8 +extern __typeof (FcUtf16ToUcs4) IA__FcUtf16ToUcs4 FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcUtf16ToUcs4 IA__FcUtf16ToUcs4 +extern __typeof (FcUtf16Len) IA__FcUtf16Len FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcUtf16Len IA__FcUtf16Len +extern __typeof (FcStrBuildFilename) IA__FcStrBuildFilename FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrBuildFilename IA__FcStrBuildFilename +extern __typeof (FcStrDirname) IA__FcStrDirname FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrDirname IA__FcStrDirname +extern __typeof (FcStrBasename) IA__FcStrBasename FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrBasename IA__FcStrBasename +extern __typeof (FcStrSetCreate) IA__FcStrSetCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrSetCreate IA__FcStrSetCreate +extern __typeof (FcStrSetMember) IA__FcStrSetMember FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrSetMember IA__FcStrSetMember +extern __typeof (FcStrSetEqual) IA__FcStrSetEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrSetEqual IA__FcStrSetEqual +extern __typeof (FcStrSetAdd) IA__FcStrSetAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrSetAdd IA__FcStrSetAdd +extern __typeof (FcStrSetAddFilename) IA__FcStrSetAddFilename FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrSetAddFilename IA__FcStrSetAddFilename +extern __typeof (FcStrSetDel) IA__FcStrSetDel FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrSetDel IA__FcStrSetDel +extern __typeof (FcStrSetDestroy) IA__FcStrSetDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrSetDestroy IA__FcStrSetDestroy +extern __typeof (FcStrListCreate) IA__FcStrListCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrListCreate IA__FcStrListCreate +extern __typeof (FcStrListFirst) IA__FcStrListFirst FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrListFirst IA__FcStrListFirst +extern __typeof (FcStrListNext) IA__FcStrListNext FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrListNext IA__FcStrListNext +extern __typeof (FcStrListDone) IA__FcStrListDone FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcStrListDone IA__FcStrListDone +extern __typeof (FcConfigParseAndLoad) IA__FcConfigParseAndLoad FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigParseAndLoad IA__FcConfigParseAndLoad +extern __typeof (FcConfigParseAndLoadFromMemory) IA__FcConfigParseAndLoadFromMemory FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigParseAndLoadFromMemory IA__FcConfigParseAndLoadFromMemory +extern __typeof (FcConfigFileGenerate) IA__FcConfigFileGenerate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigFileGenerate IA__FcConfigFileGenerate +extern __typeof (FcConfigGetRescanInverval) IA__FcConfigGetRescanInverval FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigGetRescanInverval IA__FcConfigGetRescanInverval +extern __typeof (FcConfigSetRescanInverval) IA__FcConfigSetRescanInverval FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigSetRescanInverval IA__FcConfigSetRescanInverval diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/src/fcaliastail.h b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcaliastail.h new file mode 100644 index 00000000..45902930 --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcaliastail.h @@ -0,0 +1,528 @@ +#if HAVE_GNUC_ATTRIBUTE +#ifdef __fccfg__ +# undef FcBlanksCreate +extern __typeof (FcBlanksCreate) FcBlanksCreate __attribute((alias("IA__FcBlanksCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcBlanksDestroy +extern __typeof (FcBlanksDestroy) FcBlanksDestroy __attribute((alias("IA__FcBlanksDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcBlanksAdd +extern __typeof (FcBlanksAdd) FcBlanksAdd __attribute((alias("IA__FcBlanksAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcBlanksIsMember +extern __typeof (FcBlanksIsMember) FcBlanksIsMember __attribute((alias("IA__FcBlanksIsMember"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fccfg__ */ +#ifdef __fccache__ +# undef FcCacheCopySet +extern __typeof (FcCacheCopySet) FcCacheCopySet __attribute((alias("IA__FcCacheCopySet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCacheNumSubdir +extern __typeof (FcCacheNumSubdir) FcCacheNumSubdir __attribute((alias("IA__FcCacheNumSubdir"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCacheNumFont +extern __typeof (FcCacheNumFont) FcCacheNumFont __attribute((alias("IA__FcCacheNumFont"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcDirCacheUnlink +extern __typeof (FcDirCacheUnlink) FcDirCacheUnlink __attribute((alias("IA__FcDirCacheUnlink"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcDirCacheValid +extern __typeof (FcDirCacheValid) FcDirCacheValid __attribute((alias("IA__FcDirCacheValid"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcDirCacheClean +extern __typeof (FcDirCacheClean) FcDirCacheClean __attribute((alias("IA__FcDirCacheClean"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCacheCreateTagFile +extern __typeof (FcCacheCreateTagFile) FcCacheCreateTagFile __attribute((alias("IA__FcCacheCreateTagFile"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcDirCacheCreateUUID +extern __typeof (FcDirCacheCreateUUID) FcDirCacheCreateUUID __attribute((alias("IA__FcDirCacheCreateUUID"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcDirCacheDeleteUUID +extern __typeof (FcDirCacheDeleteUUID) FcDirCacheDeleteUUID __attribute((alias("IA__FcDirCacheDeleteUUID"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fccache__ */ +#ifdef __fccfg__ +# undef FcConfigHome +extern __typeof (FcConfigHome) FcConfigHome __attribute((alias("IA__FcConfigHome"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigEnableHome +extern __typeof (FcConfigEnableHome) FcConfigEnableHome __attribute((alias("IA__FcConfigEnableHome"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetFilename +extern __typeof (FcConfigGetFilename) FcConfigGetFilename __attribute((alias("IA__FcConfigGetFilename"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigFilename +extern __typeof (FcConfigFilename) FcConfigFilename __attribute((alias("IA__FcConfigFilename"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigCreate +extern __typeof (FcConfigCreate) FcConfigCreate __attribute((alias("IA__FcConfigCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigReference +extern __typeof (FcConfigReference) FcConfigReference __attribute((alias("IA__FcConfigReference"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigDestroy +extern __typeof (FcConfigDestroy) FcConfigDestroy __attribute((alias("IA__FcConfigDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigSetCurrent +extern __typeof (FcConfigSetCurrent) FcConfigSetCurrent __attribute((alias("IA__FcConfigSetCurrent"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetCurrent +extern __typeof (FcConfigGetCurrent) FcConfigGetCurrent __attribute((alias("IA__FcConfigGetCurrent"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigUptoDate +extern __typeof (FcConfigUptoDate) FcConfigUptoDate __attribute((alias("IA__FcConfigUptoDate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigBuildFonts +extern __typeof (FcConfigBuildFonts) FcConfigBuildFonts __attribute((alias("IA__FcConfigBuildFonts"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetFontDirs +extern __typeof (FcConfigGetFontDirs) FcConfigGetFontDirs __attribute((alias("IA__FcConfigGetFontDirs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetConfigDirs +extern __typeof (FcConfigGetConfigDirs) FcConfigGetConfigDirs __attribute((alias("IA__FcConfigGetConfigDirs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetConfigFiles +extern __typeof (FcConfigGetConfigFiles) FcConfigGetConfigFiles __attribute((alias("IA__FcConfigGetConfigFiles"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetCache +extern __typeof (FcConfigGetCache) FcConfigGetCache __attribute((alias("IA__FcConfigGetCache"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetBlanks +extern __typeof (FcConfigGetBlanks) FcConfigGetBlanks __attribute((alias("IA__FcConfigGetBlanks"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetCacheDirs +extern __typeof (FcConfigGetCacheDirs) FcConfigGetCacheDirs __attribute((alias("IA__FcConfigGetCacheDirs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetRescanInterval +extern __typeof (FcConfigGetRescanInterval) FcConfigGetRescanInterval __attribute((alias("IA__FcConfigGetRescanInterval"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigSetRescanInterval +extern __typeof (FcConfigSetRescanInterval) FcConfigSetRescanInterval __attribute((alias("IA__FcConfigSetRescanInterval"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetFonts +extern __typeof (FcConfigGetFonts) FcConfigGetFonts __attribute((alias("IA__FcConfigGetFonts"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigAcceptFont +extern __typeof (FcConfigAcceptFont) FcConfigAcceptFont __attribute((alias("IA__FcConfigAcceptFont"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigAcceptFilename +extern __typeof (FcConfigAcceptFilename) FcConfigAcceptFilename __attribute((alias("IA__FcConfigAcceptFilename"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigAcceptFilter +extern __typeof (FcConfigAcceptFilter) FcConfigAcceptFilter __attribute((alias("IA__FcConfigAcceptFilter"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigAppFontAddFile +extern __typeof (FcConfigAppFontAddFile) FcConfigAppFontAddFile __attribute((alias("IA__FcConfigAppFontAddFile"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigAppFontAddDir +extern __typeof (FcConfigAppFontAddDir) FcConfigAppFontAddDir __attribute((alias("IA__FcConfigAppFontAddDir"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigAppFontClear +extern __typeof (FcConfigAppFontClear) FcConfigAppFontClear __attribute((alias("IA__FcConfigAppFontClear"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigPreferAppFont +extern __typeof (FcConfigPreferAppFont) FcConfigPreferAppFont __attribute((alias("IA__FcConfigPreferAppFont"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigSetWarningFlags +extern __typeof (FcConfigSetWarningFlags) FcConfigSetWarningFlags __attribute((alias("IA__FcConfigSetWarningFlags"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetWarningFlags +extern __typeof (FcConfigGetWarningFlags) FcConfigGetWarningFlags __attribute((alias("IA__FcConfigGetWarningFlags"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigSubstituteWithPat +extern __typeof (FcConfigSubstituteWithPat) FcConfigSubstituteWithPat __attribute((alias("IA__FcConfigSubstituteWithPat"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigSubstitute +extern __typeof (FcConfigSubstitute) FcConfigSubstitute __attribute((alias("IA__FcConfigSubstitute"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigGetSysRoot +extern __typeof (FcConfigGetSysRoot) FcConfigGetSysRoot __attribute((alias("IA__FcConfigGetSysRoot"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigSetSysRoot +extern __typeof (FcConfigSetSysRoot) FcConfigSetSysRoot __attribute((alias("IA__FcConfigSetSysRoot"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigSetFontSetFilter +extern __typeof (FcConfigSetFontSetFilter) FcConfigSetFontSetFilter __attribute((alias("IA__FcConfigSetFontSetFilter"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigFileInfoIterInit +extern __typeof (FcConfigFileInfoIterInit) FcConfigFileInfoIterInit __attribute((alias("IA__FcConfigFileInfoIterInit"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigFileInfoIterNext +extern __typeof (FcConfigFileInfoIterNext) FcConfigFileInfoIterNext __attribute((alias("IA__FcConfigFileInfoIterNext"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigFileInfoIterGet +extern __typeof (FcConfigFileInfoIterGet) FcConfigFileInfoIterGet __attribute((alias("IA__FcConfigFileInfoIterGet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fccfg__ */ +#ifdef __fccharset__ +# undef FcCharSetCreate +extern __typeof (FcCharSetCreate) FcCharSetCreate __attribute((alias("IA__FcCharSetCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetNew +extern __typeof (FcCharSetNew) FcCharSetNew __attribute((alias("IA__FcCharSetNew"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetDestroy +extern __typeof (FcCharSetDestroy) FcCharSetDestroy __attribute((alias("IA__FcCharSetDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetAddChar +extern __typeof (FcCharSetAddChar) FcCharSetAddChar __attribute((alias("IA__FcCharSetAddChar"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetDelChar +extern __typeof (FcCharSetDelChar) FcCharSetDelChar __attribute((alias("IA__FcCharSetDelChar"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetCopy +extern __typeof (FcCharSetCopy) FcCharSetCopy __attribute((alias("IA__FcCharSetCopy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetEqual +extern __typeof (FcCharSetEqual) FcCharSetEqual __attribute((alias("IA__FcCharSetEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetIntersect +extern __typeof (FcCharSetIntersect) FcCharSetIntersect __attribute((alias("IA__FcCharSetIntersect"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetUnion +extern __typeof (FcCharSetUnion) FcCharSetUnion __attribute((alias("IA__FcCharSetUnion"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetSubtract +extern __typeof (FcCharSetSubtract) FcCharSetSubtract __attribute((alias("IA__FcCharSetSubtract"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetMerge +extern __typeof (FcCharSetMerge) FcCharSetMerge __attribute((alias("IA__FcCharSetMerge"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetHasChar +extern __typeof (FcCharSetHasChar) FcCharSetHasChar __attribute((alias("IA__FcCharSetHasChar"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetCount +extern __typeof (FcCharSetCount) FcCharSetCount __attribute((alias("IA__FcCharSetCount"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetIntersectCount +extern __typeof (FcCharSetIntersectCount) FcCharSetIntersectCount __attribute((alias("IA__FcCharSetIntersectCount"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetSubtractCount +extern __typeof (FcCharSetSubtractCount) FcCharSetSubtractCount __attribute((alias("IA__FcCharSetSubtractCount"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetIsSubset +extern __typeof (FcCharSetIsSubset) FcCharSetIsSubset __attribute((alias("IA__FcCharSetIsSubset"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetFirstPage +extern __typeof (FcCharSetFirstPage) FcCharSetFirstPage __attribute((alias("IA__FcCharSetFirstPage"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetNextPage +extern __typeof (FcCharSetNextPage) FcCharSetNextPage __attribute((alias("IA__FcCharSetNextPage"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcCharSetCoverage +extern __typeof (FcCharSetCoverage) FcCharSetCoverage __attribute((alias("IA__FcCharSetCoverage"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fccharset__ */ +#ifdef __fcdbg__ +# undef FcValuePrint +extern __typeof (FcValuePrint) FcValuePrint __attribute((alias("IA__FcValuePrint"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternPrint +extern __typeof (FcPatternPrint) FcPatternPrint __attribute((alias("IA__FcPatternPrint"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFontSetPrint +extern __typeof (FcFontSetPrint) FcFontSetPrint __attribute((alias("IA__FcFontSetPrint"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcdbg__ */ +#ifdef __fcdefault__ +# undef FcConfigGetDefaultLangs +extern __typeof (FcConfigGetDefaultLangs) FcConfigGetDefaultLangs __attribute((alias("IA__FcConfigGetDefaultLangs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcGetDefaultLangs +extern __typeof (FcGetDefaultLangs) FcGetDefaultLangs __attribute((alias("IA__FcGetDefaultLangs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigSetDefaultSubstitute +extern __typeof (FcConfigSetDefaultSubstitute) FcConfigSetDefaultSubstitute __attribute((alias("IA__FcConfigSetDefaultSubstitute"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcDefaultSubstitute +extern __typeof (FcDefaultSubstitute) FcDefaultSubstitute __attribute((alias("IA__FcDefaultSubstitute"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcdefault__ */ +#ifdef __fcdir__ +# undef FcFileIsDir +extern __typeof (FcFileIsDir) FcFileIsDir __attribute((alias("IA__FcFileIsDir"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFileScan +extern __typeof (FcFileScan) FcFileScan __attribute((alias("IA__FcFileScan"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcDirScan +extern __typeof (FcDirScan) FcDirScan __attribute((alias("IA__FcDirScan"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcDirSave +extern __typeof (FcDirSave) FcDirSave __attribute((alias("IA__FcDirSave"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcdir__ */ +#ifdef __fccache__ +# undef FcDirCacheLoad +extern __typeof (FcDirCacheLoad) FcDirCacheLoad __attribute((alias("IA__FcDirCacheLoad"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fccache__ */ +#ifdef __fcdir__ +# undef FcDirCacheRescan +extern __typeof (FcDirCacheRescan) FcDirCacheRescan __attribute((alias("IA__FcDirCacheRescan"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcDirCacheRead +extern __typeof (FcDirCacheRead) FcDirCacheRead __attribute((alias("IA__FcDirCacheRead"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcdir__ */ +#ifdef __fccache__ +# undef FcDirCacheLoadFile +extern __typeof (FcDirCacheLoadFile) FcDirCacheLoadFile __attribute((alias("IA__FcDirCacheLoadFile"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcDirCacheUnload +extern __typeof (FcDirCacheUnload) FcDirCacheUnload __attribute((alias("IA__FcDirCacheUnload"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fccache__ */ +#ifdef __fcfs__ +# undef FcFontSetCreate +extern __typeof (FcFontSetCreate) FcFontSetCreate __attribute((alias("IA__FcFontSetCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFontSetDestroy +extern __typeof (FcFontSetDestroy) FcFontSetDestroy __attribute((alias("IA__FcFontSetDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFontSetAdd +extern __typeof (FcFontSetAdd) FcFontSetAdd __attribute((alias("IA__FcFontSetAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcfs__ */ +#ifdef __fcinit__ +# undef FcInitLoadConfig +extern __typeof (FcInitLoadConfig) FcInitLoadConfig __attribute((alias("IA__FcInitLoadConfig"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcInitLoadConfigAndFonts +extern __typeof (FcInitLoadConfigAndFonts) FcInitLoadConfigAndFonts __attribute((alias("IA__FcInitLoadConfigAndFonts"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcInit +extern __typeof (FcInit) FcInit __attribute((alias("IA__FcInit"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFini +extern __typeof (FcFini) FcFini __attribute((alias("IA__FcFini"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcGetVersion +extern __typeof (FcGetVersion) FcGetVersion __attribute((alias("IA__FcGetVersion"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcInitReinitialize +extern __typeof (FcInitReinitialize) FcInitReinitialize __attribute((alias("IA__FcInitReinitialize"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcInitBringUptoDate +extern __typeof (FcInitBringUptoDate) FcInitBringUptoDate __attribute((alias("IA__FcInitBringUptoDate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcinit__ */ +#ifdef __fclang__ +# undef FcGetLangs +extern __typeof (FcGetLangs) FcGetLangs __attribute((alias("IA__FcGetLangs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangNormalize +extern __typeof (FcLangNormalize) FcLangNormalize __attribute((alias("IA__FcLangNormalize"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangGetCharSet +extern __typeof (FcLangGetCharSet) FcLangGetCharSet __attribute((alias("IA__FcLangGetCharSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetCreate +extern __typeof (FcLangSetCreate) FcLangSetCreate __attribute((alias("IA__FcLangSetCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetDestroy +extern __typeof (FcLangSetDestroy) FcLangSetDestroy __attribute((alias("IA__FcLangSetDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetCopy +extern __typeof (FcLangSetCopy) FcLangSetCopy __attribute((alias("IA__FcLangSetCopy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetAdd +extern __typeof (FcLangSetAdd) FcLangSetAdd __attribute((alias("IA__FcLangSetAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetDel +extern __typeof (FcLangSetDel) FcLangSetDel __attribute((alias("IA__FcLangSetDel"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetHasLang +extern __typeof (FcLangSetHasLang) FcLangSetHasLang __attribute((alias("IA__FcLangSetHasLang"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetCompare +extern __typeof (FcLangSetCompare) FcLangSetCompare __attribute((alias("IA__FcLangSetCompare"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetContains +extern __typeof (FcLangSetContains) FcLangSetContains __attribute((alias("IA__FcLangSetContains"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetEqual +extern __typeof (FcLangSetEqual) FcLangSetEqual __attribute((alias("IA__FcLangSetEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetHash +extern __typeof (FcLangSetHash) FcLangSetHash __attribute((alias("IA__FcLangSetHash"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetGetLangs +extern __typeof (FcLangSetGetLangs) FcLangSetGetLangs __attribute((alias("IA__FcLangSetGetLangs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetUnion +extern __typeof (FcLangSetUnion) FcLangSetUnion __attribute((alias("IA__FcLangSetUnion"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcLangSetSubtract +extern __typeof (FcLangSetSubtract) FcLangSetSubtract __attribute((alias("IA__FcLangSetSubtract"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fclang__ */ +#ifdef __fclist__ +# undef FcObjectSetCreate +extern __typeof (FcObjectSetCreate) FcObjectSetCreate __attribute((alias("IA__FcObjectSetCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcObjectSetAdd +extern __typeof (FcObjectSetAdd) FcObjectSetAdd __attribute((alias("IA__FcObjectSetAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcObjectSetDestroy +extern __typeof (FcObjectSetDestroy) FcObjectSetDestroy __attribute((alias("IA__FcObjectSetDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcObjectSetVaBuild +extern __typeof (FcObjectSetVaBuild) FcObjectSetVaBuild __attribute((alias("IA__FcObjectSetVaBuild"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcObjectSetBuild +extern __typeof (FcObjectSetBuild) FcObjectSetBuild __attribute((alias("IA__FcObjectSetBuild"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFontSetList +extern __typeof (FcFontSetList) FcFontSetList __attribute((alias("IA__FcFontSetList"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFontList +extern __typeof (FcFontList) FcFontList __attribute((alias("IA__FcFontList"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fclist__ */ +#ifdef __fcatomic__ +# undef FcAtomicCreate +extern __typeof (FcAtomicCreate) FcAtomicCreate __attribute((alias("IA__FcAtomicCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcAtomicLock +extern __typeof (FcAtomicLock) FcAtomicLock __attribute((alias("IA__FcAtomicLock"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcAtomicNewFile +extern __typeof (FcAtomicNewFile) FcAtomicNewFile __attribute((alias("IA__FcAtomicNewFile"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcAtomicOrigFile +extern __typeof (FcAtomicOrigFile) FcAtomicOrigFile __attribute((alias("IA__FcAtomicOrigFile"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcAtomicReplaceOrig +extern __typeof (FcAtomicReplaceOrig) FcAtomicReplaceOrig __attribute((alias("IA__FcAtomicReplaceOrig"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcAtomicDeleteNew +extern __typeof (FcAtomicDeleteNew) FcAtomicDeleteNew __attribute((alias("IA__FcAtomicDeleteNew"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcAtomicUnlock +extern __typeof (FcAtomicUnlock) FcAtomicUnlock __attribute((alias("IA__FcAtomicUnlock"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcAtomicDestroy +extern __typeof (FcAtomicDestroy) FcAtomicDestroy __attribute((alias("IA__FcAtomicDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcatomic__ */ +#ifdef __fcmatch__ +# undef FcFontSetMatch +extern __typeof (FcFontSetMatch) FcFontSetMatch __attribute((alias("IA__FcFontSetMatch"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFontMatch +extern __typeof (FcFontMatch) FcFontMatch __attribute((alias("IA__FcFontMatch"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFontRenderPrepare +extern __typeof (FcFontRenderPrepare) FcFontRenderPrepare __attribute((alias("IA__FcFontRenderPrepare"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFontSetSort +extern __typeof (FcFontSetSort) FcFontSetSort __attribute((alias("IA__FcFontSetSort"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFontSort +extern __typeof (FcFontSort) FcFontSort __attribute((alias("IA__FcFontSort"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFontSetSortDestroy +extern __typeof (FcFontSetSortDestroy) FcFontSetSortDestroy __attribute((alias("IA__FcFontSetSortDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcmatch__ */ +#ifdef __fcmatrix__ +# undef FcMatrixCopy +extern __typeof (FcMatrixCopy) FcMatrixCopy __attribute((alias("IA__FcMatrixCopy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcMatrixEqual +extern __typeof (FcMatrixEqual) FcMatrixEqual __attribute((alias("IA__FcMatrixEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcMatrixMultiply +extern __typeof (FcMatrixMultiply) FcMatrixMultiply __attribute((alias("IA__FcMatrixMultiply"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcMatrixRotate +extern __typeof (FcMatrixRotate) FcMatrixRotate __attribute((alias("IA__FcMatrixRotate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcMatrixScale +extern __typeof (FcMatrixScale) FcMatrixScale __attribute((alias("IA__FcMatrixScale"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcMatrixShear +extern __typeof (FcMatrixShear) FcMatrixShear __attribute((alias("IA__FcMatrixShear"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcmatrix__ */ +#ifdef __fcname__ +# undef FcNameRegisterObjectTypes +extern __typeof (FcNameRegisterObjectTypes) FcNameRegisterObjectTypes __attribute((alias("IA__FcNameRegisterObjectTypes"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcNameUnregisterObjectTypes +extern __typeof (FcNameUnregisterObjectTypes) FcNameUnregisterObjectTypes __attribute((alias("IA__FcNameUnregisterObjectTypes"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcNameGetObjectType +extern __typeof (FcNameGetObjectType) FcNameGetObjectType __attribute((alias("IA__FcNameGetObjectType"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcNameRegisterConstants +extern __typeof (FcNameRegisterConstants) FcNameRegisterConstants __attribute((alias("IA__FcNameRegisterConstants"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcNameUnregisterConstants +extern __typeof (FcNameUnregisterConstants) FcNameUnregisterConstants __attribute((alias("IA__FcNameUnregisterConstants"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcNameGetConstant +extern __typeof (FcNameGetConstant) FcNameGetConstant __attribute((alias("IA__FcNameGetConstant"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcNameGetConstantFor +extern __typeof (FcNameGetConstantFor) FcNameGetConstantFor __attribute((alias("IA__FcNameGetConstantFor"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcNameConstant +extern __typeof (FcNameConstant) FcNameConstant __attribute((alias("IA__FcNameConstant"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcNameGetConstantNameFrom +extern __typeof (FcNameGetConstantNameFrom) FcNameGetConstantNameFrom __attribute((alias("IA__FcNameGetConstantNameFrom"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcNameParse +extern __typeof (FcNameParse) FcNameParse __attribute((alias("IA__FcNameParse"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcNameUnparse +extern __typeof (FcNameUnparse) FcNameUnparse __attribute((alias("IA__FcNameUnparse"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcname__ */ +#ifdef __fcpat__ +# undef FcPatternCreate +extern __typeof (FcPatternCreate) FcPatternCreate __attribute((alias("IA__FcPatternCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternDuplicate +extern __typeof (FcPatternDuplicate) FcPatternDuplicate __attribute((alias("IA__FcPatternDuplicate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternReference +extern __typeof (FcPatternReference) FcPatternReference __attribute((alias("IA__FcPatternReference"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternFilter +extern __typeof (FcPatternFilter) FcPatternFilter __attribute((alias("IA__FcPatternFilter"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcValueDestroy +extern __typeof (FcValueDestroy) FcValueDestroy __attribute((alias("IA__FcValueDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcValueEqual +extern __typeof (FcValueEqual) FcValueEqual __attribute((alias("IA__FcValueEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcValueSave +extern __typeof (FcValueSave) FcValueSave __attribute((alias("IA__FcValueSave"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternDestroy +extern __typeof (FcPatternDestroy) FcPatternDestroy __attribute((alias("IA__FcPatternDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternObjectCount +extern __typeof (FcPatternObjectCount) FcPatternObjectCount __attribute((alias("IA__FcPatternObjectCount"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternEqual +extern __typeof (FcPatternEqual) FcPatternEqual __attribute((alias("IA__FcPatternEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternEqualSubset +extern __typeof (FcPatternEqualSubset) FcPatternEqualSubset __attribute((alias("IA__FcPatternEqualSubset"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternHash +extern __typeof (FcPatternHash) FcPatternHash __attribute((alias("IA__FcPatternHash"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternAdd +extern __typeof (FcPatternAdd) FcPatternAdd __attribute((alias("IA__FcPatternAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternAddWeak +extern __typeof (FcPatternAddWeak) FcPatternAddWeak __attribute((alias("IA__FcPatternAddWeak"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternGet +extern __typeof (FcPatternGet) FcPatternGet __attribute((alias("IA__FcPatternGet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternGetWithBinding +extern __typeof (FcPatternGetWithBinding) FcPatternGetWithBinding __attribute((alias("IA__FcPatternGetWithBinding"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternDel +extern __typeof (FcPatternDel) FcPatternDel __attribute((alias("IA__FcPatternDel"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternRemove +extern __typeof (FcPatternRemove) FcPatternRemove __attribute((alias("IA__FcPatternRemove"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternAddInteger +extern __typeof (FcPatternAddInteger) FcPatternAddInteger __attribute((alias("IA__FcPatternAddInteger"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternAddDouble +extern __typeof (FcPatternAddDouble) FcPatternAddDouble __attribute((alias("IA__FcPatternAddDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternAddString +extern __typeof (FcPatternAddString) FcPatternAddString __attribute((alias("IA__FcPatternAddString"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternAddMatrix +extern __typeof (FcPatternAddMatrix) FcPatternAddMatrix __attribute((alias("IA__FcPatternAddMatrix"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternAddCharSet +extern __typeof (FcPatternAddCharSet) FcPatternAddCharSet __attribute((alias("IA__FcPatternAddCharSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternAddBool +extern __typeof (FcPatternAddBool) FcPatternAddBool __attribute((alias("IA__FcPatternAddBool"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternAddLangSet +extern __typeof (FcPatternAddLangSet) FcPatternAddLangSet __attribute((alias("IA__FcPatternAddLangSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternAddRange +extern __typeof (FcPatternAddRange) FcPatternAddRange __attribute((alias("IA__FcPatternAddRange"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternGetInteger +extern __typeof (FcPatternGetInteger) FcPatternGetInteger __attribute((alias("IA__FcPatternGetInteger"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternGetDouble +extern __typeof (FcPatternGetDouble) FcPatternGetDouble __attribute((alias("IA__FcPatternGetDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternGetString +extern __typeof (FcPatternGetString) FcPatternGetString __attribute((alias("IA__FcPatternGetString"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternGetMatrix +extern __typeof (FcPatternGetMatrix) FcPatternGetMatrix __attribute((alias("IA__FcPatternGetMatrix"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternGetCharSet +extern __typeof (FcPatternGetCharSet) FcPatternGetCharSet __attribute((alias("IA__FcPatternGetCharSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternGetBool +extern __typeof (FcPatternGetBool) FcPatternGetBool __attribute((alias("IA__FcPatternGetBool"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternGetLangSet +extern __typeof (FcPatternGetLangSet) FcPatternGetLangSet __attribute((alias("IA__FcPatternGetLangSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternGetRange +extern __typeof (FcPatternGetRange) FcPatternGetRange __attribute((alias("IA__FcPatternGetRange"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternVaBuild +extern __typeof (FcPatternVaBuild) FcPatternVaBuild __attribute((alias("IA__FcPatternVaBuild"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternBuild +extern __typeof (FcPatternBuild) FcPatternBuild __attribute((alias("IA__FcPatternBuild"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcpat__ */ +#ifdef __fcformat__ +# undef FcPatternFormat +extern __typeof (FcPatternFormat) FcPatternFormat __attribute((alias("IA__FcPatternFormat"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcformat__ */ +#ifdef __fcrange__ +# undef FcRangeCreateDouble +extern __typeof (FcRangeCreateDouble) FcRangeCreateDouble __attribute((alias("IA__FcRangeCreateDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcRangeCreateInteger +extern __typeof (FcRangeCreateInteger) FcRangeCreateInteger __attribute((alias("IA__FcRangeCreateInteger"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcRangeDestroy +extern __typeof (FcRangeDestroy) FcRangeDestroy __attribute((alias("IA__FcRangeDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcRangeCopy +extern __typeof (FcRangeCopy) FcRangeCopy __attribute((alias("IA__FcRangeCopy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcRangeGetDouble +extern __typeof (FcRangeGetDouble) FcRangeGetDouble __attribute((alias("IA__FcRangeGetDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcrange__ */ +#ifdef __fcpat__ +# undef FcPatternIterStart +extern __typeof (FcPatternIterStart) FcPatternIterStart __attribute((alias("IA__FcPatternIterStart"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternIterNext +extern __typeof (FcPatternIterNext) FcPatternIterNext __attribute((alias("IA__FcPatternIterNext"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternIterEqual +extern __typeof (FcPatternIterEqual) FcPatternIterEqual __attribute((alias("IA__FcPatternIterEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternFindIter +extern __typeof (FcPatternFindIter) FcPatternFindIter __attribute((alias("IA__FcPatternFindIter"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternIterIsValid +extern __typeof (FcPatternIterIsValid) FcPatternIterIsValid __attribute((alias("IA__FcPatternIterIsValid"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternIterGetObject +extern __typeof (FcPatternIterGetObject) FcPatternIterGetObject __attribute((alias("IA__FcPatternIterGetObject"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternIterValueCount +extern __typeof (FcPatternIterValueCount) FcPatternIterValueCount __attribute((alias("IA__FcPatternIterValueCount"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternIterGetValue +extern __typeof (FcPatternIterGetValue) FcPatternIterGetValue __attribute((alias("IA__FcPatternIterGetValue"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcpat__ */ +#ifdef __fcweight__ +# undef FcWeightFromOpenType +extern __typeof (FcWeightFromOpenType) FcWeightFromOpenType __attribute((alias("IA__FcWeightFromOpenType"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcWeightFromOpenTypeDouble +extern __typeof (FcWeightFromOpenTypeDouble) FcWeightFromOpenTypeDouble __attribute((alias("IA__FcWeightFromOpenTypeDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcWeightToOpenType +extern __typeof (FcWeightToOpenType) FcWeightToOpenType __attribute((alias("IA__FcWeightToOpenType"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcWeightToOpenTypeDouble +extern __typeof (FcWeightToOpenTypeDouble) FcWeightToOpenTypeDouble __attribute((alias("IA__FcWeightToOpenTypeDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcweight__ */ +#ifdef __fcstr__ +# undef FcStrCopy +extern __typeof (FcStrCopy) FcStrCopy __attribute((alias("IA__FcStrCopy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrCopyFilename +extern __typeof (FcStrCopyFilename) FcStrCopyFilename __attribute((alias("IA__FcStrCopyFilename"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrPlus +extern __typeof (FcStrPlus) FcStrPlus __attribute((alias("IA__FcStrPlus"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrFree +extern __typeof (FcStrFree) FcStrFree __attribute((alias("IA__FcStrFree"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrDowncase +extern __typeof (FcStrDowncase) FcStrDowncase __attribute((alias("IA__FcStrDowncase"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrCmpIgnoreCase +extern __typeof (FcStrCmpIgnoreCase) FcStrCmpIgnoreCase __attribute((alias("IA__FcStrCmpIgnoreCase"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrCmp +extern __typeof (FcStrCmp) FcStrCmp __attribute((alias("IA__FcStrCmp"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrStrIgnoreCase +extern __typeof (FcStrStrIgnoreCase) FcStrStrIgnoreCase __attribute((alias("IA__FcStrStrIgnoreCase"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrStr +extern __typeof (FcStrStr) FcStrStr __attribute((alias("IA__FcStrStr"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcUtf8ToUcs4 +extern __typeof (FcUtf8ToUcs4) FcUtf8ToUcs4 __attribute((alias("IA__FcUtf8ToUcs4"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcUtf8Len +extern __typeof (FcUtf8Len) FcUtf8Len __attribute((alias("IA__FcUtf8Len"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcUcs4ToUtf8 +extern __typeof (FcUcs4ToUtf8) FcUcs4ToUtf8 __attribute((alias("IA__FcUcs4ToUtf8"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcUtf16ToUcs4 +extern __typeof (FcUtf16ToUcs4) FcUtf16ToUcs4 __attribute((alias("IA__FcUtf16ToUcs4"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcUtf16Len +extern __typeof (FcUtf16Len) FcUtf16Len __attribute((alias("IA__FcUtf16Len"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrBuildFilename +extern __typeof (FcStrBuildFilename) FcStrBuildFilename __attribute((alias("IA__FcStrBuildFilename"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrDirname +extern __typeof (FcStrDirname) FcStrDirname __attribute((alias("IA__FcStrDirname"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrBasename +extern __typeof (FcStrBasename) FcStrBasename __attribute((alias("IA__FcStrBasename"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrSetCreate +extern __typeof (FcStrSetCreate) FcStrSetCreate __attribute((alias("IA__FcStrSetCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrSetMember +extern __typeof (FcStrSetMember) FcStrSetMember __attribute((alias("IA__FcStrSetMember"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrSetEqual +extern __typeof (FcStrSetEqual) FcStrSetEqual __attribute((alias("IA__FcStrSetEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrSetAdd +extern __typeof (FcStrSetAdd) FcStrSetAdd __attribute((alias("IA__FcStrSetAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrSetAddFilename +extern __typeof (FcStrSetAddFilename) FcStrSetAddFilename __attribute((alias("IA__FcStrSetAddFilename"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrSetDel +extern __typeof (FcStrSetDel) FcStrSetDel __attribute((alias("IA__FcStrSetDel"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrSetDestroy +extern __typeof (FcStrSetDestroy) FcStrSetDestroy __attribute((alias("IA__FcStrSetDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrListCreate +extern __typeof (FcStrListCreate) FcStrListCreate __attribute((alias("IA__FcStrListCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrListFirst +extern __typeof (FcStrListFirst) FcStrListFirst __attribute((alias("IA__FcStrListFirst"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrListNext +extern __typeof (FcStrListNext) FcStrListNext __attribute((alias("IA__FcStrListNext"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcStrListDone +extern __typeof (FcStrListDone) FcStrListDone __attribute((alias("IA__FcStrListDone"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcstr__ */ +#ifdef __fcxml__ +# undef FcConfigParseAndLoad +extern __typeof (FcConfigParseAndLoad) FcConfigParseAndLoad __attribute((alias("IA__FcConfigParseAndLoad"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigParseAndLoadFromMemory +extern __typeof (FcConfigParseAndLoadFromMemory) FcConfigParseAndLoadFromMemory __attribute((alias("IA__FcConfigParseAndLoadFromMemory"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcxml__ */ +#ifdef __fcconffile__ +# undef FcConfigFileGenerate +extern __typeof (FcConfigFileGenerate) FcConfigFileGenerate __attribute((alias("IA__FcConfigFileGenerate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcconffile__ */ +#ifdef __fccfg__ +# undef FcConfigGetRescanInverval +extern __typeof (FcConfigGetRescanInverval) FcConfigGetRescanInverval __attribute((alias("IA__FcConfigGetRescanInverval"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcConfigSetRescanInverval +extern __typeof (FcConfigSetRescanInverval) FcConfigSetRescanInverval __attribute((alias("IA__FcConfigSetRescanInverval"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* */ +#endif /* HAVE_GNUC_ATTRIBUTE */ diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/src/fcftalias.h b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcftalias.h new file mode 100644 index 00000000..4af6a68d --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcftalias.h @@ -0,0 +1,16 @@ +extern __typeof (FcFreeTypeCharIndex) IA__FcFreeTypeCharIndex FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFreeTypeCharIndex IA__FcFreeTypeCharIndex +extern __typeof (FcFreeTypeCharSetAndSpacing) IA__FcFreeTypeCharSetAndSpacing FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFreeTypeCharSetAndSpacing IA__FcFreeTypeCharSetAndSpacing +extern __typeof (FcFreeTypeCharSet) IA__FcFreeTypeCharSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFreeTypeCharSet IA__FcFreeTypeCharSet +extern __typeof (FcPatternGetFTFace) IA__FcPatternGetFTFace FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternGetFTFace IA__FcPatternGetFTFace +extern __typeof (FcPatternAddFTFace) IA__FcPatternAddFTFace FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcPatternAddFTFace IA__FcPatternAddFTFace +extern __typeof (FcFreeTypeQueryFace) IA__FcFreeTypeQueryFace FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFreeTypeQueryFace IA__FcFreeTypeQueryFace +extern __typeof (FcFreeTypeQuery) IA__FcFreeTypeQuery FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFreeTypeQuery IA__FcFreeTypeQuery +extern __typeof (FcFreeTypeQueryAll) IA__FcFreeTypeQueryAll FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFreeTypeQueryAll IA__FcFreeTypeQueryAll diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/src/fcftaliastail.h b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcftaliastail.h new file mode 100644 index 00000000..299416ed --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcftaliastail.h @@ -0,0 +1,24 @@ +#if HAVE_GNUC_ATTRIBUTE +#ifdef __fcfreetype__ +# undef FcFreeTypeCharIndex +extern __typeof (FcFreeTypeCharIndex) FcFreeTypeCharIndex __attribute((alias("IA__FcFreeTypeCharIndex"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFreeTypeCharSetAndSpacing +extern __typeof (FcFreeTypeCharSetAndSpacing) FcFreeTypeCharSetAndSpacing __attribute((alias("IA__FcFreeTypeCharSetAndSpacing"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFreeTypeCharSet +extern __typeof (FcFreeTypeCharSet) FcFreeTypeCharSet __attribute((alias("IA__FcFreeTypeCharSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcfreetype__ */ +#ifdef __fcpat__ +# undef FcPatternGetFTFace +extern __typeof (FcPatternGetFTFace) FcPatternGetFTFace __attribute((alias("IA__FcPatternGetFTFace"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcPatternAddFTFace +extern __typeof (FcPatternAddFTFace) FcPatternAddFTFace __attribute((alias("IA__FcPatternAddFTFace"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcpat__ */ +#ifdef __fcfreetype__ +# undef FcFreeTypeQueryFace +extern __typeof (FcFreeTypeQueryFace) FcFreeTypeQueryFace __attribute((alias("IA__FcFreeTypeQueryFace"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFreeTypeQuery +extern __typeof (FcFreeTypeQuery) FcFreeTypeQuery __attribute((alias("IA__FcFreeTypeQuery"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFreeTypeQueryAll +extern __typeof (FcFreeTypeQueryAll) FcFreeTypeQueryAll __attribute((alias("IA__FcFreeTypeQueryAll"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* */ +#endif /* HAVE_GNUC_ATTRIBUTE */ diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/src/fcint.h b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcint.h new file mode 100644 index 00000000..00f70533 --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcint.h @@ -0,0 +1,1752 @@ +/* + * fontconfig/src/fcint.h + * + * Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _FCINT_H_ +#define _FCINT_H_ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "fcstdint.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#include + +#if ENABLE_FONTATIONS +# include +#endif + +#include +#include +#include +#include + +#ifdef HAVE_XLOCALE_H +#include +#endif + +#include "fcatomic.h" +#include "fcdeprecate.h" +#include "fcmutex.h" + +#ifndef FC_CONFIG_PATH +# define FC_CONFIG_PATH "fonts.conf" +#endif + +#ifdef _WIN32 +# define FC_LIKELY(expr) (expr) +# define FC_UNLIKELY(expr) (expr) +#else +# define FC_LIKELY(expr) (__builtin_expect (((expr) ? 1 : 0), 1)) +# define FC_UNLIKELY(expr) (__builtin_expect (((expr) ? 1 : 0), 0)) +#endif + +#ifdef _WIN32 +# include "fcwindows.h" +typedef UINT (WINAPI *pfnGetSystemWindowsDirectory) (LPSTR, UINT); +typedef HRESULT (WINAPI *pfnSHGetFolderPathA) (HWND, int, HANDLE, DWORD, LPSTR); +extern pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory; +extern pfnSHGetFolderPathA pSHGetFolderPathA; +# define FC_SEARCH_PATH_SEPARATOR ';' +# define FC_DIR_SEPARATOR '\\' +# define FC_DIR_SEPARATOR_S "\\" +#else +# define FC_SEARCH_PATH_SEPARATOR ':' +# define FC_DIR_SEPARATOR '/' +# define FC_DIR_SEPARATOR_S "/" +#endif + +#ifdef PATH_MAX +# define FC_PATH_MAX PATH_MAX +#else +# define FC_PATH_MAX 128 +#endif + +#if __GNUC__ >= 4 +# define FC_UNUSED __attribute__ ((unused)) +#else +# define FC_UNUSED +#endif + +#ifndef FC_UINT64_FORMAT +# define FC_UINT64_FORMAT "llu" +#endif + +#define FC_DBG_MATCH 1 +#define FC_DBG_MATCHV 2 +#define FC_DBG_EDIT 4 +#define FC_DBG_FONTSET 8 +#define FC_DBG_CACHE 16 +#define FC_DBG_CACHEV 32 +#define FC_DBG_PARSE 64 +#define FC_DBG_SCAN 128 +#define FC_DBG_SCANV 256 +#define FC_DBG_CONFIG 1024 +#define FC_DBG_LANGSET 2048 +#define FC_DBG_MATCH2 4096 + +#define _FC_ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond) ? 1 : -1] FC_UNUSED +#define _FC_ASSERT_STATIC0(_line, _cond) _FC_ASSERT_STATIC1 (_line, (_cond)) +#define FC_ASSERT_STATIC(_cond) _FC_ASSERT_STATIC0 (__LINE__, (_cond)) + +#define FC_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define FC_MAX(a, b) ((a) > (b) ? (a) : (b)) + +/* slim_internal.h */ +#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun) && !defined(BINDGEN_IGNORE_VISIBILITY) +# define FcPrivate __attribute__ ((__visibility__ ("hidden"))) +# define HAVE_GNUC_ATTRIBUTE 1 +# include "fcalias.h" +#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) +# define FcPrivate __hidden +#else /* not gcc >= 3.3 and not Sun Studio >= 8 */ +# define FcPrivate +#endif + +/* NLS */ +#ifdef ENABLE_NLS +# include +# define _(x) (dgettext (GETTEXT_PACKAGE, x)) +#else +/* dgettext macro must be defined after existing declarations */ +# include +# define dgettext(d, s) (s) +# define _(x) (x) +#endif + +#define N_(x) x + +FC_ASSERT_STATIC (sizeof (FcRef) == sizeof (int)); + +#define FcFree(s) (free ((FcChar8 *)(s))) + +/* + * Serialized data structures use only offsets instead of pointers + * A low bit of 1 indicates an offset. + */ + +/* Is the provided pointer actually an offset? */ +#define FcIsEncodedOffset(p) ((((uintptr_t)(p)) & 1) != 0) + +/* Encode offset in a pointer of type t */ +#define FcOffsetEncode(o, t) ((t *)(uintptr_t)((o) | 1)) + +/* Decode a pointer into an offset */ +#define FcOffsetDecode(p) (((uintptr_t)(p)) & ~1) + +/* Compute pointer offset */ +#define FcPtrToOffset(b, p) ((ptrdiff_t)((uintptr_t)(p) - (uintptr_t)(b))) + +/* Given base address, offset and type, return a pointer */ +#define FcOffsetToPtr(b, o, t) ((t *)((uintptr_t)(b) + (ptrdiff_t)(o))) + +/* Given base address, encoded offset and type, return a pointer */ +#define FcEncodedOffsetToPtr(b, p, t) FcOffsetToPtr (b, FcOffsetDecode (p), t) + +/* Given base address, pointer and type, return an encoded offset */ +#define FcPtrToEncodedOffset(b, p, t) FcOffsetEncode (FcPtrToOffset (b, p), t) + +/* Given a structure, offset member and type, return pointer */ +#define FcOffsetMember(s, m, t) FcOffsetToPtr (s, (s)->m, t) + +/* Given a structure, encoded offset member and type, return pointer to member */ +#define FcEncodedOffsetMember(s, m, t) FcOffsetToPtr (s, FcOffsetDecode ((s)->m), t) + +/* Given a structure, member and type, convert the member to a pointer */ +#define FcPointerMember(s, m, t) (FcIsEncodedOffset ((s)->m) ? FcEncodedOffsetMember (s, m, t) : (s)->m) + +/* + * Serialized values may hold strings, charsets and langsets as pointers, + * unfortunately FcValue is an exposed type so we can't just always use + * offsets + */ +#define FcValueString(v) FcPointerMember (v, u.s, FcChar8) +#define FcValueCharSet(v) FcPointerMember (v, u.c, const FcCharSet) +#define FcValueLangSet(v) FcPointerMember (v, u.l, const FcLangSet) +#define FcValueRange(v) FcPointerMember (v, u.r, const FcRange) + +typedef struct _FcValueList *FcValueListPtr; + +typedef struct _FcValueList { + struct _FcValueList *next; + FcValue value; + FcValueBinding binding; +} FcValueList; + +#define FcValueListNext(vl) FcPointerMember (vl, next, FcValueList) + +/* The 1024 is to leave some room for future added internal objects, such + * that caches from newer fontconfig can still be used with older fontconfig + * without getting confused. */ +#define FC_EXT_OBJ_INDEX 1024 +#define FC_OBJ_ID(_n_) ((_n_) & (~FC_EXT_OBJ_INDEX)) + +typedef struct _FcPatternElt *FcPatternEltPtr; + +/* + * Pattern elts are stuck in a structure connected to the pattern, + * so they get moved around when the pattern is resized. Hence, the + * values field must be a pointer/offset instead of just an offset + */ +typedef struct _FcPatternElt { + FcObject object; + FcValueList *values; +} FcPatternElt; + +#define FcPatternEltValues(pe) FcPointerMember (pe, values, FcValueList) + +struct _FcPattern { + int num; + int size; + intptr_t elts_offset; + FcRef ref; +}; + +#define FcPatternElts(p) FcOffsetMember (p, elts_offset, FcPatternElt) + +#define FcFontSetFonts(fs) FcPointerMember (fs, fonts, FcPattern *) + +#define FcFontSetFont(fs, i) (FcIsEncodedOffset ((fs)->fonts) ? FcEncodedOffsetToPtr (fs, \ + FcFontSetFonts (fs)[i], \ + FcPattern) \ + : fs->fonts[i]) + +typedef enum _FcOp { + FcOpInteger, + FcOpDouble, + FcOpString, + FcOpMatrix, + FcOpRange, + FcOpBool, + FcOpCharSet, + FcOpLangSet, + FcOpNil, + FcOpField, + FcOpConst, + FcOpAssign, + FcOpAssignReplace, + FcOpPrependFirst, + FcOpPrepend, + FcOpAppend, + FcOpAppendLast, + FcOpDelete, + FcOpDeleteAll, + FcOpQuest, + FcOpOr, + FcOpAnd, + FcOpEqual, + FcOpNotEqual, + FcOpContains, + FcOpListing, + FcOpNotContains, + FcOpLess, + FcOpLessEqual, + FcOpMore, + FcOpMoreEqual, + FcOpPlus, + FcOpMinus, + FcOpTimes, + FcOpDivide, + FcOpNot, + FcOpComma, + FcOpFloor, + FcOpCeil, + FcOpRound, + FcOpTrunc, + FcOpInvalid +} FcOp; + +typedef enum _FcOpFlags { + FcOpFlagIgnoreBlanks = 1U << 0 +} FcOpFlags; + +#define FC_OP_GET_OP(_x_) ((_x_) & 0xffff) +#define FC_OP_GET_FLAGS(_x_) (((_x_) & 0xffff0000) >> 16) +#define FC_OP(_x_, _f_) (FC_OP_GET_OP (_x_) | ((_f_) << 16)) + +typedef struct _FcExprMatrix { + struct _FcExpr *xx, *xy, *yx, *yy; +} FcExprMatrix; + +typedef struct _FcExprName { + FcObject object; + FcMatchKind kind; +} FcExprName; + +struct _FcRange { + double begin; + double end; +}; + +typedef struct _FcExpr { + FcOp op; + union { + int ival; + double dval; + const FcChar8 *sval; + FcExprMatrix *mexpr; + FcBool bval; + FcCharSet *cval; + FcLangSet *lval; + FcRange *rval; + + FcExprName name; + const FcChar8 *constant; + struct { + struct _FcExpr *left, *right; + } tree; + } u; +} FcExpr; + +typedef struct _FcExprPage FcExprPage; + +struct _FcExprPage { + FcExprPage *next_page; + FcExpr *next; + FcExpr exprs[(1024 - 2 /* two pointers */ - 2 /* malloc overhead */) * sizeof (void *) / sizeof (FcExpr)]; + FcExpr end[FLEXIBLE_ARRAY_MEMBER]; +}; + +typedef enum _FcQual { + FcQualAny, + FcQualAll, + FcQualFirst, + FcQualNotFirst +} FcQual; + +#define FcMatchDefault ((FcMatchKind) - 1) + +typedef struct _FcTest { + FcMatchKind kind; + FcQual qual; + FcObject object; + FcOp op; + FcExpr *expr; +} FcTest; + +typedef struct _FcEdit { + FcObject object; + FcOp op; + FcExpr *expr; + FcValueBinding binding; +} FcEdit; + +typedef struct _FcPtrList FcPtrList; +/* need to sync with FcConfigFileInfoIter at fontconfig.h */ +typedef struct _FcPtrListIter { + void *dummy1; + void *dummy2; + void *dummy3; +} FcPtrListIter; + +typedef enum _FcRuleType { + FcRuleUnknown, + FcRuleTest, + FcRuleEdit +} FcRuleType; + +typedef struct _FcRule { + struct _FcRule *next; + FcRuleType type; + union { + FcTest *test; + FcEdit *edit; + } u; +} FcRule; + +typedef struct _FcRuleSet { + FcRef ref; + FcChar8 *name; + FcChar8 *description; + FcChar8 *domain; + FcBool enabled; + FcPtrList *subst[FcMatchKindEnd]; +} FcRuleSet; + +typedef struct _FcCharLeaf { + FcChar32 map[256 / 32]; +} FcCharLeaf; + +struct _FcCharSet { + FcRef ref; /* reference count */ + int num; /* size of leaves and numbers arrays */ + intptr_t leaves_offset; + intptr_t numbers_offset; +}; + +#define FcCharSetLeaves(c) FcOffsetMember (c, leaves_offset, intptr_t) +#define FcCharSetLeaf(c, i) (FcOffsetToPtr (FcCharSetLeaves (c), \ + FcCharSetLeaves (c)[i], \ + FcCharLeaf)) +#define FcCharSetNumbers(c) FcOffsetMember (c, numbers_offset, FcChar16) + +#define FCSS_DEFAULT 0 /* default behavior */ +#define FCSS_ALLOW_DUPLICATES 1 /* allows for duplicate strings in the set */ +#define FCSS_GROW_BY_64 2 /* grows buffer by 64 elements instead of 1 */ + +#define FcStrSetHasControlBit(s, c) (s->control & c) +#define FcStrSetHasControlBits(s, c) ((c) == (s->control & (c))) + +struct _FcStrSet { + FcRef ref; /* reference count */ + int num; + int size; + FcChar8 **strs; + unsigned int control; /* control bits for set behavior */ +}; + +struct _FcStrList { + FcStrSet *set; + int n; +}; + +typedef struct _FcStrBuf { + FcChar8 *buf; + FcBool allocated; + FcBool failed; + int len; + int size; + FcChar8 buf_static[16 * sizeof (void *)]; +} FcStrBuf; + +typedef struct _FcHashTable FcHashTable; + +typedef FcChar32 (*FcHashFunc) (const FcChar8 *data); +typedef int (*FcCompareFunc) (const FcChar8 *v1, const FcChar8 *v2); +typedef FcBool (*FcCopyFunc) (const void *src, void **dest); + +struct _FcCache { + unsigned int magic; /* FC_CACHE_MAGIC_MMAP or FC_CACHE_ALLOC */ + int version; /* FC_CACHE_VERSION_NUMBER */ + intptr_t size; /* size of file */ + intptr_t dir; /* offset to dir name */ + intptr_t dirs; /* offset to subdirs */ + int dirs_count; /* number of subdir strings */ + int pad1; + intptr_t set; /* offset to font set */ + int checksum; /* checksum of directory state */ + int pad2; + int64_t checksum_nano; /* checksum of directory state */ + int64_t fc_version; /* fontconfig version */ +}; + +#undef FcCacheDir +#undef FcCacheSubdir +#define FcCacheDir(c) FcOffsetMember (c, dir, FcChar8) +#define FcCacheDirs(c) FcOffsetMember (c, dirs, intptr_t) +#define FcCacheSet(c) FcOffsetMember (c, set, FcFontSet) +#define FcCacheSubdir(c, i) FcOffsetToPtr (FcCacheDirs (c), \ + FcCacheDirs (c)[i], \ + FcChar8) + +/* + * Used while constructing a directory cache object + */ + +typedef union _FcAlign { + double d; + int i; + intptr_t ip; + FcBool b; + void *p; +} FcAlign; + +typedef struct _FcSerializeBucket { + const void *object; /* key */ + uintptr_t hash; /* hash of key */ + intptr_t offset; /* value */ +} FcSerializeBucket; + +typedef struct _FcCharSetFreezer FcCharSetFreezer; + +typedef struct _FcSerialize { + intptr_t size; + FcCharSetFreezer *cs_freezer; + void *linear; + FcSerializeBucket *buckets; + size_t buckets_count; + size_t buckets_used; + size_t buckets_used_max; +} FcSerialize; + +/* + * To map adobe glyph names to unicode values, a precomputed hash + * table is used + */ + +typedef struct _FcGlyphName { + FcChar32 ucs; /* unicode value */ + FcChar8 name[1]; /* name extends beyond struct */ +} FcGlyphName; + +/* + * To perform case-insensitive string comparisons, a table + * is used which holds three different kinds of folding data. + * + * The first is a range of upper case values mapping to a range + * of their lower case equivalents. Within each range, the offset + * between upper and lower case is constant. + * + * The second is a range of upper case values which are interleaved + * with their lower case equivalents. + * + * The third is a set of raw unicode values mapping to a list + * of unicode values for comparison purposes. This allows conversion + * of ß to "ss" so that SS, ss and ß all match. A separate array + * holds the list of unicode values for each entry. + * + * These are packed into a single table. Using a binary search, + * the appropriate entry can be located. + */ + +#define FC_CASE_FOLD_RANGE 0 +#define FC_CASE_FOLD_EVEN_ODD 1 +#define FC_CASE_FOLD_FULL 2 + +typedef struct _FcCaseFold { + FcChar32 upper; + FcChar16 method : 2; + FcChar16 count : 14; + short offset; /* lower - upper for RANGE, table id for FULL */ +} FcCaseFold; + +#define FC_MAX_FILE_LEN 4096 + +#define FC_CACHE_MAGIC_MMAP 0xFC02FC04 +#define FC_CACHE_MAGIC_ALLOC 0xFC02FC05 + +struct _FcAtomic { + FcChar8 *file; /* original file name */ + FcChar8 *new; /* temp file name -- write data here */ + FcChar8 *lck; /* lockfile name (used for locking) */ + FcChar8 *tmp; /* tmpfile name (used for locking) */ +}; + +struct _FcConfig { + /* + * File names loaded from the configuration -- saved here as the + * cache file must be consulted before the directories are scanned, + * and those directives may occur in any order + */ + FcStrSet *configDirs; /* directories to scan for fonts */ + /* + * List of directories containing fonts, + * built by recursively scanning the set + * of configured directories + */ + FcStrSet *fontDirs; + /* + * List of directories containing cache files. + */ + FcStrSet *cacheDirs; + /* + * Names of all of the configuration files used + * to create this configuration + */ + FcStrSet *configFiles; /* config files loaded */ + /* + * Substitution instructions for patterns and fonts; + * maxObjects is used to allocate appropriate intermediate storage + * while performing a whole set of substitutions + * + * 0.. substitutions for patterns + * 1.. substitutions for fonts + * 2.. substitutions for scanned fonts + */ + FcPtrList *subst[FcMatchKindEnd]; + int maxObjects; /* maximum number of tests in all substs */ + /* + * List of patterns used to control font file selection + */ + FcStrSet *acceptGlobs; + FcStrSet *rejectGlobs; + FcFontSet *acceptPatterns; + FcFontSet *rejectPatterns; + /* + * The set of fonts loaded from the listed directories; the + * order within the set does not determine the font selection, + * except in the case of identical matches in which case earlier fonts + * match preferrentially + */ + FcFontSet *fonts[FcSetApplication + 1]; + /* + * Fontconfig can periodically rescan the system configuration + * and font directories. This rescanning occurs when font + * listing requests are made, but no more often than rescanInterval + * seconds apart. + */ + time_t rescanTime; /* last time information was scanned */ + int rescanInterval; /* interval between scans */ + + FcRef ref; /* reference count */ + + FcExprPage *expr_pool; /* pool of FcExpr's */ + + FcChar8 *sysRoot; /* override the system root directory */ + FcStrSet *availConfigFiles; /* config files available */ + FcPtrList *rulesetList; /* List of rulesets being installed */ + + FcFilterFontSetFunc filter_func; /* A predicate function to filter out config->fonts */ + FcDestroyFunc destroy_data_func; /* A callback function to destroy config->filter_data */ + void *filter_data; /* An user data to be used for filter_func */ + + FcBool prefer_app_fonts; /* Whether FcSetApplication has a priority than + FcSetSystem for lookup */ + + FcChar8 *default_lang; /* Primary language in default_langs */ + FcStrSet *default_langs; /* String sets of the default languages */ + FcChar8 *prgname; /* Program name of current process */ + FcChar8 *desktop_name; /* Current desktop name */ + + int warns; /* Bitfield of warning flags (FC_WARN_*) controlling which warnings to emit */ +}; + +typedef struct _FcFileTime { + time_t time; + FcBool set; +} FcFileTime; + +typedef struct _FcCharMap FcCharMap; + +typedef struct _FcStatFS FcStatFS; + +struct _FcStatFS { + FcBool is_remote_fs; + FcBool is_mtime_broken; +}; + +typedef struct _FcValuePromotionBuffer FcValuePromotionBuffer; + +struct _FcValuePromotionBuffer { + union { + double d; + int i; + long l; + char c[256]; /* Enlarge as needed */ + } u; +}; + +#ifdef _WIN32 +typedef _locale_t FcLocale; +typedef enum _FcLocaleMask { + FC_LC_CTYPE = LC_CTYPE, + FC_LC_NUMERIC = LC_NUMERIC, + FC_LC_TIME = LC_TIME, + FC_LC_COLLATE = LC_COLLATE, + FC_LC_MONETARY = LC_MONETARY, + FC_LC_MESSAGES = LC_ALL, /* not available */ + FC_LC_PAPER = LC_ALL, + FC_LC_NAME = LC_ALL, + FC_LC_ADDRESS = LC_ALL, + FC_LC_TELEPHONE = LC_ALL, + FC_LC_MEASUREMENT = LC_ALL, + FC_LC_IDENTIFICATION = LC_ALL, + FC_LC_ALL = LC_ALL, +} FcLocaleMask; +#else +typedef locale_t FcLocale; +typedef enum _FcLocaleMask { + FC_LC_CTYPE = LC_CTYPE_MASK, + FC_LC_NUMERIC = LC_NUMERIC_MASK, + FC_LC_TIME = LC_TIME_MASK, + FC_LC_COLLATE = LC_COLLATE_MASK, + FC_LC_MONETARY = LC_MONETARY_MASK, + FC_LC_MESSAGES = LC_MESSAGES_MASK, +#ifdef LC_PAPER_MASK + FC_LC_PAPER = LC_PAPER_MASK, +#else + FC_LC_PAPER = LC_ALL_MASK, +#endif +#ifdef LC_NAME_MASK + FC_LC_NAME = LC_NAME_MASK, +#else + FC_LC_NAME = LC_ALL_MASK, +#endif +#ifdef LC_ADDRESS_MASK + FC_LC_ADDRESS = LC_ADDRESS_MASK, +#else + FC_LC_ADDRESS = LC_ALL_MASK, +#endif +#ifdef LC_TELEPHONE_MASK + FC_LC_TELEPHONE = LC_TELEPHONE_MASK, +#else + FC_LC_TELEPHONE = LC_ALL_MASK, +#endif +#ifdef LC_MEASUREMENT_MASK + FC_LC_MEASUREMENT = LC_MEASUREMENT_MASK, +#else + FC_LC_MEASUREMENT = LC_ALL_MASK, +#endif +#ifdef LC_IDENTIFICATION_MASK + FC_LC_IDENTIFICATION = LC_IDENTIFICATION_MASK, +#else + FC_LC_IDENTIFICATION = LC_ALL_MASK, +#endif + FC_LC_ALL = LC_ALL_MASK, +} FcLocaleMask; +#endif + +/* fccache.c */ + +FcPrivate FcCache * +FcDirCacheScan (const FcChar8 *dir, FcConfig *config); + +FcPrivate FcCache * +FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcStrSet *dirs); + +FcPrivate FcCache * +FcDirCacheRebuild (FcCache *cache, struct stat *dir_stat, FcStrSet *dirs); + +FcPrivate FcBool +FcDirCacheWrite (FcCache *cache, FcConfig *config); + +FcPrivate FcBool +FcDirCacheCreateTagFile (const FcChar8 *cache_dir); + +FcPrivate void +FcCacheObjectReference (void *object); + +FcPrivate void +FcCacheObjectDereference (void *object); + +FcPrivate void * +FcCacheAllocate (FcCache *cache, size_t len); + +FcPrivate void +FcCacheFini (void); + +FcPrivate void +FcDirCacheReference (FcCache *cache, int nref); + +FcPrivate int +FcDirCacheLock (const FcChar8 *dir, + FcConfig *config); + +FcPrivate void +FcDirCacheUnlock (int fd); + +/* fccfg.c */ + +FcPrivate FcBool +FcConfigInit (void); + +FcPrivate void +FcConfigFini (void); + +FcPrivate FcChar8 * +FcConfigXdgCacheHome (void); + +FcPrivate FcChar8 * +FcConfigXdgConfigHome (void); + +FcPrivate FcChar8 * +FcConfigXdgDataHome (void); + +FcPrivate FcStrSet * +FcConfigXdgDataDirs (void); + +FcPrivate FcExpr * +FcConfigAllocExpr (FcConfig *config); + +FcPrivate FcBool +FcConfigAddConfigDir (FcConfig *config, + const FcChar8 *d); + +FcPrivate FcBool +FcConfigAddFontDir (FcConfig *config, + const FcChar8 *d, + const FcChar8 *m, + const FcChar8 *salt); + +FcPrivate FcBool +FcConfigResetFontDirs (FcConfig *config); + +FcPrivate FcChar8 * +FcConfigMapFontPath (FcConfig *config, + const FcChar8 *path); + +FcPrivate const FcChar8 * +FcConfigMapSalt (FcConfig *config, + const FcChar8 *path); + +FcPrivate FcBool +FcConfigAddCacheDir (FcConfig *config, + const FcChar8 *d); + +FcPrivate FcBool +FcConfigAddConfigFile (FcConfig *config, + const FcChar8 *f); + +FcPrivate FcBool +FcConfigAddBlank (FcConfig *config, + FcChar32 blank); + +FcBool +FcConfigAddRule (FcConfig *config, + FcRule *rule, + FcMatchKind kind); + +FcPrivate void +FcConfigSetFonts (FcConfig *config, + FcFontSet *fonts, + FcSetName set); + +FcPrivate FcBool +FcConfigCompareValue (const FcValue *m, + unsigned int op_, + const FcValue *v); + +FcPrivate FcBool +FcConfigGlobAdd (FcConfig *config, + const FcChar8 *glob, + FcBool accept); + +FcPrivate FcBool +FcConfigPatternsAdd (FcConfig *config, + FcPattern *pattern, + FcBool accept); + +FcPrivate FcFileTime +FcConfigModifiedTime (FcConfig *config); + +FcPrivate FcBool +FcConfigAddCache (FcConfig *config, FcCache *cache, + FcSetName set, FcStrSet *dirSet, FcChar8 *forDir); + +FcPrivate FcRuleSet * +FcRuleSetCreate (const FcChar8 *name); + +FcPrivate void +FcRuleSetDestroy (FcRuleSet *rs); + +FcPrivate void +FcRuleSetReference (FcRuleSet *rs); + +FcPrivate void +FcRuleSetEnable (FcRuleSet *rs, + FcBool flag); + +FcPrivate void +FcRuleSetAddDescription (FcRuleSet *rs, + const FcChar8 *domain, + const FcChar8 *description); + +FcPrivate int +FcRuleSetAdd (FcRuleSet *rs, + FcRule *rule, + FcMatchKind kind); + +/* fcserialize.c */ +FcPrivate intptr_t +FcAlignSize (intptr_t size); + +FcPrivate FcSerialize * +FcSerializeCreate (void); + +FcPrivate void +FcSerializeDestroy (FcSerialize *serialize); + +FcPrivate FcBool +FcSerializeAlloc (FcSerialize *serialize, const void *object, int size); + +FcPrivate intptr_t +FcSerializeReserve (FcSerialize *serialize, int size); + +FcPrivate intptr_t +FcSerializeOffset (FcSerialize *serialize, const void *object); + +FcPrivate void * +FcSerializePtr (FcSerialize *serialize, const void *object); + +FcPrivate FcBool +FcLangSetSerializeAlloc (FcSerialize *serialize, const FcLangSet *l); + +FcPrivate FcLangSet * +FcLangSetSerialize (FcSerialize *serialize, const FcLangSet *l); + +/* fccharset.c */ +FcPrivate FcCharSet * +FcCharSetPromote (FcValuePromotionBuffer *vbuf); + +FcPrivate void +FcLangCharSetPopulate (void); + +FcPrivate FcBool +FcLangIsExclusive (const FcChar8 *lang); + +FcPrivate const FcChar8 * +FcLangIsExclusiveFromOs2 (unsigned long os2ulUnicodeRange1, unsigned long os2ulUnicodeRange2); + +FcPrivate FcCharSetFreezer * +FcCharSetFreezerCreate (void); + +FcPrivate const FcCharSet * +FcCharSetFreeze (FcCharSetFreezer *freezer, const FcCharSet *fcs); + +FcPrivate void +FcCharSetFreezerDestroy (FcCharSetFreezer *freezer); + +FcPrivate FcBool +FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c); + +FcPrivate FcCharSet * +FcNameParseCharSet (FcChar8 *string); + +FcPrivate FcBool +FcNameUnparseValue (FcStrBuf *buf, + FcValue *v0, + FcChar8 *escape); + +FcPrivate FcBool +FcNameUnparseValueList (FcStrBuf *buf, + FcValueListPtr v, + FcChar8 *escape); + +FcPrivate FcCharLeaf * +FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4); + +FcPrivate FcBool +FcCharSetSerializeAlloc (FcSerialize *serialize, const FcCharSet *cs); + +FcPrivate FcCharSet * +FcCharSetSerialize (FcSerialize *serialize, const FcCharSet *cs); + +FcPrivate FcChar16 * +FcCharSetGetNumbers (const FcCharSet *c); + +/* fccompat.c */ +FcPrivate int +FcOpen (const char *pathname, int flags, ...); + +FcPrivate int +FcMakeTempfile (char *template); + +FcPrivate int32_t +FcRandom (void); + +FcPrivate FcBool +FcMakeDirectory (const FcChar8 *dir); + +FcPrivate ssize_t +FcReadLink (const FcChar8 *pathname, + FcChar8 *buf, + size_t bufsiz); + +FcPrivate FcLocale +FcLocaleCreate (FcLocaleMask mask, const char *locale); + +#ifndef _WIN32 +FcPrivate FcLocale +FcLocaleSetCurrent (FcLocale loc); +#endif + +FcPrivate void +FcLocaleDestroy (FcLocale locale); + +/* fcconffile.c */ +#if HAVE_VASPRINTF_L +# define FcStrDupVapFormat(__ret__, __format__, __va__) \ + { \ + FcLocale loc = FcLocaleCreate (FC_LC_NUMERIC, "C"); \ + if (vasprintf_l (&(__ret__), loc, __format__, __va__) < 0) { \ + (__ret__) = NULL; \ + } \ + FcLocaleDestroy (loc); \ + } +#elif HAVE__VSNPRINTF_L +# define FcStrDupVapFormat(__ret__, __format__, __va__) \ + { \ + char FcStrDupVapFormat_c; \ + va_list FcStrDupVapFormat_va; \ + int FcStrDupVapFormat_size; \ + FcLocale loc = FcLocaleCreate (FC_LC_NUMERIC, "C"); \ + \ + (__ret__) = NULL; \ + va_copy (FcStrDupVapFormat_va, __va__); \ + FcStrDupVapFormat_size = vsnprintf (&FcStrDupVapFormat_c, 1, __format__, __va__) + 1; \ + va_end (FcStrDupVapFormat_va); \ + if (FcStrDupVapFormat_size > 0) { \ + (__ret__) = malloc (FcStrDupVapFormat_size); \ + if ((__ret__)) { \ + _vsnprintf_l ((__ret__), FcStrDupVapFormat_size, __format__, loc, __va__); \ + } \ + } \ + FcLocaleDestroy (loc); \ + } +#elif HAVE_VASPRINTF +# define FcStrDupVapFormat(__ret__, __format__, __va__) \ + { \ + FcLocale loc = FcLocaleCreate (FC_LC_NUMERIC, "C"); \ + FcLocale oldloc = FcLocaleSetCurrent (loc); \ + if (vasprintf (&(__ret__), __format__, __va__) < 0) { \ + (__ret__) = NULL; \ + } \ + FcLocaleSetCurrent (oldloc); \ + FcLocaleDestroy (loc); \ + } +#elif HAVE_C99_VSNPRINTF +# define FcStrDupVapFormat(__ret__, __format__, __va__) \ + { \ + char FcStrDupVapFormat_c; \ + va_list FcStrDupVapFormat_va; \ + int FcStrDupVapFormat_size; \ + FcLocale loc = FcLocaleCreate (FC_LC_NUMERIC, "C"); \ + FcLocale oldloc = FcLocaleSetCurrent (loc); \ + \ + (__ret__) = NULL; \ + va_copy (FcStrDupVapFormat_va, __va__); \ + FcStrDupVapFormat_size = vsnprintf (&FcStrDupVapFormat_c, 1, __format__, __va__) + 1; \ + va_end (FcStrDupVapFormat_va); \ + if (FcStrDupVapFormat_size > 0) { \ + (__ret__) = malloc (FcStrDupVapFormat_size); \ + if ((__ret__)) { \ + vsprintf ((__ret__), __format__, __va__); \ + } \ + } \ + FcLocaleSetCurrent (oldloc); \ + FcLocaleDestroy (loc); \ + } +#elif HAVE_VSNPRINTF +# define FcStrDupVapFormat(__ret__, __format__, __va__) \ + { \ + va_list FcStrDupVapFormat_va; \ + int FcStrDupVapFormat_size = 1024, FcStrDupVapFormat_n; \ + char *FcStrDupVapFormat_p; \ + FcLocale loc = FcLocaleCreate (FC_LC_NUMERIC, "C"); \ + FcLocale oldloc = FcLocaleSetCurrent (loc); \ + \ + (__ret__) = malloc (FcStrDupVapFormat_size); \ + if ((__ret__)) { \ + while (1) { \ + va_copy (FcStrDupVapFormat_va, __va__); \ + FcStrDupVapFormat_n = vsnprintf ((__ret__), FcStrDupVapFormat_size, __format__, FcStrDupVapFormat_va); \ + va_end (FcStrDupVapFormat_va); \ + if (FcStrDupVapFormat_n > -1 && \ + FcStrDupVapFormat_n < FcStrDupVapFormat_size) \ + break; \ + if (FcStrDupVapFormat_n > -1) \ + FcStrDupVapFormat_size = FcStrDupVapFormat_n + 1; \ + else \ + FcStrDupVapFormat_size *= 2; \ + FcStrDupVapFormat_p = realloc ((__ret__), FcStrDupVapFormat_size); \ + if (!FcStrDupVapFormat_p) { \ + free ((__ret__)); \ + (__ret__) = NULL; \ + break; \ + } \ + (__ret__) = FcStrDupVapFormat_p; \ + } \ + } \ + FcLocaleSetCurrent (oldloc); \ + FcLocaleDestroy (loc); \ + } +#else +# error no vsnprintf function implemented +#endif + +#define FcStrBufVapFormat(__ret__, __buf__, __format__, __va__) \ + { \ + char *FcStrBufVapFormat_p = NULL; \ + FcStrDupVapFormat (FcStrBufVapFormat_p, __format__, __va__); \ + if (!FcStrBufVapFormat_p) { \ + FcStrBufDestroy (__buf__); \ + (__ret__) = FcFalse; \ + } else { \ + FcStrBufString (__buf__, (const FcChar8 *)FcStrBufVapFormat_p); \ + free (FcStrBufVapFormat_p); \ + (__ret__) = FcTrue; \ + } \ + } + +/* fcdbg.c */ + +FcPrivate void +FcValuePrintFile (FILE *stream, const FcValue v); + +FcPrivate void +FcValuePrintFileWithPosition (FILE *stream, const FcValue v, FcBool show_pos_mark); + +FcPrivate void +FcValuePrintWithPosition (const FcValue v, FcBool show_pos_mark); + +FcPrivate void +FcValueListPrintFileWithPosition (FILE *stream, FcValueListPtr l, const FcValueListPtr pos); + +FcPrivate void +FcValueListPrintWithPosition (FcValueListPtr l, const FcValueListPtr pos); + +FcPrivate void +FcValueListPrintFile (FILE *stream, FcValueListPtr l); + +FcPrivate void +FcValueListPrint (FcValueListPtr l); + +FcPrivate void +FcLangSetPrintFile (FILE *stream, const FcLangSet *ls); + +FcPrivate void +FcLangSetPrint (const FcLangSet *ls); + +FcPrivate void +FcOpPrintFile (FILE *stream, FcOp op_); + +FcPrivate void +FcOpPrint (FcOp op); + +FcPrivate void +FcTestPrintFile (FILE *stream, const FcTest *test); + +FcPrivate void +FcTestPrint (const FcTest *test); + +FcPrivate void +FcExprPrintFile (FILE *stream, const FcExpr *expr); + +FcPrivate void +FcExprPrint (const FcExpr *expr); + +FcPrivate void +FcEditPrintFile (FILE *stream, const FcEdit *edit); + +FcPrivate void +FcEditPrint (const FcEdit *edit); + +FcPrivate void +FcRulePrintFile (FILE *stream, const FcRule *rule); + +FcPrivate void +FcRulePrint (const FcRule *rule); + +FcPrivate void +FcCharSetPrintFile (FILE *stream, const FcCharSet *c); + +FcPrivate void +FcCharSetPrint (const FcCharSet *c); + +FcPrivate void +FcPatternPrintFile (FILE *stream, const FcPattern *p); + +FcPrivate void +FcPatternPrint2File (FILE *stream, + FcPattern *pp1, + FcPattern *pp2, + const FcObjectSet *os); + +FcPrivate void +FcPatternPrint2 (FcPattern *p1, FcPattern *p2, const FcObjectSet *os); + +FcPrivate void +FcFontSetPrintFile (FILE *stream, const FcFontSet *s); + +extern FcPrivate int FcDebugVal; + +#define FcDebug() (FcDebugVal) + +FcPrivate void +FcInitDebug (void); + +/* fcdefault.c */ +FcPrivate FcChar8 * +FcConfigGetDefaultLang (FcConfig *config); + +FcPrivate FcChar8 * +FcGetDefaultLang (void); + +FcPrivate FcChar8 * +FcConfigGetPrgname (FcConfig *config); + +FcPrivate FcChar8 * +FcGetPrgname (void); + +FcPrivate FcChar8 * +FcConfigGetDesktopName (FcConfig *config); + +FcPrivate FcChar8 * +FcGetDesktopName (void); + +/* fcdir.c */ + +FcPrivate FcBool +FcFileIsLink (const FcChar8 *file); + +FcPrivate FcBool +FcFileIsFile (const FcChar8 *file); + +FcPrivate FcBool +FcFileScanConfig (FcFontSet *set, + FcStrSet *dirs, + const FcChar8 *file, + FcConfig *config); + +FcPrivate FcBool +FcDirScanConfig (FcFontSet *set, + FcStrSet *dirs, + const FcChar8 *dir, + FcBool force, + FcConfig *config); + +/* fcfont.c */ +FcPrivate int +FcFontDebug (void); + +/* fcfs.c */ + +FcPrivate FcBool +FcFontSetSerializeAlloc (FcSerialize *serialize, const FcFontSet *s); + +FcPrivate FcFontSet * +FcFontSetSerialize (FcSerialize *serialize, const FcFontSet *s); + +FcPrivate FcFontSet * +FcFontSetDeserialize (const FcFontSet *set); + +/* fcgenericalias.c */ +FcPrivate uint32_t +FcGenericAliasGetClassification (const char *family); + +/* fcplist.c */ +FcPrivate FcPtrList * +FcPtrListCreate (FcDestroyFunc func); + +FcPrivate void +FcPtrListDestroy (FcPtrList *list); + +FcPrivate void +FcPtrListIterInit (const FcPtrList *list, + FcPtrListIter *iter); + +FcPrivate void +FcPtrListIterInitAtLast (FcPtrList *list, + FcPtrListIter *iter); + +FcPrivate FcBool +FcPtrListIterNext (const FcPtrList *list, + FcPtrListIter *iter); + +FcPrivate FcBool +FcPtrListIterIsValid (const FcPtrList *list, + const FcPtrListIter *iter); + +FcPrivate void * +FcPtrListIterGetValue (const FcPtrList *list, + const FcPtrListIter *iter); + +FcPrivate FcBool +FcPtrListIterAdd (FcPtrList *list, + FcPtrListIter *iter, + void *data); + +FcPrivate FcBool +FcPtrListIterRemove (FcPtrList *list, + FcPtrListIter *iter); + +/* fcinit.c */ +FcPrivate FcConfig * +FcInitLoadOwnConfig (FcConfig *config); + +FcPrivate FcConfig * +FcInitLoadOwnConfigAndFonts (FcConfig *config); + +/* fcxml.c */ +FcPrivate void +FcConfigPathFini (void); + +FcPrivate void +FcTestDestroy (FcTest *test); + +FcPrivate void +FcEditDestroy (FcEdit *e); + +void +FcRuleDestroy (FcRule *rule); + +/* fclang.c */ +typedef struct { + const FcChar8 lang[16]; + const FcCharSet charset; +} FcLangCharSet; + +typedef struct { + int begin; + int end; +} FcLangCharSetRange; + +#include "fclang.h" + +struct _FcLangSet { + FcStrSet *extra; + FcChar32 map_size; + FcChar32 map[NUM_LANG_SET_MAP]; +}; + +FcPrivate FcLangSet * +FcLangSetFromCharSet (const FcCharSet *charset, + const FcChar8 *exclusiveLang); + +FcPrivate FcLangResult +FcLangCompare (const FcChar8 *s1, const FcChar8 *s2); + +FcPrivate FcLangSet * +FcLangSetPromote (const FcChar8 *lang, FcValuePromotionBuffer *buf); + +FcPrivate FcLangSet * +FcNameParseLangSet (const FcChar8 *string); + +FcPrivate FcBool +FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls); + +FcPrivate FcChar8 * +FcNameUnparseEscaped (FcPattern *pat, FcBool escape); + +FcPrivate FcBool +FcConfigParseOnly (FcConfig *config, + const FcChar8 *name, + FcBool complain); + +FcPrivate FcChar8 * +FcConfigRealFilename (FcConfig *config, + const FcChar8 *url); + +/* fclist.c */ + +FcPrivate FcBool +FcListPatternMatchAny (const FcPattern *p, + const FcPattern *font); + +/* fcmatch.c */ + +/* fcname.c */ + +enum { + FC_INVALID_OBJECT = 0, +#define FC_OBJECT(NAME, Type, Cmp) FC_##NAME##_OBJECT, +#include "fcobjs.h" +#undef FC_OBJECT + FC_ONE_AFTER_MAX_BASE_OBJECT +#define FC_MAX_BASE_OBJECT (FC_ONE_AFTER_MAX_BASE_OBJECT - 1) +}; + +FcPrivate FcBool +FcNameConstantWithObjectCheck (const FcChar8 *string, FcObject object, int *result); + +FcPrivate const FcChar8 * +FcNameGetConstantNameFromObject (FcObject object, int value); + +FcPrivate FcBool +FcNameBool (const FcChar8 *v, FcBool *result); + +FcPrivate FcBool +FcObjectValidType (FcObject object, FcType type); + +FcPrivate FcObject +FcObjectFromName (const char *name); + +FcPrivate const char * +FcObjectName (FcObject object); + +FcPrivate FcObjectSet * +FcObjectGetSet (void); + +#define FcObjectCompare(a, b) ((int)a - (int)b) + +/* fcpat.c */ + +FcPrivate FcValue +FcValueCanonicalize (const FcValue *v); + +FcPrivate FcValueListPtr +FcValueListCreate (void); + +FcPrivate void +FcValueListDestroy (FcValueListPtr l); + +FcPrivate FcValueListPtr +FcValueListPrepend (FcValueListPtr vallist, + FcValue value, + FcValueBinding binding); + +FcPrivate FcValueListPtr +FcValueListAppend (FcValueListPtr vallist, + FcValue value, + FcValueBinding binding); + +FcPrivate FcValueListPtr +FcValueListDuplicate (FcValueListPtr orig); + +FcPrivate FcPatternElt * +FcPatternObjectFindElt (const FcPattern *p, FcObject object); + +FcPrivate FcPatternElt * +FcPatternObjectInsertElt (FcPattern *p, FcObject object); + +FcPrivate FcBool +FcPatternObjectListAdd (FcPattern *p, + FcObject object, + FcValueListPtr list, + FcBool append); + +FcPrivate FcBool +FcPatternObjectAddWithBinding (FcPattern *p, + FcObject object, + FcValue value, + FcValueBinding binding, + FcBool append); + +FcPrivate FcBool +FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append); + +FcPrivate FcBool +FcPatternObjectAddWeak (FcPattern *p, FcObject object, FcValue value, FcBool append); + +FcPrivate FcResult +FcPatternObjectGetWithBinding (const FcPattern *p, FcObject object, int id, FcValue *v, FcValueBinding *b); + +FcPrivate FcResult +FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v); + +FcPrivate FcBool +FcPatternObjectDel (FcPattern *p, FcObject object); + +FcPrivate FcBool +FcPatternObjectRemove (FcPattern *p, FcObject object, int id); + +FcPrivate FcBool +FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i); + +FcPrivate FcBool +FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d); + +FcPrivate FcBool +FcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s); + +FcPrivate FcBool +FcPatternObjectAddMatrix (FcPattern *p, FcObject object, const FcMatrix *s); + +FcPrivate FcBool +FcPatternObjectAddCharSet (FcPattern *p, FcObject object, const FcCharSet *c); + +FcPrivate FcBool +FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b); + +FcPrivate FcBool +FcPatternObjectAddLangSet (FcPattern *p, FcObject object, const FcLangSet *ls); + +FcPrivate FcBool +FcPatternObjectAddRange (FcPattern *p, FcObject object, const FcRange *r); + +FcPrivate FcResult +FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int n, int *i); + +FcPrivate FcResult +FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int n, double *d); + +FcPrivate FcResult +FcPatternObjectGetString (const FcPattern *p, FcObject object, int n, FcChar8 **s); + +FcPrivate FcResult +FcPatternObjectGetMatrix (const FcPattern *p, FcObject object, int n, FcMatrix **s); + +FcPrivate FcResult +FcPatternObjectGetCharSet (const FcPattern *p, FcObject object, int n, FcCharSet **c); + +FcPrivate FcResult +FcPatternObjectGetBool (const FcPattern *p, FcObject object, int n, FcBool *b); + +FcPrivate FcResult +FcPatternObjectGetLangSet (const FcPattern *p, FcObject object, int n, FcLangSet **ls); + +FcPrivate FcResult +FcPatternObjectGetRange (const FcPattern *p, FcObject object, int id, FcRange **r); + +FcPrivate FcBool +FcPatternAppend (FcPattern *p, FcPattern *s); + +FcPrivate int +FcPatternPosition (const FcPattern *p, const char *object); + +FcPrivate FcBool +FcPatternFindObjectIter (const FcPattern *pat, FcPatternIter *iter, FcObject object); + +FcPrivate FcObject +FcPatternIterGetObjectId (const FcPattern *pat, FcPatternIter *iter); + +FcPrivate FcValueListPtr +FcPatternIterGetValues (const FcPattern *pat, FcPatternIter *iter); + +FcPrivate FcPattern * +FcPatternCacheRewriteFile (const FcPattern *pat, FcCache *cache, const FcChar8 *relocated_font_file); + +FcPrivate FcChar32 +FcStringHash (const FcChar8 *s); + +FcPrivate FcBool +FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat); + +FcPrivate FcPattern * +FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat); + +FcPrivate FcBool +FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *pat); + +FcPrivate FcValueList * +FcValueListSerialize (FcSerialize *serialize, const FcValueList *pat); + +/* fcrender.c */ + +/* fcmatrix.c */ + +extern FcPrivate const FcMatrix FcIdentityMatrix; + +FcPrivate void +FcMatrixFree (FcMatrix *mat); + +/* fcrange.c */ + +FcPrivate FcRange * +FcRangePromote (double v, FcValuePromotionBuffer *vbuf); + +FcPrivate FcBool +FcRangeIsInRange (const FcRange *a, const FcRange *b); + +FcPrivate FcBool +FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b); + +FcPrivate FcChar32 +FcRangeHash (const FcRange *r); + +FcPrivate FcBool +FcRangeSerializeAlloc (FcSerialize *serialize, const FcRange *r); + +FcPrivate FcRange * +FcRangeSerialize (FcSerialize *serialize, const FcRange *r); + +/* fcstat.c */ + +FcPrivate int +FcStat (const FcChar8 *file, struct stat *statb); + +FcPrivate int +FcStatChecksum (const FcChar8 *file, struct stat *statb); + +FcPrivate FcBool +FcIsFsMmapSafe (int fd); + +FcPrivate FcBool +FcIsFsMtimeBroken (const FcChar8 *dir); + +/* fcstr.c */ +FcPrivate double +FcStrtod (char *s, char **end); + +FcPrivate FcChar8 * +FcStrDupVaFormat (const char *format, va_list va); + +FcPrivate FcChar8 * +FcStrDupFormat (const char *format, ...); + +FcPrivate FcStrSet * +FcStrSetCreateEx (unsigned int control); + +FcPrivate FcBool +FcStrSetInsert (FcStrSet *set, const FcChar8 *s, int pos); + +FcPrivate FcBool +FcStrSetAddLangs (FcStrSet *strs, const char *languages); + +FcPrivate void +FcStrSetSort (FcStrSet *set); + +FcPrivate FcBool +FcStrSetMemberAB (FcStrSet *set, const FcChar8 *a, FcChar8 *b, FcChar8 **ret); + +FcPrivate FcBool +FcStrSetAddTriple (FcStrSet *set, const FcChar8 *a, const FcChar8 *b, const FcChar8 *c); + +FcPrivate const FcChar8 * +FcStrTripleSecond (FcChar8 *s); + +FcPrivate const FcChar8 * +FcStrTripleThird (FcChar8 *str); + +FcPrivate FcBool +FcStrSetAddFilenamePairWithSalt (FcStrSet *strs, const FcChar8 *d, const FcChar8 *m, const FcChar8 *salt); + +FcPrivate FcBool +FcStrSetDeleteAll (FcStrSet *set); + +FcPrivate void +FcStrBufInit (FcStrBuf *buf, FcChar8 *init, int size); + +FcPrivate void +FcStrBufDestroy (FcStrBuf *buf); + +FcPrivate FcChar8 * +FcStrBufDone (FcStrBuf *buf); + +FcPrivate FcChar8 * +FcStrBufDoneStatic (FcStrBuf *buf); + +FcPrivate FcBool +FcStrBufChar (FcStrBuf *buf, FcChar8 c); + +FcPrivate FcBool +FcStrBufString (FcStrBuf *buf, const FcChar8 *s); + +FcPrivate FcBool +FcStrBufVaFormat (FcStrBuf *buf, const char *format, va_list va); + +FcPrivate FcBool +FcStrBufFormat (FcStrBuf *buf, const char *format, ...); + +FcPrivate FcBool +FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len); + +FcPrivate int +FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); + +FcPrivate int +FcStrCmpIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims); + +FcPrivate const FcChar8 * +FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); + +FcPrivate const FcChar8 * +FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2); + +FcPrivate const FcChar8 * +FcStrContainsWord (const FcChar8 *s1, const FcChar8 *s2); + +FcPrivate int +FcStrMatchIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims); + +FcPrivate FcBool +FcStrGlobMatch (const FcChar8 *glob, + const FcChar8 *string); + +FcPrivate FcBool +FcStrUsesHome (const FcChar8 *s); + +FcPrivate FcBool +FcStrIsAbsoluteFilename (const FcChar8 *s); + +FcPrivate FcChar8 * +FcStrLastSlash (const FcChar8 *path); + +FcPrivate FcChar32 +FcStrHashIgnoreCase (const FcChar8 *s); + +FcPrivate FcChar32 +FcStrHashIgnoreBlanksAndCase (const FcChar8 *s); + +FcPrivate FcChar8 * +FcStrRealPath (const FcChar8 *path); + +FcPrivate FcChar8 * +FcStrCanonFilename (const FcChar8 *s); + +FcPrivate FcBool +FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str); + +FcPrivate FcChar8 * +FcStrSerialize (FcSerialize *serialize, const FcChar8 *str); + +/* fcobjs.c */ +FcPrivate void +FcObjectInit (void); + +FcPrivate void +FcObjectFini (void); + +FcPrivate FcObject +FcObjectLookupIdByName (const char *str); + +FcPrivate FcObject +FcObjectLookupBuiltinIdByName (const char *str); + +FcPrivate const char * +FcObjectLookupOtherNameById (FcObject id); + +FcPrivate const FcObjectType * +FcObjectLookupOtherTypeById (FcObject id); + +FcPrivate const FcObjectType * +FcObjectLookupOtherTypeByName (const char *str); + +/* fchash.c */ +FcPrivate FcBool +FcHashStrCopy (const void *src, + void **dest); + +FcPrivate FcBool +FcHashUuidCopy (const void *src, + void **dest); + +FcPrivate void +FcHashUuidFree (void *data); + +FcPrivate FcHashTable * +FcHashTableCreate (FcHashFunc hash_func, + FcCompareFunc compare_func, + FcCopyFunc key_copy_func, + FcCopyFunc value_copy_func, + FcDestroyFunc key_destroy_func, + FcDestroyFunc value_destroy_func); + +FcPrivate void +FcHashTableDestroy (FcHashTable *table); + +FcPrivate FcBool +FcHashTableFind (FcHashTable *table, + const void *key, + void **value); + +FcPrivate FcBool +FcHashTableAdd (FcHashTable *table, + void *key, + void *value); + +FcPrivate FcBool +FcHashTableReplace (FcHashTable *table, + void *key, + void *value); + +FcPrivate FcBool +FcHashTableRemove (FcHashTable *table, + void *key); + +#endif /* _FC_INT_H_ */ diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/src/fcobjshash.h b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcobjshash.h new file mode 100644 index 00000000..6160272b --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcobjshash.h @@ -0,0 +1,375 @@ +/* ANSI-C code produced by gperf version 3.3 */ +/* Command-line: gperf --pic -m 100 fcobjshash.gperf */ +/* Computed positions: -k'3,5' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "fcobjshash.gperf" + +#line 13 "fcobjshash.gperf" +struct FcObjectTypeInfo { +int name; +int id; +}; +#include +/* maximum key range = 58, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +FcObjectTypeHash (register const char *str, register size_t len) +{ + static const unsigned char asso_values[] = + { + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 0, 24, 36, + 21, 0, 34, 4, 8, 6, 62, 62, 23, 4, + 12, 41, 19, 62, 4, 0, 10, 13, 26, 37, + 16, 35, 2, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62 + }; + register unsigned int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[4]]; +#if (defined __cplusplus && (__cplusplus >= 201703L || (__cplusplus >= 201103L && defined __clang__ && __clang_major__ + (__clang_minor__ >= 9) > 3))) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 202000L && ((defined __GNUC__ && __GNUC__ >= 10) || (defined __clang__ && __clang_major__ >= 9))) + [[fallthrough]]; +#elif (defined __GNUC__ && __GNUC__ >= 7) || (defined __clang__ && __clang_major__ >= 10) + __attribute__ ((__fallthrough__)); +#endif + /*FALLTHROUGH*/ + case 4: + case 3: + hval += asso_values[(unsigned char)str[2]]; + break; + } + return hval; +} + +struct FcObjectTypeNamePool_t + { + char FcObjectTypeNamePool_str4[sizeof("hash")]; + char FcObjectTypeNamePool_str5[sizeof("scale")]; + char FcObjectTypeNamePool_str6[sizeof("size")]; + char FcObjectTypeNamePool_str7[sizeof("charset")]; + char FcObjectTypeNamePool_str8[sizeof("scalable")]; + char FcObjectTypeNamePool_str9[sizeof("dpi")]; + char FcObjectTypeNamePool_str10[sizeof("rasterizer")]; + char FcObjectTypeNamePool_str11[sizeof("prgname")]; + char FcObjectTypeNamePool_str12[sizeof("variable")]; + char FcObjectTypeNamePool_str13[sizeof("spacing")]; + char FcObjectTypeNamePool_str14[sizeof("postscriptname")]; + char FcObjectTypeNamePool_str15[sizeof("slant")]; + char FcObjectTypeNamePool_str16[sizeof("lang")]; + char FcObjectTypeNamePool_str17[sizeof("desktop")]; + char FcObjectTypeNamePool_str18[sizeof("charheight")]; + char FcObjectTypeNamePool_str19[sizeof("antialias")]; + char FcObjectTypeNamePool_str20[sizeof("weight")]; + char FcObjectTypeNamePool_str21[sizeof("hintstyle")]; + char FcObjectTypeNamePool_str22[sizeof("matrix")]; + char FcObjectTypeNamePool_str23[sizeof("outline")]; + char FcObjectTypeNamePool_str24[sizeof("verticallayout")]; + char FcObjectTypeNamePool_str25[sizeof("hinting")]; + char FcObjectTypeNamePool_str26[sizeof("autohint")]; + char FcObjectTypeNamePool_str27[sizeof("file")]; + char FcObjectTypeNamePool_str28[sizeof("rgba")]; + char FcObjectTypeNamePool_str29[sizeof("genericfamily")]; + char FcObjectTypeNamePool_str30[sizeof("order")]; + char FcObjectTypeNamePool_str31[sizeof("fonthashint")]; + char FcObjectTypeNamePool_str32[sizeof("color")]; + char FcObjectTypeNamePool_str33[sizeof("family")]; + char FcObjectTypeNamePool_str34[sizeof("width")]; + char FcObjectTypeNamePool_str35[sizeof("namelang")]; + char FcObjectTypeNamePool_str36[sizeof("lcdfilter")]; + char FcObjectTypeNamePool_str37[sizeof("familylang")]; + char FcObjectTypeNamePool_str38[sizeof("namedinstance")]; + char FcObjectTypeNamePool_str39[sizeof("minspace")]; + char FcObjectTypeNamePool_str40[sizeof("style")]; + char FcObjectTypeNamePool_str41[sizeof("foundry")]; + char FcObjectTypeNamePool_str42[sizeof("index")]; + char FcObjectTypeNamePool_str43[sizeof("fullname")]; + char FcObjectTypeNamePool_str44[sizeof("stylelang")]; + char FcObjectTypeNamePool_str46[sizeof("charwidth")]; + char FcObjectTypeNamePool_str47[sizeof("fullnamelang")]; + char FcObjectTypeNamePool_str48[sizeof("pixelsize")]; + char FcObjectTypeNamePool_str49[sizeof("fontversion")]; + char FcObjectTypeNamePool_str50[sizeof("decorative")]; + char FcObjectTypeNamePool_str51[sizeof("symbol")]; + char FcObjectTypeNamePool_str52[sizeof("fontvariations")]; + char FcObjectTypeNamePool_str53[sizeof("capability")]; + char FcObjectTypeNamePool_str54[sizeof("globaladvance")]; + char FcObjectTypeNamePool_str55[sizeof("embolden")]; + char FcObjectTypeNamePool_str56[sizeof("fontformat")]; + char FcObjectTypeNamePool_str58[sizeof("fontfeatures")]; + char FcObjectTypeNamePool_str59[sizeof("embeddedbitmap")]; + char FcObjectTypeNamePool_str60[sizeof("fontwrapper")]; + char FcObjectTypeNamePool_str61[sizeof("aspect")]; + }; +static const struct FcObjectTypeNamePool_t FcObjectTypeNamePool_contents = + { + "hash", + "scale", + "size", + "charset", + "scalable", + "dpi", + "rasterizer", + "prgname", + "variable", + "spacing", + "postscriptname", + "slant", + "lang", + "desktop", + "charheight", + "antialias", + "weight", + "hintstyle", + "matrix", + "outline", + "verticallayout", + "hinting", + "autohint", + "file", + "rgba", + "genericfamily", + "order", + "fonthashint", + "color", + "family", + "width", + "namelang", + "lcdfilter", + "familylang", + "namedinstance", + "minspace", + "style", + "foundry", + "index", + "fullname", + "stylelang", + "charwidth", + "fullnamelang", + "pixelsize", + "fontversion", + "decorative", + "symbol", + "fontvariations", + "capability", + "globaladvance", + "embolden", + "fontformat", + "fontfeatures", + "embeddedbitmap", + "fontwrapper", + "aspect" + }; +#define FcObjectTypeNamePool ((const char *) &FcObjectTypeNamePool_contents) +const struct FcObjectTypeInfo * +FcObjectTypeLookup (register const char *str, register size_t len) +{ + enum + { + TOTAL_KEYWORDS = 56, + MIN_WORD_LENGTH = 3, + MAX_WORD_LENGTH = 14, + MIN_HASH_VALUE = 4, + MAX_HASH_VALUE = 61 + }; + +#if (defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 6) > 4) || (defined __clang__ && __clang_major__ >= 3) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + static const struct FcObjectTypeInfo wordlist[] = + { + {-1}, {-1}, {-1}, {-1}, +#line 62 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str4,FC_HASH_OBJECT}, +#line 45 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str5,FC_SCALE_OBJECT}, +#line 27 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str6,FC_SIZE_OBJECT}, +#line 50 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str7,FC_CHARSET_OBJECT}, +#line 42 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str8,FC_SCALABLE_OBJECT}, +#line 43 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str9,FC_DPI_OBJECT}, +#line 40 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str10,FC_RASTERIZER_OBJECT}, +#line 61 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str11,FC_PRGNAME_OBJECT}, +#line 67 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str12,FC_VARIABLE_OBJECT}, +#line 30 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str13,FC_SPACING_OBJECT}, +#line 63 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str14,FC_POSTSCRIPT_NAME_OBJECT}, +#line 24 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str15,FC_SLANT_OBJECT}, +#line 51 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str16,FC_LANG_OBJECT}, +#line 70 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str17,FC_DESKTOP_NAME_OBJECT}, +#line 48 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str18,FC_CHAR_HEIGHT_OBJECT}, +#line 32 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str19,FC_ANTIALIAS_OBJECT}, +#line 25 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str20,FC_WEIGHT_OBJECT}, +#line 33 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str21,FC_HINT_STYLE_OBJECT}, +#line 49 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str22,FC_MATRIX_OBJECT}, +#line 41 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str23,FC_OUTLINE_OBJECT}, +#line 35 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str24,FC_VERTICAL_LAYOUT_OBJECT}, +#line 34 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str25,FC_HINTING_OBJECT}, +#line 36 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str26,FC_AUTOHINT_OBJECT}, +#line 38 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str27,FC_FILE_OBJECT}, +#line 44 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str28,FC_RGBA_OBJECT}, +#line 73 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str29,FC_GENERIC_FAMILY_OBJECT}, +#line 69 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str30,FC_ORDER_OBJECT}, +#line 68 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str31,FC_FONT_HAS_HINT_OBJECT}, +#line 64 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str32,FC_COLOR_OBJECT}, +#line 18 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str33,FC_FAMILY_OBJECT}, +#line 26 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str34,FC_WIDTH_OBJECT}, +#line 59 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str35,FC_NAMELANG_OBJECT}, +#line 58 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str36,FC_LCD_FILTER_OBJECT}, +#line 19 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str37,FC_FAMILYLANG_OBJECT}, +#line 71 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str38,FC_NAMED_INSTANCE_OBJECT}, +#line 46 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str39,FC_MINSPACE_OBJECT}, +#line 20 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str40,FC_STYLE_OBJECT}, +#line 31 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str41,FC_FOUNDRY_OBJECT}, +#line 39 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str42,FC_INDEX_OBJECT}, +#line 22 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str43,FC_FULLNAME_OBJECT}, +#line 21 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str44,FC_STYLELANG_OBJECT}, + {-1}, +#line 47 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str46,FC_CHARWIDTH_OBJECT}, +#line 23 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str47,FC_FULLNAMELANG_OBJECT}, +#line 29 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str48,FC_PIXEL_SIZE_OBJECT}, +#line 52 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str49,FC_FONTVERSION_OBJECT}, +#line 57 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str50,FC_DECORATIVE_OBJECT}, +#line 65 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str51,FC_SYMBOL_OBJECT}, +#line 66 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str52,FC_FONT_VARIATIONS_OBJECT}, +#line 53 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str53,FC_CAPABILITY_OBJECT}, +#line 37 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str54,FC_GLOBAL_ADVANCE_OBJECT}, +#line 55 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str55,FC_EMBOLDEN_OBJECT}, +#line 54 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str56,FC_FONTFORMAT_OBJECT}, + {-1}, +#line 60 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str58,FC_FONT_FEATURES_OBJECT}, +#line 56 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str59,FC_EMBEDDED_BITMAP_OBJECT}, +#line 72 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str60,FC_FONT_WRAPPER_OBJECT}, +#line 28 "fcobjshash.gperf" + {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str61,FC_ASPECT_OBJECT} + }; +#if (defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 6) > 4) || (defined __clang__ && __clang_major__ >= 3) +#pragma GCC diagnostic pop +#endif + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register unsigned int key = FcObjectTypeHash (str, len); + + if (key <= MAX_HASH_VALUE) + { + register int o = wordlist[key].name; + if (o >= 0) + { + register const char *s = o + FcObjectTypeNamePool; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &wordlist[key]; + } + } + } + return (struct FcObjectTypeInfo *) 0; +} diff --git a/vendor/libghostty-vt/pkg/fontconfig/override/src/fcstdint.h b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcstdint.h new file mode 100644 index 00000000..b61b0cb4 --- /dev/null +++ b/vendor/libghostty-vt/pkg/fontconfig/override/src/fcstdint.h @@ -0,0 +1,9 @@ +#ifndef _FONTCONFIG_SRC_FCSTDINT_H +#define _FONTCONFIG_SRC_FCSTDINT_H 1 +#ifndef _GENERATED_STDINT_H +#define _GENERATED_STDINT_H "fontconfig 2.18.3" +/* generated using gnu compiler gcc (GCC) 15.3.0 */ +#define _STDINT_HAVE_STDINT_H 1 +#include +#endif +#endif diff --git a/vendor/libghostty-vt/pkg/freetype/build.zig b/vendor/libghostty-vt/pkg/freetype/build.zig index b85310a5..c1f4535c 100644 --- a/vendor/libghostty-vt/pkg/freetype/build.zig +++ b/vendor/libghostty-vt/pkg/freetype/build.zig @@ -39,7 +39,7 @@ pub fn build(b: *std.Build) !void { if (b.systemIntegrationOption("freetype", .{})) { module.linkSystemLibrary("freetype2", dynamic_link_opts); if (test_exe) |exe| { - exe.linkSystemLibrary2("freetype2", dynamic_link_opts); + exe.root_module.linkSystemLibrary("freetype2", dynamic_link_opts); } } else { const lib = try buildLib(b, module, .{ @@ -52,7 +52,7 @@ pub fn build(b: *std.Build) !void { }); if (test_exe) |exe| { - exe.linkLibrary(lib); + exe.root_module.linkLibrary(lib); } } } @@ -68,10 +68,10 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, }), .linkage = .static, }); - lib.linkLibC(); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); try apple_sdk.addPaths(b, lib); @@ -101,10 +101,10 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu // Zlib if (b.systemIntegrationOption("zlib", .{})) { - lib.linkSystemLibrary2("zlib", dynamic_link_opts); + lib.root_module.linkSystemLibrary("zlib", dynamic_link_opts); } else { const zlib_dep = b.dependency("zlib", .{ .target = target, .optimize = optimize }); - lib.linkLibrary(zlib_dep.artifact("z")); + lib.root_module.linkLibrary(zlib_dep.artifact("z")); } // Libpng @@ -113,50 +113,50 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu try flags.append(b.allocator, "-DFT_CONFIG_OPTION_USE_PNG=1"); if (b.systemIntegrationOption("libpng", .{})) { - lib.linkSystemLibrary2("libpng", dynamic_link_opts); + lib.root_module.linkSystemLibrary("libpng", dynamic_link_opts); } else { const libpng_dep = b.dependency( "libpng", .{ .target = target, .optimize = optimize }, ); - lib.linkLibrary(libpng_dep.artifact("png")); + lib.root_module.linkLibrary(libpng_dep.artifact("png")); } } if (b.lazyDependency("freetype", .{})) |upstream| { - lib.addIncludePath(upstream.path("include")); + lib.root_module.addIncludePath(upstream.path("include")); module.addIncludePath(upstream.path("include")); - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = srcs, .flags = flags.items, }); switch (target.result.os.tag) { - .linux => lib.addCSourceFile(.{ + .linux => lib.root_module.addCSourceFile(.{ .file = upstream.path("builds/unix/ftsystem.c"), .flags = flags.items, }), - .windows => lib.addCSourceFile(.{ + .windows => lib.root_module.addCSourceFile(.{ .file = upstream.path("builds/windows/ftsystem.c"), .flags = flags.items, }), - else => lib.addCSourceFile(.{ + else => lib.root_module.addCSourceFile(.{ .file = upstream.path("src/base/ftsystem.c"), .flags = flags.items, }), } switch (target.result.os.tag) { .windows => { - lib.addCSourceFile(.{ + lib.root_module.addCSourceFile(.{ .file = upstream.path("builds/windows/ftdebug.c"), .flags = flags.items, }); - lib.addWin32ResourceFile(.{ + lib.root_module.addWin32ResourceFile(.{ .file = upstream.path("src/base/ftver.rc"), }); }, - else => lib.addCSourceFile(.{ + else => lib.root_module.addCSourceFile(.{ .file = upstream.path("src/base/ftdebug.c"), .flags = flags.items, }), diff --git a/vendor/libghostty-vt/pkg/glslang/build.zig b/vendor/libghostty-vt/pkg/glslang/build.zig index 1dc82a6e..92e614b1 100644 --- a/vendor/libghostty-vt/pkg/glslang/build.zig +++ b/vendor/libghostty-vt/pkg/glslang/build.zig @@ -26,7 +26,7 @@ pub fn build(b: *std.Build) !void { .optimize = optimize, }), }); - test_exe.linkLibrary(lib); + test_exe.root_module.linkLibrary(lib); const tests_run = b.addRunArtifact(test_exe); const test_step = b.step("test", "Run tests"); test_step.dependOn(&tests_run.step); @@ -47,20 +47,18 @@ fn buildGlslang( .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, + // On MSVC, we must not use linkLibCpp because Zig unconditionally + // passes -nostdinc++ and then adds its bundled libc++/libc++abi + // include paths, which conflict with MSVC's own C++ runtime + // headers. The MSVC SDK include directories (added via linkLibC) + // contain both C and C++ headers, so linkLibCpp is not needed. + .link_libcpp = target.result.abi != .msvc, }), .linkage = .static, }); - lib.linkLibC(); - // On MSVC, we must not use linkLibCpp because Zig unconditionally - // passes -nostdinc++ and then adds its bundled libc++/libc++abi - // include paths, which conflict with MSVC's own C++ runtime headers. - // The MSVC SDK include directories (added via linkLibC) contain - // both C and C++ headers, so linkLibCpp is not needed. - if (target.result.abi != .msvc) { - lib.linkLibCpp(); - } - if (upstream_) |upstream| lib.addIncludePath(upstream.path("")); - lib.addIncludePath(b.path("override")); + if (upstream_) |upstream| lib.root_module.addIncludePath(upstream.path("")); + lib.root_module.addIncludePath(b.path("override")); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); try apple_sdk.addPaths(b, lib); @@ -82,7 +80,7 @@ fn buildGlslang( } if (upstream_) |upstream| { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .flags = flags.items, .files = &.{ @@ -141,7 +139,7 @@ fn buildGlslang( }); if (target.result.os.tag != .windows) { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .flags = flags.items, .files = &.{ @@ -149,7 +147,7 @@ fn buildGlslang( }, }); } else { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .flags = flags.items, .files = &.{ diff --git a/vendor/libghostty-vt/pkg/gtk4-layer-shell/build.zig b/vendor/libghostty-vt/pkg/gtk4-layer-shell/build.zig index 818b48f4..38dfd2c8 100644 --- a/vendor/libghostty-vt/pkg/gtk4-layer-shell/build.zig +++ b/vendor/libghostty-vt/pkg/gtk4-layer-shell/build.zig @@ -17,20 +17,46 @@ pub fn build(b: *std.Build) !void { .target = target, .optimize = optimize, }); - // Needs the gtk.h header - module.linkSystemLibrary("gtk4", dynamic_link_opts); - if (b.systemIntegrationOption("gtk4-layer-shell", .{})) { - module.linkSystemLibrary("gtk4-layer-shell-0", dynamic_link_opts); - } else { - _ = try buildLib(b, module, .{ + translate: { + const translate_c = b.lazyImport(@This(), "translate_c") orelse break :translate; + const translate_c_dep = b.lazyDependency("translate_c", .{}) orelse break :translate; + const Translator = translate_c.Translator; + + const link_system_libs_full: [2]Translator.LinkSystemLib = .{ + .{ .name = "gtk4", .options = dynamic_link_opts }, + .{ .name = "gtk4-layer-shell-0", .options = dynamic_link_opts }, + }; + + const headers = Translator.init(translate_c_dep, .{ + .c_source_file = b.addWriteFiles().add("c.h", + \\#include + ), .target = target, .optimize = optimize, + .link_system_libs = if (b.systemIntegrationOption("gtk4-layer-shell", .{})) + &link_system_libs_full + else + link_system_libs_full[0..1], }); + + if (!b.systemIntegrationOption("gtk4-layer-shell", .{})) { + // local deps (non-system layer-shell/wayland) + const deps = try LocalDeps.get(b) orelse break :translate; + headers.addIncludePath(deps.upstream.path("include")); + headers.addIncludePath(deps.upstream.path("src")); + headers.addIncludePath(deps.client_header_directory); + } + + module.addImport("c", headers.mod); + } + + if (!b.systemIntegrationOption("gtk4-layer-shell", .{})) { + _ = try buildLib(b, .{ .target = target, .optimize = optimize }); } } -fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Build.Step.Compile { +fn buildLib(b: *std.Build, options: anytype) !*std.Build.Step.Compile { const lib_version = try std.SemanticVersion.parse(version); const target = options.target; const optimize = options.optimize; @@ -42,63 +68,25 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, }), }); b.installArtifact(lib); - // We need to call both lazy dependencies to tell Zig we need both - const upstream_ = b.lazyDependency("gtk4_layer_shell", .{}); - const wayland_protocols_ = b.lazyDependency("wayland_protocols", .{}); - const upstream = upstream_ orelse return lib; - const wayland_protocols = wayland_protocols_ orelse return lib; - - lib.linkLibC(); - lib.addIncludePath(upstream.path("include")); - lib.addIncludePath(upstream.path("src")); - module.addIncludePath(upstream.path("include")); - // GTK - lib.linkSystemLibrary2("gtk4", dynamic_link_opts); - - // Wayland headers and source files - { - const protocols = [_]struct { []const u8, std.Build.LazyPath }{ - .{ - "wlr-layer-shell-unstable-v1", - upstream.path("protocol/wlr-layer-shell-unstable-v1.xml"), - }, - .{ - "xdg-shell", - wayland_protocols.path("stable/xdg-shell/xdg-shell.xml"), - }, - // Even though we don't use session lock, we still need its headers - .{ - "ext-session-lock-v1", - wayland_protocols.path("staging/ext-session-lock/ext-session-lock-v1.xml"), - }, - }; - - const wf = b.addWriteFiles(); - for (protocols) |protocol| { - const name, const xml = protocol; - - const header_scanner = b.addSystemCommand(&.{ "wayland-scanner", "client-header" }); - header_scanner.addFileArg(xml); - _ = wf.addCopyFile( - header_scanner.addOutputFileArg(name), - b.fmt("{s}-client.h", .{name}), - ); - - const source_scanner = b.addSystemCommand(&.{ "wayland-scanner", "private-code" }); - source_scanner.addFileArg(xml); - const source = source_scanner.addOutputFileArg(b.fmt("{s}.c", .{name})); - lib.addCSourceFile(.{ .file = source }); - } - lib.addIncludePath(wf.getDirectory()); + lib.root_module.linkSystemLibrary("gtk4", dynamic_link_opts); + + // local deps (non-system layer-shell/wayland) + const deps = try LocalDeps.get(b) orelse return lib; + lib.root_module.addIncludePath(deps.upstream.path("include")); + lib.root_module.addIncludePath(deps.upstream.path("src")); + lib.root_module.addIncludePath(deps.client_header_directory); + for (deps.private_code_files) |source| { + lib.root_module.addCSourceFile(.{ .file = source }); } lib.installHeadersDirectory( - upstream.path("include"), + deps.upstream.path("include"), "", .{ .include_extensions = &.{".h"} }, ); @@ -113,8 +101,8 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu "stubbed-surface.c", "xdg-surface-server.c", }; - lib.addCSourceFiles(.{ - .root = upstream.path("src"), + lib.root_module.addCSourceFiles(.{ + .root = deps.upstream.path("src"), .files = srcs, .flags = &.{ b.fmt("-DGTK_LAYER_SHELL_MAJOR={}", .{lib_version.major}), @@ -125,3 +113,68 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu return lib; } + +const LocalDeps = struct { + var cached: ?LocalDeps = null; + + upstream: *std.Build.Dependency, + wayland_protocols: *std.Build.Dependency, + client_header_directory: std.Build.LazyPath, + private_code_files: []std.Build.LazyPath, + + fn init(b: *std.Build) !?LocalDeps { + var result: LocalDeps = .{ + .upstream = b.lazyDependency("gtk4_layer_shell", .{}) orelse return null, + .wayland_protocols = b.lazyDependency("wayland_protocols", .{}) orelse return null, + .client_header_directory = undefined, + .private_code_files = &.{}, + }; + + // Wayland headers and source files + { + const protocols = [_]struct { []const u8, std.Build.LazyPath }{ + .{ + "wlr-layer-shell-unstable-v1", + result.upstream.path("protocol/wlr-layer-shell-unstable-v1.xml"), + }, + .{ + "xdg-shell", + result.wayland_protocols.path("stable/xdg-shell/xdg-shell.xml"), + }, + // Even though we don't use session lock, we still need its headers + .{ + "ext-session-lock-v1", + result.wayland_protocols.path("staging/ext-session-lock/ext-session-lock-v1.xml"), + }, + }; + + const wf = b.addWriteFiles(); + const private_code_files = try b.allocator.alloc(std.Build.LazyPath, protocols.len); + for (protocols, 0..) |protocol, idx| { + const name, const xml = protocol; + + const header_scanner = b.addSystemCommand(&.{ "wayland-scanner", "client-header" }); + header_scanner.addFileArg(xml); + _ = wf.addCopyFile( + header_scanner.addOutputFileArg(name), + b.fmt("{s}-client.h", .{name}), + ); + + const source_scanner = b.addSystemCommand(&.{ "wayland-scanner", "private-code" }); + source_scanner.addFileArg(xml); + const source = source_scanner.addOutputFileArg(b.fmt("{s}.c", .{name})); + private_code_files[idx] = source; + } + result.private_code_files = private_code_files; + result.client_header_directory = wf.getDirectory(); + } + + cached = result; + return result; + } + + fn get(b: *std.Build) !?LocalDeps { + if (cached) |c| return c; + return init(b); + } +}; diff --git a/vendor/libghostty-vt/pkg/gtk4-layer-shell/build.zig.zon b/vendor/libghostty-vt/pkg/gtk4-layer-shell/build.zig.zon index 9329e374..fd9d0cf2 100644 --- a/vendor/libghostty-vt/pkg/gtk4-layer-shell/build.zig.zon +++ b/vendor/libghostty-vt/pkg/gtk4-layer-shell/build.zig.zon @@ -14,5 +14,10 @@ .hash = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S", .lazy = true, }, + .translate_c = .{ + .url = "https://codeberg.org/vancluever/translate-c/archive/4e879eb8aba615de112eabd1231ea6e01920cead.tar.gz", + .hash = "translate_c-0.0.0-Q_BUWhVNBwDOEcIqub4VFPJPB6D9dgwzUMHTX5KWr8Xr", + .lazy = true, + }, }, } diff --git a/vendor/libghostty-vt/pkg/gtk4-layer-shell/src/main.zig b/vendor/libghostty-vt/pkg/gtk4-layer-shell/src/main.zig index a1531323..04e0f0f3 100644 --- a/vendor/libghostty-vt/pkg/gtk4-layer-shell/src/main.zig +++ b/vendor/libghostty-vt/pkg/gtk4-layer-shell/src/main.zig @@ -1,8 +1,6 @@ const std = @import("std"); -const c = @cImport({ - @cInclude("gtk4-layer-shell.h"); -}); +const c = @import("c"); const gdk = @import("gdk"); const gtk = @import("gtk"); diff --git a/vendor/libghostty-vt/pkg/harfbuzz/blob.zig b/vendor/libghostty-vt/pkg/harfbuzz/blob.zig index 9472e4c7..94a6b5c9 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/blob.zig +++ b/vendor/libghostty-vt/pkg/harfbuzz/blob.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const c = @import("c.zig").c; +const c = @import("hb_c"); const Error = @import("errors.zig").Error; /// Data type holding the memory modes available to client programs. diff --git a/vendor/libghostty-vt/pkg/harfbuzz/buffer.zig b/vendor/libghostty-vt/pkg/harfbuzz/buffer.zig index b97c1bef..ea70bbca 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/buffer.zig +++ b/vendor/libghostty-vt/pkg/harfbuzz/buffer.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const c = @import("c.zig").c; +const c = @import("hb_c"); const common = @import("common.zig"); const Error = @import("errors.zig").Error; const Direction = common.Direction; diff --git a/vendor/libghostty-vt/pkg/harfbuzz/build.zig b/vendor/libghostty-vt/pkg/harfbuzz/build.zig index b482bc8a..5c78b262 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/build.zig +++ b/vendor/libghostty-vt/pkg/harfbuzz/build.zig @@ -1,6 +1,8 @@ const std = @import("std"); const apple_sdk = @import("apple_sdk"); +const root_build_container = @This(); + pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); @@ -8,22 +10,51 @@ pub fn build(b: *std.Build) !void { const coretext_enabled = b.option(bool, "enable-coretext", "Build coretext") orelse false; const freetype_enabled = b.option(bool, "enable-freetype", "Build freetype") orelse true; + // For dynamic linking, we prefer dynamic linking and to search by + // mode first. Mode first will search all paths for a dynamic library + // before falling back to static. + const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ + .preferred_link_mode = .dynamic, + .search_strategy = .mode_first, + }; + const freetype = b.dependency("freetype", .{ .target = target, .optimize = optimize, .@"enable-libpng" = true, }); - const macos = b.dependency("macos", .{ .target = target, .optimize = optimize }); const module = harfbuzz: { const module = b.addModule("harfbuzz", .{ .root_source_file = b.path("main.zig"), .target = target, .optimize = optimize, - .imports = &.{ - .{ .name = "freetype", .module = freetype.module("freetype") }, - .{ .name = "macos", .module = macos.module("macos") }, - }, + .imports = if (target.result.os.tag.isDarwin()) + &.{ + .{ .name = "freetype", .module = freetype.module("freetype") }, + .{ + .name = "macos", + .module = b.dependency("macos", .{ .target = target, .optimize = optimize }) + .module("macos"), + }, + } + else + &.{ + .{ .name = "freetype", .module = freetype.module("freetype") }, + }, + }); + + try HarfBuzzC.addImportToModule(b, module, .{ + .target = target, + .optimize = optimize, + .harfbuzz = if (b.systemIntegrationOption("harfbuzz", .{})) .{ .dynamic = dynamic_link_opts } else .static, + .coretext = coretext_enabled, + .freetype = if (freetype_enabled) ft: { + break :ft if (b.systemIntegrationOption("freetype", .{})) + .{ .dynamic = dynamic_link_opts } + else + .static; + } else null, }); const options = b.addOptions(); @@ -33,41 +64,17 @@ pub fn build(b: *std.Build) !void { break :harfbuzz module; }; - // For dynamic linking, we prefer dynamic linking and to search by - // mode first. Mode first will search all paths for a dynamic library - // before falling back to static. - const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ - .preferred_link_mode = .dynamic, - .search_strategy = .mode_first, - }; - const test_exe = b.addTest(.{ .name = "test", - .root_module = b.createModule(.{ - .root_source_file = b.path("main.zig"), - .target = target, - .optimize = optimize, - }), + .root_module = module, }); - { - var it = module.import_table.iterator(); - while (it.next()) |entry| test_exe.root_module.addImport(entry.key_ptr.*, entry.value_ptr.*); - if (b.systemIntegrationOption("freetype", .{})) { - test_exe.linkSystemLibrary2("freetype2", dynamic_link_opts); - } else { - test_exe.linkLibrary(freetype.artifact("freetype")); - } - const tests_run = b.addRunArtifact(test_exe); - const test_step = b.step("test", "Run tests"); - test_step.dependOn(&tests_run.step); - } + const tests_run = b.addRunArtifact(test_exe); + const test_step = b.step("test", "Run tests"); + test_step.dependOn(&tests_run.step); - if (b.systemIntegrationOption("harfbuzz", .{})) { - module.linkSystemLibrary("harfbuzz", dynamic_link_opts); - test_exe.linkSystemLibrary2("harfbuzz", dynamic_link_opts); - } else { - const lib = try buildLib(b, module, .{ + if (!b.systemIntegrationOption("harfbuzz", .{})) { + const lib = try buildLib(b, .{ .target = target, .optimize = optimize, @@ -77,11 +84,11 @@ pub fn build(b: *std.Build) !void { .dynamic_link_opts = dynamic_link_opts, }); - test_exe.linkLibrary(lib); + test_exe.root_module.linkLibrary(lib); } } -fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Build.Step.Compile { +fn buildLib(b: *std.Build, options: anytype) !*std.Build.Step.Compile { const target = options.target; const optimize = options.optimize; @@ -99,18 +106,16 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, + // On MSVC, we must not use linkLibCpp because Zig unconditionally + // passes -nostdinc++ and then adds its bundled libc++/libc++abi + // include paths, which conflict with MSVC's own C++ runtime + // headers. The MSVC SDK include directories (added via linkLibC) + // contain both C and C++ headers, so linkLibCpp is not needed. + .link_libcpp = target.result.abi != .msvc, }), .linkage = .static, }); - lib.linkLibC(); - // On MSVC, we must not use linkLibCpp because Zig unconditionally - // passes -nostdinc++ and then adds its bundled libc++/libc++abi - // include paths, which conflict with MSVC's own C++ runtime headers. - // The MSVC SDK include directories (added via linkLibC) contain - // both C and C++ headers, so linkLibCpp is not needed. - if (target.result.abi != .msvc) { - lib.linkLibCpp(); - } if (target.result.os.tag.isDarwin()) { try apple_sdk.addPaths(b, lib); @@ -154,30 +159,20 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu }); if (b.systemIntegrationOption("freetype", .{})) { - lib.linkSystemLibrary2("freetype2", dynamic_link_opts); - module.linkSystemLibrary("freetype2", dynamic_link_opts); + lib.root_module.linkSystemLibrary("freetype2", dynamic_link_opts); } else { - lib.linkLibrary(freetype.artifact("freetype")); - - if (freetype.builder.lazyDependency( - "freetype", - .{}, - )) |freetype_dep| { - module.addIncludePath(freetype_dep.path("include")); - } + lib.root_module.linkLibrary(freetype.artifact("freetype")); } } if (coretext_enabled) { try flags.appendSlice(b.allocator, &.{"-DHAVE_CORETEXT=1"}); - lib.linkFramework("CoreText"); - module.linkFramework("CoreText", .{}); + lib.root_module.linkFramework("CoreText", .{}); } if (b.lazyDependency("harfbuzz", .{})) |upstream| { - lib.addIncludePath(upstream.path("src")); - module.addIncludePath(upstream.path("src")); - lib.addCSourceFile(.{ + lib.root_module.addIncludePath(upstream.path("src")); + lib.root_module.addCSourceFile(.{ .file = upstream.path("src/harfbuzz.cc"), .flags = flags.items, }); @@ -192,3 +187,173 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu return lib; } + +const HarfBuzzC = struct { + const AddImportToModuleOptions = struct { + const LinkMode = union(enum) { + static, + dynamic: std.Build.Module.LinkSystemLibraryOptions, + }; + + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, + harfbuzz: LinkMode, + coretext: bool, + freetype: ?LinkMode, + }; + + fn fmtInclude(w: *std.Io.Writer, name: []const u8, mode: AddImportToModuleOptions.LinkMode) !void { + if (mode == .dynamic) { + try w.print("#include <{s}>\n", .{name}); + } else { + try w.print("#include \"{s}\"\n", .{name}); + } + } + + fn addImportToModule( + b: *std.Build, + module: *std.Build.Module, + options: AddImportToModuleOptions, + ) !void { + // TODO: There's a decent amount of duplication here right now. + // Basically we want to mirror what we're passing in buildLib to make + // sure that the translation is generated as correct as possible. + // Eventually, we want to try and unravel this as much as we can, to + // the point that ultimately all C flags and even link options are + // self-contained in the translation artifact. + // + // This is a bit tricky right now as there are situations where we + // provide a static library built straight off of the C file, hence the + // duplication. + // + // NOTE: This function de-allocates nothing as b.allocator is an arena + // (unfortunately not documented, but a cursory search in various + // communities or the issue trackers should turn up confirmation). + + const translate_c = b.lazyImport(root_build_container, "translate_c") orelse return; + const translate_c_dep = b.lazyDependency("translate_c", .{}) orelse return; + + const c_source = c_source: { + var source_builder: std.Io.Writer.Allocating = .init(b.allocator); + try fmtInclude(&source_builder.writer, "hb.h", options.harfbuzz); + + if (options.coretext) { + try fmtInclude(&source_builder.writer, "hb-coretext.h", options.harfbuzz); + } + + if (options.freetype != null) { + try fmtInclude(&source_builder.writer, "hb-ft.h", options.harfbuzz); + } + + break :c_source source_builder.written(); + }; + + // Assemble system libs + const system_libs = libs: { + var libs_builder: std.ArrayList(translate_c.Translator.LinkSystemLib) = .empty; + if (options.harfbuzz == .dynamic) + try libs_builder.append(b.allocator, .{ .name = "harfbuzz", .options = options.harfbuzz.dynamic }); + if (options.freetype) |ft| { + if (ft == .dynamic) + try libs_builder.append(b.allocator, .{ .name = "freetype2", .options = ft.dynamic }); + } + + break :libs libs_builder.items; + }; + + // Assemble flags + const flags = flags: { + var flag_builder: std.ArrayList([]const u8) = .empty; + try flag_builder.appendSlice(b.allocator, &.{ + "-DHAVE_STDBOOL_H", + }); + // Disable ubsan for MSVC: Zig's ubsan runtime cannot be bundled + // on Windows (LNK4229), leaving __ubsan_handle_* unresolved when + // the static archive is consumed by an external linker. + if (options.target.result.abi == .msvc) { + try flag_builder.appendSlice(b.allocator, &.{ + "-fno-sanitize=undefined", + "-fno-sanitize-trap=undefined", + }); + } + if (options.target.result.os.tag != .windows) { + try flag_builder.appendSlice(b.allocator, &.{ + "-DHAVE_UNISTD_H", + "-DHAVE_SYS_MMAN_H", + "-DHAVE_PTHREAD=1", + }); + } + + // Freetype flags/non-system include paths + if (options.freetype != null) { + try flag_builder.appendSlice(b.allocator, &.{ + "-DHAVE_FREETYPE=1", + + // Let's just assume a new freetype + "-DHAVE_FT_GET_VAR_BLEND_COORDINATES=1", + "-DHAVE_FT_SET_VAR_BLEND_COORDINATES=1", + "-DHAVE_FT_DONE_MM_VAR=1", + "-DHAVE_FT_GET_TRANSFORM=1", + }); + } + + // Coretext + if (options.coretext) { + try flag_builder.appendSlice(b.allocator, &.{"-DHAVE_CORETEXT=1"}); + try flag_builder.appendSlice(b.allocator, &.{"-fblocks"}); + } + + break :flags flag_builder.items; + }; + + const hb_c: translate_c.Translator = .init(translate_c_dep, .{ + .c_source_file = b.addWriteFiles().add( + "hb_c.h", + c_source, + ), + .target = options.target, + .optimize = options.optimize, + .link_libc = true, + .link_system_libs = system_libs, + .libc_file = if (options.target.result.os.tag.isDarwin()) libc_file: { + switch (try @import("apple_sdk").pathsForTarget(b, options.target.result)) { + inline else => |paths| break :libc_file paths.libc, + } + } else null, + .extra_args = flags, + }); + + if (options.harfbuzz == .static) { + if (b.lazyDependency("harfbuzz", .{})) |upstream| { + hb_c.addIncludePath(upstream.path("src")); + } + } + + // Freetype non-system include paths + if (options.freetype) |freetype_enabled| { + if (freetype_enabled == .static) { + const ft_dep = b.dependency("freetype", .{ + .target = options.target, + .optimize = options.optimize, + .@"enable-libpng" = true, + }); + + if (ft_dep.builder.lazyDependency( + "freetype", + .{}, + )) |freetype_lazy_dep| { + hb_c.addIncludePath(freetype_lazy_dep.path("include")); + } + } + } + + // Coretext + if (options.coretext) { + // NOTE: We should not necessarily need to add this directly to C + // translation, so we just add it to the module. + hb_c.mod.linkFramework("CoreText", .{}); + } + + module.addImport("hb_c", hb_c.mod); + } +}; diff --git a/vendor/libghostty-vt/pkg/harfbuzz/build.zig.zon b/vendor/libghostty-vt/pkg/harfbuzz/build.zig.zon index b7d155e9..b3f3c238 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/build.zig.zon +++ b/vendor/libghostty-vt/pkg/harfbuzz/build.zig.zon @@ -4,6 +4,12 @@ .fingerprint = 0xbd60917cd18865d8, .paths = .{""}, .dependencies = .{ + .translate_c = .{ + .url = "https://codeberg.org/vancluever/translate-c/archive/4e879eb8aba615de112eabd1231ea6e01920cead.tar.gz", + .hash = "translate_c-0.0.0-Q_BUWhVNBwDOEcIqub4VFPJPB6D9dgwzUMHTX5KWr8Xr", + .lazy = true, + }, + // harfbuzz/harfbuzz .harfbuzz = .{ .url = "https://deps.files.ghostty.org/harfbuzz-11.0.0.tar.xz", diff --git a/vendor/libghostty-vt/pkg/harfbuzz/c.zig b/vendor/libghostty-vt/pkg/harfbuzz/c.zig deleted file mode 100644 index 49e87dce..00000000 --- a/vendor/libghostty-vt/pkg/harfbuzz/c.zig +++ /dev/null @@ -1,8 +0,0 @@ -const builtin = @import("builtin"); -const build_options = @import("build_options"); - -pub const c = @cImport({ - @cInclude("hb.h"); - if (build_options.freetype) @cInclude("hb-ft.h"); - if (build_options.coretext) @cInclude("hb-coretext.h"); -}); diff --git a/vendor/libghostty-vt/pkg/harfbuzz/common.zig b/vendor/libghostty-vt/pkg/harfbuzz/common.zig index 840ff586..01955907 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/common.zig +++ b/vendor/libghostty-vt/pkg/harfbuzz/common.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const c = @import("c.zig").c; +const c = @import("hb_c"); /// The direction of a text segment or buffer. /// diff --git a/vendor/libghostty-vt/pkg/harfbuzz/coretext.zig b/vendor/libghostty-vt/pkg/harfbuzz/coretext.zig index 73042624..72dfd53b 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/coretext.zig +++ b/vendor/libghostty-vt/pkg/harfbuzz/coretext.zig @@ -1,6 +1,6 @@ const macos = @import("macos"); const std = @import("std"); -const c = @import("c.zig").c; +const c = @import("hb_c"); const Face = @import("face.zig").Face; const Font = @import("font.zig").Font; const Error = @import("errors.zig").Error; diff --git a/vendor/libghostty-vt/pkg/harfbuzz/face.zig b/vendor/libghostty-vt/pkg/harfbuzz/face.zig index 5ffad5d3..942894b9 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/face.zig +++ b/vendor/libghostty-vt/pkg/harfbuzz/face.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const c = @import("c.zig").c; +const c = @import("hb_c"); /// A font face is an object that represents a single face from within a font family. /// diff --git a/vendor/libghostty-vt/pkg/harfbuzz/font.zig b/vendor/libghostty-vt/pkg/harfbuzz/font.zig index 13544fb9..4202ca4d 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/font.zig +++ b/vendor/libghostty-vt/pkg/harfbuzz/font.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const c = @import("c.zig").c; +const c = @import("hb_c"); const Face = @import("face.zig").Face; const Error = @import("errors.zig").Error; diff --git a/vendor/libghostty-vt/pkg/harfbuzz/freetype.zig b/vendor/libghostty-vt/pkg/harfbuzz/freetype.zig index d90d3f83..65419a6e 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/freetype.zig +++ b/vendor/libghostty-vt/pkg/harfbuzz/freetype.zig @@ -1,6 +1,6 @@ const freetype = @import("freetype"); const std = @import("std"); -const c = @import("c.zig").c; +const c = @import("hb_c"); const Face = @import("face.zig").Face; const Font = @import("font.zig").Font; const Error = @import("errors.zig").Error; diff --git a/vendor/libghostty-vt/pkg/harfbuzz/main.zig b/vendor/libghostty-vt/pkg/harfbuzz/main.zig index 08a4f9c2..6e46eb42 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/main.zig +++ b/vendor/libghostty-vt/pkg/harfbuzz/main.zig @@ -7,7 +7,7 @@ const font = @import("font.zig"); const shapepkg = @import("shape.zig"); const versionpkg = @import("version.zig"); -pub const c = @import("c.zig").c; +pub const c = @import("hb_c"); pub const freetype = @import("freetype.zig"); pub const coretext = @import("coretext.zig"); pub const MemoryMode = blob.MemoryMode; diff --git a/vendor/libghostty-vt/pkg/harfbuzz/shape.zig b/vendor/libghostty-vt/pkg/harfbuzz/shape.zig index b49020c3..38f56c4a 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/shape.zig +++ b/vendor/libghostty-vt/pkg/harfbuzz/shape.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const c = @import("c.zig").c; +const c = @import("hb_c"); const Font = @import("font.zig").Font; const Buffer = @import("buffer.zig").Buffer; const Feature = @import("common.zig").Feature; diff --git a/vendor/libghostty-vt/pkg/harfbuzz/version.zig b/vendor/libghostty-vt/pkg/harfbuzz/version.zig index dbe25b52..5546ca37 100644 --- a/vendor/libghostty-vt/pkg/harfbuzz/version.zig +++ b/vendor/libghostty-vt/pkg/harfbuzz/version.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const c = @import("c.zig").c; +const c = @import("hb_c"); pub const Version = struct { major: u32, diff --git a/vendor/libghostty-vt/pkg/highway/build.zig b/vendor/libghostty-vt/pkg/highway/build.zig index a0244728..af3300eb 100644 --- a/vendor/libghostty-vt/pkg/highway/build.zig +++ b/vendor/libghostty-vt/pkg/highway/build.zig @@ -18,17 +18,16 @@ pub fn build(b: *std.Build) !void { .root_source_file = b.path("src/detect.zig"), .target = target, .optimize = optimize, + // Our highway package is free of libc at runtime (uses no symbols) + // but does require libc headers at compile time. + .link_libc = true, }), .linkage = .static, }); - // Our highway package is free of libc at runtime (uses no symbols) - // but does require libc headers at compile time. - lib.linkLibC(); - - lib.addIncludePath(b.path("src/cpp")); + lib.root_module.addIncludePath(b.path("src/cpp")); if (upstream_) |upstream| { - lib.addIncludePath(upstream.path("")); + lib.root_module.addIncludePath(upstream.path("")); module.addIncludePath(upstream.path("")); } @@ -100,9 +99,16 @@ pub fn build(b: *std.Build) !void { "-fmath-errno", "-fno-exceptions", }); + } else if (target.result.abi == .msvc) { + try flags.appendSlice(b.allocator, &.{ + // -fno-autolink also drops UCRT's /alternatename fallback. + "-D_Avx2WmemEnabledWeakValue=_Avx2WmemEnabled", + "-fno-autolink", + "-fno-stack-protector", + }); } - lib.addCSourceFiles(.{ .flags = flags.items, .files = &.{ + lib.root_module.addCSourceFiles(.{ .flags = flags.items, .files = &.{ "src/cpp/abort.cc", "src/cpp/per_target.cc", "src/cpp/targets.cpp", @@ -127,7 +133,7 @@ pub fn build(b: *std.Build) !void { .optimize = optimize, }), }); - test_exe.linkLibrary(lib); + test_exe.root_module.linkLibrary(lib); var it = module.import_table.iterator(); while (it.next()) |entry| test_exe.root_module.addImport(entry.key_ptr.*, entry.value_ptr.*); diff --git a/vendor/libghostty-vt/pkg/libintl/build.zig b/vendor/libghostty-vt/pkg/libintl/build.zig index 32221e5a..8ef26c7a 100644 --- a/vendor/libghostty-vt/pkg/libintl/build.zig +++ b/vendor/libghostty-vt/pkg/libintl/build.zig @@ -35,11 +35,11 @@ pub fn build(b: *std.Build) !void { .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, }), .linkage = .static, }); - lib.linkLibC(); - lib.addIncludePath(b.path("")); + lib.root_module.addIncludePath(b.path("")); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); @@ -47,9 +47,9 @@ pub fn build(b: *std.Build) !void { } if (b.lazyDependency("gettext", .{})) |upstream| { - lib.addIncludePath(upstream.path("gettext-runtime/intl")); - lib.addIncludePath(upstream.path("gettext-runtime/intl/gnulib-lib")); - lib.addCSourceFiles(.{ + lib.root_module.addIncludePath(upstream.path("gettext-runtime/intl")); + lib.root_module.addIncludePath(upstream.path("gettext-runtime/intl/gnulib-lib")); + lib.root_module.addCSourceFiles(.{ .root = upstream.path("gettext-runtime/intl"), .files = srcs, .flags = flags.items, diff --git a/vendor/libghostty-vt/pkg/libpng/build.zig b/vendor/libghostty-vt/pkg/libpng/build.zig index 8734b28f..559f42a0 100644 --- a/vendor/libghostty-vt/pkg/libpng/build.zig +++ b/vendor/libghostty-vt/pkg/libpng/build.zig @@ -9,18 +9,10 @@ pub fn build(b: *std.Build) !void { .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, }), .linkage = .static, }); - lib.linkLibC(); - if (target.result.os.tag == .linux) { - lib.linkSystemLibrary("m"); - } - if (target.result.os.tag.isDarwin()) { - const apple_sdk = @import("apple_sdk"); - try apple_sdk.addPaths(b, lib); - } - // For dynamic linking, we prefer dynamic linking and to search by // mode first. Mode first will search all paths for a dynamic library // before falling back to static. @@ -28,20 +20,27 @@ pub fn build(b: *std.Build) !void { .preferred_link_mode = .dynamic, .search_strategy = .mode_first, }; + if (target.result.os.tag == .linux) { + lib.root_module.linkSystemLibrary("m", dynamic_link_opts); + } + if (target.result.os.tag.isDarwin()) { + const apple_sdk = @import("apple_sdk"); + try apple_sdk.addPaths(b, lib); + } if (b.systemIntegrationOption("zlib", .{})) { - lib.linkSystemLibrary2("zlib", dynamic_link_opts); + lib.root_module.linkSystemLibrary("zlib", dynamic_link_opts); } else { if (b.lazyDependency( "zlib", .{ .target = target, .optimize = optimize }, )) |zlib_dep| { - lib.linkLibrary(zlib_dep.artifact("z")); - lib.addIncludePath(b.path("")); + lib.root_module.linkLibrary(zlib_dep.artifact("z")); + lib.root_module.addIncludePath(b.path("")); } if (b.lazyDependency("libpng", .{})) |upstream| { - lib.addIncludePath(upstream.path("")); + lib.root_module.addIncludePath(upstream.path("")); } } @@ -61,7 +60,7 @@ pub fn build(b: *std.Build) !void { }); } - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = srcs, .flags = flags.items, diff --git a/vendor/libghostty-vt/pkg/libxml2/build.zig b/vendor/libghostty-vt/pkg/libxml2/build.zig index a9b3e4b1..07a45e94 100644 --- a/vendor/libghostty-vt/pkg/libxml2/build.zig +++ b/vendor/libghostty-vt/pkg/libxml2/build.zig @@ -11,18 +11,25 @@ pub fn build(b: *std.Build) !void { .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, }), .linkage = .static, }); - lib.linkLibC(); - if (upstream_) |upstream| lib.addIncludePath(upstream.path("include")); - lib.addIncludePath(b.path("override/include")); + if (upstream_) |upstream| lib.root_module.addIncludePath(upstream.path("include")); + lib.root_module.addIncludePath(b.path("override/include")); if (target.result.os.tag == .windows) { - lib.addIncludePath(b.path("override/config/win32")); - lib.linkSystemLibrary("ws2_32"); + lib.root_module.addIncludePath(b.path("override/config/win32")); + // For dynamic linking, we prefer dynamic linking and to search by + // mode first. Mode first will search all paths for a dynamic library + // before falling back to static. + const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ + .preferred_link_mode = .dynamic, + .search_strategy = .mode_first, + }; + lib.root_module.linkSystemLibrary("ws2_32", dynamic_link_opts); } else { - lib.addIncludePath(b.path("override/config/posix")); + lib.root_module.addIncludePath(b.path("override/config/posix")); } var flags: std.ArrayList([]const u8) = .empty; @@ -98,7 +105,7 @@ pub fn build(b: *std.Build) !void { } if (upstream_) |upstream| { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = srcs, .flags = flags.items, diff --git a/vendor/libghostty-vt/pkg/macos/build.zig b/vendor/libghostty-vt/pkg/macos/build.zig index 0525e481..5569baad 100644 --- a/vendor/libghostty-vt/pkg/macos/build.zig +++ b/vendor/libghostty-vt/pkg/macos/build.zig @@ -2,6 +2,66 @@ const std = @import("std"); const builtin = @import("builtin"); const apple_sdk = @import("apple_sdk"); +const Framework = struct { + const Tag = enum { all, macos }; + + tag: Tag, + name: []const u8, + headers: []const []const u8, +}; + +const frameworks = [_]Framework{ + .{ .tag = .all, .name = "CoreFoundation", .headers = &.{"CoreFoundation.h"} }, + .{ .tag = .all, .name = "CoreGraphics", .headers = &.{"CoreGraphics.h"} }, + .{ .tag = .all, .name = "CoreText", .headers = &.{"CoreText.h"} }, + .{ .tag = .all, .name = "CoreVideo", .headers = &.{ "CoreVideo.h", "CVPixelBuffer.h" } }, + .{ .tag = .all, .name = "QuartzCore", .headers = &.{"CALayer.h"} }, + .{ .tag = .all, .name = "IOSurface", .headers = &.{"IOSurfaceRef.h"} }, + .{ .tag = .macos, .name = "Carbon", .headers = &.{"Carbon.h"} }, +}; + +const extra_headers = [_][]const u8{ + "dispatch/dispatch.h", + "os/log.h", + "os/signpost.h", +}; + +const framework_header_fmt = "#include <{s}/{s}>\n"; +const extra_header_fmt = "#include <{s}>\n"; + +fn cSourceLen(tag: Framework.Tag) usize { + var len: usize = 0; + for (frameworks) |framework| { + if (tag != .macos and framework.tag == .macos) continue; + for (framework.headers) |h| len += std.fmt.count(framework_header_fmt, .{ framework.name, h }); + } + for (extra_headers) |h| len += std.fmt.count(extra_header_fmt, .{h}); + return len; +} + +fn genCSource(comptime tag: Framework.Tag) [cSourceLen(tag):0]u8 { + const len = cSourceLen(tag); + var buf: [len:0]u8 = undefined; + var writer: std.Io.Writer = .fixed(&buf); + for (frameworks) |framework| { + if (tag != .macos and framework.tag == .macos) continue; + for (framework.headers) |h| writer.print(framework_header_fmt, .{ framework.name, h }) catch unreachable; + } + for (extra_headers) |h| writer.print(extra_header_fmt, .{h}) catch unreachable; + buf[len] = 0; + return buf; +} + +const c_source_macos = genCSource(.macos); +const c_source_other = genCSource(.all); + +fn linkFrameworks(tag: Framework.Tag, module: *std.Build.Module) !void { + for (frameworks) |framework| { + if (tag != .macos and framework.tag == .macos) continue; + module.linkFramework(framework.name, .{}); + } +} + pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); @@ -12,6 +72,29 @@ pub fn build(b: *std.Build) !void { .optimize = optimize, }); + translate: { + const translate_c = b.lazyImport(@This(), "translate_c") orelse break :translate; + const translate_c_dep = b.lazyDependency("translate_c", .{}) orelse break :translate; + const macos_c: translate_c.Translator = .init(translate_c_dep, .{ + .c_source_file = b.addWriteFiles().add( + "macos_c.h", + if (target.result.os.tag == .macos) &c_source_macos else &c_source_other, + ), + .target = target, + .optimize = optimize, + .libc_file = if (target.result.os.tag.isDarwin()) libc_file: { + switch (try apple_sdk.pathsForTarget(b, target.result)) { + inline else => |paths| break :libc_file paths.libc, + } + } else null, + }); + + // Blocks need to be enabled to use MacOS headers + macos_c.run.addArg("-fblocks"); + + module.addImport("macos_c", macos_c.mod); + } + const lib = b.addLibrary(.{ .name = "macos", .root_module = b.createModule(.{ @@ -21,34 +104,18 @@ pub fn build(b: *std.Build) !void { .linkage = .static, }); - lib.addCSourceFile(.{ + lib.root_module.addCSourceFile(.{ .file = b.path("os/zig_macos.c"), .flags = &.{"-std=c99"}, }); - lib.addCSourceFile(.{ + lib.root_module.addCSourceFile(.{ .file = b.path("text/ext.c"), }); - lib.linkFramework("CoreFoundation"); - lib.linkFramework("CoreGraphics"); - lib.linkFramework("CoreText"); - lib.linkFramework("CoreVideo"); - lib.linkFramework("QuartzCore"); - lib.linkFramework("IOSurface"); - if (target.result.os.tag == .macos) { - lib.linkFramework("Carbon"); - module.linkFramework("Carbon", .{}); - } - - if (target.result.os.tag.isDarwin()) { - module.linkFramework("CoreFoundation", .{}); - module.linkFramework("CoreGraphics", .{}); - module.linkFramework("CoreText", .{}); - module.linkFramework("CoreVideo", .{}); - module.linkFramework("QuartzCore", .{}); - module.linkFramework("IOSurface", .{}); - try apple_sdk.addPaths(b, lib); + inline for (.{ lib.root_module, module }) |mod| { + try linkFrameworks(if (target.result.os.tag == .macos) .macos else .all, mod); } + try apple_sdk.addPaths(b, lib); b.installArtifact(lib); { @@ -63,7 +130,7 @@ pub fn build(b: *std.Build) !void { if (target.result.os.tag.isDarwin()) { try apple_sdk.addPaths(b, test_exe); } - test_exe.linkLibrary(lib); + test_exe.root_module.linkLibrary(lib); var it = module.import_table.iterator(); while (it.next()) |entry| { diff --git a/vendor/libghostty-vt/pkg/macos/build.zig.zon b/vendor/libghostty-vt/pkg/macos/build.zig.zon index 4c22ad7c..f70cb802 100644 --- a/vendor/libghostty-vt/pkg/macos/build.zig.zon +++ b/vendor/libghostty-vt/pkg/macos/build.zig.zon @@ -5,5 +5,10 @@ .paths = .{""}, .dependencies = .{ .apple_sdk = .{ .path = "../apple-sdk" }, + .translate_c = .{ + .url = "https://codeberg.org/vancluever/translate-c/archive/4e879eb8aba615de112eabd1231ea6e01920cead.tar.gz", + .hash = "translate_c-0.0.0-Q_BUWhVNBwDOEcIqub4VFPJPB6D9dgwzUMHTX5KWr8Xr", + .lazy = true, + }, }, } diff --git a/vendor/libghostty-vt/pkg/macos/foundation/string.zig b/vendor/libghostty-vt/pkg/macos/foundation/string.zig index 2f679fef..3d1c5c05 100644 --- a/vendor/libghostty-vt/pkg/macos/foundation/string.zig +++ b/vendor/libghostty-vt/pkg/macos/foundation/string.zig @@ -21,13 +21,13 @@ pub const String = opaque { pub fn createWithCharactersNoCopy( unichars: []const u16, - ) *String { - return @as(*String, @ptrFromInt(@intFromPtr(c.CFStringCreateWithCharactersNoCopy( + ) Allocator.Error!*String { + return @ptrCast(@constCast(c.CFStringCreateWithCharactersNoCopy( null, @ptrCast(unichars.ptr), @intCast(unichars.len), foundation.c.kCFAllocatorNull, - )))); + ) orelse return error.OutOfMemory)); } pub fn release(self: *String) void { diff --git a/vendor/libghostty-vt/pkg/macos/main.zig b/vendor/libghostty-vt/pkg/macos/main.zig index e4f4b950..68d61567 100644 --- a/vendor/libghostty-vt/pkg/macos/main.zig +++ b/vendor/libghostty-vt/pkg/macos/main.zig @@ -10,25 +10,7 @@ pub const text = @import("text.zig"); pub const video = @import("video.zig"); pub const iosurface = @import("iosurface.zig"); -// All of our C imports consolidated into one place. We used to -// import them one by one in each package but Zig 0.14 has some -// kind of issue with that I wasn't able to minimize. -pub const c = @cImport({ - @cInclude("CoreFoundation/CoreFoundation.h"); - @cInclude("CoreGraphics/CoreGraphics.h"); - @cInclude("CoreText/CoreText.h"); - @cInclude("CoreVideo/CoreVideo.h"); - @cInclude("CoreVideo/CVPixelBuffer.h"); - @cInclude("QuartzCore/CALayer.h"); - @cInclude("IOSurface/IOSurfaceRef.h"); - @cInclude("dispatch/dispatch.h"); - @cInclude("os/log.h"); - @cInclude("os/signpost.h"); - - if (builtin.os.tag == .macos) { - @cInclude("Carbon/Carbon.h"); - } -}); +pub const c = @import("macos_c"); test { @import("std").testing.refAllDecls(@This()); diff --git a/vendor/libghostty-vt/pkg/macos/text/font.zig b/vendor/libghostty-vt/pkg/macos/text/font.zig index ea37891f..626b9089 100644 --- a/vendor/libghostty-vt/pkg/macos/text/font.zig +++ b/vendor/libghostty-vt/pkg/macos/text/font.zig @@ -18,6 +18,17 @@ pub const Font = opaque { ) orelse Allocator.Error.OutOfMemory; } + pub fn createWithName(name: *foundation.String, size: f32) Allocator.Error!*Font { + return @as( + ?*Font, + @ptrFromInt(@intFromPtr(c.CTFontCreateWithName( + @ptrCast(name), + size, + null, + ))), + ) orelse Allocator.Error.OutOfMemory; + } + pub fn createForString( self: *Font, str: *foundation.String, @@ -156,7 +167,7 @@ pub const Font = opaque { return @ptrFromInt(@intFromPtr(c.CTFontCopyFamilyName(@ptrCast(self)))); } - pub fn copyDisplayName(self: *Font) *foundation.String { + pub fn copyDisplayName(self: *Font) ?*foundation.String { return @ptrFromInt(@intFromPtr(c.CTFontCopyDisplayName(@ptrCast(self)))); } diff --git a/vendor/libghostty-vt/pkg/macos/text/typesetter.zig b/vendor/libghostty-vt/pkg/macos/text/typesetter.zig index dc07df98..16cd7816 100644 --- a/vendor/libghostty-vt/pkg/macos/text/typesetter.zig +++ b/vendor/libghostty-vt/pkg/macos/text/typesetter.zig @@ -27,10 +27,10 @@ pub const Typesetter = opaque { pub fn createLine( self: *Typesetter, range: foundation.c.CFRange, - ) *text.Line { - return @ptrFromInt(@intFromPtr(c.CTTypesetterCreateLine( + ) Allocator.Error!*text.Line { + return @ptrCast(@constCast(c.CTTypesetterCreateLine( @ptrCast(self), range, - ))); + ) orelse return error.OutOfMemory)); } }; diff --git a/vendor/libghostty-vt/pkg/macos/video/display_link.zig b/vendor/libghostty-vt/pkg/macos/video/display_link.zig index 7d6b437f..dc984422 100644 --- a/vendor/libghostty-vt/pkg/macos/video/display_link.zig +++ b/vendor/libghostty-vt/pkg/macos/video/display_link.zig @@ -1,21 +1,19 @@ -const std = @import("std"); -const assert = std.debug.assert; -const Allocator = std.mem.Allocator; const c = @import("c.zig").c; pub const DisplayLink = opaque { pub const Error = error{ + CreationFailed, InvalidOperation, }; - pub fn createWithActiveCGDisplays() Allocator.Error!*DisplayLink { + pub fn createWithActiveCGDisplays() Error!*DisplayLink { var result: ?*DisplayLink = null; if (c.CVDisplayLinkCreateWithActiveCGDisplays( @ptrCast(&result), ) != c.kCVReturnSuccess) - return error.OutOfMemory; + return error.CreationFailed; - return result orelse error.OutOfMemory; + return result orelse error.CreationFailed; } pub fn release(self: *DisplayLink) void { diff --git a/vendor/libghostty-vt/pkg/oniguruma/build.zig b/vendor/libghostty-vt/pkg/oniguruma/build.zig index d142e5eb..f7df86e1 100644 --- a/vendor/libghostty-vt/pkg/oniguruma/build.zig +++ b/vendor/libghostty-vt/pkg/oniguruma/build.zig @@ -41,7 +41,7 @@ pub fn build(b: *std.Build) !void { module.linkSystemLibrary("oniguruma", dynamic_link_opts); if (test_exe) |exe| { - exe.linkSystemLibrary2("oniguruma", dynamic_link_opts); + exe.root_module.linkSystemLibrary("oniguruma", dynamic_link_opts); } } else { const lib = try buildLib(b, module, .{ @@ -50,7 +50,7 @@ pub fn build(b: *std.Build) !void { }); if (test_exe) |exe| { - exe.linkLibrary(lib); + exe.root_module.linkLibrary(lib); } } } @@ -64,12 +64,12 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, }), .linkage = .static, }); const t = target.result; const is_windows = t.os.tag == .windows; - lib.linkLibC(); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); @@ -77,10 +77,10 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu } if (b.lazyDependency("oniguruma", .{})) |upstream| { - lib.addIncludePath(upstream.path("src")); + lib.root_module.addIncludePath(upstream.path("src")); module.addIncludePath(upstream.path("src")); - lib.addConfigHeader(b.addConfigHeader(.{ + lib.root_module.addConfigHeader(b.addConfigHeader(.{ .style = .{ .cmake = upstream.path("src/config.h.cmake.in") }, }, .{ .PACKAGE = "oniguruma", @@ -109,7 +109,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu "-fno-sanitize-trap=undefined", }); } - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .flags = flags.items, .files = &.{ diff --git a/vendor/libghostty-vt/pkg/sentry/build.zig b/vendor/libghostty-vt/pkg/sentry/build.zig index 3c88df56..7eb755f6 100644 --- a/vendor/libghostty-vt/pkg/sentry/build.zig +++ b/vendor/libghostty-vt/pkg/sentry/build.zig @@ -17,10 +17,10 @@ pub fn build(b: *std.Build) !void { .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, }), .linkage = .static, }); - lib.linkLibC(); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); try apple_sdk.addPaths(b, lib); @@ -46,9 +46,9 @@ pub fn build(b: *std.Build) !void { if (b.lazyDependency("sentry", .{})) |upstream| { module.addIncludePath(upstream.path("include")); - lib.addIncludePath(upstream.path("include")); - lib.addIncludePath(upstream.path("src")); - lib.addCSourceFiles(.{ + lib.root_module.addIncludePath(upstream.path("include")); + lib.root_module.addIncludePath(upstream.path("src")); + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = srcs, .flags = flags.items, @@ -56,7 +56,7 @@ pub fn build(b: *std.Build) !void { // Linux-only if (target.result.os.tag == .linux) { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "vendor/stb_sprintf.c", @@ -67,7 +67,7 @@ pub fn build(b: *std.Build) !void { // Symbolizer + Unwinder if (target.result.os.tag == .windows) { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/sentry_windows_dbghelp.c", @@ -78,7 +78,7 @@ pub fn build(b: *std.Build) !void { .flags = flags.items, }); } else { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/sentry_unix_pageallocator.c", @@ -92,7 +92,7 @@ pub fn build(b: *std.Build) !void { // Module finder switch (target.result.os.tag) { - .windows => lib.addCSourceFiles(.{ + .windows => lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/modulefinder/sentry_modulefinder_windows.c", @@ -100,7 +100,7 @@ pub fn build(b: *std.Build) !void { .flags = flags.items, }), - .macos, .ios => lib.addCSourceFiles(.{ + .macos, .ios => lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/modulefinder/sentry_modulefinder_apple.c", @@ -108,7 +108,7 @@ pub fn build(b: *std.Build) !void { .flags = flags.items, }), - .linux => lib.addCSourceFiles(.{ + .linux => lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/modulefinder/sentry_modulefinder_linux.c", @@ -126,7 +126,7 @@ pub fn build(b: *std.Build) !void { // Transport switch (transport) { - .curl => lib.addCSourceFiles(.{ + .curl => lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/transports/sentry_transport_curl.c", @@ -134,7 +134,7 @@ pub fn build(b: *std.Build) !void { .flags = flags.items, }), - .winhttp => lib.addCSourceFiles(.{ + .winhttp => lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/transports/sentry_transport_winhttp.c", @@ -142,7 +142,7 @@ pub fn build(b: *std.Build) !void { .flags = flags.items, }), - .none => lib.addCSourceFiles(.{ + .none => lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/transports/sentry_transport_none.c", @@ -153,7 +153,7 @@ pub fn build(b: *std.Build) !void { // Backend switch (backend) { - .crashpad => lib.addCSourceFiles(.{ + .crashpad => lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/backends/sentry_backend_crashpad.cpp", @@ -162,7 +162,7 @@ pub fn build(b: *std.Build) !void { }), .breakpad => { - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/backends/sentry_backend_breakpad.cpp", @@ -174,15 +174,15 @@ pub fn build(b: *std.Build) !void { .target = target, .optimize = optimize, })) |breakpad_dep| { - lib.linkLibrary(breakpad_dep.artifact("breakpad")); + lib.root_module.linkLibrary(breakpad_dep.artifact("breakpad")); // We need to add this because Sentry includes some breakpad // headers that include this vendored file... - lib.addIncludePath(breakpad_dep.path("vendor")); + lib.root_module.addIncludePath(breakpad_dep.path("vendor")); } }, - .inproc => lib.addCSourceFiles(.{ + .inproc => lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/backends/sentry_backend_inproc.c", @@ -190,7 +190,7 @@ pub fn build(b: *std.Build) !void { .flags = flags.items, }), - .none => lib.addCSourceFiles(.{ + .none => lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "src/backends/sentry_backend_none.c", diff --git a/vendor/libghostty-vt/pkg/simdutf/build.zig b/vendor/libghostty-vt/pkg/simdutf/build.zig index 0859edc2..3efc0826 100644 --- a/vendor/libghostty-vt/pkg/simdutf/build.zig +++ b/vendor/libghostty-vt/pkg/simdutf/build.zig @@ -10,26 +10,21 @@ pub fn build(b: *std.Build) !void { .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, + // We link libcpp even with no_libcxx because simdutf requires + // libc++ headers at build time. But it doesn't require libc++ at + // runtime. For Ghostty itself, we have CI tests to verify this. + // + // On MSVC, we must not use linkLibCpp because Zig unconditionally + // passes -nostdinc++ and then adds its bundled libc++/libc++abi + // include paths, which conflict with MSVC's own C++ runtime + // headers. The MSVC SDK include directories (added via linkLibC) + // contain both C and C++ headers, so linkLibCpp is not needed. + .link_libcpp = target.result.abi != .msvc, }), .linkage = .static, }); - lib.addIncludePath(b.path("vendor")); - lib.linkLibC(); - libcpp: { - if (target.result.abi == .msvc) { - // On MSVC, we must not use linkLibCpp because Zig unconditionally - // passes -nostdinc++ and then adds its bundled libc++/libc++abi - // include paths, which conflict with MSVC's own C++ runtime headers. - // The MSVC SDK include directories (added via linkLibC) contain - // both C and C++ headers, so linkLibCpp is not needed. - break :libcpp; - } - - // We link libcpp even with no_libcxx because simdutf requires - // libc++ headers at build time. But it doesn't require libc++ - // at runtime. For Ghostty itself, we have CI tests to verify this. - lib.linkLibCpp(); - } + lib.root_module.addIncludePath(b.path("vendor")); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); @@ -55,10 +50,16 @@ pub fn build(b: *std.Build) !void { if (no_libcxx) { try flags.append(b.allocator, "-DSIMDUTF_NO_LIBCXX"); - if (target.result.abi != .msvc) { - // Clang/GCC-only flags; MSVC doesn't accept these. - try flags.append(b.allocator, "-fno-exceptions"); - try flags.append(b.allocator, "-fno-rtti"); + try flags.append(b.allocator, "-fno-exceptions"); + try flags.append(b.allocator, "-fno-rtti"); + if (target.result.abi == .msvc) { + try flags.appendSlice(b.allocator, &.{ + "-D_USE_STD_VECTOR_ALGORITHMS=0", + // -fno-autolink also drops UCRT's /alternatename fallback. + "-D_Avx2WmemEnabledWeakValue=_Avx2WmemEnabled", + "-fno-autolink", + "-fno-stack-protector", + }); } lib.root_module.addCMacro("SIMDUTF_NO_LIBCXX", "1"); @@ -70,11 +71,15 @@ pub fn build(b: *std.Build) !void { try flags.append(b.allocator, "-std=c++17"); } - if (target.result.os.tag == .freebsd or target.result.abi == .musl) { + if (target.result.os.tag == .freebsd or + target.result.abi == .musl or + target.result.abi == .android or + target.result.abi == .androideabi) + { try flags.append(b.allocator, "-fPIC"); } - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .flags = flags.items, .files = &.{ "vendor/simdutf.cpp", diff --git a/vendor/libghostty-vt/pkg/spirv-cross/build.zig b/vendor/libghostty-vt/pkg/spirv-cross/build.zig index 72ce61eb..3b85e8f4 100644 --- a/vendor/libghostty-vt/pkg/spirv-cross/build.zig +++ b/vendor/libghostty-vt/pkg/spirv-cross/build.zig @@ -34,12 +34,12 @@ pub fn build(b: *std.Build) !void { if (b.systemIntegrationOption("spirv-cross", .{})) { module.linkSystemLibrary("spirv-cross-c-shared", dynamic_link_opts); if (test_exe) |exe| { - exe.linkSystemLibrary2("spirv-cross-c-shared", dynamic_link_opts); + exe.root_module.linkSystemLibrary("spirv-cross-c-shared", dynamic_link_opts); } } else { const lib = try buildSpirvCross(b, module, target, optimize); b.installArtifact(lib); - if (test_exe) |exe| exe.linkLibrary(lib); + if (test_exe) |exe| exe.root_module.linkLibrary(lib); } } @@ -54,18 +54,16 @@ fn buildSpirvCross( .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, + // On MSVC, we must not use linkLibCpp because Zig unconditionally + // passes -nostdinc++ and then adds its bundled libc++/libc++abi + // include paths, which conflict with MSVC's own C++ runtime + // headers. The MSVC SDK include directories (added via linkLibC) + // contain both C and C++ headers, so linkLibCpp is not needed. + .link_libcpp = target.result.abi != .msvc, }), .linkage = .static, }); - lib.linkLibC(); - // On MSVC, we must not use linkLibCpp because Zig unconditionally - // passes -nostdinc++ and then adds its bundled libc++/libc++abi - // include paths, which conflict with MSVC's own C++ runtime headers. - // The MSVC SDK include directories (added via linkLibC) contain - // both C and C++ headers, so linkLibCpp is not needed. - if (target.result.abi != .msvc) { - lib.linkLibCpp(); - } if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); try apple_sdk.addPaths(b, lib); @@ -86,9 +84,9 @@ fn buildSpirvCross( } if (b.lazyDependency("spirv_cross", .{})) |upstream| { - lib.addIncludePath(upstream.path("")); + lib.root_module.addIncludePath(upstream.path("")); module.addIncludePath(upstream.path("")); - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .flags = flags.items, .files = &.{ diff --git a/vendor/libghostty-vt/pkg/wuffs/build.zig b/vendor/libghostty-vt/pkg/wuffs/build.zig index 95cef3e0..ce342246 100644 --- a/vendor/libghostty-vt/pkg/wuffs/build.zig +++ b/vendor/libghostty-vt/pkg/wuffs/build.zig @@ -1,5 +1,38 @@ const std = @import("std"); +// All the C macros defined so that the header matches the build. +const defines = [_][]const u8{ + "WUFFS_CONFIG__MODULES", + "WUFFS_CONFIG__MODULE__AUX__BASE", + "WUFFS_CONFIG__MODULE__AUX__IMAGE", + "WUFFS_CONFIG__MODULE__BASE", + "WUFFS_CONFIG__MODULE__ADLER32", + "WUFFS_CONFIG__MODULE__CRC32", + "WUFFS_CONFIG__MODULE__DEFLATE", + "WUFFS_CONFIG__MODULE__JPEG", + "WUFFS_CONFIG__MODULE__PNG", + "WUFFS_CONFIG__MODULE__ZLIB", +}; + +// Generated C code, includes the macros above. Designed to mimic old c.zig. +// TODO: is this still needed, or are the -D flags enough? +const wuffs_c_source = wuffs_c_source: { + const include: []const u8 = "#include "; + const len = len: { + var len: usize = 0; + for (defines) |d| len += std.fmt.count("#define {s}\n", .{d}); + len += std.fmt.count("{s}\n", .{include}); + break :len len; + }; + + var buf: [len:0]u8 = undefined; + var writer: std.Io.Writer = .fixed(&buf); + for (defines) |d| writer.print("#define {s}\n", .{d}) catch unreachable; + writer.print("{s}\n", .{include}) catch unreachable; + buf[len] = 0; + break :wuffs_c_source buf; +}; + pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); @@ -8,32 +41,60 @@ pub fn build(b: *std.Build) !void { .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, - .link_libc = true, }); const unit_tests = b.addTest(.{ .name = "test", .root_module = module, }); - unit_tests.linkLibC(); - - var flags: std.ArrayList([]const u8) = .empty; - defer flags.deinit(b.allocator); - try flags.append(b.allocator, "-DWUFFS_IMPLEMENTATION"); - if (target.result.abi == .msvc) { - try flags.append(b.allocator, "-fno-sanitize=undefined"); - try flags.append(b.allocator, "-fno-sanitize-trap=undefined"); - } - inline for (@import("src/c.zig").defines) |key| { - try flags.append(b.allocator, "-D" ++ key); - } - if (b.lazyDependency("wuffs", .{})) |wuffs_dep| { - module.addIncludePath(wuffs_dep.path("release/c")); - module.addCSourceFile(.{ - .file = wuffs_dep.path("release/c/wuffs-v0.4.c"), - .flags = flags.items, + // Windows always has a libc available. + const windows = target.result.os.tag == .windows; + + translate: { + const translate_c = b.lazyImport(@This(), "translate_c") orelse break :translate; + const translate_c_dep = b.lazyDependency("translate_c", .{}) orelse break :translate; + const wuffs_c: translate_c.Translator = .init(translate_c_dep, .{ + .c_source_file = b.addWriteFiles().add("wuffs_c.h", &wuffs_c_source), + .target = target, + .optimize = optimize, + .link_libc = windows, + .libc_file = if (b.libc_file) |path| .{ .cwd_relative = path } else null, }); + + // Wuffs only needs stdlib.h and string.h from libc, and only for + // a handful of declarations. We provide minimal versions of these + // headers so that wuffs can be translated and compiled without + // libc, notably for freestanding targets (wasm32) but this also + // avoids requiring an Apple SDK for translate-c on macOS. + if (!windows) wuffs_c.addIncludePath(b.path("include")); + + var flags: std.ArrayList([]const u8) = .empty; + defer flags.deinit(b.allocator); + try flags.append(b.allocator, "-DWUFFS_IMPLEMENTATION"); + + // Disable ubsan on Windows to avoid undefined __ubsan_handle_* + // references: Zig's ubsan runtime can't be bundled on Windows + // (its /exclude-symbols directives break the MSVC linker), so + // these handlers would go unresolved. This affects both the + // MSVC and GNU ABIs. + if (windows) { + try flags.append(b.allocator, "-fno-sanitize=undefined"); + try flags.append(b.allocator, "-fno-sanitize-trap=undefined"); + } + inline for (defines) |key| { + try flags.append(b.allocator, "-D" ++ key); + } + + if (b.lazyDependency("wuffs", .{})) |wuffs_dep| { + wuffs_c.addIncludePath(wuffs_dep.path("release/c")); + wuffs_c.mod.addCSourceFile(.{ + .file = wuffs_dep.path("release/c/wuffs-v0.4.c"), + .flags = flags.items, + }); + } + + module.addImport("wuffs_c", wuffs_c.mod); } if (b.lazyDependency("pixels", .{})) |pixels_dep| { diff --git a/vendor/libghostty-vt/pkg/wuffs/build.zig.zon b/vendor/libghostty-vt/pkg/wuffs/build.zig.zon index eb99ba0b..2813fb77 100644 --- a/vendor/libghostty-vt/pkg/wuffs/build.zig.zon +++ b/vendor/libghostty-vt/pkg/wuffs/build.zig.zon @@ -3,10 +3,16 @@ .version = "0.0.0", .fingerprint = 0x67c0c059de921c4f, .dependencies = .{ + .translate_c = .{ + .lazy = true, + .url = "https://codeberg.org/vancluever/translate-c/archive/4e879eb8aba615de112eabd1231ea6e01920cead.tar.gz", + .hash = "translate_c-0.0.0-Q_BUWhVNBwDOEcIqub4VFPJPB6D9dgwzUMHTX5KWr8Xr", + }, + // google/wuffs .wuffs = .{ - .url = "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz", - .hash = "N-V-__8AAAzZywE3s51XfsLbP9eyEw57ae9swYB9aGB6fCMs", + .url = "https://deps.files.ghostty.org/wuffs-7411f488fe2e2c205c3d3b3d28638b7356522930.tar.gz", + .hash = "N-V-__8AAP5JWgCGP_AD0teWpa4krRvE9VPZzvviGdbmN4jI", .lazy = true, }, @@ -16,12 +22,11 @@ .hash = "N-V-__8AADYiAAB_80AWnH1AxXC0tql9thT-R-DYO1gBqTLc", .lazy = true, }, - - .apple_sdk = .{ .path = "../apple-sdk" }, }, .paths = .{ "build.zig", "build.zig.zon", + "include", "src", }, } diff --git a/vendor/libghostty-vt/pkg/wuffs/include/stdlib.h b/vendor/libghostty-vt/pkg/wuffs/include/stdlib.h new file mode 100644 index 00000000..5c050743 --- /dev/null +++ b/vendor/libghostty-vt/pkg/wuffs/include/stdlib.h @@ -0,0 +1,13 @@ +// Minimal stdlib.h so that wuffs can be translated and compiled without +// requiring libc headers. See string.h in this directory for details. +#ifndef GHOSTTY_WUFFS_STDLIB_H +#define GHOSTTY_WUFFS_STDLIB_H + +#include + +void *malloc(size_t size); +void *calloc(size_t count, size_t size); +void *realloc(void *ptr, size_t size); +void free(void *ptr); + +#endif diff --git a/vendor/libghostty-vt/pkg/wuffs/include/string.h b/vendor/libghostty-vt/pkg/wuffs/include/string.h new file mode 100644 index 00000000..39d405d3 --- /dev/null +++ b/vendor/libghostty-vt/pkg/wuffs/include/string.h @@ -0,0 +1,22 @@ +// Minimal string.h so that wuffs can be translated and compiled without +// requiring libc headers (e.g. for wasm32-freestanding targets, or to +// avoid needing an Apple SDK for translate-c on macOS). +// +// Wuffs only calls the mem* family, whose symbols are provided by Zig's +// compiler-rt on targets without libc and by libc everywhere else. The +// declarations here match the standard C ABI, so this header is safe to +// use on every target, including ones that do link libc. +#ifndef GHOSTTY_WUFFS_STRING_H +#define GHOSTTY_WUFFS_STRING_H + +#include + +void *memcpy(void *dst, const void *src, size_t n); +void *memmove(void *dst, const void *src, size_t n); +void *memset(void *b, int c, size_t n); +int memcmp(const void *s1, const void *s2, size_t n); +size_t strlen(const char *s); +int strcmp(const char *s1, const char *s2); +int strncmp(const char *s1, const char *s2, size_t n); + +#endif diff --git a/vendor/libghostty-vt/pkg/wuffs/src/c.zig b/vendor/libghostty-vt/pkg/wuffs/src/c.zig deleted file mode 100644 index d94247df..00000000 --- a/vendor/libghostty-vt/pkg/wuffs/src/c.zig +++ /dev/null @@ -1,18 +0,0 @@ -pub const c = @cImport({ - for (defines) |d| @cDefine(d, "1"); - @cInclude("wuffs-v0.4.c"); -}); - -/// All the C macros defined so that the header matches the build. -pub const defines: []const []const u8 = &[_][]const u8{ - "WUFFS_CONFIG__MODULES", - "WUFFS_CONFIG__MODULE__AUX__BASE", - "WUFFS_CONFIG__MODULE__AUX__IMAGE", - "WUFFS_CONFIG__MODULE__BASE", - "WUFFS_CONFIG__MODULE__ADLER32", - "WUFFS_CONFIG__MODULE__CRC32", - "WUFFS_CONFIG__MODULE__DEFLATE", - "WUFFS_CONFIG__MODULE__JPEG", - "WUFFS_CONFIG__MODULE__PNG", - "WUFFS_CONFIG__MODULE__ZLIB", -}; diff --git a/vendor/libghostty-vt/pkg/wuffs/src/error.zig b/vendor/libghostty-vt/pkg/wuffs/src/error.zig index 0be55cf4..e4ca5c1d 100644 --- a/vendor/libghostty-vt/pkg/wuffs/src/error.zig +++ b/vendor/libghostty-vt/pkg/wuffs/src/error.zig @@ -1,6 +1,6 @@ const std = @import("std"); -const c = @import("c.zig").c; +const c = @import("wuffs_c"); pub const Error = std.mem.Allocator.Error || error{ WuffsError, Overflow }; diff --git a/vendor/libghostty-vt/pkg/wuffs/src/jpeg.zig b/vendor/libghostty-vt/pkg/wuffs/src/jpeg.zig index 69d91c8a..a7bc4bdd 100644 --- a/vendor/libghostty-vt/pkg/wuffs/src/jpeg.zig +++ b/vendor/libghostty-vt/pkg/wuffs/src/jpeg.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const c = @import("c.zig").c; +const c = @import("wuffs_c"); const Error = @import("error.zig").Error; const check = @import("error.zig").check; const ImageData = @import("main.zig").ImageData; diff --git a/vendor/libghostty-vt/pkg/wuffs/src/main.zig b/vendor/libghostty-vt/pkg/wuffs/src/main.zig index 207d83f9..41b74cab 100644 --- a/vendor/libghostty-vt/pkg/wuffs/src/main.zig +++ b/vendor/libghostty-vt/pkg/wuffs/src/main.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("std"); pub const png = @import("png.zig"); @@ -15,6 +16,51 @@ pub const ImageData = struct { data: []u8, }; +// Wuffs' generated `wuffs_foo__bar__alloc()` convenience functions are the +// only code that references libc's calloc/free. We never call them +// and linker garbage collection strips them, but that isn't guaranteed. +// Freestanding consumers may have no allocator to resolve these symbols. +// Never export stubs for hosted targets: hidden weak symbols in a static +// archive can override the embedding executable's dynamically linked libc. +comptime { + if (!builtin.link_libc and builtin.os.tag == .freestanding) { + @export(&callocStub, .{ + .name = "calloc", + .linkage = .weak, + .visibility = .hidden, + }); + @export(&freeStub, .{ + .name = "free", + .linkage = .weak, + .visibility = .hidden, + }); + } +} + +fn callocStub(count: usize, size: usize) callconv(.c) ?*anyopaque { + _ = count; + _ = size; + return null; +} + +fn freeStub(ptr: ?*anyopaque) callconv(.c) void { + _ = ptr; +} + test { - std.testing.refAllDeclsRecursive(@This()); + refAllDeclsRecursive(@This()); +} + +/// Copied from 0.15.2 stdlib (MIT license). +fn refAllDeclsRecursive(comptime T: type) void { + if (!builtin.is_test) return; + inline for (comptime std.meta.declarations(T)) |decl| { + if (@TypeOf(@field(T, decl.name)) == type) { + switch (@typeInfo(@field(T, decl.name))) { + .@"struct", .@"enum", .@"union", .@"opaque" => refAllDeclsRecursive(@field(T, decl.name)), + else => {}, + } + } + _ = &@field(T, decl.name); + } } diff --git a/vendor/libghostty-vt/pkg/wuffs/src/png.zig b/vendor/libghostty-vt/pkg/wuffs/src/png.zig index 57a0e63b..4bf3d759 100644 --- a/vendor/libghostty-vt/pkg/wuffs/src/png.zig +++ b/vendor/libghostty-vt/pkg/wuffs/src/png.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const c = @import("c.zig").c; +const c = @import("wuffs_c"); const Error = @import("error.zig").Error; const check = @import("error.zig").check; const ImageData = @import("main.zig").ImageData; diff --git a/vendor/libghostty-vt/pkg/wuffs/src/swizzle.zig b/vendor/libghostty-vt/pkg/wuffs/src/swizzle.zig index 352cf2b5..d873efea 100644 --- a/vendor/libghostty-vt/pkg/wuffs/src/swizzle.zig +++ b/vendor/libghostty-vt/pkg/wuffs/src/swizzle.zig @@ -1,7 +1,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const assert = std.debug.assert; -const c = @import("c.zig").c; +const c = @import("wuffs_c"); const Error = @import("error.zig").Error; const log = std.log.scoped(.wuffs_swizzler); @@ -16,11 +16,15 @@ pub fn gToRgba(alloc: Allocator, src: []const u8) Error![]u8 { } pub fn gaToRgba(alloc: Allocator, src: []const u8) Error![]u8 { + // Wuffs doesn't support YA_PREMUL as a swizzle source. The nonpremul + // pair produces the same bytes (r=g=b=y, a=a, no alpha math), which + // is what we want: alpha semantics are preserved as-is, matching the + // other conversions here. return swizzle( alloc, src, - c.WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL, - c.WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL, + c.WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL, + c.WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL, ); } @@ -51,6 +55,69 @@ pub fn bgraToRgba(alloc: Allocator, src: []const u8) Error![]u8 { ); } +/// Composite `src` over `dst` in place. Both are straight +/// (non-premultiplied) alpha RGBA of the same length. A transparent +/// destination pixel takes the source pixel exactly; wuffs composites +/// everything else in 16-bit integer space. +pub fn rgbaSrcOver(dst: []u8, src: []const u8) void { + assert(dst.len == src.len); + assert(dst.len % 4 == 0); + + var swizzler: c.wuffs_base__pixel_swizzler = undefined; + const status = c.wuffs_base__pixel_swizzler__prepare( + &swizzler, + c.wuffs_base__make_pixel_format(c.WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL), + c.wuffs_base__empty_slice_u8(), + c.wuffs_base__make_pixel_format(c.WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL), + c.wuffs_base__empty_slice_u8(), + c.WUFFS_BASE__PIXEL_BLEND__SRC_OVER, + ); + // This format pair and blend mode is a supported swizzle, so + // preparation can only fail on a programming error. + assert(c.wuffs_base__status__is_ok(&status)); + + _ = c.wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice( + &swizzler, + c.wuffs_base__make_slice_u8(dst.ptr, dst.len), + c.wuffs_base__empty_slice_u8(), + c.wuffs_base__make_slice_u8(@constCast(src.ptr), src.len), + ); +} + +test "gaToRgba" { + const rgba = try gaToRgba(std.testing.allocator, &.{ 7, 100, 8, 200 }); + defer std.testing.allocator.free(rgba); + + try std.testing.expectEqualSlices(u8, &.{ + 7, 7, 7, 100, + 8, 8, 8, 200, + }, rgba); +} + +test "rgbaSrcOver" { + // 50% white over opaque black, opaque over anything, transparent + // source over anything, and anything over a transparent + // destination (exact source passthrough). + var dst = [_]u8{ + 0, 0, 0, 255, + 10, 20, 30, 40, + 10, 20, 30, 40, + 0, 0, 0, 0, + }; + rgbaSrcOver(&dst, &.{ + 255, 255, 255, 128, + 100, 110, 120, 255, + 100, 110, 120, 0, + 200, 100, 50, 128, + }); + try std.testing.expectEqualSlices(u8, &.{ + 128, 128, 128, 255, + 100, 110, 120, 255, + 10, 20, 30, 40, + 200, 100, 50, 128, + }, &dst); +} + fn swizzle( alloc: Allocator, src: []const u8, diff --git a/vendor/libghostty-vt/pkg/zlib/build.zig b/vendor/libghostty-vt/pkg/zlib/build.zig index 64db13aa..3fa9e6bd 100644 --- a/vendor/libghostty-vt/pkg/zlib/build.zig +++ b/vendor/libghostty-vt/pkg/zlib/build.zig @@ -9,17 +9,17 @@ pub fn build(b: *std.Build) !void { .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, }), .linkage = .static, }); - lib.linkLibC(); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); try apple_sdk.addPaths(b, lib); } if (b.lazyDependency("zlib", .{})) |upstream| { - lib.addIncludePath(upstream.path("")); + lib.root_module.addIncludePath(upstream.path("")); lib.installHeadersDirectory( upstream.path(""), "", @@ -48,7 +48,7 @@ pub fn build(b: *std.Build) !void { "-D_CRT_NONSTDC_NO_DEPRECATE", }); } - lib.addCSourceFiles(.{ + lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = srcs, .flags = flags.items, diff --git a/vendor/libghostty-vt/src/App.zig b/vendor/libghostty-vt/src/App.zig index 93ee7dea..2ee9f936 100644 --- a/vendor/libghostty-vt/src/App.zig +++ b/vendor/libghostty-vt/src/App.zig @@ -15,6 +15,7 @@ const Config = configpkg.Config; const BlockingQueue = @import("datastruct/main.zig").BlockingQueue; const renderer = @import("renderer.zig"); const font = @import("font/main.zig"); +const global = @import("global.zig"); const log = std.log.scoped(.app); @@ -56,7 +57,7 @@ font_grid_set: font.SharedGridSet, // Used to rate limit desktop notifications. Some platforms (notably macOS) will // run out of resources if desktop notifications are sent too fast and the OS // will kill Ghostty. -last_notification_time: ?std.time.Instant = null, +last_notification_time: ?std.Io.Timestamp = null, last_notification_digest: u64 = 0, /// The conditional state of the configuration. See the equivalent field @@ -77,6 +78,32 @@ pub fn create(alloc: Allocator) CreateError!*App { var app = try alloc.create(App); errdefer alloc.destroy(app); try app.init(alloc); + + // If font discovery supports warmup, then we call it. Some font + // mechanisms (e.g. CoreText) have a multi-millisecond one-time cost + // on startup. + if (comptime @hasDecl(font.Discover, "warmup")) { + if (std.Thread.spawn( + .{}, + font.Discover.warmup, + .{}, + )) |thr| thr.detach() else |err| { + log.warn("font warmup thread spawn failed err={}", .{err}); + } + } + + // Same for the renderer's graphics API (e.g. Metal), which pays + // one-time framework initialization costs on first use. + if (comptime @hasDecl(renderer.Renderer.API, "warmup")) { + if (std.Thread.spawn( + .{}, + renderer.Renderer.API.warmup, + .{}, + )) |thr| thr.detach() else |err| { + log.warn("renderer warmup thread spawn failed err={}", .{err}); + } + } + return app; } @@ -95,7 +122,7 @@ pub fn init( self.* = .{ .alloc = alloc, - .surfaces = .{}, + .surfaces = .empty, .mailbox = .{}, .font_grid_set = font_grid_set, .config_conditional_state = .{}, @@ -236,7 +263,7 @@ pub fn needsConfirmQuit(self: *const App) bool { /// Drain the mailbox. fn drainMailbox(self: *App, rt_app: *apprt.App) !void { - while (self.mailbox.pop()) |message| { + while (self.mailbox.pop(global.io())) |message| { if (comptime std.log.logEnabled(.debug, .app)) { switch (message) { // these tend to be way too verbose for normal debugging @@ -245,7 +272,15 @@ fn drainMailbox(self: *App, rt_app: *apprt.App) !void { } } switch (message) { - .open_config => try self.performAction(rt_app, .open_config), + .open_config => |v| try self.performAction( + rt_app, + .{ + .open_config = switch (v) { + .os_open => .os_open, + .new_window => .new_window, + }, + }, + ), .new_window => |msg| try self.newWindow(rt_app, msg), .close => |surface| self.closeSurface(surface), .surface_message => |msg| try self.surfaceMessage(msg.surface, msg.message), @@ -424,7 +459,14 @@ pub fn performAction( .ignore => {}, .quit => _ = try rt_app.performAction(.app, .quit, {}), .new_window => _ = try self.newWindow(rt_app, .{ .parent = null }), - .open_config => _ = try rt_app.performAction(.app, .open_config, {}), + .open_config => |v| _ = try rt_app.performAction( + .app, + .open_config, + switch (v) { + .os_open => .os_open, + .new_window => .new_window, + }, + ), .reload_config => _ = try rt_app.performAction(.app, .reload_config, .{}), .close_all_windows => _ = try rt_app.performAction(.app, .close_all_windows, {}), .toggle_quick_terminal => _ = try rt_app.performAction(.app, .toggle_quick_terminal, {}), @@ -475,8 +517,8 @@ pub fn performAllAction( // are logged but processing continues. .surface => for (self.surfaces.items) |surface| { _ = surface.core().performBindingAction(action) catch |err| { - log.warn("error performing binding action on surface ptr={X} err={}", .{ - @intFromPtr(surface), + log.warn("error performing binding action on surface id={x} err={}", .{ + surface.core().id, err, }); }; @@ -526,7 +568,7 @@ fn hasRtSurface(self: *const App, surface: *apprt.Surface) bool { /// The message types that can be sent to the app thread. pub const Message = union(enum) { // Open the configuration file - open_config: void, + open_config: OpenConfig, /// Create a new terminal window. new_window: NewWindow, @@ -554,6 +596,13 @@ pub const Message = union(enum) { /// The parent surface parent: ?*Surface = null, }; + + pub const OpenConfig = enum { + /// Open the config in the OS default editor. + os_open, + /// Open the config in a new window using $EDITOR or $VISUAL + new_window, + }; }; /// Mailbox is the way that other threads send the app thread messages. @@ -566,7 +615,7 @@ pub const Mailbox = struct { /// Send a message to the surface. pub fn push(self: Mailbox, msg: Message, timeout: Queue.Timeout) Queue.Size { - const result = self.mailbox.push(msg, timeout); + const result = self.mailbox.push(global.io(), msg, timeout); // Wake up our app loop self.rt_app.wakeup(); diff --git a/vendor/libghostty-vt/src/Command.zig b/vendor/libghostty-vt/src/Command.zig index b8193625..3fc498a9 100644 --- a/vendor/libghostty-vt/src/Command.zig +++ b/vendor/libghostty-vt/src/Command.zig @@ -14,12 +14,15 @@ //! * posix_spawn is used for Mac, but doesn't support the necessary //! features for tty setup. //! +//! +//! TODO: This may have changed a lot now with the new I/O implementations in +//! >= 0.16.0, so this might warrant a recheck. const Command = @This(); const std = @import("std"); const builtin = @import("builtin"); const configpkg = @import("config.zig"); -const global_state = &@import("global.zig").state; +const global = @import("global.zig"); const internal_os = @import("os/main.zig"); const windows = internal_os.windows; const TempDir = internal_os.TempDir; @@ -29,8 +32,8 @@ const posix = std.posix; const debug = std.debug; const testing = std.testing; const Allocator = std.mem.Allocator; -const File = std.fs.File; -const EnvMap = std.process.EnvMap; +const File = std.Io.File; +const EnvMap = std.process.Environ.Map; const apprt = @import("apprt.zig"); /// Function prototype for a function executed /in the child process/ after the @@ -65,7 +68,7 @@ env: ?*const EnvMap = null, /// Working directory to change to in the child process. If not set, the /// working directory of the calling process is preserved. -cwd: ?[]const u8 = null, +cwd: ?[:0]const u8 = null, /// The file handle to set for stdin/out/err. If this isn't set, we do /// nothing explicitly so it is up to the behavior of the operating system. @@ -98,7 +101,7 @@ rt_post_fork_info: RtPostForkInfo, /// If set, then the process will be created attached to this pseudo console. /// `stdin`, `stdout`, and `stderr` will be ignored if set. -pseudo_console: if (builtin.os.tag == .windows) ?windows.exp.HPCON else void = +pseudo_console: if (builtin.os.tag == .windows) ?windows.HPCON else void = if (builtin.os.tag == .windows) null else {}, /// User data that is sent to the callback. Set with setData and getData @@ -106,7 +109,7 @@ pseudo_console: if (builtin.os.tag == .windows) ?windows.exp.HPCON else void = data: ?*anyopaque = null, /// Process ID is set after start is called. -pid: ?posix.pid_t = null, +pid: ?posix.system.pid_t = null, /// The various methods a process may exit. pub const Exit = if (builtin.os.tag == .windows) union(enum) { @@ -128,9 +131,9 @@ pub const Exit = if (builtin.os.tag == .windows) union(enum) { return if (posix.W.IFEXITED(status)) Exit{ .Exited = posix.W.EXITSTATUS(status) } else if (posix.W.IFSIGNALED(status)) - Exit{ .Signal = posix.W.TERMSIG(status) } + Exit{ .Signal = @intFromEnum(posix.W.TERMSIG(status)) } else if (posix.W.IFSTOPPED(status)) - Exit{ .Stopped = posix.W.STOPSIG(status) } + Exit{ .Stopped = @intFromEnum(posix.W.STOPSIG(status)) } else Exit{ .Unknown = status }; } @@ -186,7 +189,7 @@ fn startPosix(self: *Command, arena: Allocator) !void { @compileError("missing env vars"); // Fork. - const pid = try posix.fork(); + const pid = try fork(); if (pid != 0) { // Parent, return immediately. @@ -205,37 +208,68 @@ fn startPosix(self: *Command, arena: Allocator) !void { if (self.stderr) |f| setupFd(f.handle, posix.STDERR_FILENO) catch return error.ExecFailedInChild; - // Setup our working directory - if (self.cwd) |cwd| posix.chdir(cwd) catch { - // This can fail if we don't have permission to go to - // this directory or if due to race conditions it doesn't - // exist or any various other reasons. We don't want to - // crash the entire process if this fails so we ignore it. - // We don't log because that'll show up in the output. - }; + // Setup our working directory. + // + // NOTE: this can fail if we don't have permission to go to this directory + // or if due to race conditions it doesn't exist or any various other + // reasons. We don't want to crash the entire process if this fails so we + // ignore it. We don't log because that'll show up in the output. + if (self.cwd) |cwd| _ = posix.system.chdir(cwd); // Restore any rlimits that were set by Ghostty. This might fail but // any failures are ignored (its best effort). - global_state.rlimits.restore(); + global.rlimits().restore(); // If there are pre exec callbacks, call them now. - if (self.os_pre_exec) |f| if (f(self)) |exitcode| posix.exit(exitcode); - if (self.rt_pre_exec) |f| if (f(self)) |exitcode| posix.exit(exitcode); + if (self.os_pre_exec) |f| if (f(self)) |exitcode| posix.system.exit(exitcode); + if (self.rt_pre_exec) |f| if (f(self)) |exitcode| posix.system.exit(exitcode); + + const err: posix.E = execve: { + // This functionality has been taken from Zig stdlib, a simplified + // version of the exec bits with PATH search so that we can just + // offload to execve below. + const file_slice = std.mem.sliceTo(self.path, 0); + if (std.mem.findScalar(u8, file_slice, '/') != null) { + break :execve posix.errno(posix.system.execve(self.path, argsZ, envp)); + } - // Finally, replace our process. - // Note: we must use the "p"-variant of exec here because we - // do not guarantee our command is looked up already in the path. - const err = posix.execvpeZ(self.path, argsZ, envp); + var path_expanded_buf: [std.fs.max_path_bytes]u8 = undefined; + const PATH = global.environ().getPosix("PATH") orelse "/usr/local/bin:/bin/:/usr/bin"; + var it = std.mem.tokenizeScalar(u8, PATH, ':'); + var err: posix.system.E = .NOENT; + var seen_eacces = false; + + while (it.next()) |search_path| { + const path_len = search_path.len + file_slice.len + 1; + if (path_expanded_buf.len < path_len + 1) break :execve .NAMETOOLONG; + @memcpy(path_expanded_buf[0..search_path.len], search_path); + path_expanded_buf[search_path.len] = '/'; + @memcpy(path_expanded_buf[search_path.len + 1 ..][0..file_slice.len], file_slice); + path_expanded_buf[path_len] = 0; + const full_path = path_expanded_buf[0..path_len :0].ptr; + // Replace here, switch on error (any error means that replace + // failed, but we might need to retry). + err = posix.errno(posix.system.execve(full_path, argsZ, envp)); + switch (err) { + .ACCES => seen_eacces = true, + .NOENT, .NOTDIR => {}, + else => break :execve err, + } + } + + if (seen_eacces) break :execve .ACCES; + break :execve err; + }; // If we are executing this code, the exec failed. We're in the // child process so there isn't much we can do. We try to output // something reasonable. Its important to note we MUST NOT return // any other error condition from here on out. var stderr_buf: [1024]u8 = undefined; - var stderr_writer = std.fs.File.stderr().writer(&stderr_buf); + var stderr_writer = std.Io.File.stderr().writer(global.io(), &stderr_buf); const stderr = &stderr_writer.interface; switch (err) { - error.FileNotFound => stderr.print( + posix.system.E.NOENT => stderr.print( \\Requested executable not found. Please verify the command is on \\the PATH and try again. \\ @@ -243,11 +277,11 @@ fn startPosix(self: *Command, arena: Allocator) !void { .{}, ) catch {}, - else => stderr.print( - \\exec syscall failed with unexpected error: {} + else => |e| stderr.print( + \\exec syscall failed with unexpected error: E{s} \\ , - .{err}, + .{@tagName(e)}, ) catch {}, } stderr.flush() catch {}; @@ -257,6 +291,17 @@ fn startPosix(self: *Command, arena: Allocator) !void { return error.ExecFailedInChild; } +/// Wrapper for the raw fork syscall. This preserves the error handling from +/// the std.posix wrapper that was removed in Zig 0.16. +fn fork() !posix.pid_t { + const rc = posix.system.fork(); + switch (posix.errno(rc)) { + .SUCCESS => return @intCast(rc), + .AGAIN, .NOMEM => return error.SystemResources, + else => |err| return posix.unexpectedErrno(err), + } +} + fn startWindows(self: *Command, arena: Allocator) !void { const cwd_w = if (self.cwd) |cwd| try std.unicode.utf8ToUtf16LeAllocZ(arena, cwd) else null; @@ -275,15 +320,37 @@ fn startWindows(self: *Command, arena: Allocator) !void { const env_w = if (self.env) |env_map| try createWindowsEnvBlock(arena, env_map) else null; const any_null_fd = self.stdin == null or self.stdout == null or self.stderr == null; - const null_fd = if (any_null_fd) try windows.OpenFile( - &[_]u16{ '\\', 'D', 'e', 'v', 'i', 'c', 'e', '\\', 'N', 'u', 'l', 'l' }, - .{ - .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE, - .share_access = windows.FILE_SHARE_READ, - .creation = windows.OPEN_EXISTING, - }, - ) else null; - defer if (null_fd) |fd| posix.close(fd); + const null_fd = if (any_null_fd) null_fd: { + // path = "\Device\Null" + const path = [_]u16{ '\\', 'D', 'e', 'v', 'i', 'c', 'e', '\\', 'N', 'u', 'l', 'l' }; + var path_unicode_string: windows.UNICODE_STRING = .init(&path); + var attrs: windows.OBJECT_ATTRIBUTES = .{ .ObjectName = &path_unicode_string }; + + var fd: windows.HANDLE = undefined; + var io_status: windows.IO_STATUS_BLOCK = undefined; // unused + const result = windows.exp.ntdll.NtCreateFile( + &fd, + .{ .GENERIC = .{ .READ = true }, .STANDARD = .{ .SYNCHRONIZE = true } }, + &attrs, + &io_status, + null, + windows.FILE_ATTRIBUTE_NORMAL, + windows.FILE_SHARE_READ, + windows.OPEN_EXISTING, + windows.FILE_NON_DIRECTORY_FILE, + null, + 0, + ); + + if (result != .SUCCESS) { + return windows.unexpectedStatus(result); + } + + break :null_fd fd; + } else null; + defer { + if (null_fd) |fd| _ = windows.exp.kernel32.CloseHandle(fd); + } // TODO: In the case of having FDs instead of pty, need to set up // attributes such that the child process only inherits these handles, @@ -304,17 +371,17 @@ fn startWindows(self: *Command, arena: Allocator) !void { 1, 0, &attribute_list_size, - ) == 0) return windows.unexpectedError(windows.kernel32.GetLastError()); + ) == windows.FALSE) return windows.unexpectedError(windows.GetLastError()); if (windows.exp.kernel32.UpdateProcThreadAttribute( attribute_list_buf.ptr, 0, - windows.exp.PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, + windows.PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, pseudo_console, - @sizeOf(windows.exp.HPCON), + @sizeOf(windows.HPCON), null, null, - ) == 0) return windows.unexpectedError(windows.kernel32.GetLastError()); + ) == windows.FALSE) return windows.unexpectedError(windows.GetLastError()); break :b .{ attribute_list_buf.ptr, null, null, null }; } else b: { @@ -324,9 +391,9 @@ fn startWindows(self: *Command, arena: Allocator) !void { break :b .{ null, stdin, stdout, stderr }; }; - var startup_info_ex = windows.exp.STARTUPINFOEX{ + var startup_info_ex = windows.STARTUPINFOEX{ .StartupInfo = .{ - .cb = if (attribute_list != null) @sizeOf(windows.exp.STARTUPINFOEX) else @sizeOf(windows.STARTUPINFOW), + .cb = if (attribute_list != null) @sizeOf(windows.STARTUPINFOEX) else @sizeOf(windows.STARTUPINFOW), .hStdError = stderr, .hStdOutput = stdout, .hStdInput = stdin, @@ -348,8 +415,8 @@ fn startWindows(self: *Command, arena: Allocator) !void { .lpAttributeList = attribute_list, }; - var flags: windows.DWORD = windows.exp.CREATE_UNICODE_ENVIRONMENT; - if (attribute_list != null) flags |= windows.exp.EXTENDED_STARTUPINFO_PRESENT; + var flags: windows.DWORD = windows.CREATE_UNICODE_ENVIRONMENT; + if (attribute_list != null) flags |= windows.EXTENDED_STARTUPINFO_PRESENT; var process_information: windows.PROCESS_INFORMATION = undefined; if (windows.exp.kernel32.CreateProcessW( @@ -363,21 +430,18 @@ fn startWindows(self: *Command, arena: Allocator) !void { if (cwd_w) |w| w.ptr else null, @ptrCast(&startup_info_ex.StartupInfo), &process_information, - ) == 0) return windows.unexpectedError(windows.kernel32.GetLastError()); + ) == windows.FALSE) return windows.unexpectedError(windows.GetLastError()); self.pid = process_information.hProcess; } fn setupFd(src: File.Handle, target: i32) !void { - switch (builtin.os.tag) { - .linux => { - // We use dup3 so that we can clear CLO_ON_EXEC. We do NOT want this - // file descriptor to be closed on exec since we're exactly exec-ing after - // this. + const PosixCall = struct { + fn f(func: anytype, args: anytype) !usize { while (true) { - const rc = linux.dup3(src, target, 0); + const rc = @call(.auto, func, args); switch (posix.errno(rc)) { - .SUCCESS => break, + .SUCCESS => return @intCast(rc), .INTR => continue, .AGAIN, .ACCES => return error.Locked, .BADF => unreachable, @@ -391,16 +455,28 @@ fn setupFd(src: File.Handle, target: i32) !void { else => |err| return posix.unexpectedErrno(err), } } + } + }; + + switch (builtin.os.tag) { + .linux => { + // We use dup3 so that we can clear CLO_ON_EXEC. We do NOT want this + // file descriptor to be closed on exec since we're exactly exec-ing after + // this. + _ = try PosixCall.f(linux.dup3, .{ src, target, 0 }); }, .freebsd, .ios, .macos => { // Mac doesn't support dup3 so we use dup2. We purposely clear // CLO_ON_EXEC for this fd. - const flags = try posix.fcntl(src, posix.F.GETFD, 0); + const flags = try PosixCall.f(posix.system.fcntl, .{ src, posix.F.GETFD }); if (flags & posix.FD_CLOEXEC != 0) { - _ = try posix.fcntl(src, posix.F.SETFD, flags & ~@as(u32, posix.FD_CLOEXEC)); + _ = try PosixCall.f( + posix.system.fcntl, + .{ src, posix.F.SETFD, flags & ~@as(u32, posix.FD_CLOEXEC) }, + ); } - try posix.dup2(src, target); + _ = try PosixCall.f(posix.system.dup2, .{ src, target }); }, else => @compileError("unsupported platform"), } @@ -411,21 +487,29 @@ pub fn wait(self: Command, block: bool) !Exit { if (comptime builtin.os.tag == .windows) { // Block until the process exits. This returns immediately if the // process already exited. - const result = windows.kernel32.WaitForSingleObject(self.pid.?, windows.INFINITE); + // + // NOTE: We can use the pid directly as posix.system.pid_t is still an + // alias for a handle under Windows. We might want to keep an eye on if + // this changes, though. + const result = windows.exp.kernel32.WaitForSingleObject(self.pid.?, windows.INFINITE); if (result == windows.WAIT_FAILED) { - return windows.unexpectedError(windows.kernel32.GetLastError()); + return windows.unexpectedError(windows.GetLastError()); } var exit_code: windows.DWORD = undefined; - const has_code = windows.kernel32.GetExitCodeProcess(self.pid.?, &exit_code) != 0; + const has_code = windows.exp.kernel32.GetExitCodeProcess(self.pid.?, &exit_code) != windows.FALSE; if (!has_code) { - return windows.unexpectedError(windows.kernel32.GetLastError()); + return windows.unexpectedError(windows.GetLastError()); } return .{ .Exited = exit_code }; } - const res = if (block) posix.waitpid(self.pid.?, 0) else res: { + const status: u32 = if (block) wait_block: { + var status: if (builtin.link_libc) c_int else u32 = undefined; + _ = try waitPid(self.pid.?, &status, 0); + break :wait_block @bitCast(status); + } else wait_nohang: { // We specify NOHANG because its not our fault if the process we launch // for the tty doesn't properly waitpid its children. We don't want // to hang the terminal over it. @@ -434,12 +518,32 @@ pub fn wait(self: Command, block: bool) !Exit { // wait call has not been performed, so we need to keep trying until we get // a non-zero pid back, otherwise we end up with zombie processes. while (true) { - const res = posix.waitpid(self.pid.?, std.c.W.NOHANG); - if (res.pid != 0) break :res res; + var status: if (builtin.link_libc) c_int else u32 = undefined; + const pid = try waitPid(self.pid.?, &status, posix.system.W.NOHANG); + if (pid != 0) break :wait_nohang @bitCast(status); } }; - return .init(res.status); + return .init(status); +} + +/// Wrapper for the raw waitpid syscall. Status is only initialized on success; +/// interrupted waits are retried and all other errors are propagated. +fn waitPid( + pid: posix.pid_t, + status: *if (builtin.link_libc) c_int else u32, + flags: u32, +) !posix.pid_t { + while (true) { + const rc = posix.system.waitpid(pid, status, @intCast(flags)); + switch (posix.errno(rc)) { + .SUCCESS => return @intCast(rc), + .INTR => continue, + .CHILD => return error.NoChildProcess, + .INVAL => return error.InvalidWaitOptions, + else => |err| return posix.unexpectedErrno(err), + } + } } /// Sets command->data to data. @@ -587,7 +691,7 @@ test "Command: os pre exec 1" { fn do(_: *Command) ?u8 { // This runs in the child, so we can exit and it won't // kill the test runner. - posix.exit(42); + posix.system.exit(42); } }).do, .rt_pre_exec = null, @@ -638,7 +742,7 @@ test "Command: rt pre exec 1" { fn do(_: *Command) ?u8 { // This runs in the child, so we can exit and it won't // kill the test runner. - posix.exit(42); + posix.system.exit(42); } }).do, .rt_post_fork = null, @@ -697,27 +801,31 @@ test "Command: rt post fork 1" { try testing.expectError(error.PostForkError, cmd.testingStart()); } -fn createTestStdout(dir: std.fs.Dir) !File { - const file = try dir.createFile("stdout.txt", .{ .read = true }); +fn createTestStdout(io: std.Io, dir: std.Io.Dir) !File { + const file = try dir.createFile(io, "stdout.txt", .{ .read = true }); if (builtin.os.tag == .windows) { - try windows.SetHandleInformation( + if (windows.exp.kernel32.SetHandleInformation( file.handle, windows.HANDLE_FLAG_INHERIT, windows.HANDLE_FLAG_INHERIT, - ); + ) == windows.FALSE) { + return windows.unexpectedError(windows.GetLastError()); + } } return file; } -fn createTestStderr(dir: std.fs.Dir) !File { - const file = try dir.createFile("stderr.txt", .{ .read = true }); +fn createTestStderr(io: std.Io, dir: std.Io.Dir) !File { + const file = try dir.createFile(io, "stderr.txt", .{ .read = true }); if (builtin.os.tag == .windows) { - try windows.SetHandleInformation( + if (windows.exp.kernel32.SetHandleInformation( file.handle, windows.HANDLE_FLAG_INHERIT, windows.HANDLE_FLAG_INHERIT, - ); + ) == windows.FALSE) { + return windows.unexpectedError(windows.GetLastError()); + } } return file; @@ -726,8 +834,8 @@ fn createTestStderr(dir: std.fs.Dir) !File { test "Command: redirect stdout to file" { var td = try TempDir.init(); defer td.deinit(); - var stdout = try createTestStdout(td.dir); - defer stdout.close(); + var stdout = try createTestStdout(testing.io, td.dir); + defer stdout.close(testing.io); var cmd: Command = if (builtin.os.tag == .windows) .{ .path = "C:\\Windows\\System32\\whoami.exe", @@ -756,8 +864,13 @@ test "Command: redirect stdout to file" { try testing.expectEqual(@as(u32, 0), @as(u32, exit.Exited)); // Read our stdout - try stdout.seekTo(0); - const contents = try stdout.readToEndAlloc(testing.allocator, 1024 * 128); + const contents = contents: { + const size = (try stdout.stat(testing.io)).size; + const data = try testing.allocator.alloc(u8, size); + errdefer testing.allocator.free(data); + try testing.expectEqual(size, try stdout.readPositionalAll(testing.io, data, 0)); + break :contents data; + }; defer testing.allocator.free(contents); try testing.expect(contents.len > 0); } @@ -765,8 +878,8 @@ test "Command: redirect stdout to file" { test "Command: custom env vars" { var td = try TempDir.init(); defer td.deinit(); - var stdout = try createTestStdout(td.dir); - defer stdout.close(); + var stdout = try createTestStdout(testing.io, td.dir); + defer stdout.close(testing.io); var env = EnvMap.init(testing.allocator); defer env.deinit(); @@ -801,8 +914,13 @@ test "Command: custom env vars" { try testing.expect(exit.Exited == 0); // Read our stdout - try stdout.seekTo(0); - const contents = try stdout.readToEndAlloc(testing.allocator, 4096); + const contents = contents: { + const size = (try stdout.stat(testing.io)).size; + const data = try testing.allocator.alloc(u8, size); + errdefer testing.allocator.free(data); + try testing.expectEqual(size, try stdout.readPositionalAll(testing.io, data, 0)); + break :contents data; + }; defer testing.allocator.free(contents); if (builtin.os.tag == .windows) { @@ -815,8 +933,8 @@ test "Command: custom env vars" { test "Command: custom working directory" { var td = try TempDir.init(); defer td.deinit(); - var stdout = try createTestStdout(td.dir); - defer stdout.close(); + var stdout = try createTestStdout(testing.io, td.dir); + defer stdout.close(testing.io); var cmd: Command = if (builtin.os.tag == .windows) .{ .path = "C:\\Windows\\System32\\cmd.exe", @@ -847,8 +965,13 @@ test "Command: custom working directory" { try testing.expect(exit.Exited == 0); // Read our stdout - try stdout.seekTo(0); - const contents = try stdout.readToEndAlloc(testing.allocator, 4096); + const contents = contents: { + const size = (try stdout.stat(testing.io)).size; + const data = try testing.allocator.alloc(u8, size); + errdefer testing.allocator.free(data); + try testing.expectEqual(size, try stdout.readPositionalAll(testing.io, data, 0)); + break :contents data; + }; defer testing.allocator.free(contents); if (builtin.os.tag == .windows) { @@ -872,10 +995,10 @@ test "Command: posix fork handles execveZ failure" { } var td = try TempDir.init(); defer td.deinit(); - var stdout = try createTestStdout(td.dir); - defer stdout.close(); - var stderr = try createTestStderr(td.dir); - defer stderr.close(); + var stdout = try createTestStdout(testing.io, td.dir); + defer stdout.close(testing.io); + var stderr = try createTestStderr(testing.io, td.dir); + defer stderr.close(testing.io); var cmd: Command = .{ .path = "/not/a/binary", @@ -904,7 +1027,7 @@ fn testingStart(self: *Command) !void { self.start(testing.allocator) catch |err| { if (err == error.ExecFailedInChild) { // I am a child process, I must not get confused and continue running the rest of the test suite. - posix.exit(1); + posix.system.exit(1); } return err; }; diff --git a/vendor/libghostty-vt/src/Surface.zig b/vendor/libghostty-vt/src/Surface.zig index 2c4edc49..77529212 100644 --- a/vendor/libghostty-vt/src/Surface.zig +++ b/vendor/libghostty-vt/src/Surface.zig @@ -20,8 +20,9 @@ const builtin = @import("builtin"); const assert = @import("quirks.zig").inlineAssert; const Allocator = std.mem.Allocator; const ArenaAllocator = std.heap.ArenaAllocator; -const global_state = &@import("global.zig").state; +const global = @import("global.zig"); const oni = @import("oniguruma"); +const simd = @import("simd/main.zig"); const crash = @import("crash/main.zig"); const unicode = @import("unicode/main.zig"); const rendererpkg = @import("renderer.zig"); @@ -154,6 +155,10 @@ child_exited: bool = false, /// to let us know. focused: bool = true, +/// Whether this surface may be visible. Unknown visibility is considered +/// visible so reporting remains conservative. +visible: bool = true, + /// Used to determine whether to continuously scroll. selection_scroll_active: bool = false, @@ -168,13 +173,13 @@ readonly: bool = false, /// precision timestamp. It does not necessarily need to correspond to the /// actual time, but we must be able to compare two subsequent timestamps to get /// the wall clock time that has elapsed between timestamps. -command_timer: ?std.time.Instant = null, +command_timer: ?std.Io.Timestamp = null, /// Search state search: ?Search = null, /// Used to rate limit BEL handling. -last_bell_time: ?std.time.Instant = null, +last_bell_time: ?std.Io.Timestamp = null, /// The effect of an input event. This can be used by callers to take /// the appropriate action after an input event. For example, key @@ -330,6 +335,7 @@ const DerivedConfig = struct { title: ?[:0]const u8, title_report: bool, links: []DerivedConfig.Link, + link_osc8: bool, link_previews: configpkg.LinkPreviews, scroll_to_bottom: configpkg.Config.ScrollToBottom, notify_on_command_finish: configpkg.Config.NotifyOnCommandFinish, @@ -409,6 +415,7 @@ const DerivedConfig = struct { .title = config.title, .title_report = config.@"title-report", .links = links, + .link_osc8 = config.@"link-osc8", .link_previews = config.@"link-previews", .scroll_to_bottom = config.@"scroll-to-bottom", .notify_on_command_finish = config.@"notify-on-command-finish", @@ -559,8 +566,8 @@ pub fn init( errdefer renderer_impl.deinit(); // The mutex used to protect our renderer state. - const mutex = try alloc.create(std.Thread.Mutex); - mutex.* = .{}; + const mutex = try alloc.create(std.Io.Mutex); + mutex.* = .init; errdefer alloc.destroy(mutex); // Create the renderer thread @@ -581,7 +588,11 @@ pub fn init( self.* = .{ .id = id: { while (true) { - const candidate = std.crypto.random.int(u64); + const candidate = candidate: { + const rng_impl: std.Random.IoSource = .{ .io = global.io() }; + const rng = rng_impl.interface(); + break :candidate rng.int(u64); + }; if (candidate == 0) continue; break :id candidate; } @@ -631,13 +642,12 @@ pub fn init( var env = rt_surface.defaultTermioEnv() catch |err| env: { // If an error occurs, we don't want to block surface startup. log.warn("error getting env map for surface err={}", .{err}); - break :env internal_os.getEnvMap(alloc) catch - std.process.EnvMap.init(alloc); + break :env global.environMap() catch std.process.Environ.Map.init(alloc); }; errdefer env.deinit(); // don't leak GHOSTTY_LOG to any subprocesses - env.remove("GHOSTTY_LOG"); + _ = env.orderedRemove("GHOSTTY_LOG"); var buf: [18]u8 = undefined; try env.put( @@ -654,7 +664,7 @@ pub fn init( .shell_integration_features = config.@"shell-integration-features", .cursor_blink = config.@"cursor-style-blink", .working_directory = if (config.@"working-directory") |wd| wd.value() else null, - .resources_dir = global_state.resources_dir.host(), + .resources_dir = global.resourcesDir().host(), .term = config.term, .rt_pre_exec_info = .init(config), .rt_post_fork_info = .init(config), @@ -717,7 +727,7 @@ pub fn init( rendererpkg.Thread.threadMain, .{&self.renderer_thread}, ); - self.renderer_thr.setName("renderer") catch {}; + self.renderer_thr.setName(global.io(), "renderer") catch {}; // Start our IO thread self.io_thr = try std.Thread.spawn( @@ -725,7 +735,7 @@ pub fn init( termio.Thread.threadMain, .{ &self.io_thread, &self.io }, ); - self.io_thr.setName("io") catch {}; + self.io_thr.setName(global.io(), "io") catch {}; // Determine our initial window size if configured. We need to do this // quite late in the process because our height/width are in grid dimensions, @@ -834,7 +844,7 @@ pub fn deinit(self: *Surface) void { self.alloc.destroy(self.renderer_state.mutex); self.config.deinit(); - log.info("surface closed addr={x}", .{@intFromPtr(self)}); + log.info("surface closed id={x}", .{self.id}); } /// Close this surface. This will trigger the runtime to start the @@ -851,7 +861,7 @@ inline fn surfaceMailbox(self: *Surface) Mailbox { }; } -/// Queue a message for the IO thread. +/// Queue a message for the IO thread, taking ownership of `msg`. /// /// We centralize all our logic into this spot so we can intercept /// messages for example in readonly mode. @@ -866,7 +876,10 @@ fn queueIo( .write_small, .write_stable, .write_alloc, - => return, + => { + msg.deinit(); + return; + }, else => {}, } @@ -900,14 +913,14 @@ pub fn activateInspector(self: *Surface) !void { // Put the inspector onto the render state { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); assert(self.renderer_state.inspector == null); self.renderer_state.inspector = self.inspector; } // Notify our components we have an inspector active - _ = self.renderer_thread.mailbox.push(.{ .inspector = true }, .{ .forever = {} }); + _ = self.renderer_thread.mailbox.push(global.io(), .{ .inspector = true }, .{ .forever = {} }); self.queueIo(.{ .inspector = true }, .unlocked); } @@ -917,14 +930,14 @@ pub fn deactivateInspector(self: *Surface) void { // Remove the inspector from the render state { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); assert(self.renderer_state.inspector != null); self.renderer_state.inspector = null; } // Notify our components we have deactivated inspector - _ = self.renderer_thread.mailbox.push(.{ .inspector = false }, .{ .forever = {} }); + _ = self.renderer_thread.mailbox.push(global.io(), .{ .inspector = false }, .{ .forever = {} }); self.queueIo(.{ .inspector = false }, .unlocked); // Deinit the inspector @@ -948,8 +961,8 @@ pub fn needsConfirmQuit(self: *Surface) bool { .always => true, .false => false, .true => true: { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); break :true !self.io.terminal.cursorIsAtPrompt(); }, }; @@ -1049,6 +1062,10 @@ pub fn handleMessage(self: *Surface, msg: Message) !void { _ = try self.startClipboardRequest(.standard, .{ .osc_52_read = clipboard }); }, + .kitty_clipboard_read => |req| try self.kittyClipboardRead(req), + + .kitty_clipboard_write => |req| try self.kittyClipboardWrite(req), + .clipboard_write => |w| switch (w.req) { .small => |v| try self.clipboardWrite(v.data[0..v.len], w.clipboard_type), .stable => |v| try self.clipboardWrite(v, w.clipboard_type), @@ -1061,9 +1078,10 @@ pub fn handleMessage(self: *Surface, msg: Message) !void { .pwd_change => |w| { defer w.deinit(); - // We always allocate for this because we need to null-terminate. - const str = try self.alloc.dupeZ(u8, w.slice()); - defer self.alloc.free(str); + var stack = std.heap.stackFallback(256, self.alloc); + const alloc = stack.get(); + const str = try alloc.dupeZ(u8, w.slice()); + defer alloc.free(str); _ = try self.rt_app.performAction( .{ .surface = self }, @@ -1096,9 +1114,9 @@ pub fn handleMessage(self: *Surface, msg: Message) !void { .password_input => |v| try self.passwordInput(v), .ring_bell => bell: { - const now = std.time.Instant.now() catch unreachable; + const now: std.Io.Timestamp = .now(global.io(), .awake); if (self.last_bell_time) |last| { - if (now.since(last) < 100 * std.time.ns_per_ms) break :bell; + if (last.durationTo(now).toMilliseconds() < 100) break :bell; } self.last_bell_time = now; _ = self.rt_app.performAction( @@ -1126,15 +1144,22 @@ pub fn handleMessage(self: *Surface, msg: Message) !void { }, .start_command => { - self.command_timer = try .now(); + self.command_timer = .now(global.io(), .awake); }, .stop_command => |v| timer: { - const end: std.time.Instant = try .now(); + const end: std.Io.Timestamp = .now(global.io(), .awake); const start = self.command_timer orelse break :timer; self.command_timer = null; + const duration_raw = start.durationTo(end).nanoseconds; + assert(duration_raw >= 0 and duration_raw <= std.math.maxInt(u64)); - const duration: Duration = .{ .duration = end.since(start) }; + const duration: Duration = .{ + .duration = @as( + u64, + @intCast(std.math.clamp(start.durationTo(end).nanoseconds, 0, std.math.maxInt(u64))), + ), + }; log.debug("command took {f}", .{duration}); _ = self.rt_app.performAction( @@ -1185,8 +1210,8 @@ fn selectionScrollTick(self: *Surface) !void { const pos_vp = self.posToViewport(pos.x, pos.y); // We need our locked state for the remainder - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const t: *terminal.Terminal = self.renderer_state.terminal; const selection = self.mouse.selection_gesture.autoscrollTick(t, .{ @@ -1276,8 +1301,8 @@ fn childExited(self: *Surface, info: apprt.surface.Message.ChildExited) void { // If the native GUI can't be shown, display a text message in the // terminal. - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const t: *terminal.Terminal = self.renderer_state.terminal; t.carriageReturn(); t.linefeed() catch break :terminal; @@ -1316,8 +1341,8 @@ fn childExitedAbnormally( }); const runtime_str = try std.fmt.allocPrint(alloc, "{d} ms", .{info.runtime_ms}); - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const t: *terminal.Terminal = self.renderer_state.terminal; // No matter what move the cursor back to the column 0. @@ -1383,8 +1408,8 @@ fn childExitedAbnormally( /// Called when the terminal detects there is a password input prompt. fn passwordInput(self: *Surface, v: bool) !void { { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); // If our password input state is unchanged then we don't // waste time doing anything more. @@ -1436,6 +1461,7 @@ fn searchCallback_( for (matches) |*m| m.* = try m.clone(alloc); _ = self.renderer_thread.mailbox.push( + global.io(), .{ .search_viewport_matches = .{ .arena = arena, .matches = matches, @@ -1454,6 +1480,7 @@ fn searchCallback_( const match = try sel.highlight.clone(alloc); _ = self.renderer_thread.mailbox.push( + global.io(), .{ .search_selected_match = .{ .arena = arena, .match = match, @@ -1469,6 +1496,7 @@ fn searchCallback_( } else { // Reset our selected match _ = self.renderer_thread.mailbox.push( + global.io(), .{ .search_selected_match = null }, .forever, ); @@ -1493,10 +1521,12 @@ fn searchCallback_( // When we quit, tell our renderer to reset any search state. .quit => { _ = self.renderer_thread.mailbox.push( + global.io(), .{ .search_selected_match = null }, .forever, ); _ = self.renderer_thread.mailbox.push( + global.io(), .{ .search_viewport_matches = .{ .arena = .init(self.alloc), .matches = &.{}, @@ -1539,8 +1569,8 @@ fn modsChanged(self: *Surface, mods: input.Mods) void { // highlight links. Additionally, mark the screen as dirty so // that the highlight state of all links is properly updated. { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); self.renderer_state.mouse.mods = self.mouseModsWithCapture(self.mouse.mods); // We use the clear screen dirty flag to force a rebuild of all @@ -1786,7 +1816,7 @@ pub fn updateConfig( termio_config_ptr.* = try termio.Termio.DerivedConfig.init(self.alloc, config); errdefer termio_config_ptr.deinit(); - _ = self.renderer_thread.mailbox.push(renderer_message, .{ .forever = {} }); + _ = self.renderer_thread.mailbox.push(global.io(), renderer_message, .{ .forever = {} }); self.queueIo(.{ .change_config = .{ .alloc = self.alloc, @@ -1907,8 +1937,8 @@ pub fn dumpText( alloc: Allocator, sel: terminal.Selection, ) !Text { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); return try self.dumpTextLocked(alloc, sel); } @@ -2033,15 +2063,15 @@ pub fn dumpTextLocked( /// Returns true if the terminal has a selection. pub fn hasSelection(self: *const Surface) bool { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); return self.io.terminal.screens.active.selection != null; } /// Returns the selected text. This is allocated. pub fn selectionString(self: *Surface, alloc: Allocator) !?[:0]const u8 { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const sel = self.io.terminal.screens.active.selection orelse return null; return try self.io.terminal.screens.active.selectionString(alloc, .{ .sel = sel, @@ -2056,8 +2086,8 @@ pub fn pwd( self: *const Surface, alloc: Allocator, ) Allocator.Error!?[]const u8 { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const terminal_pwd = self.io.terminal.getPwd() orelse return null; return try alloc.dupe(u8, terminal_pwd); } @@ -2074,7 +2104,7 @@ fn resolvePathForOpening( const resolved = try std.fs.path.resolve(self.alloc, &.{ terminal_pwd, path }); - std.fs.accessAbsolute(resolved, .{}) catch { + std.Io.Dir.accessAbsolute(global.io(), resolved, .{}) catch { self.alloc.free(resolved); return null; }; @@ -2088,10 +2118,10 @@ fn resolvePathForOpening( /// Returns the x/y coordinate of where the IME (Input Method Editor) /// keyboard should be rendered. pub fn imePoint(self: *const Surface) apprt.IMEPos { - self.renderer_state.mutex.lock(); + self.renderer_state.mutex.lockUncancelable(global.io()); const cursor = self.renderer_state.terminal.screens.active.cursor; const preedit_width: usize = if (self.renderer_state.preedit) |preedit| preedit.width() else 0; - self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.unlock(global.io()); // TODO: need to handle when scrolling and the cursor is not // in the visible portion of the screen. @@ -2165,34 +2195,18 @@ fn clipboardWrite(self: *const Surface, data: []const u8, loc: apprt.Clipboard) return; } - const dec = std.base64.standard.Decoder; - - // Build buffer - const size = dec.calcSizeForSlice(data) catch |err| switch (err) { - error.InvalidPadding => { - log.info("application sent invalid base64 data for OSC 52", .{}); - return; - }, - - // Should not be reachable but don't want to risk it. - else => return, - }; - var buf = try self.alloc.allocSentinel(u8, size, 0); + // Decode with the SIMD decoder, strict per the Kitty clipboard + // spec that also governs OSC 52 base64 handling: a request with + // characters outside the base64 alphabet is discarded entirely + // (never partially decoded), while a missing-padding tail is + // tolerated since OSC 52 has no way to report errors. + var buf = try self.alloc.allocSentinel(u8, simd.base64.maxLen(data), 0); defer self.alloc.free(buf); - buf[buf.len] = 0; - - // Decode - dec.decode(buf, data) catch |err| switch (err) { - // Ignore this. It is possible to actually have valid data and - // get this error, so we allow it. - error.InvalidPadding => {}, - - else => { - log.info("application sent invalid base64 data for OSC 52", .{}); - return; - }, + const decoded = simd.base64.decodeStrict(data, buf, .optional) catch { + log.info("application sent invalid base64 data for OSC 52", .{}); + return; }; - assert(buf[buf.len] == 0); + buf[decoded.len] = 0; // When clipboard-write is "ask" a prompt is displayed to the user asking // them to confirm the clipboard access. Each app runtime handles this @@ -2200,7 +2214,7 @@ fn clipboardWrite(self: *const Surface, data: []const u8, loc: apprt.Clipboard) const confirm = self.config.clipboard_write == .ask; self.rt_surface.setClipboard(loc, &.{.{ .mime = "text/plain", - .data = buf, + .data = buf[0..decoded.len :0], }}, confirm) catch |err| { log.err("error setting clipboard string err={}", .{err}); return; @@ -2232,13 +2246,14 @@ fn copySelectionToClipboards( const ScreenFormatter = terminal.formatter.ScreenFormatter; var aw: std.Io.Writer.Allocating = .init(alloc); - var contents: std.ArrayList(apprt.ClipboardContent) = .empty; + var contents_buf: [2]apprt.ClipboardContent = undefined; + var contents: std.ArrayList(apprt.ClipboardContent) = .initBuffer(&contents_buf); switch (format) { .plain => { var formatter: ScreenFormatter = .init(self.io.terminal.screens.active, opts); formatter.content = .{ .selection = sel }; try formatter.format(&aw.writer); - try contents.append(alloc, .{ + contents.appendAssumeCapacity(.{ .mime = "text/plain", .data = try aw.toOwnedSliceSentinel(0), }); @@ -2255,7 +2270,7 @@ fn copySelectionToClipboards( // Note: We don't apply codepoint mappings to VT format since it contains // escape sequences that should be preserved as-is - try contents.append(alloc, .{ + contents.appendAssumeCapacity(.{ .mime = "text/plain", .data = try aw.toOwnedSliceSentinel(0), }); @@ -2272,7 +2287,7 @@ fn copySelectionToClipboards( // Note: We don't apply codepoint mappings to HTML format since HTML // has its own character encoding and entity system - try contents.append(alloc, .{ + contents.appendAssumeCapacity(.{ .mime = "text/html", .data = try aw.toOwnedSliceSentinel(0), }); @@ -2283,7 +2298,7 @@ fn copySelectionToClipboards( var formatter: ScreenFormatter = .init(self.io.terminal.screens.active, opts); formatter.content = .{ .selection = sel }; try formatter.format(&aw.writer); - try contents.append(alloc, .{ + contents.appendAssumeCapacity(.{ .mime = "text/plain", .data = try aw.toOwnedSliceSentinel(0), }); @@ -2306,7 +2321,7 @@ fn copySelectionToClipboards( try formatter.format(&aw.writer); // Note: We don't apply codepoint mappings to HTML format - try contents.append(alloc, .{ + contents.appendAssumeCapacity(.{ .mime = "text/html", .data = try aw.toOwnedSliceSentinel(0), }); @@ -2363,31 +2378,29 @@ fn setSelection(self: *Surface, sel_: ?terminal.Selection) !void { fn setSelectionAndCopy(self: *Surface, sel: terminal.Selection) !void { try self.setSelection(sel); - // If copy on select is false then exit early. - if (self.config.copy_on_select == .false) return; - switch (self.config.copy_on_select) { - .false => unreachable, // handled above with an early exit + .none => {}, - // Both standard and selection clipboards are set. + // The selection clipboard is set if supported, otherwise nothing is copied. + .primary => try self.copySelectionToClipboards( + sel, + &.{.selection}, + .mixed, + ), + + // Only the standard clipboard is set. .clipboard => try self.copySelectionToClipboards( sel, - &.{ .standard, .selection }, + &.{.standard}, .mixed, ), - // The selection clipboard is set if supported, otherwise the standard. - .true => { - const clipboard: apprt.Clipboard = if (self.rt_surface.supportsClipboard(.selection)) - .selection - else - .standard; - try self.copySelectionToClipboards( - sel, - &.{clipboard}, - .mixed, - ); - }, + // Both standard and selection clipboards are set. + .both => try self.copySelectionToClipboards( + sel, + &.{ .standard, .selection }, + .mixed, + ), } } @@ -2440,7 +2453,7 @@ pub fn setFontSize(self: *Surface, size: font.face.DesiredSize) !void { // Notify our render thread of the new font stack. The renderer // MUST accept the new font grid and deref the old. - _ = self.renderer_thread.mailbox.push(.{ + _ = self.renderer_thread.mailbox.push(global.io(), .{ .font_grid = .{ .grid = font_grid, .set = &self.app.font_grid_set, @@ -2530,8 +2543,8 @@ pub fn preeditCallback(self: *Surface, preedit_: ?[]const u8) !void { crash.sentry.thread_state = self.crashThreadState(); defer crash.sentry.thread_state = null; - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); // We clear our selection when ANY OF: // 1. We have an existing preedit @@ -2566,7 +2579,7 @@ pub fn preeditCallback(self: *Surface, preedit_: ?[]const u8) !void { // Allocate the codepoints slice const Codepoint = rendererpkg.State.Preedit.Codepoint; - var codepoints: std.ArrayListUnmanaged(Codepoint) = .{}; + var codepoints: std.ArrayList(Codepoint) = .empty; defer codepoints.deinit(self.alloc); while (it.nextCodepoint()) |cp| { const width: usize = @intCast(unicode.table.get(cp).width); @@ -2697,8 +2710,8 @@ pub fn keyCallback( )) |v| return v; // If we allow KAM and KAM is enabled then we do nothing. if (self.config.vt_kam_allowed) { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); if (self.io.terminal.modes.get(.disable_keyboard)) return .consumed; } @@ -2728,8 +2741,8 @@ pub fn keyCallback( { // Refresh our link state const pos = self.rt_surface.getCursorPos() catch break :mouse_mods; - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); self.mouseRefreshLinks( pos, self.posToViewport(pos.x, pos.y), @@ -2802,11 +2815,11 @@ pub fn keyCallback( // an encoded value, we close the surface. We want to eventually // move this behavior to the apprt probably. if (self.child_exited) { + write_req.deinit(); self.close(); return .closed; } - errdefer write_req.deinit(); self.queueIo(switch (write_req) { .small => |v| .{ .write_small = v }, .stable => |v| .{ .write_stable = v }, @@ -2821,8 +2834,8 @@ pub fn keyCallback( // some data to send to the pty, then we move the viewport down to the // bottom. We also clear the selection for any key other then modifiers. if (!event.key.modifier()) { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); if (self.config.selection_clear_on_typing or event.key == .escape) @@ -2924,16 +2937,19 @@ fn maybeHandleBinding( // Determine if this entry has an action or if its a leader key. const leaf: input.Binding.Set.GenericLeaf = switch (entry.value_ptr.*) { .leader => |set| { - // Setup the next set we'll look at. - self.keyboard.sequence_set = set; - // Store this event so that we can drain and encode on invalid. // We don't need to cap this because it is naturally capped by // the config validation. if (try self.encodeKey(event, insp_ev)) |req| { - try self.keyboard.sequence_queued.append(self.alloc, req); + self.keyboard.sequence_queued.append(self.alloc, req) catch |err| { + req.deinit(); + return err; + }; } + // Setup the next set we'll look at only after all fallible work. + self.keyboard.sequence_set = set; + // Start or continue our key sequence _ = self.rt_app.performAction( .{ .surface = self }, @@ -3222,17 +3238,15 @@ fn encodeKey( ); defer alloc_writer.deinit(); - // This results in a double allocation but this is such an unlikely - // path the performance impact is unimportant. try input.key_encode.encode( &alloc_writer.writer, event, encoding_opts, ); - break :req try termio.Message.WriteReq.init( - self.alloc, - alloc_writer.writer.buffered(), - ); + break :req .{ .alloc = .{ + .alloc = self.alloc, + .data = try alloc_writer.toOwnedSlice(), + } }; }; // Copy the encoded data into the inspector event if we have one. @@ -3253,8 +3267,8 @@ fn encodeKey( } fn encodeKeyOpts(self: *const Surface) input.key_encode.Options { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const t = &self.io.terminal; var opts: input.key_encode.Options = .fromTerminal(t); @@ -3295,9 +3309,27 @@ pub fn occlusionCallback(self: *Surface, visible: bool) !void { crash.sentry.thread_state = self.crashThreadState(); defer crash.sentry.thread_state = null; - _ = self.renderer_thread.mailbox.push(.{ + // Avoid duplicate renderer and visibility reports. + if (self.visible == visible) return; + self.visible = visible; + + // Update the terminal state for synchronous queries, then notify the IO + // thread so it can emit a mode 2033 report when enabled. + self.renderer_state.mutex.lockUncancelable(global.io()); + self.io.terminal.flags.visible = visible; + const report_visibility = self.io.terminal.modes.get(.report_visibility); + self.renderer_state.mutex.unlock(global.io()); + if (report_visibility) { + self.queueIo(.{ .visibility_report = .{ + .visible = visible, + .force = false, + } }, .unlocked); + } + + _ = self.renderer_thread.mailbox.push(global.io(), .{ .visible = visible, }, .{ .forever = {} }); + try self.queueRender(); } @@ -3315,7 +3347,7 @@ pub fn focusCallback(self: *Surface, focused: bool) !void { self.focused = focused; // Notify our render thread of the new state - _ = self.renderer_thread.mailbox.push(.{ + _ = self.renderer_thread.mailbox.push(global.io(), .{ .focus = focused, }, .{ .forever = {} }); @@ -3382,9 +3414,9 @@ pub fn focusCallback(self: *Surface, focused: bool) !void { // Update the focus state and notify the terminal { - self.renderer_state.mutex.lock(); + self.renderer_state.mutex.lockUncancelable(global.io()); self.io.terminal.flags.focused = focused; - self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.unlock(global.io()); self.queueIo(.{ .focused = focused }, .unlocked); } } @@ -3516,8 +3548,8 @@ pub fn scrollCallback( // log.info("SCROLL: delta_y={} delta_x={}", .{ y.delta, x.delta }); { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); // If we have an active mouse reporting mode, clear the selection. // The selection can occur if the user uses the shift mod key to @@ -3642,6 +3674,12 @@ fn isMouseReporting(self: *const Surface) bool { self.io.terminal.flags.mouse_event != .none; } +pub fn mouseReportingActive(self: *Surface) bool { + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); + return self.isMouseReporting(); +} + fn mouseReport( self: *Surface, button: ?input.MouseButton, @@ -3717,8 +3755,8 @@ fn mouseShiftCapture(self: *const Surface, lock: bool) bool { .false, .true => {}, } - if (lock) self.renderer_state.mutex.lock(); - defer if (lock) self.renderer_state.mutex.unlock(); + if (lock) self.renderer_state.mutex.lockUncancelable(global.io()); + defer if (lock) self.renderer_state.mutex.unlock(global.io()); // If the terminal explicitly requests it then we always allow it // since we processed never/always at this point. @@ -3739,8 +3777,8 @@ fn mouseShiftCapture(self: *const Surface, lock: bool) bool { /// Returns true if the mouse is currently captured by the terminal /// (i.e. reporting events). pub fn mouseCaptured(self: *Surface) bool { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); return self.io.terminal.flags.mouse_event != .none; } @@ -3796,21 +3834,12 @@ pub fn mouseButtonCallback( // If we are within the interval that the click would register // an increment then we do not extend the selection. - if (std.time.Instant.now()) |now| { - const click_time = self.mouse.selection_gesture.left_click_time orelse - break :extend_selection; - const since = now.since(click_time); - if (since <= self.config.mouse_interval) { - // Click interval very short, we may be increasing - // click counts so we don't extend the selection. - break :extend_selection; - } - } else |err| { - // This is a weird behavior, I think either behavior is actually - // fine. This failure should be exceptionally rare anyways. - // My thinking here is that we can't be sure if we should extend - // the selection or not so we just don't. - log.warn("failed to get time, not extending selection err={}", .{err}); + const click_time = self.mouse.selection_gesture.left_click_time orelse + break :extend_selection; + const since = click_time.untilNow(global.io(), .awake); + if (since.toNanoseconds() <= self.config.mouse_interval) { + // Click interval very short, we may be increasing + // click counts so we don't extend the selection. break :extend_selection; } @@ -3821,8 +3850,8 @@ pub fn mouseButtonCallback( } if (button == .left and action == .release) { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); // The selection gesture tracks whether a press became a drag by // comparing the release cell to the original press cell. Resolve the @@ -3860,7 +3889,7 @@ pub fn mouseButtonCallback( // The selection clipboard is only updated for left-click drag when // the left button is released. This is to avoid the clipboard // being updated on every mouse move which would be noisy. - if (self.config.copy_on_select != .false) { + if (self.config.copy_on_select != .none) { const prev_ = self.io.terminal.screens.active.selection; if (prev_) |prev| { try self.setSelectionAndCopy(terminal.Selection.init( @@ -3897,8 +3926,8 @@ pub fn mouseButtonCallback( // Report mouse events if enabled { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); if (self.isMouseReporting()) report: { // If we have shift-pressed and we aren't allowed to capture it, // then we do not do a mouse report. @@ -3937,8 +3966,8 @@ pub fn mouseButtonCallback( // For left button clicks we always record some information for // selection/highlighting purposes. if (button == .left and action == .press) click: { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const t: *terminal.Terminal = self.renderer_state.terminal; const screen: *terminal.Screen = self.renderer_state.terminal.screens.active; @@ -3962,12 +3991,8 @@ pub fn mouseButtonCallback( break :pin pin; }; - const time = std.time.Instant.now() catch |err| time: { - log.err("error reading time, mouse multi-click won't work err={}", .{err}); - break :time null; - }; var press_selection = try self.mouse.selection_gesture.press(t, .{ - .time = time, + .time = std.Io.Timestamp.now(global.io(), .awake), .pin = pin, .xpos = pos.x, .ypos = pos.y, @@ -4022,22 +4047,16 @@ pub fn mouseButtonCallback( } } - // Middle-click paste source follows copy-on-select: when copy-on-select - // targets the selection clipboard, middle-click reads from it; when - // copy-on-select targets the system clipboard, middle-click reads from - // that instead. Falls back to the standard clipboard on platforms that - // do not support the selection clipboard. + // Middle-click action, either ignore, or paste from clipboard or paste from the selection clipboard if supported. if (button == .middle and action == .press) switch (self.config.middle_click_action) { .ignore => {}, + .@"clipboard-paste" => { + _ = try self.startClipboardRequest(.standard, .{ .paste = .standard }); + }, .@"primary-paste" => { - const clipboard: apprt.Clipboard = switch (self.config.copy_on_select) { - .clipboard => .standard, - .true, .false => if (self.rt_surface.supportsClipboard(.selection)) - .selection - else - .standard, - }; - _ = try self.startClipboardRequest(clipboard, .{ .paste = {} }); + if (self.rt_surface.supportsClipboard(.selection)) { + _ = try self.startClipboardRequest(.selection, .{ .paste = .selection }); + } }, }; @@ -4047,8 +4066,8 @@ pub fn mouseButtonCallback( // want to be careful in the future we can add a function to apprts // that let's us know. if (button == .right and action == .press) sel: { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); // Get our viewport pin const screen: *terminal.Screen = self.renderer_state.terminal.screens.active; @@ -4119,9 +4138,9 @@ pub fn mouseButtonCallback( } else { // Pasting can trigger a lock grab in complete clipboard // request so we need to unlock. - self.renderer_state.mutex.unlock(); - defer self.renderer_state.mutex.lock(); - _ = try self.startClipboardRequest(.standard, .paste); + self.renderer_state.mutex.unlock(global.io()); + defer self.renderer_state.mutex.lockUncancelable(global.io()); + _ = try self.startClipboardRequest(.standard, .{ .paste = .standard }); // We don't need to clear selection because we didn't have // one to begin with. @@ -4134,9 +4153,9 @@ pub fn mouseButtonCallback( // Pasting can trigger a lock grab in complete clipboard // request so we need to unlock. - self.renderer_state.mutex.unlock(); - defer self.renderer_state.mutex.lock(); - _ = try self.startClipboardRequest(.standard, .paste); + self.renderer_state.mutex.unlock(global.io()); + defer self.renderer_state.mutex.lockUncancelable(global.io()); + _ = try self.startClipboardRequest(.standard, .{ .paste = .standard }); }, } @@ -4295,7 +4314,9 @@ fn linkAtPos( const mouse_mods = self.mouseModsWithCapture(self.mouse.mods); // If we have the proper modifiers set then we can check for OSC8 links. - if (mouse_mods.equal(input.ctrlOrSuper(.{}))) hyperlink: { + if (self.config.link_osc8 and + mouse_mods.equal(input.ctrlOrSuper(.{}))) + hyperlink: { const rac = mouse_pin.rowAndCell(); const cell = rac.cell; if (!cell.hyperlink) break :hyperlink; @@ -4329,12 +4350,10 @@ fn linkAtPin( .semantic_prompt_boundary = true, }) orelse return null; - var strmap: terminal.StringMap = undefined; - self.alloc.free(try screen.selectionString(self.alloc, .{ + const strmap = try screen.selectionStringMap(self.alloc, .{ .sel = line, .trim = false, - .map = &strmap, - })); + }); defer strmap.deinit(self.alloc); for (self.config.links) |link| { @@ -4405,7 +4424,7 @@ fn processLinks(self: *Surface, pos: apprt.CursorPos) !bool { log.warn("failed to get URI for OSC8 hyperlink", .{}); return false; }; - try self.openUrl(.{ .kind = .unknown, .url = uri }); + try self.openUrl(.{ .kind = .osc8, .url = uri }); }, } @@ -4428,7 +4447,6 @@ fn openUrl( // apprts to handle this themselves. log.warn("apprt did not handle open URL action, falling back to default opener", .{}); try internal_os.open( - self.alloc, action.kind, action.url, ); @@ -4474,8 +4492,8 @@ pub fn mousePressureCallback( if (self.mouse.click_state[left_idx] == .press and stage == .deep) select: { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const sel = self.mouse.selection_gesture.deepPress( self.renderer_state.terminal, @@ -4540,8 +4558,8 @@ pub fn cursorPosCallback( try self.queueRender(); } - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); // No mouse point so we don't highlight links self.renderer_state.mouse.point = null; @@ -4567,8 +4585,8 @@ pub fn cursorPosCallback( self.mouse.over_link = false; // We are reading/writing state for the remainder - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); // Update our mouse state. We set this to null initially because we only // want to set it when we're not selecting or doing any other mouse @@ -4824,8 +4842,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool // CSI/ESC triggers a scroll. { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); self.scrollToBottom() catch |err| { log.warn("error scrolling to bottom err={}", .{err}); }; @@ -4833,10 +4851,10 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool }, .text => |data| { - // For text we always allocate just because its easier to - // handle all cases that way. - const buf = try self.alloc.alloc(u8, data.len); - defer self.alloc.free(buf); + var stack = std.heap.stackFallback(256, self.alloc); + const alloc = stack.get(); + const buf = try alloc.alloc(u8, data.len); + defer alloc.free(buf); const text = configpkg.string.parse(buf, data) catch |err| { log.warn( "error parsing text binding text={s} err={}", @@ -4851,8 +4869,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool // Text triggers a scroll. { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); self.scrollToBottom() catch |err| { log.warn("error scrolling to bottom err={}", .{err}); }; @@ -4864,8 +4882,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool // in cursor keys mode. We're in "normal" mode if cursor // keys mode is NOT set. const normal = normal: { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); // With the lock held, we must scroll to the bottom. // We always scroll to the bottom for these inputs. @@ -4884,8 +4902,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool }, .reset => { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); self.renderer_state.terminal.fullReset(); }, @@ -4955,7 +4973,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool terminal.search.Thread.threadMain, .{&s.state}, ); - s.thread.setName("search") catch {}; + s.thread.setName(global.io(), "search") catch {}; break :init s; }; @@ -4968,6 +4986,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool } _ = s.state.mailbox.push( + global.io(), .{ .change_needle = try .init( self.alloc, text, @@ -4980,6 +4999,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool .navigate_search => |nav| { const s: *Search = if (self.search) |*s| s else return false; _ = s.state.mailbox.push( + global.io(), .{ .select = switch (nav) { .next => .next, .previous => .prev, @@ -4990,8 +5010,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool }, .copy_to_clipboard => |format| { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); if (self.io.terminal.screens.active.selection) |sel| { try self.copySelectionToClipboards( @@ -5022,8 +5042,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool if (!self.mouse.over_link) return false; const pos = try self.rt_surface.getCursorPos(); - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); if (try self.linkAtPos(pos)) |link_info| { const url_text = switch (link_info.action) { .open => url_text: { @@ -5068,15 +5088,15 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool {}, ), - .paste_from_clipboard => return try self.startClipboardRequest( + .paste_from_clipboard => return (try self.startClipboardRequest( .standard, - .{ .paste = {} }, - ), + .{ .paste = .standard }, + )) == .started, - .paste_from_selection => return try self.startClipboardRequest( + .paste_from_selection => return (try self.startClipboardRequest( .selection, - .{ .paste = {} }, - ), + .{ .paste = .selection }, + )) == .started, .increase_font_size => |delta| { // Max delta is somewhat arbitrary. @@ -5141,6 +5161,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool .tab, ), + .prompt_window_title => return try self.rt_app.performAction( + .{ .surface = self }, + .prompt_title, + .window, + ), + .set_surface_title => |v| { const title = try self.alloc.dupeZ(u8, v); defer self.alloc.free(title); @@ -5161,6 +5187,16 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool ); }, + .set_window_title => |v| { + const title = try self.alloc.dupeZ(u8, v); + defer self.alloc.free(title); + return try self.rt_app.performAction( + .{ .surface = self }, + .set_window_title, + .{ .title = title }, + ); + }, + .clear_screen => { // This is a duplicate of some of the logic in termio.clearScreen // but we need to do this here so we can know the answer before @@ -5168,8 +5204,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool // alternate screen then clear screen does nothing so we want to // return false so the keybind can be unconsumed. { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); if (self.io.terminal.screens.active_key == .alternate) return false; } @@ -5192,8 +5228,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool .scroll_to_row => |n| { { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const t: *terminal.Terminal = self.renderer_state.terminal; t.screens.active.scroll(.{ .row = n }); } @@ -5203,8 +5239,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool .scroll_to_selection => { { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const sel = self.io.terminal.screens.active.selection orelse return false; const tl = sel.topLeft(self.io.terminal.screens.active); self.io.terminal.screens.active.scroll(.{ .pin = tl }); @@ -5300,6 +5336,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool .{ .amount = position }, ), + .move_tab_to_new_window => return try self.rt_app.performAction( + .{ .surface = self }, + .move_tab_to_new_window, + {}, + ), + .new_split => |direction| return try self.rt_app.performAction( .{ .surface = self }, .new_split, @@ -5442,8 +5484,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool ), .select_all => { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const sel = self.io.terminal.screens.active.selectAll(); if (sel) |s| { @@ -5564,7 +5606,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool .main => @panic("crash binding action, crashing intentionally"), .render => { - _ = self.renderer_thread.mailbox.push(.{ .crash = {} }, .{ .forever = {} }); + _ = self.renderer_thread.mailbox.push(global.io(), .{ .crash = {} }, .{ .forever = {} }); self.queueRender() catch |err| { // Not a big deal if this fails. log.warn("failed to notify renderer of crash message err={}", .{err}); @@ -5575,8 +5617,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool }, .adjust_selection => |direction| { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const screen: *terminal.Screen = self.io.terminal.screens.active; const sel = if (screen.selection) |*sel| sel else { @@ -5655,7 +5697,8 @@ fn writeScreenFile( ) !void { // Create a temporary directory to store our scrollback. var tmp_dir = try internal_os.TempDir.init(); - errdefer tmp_dir.deinit(); + var retain_tmp_dir = false; + defer if (retain_tmp_dir) tmp_dir.close(.retain) else tmp_dir.deinit(); var filename_buf: [std.fs.max_path_bytes]u8 = undefined; const filename = try std.fmt.bufPrint( @@ -5672,23 +5715,24 @@ fn writeScreenFile( // Open our scrollback file var file = try tmp_dir.dir.createFile( + global.io(), filename, switch (builtin.os.tag) { .windows => .{}, - else => .{ .mode = 0o600 }, + else => .{ .permissions = .fromMode(0o600) }, }, ); - defer file.close(); + defer file.close(global.io()); // Screen.dumpString writes byte-by-byte, so buffer it var buf: [4096]u8 = undefined; - var file_writer = file.writer(&buf); + var file_writer = file.writer(global.io(), &buf); var buf_writer = &file_writer.interface; // Write the scrollback contents. This requires a lock. { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); // We only dump history if we have history. We still keep // the file and write the empty file to the pty so that this @@ -5724,7 +5768,6 @@ fn writeScreenFile( const sel = sel_ orelse { // If we have no selection we have no data so we do nothing. - tmp_dir.deinit(); return; }; @@ -5751,7 +5794,11 @@ fn writeScreenFile( // Get the final path var path_buf: [std.fs.max_path_bytes]u8 = undefined; - const path = try tmp_dir.dir.realpath(filename, &path_buf); + const path = path_buf[0..try tmp_dir.dir.realPathFile( + global.io(), + filename, + &path_buf, + )]; switch (write_screen.action) { .copy => { @@ -5774,71 +5821,294 @@ fn writeScreenFile( path, ), .unlocked), } + + // The action accepted the path, so retain the file for its consumer. + retain_tmp_dir = true; } +/// The payload for completing a clipboard request with +/// completeClipboardRequest. +pub const CompleteClipboard = struct { + /// The representations the apprt could serve for the request's MIME + /// types. These are immediately copied as needed so they only need + /// to live for the duration of the completion call. Requesters that + /// only carry text (paste, OSC 52) use the first text-like + /// representation. + contents: []const terminal.clipboard.Content = &.{}, + + /// The listing of MIME types available on the clipboard, only + /// gathered when the request asked for it. + available: []const []const u8 = &.{}, + + /// True if any clipboard confirmation prompt was already answered + /// by the user, skipping further prompts: + /// + /// - For "regular" pasting this means that unsafe pastes are + /// allowed. Unsafe data is defined as data that contains + /// newlines, though this definition may change later to detect + /// other scenarios. + /// + /// - For OSC 52 and Kitty clipboard protocol reads and writes no + /// prompt is shown to the user when this is true. + confirmed: bool = false, + + /// True if the user asked to remember their decision. This is only + /// honored by request types that support session grants (Kitty + /// clipboard protocol requests carrying a password). + remember: bool = false, +}; + /// Call this to complete a clipboard request sent to apprt. This should -/// only be called once for each request. The data is immediately copied so -/// it is safe to free the data after this call. -/// -/// If `confirmed` is true then any clipboard confirmation prompts are skipped: -/// -/// - For "regular" pasting this means that unsafe pastes are allowed. Unsafe -/// data is defined as data that contains newlines, though this definition -/// may change later to detect other scenarios. -/// -/// - For OSC 52 reads and writes no prompt is shown to the user if -/// `confirmed` is true. +/// only be called once for each request. /// -/// If `confirmed` is false then this may return either an UnsafePaste or -/// UnauthorizedPaste error, depending on the type of clipboard request. +/// If `complete.confirmed` is false then this may return either an +/// UnsafePaste or UnauthorizedPaste error, depending on the type of +/// clipboard request. The request state remains alive in that case so +/// the apprt can run its confirmation flow. pub fn completeClipboardRequest( self: *Surface, req: apprt.ClipboardRequest, - data: [:0]const u8, - confirmed: bool, + complete: CompleteClipboard, ) !void { switch (req) { - .paste => try self.completeClipboardPaste(data, confirmed), + .paste => try self.completeClipboardPaste( + clipboardTextContent(complete.contents) orelse "", + complete.confirmed, + ), + + .list => |clipboard| if (!try self.completeClipboardPasteEvent( + clipboard, + complete.available, + )) { + log.debug("mode 5522 paste event was not written", .{}); + }, .osc_52_read => |clipboard| try self.completeClipboardReadOSC52( - data, + clipboardTextContent(complete.contents) orelse "", clipboard, - confirmed, + complete.confirmed, ), - .osc_52_write => |clipboard| try self.rt_surface.setClipboard(clipboard, &.{.{ - .mime = "text/plain", - .data = data, - }}, !confirmed), + .osc_52_write => |clipboard| { + // The write API wants sentinel-terminated data; the write + // text round-tripped through the apprt confirmation flow as + // a plain representation. + const data = try self.alloc.dupeZ( + u8, + clipboardTextContent(complete.contents) orelse "", + ); + defer self.alloc.free(data); + try self.rt_surface.setClipboard(clipboard, &.{.{ + .mime = "text/plain", + .data = data, + }}, !complete.confirmed); + }, + + .kitty_read => |kitty| { + // If we need confirmation we return an error without + // consuming the request state; the apprt keeps it alive + // for the confirmation flow. A session grant carried by + // the request skips the prompt, and a request with no + // data types is exempt from prompting entirely; see + // readPromptExempt. + if (self.config.clipboard_read == .ask and + !complete.confirmed and + !kitty.granted and + !terminal.kitty.clipboard.readPromptExempt(kitty.mimes.len)) + { + return error.UnauthorizedPaste; + } + + // Past the confirmation check the request is consumed: + // every path from here, including errors, must destroy it. + defer kitty.destroy(); + + // Record a session grant when the user asked to remember + // their decision and the request carried a usable + // password. The grants live with the terminal state on + // the IO thread. + if (complete.remember and kitty.pw.len > 0) { + const pw = try self.alloc.dupe(u8, kitty.pw); + self.queueIo(.{ .kitty_clipboard_grant_read = .{ + .alloc = self.alloc, + .pw = pw, + } }, .unlocked); + } + + try self.completeKittyClipboardRead( + kitty, + complete.contents, + complete.available, + ); + }, + + .kitty_write => |kitty| { + // If we need confirmation we return an error without + // consuming the request state; the apprt keeps it alive + // for the confirmation flow. A session grant carried by + // the request skips the prompt. + if (self.config.clipboard_write == .ask and + !complete.confirmed and + !kitty.granted) + { + return error.UnauthorizedPaste; + } + + // Past the confirmation check the request is consumed: + // every path from here, including errors, must destroy it. + defer kitty.destroy(); + + // Record a session grant when the user asked to remember + // their decision and the request carried a usable + // password. The grants live with the terminal state on + // the IO thread. + if (complete.remember and kitty.pw.len > 0) { + const pw = try self.alloc.dupe(u8, kitty.pw); + self.queueIo(.{ .kitty_clipboard_grant_write = .{ + .alloc = self.alloc, + .pw = pw, + } }, .unlocked); + } + + // Apply the committed representations carried by the + // request itself; any contents echoed back by the apprt + // are only what its confirmation prompt displayed. An + // empty commit clears the clipboard, which the apprt + // write API expresses as a single empty text entry. + self.rt_surface.setClipboard( + kitty.location, + if (kitty.contents.len > 0) kitty.contents else &.{.{ + .mime = "text/plain", + .data = "", + }}, + false, + ) catch |err| { + log.err("error setting clipboard err={}", .{err}); + try self.kittyClipboardStatus( + .write, + kitty.id, + kitty.terminator, + .EIO, + ); + return; + }; + + try self.kittyClipboardStatus( + .write, + kitty.id, + kitty.terminator, + .DONE, + ); + }, + } +} + +/// The first text-like representation of the contents, if any. +fn clipboardTextContent(contents: []const terminal.clipboard.Content) ?[]const u8 { + for (contents) |content| { + if (terminal.clipboard.isTextMime(content.mime)) return content.data; + } + return null; +} + +/// Deny an in-flight clipboard request. This consumes the request: for +/// request types whose protocol expects an answer, the denial reply is +/// written to the pty. +pub fn denyClipboardRequest(self: *Surface, req: apprt.ClipboardRequest) void { + switch (req) { + // A denied paste simply doesn't happen. + .paste, .list => {}, + + // OSC 52 has no error responses, but the client is waiting on + // a reply, so a denied read is answered with empty contents. + .osc_52_read => |clipboard| self.completeClipboardReadOSC52( + "", + clipboard, + true, + ) catch |err| { + log.warn("error replying to OSC 52 clipboard read err={}", .{err}); + }, + + // A denied write simply doesn't happen. + .osc_52_write => {}, + + // The Kitty clipboard protocol reports denial explicitly. + .kitty_read => |kitty| { + defer kitty.destroy(); + self.kittyClipboardStatus( + .read, + kitty.id, + kitty.terminator, + .EPERM, + ) catch |err| { + log.warn("error replying to kitty clipboard read err={}", .{err}); + }; + }, + + .kitty_write => |kitty| { + defer kitty.destroy(); + self.kittyClipboardStatus( + .write, + kitty.id, + kitty.terminator, + .EPERM, + ) catch |err| { + log.warn("error replying to kitty clipboard write err={}", .{err}); + }; + }, } } /// This starts a clipboard request, with some basic validation. For example, /// an OSC 52 request is not actually requested if OSC 52 is disabled. /// -/// Returns true if the request was started, false if it was not (e.g., clipboard -/// doesn't contain text for paste requests). This allows performable keybinds -/// to pass through when the action cannot be performed. +/// The result reports whether the request was started; requests that +/// weren't started never complete. Callers own reacting to that, e.g. +/// performable paste keybinds pass through and Kitty clipboard reads +/// answer the program. fn startClipboardRequest( self: *Surface, loc: apprt.Clipboard, req: apprt.ClipboardRequest, -) !bool { - switch (req) { - .paste => {}, // always allowed +) !apprt.ClipboardReadResult { + const effective_req: apprt.ClipboardRequest = switch (req) { + .paste => |clipboard| effective: { + // Snapshot the mode before asking the apprt for clipboard data. + // Event pastes request only a MIME listing, while ordinary + // pastes request the text representation as before. + self.renderer_state.mutex.lockUncancelable(global.io()); + const event = self.io.terminal.modes.get(.kitty_paste_events); + self.renderer_state.mutex.unlock(global.io()); + + break :effective if (event) + .{ .list = clipboard } + else + req; + }, + else => req, + }; + + switch (effective_req) { + .paste, .list => {}, // always allowed .osc_52_read => if (self.config.clipboard_read == .deny) { log.info( "application attempted to read clipboard, but 'clipboard-read' is set to deny", .{}, ); - return false; + return .unsupported; }, - // No clipboard write code paths travel through this function + // The clipboard access policies were already applied by + // kittyClipboardRead and kittyClipboardWrite, which own + // replying on denial. + .kitty_read, .kitty_write => {}, + + // OSC 52 writes don't travel through this function; they go + // straight to the apprt setClipboard API. .osc_52_write => unreachable, } - return try self.rt_surface.clipboardRequest(loc, req); + return try self.rt_surface.clipboardRequest(loc, effective_req); } fn completeClipboardPaste( @@ -5849,8 +6119,8 @@ fn completeClipboardPaste( if (data.len == 0) return; const encode_opts: input.paste.Options = encode_opts: { - self.renderer_state.mutex.lock(); - defer self.renderer_state.mutex.unlock(); + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); const opts: input.paste.Options = .fromTerminal(&self.io.terminal); // If we have paste protection enabled, we detect unsafe pastes and return @@ -5920,6 +6190,63 @@ fn completeClipboardPaste( }; } +/// Send a Kitty clipboard-protocol paste event when mode 5522 is enabled. +/// The event only lists the available MIME types; it does not read any of +/// their data. The shared terminal paste implementation generates and records +/// the one-time password used by the program's follow-up OSC 5522 read. +fn completeClipboardPasteEvent( + self: *Surface, + clipboard: apprt.Clipboard, + available: []const []const u8, +) !bool { + if (self.readonly) return false; + + const kitty_clipboard = terminal.kitty.clipboard; + const location: terminal.clipboard.Location = switch (clipboard) { + .standard => .standard, + .selection => .selection, + .primary => .primary, + }; + + // The protocol implementation caps listings at this size too. Cap here + // so the temporary Content array stays on the stack. + var contents_buf: [kitty_clipboard.max_listing_mimes]terminal.clipboard.Content = undefined; + const contents_len = @min(available.len, contents_buf.len); + for (available[0..contents_len], contents_buf[0..contents_len]) |mime, *content| { + content.* = .{ .mime = mime, .data = "" }; + } + + var aw: std.Io.Writer.Allocating = .init(self.alloc); + defer aw.deinit(); + + self.renderer_state.mutex.lockUncancelable(global.io()); + defer self.renderer_state.mutex.unlock(global.io()); + + const pasted = try terminal.paste.paste(.{ + .terminal = &self.io.terminal, + .alloc = self.alloc, + .writer = &aw.writer, + .kitty_clipboard = .{ + .grants = &self.io.terminal_stream.handler.kitty_clipboard_grants, + .io = global.io(), + }, + }, .{ + .source = .{ .clipboard = location }, + .contents = .{ .memory = contents_buf[0..contents_len] }, + // A paste event discloses no clipboard data, so unsafe-text + // confirmation does not apply. If mode 5522 is reset, the empty + // stand-in representations cause the shared helper to write nothing. + .allow_unsafe = true, + }); + if (!pasted) return false; + + self.queueIo(.{ .write_alloc = .{ + .alloc = self.alloc, + .data = try aw.toOwnedSlice(), + } }, .locked); + return true; +} + fn completeClipboardReadOSC52( self: *Surface, data: []const u8, @@ -5940,8 +6267,8 @@ fn completeClipboardReadOSC52( // This must hold the base64 encoded data PLUS the OSC code surrounding it. const enc = std.base64.standard.Encoder; const size = enc.calcSize(data.len); - var buf = try self.alloc.alloc(u8, size + 9); // const for OSC - defer self.alloc.free(buf); + const buf = try self.alloc.alloc(u8, size + 9); // const for OSC + errdefer self.alloc.free(buf); const kind: u8 = switch (clipboard_type) { .standard => 'c', @@ -5959,10 +6286,177 @@ fn completeClipboardReadOSC52( const encoded = enc.encode(buf[prefix.len..], data); assert(encoded.len == size); - self.queueIo(try termio.Message.writeReq( - self.alloc, - buf, - ), .unlocked); + self.queueIo(.{ .write_alloc = .{ + .alloc = self.alloc, + .data = buf, + } }, .unlocked); +} + +/// Handle a Kitty clipboard protocol (OSC 5522) read request forwarded +/// by the IO thread. This takes ownership of the request state. +fn kittyClipboardRead( + self: *Surface, + req: *apprt.ClipboardRequest.KittyRead, +) !void { + // A read denied by policy answers EPERM so clients degrade + // gracefully instead of waiting on a response that never comes. + if (self.config.clipboard_read == .deny) { + defer req.destroy(); + log.info("application attempted to read clipboard, but 'clipboard-read' is set to deny", .{}); + try self.kittyClipboardStatus(.read, req.id, req.terminator, .EPERM); + return; + } + + const result = self.startClipboardRequest( + req.location, + .{ .kitty_read = req }, + ) catch |err| { + defer req.destroy(); + self.kittyClipboardStatus(.read, req.id, req.terminator, .EIO) catch {}; + return err; + }; + + switch (result) { + // The request completes asynchronously. + .started => {}, + + // The clipboard has nothing we can serve, which is a + // successful read that serves no representations. This never + // prompts even under an ask policy since there are no contents + // to disclose. + .unavailable => { + defer req.destroy(); + try self.completeKittyClipboardRead(req, &.{}, &.{}); + }, + + // The apprt can't serve this clipboard at all, e.g. an + // unsupported primary selection. + .unsupported => { + defer req.destroy(); + try self.kittyClipboardStatus(.read, req.id, req.terminator, .ENOSYS); + }, + } +} + +/// Handle a committed Kitty clipboard protocol (OSC 5522) write +/// transaction forwarded by the IO thread. This takes ownership of the +/// request state. +fn kittyClipboardWrite( + self: *Surface, + req: *apprt.ClipboardRequest.KittyWrite, +) !void { + // A write denied by policy answers EPERM so clients degrade + // gracefully instead of waiting on a response that never comes. + // The IO thread already fails transactions that begin under a + // deny policy, but the policy may have changed mid-transaction. + if (self.config.clipboard_write == .deny) { + defer req.destroy(); + log.info("application attempted to write clipboard, but 'clipboard-write' is set to deny", .{}); + try self.kittyClipboardStatus(.write, req.id, req.terminator, .EPERM); + return; + } + + const result = self.startClipboardRequest( + req.location, + .{ .kitty_write = req }, + ) catch |err| { + defer req.destroy(); + self.kittyClipboardStatus(.write, req.id, req.terminator, .EIO) catch {}; + return err; + }; + + switch (result) { + // The request completes asynchronously. + .started => {}, + + // The apprt can't write this clipboard at all, e.g. an + // unsupported primary selection. Writes carry their own + // contents so there is no meaningful unavailable state; treat + // it the same. + .unavailable, .unsupported => { + defer req.destroy(); + try self.kittyClipboardStatus(.write, req.id, req.terminator, .ENOSYS); + }, + } +} + +/// Reply to a Kitty clipboard request with a single status packet. +fn kittyClipboardStatus( + self: *Surface, + op: terminal.kitty.clipboard.Operation, + id: []const u8, + terminator: terminal.osc.Terminator, + status: terminal.kitty.clipboard.Status, +) error{ OutOfMemory, WriteFailed }!void { + var aw: std.Io.Writer.Allocating = .init(self.alloc); + defer aw.deinit(); + try (terminal.kitty.clipboard.Response{ + .op = op, + .status = status, + .id = id, + .terminator = terminator, + }).encode(&aw.writer); + + self.queueIo(.{ .write_alloc = .{ + .alloc = self.alloc, + .data = try aw.toOwnedSlice(), + } }, .unlocked); +} + +/// Complete a Kitty clipboard protocol read with the clipboard +/// contents. +fn completeKittyClipboardRead( + self: *Surface, + req: *const apprt.ClipboardRequest.KittyRead, + contents: []const terminal.clipboard.Content, + available: []const []const u8, +) !void { + const kitty_clipboard = terminal.kitty.clipboard; + + // Serve the requested representations in request order under their + // requested names. Text-like MIME aliases all match the canonical + // text representation, since that is the only name the apprt + // serves text under. Requested types without a representation are + // simply never served, which is how the protocol communicates an + // unavailable representation. + var contents_buf: [kitty_clipboard.max_read_mimes]terminal.clipboard.Content = undefined; + var contents_len: usize = 0; + for (req.mimes) |mime| { + const data: []const u8 = data: { + for (contents) |content| { + if (std.mem.eql(u8, content.mime, mime)) break :data content.data; + if (terminal.clipboard.isTextMime(mime) and + terminal.clipboard.isTextMime(content.mime)) + { + break :data content.data; + } + } + + continue; + }; + + contents_buf[contents_len] = .{ .mime = mime, .data = data }; + contents_len += 1; + } + + // Encode the full success sequence: the OK packet, the targets + // listing if it was requested, DATA chunks for each served + // representation, and the final DONE packet. + var aw: std.Io.Writer.Allocating = .init(self.alloc); + defer aw.deinit(); + try (kitty_clipboard.ReadSuccess{ + .primary = req.location == .primary, + .id = req.id, + .list = req.list, + .available = available, + .contents = contents_buf[0..contents_len], + .terminator = req.terminator, + }).encode(&aw.writer); + + self.queueIo(.{ .write_alloc = .{ + .alloc = self.alloc, + .data = try aw.toOwnedSlice(), + } }, .unlocked); } fn showDesktopNotification(self: *Surface, title: [:0]const u8, body: [:0]const u8) !void { @@ -5970,12 +6464,12 @@ fn showDesktopNotification(self: *Surface, title: [:0]const u8, body: [:0]const // how fast identical notifications can be sent sequentially. const hash_algorithm = std.hash.Wyhash; - const now = try std.time.Instant.now(); + const now: std.Io.Timestamp = .now(global.io(), .awake); // Set a limit of one desktop notification per second so that the OS // doesn't kill us when we run out of resources. if (self.app.last_notification_time) |last| { - if (now.since(last) < 1 * std.time.ns_per_s) { + if (last.durationTo(now).toSeconds() < 1) { log.warn("rate limiting desktop notifications", .{}); return; } @@ -5992,7 +6486,7 @@ fn showDesktopNotification(self: *Surface, title: [:0]const u8, body: [:0]const // notifications with identical content. if (self.app.last_notification_time) |last| { if (self.app.last_notification_digest == new_digest) { - if (now.since(last) < 5 * std.time.ns_per_s) { + if (last.durationTo(now).toSeconds() < 5) { log.warn("suppressing identical desktop notification", .{}); return; } @@ -6034,3 +6528,18 @@ fn presentSurface(self: *Surface) !void { pub fn getProcessInfo(self: *Surface, comptime info: ProcessInfo) ?ProcessInfo.Type(info) { return self.io.getProcessInfo(info); } + +test "queueIo frees allocated writes in readonly mode" { + const testing = std.testing; + + const surface = try testing.allocator.create(Surface); + defer testing.allocator.destroy(surface); + surface.readonly = true; + + // queueIo must free allocated writes in read-only mode. + const data = try testing.allocator.dupe(u8, "\x1b]lGhostty\x1b\\"); + surface.queueIo(.{ .write_alloc = .{ + .alloc = testing.allocator, + .data = data, + } }, .unlocked); +} diff --git a/vendor/libghostty-vt/src/apprt.zig b/vendor/libghostty-vt/src/apprt.zig index c467f180..22256cc9 100644 --- a/vendor/libghostty-vt/src/apprt.zig +++ b/vendor/libghostty-vt/src/apprt.zig @@ -27,6 +27,7 @@ pub const Target = action.Target; pub const ContentScale = structs.ContentScale; pub const Clipboard = structs.Clipboard; pub const ClipboardContent = structs.ClipboardContent; +pub const ClipboardReadResult = structs.ClipboardReadResult; pub const ClipboardRequest = structs.ClipboardRequest; pub const ClipboardRequestType = structs.ClipboardRequestType; pub const ColorScheme = structs.ColorScheme; @@ -51,6 +52,15 @@ pub const runtime = switch (build_config.artifact) { pub const App = runtime.App; pub const Surface = runtime.Surface; +/// True if all GPU operations (drawing, resource creation and +/// destruction) must happen on the app thread. This is the case +/// when the graphics context is owned by the app thread (GTK's +/// GLArea). When false, the render thread performs GPU operations +/// itself. +pub const must_draw_from_app_thread = + @hasDecl(App, "must_draw_from_app_thread") and + App.must_draw_from_app_thread; + test { _ = Runtime; _ = runtime; diff --git a/vendor/libghostty-vt/src/apprt/action.zig b/vendor/libghostty-vt/src/apprt/action.zig index 4728d73c..7e902e56 100644 --- a/vendor/libghostty-vt/src/apprt/action.zig +++ b/vendor/libghostty-vt/src/apprt/action.zig @@ -8,6 +8,7 @@ const renderer = @import("../renderer.zig"); const terminal = @import("../terminal/main.zig"); const CoreSurface = @import("../Surface.zig"); const lib = @import("../lib/main.zig"); +const compat_testing = @import("../lib/compat/testing.zig"); /// The target for an action. This is generally the thing that had focus /// while the action was made but the concept of "focus" is not guaranteed @@ -195,6 +196,9 @@ pub const Action = union(Key) { /// rendered at the next opportunity. render_inspector, + /// Export the Terminal IO inspector event log. + export_terminal_io: ExportTerminalIO, + /// Show a desktop notification. desktop_notification: DesktopNotification, @@ -204,6 +208,9 @@ pub const Action = union(Key) { /// Set the tab title override for the target's tab. set_tab_title: SetTitle, + /// Set the window title override for the target's tab. + set_window_title: SetTitle, + /// Set the title of the target to a prompted value. It is up to /// the apprt to prompt. The value specifies whether to prompt for the /// surface title or the tab title. @@ -227,7 +234,7 @@ pub const Action = union(Key) { /// Open the Ghostty configuration. This is platform-specific about /// what it means; it can mean opening a dedicated UI or just opening /// a file in a text editor. - open_config, + open_config: OpenConfig, /// Called when there are no more surfaces and the app should quit /// after the configured delay. @@ -347,6 +354,9 @@ pub const Action = union(Key) { /// otherwise the terminal-set title. copy_title_to_clipboard, + /// Move a tab to a new window. + move_tab_to_new_window, + /// Sync with: ghostty_action_tag_e pub const Key = enum(c_int) { quit, @@ -380,9 +390,11 @@ pub const Action = union(Key) { inspector, show_gtk_inspector, render_inspector, + export_terminal_io, desktop_notification, set_title, set_tab_title, + set_window_title, prompt_title, pwd, mouse_shape, @@ -415,6 +427,7 @@ pub const Action = union(Key) { search_selected, readonly, copy_title_to_clipboard, + move_tab_to_new_window, test "ghostty.h Action.Key" { try lib.checkGhosttyHEnum(Key, "GHOSTTY_ACTION_"); @@ -424,8 +437,11 @@ pub const Action = union(Key) { /// Sync with: ghostty_action_u pub const CValue = cvalue: { const key_fields = @typeInfo(Key).@"enum".fields; - var union_fields: [key_fields.len]std.builtin.Type.UnionField = undefined; - for (key_fields, 0..) |field, i| { + var names: [key_fields.len][]const u8 = undefined; + var types: [key_fields.len]type = undefined; + var attrs: [key_fields.len]std.builtin.Type.UnionField.Attributes = undefined; + + for (key_fields, &names, &types, &attrs) |field, *name, *ty, *attr| { const action = @unionInit(Action, field.name, undefined); const Type = t: { const Type = @TypeOf(@field(action, field.name)); @@ -434,19 +450,12 @@ pub const Action = union(Key) { break :t Type; }; - union_fields[i] = .{ - .name = field.name, - .type = Type, - .alignment = @alignOf(Type), - }; + name.* = field.name; + ty.* = Type; + attr.* = .{ .@"align" = @alignOf(Type) }; } - break :cvalue @Type(.{ .@"union" = .{ - .layout = .@"extern", - .tag_type = null, - .fields = &union_fields, - .decls = &.{}, - } }); + break :cvalue @Union(.@"extern", null, &names, &types, &attrs); }; /// Sync with: ghostty_action_s @@ -460,7 +469,7 @@ pub const Action = union(Key) { // At the time of writing, we don't promise ABI compatibility // so we can change this but I want to be aware of it. assert(@sizeOf(CValue) == switch (@sizeOf(usize)) { - 4 => 16, + 4 => 24, 8 => 24, else => unreachable, }); @@ -615,6 +624,37 @@ pub const Inspector = enum(c_int) { } }; +/// Terminal IO inspector contents to export. The contents are only valid for +/// the duration of the action callback. +pub const ExportTerminalIO = struct { + contents: []const u8, + + // Sync with: ghostty_action_export_terminal_io_s + pub const C = extern struct { + contents: [*]const u8, + len: usize, + }; + + pub fn cval(self: ExportTerminalIO) C { + return .{ + .contents = self.contents.ptr, + .len = self.contents.len, + }; + } + + pub fn format( + value: @This(), + comptime _: []const u8, + _: std.fmt.Options, + writer: *std.Io.Writer, + ) !void { + try writer.print( + "{s}{{ contents: {d} bytes }}", + .{ @typeName(@This()), value.contents.len }, + ); + } +}; + pub const QuitTimer = enum(c_int) { start, stop, @@ -642,10 +682,11 @@ pub const MouseVisibility = enum(c_int) { } }; -/// Whether to prompt for the surface title or tab title. +/// Whether to prompt for the surface, tab, or window title. pub const PromptTitle = enum(c_int) { surface, tab, + window, test "ghostty.h PromptTitle" { try lib.checkGhosttyHEnum(PromptTitle, "GHOSTTY_PROMPT_TITLE_"); @@ -713,7 +754,7 @@ pub const SetTitle = struct { pub fn format( value: @This(), comptime _: []const u8, - _: std.fmt.FormatOptions, + _: std.fmt.Options, writer: *std.Io.Writer, ) !void { try writer.print("{s}{{ {s} }}", .{ @typeName(@This()), value.title }); @@ -737,7 +778,7 @@ pub const Pwd = struct { pub fn format( value: @This(), comptime _: []const u8, - _: std.fmt.FormatOptions, + _: std.fmt.Options, writer: *std.Io.Writer, ) !void { try writer.print("{s}{{ {s} }}", .{ @typeName(@This()), value.pwd }); @@ -765,7 +806,7 @@ pub const DesktopNotification = struct { pub fn format( value: @This(), comptime _: []const u8, - _: std.fmt.FormatOptions, + _: std.fmt.Options, writer: *std.Io.Writer, ) !void { try writer.print("{s}{{ title: {s}, body: {s} }}", .{ @@ -909,6 +950,11 @@ pub const OpenUrl = struct { /// The URL is known to contain HTML content. html, + /// The URL came from an OSC 8 hyperlink. Application runtimes should + /// treat this as untrusted terminal output and apply a platform-specific + /// safe-opening policy. + osc8, + test "ghostty.h OpenUrl.Kind" { try lib.checkGhosttyHEnum(Kind, "GHOSTTY_ACTION_OPEN_URL_KIND_"); } @@ -1007,6 +1053,19 @@ pub const SearchSelected = struct { } }; +/// sync with ghostty_action_close_tab_mode_e in ghostty.h +pub const OpenConfig = enum(c_int) { + /// Open the config in the OS default editor. + os_open, + + /// Open the config in a new window using $EDITOR or $VISUAL + new_window, + + test "ghostty.h OpenConfig" { + try lib.checkGhosttyHEnum(OpenConfig, "GHOSTTY_ACTION_OPEN_CONFIG_"); + } +}; + test { - _ = std.testing.refAllDeclsRecursive(@This()); + _ = compat_testing.refAllDeclsRecursive(@This()); } diff --git a/vendor/libghostty-vt/src/apprt/embedded.zig b/vendor/libghostty-vt/src/apprt/embedded.zig index 7310159c..525bc856 100644 --- a/vendor/libghostty-vt/src/apprt/embedded.zig +++ b/vendor/libghostty-vt/src/apprt/embedded.zig @@ -11,6 +11,7 @@ const Allocator = std.mem.Allocator; const objc = @import("objc"); const apprt = @import("../apprt.zig"); const font = @import("../font/main.zig"); +const global = @import("../global.zig"); const input = @import("../input.zig"); const internal_os = @import("../os/main.zig"); const renderer = @import("../renderer.zig"); @@ -51,18 +52,36 @@ pub const App = struct { /// Callback called to handle an action. action: *const fn (*App, apprt.Target.C, apprt.Action.C) callconv(.c) bool, - /// Read the clipboard value. Returns true if the clipboard request - /// was started and complete_clipboard_request may be called with the - /// given state pointer. Returns false if the clipboard request couldn't - /// be started (such as when no text is available for a paste request). - read_clipboard: *const fn (SurfaceUD, c_int, *apprt.ClipboardRequest) callconv(.c) bool, + /// Read the clipboard value. The result only reports facts about + /// the clipboard: whether the request was started (in which case + /// complete_clipboard_request or deny_clipboard_request must + /// eventually be called with the given state pointer), whether the + /// clipboard has no servable contents, or whether the clipboard + /// can't be read at all. How each non-started state is answered is + /// up to the core. + /// + /// The MIME types are exactly the representations the caller wants + /// served; the embedder should read only those. Text-like types + /// are always requested as the canonical "text/plain". The final + /// bool asks for the listing of all MIME types available on the + /// clipboard to be delivered with the completion. + read_clipboard: *const fn ( + SurfaceUD, + c_int, + *apprt.ClipboardRequest, + [*]const [*:0]const u8, + usize, + bool, + ) callconv(.c) apprt.ClipboardReadResult, /// This may be called after a read clipboard call to request - /// confirmation that the clipboard value is safe to read. The embedder - /// must call complete_clipboard_request with the given request. + /// confirmation that the clipboard value is safe to read. The + /// embedder must call complete_clipboard_request (usually with + /// the confirmation's contents, which are only borrowed for + /// this call) or deny_clipboard_request with the given request. confirm_read_clipboard: *const fn ( SurfaceUD, - [*:0]const u8, + *const CAPI.ClipboardConfirm, *apprt.ClipboardRequest, apprt.ClipboardRequestType, ) callconv(.c) void, @@ -119,7 +138,13 @@ pub const App = struct { core_app: *CoreApp, opts: Options, - keymap: input.Keymap, + + /// The keyboard layout keymap. This is lazily initialized on first + /// use because creating it requires talking to the text input + /// system (TIS on macOS), and the first such call in a process is + /// slow (multiple milliseconds). It is only needed once keyboard + /// events start flowing, at which point the system is warm. + keymap: ?input.Keymap, /// The configuration for the app. This is owned by this structure. config: Config, @@ -135,19 +160,16 @@ pub const App = struct { var config_clone = try config.clone(alloc); errdefer config_clone.deinit(); - var keymap = try input.Keymap.init(); - errdefer keymap.deinit(); - self.* = .{ .core_app = core_app, .config = config_clone, .opts = opts, - .keymap = keymap, + .keymap = null, }; } pub fn terminate(self: *App) void { - self.keymap.deinit(); + if (self.keymap) |*v| v.deinit(); self.config.deinit(); } @@ -207,8 +229,10 @@ pub const App = struct { /// This should be called whenever the keyboard layout was changed. pub fn reloadKeymap(self: *App) !void { - // Reload the keymap - try self.keymap.reload(); + // Reload the keymap. If it was never initialized we don't need + // to do anything since lazy initialization will pick up the + // current layout. + if (self.keymap) |*v| try v.reload(); } /// Loads the keyboard layout. @@ -216,13 +240,25 @@ pub const App = struct { /// Kind of expensive so this should be avoided if possible. When I say /// "kind of expensive" I mean that its not something you probably want /// to run on every keypress. - pub fn keyboardLayout(self: *const App) input.KeyboardLayout { + pub fn keyboardLayout(self: *App) input.KeyboardLayout { // We only support keyboard layout detection on macOS. if (comptime builtin.os.tag != .macos) return .unknown; + // Lazily initialize the keymap. + const keymap: *input.Keymap = keymap: { + if (self.keymap == null) { + self.keymap = input.Keymap.init() catch |err| { + log.warn("error initializing keymap err={}", .{err}); + return .unknown; + }; + } + + break :keymap &self.keymap.?; + }; + // Any layout larger than this is not something we can handle. var buf: [256]u8 = undefined; - const id = self.keymap.sourceId(&buf) catch |err| { + const id = keymap.sourceId(&buf) catch |err| { comptime assert(@TypeOf(err) == error{OutOfMemory}); return .unknown; }; @@ -333,9 +369,10 @@ pub const App = struct { _: apprt.ipc.Target, comptime action: apprt.ipc.Action.Key, _: apprt.ipc.Action.Value(action), - ) (Allocator.Error || std.posix.WriteError || apprt.ipc.Errors)!bool { + ) (Allocator.Error || apprt.ipc.Errors)!bool { switch (action) { .new_window => return false, + .new_tab => return false, .toggle_quick_terminal => return false, } } @@ -372,7 +409,7 @@ pub const Platform = union(PlatformTag) { /// Initialize a Platform a tag and configuration from the C ABI. pub fn init(tag_int: c_int, c_platform: C) !Platform { - const tag = try std.meta.intToEnum(PlatformTag, tag_int); + const tag = std.enums.fromInt(PlatformTag, tag_int) orelse return error.InvalidEnumTag; return switch (tag) { .macos => if (MacOS != void) macos: { const config = c_platform.macos; @@ -490,16 +527,16 @@ pub const Surface = struct { if (opts.working_directory) |c_wd| { const wd = std.mem.sliceTo(c_wd, 0); if (wd.len > 0) wd: { - var dir = std.fs.openDirAbsolute(wd, .{}) catch |err| { + var dir = std.Io.Dir.openDirAbsolute(global.io(), wd, .{}) catch |err| { log.warn( "error opening requested working directory dir={s} err={}", .{ wd, err }, ); break :wd; }; - defer dir.close(); + defer dir.close(global.io()); - const stat = dir.stat() catch |err| { + const stat = dir.stat(global.io()) catch |err| { log.warn( "failed to stat requested working directory dir={s} err={}", .{ wd, err }, @@ -665,7 +702,13 @@ pub const Surface = struct { ) bool { return switch (clipboard_type) { .standard => true, - .selection, .primary => self.app.opts.supports_selection_clipboard, + .selection => self.app.opts.supports_selection_clipboard, + + // No embedder can serve the primary selection: the embedding + // API has no option to declare support for it, and macOS (the + // only GUI embedder) has no primary selection. The selection + // flag above covers a distinct custom pasteboard, not this. + .primary => false, }; } @@ -673,7 +716,67 @@ pub const Surface = struct { self: *Surface, clipboard_type: apprt.Clipboard, state: apprt.ClipboardRequest, - ) !bool { + ) !apprt.ClipboardReadResult { + // Kitty clipboard writes carry their own contents and read + // nothing from the clipboard, so they skip the read callback + // entirely: the request is completed immediately, and a + // completion that requires confirmation diverts into the + // apprt confirmation flow just like a read. + if (state == .kitty_write) { + // A write to a location the embedder can't serve is + // rejected before the transaction completes so the caller + // answers ENOSYS without a permission prompt, matching + // reads, where the embedder reports an unsupported + // location from the read callback. The write callback only + // fires after any prompt, so it is too late to reject. + if (!self.supportsClipboard(clipboard_type)) return .unsupported; + + const alloc = self.app.core_app.alloc; + const state_ptr = try alloc.create(apprt.ClipboardRequest); + errdefer alloc.destroy(state_ptr); + state_ptr.* = state; + self.completeKittyClipboardWrite(state_ptr); + return .started; + } + + // The representations the read wants served. Text-only + // requesters ask for the canonical text type; Kitty clipboard + // reads ask for exactly what the program requested, with + // text-like aliases normalized so the embedder never has to + // know about them. + var mimes_buf: [terminal.kitty.clipboard.max_read_mimes][*:0]const u8 = undefined; + const mimes: []const [*:0]const u8 = switch (state) { + .paste, .osc_52_read => &.{"text/plain"}, + + // A mode 5522 paste event only lists types and must not read + // any clipboard data. + .list => &.{}, + + .kitty_read => |kitty| mimes: { + assert(kitty.mimes.len <= mimes_buf.len); + for (kitty.mimes, mimes_buf[0..kitty.mimes.len]) |mime, *dst| { + dst.* = if (terminal.clipboard.isTextMime(mime)) + "text/plain" + else + mime.ptr; + } + break :mimes mimes_buf[0..kitty.mimes.len]; + }, + + // Handled above. + .kitty_write => unreachable, + + // No clipboard write code paths travel through this function + .osc_52_write => unreachable, + }; + const list = switch (state) { + // Paste events need the full MIME listing without reading any + // representation. Kitty reads only ask for it when requested. + .list => true, + .kitty_read => |kitty| kitty.list, + else => false, + }; + // We need to allocate to get a pointer to store our clipboard request // so that it is stable until the read_clipboard callback and call // complete_clipboard_request. This sucks but clipboard requests aren't @@ -683,40 +786,156 @@ pub const Surface = struct { errdefer alloc.destroy(state_ptr); state_ptr.* = state; - const started = self.app.opts.read_clipboard( + const result = self.app.opts.read_clipboard( self.userdata, @intCast(@intFromEnum(clipboard_type)), state_ptr, + mimes.ptr, + mimes.len, + list, ); - if (!started) { - alloc.destroy(state_ptr); - return false; - } - return true; + // Only a started request completes later and keeps the state. + if (result != .started) alloc.destroy(state_ptr); + return result; } - fn completeClipboardRequest( + /// Complete a Kitty clipboard protocol write request. The apprt + /// contributes nothing to the completion (the authoritative + /// contents live in the request itself), but a completion that + /// requires confirmation diverts into the confirm callback, which + /// keeps the state alive for the asynchronous prompt. + fn completeKittyClipboardWrite( self: *Surface, - str: [:0]const u8, state: *apprt.ClipboardRequest, - confirmed: bool, ) void { const alloc = self.app.core_app.alloc; + const kitty = state.kitty_write; - // Attempt to complete the request, but we may request - // confirmation. self.core_surface.completeClipboardRequest( state.*, - str, - confirmed, + .{}, ) catch |err| switch (err) { + error.UnauthorizedPaste => { + // Convert the would-be contents so the permission + // prompt can display exactly what would be written. + var stack = std.heap.stackFallback(1024, alloc); + const conv_alloc = stack.get(); + const contents = conv_alloc.alloc( + CAPI.ClipboardContent, + kitty.contents.len, + ) catch |alloc_err| { + log.err("error confirming clipboard request err={}", .{alloc_err}); + self.core_surface.denyClipboardRequest(state.*); + alloc.destroy(state); + return; + }; + defer conv_alloc.free(contents); + for (kitty.contents, contents) |src, *dst| dst.* = .{ + .mime = src.mime, + .data = src.data.ptr, + .len = src.data.len, + }; + + self.app.opts.confirm_read_clipboard( + self.userdata, + &.{ + .contents = contents.ptr, + .contents_len = contents.len, + .available = null, + .available_len = 0, + .name = if (kitty.name.len > 0) kitty.name.ptr else null, + .can_remember = kitty.pw.len > 0, + }, + state, + state.*, + ); + + return; + }, + + else => log.err("error completing clipboard request err={}", .{err}), + }; + + // We don't defer this because the clipboard confirmation route + // preserves the clipboard request. + alloc.destroy(state); + } + + fn completeClipboardRequest( + self: *Surface, + complete: *const CAPI.ClipboardComplete, + state: *apprt.ClipboardRequest, + ) void { + const alloc = self.app.core_app.alloc; + + // Convert the C representations to the core types. Everything + // remains borrowed from the caller for the duration of the call. + var stack = std.heap.stackFallback(1024, alloc); + const conv_alloc = stack.get(); + + const raw_contents: []const CAPI.ClipboardContent = + if (complete.contents) |v| v[0..complete.contents_len] else &.{}; + const contents = conv_alloc.alloc( + terminal.clipboard.Content, + raw_contents.len, + ) catch |err| { + log.err("error completing clipboard request err={}", .{err}); + alloc.destroy(state); + return; + }; + defer conv_alloc.free(contents); + for (raw_contents, contents) |raw, *content| content.* = .{ + .mime = std.mem.sliceTo(raw.mime, 0), + .data = raw.data[0..raw.len], + }; + + const raw_available: []const [*:0]const u8 = + if (complete.available) |v| v[0..complete.available_len] else &.{}; + const available = conv_alloc.alloc( + []const u8, + raw_available.len, + ) catch |err| { + log.err("error completing clipboard request err={}", .{err}); + alloc.destroy(state); + return; + }; + defer conv_alloc.free(available); + for (raw_available, available) |raw, *mime| { + mime.* = std.mem.sliceTo(raw, 0); + } + + // Attempt to complete the request, but we may request + // confirmation. + self.core_surface.completeClipboardRequest(state.*, .{ + .contents = contents, + .available = available, + .confirmed = complete.confirmed, + .remember = complete.remember, + }) catch |err| switch (err) { error.UnsafePaste, error.UnauthorizedPaste, => { + // Session grant information for the permission prompt, + // carried only by Kitty clipboard protocol requests. + const name: ?[*:0]const u8, const can_remember: bool = switch (state.*) { + inline .kitty_read, .kitty_write => |kitty| .{ + if (kitty.name.len > 0) kitty.name.ptr else null, + kitty.pw.len > 0, + }, + else => .{ null, false }, + }; + self.app.opts.confirm_read_clipboard( self.userdata, - str.ptr, + &.{ + .contents = complete.contents, + .contents_len = complete.contents_len, + .available = complete.available, + .available_len = complete.available_len, + .name = name, + .can_remember = can_remember, + }, state, state.*, ); @@ -732,6 +951,14 @@ pub const Surface = struct { alloc.destroy(state); } + fn denyClipboardRequest( + self: *Surface, + state: *apprt.ClipboardRequest, + ) void { + self.core_surface.denyClipboardRequest(state.*); + self.app.core_app.alloc.destroy(state); + } + pub fn setClipboard( self: *const Surface, clipboard_type: apprt.Clipboard, @@ -744,7 +971,8 @@ pub const Surface = struct { for (contents, 0..) |content, i| { array[i] = .{ .mime = content.mime, - .data = content.data, + .data = content.data.ptr, + .len = content.data.len, }; } @@ -950,32 +1178,32 @@ pub const Surface = struct { }; } - pub fn defaultTermioEnv(self: *const Surface) !std.process.EnvMap { - const alloc = self.app.core_app.alloc; - var env = try internal_os.getEnvMap(alloc); + pub fn defaultTermioEnv(self: *const Surface) !std.process.Environ.Map { + _ = self; + var env = try global.environMap(); errdefer env.deinit(); if (comptime builtin.target.os.tag.isDarwin()) { if (env.get("__XCODE_BUILT_PRODUCTS_DIR_PATHS") != null) { - env.remove("__XCODE_BUILT_PRODUCTS_DIR_PATHS"); - env.remove("__XPC_DYLD_LIBRARY_PATH"); - env.remove("DYLD_FRAMEWORK_PATH"); - env.remove("DYLD_INSERT_LIBRARIES"); - env.remove("DYLD_LIBRARY_PATH"); - env.remove("LD_LIBRARY_PATH"); - env.remove("SECURITYSESSIONID"); - env.remove("XPC_SERVICE_NAME"); + _ = env.orderedRemove("__XCODE_BUILT_PRODUCTS_DIR_PATHS"); + _ = env.orderedRemove("__XPC_DYLD_LIBRARY_PATH"); + _ = env.orderedRemove("DYLD_FRAMEWORK_PATH"); + _ = env.orderedRemove("DYLD_INSERT_LIBRARIES"); + _ = env.orderedRemove("DYLD_LIBRARY_PATH"); + _ = env.orderedRemove("LD_LIBRARY_PATH"); + _ = env.orderedRemove("SECURITYSESSIONID"); + _ = env.orderedRemove("XPC_SERVICE_NAME"); } // Remove this so that running `ghostty` within Ghostty works. - env.remove("GHOSTTY_MAC_LAUNCH_SOURCE"); + _ = env.orderedRemove("GHOSTTY_MAC_LAUNCH_SOURCE"); // If we were launched from the desktop then we want to // remove the LANGUAGE env var so that we don't inherit // our translation settings for Ghostty. If we aren't from // the desktop then we didn't set our LANGUAGE var so we // don't need to remove it. - if (internal_os.launchedFromDesktop()) env.remove("LANGUAGE"); + if (internal_os.launchedFromDesktop()) _ = env.orderedRemove("LANGUAGE"); } return env; @@ -1000,7 +1228,7 @@ pub const Inspector = struct { content_scale: f64 = 1, /// Our previous instant used to calculate delta time for animations. - instant: ?std.time.Instant = null, + instant: ?std.Io.Timestamp = null, const Backend = enum { metal, @@ -1229,9 +1457,9 @@ pub const Inspector = struct { const io: *cimgui.c.ImGuiIO = cimgui.c.ImGui_GetIO(); // Determine our delta time - const now = try std.time.Instant.now(); + const now: std.Io.Timestamp = .now(global.io(), .awake); io.DeltaTime = if (self.instant) |prev| delta: { - const since_ns: f64 = @floatFromInt(now.since(prev)); + const since_ns: f64 = @floatFromInt(prev.durationTo(now).toNanoseconds()); const ns_per_s: f64 = @floatFromInt(std.time.ns_per_s); const since_s: f32 = @floatCast(since_ns / ns_per_s); break :delta @max(0.00001, since_s); @@ -1242,8 +1470,6 @@ pub const Inspector = struct { // C API pub const CAPI = struct { - const global = &@import("../global.zig").state; - /// This is the same as Surface.KeyEvent but this is the raw C API version. const KeyEvent = extern struct { action: input.Action, @@ -1284,9 +1510,48 @@ pub const CAPI = struct { }; // ghostty_clipboard_content_s + // + // One representation of clipboard contents. The data is binary-safe + // and its length is explicit; it is not sentinel-terminated. const ClipboardContent = extern struct { mime: [*:0]const u8, - data: [*:0]const u8, + data: [*]const u8, + len: usize, + }; + + // ghostty_clipboard_complete_s + // + // The payload for completing a clipboard read request. See + // Surface.CompleteClipboard for the field documentation. + const ClipboardComplete = extern struct { + contents: ?[*]const ClipboardContent, + contents_len: usize, + available: ?[*]const [*:0]const u8, + available_len: usize, + confirmed: bool, + remember: bool, + }; + + // ghostty_clipboard_confirm_s + // + // The payload of a clipboard read confirmation request: the + // would-be completion contents plus the information shown in the + // permission prompt. All memory is borrowed for the duration of + // the confirm_read_clipboard callback. + const ClipboardConfirm = extern struct { + contents: ?[*]const ClipboardContent, + contents_len: usize, + available: ?[*]const [*:0]const u8, + available_len: usize, + + /// The human friendly name of the requesting program for the + /// prompt, null when the protocol doesn't carry one. + name: ?[*:0]const u8, + + /// True when the user's decision may be remembered as a + /// session grant, reported back through the completion's + /// remember field. + can_remember: bool, }; // ghostty_text_s @@ -1300,7 +1565,7 @@ pub const CAPI = struct { pub fn deinit(self: *Text) void { if (self.text) |ptr| { - global.alloc.free(ptr[0..self.text_len :0]); + global.alloc().free(ptr[0..self.text_len :0]); } } }; @@ -1410,12 +1675,12 @@ pub const CAPI = struct { opts: *const apprt.runtime.App.Options, config: *const Config, ) !*App { - const core_app = try CoreApp.create(global.alloc); + const core_app = try CoreApp.create(global.alloc()); errdefer core_app.destroy(); // Create our runtime app - var app = try global.alloc.create(App); - errdefer global.alloc.destroy(app); + var app = try global.alloc().create(App); + errdefer global.alloc().destroy(app); try app.init(core_app, config, opts.*); errdefer app.terminate(); @@ -1438,7 +1703,7 @@ pub const CAPI = struct { export fn ghostty_app_free(v: *App) void { const core_app = v.core_app; v.terminate(); - global.alloc.destroy(v); + global.alloc().destroy(v); core_app.destroy(); } @@ -1490,7 +1755,7 @@ pub const CAPI = struct { /// Open the configuration. export fn ghostty_app_open_config(v: *App) void { - _ = v.performAction(.app, .open_config, {}) catch |err| { + _ = v.performAction(.app, .open_config, .new_window) catch |err| { log.err("error reloading config err={}", .{err}); return; }; @@ -1520,13 +1785,7 @@ pub const CAPI = struct { /// Update the color scheme of the app. export fn ghostty_app_set_color_scheme(v: *App, scheme_raw: c_int) void { - const scheme = std.meta.intToEnum(apprt.ColorScheme, scheme_raw) catch { - log.warn( - "invalid color scheme to ghostty_surface_set_color_scheme value={}", - .{scheme_raw}, - ); - return; - }; + const scheme = std.enums.fromInt(apprt.ColorScheme, scheme_raw) orelse return; v.core_app.colorSchemeEvent(v, scheme) catch |err| { log.err("error setting color scheme err={}", .{err}); @@ -1612,8 +1871,8 @@ pub const CAPI = struct { result: *Text, ) bool { const core_surface = &surface.core_surface; - core_surface.renderer_state.mutex.lock(); - defer core_surface.renderer_state.mutex.unlock(); + core_surface.renderer_state.mutex.lockUncancelable(global.io()); + defer core_surface.renderer_state.mutex.unlock(global.io()); // If we don't have a selection, do nothing. const core_sel = core_surface.io.terminal.screens.active.selection orelse return false; @@ -1632,8 +1891,8 @@ pub const CAPI = struct { sel: Selection, result: *Text, ) bool { - surface.core_surface.renderer_state.mutex.lock(); - defer surface.core_surface.renderer_state.mutex.unlock(); + surface.core_surface.renderer_state.mutex.lockUncancelable(global.io()); + defer surface.core_surface.renderer_state.mutex.unlock(global.io()); const core_sel = sel.core( surface.core_surface.renderer_state.terminal.screens.active, @@ -1651,7 +1910,7 @@ pub const CAPI = struct { // Get our text directly from the core surface. const text = core_surface.dumpTextLocked( - global.alloc, + global.alloc(), core_sel, ) catch |err| { log.warn("error reading text err={}", .{err}); @@ -1730,14 +1989,7 @@ pub const CAPI = struct { /// Update the color scheme of the surface. export fn ghostty_surface_set_color_scheme(surface: *Surface, scheme_raw: c_int) void { - const scheme = std.meta.intToEnum(apprt.ColorScheme, scheme_raw) catch { - log.warn( - "invalid color scheme to ghostty_surface_set_color_scheme value={}", - .{scheme_raw}, - ); - return; - }; - + const scheme = std.enums.fromInt(apprt.ColorScheme, scheme_raw) orelse return; surface.colorSchemeCallback(scheme); } @@ -1891,17 +2143,7 @@ pub const CAPI = struct { stage_raw: u32, pressure: f64, ) void { - const stage = std.meta.intToEnum( - input.MousePressureStage, - stage_raw, - ) catch { - log.warn( - "invalid mouse pressure stage value={}", - .{stage_raw}, - ); - return; - }; - + const stage = std.enums.fromInt(input.MousePressureStage, stage_raw) orelse return; surface.mousePressureCallback(stage, pressure); } @@ -2001,20 +2243,32 @@ pub const CAPI = struct { }; } - /// Complete a clipboard read request started via the read callback. - /// This can only be called once for a given request. Once it is called - /// with a request the request pointer will be invalidated. + /// Complete a clipboard read request started via the read callback + /// with the representations that could be served and, if requested, + /// the listing of available MIME types. All memory is borrowed for + /// the duration of the call. This can only be called once for a given + /// request. Once it is called with a request the request pointer will + /// be invalidated. + /// + /// To deny a request use ghostty_surface_deny_clipboard_request + /// instead. export fn ghostty_surface_complete_clipboard_request( ptr: *Surface, - str: [*:0]const u8, + complete: *const ClipboardComplete, state: *apprt.ClipboardRequest, - confirmed: bool, ) void { - ptr.completeClipboardRequest( - std.mem.sliceTo(str, 0), - state, - confirmed, - ); + ptr.completeClipboardRequest(complete, state); + } + + /// Deny a clipboard read request started via the read callback, + /// e.g. because the user rejected a confirmation prompt. Request + /// types whose protocol expects an answer have their denial reply + /// written to the pty. The request pointer is invalidated. + export fn ghostty_surface_deny_clipboard_request( + ptr: *Surface, + state: *apprt.ClipboardRequest, + ) void { + ptr.denyClipboardRequest(state); } export fn ghostty_surface_inspector(ptr: *Surface) ?*Inspector { @@ -2134,6 +2388,7 @@ pub const CAPI = struct { export fn ghostty_surface_set_display_id(ptr: *Surface, display_id: u32) void { const surface = &ptr.core_surface; _ = surface.renderer_thread.mailbox.push( + global.io(), .{ .macos_display_id = display_id }, .{ .forever = {} }, ); @@ -2157,8 +2412,8 @@ pub const CAPI = struct { // read the font face. It should not be deferred since // we're loading the primary face. const grid = ptr.core_surface.renderer.font_grid; - grid.lock.lockShared(); - defer grid.lock.unlockShared(); + grid.lock.lockSharedUncancelable(global.io()); + defer grid.lock.unlockShared(global.io()); const collection = &grid.resolver.collection; const face = collection.getFace(.{}) catch return null; @@ -2195,8 +2450,8 @@ pub const CAPI = struct { result: *Text, ) bool { const surface = &ptr.core_surface; - surface.renderer_state.mutex.lock(); - defer surface.renderer_state.mutex.unlock(); + surface.renderer_state.mutex.lockUncancelable(global.io()); + defer surface.renderer_state.mutex.unlock(global.io()); // Get our word selection const sel = sel: { diff --git a/vendor/libghostty-vt/src/apprt/gtk/App.zig b/vendor/libghostty-vt/src/apprt/gtk/App.zig index 8a7b3a8e..9fbea7c1 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/App.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/App.zig @@ -13,6 +13,7 @@ const CoreApp = @import("../../App.zig"); const Application = @import("class/application.zig").Application; const Surface = @import("Surface.zig"); const ipcNewWindow = @import("ipc/new_window.zig").newWindow; +const ipcNewTab = @import("ipc/new_tab.zig").newTab; const ipcToggleQuickTerminal = @import("ipc/toggle_quick_terminal.zig").toggleQuickTerminal; const log = std.log.scoped(.gtk); @@ -85,6 +86,7 @@ pub fn performIpc( ) !bool { switch (action) { .new_window => return try ipcNewWindow(alloc, target, value), + .new_tab => return try ipcNewTab(alloc, target, value), .toggle_quick_terminal => return try ipcToggleQuickTerminal(alloc, target), } } diff --git a/vendor/libghostty-vt/src/apprt/gtk/Surface.zig b/vendor/libghostty-vt/src/apprt/gtk/Surface.zig index 71597367..4a59ab21 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/Surface.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/Surface.zig @@ -74,7 +74,7 @@ pub fn clipboardRequest( self: *Self, clipboard_type: apprt.Clipboard, state: apprt.ClipboardRequest, -) !bool { +) !apprt.ClipboardReadResult { return try self.surface.clipboardRequest( clipboard_type, state, @@ -94,7 +94,7 @@ pub fn setClipboard( ); } -pub fn defaultTermioEnv(self: *Self) !std.process.EnvMap { +pub fn defaultTermioEnv(self: *Self) !std.process.Environ.Map { return try self.surface.defaultTermioEnv(); } diff --git a/vendor/libghostty-vt/src/apprt/gtk/adw_version.zig b/vendor/libghostty-vt/src/apprt/gtk/adw_version.zig index 6f7be52d..1ac750fb 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/adw_version.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/adw_version.zig @@ -4,18 +4,16 @@ const std = @import("std"); // Ghostty, we need to import `adwaita.h` directly to ensure that the version // macros match the version of `libadwaita` that we are building/linking // against. -const c = @cImport({ - @cInclude("adwaita.h"); -}); +const adw_c = @import("adw_c"); const adw = @import("adw"); const log = std.log.scoped(.gtk); pub const comptime_version: std.SemanticVersion = .{ - .major = c.ADW_MAJOR_VERSION, - .minor = c.ADW_MINOR_VERSION, - .patch = c.ADW_MICRO_VERSION, + .major = adw_c.ADW_MAJOR_VERSION, + .minor = adw_c.ADW_MINOR_VERSION, + .patch = adw_c.ADW_MICRO_VERSION, }; pub fn getRuntimeVersion() std.SemanticVersion { @@ -89,14 +87,14 @@ test "versionAtLeast" { const funs = &.{ atLeast, runtimeAtLeast }; inline for (funs) |fun| { - try testing.expect(fun(c.ADW_MAJOR_VERSION, c.ADW_MINOR_VERSION, c.ADW_MICRO_VERSION)); - try testing.expect(!fun(c.ADW_MAJOR_VERSION, c.ADW_MINOR_VERSION, c.ADW_MICRO_VERSION + 1)); - try testing.expect(!fun(c.ADW_MAJOR_VERSION, c.ADW_MINOR_VERSION + 1, c.ADW_MICRO_VERSION)); - try testing.expect(!fun(c.ADW_MAJOR_VERSION + 1, c.ADW_MINOR_VERSION, c.ADW_MICRO_VERSION)); - try testing.expect(fun(c.ADW_MAJOR_VERSION - 1, c.ADW_MINOR_VERSION, c.ADW_MICRO_VERSION)); - try testing.expect(fun(c.ADW_MAJOR_VERSION - 1, c.ADW_MINOR_VERSION + 1, c.ADW_MICRO_VERSION)); - try testing.expect(fun(c.ADW_MAJOR_VERSION - 1, c.ADW_MINOR_VERSION, c.ADW_MICRO_VERSION + 1)); - try testing.expect(fun(c.ADW_MAJOR_VERSION, c.ADW_MINOR_VERSION - 1, c.ADW_MICRO_VERSION + 1)); + try testing.expect(fun(adw_c.ADW_MAJOR_VERSION, adw_c.ADW_MINOR_VERSION, adw_c.ADW_MICRO_VERSION)); + try testing.expect(!fun(adw_c.ADW_MAJOR_VERSION, adw_c.ADW_MINOR_VERSION, adw_c.ADW_MICRO_VERSION + 1)); + try testing.expect(!fun(adw_c.ADW_MAJOR_VERSION, adw_c.ADW_MINOR_VERSION + 1, adw_c.ADW_MICRO_VERSION)); + try testing.expect(!fun(adw_c.ADW_MAJOR_VERSION + 1, adw_c.ADW_MINOR_VERSION, adw_c.ADW_MICRO_VERSION)); + try testing.expect(fun(adw_c.ADW_MAJOR_VERSION - 1, adw_c.ADW_MINOR_VERSION, adw_c.ADW_MICRO_VERSION)); + try testing.expect(fun(adw_c.ADW_MAJOR_VERSION - 1, adw_c.ADW_MINOR_VERSION + 1, adw_c.ADW_MICRO_VERSION)); + try testing.expect(fun(adw_c.ADW_MAJOR_VERSION - 1, adw_c.ADW_MINOR_VERSION, adw_c.ADW_MICRO_VERSION + 1)); + try testing.expect(fun(adw_c.ADW_MAJOR_VERSION, adw_c.ADW_MINOR_VERSION - 1, adw_c.ADW_MICRO_VERSION + 1)); } } diff --git a/vendor/libghostty-vt/src/apprt/gtk/build/blueprint.zig b/vendor/libghostty-vt/src/apprt/gtk/build/blueprint.zig index 4920ce6f..fb3f6ae2 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/build/blueprint.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/build/blueprint.zig @@ -6,10 +6,7 @@ //! Example: blueprint.zig 1 5 output.ui input.blp const std = @import("std"); - -pub const c = @cImport({ - @cInclude("adwaita.h"); -}); +const adw_c = @import("adw_c"); pub const blueprint_compiler_help = \\ @@ -26,23 +23,24 @@ pub const blueprint_compiler_help = ; const adwaita_version = std.SemanticVersion{ - .major = c.ADW_MAJOR_VERSION, - .minor = c.ADW_MINOR_VERSION, - .patch = c.ADW_MICRO_VERSION, + .major = adw_c.ADW_MAJOR_VERSION, + .minor = adw_c.ADW_MINOR_VERSION, + .patch = adw_c.ADW_MICRO_VERSION, }; + const required_blueprint_version = std.SemanticVersion{ .major = 0, .minor = 16, .patch = 0, }; -pub fn main() !void { +pub fn main(init: std.process.Init) !void { var debug_allocator: std.heap.DebugAllocator(.{}) = .init; defer _ = debug_allocator.deinit(); const alloc = debug_allocator.allocator(); // Get our args - var it = try std.process.argsWithAllocator(alloc); + var it = try init.minimal.args.iterateAllocator(alloc); defer it.deinit(); _ = it.next(); // Skip argv0 const arg_major = it.next() orelse return error.NoMajorVersion; @@ -63,51 +61,37 @@ pub fn main() !void { \\compile this blueprint. Please install it, ensure that it is \\available on your PATH, and then retry building Ghostty. , .{required_adwaita_version}); - std.posix.exit(1); + std.process.exit(1); } // Version checks { - var stdout: std.ArrayListUnmanaged(u8) = .empty; - defer stdout.deinit(alloc); - var stderr: std.ArrayListUnmanaged(u8) = .empty; - defer stderr.deinit(alloc); - - var blueprint_compiler = std.process.Child.init( - &.{ - "blueprint-compiler", - "--version", - }, - alloc, - ); - blueprint_compiler.stdout_behavior = .Pipe; - blueprint_compiler.stderr_behavior = .Pipe; - try blueprint_compiler.spawn(); - try blueprint_compiler.collectOutput( - alloc, - &stdout, - &stderr, - std.math.maxInt(u16), - ); - const term = blueprint_compiler.wait() catch |err| switch (err) { + const blueprint_compiler = std.process.run(alloc, init.io, .{ + .argv = &.{ "blueprint-compiler", "--version" }, + }) catch |err| switch (err) { error.FileNotFound => { std.debug.print( \\`blueprint-compiler` not found. ++ blueprint_compiler_help, .{required_blueprint_version}, ); - std.posix.exit(1); + std.process.exit(1); }, else => return err, }; - switch (term) { - .Exited => |rc| if (rc != 0) std.process.exit(1), + defer { + alloc.free(blueprint_compiler.stdout); + alloc.free(blueprint_compiler.stderr); + } + + switch (blueprint_compiler.term) { + .exited => |rc| if (rc != 0) std.process.exit(1), else => std.process.exit(1), } const version = try std.SemanticVersion.parse(std.mem.trim( u8, - stdout.items, + blueprint_compiler.stdout, &std.ascii.whitespace, )); if (version.order(required_blueprint_version) == .lt) { @@ -116,57 +100,45 @@ pub fn main() !void { ++ blueprint_compiler_help, .{required_blueprint_version}, ); - std.posix.exit(1); + std.process.exit(1); } } // Compilation { - var stdout: std.ArrayListUnmanaged(u8) = .empty; - defer stdout.deinit(alloc); - var stderr: std.ArrayListUnmanaged(u8) = .empty; - defer stderr.deinit(alloc); - - var blueprint_compiler = std.process.Child.init( - &.{ + const blueprint_compiler = std.process.run(alloc, init.io, .{ + .argv = &.{ "blueprint-compiler", "compile", "--output", output, input, }, - alloc, - ); - blueprint_compiler.stdout_behavior = .Pipe; - blueprint_compiler.stderr_behavior = .Pipe; - try blueprint_compiler.spawn(); - try blueprint_compiler.collectOutput( - alloc, - &stdout, - &stderr, - std.math.maxInt(u16), - ); - const term = blueprint_compiler.wait() catch |err| switch (err) { + }) catch |err| switch (err) { error.FileNotFound => { std.debug.print( \\`blueprint-compiler` not found. ++ blueprint_compiler_help, .{required_blueprint_version}, ); - std.posix.exit(1); + std.process.exit(1); }, else => return err, }; + defer { + alloc.free(blueprint_compiler.stdout); + alloc.free(blueprint_compiler.stderr); + } - switch (term) { - .Exited => |rc| { + switch (blueprint_compiler.term) { + .exited => |rc| { if (rc != 0) { - std.debug.print("{s}", .{stderr.items}); + std.debug.print("{s}", .{blueprint_compiler.stderr}); std.process.exit(1); } }, else => { - std.debug.print("{s}", .{stderr.items}); + std.debug.print("{s}", .{blueprint_compiler.stderr}); std.process.exit(1); }, } diff --git a/vendor/libghostty-vt/src/apprt/gtk/build/gresource.zig b/vendor/libghostty-vt/src/apprt/gtk/build/gresource.zig index c50ea8cd..57c32a35 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/build/gresource.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/build/gresource.zig @@ -122,18 +122,17 @@ pub fn blueprint(comptime bp: Blueprint) [:0]const u8 { } } -pub fn main() !void { - var debug_allocator: std.heap.DebugAllocator(.{}) = .init; - defer _ = debug_allocator.deinit(); - const alloc = debug_allocator.allocator(); +pub fn main(init: std.process.Init) !void { + const alloc = init.arena.allocator(); // Collect the UI files that are passed in as arguments. - var ui_files: std.ArrayListUnmanaged([]const u8) = .empty; + var ui_files: std.ArrayList([]const u8) = .empty; defer { for (ui_files.items) |item| alloc.free(item); ui_files.deinit(alloc); } - var it = try std.process.argsWithAllocator(alloc); + + var it = try init.minimal.args.iterateAllocator(alloc); defer it.deinit(); while (it.next()) |arg| { if (!std.mem.endsWith(u8, arg, ".ui")) continue; @@ -144,7 +143,7 @@ pub fn main() !void { } var buf: [4096]u8 = undefined; - var stdout = std.fs.File.stdout().writer(&buf); + var stdout = std.Io.File.stdout().writer(init.io, &buf); const writer = &stdout.interface; try writer.writeAll( \\ @@ -152,8 +151,8 @@ pub fn main() !void { \\ ); - try genRoot(writer); - try genIcons(writer); + try genRoot(init.io, writer); + try genIcons(init.io, writer); try genUi(alloc, writer, &ui_files); try writer.writeAll( @@ -167,19 +166,19 @@ pub fn main() !void { /// Generate the icon resources. This works by looking up all the icons /// specified by `icon_sizes` in `images/icons/`. They are asserted to exist /// by trying to access the file. -fn genIcons(writer: *std.Io.Writer) !void { +fn genIcons(io: std.Io, writer: *std.Io.Writer) !void { try writer.print( \\ \\ , .{build_info.resource_path}); - const cwd = std.fs.cwd(); + const cwd: std.Io.Dir = .cwd(); inline for (icon_sizes) |size| { // 1x { const alias = std.fmt.comptimePrint("{d}x{d}", .{ size, size }); const source = std.fmt.comptimePrint("images/gnome/{d}.png", .{size}); - try cwd.access(source, .{}); + try cwd.access(io, source, .{}); try writer.print( \\ {s} \\ @@ -192,7 +191,7 @@ fn genIcons(writer: *std.Io.Writer) !void { { const alias = std.fmt.comptimePrint("{d}x{d}@2", .{ size, size }); const source = std.fmt.comptimePrint("images/gnome/{d}.png", .{size * 2}); - try cwd.access(source, .{}); + try cwd.access(io, source, .{}); try writer.print( \\ {s} \\ @@ -209,19 +208,19 @@ fn genIcons(writer: *std.Io.Writer) !void { } /// Generate the resources at the root prefix. -fn genRoot(writer: *std.Io.Writer) !void { +fn genRoot(io: std.Io, writer: *std.Io.Writer) !void { try writer.print( \\ \\ , .{build_info.resource_path}); - const cwd = std.fs.cwd(); + const cwd: std.Io.Dir = .cwd(); inline for (css) |name| { const source = std.fmt.comptimePrint( "{s}/{s}", .{ css_path, name }, ); - try cwd.access(source, .{}); + try cwd.access(io, source, .{}); try writer.print( \\ {s} \\ @@ -242,7 +241,7 @@ fn genRoot(writer: *std.Io.Writer) !void { fn genUi( alloc: Allocator, writer: *std.Io.Writer, - files: *const std.ArrayListUnmanaged([]const u8), + files: *const std.ArrayList([]const u8), ) !void { try writer.print( \\ diff --git a/vendor/libghostty-vt/src/apprt/gtk/class.zig b/vendor/libghostty-vt/src/apprt/gtk/class.zig index 942666cf..a1dba716 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class.zig @@ -145,16 +145,24 @@ pub fn Common( /// as the virtual method but the self parameter points to the /// target instead of the original class. fn ImplementFunc(comptime T: type) type { - var params: [fn_info.params.len]std.builtin.Type.Fn.Param = undefined; - @memcpy(¶ms, fn_info.params); - params[0].type = *ClassInstance(T); - return @Type(.{ .@"fn" = .{ - .calling_convention = fn_info.calling_convention, - .is_generic = fn_info.is_generic, - .is_var_args = fn_info.is_var_args, - .return_type = fn_info.return_type, - .params = ¶ms, - } }); + var types: [fn_info.params.len]type = undefined; + var attrs: [fn_info.params.len]std.builtin.Type.Fn.Param.Attributes = undefined; + + for (fn_info.params, &types, &attrs) |info, *ty, *attr| { + ty.* = info.type.?; + attr.* = .{ .@"noalias" = info.is_noalias }; + } + types[0] = *ClassInstance(T); + + return @Fn( + &types, + &attrs, + fn_info.return_type.?, + .{ + .@"callconv" = fn_info.calling_convention, + .varargs = fn_info.is_var_args, + }, + ); } }; } diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/application.zig b/vendor/libghostty-vt/src/apprt/gtk/class/application.zig index a627086e..5b9d3bf2 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/application.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/application.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("std"); const assert = @import("../../../quirks.zig").inlineAssert; const Allocator = std.mem.Allocator; @@ -5,25 +6,27 @@ const adw = @import("adw"); const gdk = @import("gdk"); const gio = @import("gio"); const glib = @import("glib"); +const glibunix = @import("glibunix"); const gobject = @import("gobject"); const gtk = @import("gtk"); const build_config = @import("../../../build_config.zig"); const build_info = @import("../build/info.zig"); -const state = &@import("../../../global.zig").state; +const cli = @import("../../../cli.zig"); +const global = @import("../../../global.zig"); const i18n = @import("../../../os/main.zig").i18n; const apprt = @import("../../../apprt.zig"); const CoreApp = @import("../../../App.zig"); +const compat_file = @import("../../../lib/compat/file.zig"); const configpkg = @import("../../../config.zig"); const input = @import("../../../input.zig"); const internal_os = @import("../../../os/main.zig"); const systemd = @import("../../../os/systemd.zig"); const terminal = @import("../../../terminal/main.zig"); -const xev = @import("../../../global.zig").xev; +const xev = global.xev; const Binding = @import("../../../input.zig").Binding; const CoreConfig = configpkg.Config; const CoreSurface = @import("../../../Surface.zig"); -const lib = @import("../../../lib/main.zig"); const ext = @import("../ext.zig"); const key = @import("../key.zig"); @@ -42,9 +45,12 @@ const CloseConfirmationDialog = @import("close_confirmation_dialog.zig").CloseCo const ConfigErrorsDialog = @import("config_errors_dialog.zig").ConfigErrorsDialog; const GlobalShortcuts = @import("global_shortcuts.zig").GlobalShortcuts; const OpenURI = @import("../portal.zig").OpenURI; +const media = @import("../media.zig"); const log = std.log.scoped(.gtk_ghostty_application); +extern "c" fn setenv(name: ?[*]const u8, value: ?[*]const u8, overwrite: c_int) c_int; + /// Function used to funnel GLib/GObject/GTK log messages into Zig's logging /// system rather than just getting dumped directly to stderr. fn glibLogWriterFunction( @@ -218,6 +224,12 @@ pub const Application = extern struct { open_uri: OpenURI = undefined, + // The audio bell's MediaFile, reused across bells so we don't leak a + // GStreamer pipeline (and its GL threads) on every ring. Built lazily + // on the first audio bell and rebuilt when `bell-audio-path` changes; + // unref'd on dispose. See ringBell and media.zig. + bell_media: ?*gtk.MediaFile = null, + pub var offset: c_int = 0; }; @@ -271,15 +283,17 @@ pub const Application = extern struct { }; defer config.deinit(); + // Set the old language, const saved_language: ?[:0]const u8 = saved_language: { const old_language = old_language: { - const result = (internal_os.getenv(alloc, "LANG") catch break :old_language null) orelse break :old_language null; - defer result.deinit(alloc); - break :old_language alloc.dupeZ(u8, result.value) catch break :old_language null; + const lang = global.environ().getPosix("LANG") orelse break :old_language null; + break :old_language alloc.dupeSentinel(u8, @ptrCast(lang), 0) catch null; }; - - if (config.language) |language| _ = internal_os.setenv("LANG", language); - + if (config.language) |language| { + // Override LANG if we need to (sync global environs if so) + _ = setenv("LANG", @ptrCast(language), 1); + global.syncEnviron(); + } break :saved_language old_language; }; @@ -294,7 +308,7 @@ pub const Application = extern struct { // Setup our GTK init env vars setGtkEnv(&config) catch |err| switch (err) { - error.NoSpaceLeft => { + error.WriteFailed => { // If we fail to set GTK environment variables then we still // try to start the application... log.warn( @@ -338,7 +352,7 @@ pub const Application = extern struct { // I'm unsure of any scenario where this happens. Because we don't // want to litter null checks everywhere, we just exit here. log.warn("gdk display is null, exiting", .{}); - std.posix.exit(1); + std.process.exit(1); }; // Setup our windowing protocol logic @@ -696,6 +710,11 @@ pub const Application = extern struct { .initial_size => return Action.initialSize(target, value), .inspector => return Action.controlInspector(target, value), + .export_terminal_io => return try Action.exportTerminalIO( + self, + target, + value, + ), .key_sequence => return Action.keySequence(target, value), .key_table => return Action.keyTable(target, value), @@ -705,10 +724,11 @@ pub const Application = extern struct { .mouse_visibility => Action.mouseVisibility(target, value), .move_tab => return Action.moveTab(target, value), + .move_tab_to_new_window => return Action.moveTabToNewWindow(target), .new_split => return Action.newSplit(target, value), - .new_tab => return Action.newTab(target), + .new_tab => return Action.newTab(target, .none), .new_window => try Action.newWindow( self, @@ -719,7 +739,7 @@ pub const Application = extern struct { .none, ), - .open_config => return Action.openConfig(self), + .open_config => return Action.openConfig(self, value), .open_url => Action.openUrl(self, value), @@ -750,6 +770,7 @@ pub const Application = extern struct { .set_title => Action.setTitle(target, value), .set_tab_title => return Action.setTabTitle(target, value), + .set_window_title => return Action.setWindowTitle(target, value), .show_child_exited => return Action.showChildExited(target, value), @@ -1016,6 +1037,38 @@ pub const Application = extern struct { \\} \\ \\/* + \\ * Drag and Drop Overlay + \\ */ + \\.drop-overlay.drop-left { + \\ background: linear-gradient( + \\ to left, + \\ transparent, 50%, + \\ color-mix(in srgb, var(--accent-bg-color), transparent 80%) 50% + \\ ); + \\} + \\.drop-overlay.drop-right { + \\ background: linear-gradient( + \\ to right, + \\ transparent, 50%, + \\ color-mix(in srgb, var(--accent-bg-color), transparent 80%) 50% + \\ ); + \\} + \\.drop-overlay.drop-top { + \\ background: linear-gradient( + \\ to top, + \\ transparent, 50%, + \\ color-mix(in srgb, var(--accent-bg-color), transparent 80%) 50% + \\ ); + \\} + \\.drop-overlay.drop-bottom { + \\ background: linear-gradient( + \\ to bottom, + \\ transparent, 50%, + \\ color-mix(in srgb, var(--accent-bg-color), transparent 80%) 50% + \\ ); + \\} + \\ + \\/* \\ * Splits \\ */ \\ @@ -1063,7 +1116,11 @@ pub const Application = extern struct { } } - fn loadCustomCss(self: *Self) (std.fs.File.ReadError || Allocator.Error)!void { + const LoadCustomCssError = std.Io.File.OpenError || + compat_file.ReadToEndAllocError || + std.mem.Allocator.Error; + + fn loadCustomCss(self: *Self) LoadCustomCssError!void { const priv: *Private = self.private(); const alloc = self.allocator(); const display = gdk.Display.getDefault() orelse { @@ -1087,7 +1144,11 @@ pub const Application = extern struct { .optional => |path| .{ path, true }, .required => |path| .{ path, false }, }; - const file = std.fs.openFileAbsolute(path, .{}) catch |err| { + const file = std.Io.Dir.openFileAbsolute( + global.io(), + path, + .{}, + ) catch |err| { if (err != error.FileNotFound or !optional) { log.warn( "error opening gtk-custom-css file {s}: {}", @@ -1096,12 +1157,14 @@ pub const Application = extern struct { } continue; }; - defer file.close(); + defer file.close(global.io()); const css_file_size_limit = 5 * 1024 * 1024; // 5MB log.info("loading gtk-custom-css path={s}", .{path}); - const contents = file.readToEndAlloc( + + const contents = compat_file.readToEndAlloc( + file, alloc, css_file_size_limit, ) catch |err| switch (err) { @@ -1111,6 +1174,7 @@ pub const Application = extern struct { }, else => |e| return e, }; + defer alloc.free(contents); const bytes = glib.Bytes.new(contents.ptr, contents.len); @@ -1141,7 +1205,8 @@ pub const Application = extern struct { fn syncActionAccelerators(self: *Self) void { self.syncActionAccelerator("app.quit", .{ .quit = {} }); - self.syncActionAccelerator("app.open-config", .{ .open_config = {} }); + self.syncActionAccelerator("app.open-config::os-open", .{ .open_config = .os_open }); + self.syncActionAccelerator("app.open-config::new-window", .{ .open_config = .new_window }); self.syncActionAccelerator("app.reload-config", .{ .reload_config = {} }); self.syncActionAccelerator("win.toggle-inspector", .{ .inspector = .toggle }); self.syncActionAccelerator("app.show-gtk-inspector", .show_gtk_inspector); @@ -1400,8 +1465,8 @@ pub const Application = extern struct { fn startupSignals(self: *Self) void { const priv = self.private(); assert(priv.signal_source == null); - priv.signal_source = glib.unixSignalAdd( - std.posix.SIG.USR2, + priv.signal_source = glibunix.signalAdd( + @intFromEnum(std.posix.SIG.USR2), handleSigusr2, self, ); @@ -1415,14 +1480,22 @@ pub const Application = extern struct { const as_variant_type = glib.VariantType.new("as"); defer as_variant_type.free(); + const tas_variant_type = glib.VariantType.new("(tas)"); + defer tas_variant_type.free(); + + const s_variant_type = glib.ext.VariantType.newFor([:0]const u8); + defer s_variant_type.free(); + const actions = [_]ext.actions.Action(Self){ .init("new-window", actionNewWindow, null), .init("new-window-command", actionNewWindow, as_variant_type), - .init("open-config", actionOpenConfig, null), + .init("new-tab", actionNewTab, tas_variant_type), + .init("open-config", actionOpenConfig, s_variant_type), .init("present-surface", actionPresentSurface, t_variant_type), .init("quit", actionQuit, null), .init("reload-config", actionReloadConfig, null), .init("toggle-quick-terminal", actionToggleQuickTerminal, null), + .init("ring-bell", actionRingBell, null), }; ext.actions.add(Self, self, &actions); @@ -1454,6 +1527,14 @@ pub const Application = extern struct { self, .{}, ); + + _ = GlobalShortcuts.signals.@"bind-failed".connect( + priv.global_shortcuts, + *Application, + globalShortcutBindFailed, + self, + .{}, + ); } fn activate(self: *Self) callconv(.c) void { @@ -1461,7 +1542,7 @@ pub const Application = extern struct { // Queue a new window const priv = self.private(); - _ = priv.core_app.mailbox.push(.{ + _ = priv.core_app.mailbox.push(global.io(), .{ .new_window = .{}, }, .{ .forever = {} }); @@ -1478,7 +1559,7 @@ pub const Application = extern struct { diag.close(); diag.unref(); // strong ref from get() } - priv.config_errors_dialog.set(null); + priv.config_errors_dialog.deinit(); if (priv.signal_source) |v| { if (glib.Source.remove(v) == 0) { log.warn("unable to remove signal source", .{}); @@ -1486,6 +1567,11 @@ pub const Application = extern struct { priv.signal_source = null; } + if (priv.bell_media) |v| { + v.unref(); + priv.bell_media = null; + } + gobject.Object.virtual_methods.dispose.call( Class.parent, self.as(Parent), @@ -1662,6 +1748,41 @@ pub const Application = extern struct { }; } + /// May fire before any window exists, hence a desktop notification + /// rather than a toast. + fn globalShortcutBindFailed( + _: *GlobalShortcuts, + failure: *const GlobalShortcuts.BindFailed, + self: *Self, + ) callconv(.c) void { + var label_buf: [128]u8 = undefined; + var writer: std.Io.Writer = .fixed(&label_buf); + const label: []const u8 = label: { + const ok = key.labelFromTrigger(&writer, failure.trigger) catch false; + break :label if (ok) writer.buffered() else "?"; + }; + + const detail: [*:0]const u8 = detail: { + if (failure.message[0] != 0) break :detail failure.message; + break :detail if (failure.revoked) + i18n._("The keybind was revoked by the system.") + else + i18n._("The keybind was denied by the system."); + }; + + var body_buf: [512]u8 = undefined; + const body = std.fmt.bufPrintZ( + &body_buf, + "{s}: {s}", + .{ label, detail }, + ) catch return; + + Action.desktopNotification(self, .app, .{ + .title = std.mem.span(i18n._("Global keybind unavailable")), + .body = body, + }); + } + fn actionReloadConfig( _: *gio.SimpleAction, _: ?*glib.Variant, @@ -1703,93 +1824,227 @@ pub const Application = extern struct { ) callconv(.c) void { log.debug("received new window action", .{}); - var arena: std.heap.ArenaAllocator = .init(Application.default().allocator()); + var arena: std.heap.ArenaAllocator = .init(self.core().alloc); defer arena.deinit(); const alloc = arena.allocator(); - var working_directory: ?[:0]const u8 = null; - var title: ?[:0]const u8 = null; - var command: ?configpkg.Command = null; - var args: std.ArrayList([:0]const u8) = .empty; - - overrides: { + const overrides = overrides: { // were we given a parameter? - const parameter = parameter_ orelse break :overrides; + const arguments = parameter_ orelse break :overrides null; const as_variant_type = glib.VariantType.new("as"); defer as_variant_type.free(); // ensure that the supplied parameter is an array of strings - if (glib.Variant.isOfType(parameter, as_variant_type) == 0) { + if (glib.Variant.isOfType(arguments, as_variant_type) == 0) { log.warn("parameter is of type '{s}', not '{s}'", .{ - parameter.getTypeString(), + arguments.getTypeString(), as_variant_type.peekString()[0..as_variant_type.getStringLength()], }); - break :overrides; + break :overrides null; } - const s_variant_type = glib.VariantType.new("s"); - defer s_variant_type.free(); + var arguments_it: glib.VariantIter = undefined; + _ = arguments_it.init(arguments); - var it: glib.VariantIter = undefined; - _ = it.init(parameter); + break :overrides parseOverrides(alloc, &arguments_it) catch null; + }; - var e_seen: bool = false; - var i: usize = 0; + Action.newWindow( + self, + null, + if (overrides) |o| .{ + .command = o.command, + .shell_integration = o.shell_integration, + .working_directory = o.working_directory, + .title = o.title, + } else .none, + ) catch |err| { + log.warn("unable to create new window: {t}", .{err}); + }; + } - while (it.nextValue()) |value| : (i += 1) { - defer value.unref(); + /// Handle `app.new-tab` GTK action + pub fn actionNewTab( + _: *gio.SimpleAction, + parameter_: ?*glib.Variant, + self: *Self, + ) callconv(.c) void { + log.debug("received new tab action", .{}); - // just to be sure - if (value.isOfType(s_variant_type) == 0) continue; + const core_app = self.core(); - var len: usize = undefined; - const buf = value.getString(&len); - const str = buf[0..len]; + var arena: std.heap.ArenaAllocator = .init(core_app.alloc); + defer arena.deinit(); - log.debug("new-window argument: {d} {s}", .{ i, str }); + const alloc = arena.allocator(); - if (e_seen) { - const duplicated = alloc.dupeZ(u8, str) catch |err| { - log.warn("unable to duplicate argument {d} {s}: {t}", .{ i, str, err }); - break :overrides; - }; - args.append(alloc, duplicated) catch |err| { - log.warn("unable to append argument {d} {s}: {t}", .{ i, str, err }); - break :overrides; - }; - continue; - } + const surface_id_, const overrides = result: { + // were we given a parameter? + const parameter = parameter_ orelse { + log.warn("app.new-tab did not receive a parameter", .{}); + return; + }; - if (std.mem.eql(u8, str, "-e")) { - e_seen = true; - continue; - } + log.warn("got parameter: {s}", .{parameter.getTypeString()}); - if (lib.cutPrefix(u8, str, "--command=")) |v| { - var cmd: configpkg.Command = undefined; - cmd.parseCLI(alloc, v) catch |err| { - log.warn("unable to parse command: {t}", .{err}); - continue; - }; - command = cmd; - continue; - } - if (lib.cutPrefix(u8, str, "--working-directory=")) |v| { - working_directory = alloc.dupeZ(u8, std.mem.trim(u8, v, &std.ascii.whitespace)) catch |err| wd: { - log.warn("unable to duplicate working directory: {t}", .{err}); - break :wd null; - }; - continue; - } - if (lib.cutPrefix(u8, str, "--title=")) |v| { - title = alloc.dupeZ(u8, std.mem.trim(u8, v, &std.ascii.whitespace)) catch |err| t: { - log.warn("unable to duplicate title: {t}", .{err}); - break :t null; - }; + const tas_variant_type = glib.VariantType.new("(tas)"); + defer tas_variant_type.free(); + + // ensure that the supplied parameter is an array of strings + if (glib.Variant.isOfType(parameter, tas_variant_type) == 0) { + log.warn("parameter is of type '{s}', not '{s}'", .{ + parameter.getTypeString(), + tas_variant_type.peekString()[0..tas_variant_type.getStringLength()], + }); + return; + } + + var surface_id: u64 = 0; + var arguments_it_: ?*glib.VariantIter = null; + defer if (arguments_it_) |arguments_it| arguments_it.free(); + + parameter.get("(tas)", &surface_id, &arguments_it_); + + const arguments_it = arguments_it_ orelse return; + + const overrides = parseOverrides(alloc, arguments_it) catch return; + + break :result .{ if (surface_id == 0) null else surface_id, overrides }; + }; + + const surface_ = surface: { + if (surface_id_) |surface_id| find_by_id: { + break :surface core_app.findSurfaceByID(surface_id) orelse { + log.warn("new-tab: unable to find surface 0x{x:0>16}", .{surface_id}); + break :find_by_id; + }; + } + find_focused: { + break :surface core_app.focusedSurface() orelse { + log.warn("new-tab: unable to find surface", .{}); + break :find_focused; + }; + } + break :surface null; + }; + + if (surface_) |surface| { + if (!Action.newTab( + .{ + .surface = surface, + }, + .{ + .command = overrides.command, + .shell_integration = overrides.shell_integration, + .working_directory = overrides.working_directory, + .title = overrides.title, + }, + )) { + log.warn("new-tab: unable to create tab", .{}); + } + } else { + Action.newWindow( + self, + null, + .{ + .command = overrides.command, + .shell_integration = overrides.shell_integration, + .working_directory = overrides.working_directory, + .title = overrides.title, + }, + ) catch |err| { + log.warn("new-tab: unable to create new window: {t}", .{err}); + }; + } + } + + fn parseOverrides(arena_alloc: Allocator, arguments_it: *glib.VariantIter) (Allocator.Error || error{ValueRequired})!struct { + command: ?configpkg.Command = null, + shell_integration: ?configpkg.Config.ShellIntegration = null, + working_directory: ?[:0]const u8 = null, + title: ?[:0]const u8 = null, + } { + var args: std.ArrayList([:0]const u8) = .empty; + + var working_directory: ?[:0]const u8 = null; + var title: ?[:0]const u8 = null; + var command: ?configpkg.Command = null; + var parsed_shell_integration: struct { + @"shell-integration": ?configpkg.Config.ShellIntegration = null, + } = .{}; + + const s_variant_type = glib.VariantType.new("s"); + defer s_variant_type.free(); + + var e_seen: bool = false; + var i: usize = 0; + + while (arguments_it.nextValue()) |value| : (i += 1) { + defer value.unref(); + + // just to be sure + if (value.isOfType(s_variant_type) == 0) continue; + + var len: usize = undefined; + const buf = value.getString(&len); + const str = buf[0..len]; + + log.debug("argument: {d} {s}", .{ i, str }); + + if (e_seen) { + const copy = arena_alloc.dupeZ(u8, str) catch |err| { + log.warn("unable to duplicate argument {d} {s}: {t}", .{ i, str, err }); + return err; + }; + args.append(arena_alloc, copy) catch |err| { + log.warn("unable to append argument {d} {s}: {t}", .{ i, str, err }); + return err; + }; + continue; + } + + if (std.mem.eql(u8, str, "-e")) { + e_seen = true; + continue; + } + + if (std.mem.cutPrefix(u8, str, "--command=")) |v| { + var cmd: configpkg.Command = undefined; + cmd.parseCLI(arena_alloc, v) catch |err| { + log.warn("unable to parse command: {t}", .{err}); + return err; + }; + command = cmd; + continue; + } + if (std.mem.cutPrefix(u8, str, "--shell-integration=")) |v| { + cli.args.parseIntoField( + @TypeOf(parsed_shell_integration), + arena_alloc, + &parsed_shell_integration, + "shell-integration", + std.mem.trim(u8, v, &std.ascii.whitespace), + ) catch |err| { + log.warn("unable to parse shell integration {s}: {t}", .{ v, err }); continue; - } + }; + continue; + } + if (std.mem.cutPrefix(u8, str, "--working-directory=")) |v| { + working_directory = arena_alloc.dupeZ(u8, std.mem.trim(u8, v, &std.ascii.whitespace)) catch |err| { + log.warn("unable to duplicate working directory: {t}", .{err}); + return err; + }; + continue; + } + if (std.mem.cutPrefix(u8, str, "--title=")) |v| { + title = arena_alloc.dupeZ(u8, std.mem.trim(u8, v, &std.ascii.whitespace)) catch |err| { + log.warn("unable to duplicate title: {t}", .{err}); + return err; + }; + continue; } } @@ -1799,21 +2054,52 @@ pub const Application = extern struct { }; } - Action.newWindow(self, null, .{ + return .{ .command = command, + .shell_integration = parsed_shell_integration.@"shell-integration", .working_directory = working_directory, .title = title, - }) catch |err| { - log.warn("unable to create new window: {t}", .{err}); }; } pub fn actionOpenConfig( _: *gio.SimpleAction, - _: ?*glib.Variant, + parameter_: ?*glib.Variant, self: *Self, ) callconv(.c) void { - _ = self.core().mailbox.push(.open_config, .forever); + const target: CoreApp.Message.OpenConfig = target: { + const target_map: std.StaticStringMap(CoreApp.Message.OpenConfig) = .initComptime(&.{ + .{ "os-open", .os_open }, + .{ "new-window", .new_window }, + }); + + const parameter = parameter_ orelse { + log.warn("no parameter provided to app.open-config action", .{}); + break :target .os_open; + }; + + const s_variant_type = glib.ext.VariantType.newFor([:0]const u8); + defer s_variant_type.free(); + + if (parameter.isOfType(s_variant_type) == 0) { + log.warn("parameter to app.open-config action is of type '{s}' not '{s}'", .{ + parameter.getTypeString(), + s_variant_type.peekString()[0..s_variant_type.getStringLength()], + }); + break :target .os_open; + } + + var len: usize = undefined; + const buf = parameter.getString(&len); + const str = buf[0..len]; + + break :target target_map.get(str) orelse { + log.warn("'{s}' is not configured as a target for the app.open-config action", .{str}); + break :target .os_open; + }; + }; + + _ = self.core().mailbox.push(global.io(), .{ .open_config = target }, .forever); } fn actionPresentSurface( @@ -1839,6 +2125,7 @@ pub const Application = extern struct { const surface = self.core().findSurfaceByID(surface_id) orelse return; _ = self.core().mailbox.push( + global.io(), .{ .surface_message = .{ .surface = surface, @@ -1849,6 +2136,40 @@ pub const Application = extern struct { ); } + pub fn actionRingBell( + _: *gio.SimpleAction, + _: ?*glib.Variant, + self: *Self, + ) callconv(.c) void { + const priv: *Private = self.private(); + const config = priv.config.get(); + + // Do our sound + if (config.@"bell-features".audio) audio: { + const config_path = config.@"bell-audio-path" orelse break :audio; + const path, const required = switch (config_path) { + .optional => |path| .{ path, false }, + .required => |path| .{ path, true }, + }; + + const volume = std.math.clamp( + config.@"bell-audio-volume", + 0.0, + 1.0, + ); + + // Reuse one MediaFile per application (rebuilt only when the path + // changes) so each bell replays the same pipeline instead of + // leaking a fresh one. Assign unconditionally: bellMediaFile frees + // any stale MediaFile and returns the current slot value (possibly + // null if the path is now inaccessible), so priv.bell_media never + // dangles. + priv.bell_media = media.bellMediaFile(priv.bell_media, path, required); + const media_file = priv.bell_media orelse break :audio; + media.playBell(media_file, volume); + } + } + //---------------------------------------------------------------- // Boilerplate/Noise @@ -1866,11 +2187,8 @@ pub const Application = extern struct { fn init(class: *Class) callconv(.c) void { // Register our compiled resources exactly once. { - const c = @cImport({ - // generated header files - @cInclude("ghostty_resources.h"); - }); - if (c.ghostty_get_resource()) |ptr| { + const ghostty_gtk_resources = @import("ghostty_gtk_resources"); + if (ghostty_gtk_resources.ghostty_get_resource()) |ptr| { gio.resourcesRegister(@ptrCast(@alignCast(ptr))); } else { // If we fail to load resources then things will @@ -1894,11 +2212,11 @@ pub const Application = extern struct { }; pub fn openUrlFallback(self: *Application, kind: apprt.action.OpenUrl.Kind, url: []const u8) void { + _ = self; // Fallback to the minimal cross-platform way of opening a URL. // This is always a safe fallback and enables for example Windows // to open URLs (GTK on Windows via WSL is a thing). internal_os.open( - self.allocator(), kind, url, ) catch |err| log.warn("unable to open url: {}", .{err}); @@ -1938,6 +2256,98 @@ const Action = struct { }; } + pub fn exportTerminalIO( + self: *Application, + target: apprt.Target, + value: apprt.Action.Value(.export_terminal_io), + ) Allocator.Error!bool { + const surface = switch (target) { + .app => return false, + .surface => |v| v.rt_surface.gobj(), + }; + + const alloc = self.allocator(); + const contents = try alloc.dupe(u8, value.contents); + errdefer alloc.free(contents); + const request = try alloc.create(ExportTerminalIORequest); + errdefer alloc.destroy(request); + request.* = .{ + .alloc = alloc, + .contents = contents, + }; + + const parent = ext.getAncestor(gtk.Window, surface.as(gtk.Widget)); + const dialog = gtk.FileChooserNative.new( + i18n._("Export Terminal IO Events"), + parent, + .save, + i18n._("Export"), + i18n._("Cancel"), + ); + const chooser = dialog.as(gtk.FileChooser); + chooser.setCreateFolders(1); + chooser.setCurrentName("ghostty-terminal-io.txt"); + + _ = gtk.NativeDialog.signals.response.connect( + dialog, + *ExportTerminalIORequest, + ExportTerminalIORequest.response, + request, + .{ .destroyData = ExportTerminalIORequest.destroy }, + ); + dialog.as(gtk.NativeDialog).show(); + return true; + } + + const ExportTerminalIORequest = struct { + alloc: Allocator, + contents: []u8, + + fn destroy(self: *ExportTerminalIORequest) callconv(.c) void { + self.alloc.free(self.contents); + self.alloc.destroy(self); + } + + fn response( + dialog: *gtk.FileChooserNative, + response_id: c_int, + self: *ExportTerminalIORequest, + ) callconv(.c) void { + defer dialog.unref(); + + if (response_id != @intFromEnum(gtk.ResponseType.accept)) return; + + const file = dialog.as(gtk.FileChooser).getFile() orelse { + log.warn("inspector export dialog returned no file", .{}); + return; + }; + defer file.unref(); + + var gerr: ?*glib.Error = null; + const replaced = file.replaceContents( + self.contents.ptr, + self.contents.len, + null, + 0, + .{}, + null, + null, + &gerr, + ); + if (gerr) |err| { + defer err.free(); + log.err( + "failed to export terminal IO events err={s}", + .{err.f_message orelse "(unknown)"}, + ); + return; + } + if (replaced == 0) { + log.err("failed to export terminal IO events", .{}); + } + } + }; + pub fn configChange( self: *Application, target: apprt.Target, @@ -2202,6 +2612,26 @@ const Action = struct { } } + pub fn moveTabToNewWindow( + target: apprt.Target, + ) bool { + switch (target) { + .app => return false, + .surface => |core| { + const surface = core.rt_surface.surface; + const window = ext.getAncestor( + Window, + surface.as(gtk.Widget), + ) orelse { + log.warn("surface is not in a window, ignoring new_tab_to_new_window", .{}); + return false; + }; + + return window.moveTabToNewWindow(surface); + }, + } + } + pub fn newSplit( target: apprt.Target, direction: apprt.action.SplitDirection, @@ -2224,7 +2654,17 @@ const Action = struct { } } - pub fn newTab(target: apprt.Target) bool { + pub fn newTab( + target: apprt.Target, + overrides: struct { + command: ?configpkg.Command = null, + shell_integration: ?configpkg.Config.ShellIntegration = null, + working_directory: ?[:0]const u8 = null, + title: ?[:0]const u8 = null, + + pub const none: @This() = .{}; + }, + ) bool { switch (target) { .app => { log.warn("new tab to app is unexpected", .{}); @@ -2243,7 +2683,12 @@ const Action = struct { log.warn("surface is not in a window, ignoring new_tab", .{}); return false; }; - window.newTab(core); + window.newTab(core, .{ + .command = overrides.command, + .shell_integration = overrides.shell_integration, + .working_directory = overrides.working_directory, + .title = overrides.title, + }); return true; }, } @@ -2254,6 +2699,7 @@ const Action = struct { parent: ?*CoreSurface, overrides: struct { command: ?configpkg.Command = null, + shell_integration: ?configpkg.Config.ShellIntegration = null, working_directory: ?[:0]const u8 = null, title: ?[:0]const u8 = null, @@ -2276,6 +2722,7 @@ const Action = struct { parent, .{ .command = overrides.command, + .shell_integration = overrides.shell_integration, .working_directory = overrides.working_directory, .title = overrides.title, }, @@ -2288,6 +2735,7 @@ const Action = struct { parent: ?*CoreSurface, overrides: struct { command: ?configpkg.Command = null, + shell_integration: ?configpkg.Config.ShellIntegration = null, working_directory: ?[:0]const u8 = null, title: ?[:0]const u8 = null, @@ -2308,6 +2756,7 @@ const Action = struct { // Create a new tab with window context (first tab in new window) win.newTabForWindow(parent, .{ .command = overrides.command, + .shell_integration = overrides.shell_integration, .working_directory = overrides.working_directory, .title = overrides.title, }); @@ -2328,18 +2777,55 @@ const Action = struct { gtk.Window.present(win.as(gtk.Window)); } - pub fn openConfig(self: *Application) bool { - // Get the config file path + pub fn openConfig(self: *Application, value: apprt.action.OpenConfig) bool { const alloc = self.allocator(); + + // Get the config file path const path = configpkg.edit.openPath(alloc) catch |err| { - log.warn("error getting config file path: {}", .{err}); + log.warn("error getting config file path: {t}", .{err}); return false; }; defer alloc.free(path); - // Open it using openURL. "path" isn't actually a URL but - // at the time of writing that works just fine for GTK. - openUrl(self, .{ .kind = .text, .url = path }); + switch (value) { + .os_open => { + // Open it using openUrl. "path" isn't actually a URL but + // at the time of writing that works just fine for GTK. + openUrl(self, .{ .kind = .text, .url = path }); + }, + + .new_window => { + const cmd = internal_os.getConfigEditCommand(alloc, path, .default) catch |err| { + log.warn("unable to get command to edit the config: {t}", .{err}); + return false; + }; + defer alloc.free(cmd); + + const command: configpkg.Command = .{ + .direct = &.{ "/bin/sh", "-c", cmd }, + }; + + const title = std.fmt.allocPrintSentinel( + alloc, + "{s} {s}", + .{ i18n._("Editing configuration file"), path }, + 0, + ) catch |err| t: { + log.warn("unable to format title: {t}", .{err}); + break :t null; + }; + defer if (title) |t| alloc.free(t); + + Action.newWindow(self, null, .{ + .command = command, + .title = title, + }) catch |err| { + log.warn("unable to create new window: {t}", .{err}); + return false; + }; + }, + } + return true; } @@ -2434,6 +2920,23 @@ const Action = struct { }, } }, + .window => { + switch (target) { + .app => return false, + .surface => |v| { + const surface = v.rt_surface.surface; + const win = ext.getAncestor( + Window, + surface.as(gtk.Widget), + ) orelse { + log.warn("surface is not in a window, ignoring prompt_window_title", .{}); + return false; + }; + win.promptWindowTitle(); + return true; + }, + } + }, } } @@ -2605,6 +3108,30 @@ const Action = struct { } } + pub fn setWindowTitle( + target: apprt.Target, + value: apprt.action.SetTitle, + ) bool { + switch (target) { + .app => { + log.warn("set_tab_title to app is unexpected", .{}); + return false; + }, + .surface => |core| { + const surface = core.rt_surface.surface; + const window = ext.getAncestor( + Window, + surface.as(gtk.Widget), + ) orelse { + log.warn("surface is not in a window, ignoring set_window_title", .{}); + return false; + }; + window.setTitleOverride(if (value.title.len == 0) null else value.title); + return true; + }, + } + } + pub fn showChildExited( target: apprt.Target, value: apprt.surface.Message.ChildExited, @@ -2846,7 +3373,7 @@ const Action = struct { /// given the runtime environment or configuration. /// /// This must be called BEFORE GTK initialization. -fn setGtkEnv(config: *const CoreConfig) error{NoSpaceLeft}!void { +fn setGtkEnv(config: *const CoreConfig) std.Io.Writer.Error!void { assert(gtk.isInitialized() == 0); var gdk_debug: struct { @@ -2863,7 +3390,7 @@ fn setGtkEnv(config: *const CoreConfig) error{NoSpaceLeft}!void { } = .{ // `gtk-opengl-debug` dumps logs directly to stderr so both must be true // to enable OpenGL debugging. - .opengl = state.logging.stderr and config.@"gtk-opengl-debug", + .opengl = global.logging().stderr and config.@"gtk-opengl-debug", }; var gdk_disable: struct { @@ -2915,8 +3442,7 @@ fn setGtkEnv(config: *const CoreConfig) error{NoSpaceLeft}!void { { var buf: [1024]u8 = undefined; - var fmt = std.io.fixedBufferStream(&buf); - const writer = fmt.writer(); + var writer: std.Io.Writer = .fixed(&buf); var first: bool = true; inline for (@typeInfo(@TypeOf(gdk_debug)).@"struct".fields) |field| { if (@field(gdk_debug, field.name)) { @@ -2926,15 +3452,14 @@ fn setGtkEnv(config: *const CoreConfig) error{NoSpaceLeft}!void { } } try writer.writeByte(0); - const value = fmt.getWritten(); + const value = writer.buffered(); log.warn("setting GDK_DEBUG={s}", .{value[0 .. value.len - 1]}); - _ = internal_os.setenv("GDK_DEBUG", value[0 .. value.len - 1 :0]); + _ = setenv("GDK_DEBUG", @ptrCast(value[0 .. value.len - 1 :0]), 1); } { var buf: [1024]u8 = undefined; - var fmt = std.io.fixedBufferStream(&buf); - const writer = fmt.writer(); + var writer: std.Io.Writer = .fixed(&buf); var first: bool = true; inline for (@typeInfo(@TypeOf(gdk_disable)).@"struct".fields) |field| { if (@field(gdk_disable, field.name)) { @@ -2944,10 +3469,13 @@ fn setGtkEnv(config: *const CoreConfig) error{NoSpaceLeft}!void { } } try writer.writeByte(0); - const value = fmt.getWritten(); + const value = writer.buffered(); log.warn("setting GDK_DISABLE={s}", .{value[0 .. value.len - 1]}); - _ = internal_os.setenv("GDK_DISABLE", value[0 .. value.len - 1 :0]); + _ = setenv("GDK_DISABLE", @ptrCast(value[0 .. value.len - 1 :0]), 1); } + + // Sync environ after altering system env + global.syncEnviron(); } fn findActiveWindow(data: ?*const anyopaque, _: ?*const anyopaque) callconv(.c) c_int { diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/clipboard_confirmation_dialog.zig b/vendor/libghostty-vt/src/apprt/gtk/class/clipboard_confirmation_dialog.zig index d44d38a3..d993b55c 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/clipboard_confirmation_dialog.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/clipboard_confirmation_dialog.zig @@ -193,11 +193,11 @@ pub const ClipboardConfirmationDialog = extern struct { const priv = self.private(); const req = priv.request orelse return; switch (req.*) { - .osc_52_write => { + .osc_52_write, .kitty_write => { self.as(Dialog.Parent).setHeading(i18n._("Authorize Clipboard Access")); self.as(Dialog.Parent).setBody(i18n._("An application is attempting to write to the clipboard. The current clipboard contents are shown below.")); }, - .osc_52_read => { + .osc_52_read, .kitty_read => { self.as(Dialog.Parent).setHeading(i18n._("Authorize Clipboard Access")); self.as(Dialog.Parent).setBody(i18n._("An application is attempting to read from the clipboard. The current clipboard contents are shown below.")); }, @@ -205,6 +205,7 @@ pub const ClipboardConfirmationDialog = extern struct { self.as(Dialog.Parent).setHeading(i18n._("Warning: Potentially Unsafe Paste")); self.as(Dialog.Parent).setBody(i18n._("Pasting this text into the terminal may be dangerous as it looks like some commands may be executed.")); }, + .list => unreachable, } } diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/command_palette.zig b/vendor/libghostty-vt/src/apprt/gtk/class/command_palette.zig index 6101e82e..aaec0058 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/command_palette.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/command_palette.zig @@ -153,7 +153,7 @@ pub const CommandPalette = extern struct { priv.source.removeAll(); const alloc = Application.default().allocator(); - var commands: std.ArrayList(*Command) = .{}; + var commands: std.ArrayList(*Command) = .empty; defer { for (commands.items) |cmd| cmd.unref(); commands.deinit(alloc); @@ -581,10 +581,8 @@ const Command = extern struct { const priv = self.private(); priv.data = .{ - .jump = .{ - // TODO: Replace with surface id whenever Ghostty adds one - .sort_key = @intFromPtr(surface), - }, + // Surface should be initialized at this point. + .jump = .{ .sort_key = surface.core().?.id }, }; priv.data.jump.surface.set(surface); @@ -611,7 +609,7 @@ const Command = extern struct { switch (priv.data) { .regular => {}, .jump => |*j| { - j.surface.set(null); + j.surface.deinit(); }, } diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/global_shortcuts.zig b/vendor/libghostty-vt/src/apprt/gtk/class/global_shortcuts.zig index 28987c25..88aaba9f 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/global_shortcuts.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/global_shortcuts.zig @@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator; const gio = @import("gio"); const glib = @import("glib"); const gobject = @import("gobject"); +const global = @import("../../../global.zig"); const Binding = @import("../../../input.zig").Binding; const key = @import("../key.zig"); @@ -82,6 +83,24 @@ pub const GlobalShortcuts = extern struct { pub var offset: c_int = 0; }; + /// A global shortcut that failed to bind or was revoked. + /// Only valid for the duration of the signal emission. + pub const BindFailed = struct { + trigger: Binding.Trigger, + action: Binding.Action, + + /// May be empty. + message: [*:0]const u8, + + /// Revoked after binding rather than denied up front. + revoked: bool, + + pub const getGObjectType = gobject.ext.defineBoxed( + BindFailed, + .{ .name = "GhosttyGlobalShortcutsBindFailed" }, + ); + }; + pub const signals = struct { /// Emitted whenever a global shortcut is triggered. pub const trigger = struct { @@ -94,6 +113,18 @@ pub const GlobalShortcuts = extern struct { void, ); }; + + /// Emitted when a global shortcut fails to bind or is revoked. + pub const @"bind-failed" = struct { + pub const name = "bind-failed"; + pub const connect = impl.connect; + const impl = gobject.ext.defineSignal( + name, + Self, + &.{*const BindFailed}, + void, + ); + }; }; fn init(self: *Self, _: *Class) callconv(.c) void { @@ -109,6 +140,10 @@ pub const GlobalShortcuts = extern struct { fn close(self: *Self) void { const priv = self.private(); + // This is safe to call even if the winproto was already + // deinitialized, which happens during application teardown. + Application.default().winproto().clearGlobalShortcuts(); + if (priv.dbus_connection) |dbus| { if (priv.response_subscription != 0) { dbus.signalUnsubscribe(priv.response_subscription); @@ -152,10 +187,19 @@ pub const GlobalShortcuts = extern struct { const priv = self.private(); - // We need a dbus connection and configuration to proceed. - if (priv.dbus_connection == null) return; + // We need a configuration to proceed. const config = if (priv.config) |v| v.get() else return; + // Prefer a windowing protocol native mechanism over the + // XDG desktop portal when available. + if (Application.default().winproto().bindGlobalShortcuts(self, config)) { + log.debug("global shortcuts bound via winproto", .{}); + return; + } + + // The portal fallback requires a dbus connection. + if (priv.dbus_connection == null) return; + // Setup our new arena that we'll use for memory allocations. assert(priv.arena == null); var arena: std.heap.ArenaAllocator = .init(Application.default().allocator()); @@ -558,10 +602,25 @@ pub const GlobalShortcuts = extern struct { log.debug("activated={s}", .{shortcut_id}); const action = self.private().map.get(std.mem.span(shortcut_id)) orelse return; + self.emitTrigger(&action); + } + + /// Emit the trigger signal. Public for winproto shortcut backends. + pub fn emitTrigger(self: *Self, action: *const Binding.Action) void { signals.trigger.impl.emit( self, null, - .{&action}, + .{action}, + null, + ); + } + + /// Emit the bind-failed signal. Public for winproto shortcut backends. + pub fn emitBindFailed(self: *Self, failure: *const BindFailed) void { + signals.@"bind-failed".impl.emit( + self, + null, + .{failure}, null, ); } @@ -611,6 +670,7 @@ pub const GlobalShortcuts = extern struct { // Signals signals.trigger.impl.register(.{}); + signals.@"bind-failed".impl.register(.{}); // Virtual methods gobject.Object.virtual_methods.dispose.implement(class, &dispose); @@ -630,6 +690,9 @@ fn generateToken(buf: *Token) [:0]const u8 { return std.fmt.bufPrintZ( buf, "ghostty_{x:0<7}", - .{std.crypto.random.int(u28)}, + .{rand_int: { + const rng_impl: std.Random.IoSource = .{ .io = global.io() }; + break :rand_int rng_impl.interface().int(u28); + }}, ) catch unreachable; } diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/imgui_widget.zig b/vendor/libghostty-vt/src/apprt/gtk/class/imgui_widget.zig index 0ef753a8..50247fbf 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/imgui_widget.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/imgui_widget.zig @@ -7,6 +7,7 @@ const adw = @import("adw"); const gdk = @import("gdk"); const gobject = @import("gobject"); const gtk = @import("gtk"); +const global = @import("../../../global.zig"); const input = @import("../../../input.zig"); const gresource = @import("../build/gresource.zig"); @@ -61,13 +62,13 @@ pub const ImguiWidget = extern struct { ig_context: ?*cimgui.c.ImGuiContext = null, /// Our previous instant used to calculate delta time for animations. - instant: ?std.time.Instant = null, + instant: ?std.Io.Timestamp = null, /// Tick callback ID for timed updates. tick_callback_id: c_uint = 0, /// Last render time for throttling to 30 FPS. - last_render_time: ?std.time.Instant = null, + last_render_time: ?std.Io.Timestamp = null, pub var offset: c_int = 0; }; @@ -140,10 +141,11 @@ pub const ImguiWidget = extern struct { const priv = self.private(); const io: *cimgui.c.ImGuiIO = cimgui.c.ImGui_GetIO(); + const now: std.Io.Timestamp = .now(global.io(), .awake); + // Determine our delta time - const now = std.time.Instant.now() catch unreachable; io.DeltaTime = if (priv.instant) |prev| delta: { - const since_ns: f64 = @floatFromInt(now.since(prev)); + const since_ns: f64 = @floatFromInt(prev.durationTo(now).nanoseconds); const ns_per_s: f64 = @floatFromInt(std.time.ns_per_s); const since_s: f32 = @floatCast(since_ns / ns_per_s); break :delta @max(0.00001, since_s); @@ -298,7 +300,7 @@ pub const ImguiWidget = extern struct { // Update last render time for tick callback throttling. const priv = self.private(); - priv.last_render_time = std.time.Instant.now() catch null; + priv.last_render_time = .now(global.io(), .awake); // Setup our frame. We render twice because some ImGui behaviors // take multiple renders to process. I don't know how to make this @@ -457,15 +459,10 @@ pub const ImguiWidget = extern struct { const self: *Self = gobject.ext.cast(Self, widget) orelse return 0; const priv = self.private(); - const now = std.time.Instant.now() catch { - self.queueRender(); - return 1; - }; - // Throttle to 30 FPS (~33ms between frames) const frame_time_ns: u64 = std.time.ns_per_s / 30; const should_render = if (priv.last_render_time) |last| - now.since(last) >= frame_time_ns + last.untilNow(global.io(), .awake).nanoseconds >= frame_time_ns else true; diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/split_tree.zig b/vendor/libghostty-vt/src/apprt/gtk/class/split_tree.zig index 7a6b66de..ca743712 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/split_tree.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/split_tree.zig @@ -214,6 +214,7 @@ pub const SplitTree = extern struct { parent_: ?*Surface, overrides: struct { command: ?configpkg.Command = null, + shell_integration: ?configpkg.Config.ShellIntegration = null, working_directory: ?[:0]const u8 = null, title: ?[:0]const u8 = null, @@ -225,6 +226,7 @@ pub const SplitTree = extern struct { // Create our new surface. const surface: *Surface = .new(.{ .command = overrides.command, + .shell_integration = overrides.shell_integration, .working_directory = overrides.working_directory, .title = overrides.title, }); @@ -239,12 +241,7 @@ pub const SplitTree = extern struct { } // Bind is-split property for new surface - _ = self.as(gobject.Object).bindProperty( - "is-split", - surface.as(gobject.Object), - "is-split", - .{ .sync_create = true }, - ); + surface.bindIsSplit(self); // Create our tree var single_tree = try Surface.Tree.init(alloc, surface); @@ -387,6 +384,77 @@ pub const SplitTree = extern struct { return true; } + /// Move the source split onto the target split in a given direction. + /// The target split must be located within this tree. + pub fn moveSplit( + self: *Self, + source: *Surface, + target: *Surface, + dir: Surface.Tree.Split.Direction, + ) Allocator.Error!void { + const alloc = Application.default().allocator(); + const target_tree = self.getTree() orelse return; + + // This really shouldn't fail, but just in case + const target_handle = target_tree.locate(target) orelse { + log.warn("target is not placed in a split tree", .{}); + return; + }; + + // Try to find the source within the current tree. + // If it exists, then it's a local move; otherwise the logic gets more + // complicated + const source_handle = target_tree.locate(source); + + // First add the source into this tree. + // We have to do this no matter what + var branch = try Surface.Tree.init(alloc, source); + defer branch.deinit(); + + var after_split = try target_tree.split( + alloc, + target_handle, + dir, + 0.5, + &branch, + ); + defer after_split.deinit(); + + if (source_handle) |handle| { + // Happy path: source and target are located within the same tree. + // In that case, we just remove the existing source from this tree + + var after_remove = try after_split.remove(alloc, handle); + defer after_remove.deinit(); + + self.setTree(&after_remove); + } else { + // :( Cross-tree moves are a bit more complicated. + + // TODO: Find a better way to access the split tree from here + const source_tree_widget = ext.getAncestor( + SplitTree, + source.as(gtk.Widget), + ) orelse { + log.warn("source is not placed in a split tree", .{}); + return; + }; + const source_tree = source_tree_widget.getTree() orelse return; + + // Remove the source from its own tree + const handle = source_tree.locate(source) orelse return; + var new_source_tree = try source_tree.remove(alloc, handle); + defer new_source_tree.deinit(); + + // Finally, set the final tree structures for both tree widgets + source_tree_widget.setTree(&new_source_tree); + self.setTree(&after_split); + + // Re-bind vital properties like `is-split` + source.bindIsSplit(self); + } + } + fn disconnectSurfaceHandlers(self: *Self) void { const tree = self.getTree() orelse return; var it = tree.iterator(); @@ -579,7 +647,7 @@ pub const SplitTree = extern struct { fn dispose(self: *Self) callconv(.c) void { const priv = self.private(); - priv.last_focused.set(null); + priv.last_focused.deinit(); if (priv.rebuild_source) |v| { if (glib.Source.remove(v) == 0) { log.warn("unable to remove rebuild source", .{}); @@ -705,17 +773,8 @@ pub const SplitTree = extern struct { // Find the surface in the tree to verify this is valid and // set our pending close handle. - priv.pending_close = handle: { - const tree = self.getTree() orelse return; - var it = tree.iterator(); - while (it.next()) |entry| { - if (entry.view == surface) { - break :handle entry.handle; - } - } - - return; - }; + const tree = self.getTree() orelse return; + priv.pending_close = tree.locate(surface) orelse return; // If we don't need to confirm then just close immediately. if (!core.needsConfirmQuit()) { @@ -1115,12 +1174,17 @@ const SplitTreeSplit = extern struct { /// Assumed to be correct. handle: Surface.Tree.Node.Handle, + /// Cache the split ratio. Looking it up is relatively expensive + /// because we have to first walk the widget tree to find the + /// SplitTree widget. + ratio: f64, + /// Source to handle repositioning the split when properties change. idle: ?c_uint = null, /// Whether the max-position/position property of the gtk.Paned widget /// changed. We use these to distinguish between a resize and the user - /// manually moving the split divider. See the "on-idle" function. + /// manually moving the split divider. See the "onIdle" function. max_changed: bool = false, pos_changed: bool = false, @@ -1144,6 +1208,7 @@ const SplitTreeSplit = extern struct { const self = gobject.ext.newInstance(Self, .{}); const priv = self.private(); priv.handle = handle; + priv.ratio = split.ratio; // Setup our paned fields const paned = priv.paned; @@ -1154,6 +1219,17 @@ const SplitTreeSplit = extern struct { .vertical => .vertical, }); + // Request min width/height 1 for surfaces to prevent them from + // becoming temporarily invisible in nested layouts. Otherwise + // gtk.Paned might mark a surface as not visible and unmap it + // for a single frame. See the comments below in propMaxPosition. + if (gobject.ext.isA(start_child, SurfaceScrolledWindow)) { + start_child.setSizeRequest(1, 1); + } + if (gobject.ext.isA(end_child, SurfaceScrolledWindow)) { + end_child.setSizeRequest(1, 1); + } + // Signals and so on are setup in the template. return self; @@ -1163,49 +1239,18 @@ const SplitTreeSplit = extern struct { gtk.Widget.initTemplate(self.as(gtk.Widget)); } - // We need to keep the split ratios from the tree datastructure and - // widget tree in sync. Using the max-position and position properties - // of the gtk.Paned widget, we can distinguish a resize from a manual - // update (e.g. the user dragging the divider).If max-position changes, - // we always have a widget resize. Usually position will change as well - // but it might not if the size change is small enough. If only position - // changes, we have a manual human update. - // - // This is a hack, it relies on the timing of property notifcations. - // From looking at the GTK source code, it should not be possible that - // we interpret a position change from a resize as a manual update. - // When a gtk.Paned is resized, internally the gtk_paned_calc_position - // function will change both max-position and position and synchronously - // call our propMaxPosition and propPosition functions. I.e. when the - // widget is resized, it should not be possible for onIdle to run before - // we have been notified of both property changes. - fn onIdle(ud: ?*anyopaque) callconv(.c) c_int { - const self: *Self = @ptrCast(@alignCast(ud orelse return 0)); + const SyncDirection = enum { + // Update gtk.Paned widget to match ratio from split tree node. + tree_to_widget, + // Update split tree node to match ratio from gtk.Paned widget. + widget_to_tree, + }; + + // Sync split ratio between the gtk.Paned widget and the split tree. + fn syncSplitRatio(self: *Self, direction: SyncDirection) void { const priv = self.private(); const paned = priv.paned; - // Clear source and fields at the end. Otherwise if setPosition is - // called below, propPosition is triggered and would add another - // idle callback before this one is finished. - defer priv.idle = null; - defer priv.max_changed = false; - defer priv.pos_changed = false; - - if (!priv.max_changed and !priv.pos_changed) { - return 0; - } - - // Get our split. This is the most dangerous part of this entire - // widget. We assume that this widget is always a child of a - // SplitTree, we assume that our handle is valid, and we assume - // the handle is always a split node. - const split_tree = ext.getAncestor( - SplitTree, - self.as(gtk.Widget), - ) orelse return 0; - const tree = split_tree.getTree() orelse return 0; - const split: *const Surface.Tree.Split = &tree.nodes[priv.handle.idx()].split; - // Current, min, and max positions as pixels. const pos = paned.getPosition(); const min = min: { @@ -1236,7 +1281,7 @@ const SplitTreeSplit = extern struct { // If our max is zero then we can't do any math. I don't know // if this is possible but I suspect it can be if you make a nested // split completely minimized. - if (max == 0) return 0; + if (max == 0) return; // Determine our current ratio. const current_ratio: f64 = ratio: { @@ -1244,7 +1289,7 @@ const SplitTreeSplit = extern struct { const max_f64: f64 = @floatFromInt(max); break :ratio pos_f64 / max_f64; }; - const desired_ratio: f64 = @floatCast(split.ratio); + const desired_ratio: f64 = priv.ratio; // If our ratio is close enough to our desired ratio, then // we ignore the update. This is to avoid constant split updates @@ -1255,24 +1300,85 @@ const SplitTreeSplit = extern struct { desired_ratio, 0.001, )) { - return 0; + return; + } + + switch (direction) { + .tree_to_widget => { + // Update position in gtk.Paned to match desired ratio. Note that if + // max-position is small, it might not be possible to accurately set + // the desired ratio. E.g. with max-position=2 you can only have + // ratios 0, 0.5 and 1. + const desired_pos: c_int = desired_pos: { + const max_f64: f64 = @floatFromInt(max); + break :desired_pos @intFromFloat(@round(max_f64 * desired_ratio)); + }; + paned.setPosition(desired_pos); + }, + .widget_to_tree => { + // Update ratio of the split tree node. This is the most dangerous + // part of this widget. We assume that this widget is always a child + // of a SplitTree, we assume that our handle is valid, and we assume + // the handle is always a split node. + const split_tree = ext.getAncestor( + SplitTree, + self.as(gtk.Widget), + ) orelse { + log.warn("SplitTree ancestor not found", .{}); + return; + }; + const tree = split_tree.getTree() orelse { + log.warn("no tree data model set", .{}); + return; + }; + assert(priv.handle.idx() < tree.nodes.len); + assert(tree.nodes[priv.handle.idx()] == .split); + tree.resizeInPlace(priv.handle, @floatCast(current_ratio)); + priv.ratio = current_ratio; + }, + } + } + + // We need to keep the split ratios from the tree datastructure and + // widget tree in sync. Using the max-position and position properties + // of the gtk.Paned widget, we can distinguish a resize from a manual + // update (e.g. the user dragging the divider). If max-position changes, + // we always have a widget resize and we sync the ratio directly from + // the propMaxPosition function. Usually position will change as well + // but it might not if the size change is small enough. If only position + // changes, we have a manual human update and we sync the ratio here. + // + // This is a hack, it relies on the timing of property notifcations. + // From looking at the GTK source code, it should not be possible that + // we interpret a position change from a resize as a manual update. + // When a gtk.Paned is resized, internally the gtk_paned_calc_position + // function will change both max-position and position and synchronously + // call our propMaxPosition and propPosition functions. I.e. when the + // widget is resized, it should not be possible for onIdle to run before + // we have been notified of both property changes. + fn onIdle(ud: ?*anyopaque) callconv(.c) c_int { + const self: *Self = @ptrCast(@alignCast(ud orelse return 0)); + const priv = self.private(); + + // Clear source and fields. + defer { + priv.idle = null; + priv.max_changed = false; + priv.pos_changed = false; } if (priv.max_changed) { - // Widget got resized, update position to match desired ratio. - // Note that if max-position is small, it might not be possible - // to accurately set the desired ratio. E.g. with max-position=2 - // you can only have ratios 0, 0.5 and 1. - const desired_pos: c_int = desired_pos: { - const max_f64: f64 = @floatFromInt(max); - break :desired_pos @intFromFloat(@round(max_f64 * desired_ratio)); - }; - paned.setPosition(desired_pos); - } else { - // If only position changed, this is a manual human update and - // we need to write our update back to the tree. - tree.resizeInPlace(priv.handle, @floatCast(current_ratio)); + // Nothing to do, syncSplitRatio was already called + // directly from propMaxPosition. + return 0; + } + if (!priv.pos_changed) { + return 0; } + + // If only position changed, this is a manual human update and + // we need to write our update back to the tree. + self.syncSplitRatio(.widget_to_tree); return 0; } @@ -1286,6 +1392,41 @@ const SplitTreeSplit = extern struct { ) callconv(.c) void { const priv = self.private(); priv.max_changed = true; + + // Widget got resized, update position to match desired ratio. + // + // Syncing the split ratio directly here ensures that every surface + // gets the correct size allocated immediately. This works because + // this callback runs during size allocation, so that we update the + // divider position right after the gtk.Paned widget computes it and + // right before it will use the position to compute the sizes of its + // children. See the size_allocate and calc_position functions of the + // gtk.Paned widget. + // + // If we synced the ratio in an idle callback, there might be some + // flickering as surfaces are shown with the wrong size for a few + // frames until our idle callback runs. Depending on the split layout + // it might take multiple rounds of size allocation and idle callbacks + // for every widget to get the correct size. + // + // Note that gtk.Paned calls Widget.setChildVisible(true/false) for + // both children based on the initial divider position it computes. + // If we then update the position here, we might sometimes have to + // call setChildVisible again. This would be necessary if we updated + // the position from initially 0 (max), where start (end) child is + // invisible, to a value > 0 (< max). However, we can skip this because + // set_position already queues another round of size allocation, during + // which gtk.Paned will keep the correct position we set manually and + // then call setChildVisible again based on that. The only problematic + // situation is when we update the position from 0 to a value > 0, + // because setChildVisible(false) will unmap the start child widget. + // It will not be visible for a single frame which introduces some + // flickering. To prevent this from happening we set a min size request + // of 1 for all surfaces (see the "new" function above). + self.syncSplitRatio(.tree_to_widget); + + // We still need the idle callback to clear the max_changed field + // later, because propPosition might or might not still get called. if (priv.idle == null) priv.idle = glib.idleAdd( onIdle, self, diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/surface.zig b/vendor/libghostty-vt/src/apprt/gtk/class/surface.zig index 54825ce0..9d45bc6c 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/surface.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/surface.zig @@ -34,8 +34,10 @@ const ClipboardConfirmationDialog = @import("clipboard_confirmation_dialog.zig") const TitleDialog = @import("title_dialog.zig").TitleDialog; const Window = @import("window.zig").Window; const InspectorWindow = @import("inspector_window.zig").InspectorWindow; +const SplitTree = @import("split_tree.zig").SplitTree; const i18n = @import("../../../os/i18n.zig"); -const media = @import("../media.zig"); +const global = @import("../../../global.zig"); +const gtk_version = @import("../gtk_version.zig"); const log = std.log.scoped(.gtk_ghostty_surface); @@ -674,12 +676,6 @@ pub const Surface = extern struct { // false by a parent widget. bell_ringing: bool = false, - // The audio bell's MediaFile, reused across bells so we don't leak a - // GStreamer pipeline (and its GL threads) on every ring. Built lazily - // on the first audio bell and rebuilt when `bell-audio-path` changes; - // unref'd on dispose. See ringBell and media.zig. - bell_media: ?*gtk.MediaFile = null, - /// True if this surface is in an error state. This is currently /// a simple boolean with no additional information on WHAT the /// error state is, because we don't yet need it or use it. For now, @@ -695,6 +691,7 @@ pub const Surface = extern struct { // True if the current surface is a split, this is used to apply // unfocused-split-* options is_split: bool = false, + is_split_binding: ?*gobject.Binding = null, action_group: ?*gio.SimpleActionGroup = null, @@ -713,6 +710,9 @@ pub const Surface = extern struct { child_exited_overlay: *ChildExited, context_menu: *gtk.PopoverMenu, drop_target: *gtk.DropTarget, + surface_drop_target: *gtk.DropTarget, + drag_handle: *gtk.Widget, + drop_overlay: *gtk.Widget, progress_bar_overlay: *gtk.ProgressBar, error_page: *adw.StatusPage, terminal_page: *gtk.Overlay, @@ -736,6 +736,7 @@ pub const Surface = extern struct { overrides: struct { command: ?configpkg.Command = null, + shell_integration: ?configpkg.Config.ShellIntegration = null, working_directory: ?[:0]const u8 = null, pub const none: @This() = .{}; @@ -746,6 +747,7 @@ pub const Surface = extern struct { pub fn new(overrides: struct { command: ?configpkg.Command = null, + shell_integration: ?configpkg.Config.ShellIntegration = null, working_directory: ?[:0]const u8 = null, title: ?[:0]const u8 = null, @@ -758,6 +760,7 @@ pub const Surface = extern struct { const priv: *Private = self.private(); priv.overrides = .{ .command = if (overrides.command) |c| c.clone(alloc) catch null else null, + .shell_integration = overrides.shell_integration, .working_directory = if (overrides.working_directory) |wd| alloc.dupeZ(u8, wd) catch null else null, }; return self; @@ -848,6 +851,28 @@ pub const Surface = extern struct { return @intFromBool(config.@"bell-features".border); } + pub fn bindIsSplit(self: *Self, tree: *SplitTree) void { + const priv = self.private(); + if (priv.is_split_binding) |binding| { + binding.unbind(); + binding.unref(); + priv.is_split_binding = null; + } + + const binding = tree.as(gobject.Object).bindProperty( + "is-split", + self.as(gobject.Object), + "is-split", + .{ .sync_create = true }, + ); + // The ref created by bindProperty is owned by the binding itself. + // We need another ref to prevent the binding object from being + // freed if the source object (SplitTree) is finalized. Otherwise + // our pointer to the binding could become stale. + binding.ref(); + priv.is_split_binding = binding; + } + /// Callback used to determine whether unfocused-split-fill / unfocused-split-opacity /// should be applied to the surface fn closureShouldUnfocusedSplitBeShown( @@ -1363,19 +1388,11 @@ pub const Surface = extern struct { if (entry.native == keycode) break :w3c entry.key; } else .unidentified; - // Consult the pre-remapped XKB keyval/keysym to get the (possibly) - // remapped key. If the W3C key or the remapped key - // is eligible for remapping, we use it. - // - // See the docs for `shouldBeRemappable` for why we even have to - // do this in the first place. - if (gtk_key.keyFromKeyval(keyval)) |remapped| { - if (w3c_key.shouldBeRemappable() or remapped.shouldBeRemappable()) - break :keycode remapped; - } - - // Return the original physical key - break :keycode w3c_key; + break :keycode gtk_key.remapKey( + w3c_key, + keyval, + key_event.isModifier() != 0, + ); }; // Get our modifier for the event @@ -1560,7 +1577,11 @@ pub const Surface = extern struct { // https://gitlab.gnome.org/GNOME/libadwaita/-/commit/a7738a4d269bfdf4d8d5429ca73ccdd9b2450421 // https://gitlab.gnome.org/GNOME/libadwaita/-/commit/9759d3fd81129608dd78116001928f2aed974ead if (gtk_xft_dpi <= 0) { - log.warn("gtk-xft-dpi has invalid value ({}), using default", .{gtk_xft_dpi}); + // -1 is a valid value which specifies default scale. + // https://docs.gtk.org/gtk4/property.Settings.gtk-xft-dpi.html + if (gtk_xft_dpi != -1) { + log.warn("gtk-xft-dpi has invalid value ({}), using default", .{gtk_xft_dpi}); + } break :xft_scale 1.0; } @@ -1589,32 +1610,35 @@ pub const Surface = extern struct { return self.private().cursor_pos; } - pub fn defaultTermioEnv(self: *Self) !std.process.EnvMap { + pub fn defaultTermioEnv(self: *Self) !std.process.Environ.Map { const app = Application.default(); const alloc = app.allocator(); - var env = try internal_os.getEnvMap(alloc); + var env = if (internal_os.isFlatpak()) + std.process.Environ.Map.init(alloc) + else + try global.environMap(); errdefer env.deinit(); if (app.savedLanguage()) |language| { try env.put("LANG", language); } else { - env.remove("LANG"); + _ = env.orderedRemove("LANG"); } // Don't leak these GTK environment variables to child processes. - env.remove("GDK_DEBUG"); - env.remove("GDK_DISABLE"); - env.remove("GSK_RENDERER"); + _ = env.orderedRemove("GDK_DEBUG"); + _ = env.orderedRemove("GDK_DISABLE"); + _ = env.orderedRemove("GSK_RENDERER"); // Remove some environment variables that are set when Ghostty is launched // from a `.desktop` file, by D-Bus activation, or systemd. - env.remove("GIO_LAUNCHED_DESKTOP_FILE"); - env.remove("GIO_LAUNCHED_DESKTOP_FILE_PID"); - env.remove("DBUS_STARTER_ADDRESS"); - env.remove("DBUS_STARTER_BUS_TYPE"); - env.remove("INVOCATION_ID"); - env.remove("JOURNAL_STREAM"); - env.remove("NOTIFY_SOCKET"); + _ = env.orderedRemove("GIO_LAUNCHED_DESKTOP_FILE"); + _ = env.orderedRemove("GIO_LAUNCHED_DESKTOP_FILE_PID"); + _ = env.orderedRemove("DBUS_STARTER_ADDRESS"); + _ = env.orderedRemove("DBUS_STARTER_BUS_TYPE"); + _ = env.orderedRemove("INVOCATION_ID"); + _ = env.orderedRemove("JOURNAL_STREAM"); + _ = env.orderedRemove("NOTIFY_SOCKET"); // Unset environment varies set by snaps if we're running in a snap. // This allows Ghostty to further launch additional snaps. @@ -1641,7 +1665,7 @@ pub const Surface = extern struct { } /// Filter out environment variables that start with forbidden prefixes. - fn filterSnapPaths(gpa: std.mem.Allocator, env_map: *std.process.EnvMap) !void { + fn filterSnapPaths(gpa: std.mem.Allocator, env_map: *std.process.Environ.Map) !void { comptime assert(build_config.snap); const snap_vars = [_][]const u8{ @@ -1708,14 +1732,14 @@ pub const Surface = extern struct { item.key, item.value, ); - for (env_to_remove.items) |key| _ = env_map.remove(key); + for (env_to_remove.items) |key| _ = env_map.orderedRemove(key); } pub fn clipboardRequest( self: *Self, clipboard_type: apprt.Clipboard, state: apprt.ClipboardRequest, - ) !bool { + ) !apprt.ClipboardReadResult { return try Clipboard.request( self, clipboard_type, @@ -1825,8 +1849,19 @@ pub const Surface = extern struct { }; priv.drop_target.setGtypes(&drop_target_types, drop_target_types.len); + // Also have to set up the surface drop target to accept other surfaces + // (in particular, their surface IDs) + var surface_drop_target_types = [_]gobject.Type{ + gobject.ext.types.uint64, + }; + priv.surface_drop_target.setGtypes( + &surface_drop_target_types, + surface_drop_target_types.len, + ); + // Setup properties we can't set from our Blueprint file. self.as(gtk.Widget).setCursorFromName("text"); + priv.drag_handle.setCursorFromName("grab"); // Initialize our config self.propConfig(undefined, null); @@ -1860,9 +1895,10 @@ pub const Surface = extern struct { priv.config = null; } - if (priv.bell_media) |v| { - v.unref(); - priv.bell_media = null; + if (priv.is_split_binding) |binding| { + binding.unbind(); + binding.unref(); + priv.is_split_binding = null; } if (priv.vadj_signal_group) |group| { @@ -1987,6 +2023,58 @@ pub const Surface = extern struct { ); } + fn snapshot(self: *Self, snap: *gtk.Snapshot) callconv(.c) void { + const priv = self.private(); + + const blur = blur: { + // Native GTK blur is only available since GTK 4.23.3 + if (gtk_version.runtimeUntil(4, 23, 3)) break :blur null; + const config = priv.config orelse break :blur null; + + break :blur switch (config.get().@"background-blur") { + .radius => |v| @as(f32, v), + .true, .@"macos-glass-regular", .@"macos-glass-clear" => 20.0, + .false => null, + }; + }; + + if (blur) |b| blur: { + // pushCopy and appendPaste are only supported since 4.22. + // These two functions are crucial for the blur function + // and it cannot be implemented otherwise, so if you compile + // Ghostty on an older GTK version, you won't get blur. + // Sorry. + if (comptime !gtk_version.atLeast(4, 22, 0)) break :blur; + + const width = self.as(gtk.Widget).getWidth(); + const height = self.as(gtk.Widget).getHeight(); + + // Push the current render state (background) + // to be appended below + snap.pushCopy(); + defer snap.pop(); + + // Apply blur to the copied background + snap.pushBlur(b); + defer snap.pop(); + + snap.appendPaste(&.{ + .f_origin = .{ .f_x = 0, .f_y = 0 }, + .f_size = .{ + .f_width = @floatFromInt(width), + .f_height = @floatFromInt(height), + }, + }, 0); + } + + // Draw the children normally + gtk.Widget.virtual_methods.snapshot.call( + Class.parent, + self.as(Parent), + snap, + ); + } + //--------------------------------------------------------------- // Properties @@ -2213,7 +2301,12 @@ pub const Surface = extern struct { // Logic around bell reaction happens on every event even if we're // already in the ringing state. - if (ringing) self.ringBell(); + if (ringing) { + self.ringBell(); + // focus clears ringing state, so we should not change state to + // ringing if we're already focused + if (self.getFocused()) return; + } // Property change only happens on actual state change const priv = self.private(); @@ -2467,8 +2560,6 @@ pub const Surface = extern struct { /// Handle bell features that need to happen every time a BEL is received /// Currently this is audio and system but this could change in the future. fn ringBell(self: *Self) void { - const priv = self.private(); - // Emit the signal signals.bell.impl.emit( self, @@ -2480,33 +2571,7 @@ pub const Surface = extern struct { // Activate actions if they exist _ = self.as(gtk.Widget).activateAction("tab.ring-bell", null); _ = self.as(gtk.Widget).activateAction("win.ring-bell", null); - - const config = if (priv.config) |c| c.get() else return; - - // Do our sound - if (config.@"bell-features".audio) audio: { - const config_path = config.@"bell-audio-path" orelse break :audio; - const path, const required = switch (config_path) { - .optional => |path| .{ path, false }, - .required => |path| .{ path, true }, - }; - - const volume = std.math.clamp( - config.@"bell-audio-volume", - 0.0, - 1.0, - ); - - // Reuse one MediaFile per surface (rebuilt only when the path - // changes) so each bell replays the same pipeline instead of - // leaking a fresh one. Assign unconditionally: bellMediaFile frees - // any stale MediaFile and returns the current slot value (possibly - // null if the path is now inaccessible), so priv.bell_media never - // dangles. - priv.bell_media = media.bellMediaFile(priv.bell_media, path, required); - const media_file = priv.bell_media orelse break :audio; - media.playBell(media_file, volume); - } + _ = self.as(gtk.Widget).activateAction("app.ring-bell", null); } //--------------------------------------------------------------- @@ -2815,7 +2880,10 @@ pub const Surface = extern struct { return; } - if (button == .middle and !priv.gtk_enable_primary_paste) { + if (button == .middle and + !priv.gtk_enable_primary_paste and + !core_surface.mouseReportingActive()) + { return; } @@ -2875,7 +2943,10 @@ pub const Surface = extern struct { return; } - if (button == .middle and !priv.gtk_enable_primary_paste) { + if (button == .middle and + !priv.gtk_enable_primary_paste and + !surface.mouseReportingActive()) + { return; } @@ -3320,7 +3391,7 @@ pub const Surface = extern struct { self: *Self, ) callconv(.c) void { self.updateMapped(true); - self.updateOcclusion(true); + self.updateOcclusion(); } fn glareaUnmap( @@ -3328,7 +3399,7 @@ pub const Surface = extern struct { self: *Self, ) callconv(.c) void { self.updateMapped(false); - self.updateOcclusion(false); + self.updateOcclusion(); } fn updateMapped(self: *Self, mapped: bool) void { @@ -3337,13 +3408,23 @@ pub const Surface = extern struct { self.as(gobject.Object).notifyByPspec(properties.mapped.impl.param_spec); } - fn updateOcclusion(self: *Self, visible: bool) void { + /// Update the core surface visibility based on both GTK widget and + /// toplevel state. This is public so the window can call it when its + /// suspended state changes. + pub fn updateOcclusion(self: *Self) void { const surface = self.core() orelse return; + const visible = self.private().mapped and !self.windowSuspended(); surface.occlusionCallback(visible) catch |err| { log.warn("error in occlusion callback err={}", .{err}); }; } + fn windowSuspended(self: *Self) bool { + const native = self.as(gtk.Widget).getNative() orelse return false; + const window = gobject.ext.cast(gtk.Window, native) orelse return false; + return window.isSuspended() != 0; + } + fn glareaRender( _: *gtk.GLArea, _: *gdk.GLContext, @@ -3461,9 +3542,11 @@ pub const Surface = extern struct { ); defer config.deinit(); - if (priv.overrides.command) |c| { - config.command = try c.clone(config._arena.?.allocator()); - } + try applyCommandOverrides( + &config, + priv.overrides.command, + priv.overrides.shell_integration, + ); if (priv.overrides.working_directory) |wd| { const config_alloc = config.arenaAlloc(); var wd_val: configpkg.WorkingDirectory = .{ .path = try config_alloc.dupe(u8, wd) }; @@ -3597,6 +3680,178 @@ pub const Surface = extern struct { }; } + fn closureShouldDragHandleBeShown( + _: *Self, + config_: ?*Config, + is_split: c_int, + ) callconv(.c) c_int { + const config = config_ orelse return @intFromBool(false); + + const shown = switch (config.get().@"drag-handle") { + .always => true, + .auto => is_split != 0, + .never => false, + }; + return @intFromBool(shown); + } + + fn surfaceDragPrepare( + src: *gtk.DragSource, + x: f64, + y: f64, + self: *Self, + ) callconv(.c) *gdk.ContentProvider { + // TODO: Use a static content provider once we make `self.core()` + // available immediately when constructing the surface widget + _ = src; + _ = x; + _ = y; + var val = gobject.ext.Value.newFrom(self.core().?.id); + return gdk.ContentProvider.newForValue(&val); + } + + fn surfaceDragBegin( + src: *gtk.DragSource, + _: *gdk.Drag, + self: *Self, + ) callconv(.c) void { + // The scale of the preview + const preview_scale: f32 = 0.2; + + // Snapshot the entire surface widget as the icon preview + const paintable = gtk.WidgetPaintable.new(self.as(gtk.Widget)); + defer paintable.unref(); + + // Center the preview + const width = self.as(gtk.Widget).getWidth(); + const height = self.as(gtk.Widget).getHeight(); + const mid_x = @as(f32, @floatFromInt(width)) / 2; + const mid_y = @as(f32, @floatFromInt(height)) / 2; + + // Create a snapshot to render the scaled paintable + const snap = gtk.Snapshot.new(); + snap.scale(preview_scale, preview_scale); + paintable.as(gdk.Paintable).snapshot( + snap.as(gdk.Snapshot), + @floatFromInt(width), + @floatFromInt(height), + ); + + if (snap.freeToPaintable(null)) |scaled| { + defer scaled.unref(); + src.setIcon( + scaled, + @intFromFloat(mid_x * preview_scale), + @intFromFloat(mid_y * preview_scale), + ); + } else { + // The scaling process somehow failed. + // Use the original paintable as a fail-safe + log.warn("preview scaling failed - falling back to original paintable", .{}); + src.setIcon( + paintable.as(gdk.Paintable), + @intFromFloat(mid_x), + @intFromFloat(mid_y), + ); + } + } + + fn surfaceDrop( + _: *gtk.DropTarget, + v: *const gobject.Value, + x: f64, + y: f64, + self: *Self, + ) callconv(.c) void { + const dropped_id = v.getUint64(); + const dropped = self.core().?.app.findSurfaceByID(dropped_id) orelse return; + const from = dropped.rt_surface.gobj(); + + const st = ext.getAncestor( + SplitTree, + self.as(gtk.Widget), + ) orelse { + log.warn("surface is not placed in a split tree", .{}); + return; + }; + + const dir = self.calcDropDirection(x, y); + + // The only error that could happen here is an OOM, + // and in that case we're already milliseconds away from crashing, so... + st.moveSplit(from, self, dir) catch return; + + // Clean up overlay state + self.setDropOverlayDirection(null); + } + + fn surfaceDropLeave( + _: *gtk.DropTarget, + self: *Self, + ) callconv(.c) void { + // Hide overlay + self.setDropOverlayDirection(null); + } + + fn surfaceDropMotion( + _: *gtk.DropTarget, + x: f64, + y: f64, + self: *Self, + ) callconv(.c) gdk.DragAction { + // Recalculate the drop region + const dir = self.calcDropDirection(x, y); + self.setDropOverlayDirection(dir); + return .{ .move = true }; + } + + fn propDropValue( + tgt: *gtk.DropTarget, + _: *gobject.ParamSpec, + self: *Self, + ) callconv(.c) void { + // Reject the drop if we're dropping a surface onto itself. + // Note that we cannot implement this via the `accept` signal, + // since the decision of whether to accept or deny a drop is dependent + // on the payload (i.e. the surface being dropped). This is + // well-documented in GTK docs. + + const core_surface = self.core() orelse return; + const value = tgt.getValue() orelse return; + const surface_id = value.getUint64(); + if (core_surface.id == surface_id) tgt.reject(); + } + + fn setDropOverlayDirection(self: *Self, dir: ?Tree.Split.Direction) void { + const priv = self.private(); + inline for (&.{ "drop-top", "drop-left", "drop-right", "drop-bottom" }) |c| { + priv.drop_overlay.removeCssClass(c); + } + + if (dir) |d| priv.drop_overlay.addCssClass(switch (d) { + .up => "drop-top", + .left => "drop-left", + .right => "drop-right", + .down => "drop-bottom", + }); + } + + fn calcDropDirection(self: *Self, x: f64, y: f64) Tree.Split.Direction { + const width: f64 = @floatFromInt(self.as(gtk.Widget).getWidth()); + const height: f64 = @floatFromInt(self.as(gtk.Widget).getHeight()); + + const l_dist = x / width; + const t_dist = y / height; + const r_dist = 1 - l_dist; + const b_dist = 1 - t_dist; + const min = @min(l_dist, t_dist, r_dist, b_dist); + + if (min == l_dist) return .left; + if (min == r_dist) return .right; + if (min == t_dist) return .up; + return .down; + } + const C = Common(Self, Private); pub const as = C.as; pub const ref = C.ref; @@ -3636,6 +3891,9 @@ pub const Surface = extern struct { class.bindTemplateChildPrivate("key_state_overlay", .{}); class.bindTemplateChildPrivate("terminal_page", .{}); class.bindTemplateChildPrivate("drop_target", .{}); + class.bindTemplateChildPrivate("surface_drop_target", .{}); + class.bindTemplateChildPrivate("drag_handle", .{}); + class.bindTemplateChildPrivate("drop_overlay", .{}); class.bindTemplateChildPrivate("im_context", .{}); // Template Callbacks @@ -3678,6 +3936,13 @@ pub const Surface = extern struct { class.bindTemplateCallback("search_changed", &searchChanged); class.bindTemplateCallback("search_next_match", &searchNextMatch); class.bindTemplateCallback("search_previous_match", &searchPreviousMatch); + class.bindTemplateCallback("should_drag_handle_be_shown", &closureShouldDragHandleBeShown); + class.bindTemplateCallback("surface_drag_prepare", &surfaceDragPrepare); + class.bindTemplateCallback("surface_drag_begin", &surfaceDragBegin); + class.bindTemplateCallback("surface_drop", &surfaceDrop); + class.bindTemplateCallback("surface_drop_leave", &surfaceDropLeave); + class.bindTemplateCallback("surface_drop_motion", &surfaceDropMotion); + class.bindTemplateCallback("notify_drop_value", &propDropValue); // Properties gobject.ext.registerProperties(class, &.{ @@ -3723,6 +3988,7 @@ pub const Surface = extern struct { // Virtual methods gobject.Object.virtual_methods.dispose.implement(class, &dispose); gobject.Object.virtual_methods.finalize.implement(class, &finalize); + gtk.Widget.virtual_methods.snapshot.implement(class, &snapshot); } pub const as = C.Class.as; @@ -3865,22 +4131,25 @@ const Clipboard = struct { ); } - /// Request data from the clipboard (read the clipboard). This - /// completes asynchronously and will call the `completeClipboardRequest` - /// core surface API when done. - /// - /// Returns true if the request was started, false if the clipboard - /// doesn't contain text (allowing performable keybinds to pass through). + /// Request data from the clipboard (read the clipboard). A started + /// request completes asynchronously and will call the + /// `completeClipboardRequest` core surface API when done. pub fn request( self: *Surface, clipboard_type: apprt.Clipboard, state: apprt.ClipboardRequest, - ) Allocator.Error!bool { + ) Allocator.Error!apprt.ClipboardReadResult { + // The GTK apprt doesn't support the Kitty clipboard protocol + // yet. + if (state == .kitty_read or + state == .kitty_write or + state == .list) return .unsupported; + // Get our requested clipboard const clipboard = get( self.private().gl_area.as(gtk.Widget), clipboard_type, - ) orelse return false; + ) orelse return .unsupported; // For paste requests, check if clipboard has text format available. // This is a synchronous check that allows performable keybinds to @@ -3889,7 +4158,7 @@ const Clipboard = struct { const formats = clipboard.getFormats(); if (formats.containGtype(gobject.ext.types.string) == 0) { log.debug("clipboard has no text format, not starting paste request", .{}); - return false; + return .unavailable; } } @@ -3912,7 +4181,7 @@ const Clipboard = struct { ud, ); - return true; + return .started; } /// Paste explicit text directly into the surface, regardless of the @@ -3925,16 +4194,15 @@ const Clipboard = struct { const surface = self.private().core_surface orelse return; surface.completeClipboardRequest( - .paste, - text, - false, + .{ .paste = .standard }, + .{ .contents = &.{.{ .mime = "text/plain", .data = text }} }, ) catch |err| switch (err) { error.UnsafePaste, error.UnauthorizedPaste, => { showClipboardConfirmation( self, - .paste, + .{ .paste = .standard }, text, ); return; @@ -3978,7 +4246,7 @@ const Clipboard = struct { .request = &req, .@"can-remember" = switch (req) { .osc_52_read, .osc_52_write => true, - .paste => false, + .paste, .list, .kitty_read, .kitty_write => false, }, .@"clipboard-contents" = contents_buf, }, @@ -4015,7 +4283,7 @@ const Clipboard = struct { if (remember) switch (req.*) { .osc_52_read => surface.config.clipboard_read = .allow, .osc_52_write => surface.config.clipboard_write = .allow, - .paste => {}, + .paste, .list, .kitty_read, .kitty_write => {}, }; // Get our text @@ -4032,11 +4300,10 @@ const Clipboard = struct { ?[:0]const u8, ) orelse return; - surface.completeClipboardRequest( - req.*, - text, - true, - ) catch |err| { + surface.completeClipboardRequest(req.*, .{ + .contents = &.{.{ .mime = "text/plain", .data = text }}, + .confirmed = true, + }) catch |err| { log.warn("failed to complete clipboard request: {}", .{err}); }; } @@ -4054,7 +4321,7 @@ const Clipboard = struct { if (remember) switch (req.*) { .osc_52_read => surface.config.clipboard_read = .deny, .osc_52_write => surface.config.clipboard_write = .deny, - .paste => @panic("paste should not be able to be remembered"), + .paste, .list, .kitty_read, .kitty_write => @panic("request should not be able to be remembered"), }; } @@ -4092,8 +4359,7 @@ const Clipboard = struct { const surface = self.private().core_surface orelse return; surface.completeClipboardRequest( req.state, - str, - false, + .{ .contents = &.{.{ .mime = "text/plain", .data = str }} }, ) catch |err| switch (err) { error.UnsafePaste, error.UnauthorizedPaste, @@ -4144,3 +4410,57 @@ test "computeFraction" { try std.testing.expectEqual(0.0, computeFraction(0)); try std.testing.expectEqual(0.5, computeFraction(50)); } + +/// Apply command and shell integration overrides received from the CLI. +/// Explicit commands should only receive shell integration when their +/// executable can be detected as a supported shell. An explicit shell +/// integration override is also valid without a command. +fn applyCommandOverrides( + config: *configpkg.Config, + command: ?configpkg.Command, + shell_integration: ?configpkg.Config.ShellIntegration, +) Allocator.Error!void { + if (command) |value| { + config.command = try value.clone(config.arenaAlloc()); + + if (shell_integration) |integration| { + config.@"shell-integration" = integration; + } else if (config.@"shell-integration" != .none) { + config.@"shell-integration" = .detect; + } + } else if (shell_integration) |value| { + config.@"shell-integration" = value; + } +} + +test "command and shell integration overrides" { + const testing = std.testing; + + var config = try configpkg.Config.default(testing.allocator); + defer config.deinit(); + + config.@"shell-integration" = .nushell; + try applyCommandOverrides(&config, .{ .shell = "vim" }, null); + try testing.expectEqual(.detect, config.@"shell-integration"); + + config.@"shell-integration" = .none; + try applyCommandOverrides(&config, .{ .shell = "vim" }, null); + try testing.expectEqual(.none, config.@"shell-integration"); + + try applyCommandOverrides(&config, .{ .shell = "nu" }, .nushell); + try testing.expectEqual(.nushell, config.@"shell-integration"); + + try applyCommandOverrides(&config, .{ .shell = "vim" }, .none); + try testing.expectEqual(.none, config.@"shell-integration"); + + config.@"shell-integration" = .nushell; + try applyCommandOverrides(&config, null, null); + try testing.expectEqual(.nushell, config.@"shell-integration"); + + config.@"shell-integration" = .none; + try applyCommandOverrides(&config, null, .nushell); + try testing.expectEqual(.nushell, config.@"shell-integration"); + + try applyCommandOverrides(&config, null, .none); + try testing.expectEqual(.none, config.@"shell-integration"); +} diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/surface_child_exited.zig b/vendor/libghostty-vt/src/apprt/gtk/class/surface_child_exited.zig index d7dd41bc..3c103d59 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/surface_child_exited.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/surface_child_exited.zig @@ -106,11 +106,11 @@ const SurfaceChildExitedBanner = extern struct { return; }; if (data.exit_code == 0) { - banner.as(adw.Banner).setTitle(i18n._("Command succeeded")); + banner.as(adw.Banner).setTitle(i18n._("Command Succeeded")); self.as(gtk.Widget).addCssClass("normal"); self.as(gtk.Widget).removeCssClass("abnormal"); } else { - banner.as(adw.Banner).setTitle(i18n._("Command failed")); + banner.as(adw.Banner).setTitle(i18n._("Command Failed")); self.as(gtk.Widget).removeCssClass("normal"); self.as(gtk.Widget).addCssClass("abnormal"); } diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/surface_scrolled_window.zig b/vendor/libghostty-vt/src/apprt/gtk/class/surface_scrolled_window.zig index 6ccb0a0d..ad9a4cc7 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/surface_scrolled_window.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/surface_scrolled_window.zig @@ -89,7 +89,8 @@ pub const SurfaceScrolledWindow = extern struct { const priv = self.private(); if (priv.config_binding) |binding| { - binding.as(gobject.Object).unref(); + binding.unbind(); + binding.unref(); priv.config_binding = null; } @@ -168,18 +169,23 @@ pub const SurfaceScrolledWindow = extern struct { // Unbind old config binding if it exists if (priv.config_binding) |binding| { - binding.as(gobject.Object).unref(); + binding.unbind(); + binding.unref(); priv.config_binding = null; } // Bind config from surface to our config property if (priv.surface) |surface| { - priv.config_binding = surface.as(gobject.Object).bindProperty( + const binding = surface.as(gobject.Object).bindProperty( properties.config.name, self.as(gobject.Object), properties.config.name, .{ .sync_create = true }, ); + // Keep another ref, otherwise the binding would be freed and + // our pointer become stale if the surface gets finalized. + binding.ref(); + priv.config_binding = binding; } } diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/tab.zig b/vendor/libghostty-vt/src/apprt/gtk/class/tab.zig index 0c60c8cc..204be58f 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/tab.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/tab.zig @@ -162,7 +162,7 @@ pub const Tab = extern struct { /// The title of this tab. This is usually bound to the active surface. title: ?[:0]const u8 = null, - /// The manually overridden title from `promptTabTitle`. + /// The manually overridden title. title_override: ?[:0]const u8 = null, /// The tooltip of this tab. This is usually bound to the active surface. @@ -189,6 +189,7 @@ pub const Tab = extern struct { pub fn new(config: ?*Config, overrides: struct { command: ?configpkg.Command = null, + shell_integration: ?configpkg.Config.ShellIntegration = null, working_directory: ?[:0]const u8 = null, title: ?[:0]const u8 = null, @@ -212,6 +213,7 @@ pub const Tab = extern struct { // Create our initial surface in the split tree. priv.split_tree.newSplit(.right, null, .{ .command = overrides.command, + .shell_integration = overrides.shell_integration, .working_directory = overrides.working_directory, .title = overrides.title, }) catch |err| switch (err) { diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/title_dialog.zig b/vendor/libghostty-vt/src/apprt/gtk/class/title_dialog.zig index ac95ae4b..057e9dee 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/title_dialog.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/title_dialog.zig @@ -220,10 +220,13 @@ pub const TitleDialog = extern struct { pub const Target = enum(c_int) { surface, tab, + window, + pub fn title(self: Target) [*:0]const u8 { return switch (self) { .surface => i18n._("Change Terminal Title"), .tab => i18n._("Change Tab Title"), + .window => i18n._("Change Window Title"), }; } diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/window.zig b/vendor/libghostty-vt/src/apprt/gtk/class/window.zig index c34f2cb4..e2fe6403 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/class/window.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/class/window.zig @@ -29,6 +29,7 @@ const Tab = @import("tab.zig").Tab; const DebugWarning = @import("debug_warning.zig").DebugWarning; const CommandPalette = @import("command_palette.zig").CommandPalette; const WeakRef = @import("../weak_ref.zig").WeakRef; +const TitleDialog = @import("title_dialog.zig").TitleDialog; const log = std.log.scoped(.gtk_ghostty_window); @@ -213,6 +214,19 @@ pub const Window = extern struct { }, ); }; + + pub const @"title-override" = struct { + pub const name = "title-override"; + const impl = gobject.ext.defineProperty( + name, + Self, + ?[:0]const u8, + .{ + .default = null, + .accessor = C.privateStringFieldAccessor("title_override"), + }, + ); + }; }; const Private = struct { @@ -259,6 +273,9 @@ pub const Window = extern struct { /// setup by `setup-menu`. context_menu_page: ?*adw.TabPage = null, + /// The manually overridden title. + title_override: ?[:0]const u8 = null, + // Template bindings tab_overview: *adw.TabOverview, tab_bar: *adw.TabBar, @@ -365,6 +382,7 @@ pub const Window = extern struct { .init("prompt-surface-title", actionPromptSurfaceTitle, null), .init("prompt-tab-title", actionPromptTabTitle, null), .init("prompt-context-tab-title", actionPromptContextTabTitle, null), + .init("prompt-window-title", actionPromptWindowTitle, null), .init("ring-bell", actionRingBell, null), .init("split-right", actionSplitRight, null), .init("split-left", actionSplitLeft, null), @@ -390,8 +408,20 @@ pub const Window = extern struct { /// Create a new tab with the given parent. The tab will be inserted /// at the position dictated by the `window-new-tab-position` config. /// The new tab will be selected. - pub fn newTab(self: *Self, parent_: ?*CoreSurface) void { - _ = self.newTabPage(parent_, .tab, .none); + pub fn newTab(self: *Self, parent_: ?*CoreSurface, overrides: struct { + command: ?configpkg.Command = null, + shell_integration: ?configpkg.Config.ShellIntegration = null, + working_directory: ?[:0]const u8 = null, + title: ?[:0]const u8 = null, + + pub const none: @This() = .{}; + }) void { + _ = self.newTabPage(parent_, .tab, .{ + .command = overrides.command, + .shell_integration = overrides.shell_integration, + .working_directory = overrides.working_directory, + .title = overrides.title, + }); } pub fn newTabForWindow( @@ -399,6 +429,7 @@ pub const Window = extern struct { parent_: ?*CoreSurface, overrides: struct { command: ?configpkg.Command = null, + shell_integration: ?configpkg.Config.ShellIntegration = null, working_directory: ?[:0]const u8 = null, title: ?[:0]const u8 = null, @@ -410,6 +441,7 @@ pub const Window = extern struct { .window, .{ .command = overrides.command, + .shell_integration = overrides.shell_integration, .working_directory = overrides.working_directory, .title = overrides.title, }, @@ -422,6 +454,7 @@ pub const Window = extern struct { context: apprt.surface.NewSurfaceContext, overrides: struct { command: ?configpkg.Command = null, + shell_integration: ?configpkg.Config.ShellIntegration = null, working_directory: ?[:0]const u8 = null, title: ?[:0]const u8 = null, @@ -436,6 +469,7 @@ pub const Window = extern struct { priv.config, .{ .command = overrides.command, + .shell_integration = overrides.shell_integration, .working_directory = overrides.working_directory, .title = overrides.title, }, @@ -604,6 +638,29 @@ pub const Window = extern struct { return tab_view.reorderPage(page, desired_pos) != 0; } + pub fn moveTabToNewWindow(self: *Self, surface: *Surface) bool { + const tab_view = self.private().tab_view; + const tab = ext.getAncestor( + Tab, + surface.as(gtk.Widget), + ) orelse return false; + const page = tab_view.getPage(tab.as(gtk.Widget)); + + // Skip if this is the only tab in the existing window + if (tab_view.getNPages() <= 1) return false; + + const app = Application.default(); + const window = Window.new(app, .none); + + tab_view.transferPage( + page, + window.private().tab_view, + 0, + ); + window.as(gtk.Window).present(); + return true; + } + pub fn toggleTabOverview(self: *Self) void { const priv = self.private(); const tab_overview = priv.tab_overview; @@ -1268,6 +1325,57 @@ pub const Window = extern struct { }); } + pub fn setTitleOverride(self: *Self, title: ?[]const u8) void { + const priv: *Private = self.private(); + + if (priv.title_override) |v| glib.free(@ptrCast(@constCast(v))); + priv.title_override = null; + + if (title) |v| priv.title_override = glib.ext.dupeZ(u8, v); + + self.as(gobject.Object).notifyByPspec(properties.@"title-override".impl.param_spec); + } + + fn titleDialogSet(_: *TitleDialog, title_: [*:0]const u8, self: *Self) callconv(.c) void { + const title = std.mem.span(title_); + self.setTitleOverride(if (title.len == 0) null else title); + } + + pub fn promptWindowTitle(self: *Self) void { + const priv: *Private = self.private(); + + var value = std.mem.zeroes(gobject.Value); + _ = value.init(gobject.ext.types.string); + defer value.unset(); + + self.as(gobject.Object).getProperty("title", &value); + + const title_: ?[*:0]const u8 = value.getString(); + const title: ?[:0]const u8 = if (title_) |v| std.mem.span(v) else null; + + const dialog = TitleDialog.new(.window, priv.title_override orelse title); + _ = TitleDialog.signals.set.connect( + dialog, + *Self, + titleDialogSet, + self, + .{}, + ); + + dialog.present(self.as(gtk.Widget)); + } + + fn closureTitle( + _: *Self, + _: ?*Config, + title_: ?[*:0]const u8, + title_override_: ?[*:0]const u8, + ) callconv(.c) ?[*:0]const u8 { + if (title_override_) |v| return glib.ext.dupeZ(u8, std.mem.span(v)); + if (title_) |v| return glib.ext.dupeZ(u8, std.mem.span(v)); + return glib.ext.dupeZ(u8, "Ghostty"); + } + fn closureSubtitle( _: *Self, config_: ?*Config, @@ -1296,7 +1404,7 @@ pub const Window = extern struct { priv.handle_active_state_source = null; } - priv.command_palette.set(null); + priv.command_palette.deinit(); if (priv.config) |v| { v.unref(); @@ -1320,6 +1428,7 @@ pub const Window = extern struct { const priv = self.private(); priv.tab_bindings.unref(); priv.winproto.deinit(); + if (priv.title_override) |v| glib.free(@ptrCast(@constCast(v))); gobject.Object.virtual_methods.finalize.call( Class.parent, @@ -1374,11 +1483,33 @@ pub const Window = extern struct { } } + // Notify every displayed surface when the compositor changes the + // Wayland xdg_toplevel suspended state. + _ = gobject.Object.signals.notify.connect( + self.as(gtk.Window), + *Self, + propSuspended, + self, + .{ .detail = "suspended" }, + ); + // When we are realized we always setup our appearance since this // calls some winproto functions. self.syncAppearance(); } + fn propSuspended( + _: *gtk.Window, + _: *gobject.ParamSpec, + self: *Self, + ) callconv(.c) void { + const tab = self.getSelectedTab() orelse return; + const tree = tab.getSurfaceTree() orelse return; + + var it = tree.iterator(); + while (it.next()) |entry| entry.view.updateOcclusion(); + } + fn btnNewTab(_: *adw.SplitButton, self: *Self) callconv(.c) void { self.performBindingAction(.new_tab); } @@ -1954,6 +2085,14 @@ pub const Window = extern struct { self.performBindingAction(.prompt_tab_title); } + fn actionPromptWindowTitle( + _: *gio.SimpleAction, + _: ?*glib.Variant, + self: *Window, + ) callconv(.c) void { + self.performBindingAction(.prompt_window_title); + } + fn actionSplitRight( _: *gio.SimpleAction, _: ?*glib.Variant, @@ -2161,6 +2300,7 @@ pub const Window = extern struct { properties.@"tabs-wide".impl, properties.@"toolbar-style".impl, properties.@"titlebar-style".impl, + properties.@"title-override".impl, }); // Bindings @@ -2191,6 +2331,7 @@ pub const Window = extern struct { class.bindTemplateCallback("notify_quick_terminal", &propQuickTerminal); class.bindTemplateCallback("notify_scale_factor", &propScaleFactor); class.bindTemplateCallback("titlebar_style_is_tabs", &closureTitlebarStyleIsTab); + class.bindTemplateCallback("computed_title", &closureTitle); class.bindTemplateCallback("computed_subtitle", &closureSubtitle); // Virtual methods diff --git a/vendor/libghostty-vt/src/apprt/gtk/css/style.css b/vendor/libghostty-vt/src/apprt/gtk/css/style.css index 9c0f115f..045d9906 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/css/style.css +++ b/vendor/libghostty-vt/src/apprt/gtk/css/style.css @@ -127,7 +127,7 @@ label.resize-overlay { } .surface .bell-overlay { - border-color: rgba(58, 148, 74, 0.5); + border-color: rgba(53, 132, 228, 0.5); /* after GTK 4.16 is a requirement, switch to the following: */ /* background-color: color-mix(in srgb, var(--accent-color), transparent 50%); */ border-width: 3px; @@ -144,6 +144,58 @@ label.resize-overlay { outline-style: solid; outline-width: 1px; } +/* + * Drag and drop overlay + */ +.drag-handle { + background-color: rgba(0, 0, 0, 0.15); + opacity: 0; + transition: 0.1s opacity; +} +.drag-handle:hover { + opacity: 1; +} +.drop-overlay.drop-left { + /* after GTK 4.16 is a requirement, switch to the following: */ + /* background: linear-gradient(to left, transparent, 50%, color-mix(in srgb, var(--accent-color), transparent 50%) 50%); */ + background: linear-gradient( + to left, + transparent, + 50%, + rgba(53, 132, 228, 0.2) 50% + ); +} +.drop-overlay.drop-right { + /* after GTK 4.16 is a requirement, switch to the following: */ + /* background: linear-gradient(to right, transparent, 50%, color-mix(in srgb, var(--accent-color), transparent 50%) 50%); */ + background: linear-gradient( + to right, + transparent, + 50%, + rgba(53, 132, 228, 0.2) 50% + ); +} +.drop-overlay.drop-top { + /* after GTK 4.16 is a requirement, switch to the following: */ + /* background: linear-gradient(to top, transparent, 50%, color-mix(in srgb, var(--accent-color), transparent 50%) 50%); */ + background: linear-gradient( + to top, + transparent, + 50%, + rgba(53, 132, 228, 0.2) 50% + ); +} +.drop-overlay.drop-bottom { + /* after GTK 4.16 is a requirement, switch to the following: */ + /* background: linear-gradient(to bottom, transparent, 50%, color-mix(in srgb, var(--accent-color), transparent 50%) 50%); */ + background: linear-gradient( + to bottom, + transparent, + 50%, + rgba(53, 132, 228, 0.2) 50% + ); +} + /* * Command Palette */ diff --git a/vendor/libghostty-vt/src/apprt/gtk/ext/actions.zig b/vendor/libghostty-vt/src/apprt/gtk/ext/actions.zig index 3232bc18..6ba9c678 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/ext/actions.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/ext/actions.zig @@ -176,7 +176,11 @@ test "adding actions to an object" { _ = addAsGroup(gtk.Box, box, "test", &actions); } - const expected = std.crypto.random.intRangeAtMost(i32, 1, std.math.maxInt(u31)); + const expected = expected: { + const rng_impl: std.Random.IoSource = .{ .io = testing.io }; + const rng = rng_impl.interface(); + break :expected rng.intRangeAtMost(i32, 1, std.math.maxInt(u31)); + }; const parameter = glib.Variant.newInt32(expected); try testing.expect(box.as(gtk.Widget).activateActionVariant("test.test", parameter) != 0); diff --git a/vendor/libghostty-vt/src/apprt/gtk/gtk_version.zig b/vendor/libghostty-vt/src/apprt/gtk/gtk_version.zig index 71edb076..97e0a523 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/gtk_version.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/gtk_version.zig @@ -3,18 +3,16 @@ const std = @import("std"); // Until the gobject bindings are built at the same time we are building // Ghostty, we need to import `gtk/gtk.h` directly to ensure that the version // macros match the version of `gtk4` that we are building/linking against. -const c = @cImport({ - @cInclude("gtk/gtk.h"); -}); +const gtk_c = @import("gtk_c"); const gtk = @import("gtk"); const log = std.log.scoped(.gtk); pub const comptime_version: std.SemanticVersion = .{ - .major = c.GTK_MAJOR_VERSION, - .minor = c.GTK_MINOR_VERSION, - .patch = c.GTK_MICRO_VERSION, + .major = gtk_c.GTK_MAJOR_VERSION, + .minor = gtk_c.GTK_MINOR_VERSION, + .patch = gtk_c.GTK_MICRO_VERSION, }; pub fn getRuntimeVersion() std.SemanticVersion { @@ -105,17 +103,17 @@ test "atLeast" { const funs = &.{ atLeast, runtimeAtLeast }; inline for (funs) |fun| { - try testing.expect(fun(c.GTK_MAJOR_VERSION, c.GTK_MINOR_VERSION, c.GTK_MICRO_VERSION)); + try testing.expect(fun(gtk_c.GTK_MAJOR_VERSION, gtk_c.GTK_MINOR_VERSION, gtk_c.GTK_MICRO_VERSION)); - try testing.expect(!fun(c.GTK_MAJOR_VERSION, c.GTK_MINOR_VERSION, c.GTK_MICRO_VERSION + 1)); - try testing.expect(!fun(c.GTK_MAJOR_VERSION, c.GTK_MINOR_VERSION + 1, c.GTK_MICRO_VERSION)); - try testing.expect(!fun(c.GTK_MAJOR_VERSION + 1, c.GTK_MINOR_VERSION, c.GTK_MICRO_VERSION)); + try testing.expect(!fun(gtk_c.GTK_MAJOR_VERSION, gtk_c.GTK_MINOR_VERSION, gtk_c.GTK_MICRO_VERSION + 1)); + try testing.expect(!fun(gtk_c.GTK_MAJOR_VERSION, gtk_c.GTK_MINOR_VERSION + 1, gtk_c.GTK_MICRO_VERSION)); + try testing.expect(!fun(gtk_c.GTK_MAJOR_VERSION + 1, gtk_c.GTK_MINOR_VERSION, gtk_c.GTK_MICRO_VERSION)); - try testing.expect(fun(c.GTK_MAJOR_VERSION - 1, c.GTK_MINOR_VERSION, c.GTK_MICRO_VERSION)); - try testing.expect(fun(c.GTK_MAJOR_VERSION - 1, c.GTK_MINOR_VERSION + 1, c.GTK_MICRO_VERSION)); - try testing.expect(fun(c.GTK_MAJOR_VERSION - 1, c.GTK_MINOR_VERSION, c.GTK_MICRO_VERSION + 1)); + try testing.expect(fun(gtk_c.GTK_MAJOR_VERSION - 1, gtk_c.GTK_MINOR_VERSION, gtk_c.GTK_MICRO_VERSION)); + try testing.expect(fun(gtk_c.GTK_MAJOR_VERSION - 1, gtk_c.GTK_MINOR_VERSION + 1, gtk_c.GTK_MICRO_VERSION)); + try testing.expect(fun(gtk_c.GTK_MAJOR_VERSION - 1, gtk_c.GTK_MINOR_VERSION, gtk_c.GTK_MICRO_VERSION + 1)); - try testing.expect(fun(c.GTK_MAJOR_VERSION, c.GTK_MINOR_VERSION - 1, c.GTK_MICRO_VERSION + 1)); + try testing.expect(fun(gtk_c.GTK_MAJOR_VERSION, gtk_c.GTK_MINOR_VERSION - 1, gtk_c.GTK_MICRO_VERSION + 1)); } } @@ -125,16 +123,16 @@ test "runtimeUntil" { // This is an array in case we add a comptime variant. const funs = &.{runtimeUntil}; inline for (funs) |fun| { - try testing.expect(!fun(c.GTK_MAJOR_VERSION, c.GTK_MINOR_VERSION, c.GTK_MICRO_VERSION)); + try testing.expect(!fun(gtk_c.GTK_MAJOR_VERSION, gtk_c.GTK_MINOR_VERSION, gtk_c.GTK_MICRO_VERSION)); - try testing.expect(fun(c.GTK_MAJOR_VERSION, c.GTK_MINOR_VERSION, c.GTK_MICRO_VERSION + 1)); - try testing.expect(fun(c.GTK_MAJOR_VERSION, c.GTK_MINOR_VERSION + 1, c.GTK_MICRO_VERSION)); - try testing.expect(fun(c.GTK_MAJOR_VERSION + 1, c.GTK_MINOR_VERSION, c.GTK_MICRO_VERSION)); + try testing.expect(fun(gtk_c.GTK_MAJOR_VERSION, gtk_c.GTK_MINOR_VERSION, gtk_c.GTK_MICRO_VERSION + 1)); + try testing.expect(fun(gtk_c.GTK_MAJOR_VERSION, gtk_c.GTK_MINOR_VERSION + 1, gtk_c.GTK_MICRO_VERSION)); + try testing.expect(fun(gtk_c.GTK_MAJOR_VERSION + 1, gtk_c.GTK_MINOR_VERSION, gtk_c.GTK_MICRO_VERSION)); - try testing.expect(!fun(c.GTK_MAJOR_VERSION - 1, c.GTK_MINOR_VERSION, c.GTK_MICRO_VERSION)); - try testing.expect(!fun(c.GTK_MAJOR_VERSION - 1, c.GTK_MINOR_VERSION + 1, c.GTK_MICRO_VERSION)); - try testing.expect(!fun(c.GTK_MAJOR_VERSION - 1, c.GTK_MINOR_VERSION, c.GTK_MICRO_VERSION + 1)); + try testing.expect(!fun(gtk_c.GTK_MAJOR_VERSION - 1, gtk_c.GTK_MINOR_VERSION, gtk_c.GTK_MICRO_VERSION)); + try testing.expect(!fun(gtk_c.GTK_MAJOR_VERSION - 1, gtk_c.GTK_MINOR_VERSION + 1, gtk_c.GTK_MICRO_VERSION)); + try testing.expect(!fun(gtk_c.GTK_MAJOR_VERSION - 1, gtk_c.GTK_MINOR_VERSION, gtk_c.GTK_MICRO_VERSION + 1)); - try testing.expect(!fun(c.GTK_MAJOR_VERSION, c.GTK_MINOR_VERSION - 1, c.GTK_MICRO_VERSION + 1)); + try testing.expect(!fun(gtk_c.GTK_MAJOR_VERSION, gtk_c.GTK_MINOR_VERSION - 1, gtk_c.GTK_MICRO_VERSION + 1)); } } diff --git a/vendor/libghostty-vt/src/apprt/gtk/ipc/DBus.zig b/vendor/libghostty-vt/src/apprt/gtk/ipc/DBus.zig index fa4a6723..66904783 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/ipc/DBus.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/ipc/DBus.zig @@ -6,6 +6,7 @@ const Allocator = std.mem.Allocator; const gio = @import("gio"); const glib = @import("glib"); +const global = @import("../../../global.zig"); const apprt = @import("../../../apprt.zig"); const ApprtApp = @import("../App.zig"); @@ -28,10 +29,12 @@ payload_builder: *glib.VariantBuilder, /// Used to build the parameters for the IPC. parameters_builder: *glib.VariantBuilder, +pub const InitError = Allocator.Error || std.Io.Writer.Error || apprt.ipc.Errors; + /// Initialize the helper. -pub fn init(alloc: Allocator, target: apprt.ipc.Target, action: [:0]const u8) (Allocator.Error || std.Io.Writer.Error || apprt.ipc.Errors)!Self { +pub fn init(alloc: Allocator, target: apprt.ipc.Target, action: [:0]const u8) InitError!Self { var buf: [256]u8 = undefined; - var stderr_writer = std.fs.File.stderr().writer(&buf); + var stderr_writer = std.Io.File.stderr().writer(global.io(), &buf); const stderr = &stderr_writer.interface; // Get the appropriate bus name and object path for contacting the @@ -133,7 +136,7 @@ pub fn addParameter(self: *Self, variant: *glib.Variant) void { /// should be done with this object other than call `deinit`. pub fn send(self: *Self) (std.Io.Writer.Error || apprt.ipc.Errors)!void { var buf: [256]u8 = undefined; - var stderr_writer = std.fs.File.stderr().writer(&buf); + var stderr_writer = std.Io.File.stderr().writer(global.io(), &buf); const stderr = &stderr_writer.interface; // finish building the parameters diff --git a/vendor/libghostty-vt/src/apprt/gtk/ipc/new_tab.zig b/vendor/libghostty-vt/src/apprt/gtk/ipc/new_tab.zig new file mode 100644 index 00000000..c5e53895 --- /dev/null +++ b/vendor/libghostty-vt/src/apprt/gtk/ipc/new_tab.zig @@ -0,0 +1,71 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; + +const glib = @import("glib"); + +const apprt = @import("../../../apprt.zig"); +const DBus = @import("DBus.zig"); + +// Use a D-Bus method call to open a new tab on GTK. +// See: https://wiki.gnome.org/Projects/GLib/GApplication/DBusAPI +// +// `ghostty +new-tab` is equivalent to the following command (on a release build): +// +// ``` +// gdbus call --session --dest com.mitchellh.ghostty --object-path /com/mitchellh/ghostty --method org.gtk.Actions.Activate new-tab '[<@(tas) (0, [])>]' [] +// ``` +// +// `ghostty +new-tab -e echo hello` would be equivalent to the following command (on a release build): +// +// ``` +// gdbus call --session --dest com.mitchellh.ghostty --object-path /com/mitchellh/ghostty --method org.gtk.Actions.Activate new-tab '[<@(tas) (0, ["-e" "echo" "hello"])>]' [] +// ``` +pub fn newTab(alloc: Allocator, target: apprt.ipc.Target, value: apprt.ipc.Action.NewTab) (Allocator.Error || std.Io.Writer.Error || apprt.ipc.Errors)!bool { + var dbus = try DBus.init(alloc, target, "new-tab"); + defer dbus.deinit(alloc); + + const tas_variant_type = glib.VariantType.new("(tas)"); + defer tas_variant_type.free(); + + var parameter: glib.VariantBuilder = undefined; + parameter.init(tas_variant_type); + errdefer parameter.clear(); + + { + // Add the target surface ID to the parameter. + const t = glib.Variant.newUint64(value.surface_id); + parameter.addValue(t); + } + + { + // If any arguments were specified on the command line, this value is an + // array of strings that contain the arguments. They will be sent to the + // main Ghostty instance and interpreted as CLI arguments. + const as_variant_type = glib.VariantType.new("as"); + defer as_variant_type.free(); + + const s_variant_type = glib.VariantType.new("s"); + defer s_variant_type.free(); + + var command: glib.VariantBuilder = undefined; + command.init(as_variant_type); + errdefer command.clear(); + + if (value.arguments) |arguments| { + for (arguments) |argument| { + const bytes = glib.Bytes.new(argument.ptr, argument.len + 1); + defer bytes.unref(); + const string = glib.Variant.newFromBytes(s_variant_type, bytes, @intFromBool(true)); + command.addValue(string); + } + } + + parameter.addValue(command.end()); + } + + dbus.addParameter(parameter.end()); + + try dbus.send(); + + return true; +} diff --git a/vendor/libghostty-vt/src/apprt/gtk/key.zig b/vendor/libghostty-vt/src/apprt/gtk/key.zig index 5f717e14..ff2064d4 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/key.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/key.zig @@ -57,6 +57,16 @@ pub fn xdgShortcutFromTrigger( return slice[0 .. slice.len - 1 :0]; } +/// Returns the keysym (identical to a GDK keyval) for a trigger key, +/// or null if the trigger has no keysym representation. +pub fn keysymFromTrigger(trigger: input.Binding.Trigger) ?c_uint { + return switch (trigger.key) { + .physical => |k| keyvalFromKey(k), + .unicode => |cp| gdk.unicodeToKeyval(cp), + .catch_all => null, + }; +} + fn writeTriggerKey( writer: *std.Io.Writer, trigger: input.Binding.Trigger, @@ -217,6 +227,94 @@ pub fn keyFromKeyval(keyval: c_uint) ?input.Key { return null; } +/// Returns the logical key after applying any eligible XKB remapping. +/// +/// Modifier keyvals that Ghostty doesn't represent must not fall back to the +/// physical key. XKB can turn any physical key into a modifier, and using the +/// original key in that case would encode an unrelated key press. +pub fn remapKey( + physical_key: input.Key, + keyval: c_uint, + is_modifier: bool, +) input.Key { + if (keyFromKeyval(keyval)) |remapped| { + if (physical_key.shouldBeRemappable() or remapped.shouldBeRemappable()) + return remapped; + } + + if (is_modifier or isModifierKeyval(keyval)) return .unidentified; + return physical_key; +} + +/// Returns whether a keyval has modifier semantics that GDK may not expose +/// through `gdk_key_event_is_modifier`. +/// +/// In particular, XKB can report ISO level and group modifiers as keyvals +/// such as `Mode_switch` while GDK reports that the event is not a modifier. +fn isModifierKeyval(keyval: c_uint) bool { + return switch (keyval) { + gdk.KEY_Shift_L, + gdk.KEY_Shift_R, + gdk.KEY_Shift_Lock, + gdk.KEY_Control_L, + gdk.KEY_Control_R, + gdk.KEY_Caps_Lock, + gdk.KEY_Meta_L, + gdk.KEY_Meta_R, + gdk.KEY_Alt_L, + gdk.KEY_Alt_R, + gdk.KEY_Super_L, + gdk.KEY_Super_R, + gdk.KEY_Hyper_L, + gdk.KEY_Hyper_R, + gdk.KEY_Num_Lock, + gdk.KEY_Mode_switch, + gdk.KEY_ISO_Lock, + gdk.KEY_ISO_Level2_Latch, + gdk.KEY_ISO_Level3_Shift, + gdk.KEY_ISO_Level3_Latch, + gdk.KEY_ISO_Level3_Lock, + gdk.KEY_ISO_Level5_Shift, + gdk.KEY_ISO_Level5_Latch, + gdk.KEY_ISO_Level5_Lock, + gdk.KEY_ISO_Group_Latch, + gdk.KEY_ISO_Group_Lock, + => true, + + else => false, + }; +} + +test "remap key" { + const testing = std.testing; + + // XKB remaps between non-writing-system keys are honored. + try testing.expectEqual( + input.Key.escape, + remapKey(.caps_lock, gdk.KEY_Escape, false), + ); + + // Writing-system keys retain their physical identity. + try testing.expectEqual( + input.Key.key_a, + remapKey(.key_a, gdk.KEY_b, false), + ); + + // GDK doesn't identify Mode_switch as a modifier, but it must not fall + // back to the physical key. + try testing.expectEqual( + input.Key.unidentified, + remapKey(.delete, gdk.KEY_Mode_switch, false), + ); + + // GDK's modifier flag also covers custom modifier actions whose keyval + // Ghostty doesn't represent. + try testing.expectEqual( + input.Key.unidentified, + remapKey(.delete, gdk.KEY_VoidSymbol, true), + ); +} + /// Returns a keyval from an input key or null if we don't have a mapping. pub fn keyvalFromKey(key: input.Key) ?c_uint { switch (key) { @@ -327,6 +425,28 @@ test "xdgShortcutFromTrigger" { })).?); } +test "keysymFromTrigger" { + const testing = std.testing; + + // Unicode keys use the keysym numbering (latin-1 maps directly). + try testing.expectEqual(@as(?c_uint, 'q'), keysymFromTrigger(.{ + .mods = .{ .super = true }, + .key = .{ .unicode = 'q' }, + })); + + // Physical keys map through our keymap. + try testing.expectEqual(@as(?c_uint, gdk.KEY_a), keysymFromTrigger(.{ + .mods = .{}, + .key = .{ .physical = .key_a }, + })); + + // catch_all has no keysym representation. + try testing.expectEqual(@as(?c_uint, null), keysymFromTrigger(.{ + .mods = .{}, + .key = .catch_all, + })); +} + test "labelFromTrigger" { const testing = std.testing; diff --git a/vendor/libghostty-vt/src/apprt/gtk/media.zig b/vendor/libghostty-vt/src/apprt/gtk/media.zig index 7883bf37..3e6a19c3 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/media.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/media.zig @@ -7,10 +7,15 @@ const gio = @import("gio"); const glib = @import("glib"); const gobject = @import("gobject"); const gtk = @import("gtk"); +const global = @import("../../global.zig"); pub fn fromFilename(path: [:0]const u8) ?*gtk.MediaFile { assert(std.fs.path.isAbsolute(path)); - std.fs.accessAbsolute(path, .{ .mode = .read_only }) catch |err| { + std.Io.Dir.accessAbsolute( + global.io(), + path, + .{ .read = true }, + ) catch |err| { log.warn("unable to access {s}: {t}", .{ path, err }); return null; }; diff --git a/vendor/libghostty-vt/src/apprt/gtk/portal.zig b/vendor/libghostty-vt/src/apprt/gtk/portal.zig index 3e51042d..11c3356d 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/portal.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/portal.zig @@ -1,6 +1,7 @@ const std = @import("std"); const gio = @import("gio"); +const global = @import("../../global.zig"); const Allocator = std.mem.Allocator; @@ -11,7 +12,8 @@ const token_format = std.fmt.comptimePrint("{{x:0>{}}}", .{token_hex_len}); /// Generate a token suitable for use in requests to the XDG Desktop Portal pub fn generateToken() usize { - return std.crypto.random.int(usize); + const rng_impl: std.Random.IoSource = .{ .io = global.io() }; + return rng_impl.interface().int(usize); } /// Format a request token consistently for use in portal object paths and payloads. diff --git a/vendor/libghostty-vt/src/apprt/gtk/portal/OpenURI.zig b/vendor/libghostty-vt/src/apprt/gtk/portal/OpenURI.zig index 97aa013e..40191482 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/portal/OpenURI.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/portal/OpenURI.zig @@ -9,6 +9,7 @@ const assert = std.debug.assert; const gio = @import("gio"); const glib = @import("glib"); const gobject = @import("gobject"); +const global = @import("../../../global.zig"); const App = @import("../App.zig"); const portal = @import("../portal.zig"); @@ -23,7 +24,7 @@ app: *App, dbus: ?*gio.DBusConnection = null, /// Mutex to protect modification of the entries map or the cleanup timer. -mutex: std.Thread.Mutex = .{}, +mutex: std.Io.Mutex = .init, /// Map to store data about any in-flight calls to the portal. entries: std.AutoArrayHashMapUnmanaged(usize, *Entry) = .empty, @@ -78,7 +79,7 @@ const RequestData = struct { /// Data about any in-flight calls to the portal. pub const Entry = struct { /// When the request started. - start: std.time.Instant, + start: std.Io.Timestamp, /// A token used by the portal to identify requests and responses. The /// actual format of the token does not really matter as long as it can be /// used as part of a D-Bus object path. `usize` was chosen since it's easy @@ -123,8 +124,8 @@ pub fn setDbusConnection(self: *OpenURI, dbus: ?*gio.DBusConnection) void { pub fn deinit(self: *OpenURI) void { const alloc = self.app.app.allocator(); - self.mutex.lock(); - defer self.mutex.unlock(); + self.mutex.lockUncancelable(global.io()); + defer self.mutex.unlock(global.io()); if (!self.alive) return; self.alive = false; @@ -157,8 +158,8 @@ pub fn start(self: *OpenURI, value: apprt.action.OpenUrl) (Allocator.Error || Er alloc.destroy(request); } - self.mutex.lock(); - defer self.mutex.unlock(); + self.mutex.lockUncancelable(global.io()); + defer self.mutex.unlock(global.io()); // Create an entry that is used to track the results of the D-Bus method // call. @@ -166,7 +167,7 @@ pub fn start(self: *OpenURI, value: apprt.action.OpenUrl) (Allocator.Error || Er const entry = try alloc.create(Entry); errdefer alloc.destroy(entry); entry.* = .{ - .start = std.time.Instant.now() catch return error.TimerUnavailable, + .start = std.Io.Timestamp.now(global.io(), .awake), .token = token, .kind = value.kind, .uri = try alloc.dupeZ(u8, value.url), @@ -235,8 +236,8 @@ fn destroyEntry(alloc: Allocator, entry: *Entry) void { } fn failRequest(self: *OpenURI, token: usize) ?*Entry { - self.mutex.lock(); - defer self.mutex.unlock(); + self.mutex.lockUncancelable(global.io()); + defer self.mutex.unlock(global.io()); if (!self.alive) return null; @@ -422,8 +423,8 @@ fn requestCallback( return; } - self.mutex.lock(); - defer self.mutex.unlock(); + self.mutex.lockUncancelable(global.io()); + defer self.mutex.unlock(global.io()); if (!self.alive) return; @@ -461,8 +462,8 @@ fn responseReceived( return; }; - self.mutex.lock(); - defer self.mutex.unlock(); + self.mutex.lockUncancelable(global.io()); + defer self.mutex.unlock(global.io()); if (!self.alive) return; @@ -534,22 +535,18 @@ fn cleanup(ud: ?*anyopaque) callconv(.c) c_int { const alloc = self.app.app.allocator(); - self.mutex.lock(); - defer self.mutex.unlock(); + self.mutex.lockUncancelable(global.io()); + defer self.mutex.unlock(global.io()); self.cleanup_timer = null; if (!self.alive) return @intFromBool(glib.SOURCE_REMOVE); - const now = std.time.Instant.now() catch { - // `now()` should never fail, but if it does, don't crash, just return. - // This might cause a small memory leak in rare circumstances but it - // should get cleaned up the next time a URL is clicked. - return @intFromBool(glib.SOURCE_REMOVE); - }; - loop: while (true) { for (self.entries.entries.items(.value)) |entry| { - if (now.since(entry.start) > cleanup_timeout * std.time.ns_per_s) { + if (entry.start.untilNow( + global.io(), + .awake, + ).toSeconds() > cleanup_timeout) { log.warn("open uri request timed out token={x}", .{entry.token}); self.unsubscribeFromResponse(entry); _ = self.entries.swapRemove(entry.token); diff --git a/vendor/libghostty-vt/src/apprt/gtk/post_fork.zig b/vendor/libghostty-vt/src/apprt/gtk/post_fork.zig index ff021950..d9b576fa 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/post_fork.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/post_fork.zig @@ -2,6 +2,7 @@ const std = @import("std"); const gio = @import("gio"); const glib = @import("glib"); +const global = @import("../../global.zig"); const log = std.log.scoped(.gtk_post_fork); @@ -85,12 +86,10 @@ pub fn postFork(cmd: *Command) Command.PostForkError!void { return; }; - const start = std.time.Instant.now() catch unreachable; + const start: std.Io.Timestamp = .now(global.io(), .awake); loop: while (true) { - const now = std.time.Instant.now() catch unreachable; - - if (now.since(start) > 250 * std.time.ns_per_ms) { + if (start.untilNow(global.io(), .awake).toMilliseconds() > 250) { if (cmd.rt_pre_exec_info.linux_cgroup_hard_fail) { log.err("transition to new transient systemd scope {s} took too long", .{expected_cgroup}); return error.PostForkError; @@ -116,6 +115,6 @@ pub fn postFork(cmd: *Command) Command.PostForkError!void { } } - std.Thread.sleep(25 * std.time.ns_per_ms); + std.Io.sleep(global.io(), .fromMilliseconds(25), .awake) catch unreachable; } } diff --git a/vendor/libghostty-vt/src/apprt/gtk/pre_exec.zig b/vendor/libghostty-vt/src/apprt/gtk/pre_exec.zig index 6f6a9ed5..a4eda462 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/pre_exec.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/pre_exec.zig @@ -3,6 +3,7 @@ const std = @import("std"); const log = std.log.scoped(.gtk_pre_exec); const configpkg = @import("../../config.zig"); +const global = @import("../../global.zig"); const internal_os = @import("../../os/main.zig"); const Command = @import("../../Command.zig"); @@ -47,12 +48,10 @@ pub fn preExec(cmd: *Command) ?u8 { var expected_cgroup_buf: [256]u8 = undefined; const expected_cgroup = cgroup.fmtScope(&expected_cgroup_buf, pid); - const start = std.time.Instant.now() catch unreachable; + const start: std.Io.Timestamp = .now(global.io(), .awake); while (true) { - const now = std.time.Instant.now() catch unreachable; - - if (now.since(start) > 250 * std.time.ns_per_ms) { + if (start.untilNow(global.io(), .awake).toMilliseconds() > 250) { if (cmd.rt_pre_exec_info.linux_cgroup_hard_fail) { log.err("transition to new transient systemd scope took too long", .{}); return 127; @@ -74,7 +73,7 @@ pub fn preExec(cmd: *Command) ?u8 { if (std.mem.eql(u8, current_cgroup, expected_cgroup)) return null; } - std.Thread.sleep(25 * std.time.ns_per_ms); + std.Io.sleep(global.io(), .fromMilliseconds(25), .awake) catch unreachable; } return null; diff --git a/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/config-errors-dialog.blp b/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/config-errors-dialog.blp index 845909eb..77c71ede 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/config-errors-dialog.blp +++ b/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/config-errors-dialog.blp @@ -4,7 +4,9 @@ using Adw 1; template $GhosttyConfigErrorsDialog: $GhosttyDialog { heading: _("Configuration Errors"); - body: _("One or more configuration errors were found. Please review the errors below, and either reload your configuration or ignore these errors."); + body: _( + "One or more configuration errors were found. Please review the errors below, and either reload your configuration or ignore these errors." + ); responses [ ignore: _("Ignore"), diff --git a/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/search-overlay.blp b/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/search-overlay.blp index 6523d414..8ab2e310 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/search-overlay.blp +++ b/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/search-overlay.blp @@ -46,7 +46,12 @@ template $GhosttySearchOverlay: Adw.Bin { "dim-label", ] - label: bind $match_label_closure(template.has-search-selected, template.search-selected, template.has-search-total, template.search-total) as ; + label: bind $match_label_closure( + template.has-search-selected, + template.search-selected, + template.has-search-total, + template.search-total + ) as ; width-chars: 6; xalign: 1.0; } diff --git a/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/surface.blp b/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/surface.blp index 2ae0a347..010798ae 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/surface.blp +++ b/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/surface.blp @@ -1,4 +1,5 @@ using Gtk 4.0; +using Gdk 4.0; using Adw 1; Adw.StatusPage error_page { @@ -96,7 +97,9 @@ Overlay terminal_page { // TODO: the tooltip doesn't actually work, but keep it here for now so // that we can get the tooltip text translated. has-tooltip: true; - tooltip-text: _("This terminal is in read-only mode. You can still view, select, and scroll through the content, but no input events will be sent to the running application."); + tooltip-text: _( + "This terminal is in read-only mode. You can still view, select, and scroll through the content, but no input events will be sent to the running application." + ); halign: end; valign: start; spacing: 6; @@ -205,7 +208,11 @@ Overlay terminal_page { // Apply unfocused-split-fill and unfocused-split-opacity to current surface // this is only applied when a tab has more than one surface Revealer { - reveal-child: bind $should_unfocused_split_be_shown(search_overlay.active, template.focused, template.is-split) as ; + reveal-child: bind $should_unfocused_split_be_shown( + search_overlay.active, + template.focused, + template.is-split + ) as ; transition-duration: 0; // This is all necessary so that the Revealer itself doesn't override // any input events from the other overlays. Namely, if you don't have @@ -221,10 +228,57 @@ Overlay terminal_page { } } + [overlay] + CenterBox drag_handle { + halign: fill; + valign: start; + visible: bind $should_drag_handle_be_shown(template.config, template.is-split) as ; + + styles [ + "drag-handle", + ] + + [center] + Image { + icon-name: "view-more-horizontal-symbolic"; + } + + DragSource surface_drag_source { + actions: move; + prepare => $surface_drag_prepare(); + drag-begin => $surface_drag_begin(); + } + } + + [overlay] + DrawingArea drop_overlay { + halign: fill; + valign: fill; + can-focus: false; + can-target: false; + focusable: false; + + styles [ + "drop-overlay", + ] + } + DropTarget drop_target { drop => $drop(); actions: copy | move; } + + DropTarget surface_drop_target { + // Enabling preload is required since that lets us know + // which surface is currently being dragged, and to turn off + // the drop overlay if the source and target are the same + preload: true; + leave => $surface_drop_leave(); + motion => $surface_drop_motion(); + drop => $surface_drop(); + notify::value => $notify_drop_value(); + actions: move; + } } template $GhosttySurface: Adw.Bin { @@ -348,6 +402,11 @@ menu context_menu_model { submenu { label: _("Window"); + item { + label: _("Change Window Title…"); + action: "win.prompt-window-title"; + } + item { label: _("New Window"); action: "win.new-window"; @@ -365,8 +424,15 @@ menu context_menu_model { label: _("Config"); item { - label: _("Open Configuration"); + label: _("Open Configuration in OS Editor"); + action: "app.open-config"; + target: "os-open"; + } + + item { + label: _("Open Configuration in New Window"); action: "app.open-config"; + target: "new-window"; } item { diff --git a/vendor/libghostty-vt/src/apprt/gtk/ui/1.5/tab.blp b/vendor/libghostty-vt/src/apprt/gtk/ui/1.5/tab.blp index 55f2e7ef..21a30bec 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/ui/1.5/tab.blp +++ b/vendor/libghostty-vt/src/apprt/gtk/ui/1.5/tab.blp @@ -8,7 +8,14 @@ template $GhosttyTab: Box { orientation: vertical; hexpand: true; vexpand: true; - title: bind $computed_title(template.config, split_tree.active-surface as <$GhosttySurface>.title, split_tree.active-surface as <$GhosttySurface>.title-override, template.title-override, split_tree.is-zoomed, split_tree.active-surface as <$GhosttySurface>.bell-ringing) as ; + title: bind $computed_title( + template.config, + split_tree.active-surface as <$GhosttySurface>.title, + split_tree.active-surface as <$GhosttySurface>.title-override, + template.title-override, + split_tree.is-zoomed, + split_tree.active-surface as <$GhosttySurface>.bell-ringing + ) as ; tooltip: bind split_tree.active-surface as <$GhosttySurface>.pwd; $GhosttySplitTree split_tree { diff --git a/vendor/libghostty-vt/src/apprt/gtk/ui/1.5/window.blp b/vendor/libghostty-vt/src/apprt/gtk/ui/1.5/window.blp index b66a9309..32d1bf37 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/ui/1.5/window.blp +++ b/vendor/libghostty-vt/src/apprt/gtk/ui/1.5/window.blp @@ -40,14 +40,17 @@ template $GhosttyWindow: Adw.ApplicationWindow { visible: bind template.headerbar-visible; title-widget: Adw.WindowTitle { - title: bind template.title; + title: bind $computed_title(template.config, template.title, template.title-override) as ; // Blueprint auto-formatter won't let me split this into multiple // lines. Let me explain myself. All parameters to a closure are used // as notifications to recompute the value of the closure. All // elements of a property chain are also subscribed to for changes. // This one long, ugly line saves us from manually building up this // massive notify chain in code. - subtitle: bind $computed_subtitle(template.config, tab_view.selected-page.child as <$GhosttyTab>.active-surface as <$GhosttySurface>.pwd) as ; + subtitle: bind $computed_subtitle( + template.config, + tab_view.selected-page.child as <$GhosttyTab>.active-surface as <$GhosttySurface>.pwd + ) as ; }; [start] @@ -208,6 +211,11 @@ menu main_menu { } section { + item { + label: _("Change Window Title…"); + action: "win.prompt-window-title"; + } + item { label: _("New Window"); action: "win.new-window"; @@ -291,14 +299,25 @@ menu main_menu { action: "win.toggle-inspector"; } - item { - label: _("Open Configuration"); - action: "app.open-config"; - } + submenu { + label: _("Config"); - item { - label: _("Reload Configuration"); - action: "app.reload-config"; + item { + label: _("Open Configuration in OS Editor"); + action: "app.open-config"; + target: "os-open"; + } + + item { + label: _("Open Configuration in New Window"); + action: "app.open-config"; + target: "new-window"; + } + + item { + label: _("Reload Configuration"); + action: "app.reload-config"; + } } } diff --git a/vendor/libghostty-vt/src/apprt/gtk/weak_ref.zig b/vendor/libghostty-vt/src/apprt/gtk/weak_ref.zig index f689e45f..73cc6e51 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/weak_ref.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/weak_ref.zig @@ -22,6 +22,23 @@ pub fn WeakRef(comptime T: type) type { } } + /// Release this weak reference. + /// + /// You MUST call this before the memory holding this struct is freed, + /// which in practice means from the owner's `dispose`. The target keeps + /// a pointer to this `GWeakRef` so that it can clear it when the target + /// is finalized; if this memory is gone by then, the target walks into + /// whatever now occupies it. That is an invalid read at best, and can + /// hang: the target takes a lock inside each registered weak ref, and + /// reused memory with the low bit set is a lock nothing will release. + /// + /// `set(null)` also unregisters and remains valid. This exists so the + /// requirement has a name at the use site rather than looking like an + /// ordinary assignment. + pub fn deinit(self: *Self) void { + self.ref.clear(); + } + /// Get a strong reference to the object, or null if the object /// has been finalized. This increases the reference count by one. pub fn get(self: *Self) ?*T { diff --git a/vendor/libghostty-vt/src/apprt/gtk/winproto.zig b/vendor/libghostty-vt/src/apprt/gtk/winproto.zig index d409d6c2..abf46d99 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/winproto.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/winproto.zig @@ -8,6 +8,7 @@ const Config = @import("../../config.zig").Config; const input = @import("../../input.zig"); const key = @import("key.zig"); const ApprtWindow = @import("class/window.zig").Window; +const GlobalShortcuts = @import("class/global_shortcuts.zig").GlobalShortcuts; pub const noop = @import("winproto/noop.zig"); pub const x11 = @import("winproto/x11.zig"); @@ -78,6 +79,26 @@ pub const App = union(Protocol) { inline else => |*v| try v.initQuickTerminal(apprt_window), } } + + /// Bind all global keybinds through a mechanism native to the + /// windowing protocol. Returns false if there is none; the caller + /// should then fall back to the XDG desktop portal. + pub fn bindGlobalShortcuts( + self: *App, + shortcuts: *GlobalShortcuts, + config: *const Config, + ) bool { + return switch (self.*) { + inline else => |*v| v.bindGlobalShortcuts(shortcuts, config), + }; + } + + /// Unbind all global keybinds bound via bindGlobalShortcuts. + pub fn clearGlobalShortcuts(self: *App) void { + switch (self.*) { + inline else => |*v| v.clearGlobalShortcuts(), + } + } }; /// Per-Window state for the underlying windowing protocol. @@ -141,7 +162,7 @@ pub const Window = union(Protocol) { }; } - pub fn addSubprocessEnv(self: *Window, env: *std.process.EnvMap) !void { + pub fn addSubprocessEnv(self: *Window, env: *std.process.Environ.Map) !void { switch (self.*) { inline else => |*v| try v.addSubprocessEnv(env), } diff --git a/vendor/libghostty-vt/src/apprt/gtk/winproto/noop.zig b/vendor/libghostty-vt/src/apprt/gtk/winproto/noop.zig index 950ee0f3..e5f59dc4 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/winproto/noop.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/winproto/noop.zig @@ -6,6 +6,7 @@ const gdk = @import("gdk"); const Config = @import("../../../config.zig").Config; const input = @import("../../../input.zig"); const ApprtWindow = @import("../class/window.zig").Window; +const GlobalShortcuts = @import("../class/global_shortcuts.zig").GlobalShortcuts; const log = std.log.scoped(.winproto_noop); @@ -35,6 +36,16 @@ pub const App = struct { return false; } pub fn initQuickTerminal(_: *App, _: *ApprtWindow) !void {} + + pub fn bindGlobalShortcuts( + _: *App, + _: *GlobalShortcuts, + _: *const Config, + ) bool { + return false; + } + + pub fn clearGlobalShortcuts(_: *App) void {} }; pub const Window = struct { @@ -67,7 +78,7 @@ pub const Window = struct { return true; } - pub fn addSubprocessEnv(_: *Window, _: *std.process.EnvMap) !void {} + pub fn addSubprocessEnv(_: *Window, _: *std.process.Environ.Map) !void {} pub fn setUrgent(_: *Window, _: bool) !void {} }; diff --git a/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland.zig b/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland.zig index 12c7fb8a..81481514 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland.zig @@ -17,9 +17,12 @@ const xdg = wayland.client.xdg; const Config = @import("../../../config.zig").Config; const Globals = @import("wayland/Globals.zig"); +const Hotkeys = @import("wayland/Hotkeys.zig"); const input = @import("../../../input.zig"); const ApprtWindow = @import("../class/window.zig").Window; +const GlobalShortcuts = @import("../class/global_shortcuts.zig").GlobalShortcuts; const BlurRegion = @import("BlurRegion.zig"); +const gtk_version = @import("../gtk_version.zig"); const log = std.log.scoped(.winproto_wayland); @@ -27,6 +30,7 @@ const log = std.log.scoped(.winproto_wayland); pub const App = struct { display: *wl.Display, globals: *Globals, + hotkeys: Hotkeys, pub fn init( alloc: Allocator, @@ -35,7 +39,6 @@ pub const App = struct { config: *const Config, ) !?App { _ = config; - _ = app_id; const gdk_wayland_display = gobject.ext.cast( gdk_wayland.WaylandDisplay, @@ -49,16 +52,35 @@ pub const App = struct { const globals: *Globals = try .init(alloc, display); errdefer globals.deinit(); + var hotkeys: Hotkeys = try .init(alloc, app_id); + errdefer hotkeys.deinit(); + return .{ .display = display, .globals = globals, + .hotkeys = hotkeys, }; } pub fn deinit(self: *App) void { + self.hotkeys.deinit(); self.globals.deinit(); } + pub fn bindGlobalShortcuts( + self: *App, + shortcuts: *GlobalShortcuts, + config: *const Config, + ) bool { + const manager = self.globals.get(.vicinae_hotkey_manager) orelse return false; + self.hotkeys.bind(manager, shortcuts, config); + return true; + } + + pub fn clearGlobalShortcuts(self: *App) void { + self.hotkeys.clear(); + } + pub fn eventMods( _: *App, _: ?*gdk.Device, @@ -153,6 +175,12 @@ pub const Window = struct { }; const bg_effect: ?*ext.BackgroundEffectSurfaceV1 = bg: { + if (gtk_version.runtimeAtLeast(4, 23, 3)) { + // GTK 4.23.3 added an official way to do background blur, + // so we don't need to do anything on our own. + break :bg null; + } + const mgr = app.globals.get(.ext_background_effect) orelse break :bg null; @@ -225,7 +253,7 @@ pub const Window = struct { }; } - pub fn addSubprocessEnv(self: *Window, env: *std.process.EnvMap) !void { + pub fn addSubprocessEnv(self: *Window, env: *std.process.Environ.Map) !void { _ = self; _ = env; } @@ -278,7 +306,7 @@ pub const Window = struct { } const wl_region = try compositor.createRegion(); - errdefer if (wl_region) |r| r.destroy(); + defer wl_region.destroy(); for (region.slices.items) |s| wl_region.add( @intCast(s.x), @intCast(s.y), @@ -287,6 +315,7 @@ pub const Window = struct { ); bg.setBlurRegion(wl_region); + self.blur_region.deinit(self.globals.alloc); self.blur_region = region; } diff --git a/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/Globals.zig b/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/Globals.zig index 83052cbe..bb4a48c9 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/Globals.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/Globals.zig @@ -8,6 +8,7 @@ const wl = wayland.client.wl; const ext = wayland.client.ext; const kde = wayland.client.kde; const org = wayland.client.org; +const vicinae = wayland.client.vicinae; const xdg = wayland.client.xdg; const log = std.log.scoped(.winproto_wayland_globals); @@ -32,6 +33,7 @@ pub const Tag = enum { kde_decoration_manager, kde_slide_manager, kde_output_order, + vicinae_hotkey_manager, xdg_activation, fn Type(comptime self: Tag) type { @@ -41,6 +43,7 @@ pub const Tag = enum { .kde_decoration_manager => org.KdeKwinServerDecorationManager, .kde_slide_manager => org.KdeKwinSlideManager, .kde_output_order => kde.OutputOrderV1, + .vicinae_hotkey_manager => vicinae.HotkeyManagerV1, .xdg_activation => xdg.ActivationV1, }; } diff --git a/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/Hotkeys.zig b/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/Hotkeys.zig new file mode 100644 index 00000000..91e54646 --- /dev/null +++ b/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/Hotkeys.zig @@ -0,0 +1,165 @@ +//! Global shortcuts backed by the vicinae-hotkey Wayland protocol. +const Hotkeys = @This(); + +const std = @import("std"); +const Allocator = std.mem.Allocator; + +const wayland = @import("wayland"); +const vicinae = wayland.client.vicinae; + +const Config = @import("../../../../config.zig").Config; +const Binding = @import("../../../../input.zig").Binding; +const key = @import("../../key.zig"); +const GlobalShortcuts = @import("../../class/global_shortcuts.zig").GlobalShortcuts; + +const log = std.log.scoped(.winproto_wayland_hotkeys); + +alloc: Allocator, +app_id: [:0]const u8, +entries: std.ArrayList(Entry) = .empty, + +const Entry = struct { + /// Null once the binding was denied or revoked. + hotkey: ?*vicinae.HotkeyV1, + trigger: Binding.Trigger, + action: Binding.Action, + shortcuts: *GlobalShortcuts, + + fn deinit(self: *Entry) void { + if (self.hotkey) |hotkey| hotkey.destroy(); + } + + fn bind( + self: *Entry, + manager: *vicinae.HotkeyManagerV1, + app_id: [:0]const u8, + ) !void { + // The only time this will return an error is when + // `trigger.key` is `catch_all`, which is guarded + // in the public `bind` function + const keysym = key.keysymFromTrigger(self.trigger) orelse unreachable; + + var desc_buf: [256]u8 = undefined; + const desc = std.fmt.bufPrintZ(&desc_buf, "{f}", .{self.action}) catch ""; + + const hotkey = try manager.bind( + keysym, + .{ + .shift = self.trigger.mods.shift, + .ctrl = self.trigger.mods.ctrl, + .alt = self.trigger.mods.alt, + .super = self.trigger.mods.super, + }, + null, + app_id.ptr, + desc.ptr, + ); + errdefer hotkey.destroy(); + hotkey.setListener(*Entry, hotkeyListener, self); + self.hotkey = hotkey; + } + + fn fail(self: *Entry, message: [*:0]const u8, revoked: bool) void { + self.hotkey.?.destroy(); + self.hotkey = null; + + self.shortcuts.emitBindFailed(&.{ + .trigger = self.trigger, + .action = self.action, + .message = message, + .revoked = revoked, + }); + } +}; + +pub fn init(alloc: Allocator, app_id: [:0]const u8) Allocator.Error!Hotkeys { + return .{ + .alloc = alloc, + .app_id = try alloc.dupeZ(u8, app_id), + }; +} + +/// Must leave the entries in a valid empty state: clear may still be +/// called after deinit during application teardown. +pub fn deinit(self: *Hotkeys) void { + for (self.entries.items) |*entry| entry.deinit(); + self.entries.clearAndFree(self.alloc); + self.alloc.free(self.app_id); +} + +pub fn clear(self: *Hotkeys) void { + for (self.entries.items) |*entry| entry.deinit(); + self.entries.clearRetainingCapacity(); +} + +pub fn bind( + self: *Hotkeys, + manager: *vicinae.HotkeyManagerV1, + shortcuts: *GlobalShortcuts, + config: *const Config, +) void { + self.clear(); + + var it = config.keybind.set.bindings.iterator(); + while (it.next()) |entry| { + const leaf: Binding.Set.GenericLeaf = switch (entry.value_ptr.*) { + .leader => continue, + inline .leaf, .leaf_chained => |leaf| leaf.generic(), + }; + if (!leaf.flags.global) continue; + // Catch all global keybinds don't really make sense + if (entry.key_ptr.key == .catch_all) continue; + + // Only single-action global keybinds are supported, as in the + // portal implementation. + const actions = leaf.actionsSlice(); + if (actions.len != 1) continue; + + self.entries.append(self.alloc, .{ + .hotkey = null, + .trigger = entry.key_ptr.*, + .action = actions[0], + .shortcuts = shortcuts, + }) catch {}; + } + + for (self.entries.items) |*entry| { + entry.bind(manager, self.app_id) catch |err| { + log.warn("failed to request hotkey trigger={f} err={}", .{ + entry.trigger, + err, + }); + }; + } +} + +fn hotkeyListener( + _: *vicinae.HotkeyV1, + event: vicinae.HotkeyV1.Event, + entry: *Entry, +) void { + switch (event) { + .bound => log.debug("hotkey bound action={f}", .{entry.action}), + + .denied => |v| { + log.warn("hotkey denied action={f} reason={} message={s}", .{ + entry.action, + v.reason, + v.message, + }); + entry.fail(v.message, false); + }, + + .revoked => |v| { + log.warn("hotkey revoked action={f} reason={} message={s}", .{ + entry.action, + v.reason, + v.message, + }); + entry.fail(v.message, true); + }, + + .pressed => entry.shortcuts.emitTrigger(&entry.action), + .released => {}, + } +} diff --git a/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/protocols/vicinae-hotkey-v1.xml b/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/protocols/vicinae-hotkey-v1.xml new file mode 100644 index 00000000..30f97394 --- /dev/null +++ b/vendor/libghostty-vt/src/apprt/gtk/winproto/wayland/protocols/vicinae-hotkey-v1.xml @@ -0,0 +1,305 @@ + + + + Copyright © 2026 Aurelien Brabant + + 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: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + 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. + + + + This protocol lets a client choose, and freely reconfigure, its own + global hotkeys: it requests a specific key combination and the compositor + accepts it or rejects it with a reason. The compositor remains the eventual + arbiter (it may deny a request, revoke a binding at any time, or apply + whatever policy it likes), but within that the application manages its own + bindings, including changing them at runtime, with no out-of-band user + configuration and no persisted compositor state. + + A hotkey is a key combination that fires regardless of which surface holds + keyboard focus. This is unrelated to keyboard-shortcuts-inhibit, which lets a + focused client suppress the compositor's own shortcuts. + + Whether a combination is exclusive is compositor policy. A compositor MAY + treat combinations as exclusive and reject a clashing request with + "already_bound", or MAY grant the same combination to more than one binding + (each bound hotkey then receives the events), as some platforms do. Clients + must cope with either. + + It is intentionally a thin mechanism. It does NOT define which combinations + are acceptable: that is policy and belongs to the compositor, expressed + through the accept/deny channel. It does NOT persist hotkeys: a binding lives + only as long as its vicinae_hotkey_v1 object and the client connection; there is + no configure or storage step, a binding never outlives the client that created + it, and reconfiguring is simply destroying a hotkey and binding the new + combination. + + Warning! The protocol described in this file is currently in the testing + phase. Backward incompatible changes may be added together with the + corresponding interface version bump. Backward compatible changes are added + by bumping the interface version. + + Security considerations: + + A global hotkey lets an unfocused client observe that a specific key + combination was pressed. Compositors are the security boundary and SHOULD + apply policy when deciding whether to accept a request. In particular, + implementations SHOULD reject combinations that do not include at least one + non-latching modifier among Ctrl, Alt or Super, unless the trigger is a + function key, because unmodified (and Shift-only) keys carry ordinary text + entry and grabbing them turns this protocol into a keylogger. + + The protocol's one hard guarantee is containment: a compositor MUST NOT + deliver events for a combination the client did not successfully bind, and + never forwards the raw key stream, so a client learns nothing about input it + did not explicitly, and successfully, bind. Beyond that, a compositor MAY + apply any further policy it sees fit (for example prompting the user, + restricting which clients may bind, or limiting how many bindings a client may + hold) and MAY revoke a binding at any time via the "revoked" event, including + under user control. + + These are recommendations, not wire requirements: a combination the + compositor disallows is simply reported through the "denied" event with the + "not_permitted" reason, so applications can rely on a uniform rejection path + regardless of each compositor's policy. + + + + + This interface is the entry point of the protocol. It is used to request + global hotkeys. + + + + + A bitmask of the modifiers that must be held for the hotkey to fire. + + These are fixed, keymap-independent semantic bits naming the standard + modifiers, suitable for expressing a binding, unlike wl_keyboard.modifiers, + which carries opaque, keymap-derived masks for runtime state. A compositor + matches each bit against the corresponding modifier in its keyboard state + as the keymap defines it; for the xkb_v1 keymap format that is shift -> + XKB_MOD_NAME_SHIFT, ctrl -> XKB_MOD_NAME_CTRL, alt -> XKB_MOD_NAME_ALT + ("Mod1"), super -> XKB_MOD_NAME_LOGO ("Mod4"). + + Lock modifiers (Caps Lock, Num Lock) are never part of a binding and are + ignored when matching. + + + + + + + + + + Destroy the manager object. Hotkey objects created through this manager + are unaffected and remain valid; their bindings persist until they are + themselves destroyed or the client disconnects. + + + + + + Request that the given key combination be bound as a global hotkey. + + The keysym identifies the trigger key using the keysym numbering shared + with the keymap delivered over wl_keyboard (for the xkb_v1 keymap format, + an XKB_KEY_* value), taken in its unshifted form (XKB_KEY_b not XKB_KEY_B). A compositor SHOULD match + it against any of the user's layout groups, so a binding keeps firing after + the user switches layout group. This is one deliberately specified rule, + not a universal one: other platforms differ (macOS matches a physical + keycode, X11 re-grabs per layout, Windows tracks the active layout's key), + and no rule serves a layout that never produces the keysym; the single + documented rule is chosen for predictability across compositors. + + The request creates an vicinae_hotkey_v1 object immediately, but the binding + is not active yet. The compositor replies asynchronously with either the + "bound" event (the hotkey is now active) or the "denied" event (the + request was rejected, with a reason). + + seat is the wl_seat whose keyboard should trigger the hotkey, or null to + request it on all of the client's seats. Most clients pass null; seat is + provided for completeness on multi-seat systems. + + app_id identifies the requesting application, for use in the compositor's + policy and any user-facing audit UI. Where the application has a desktop + entry, app_id SHOULD be its desktop file ID as defined by the + freedesktop.org Desktop Entry specification, that is the .desktop file + name with the .desktop suffix removed (for example "org.example.Launcher"), + matching the convention used by xdg_toplevel.set_app_id so a compositor + can correlate the two. It is advisory and may be spoofed; a compositor + that needs a trustworthy identity SHOULD obtain it through the + security-context mechanism rather than relying on this string. + + description is a human-readable, localized description of what the hotkey + does (e.g. "Toggle the launcher"), for display in compositor UI or even in this protocol error messages. + + + + + + + + + + + + + Represents one requested global hotkey. Its binding is ephemeral: it is + released when this object is destroyed or when the client disconnects, and + it is never written to any persistent store. + + After bind, exactly one of "bound" or "denied" is sent. While the hotkey is + bound, "pressed" and "released" are sent as the combination is activated. + The compositor may send "revoked" at any time after "bound" to indicate the + binding is no longer active (for example because the user removed it, or a + higher-priority binding took the combination). + + + + + Carried by the "denied" event. This is a reason code, not a fatal + protocol error: the object remains valid and the client should destroy + it (or try a different combination). + + + + + + + + + Carried by the "revoked" event. This is a reason code, not a fatal + protocol error: the object remains valid and the client should destroy + it. + + The distinction is actionable: on "superseded" the combination may + become available again, so a client may reasonably re-request it later; + on "removed" the withdrawal is a deliberate user or compositor decision, + so a client MUST NOT silently re-request the same combination. A client + that receives a value it does not recognise (a future addition) MUST + treat it conservatively as "removed" and not auto-rebind. + + + + + + + + + Release the binding and destroy the object. The combination becomes + available again immediately. It is valid to destroy the object before + receiving "bound" or "denied", which cancels the pending request. + + + + + + The requested combination was accepted and is now active. "pressed" and + "released" events may follow. + + + + + + The requested combination was not bound. No input events will be sent. + The client should destroy this object; it may then create a new request + with a different combination. + + message is an optional, advisory, human-readable explanation in the + compositor's locale, intended for verbatim display in client UI (for + example a "change shortcut" settings screen). It may be empty, and a + compositor is never required to provide it. Clients MUST NOT parse it or + rely on its contents in any way; all programmatic behavior keys off + reason. A client with nowhere to show it simply ignores it. + + + + + + + + A binding that was previously "bound" is no longer active. No further + input events will be sent for it. The client should destroy this object; + it may request the combination again later. + + message is an optional, advisory, human-readable explanation in the + compositor's locale, intended for verbatim display in client UI. It may + be empty, and a compositor is never required to provide it. Clients MUST + NOT parse it or rely on its contents in any way; all programmatic + behavior keys off reason. A client with nowhere to show it simply + ignores it. + + + + + + + + The bound combination was activated. + + This event is sent once per activation. While the combination is held + down no further "pressed" events are sent, and a single "released" + follows when the trigger key is released: the compositor does not + auto-repeat the hotkey. + + serial is a compositor-issued input serial that counts as a recent user + interaction, so the client can act on the hotkey even though the + triggering key press is not otherwise delivered to it (the compositor + consumes it). In particular, a client may pass this serial to + xdg_activation_token_v1.set_serial in order to raise or focus a surface in + response to the hotkey; a compositor SHOULD honor activation carried by + this serial, since the hotkey is itself a deliberate user action. The + serial is drawn from the same space as other input event serials. + + time is the event timestamp, with the same millisecond clock as wl_pointer + and wl_keyboard input events; it is useful for ordering and for measuring + press-to-release duration. + + + + + + + + The trigger key of a previously pressed combination was released. This + enables press-and-hold uses (e.g. push-to-talk); clients that only act + on activation may ignore it. + + serial and time have the same meaning as in the "pressed" event. + + + + + + diff --git a/vendor/libghostty-vt/src/apprt/gtk/winproto/x11.zig b/vendor/libghostty-vt/src/apprt/gtk/winproto/x11.zig index 8109959d..fe0e6f61 100644 --- a/vendor/libghostty-vt/src/apprt/gtk/winproto/x11.zig +++ b/vendor/libghostty-vt/src/apprt/gtk/winproto/x11.zig @@ -19,6 +19,7 @@ pub const c = @cImport({ const input = @import("../../../input.zig"); const Config = @import("../../../config.zig").Config; const ApprtWindow = @import("../class/window.zig").Window; +const GlobalShortcuts = @import("../class/global_shortcuts.zig").GlobalShortcuts; const BlurRegion = @import("BlurRegion.zig"); const log = std.log.scoped(.gtk_x11); @@ -158,6 +159,16 @@ pub const App = struct { return mods; } + pub fn bindGlobalShortcuts( + _: *App, + _: *GlobalShortcuts, + _: *const Config, + ) bool { + return false; + } + + pub fn clearGlobalShortcuts(_: *App) void {} + pub fn supportsQuickTerminal(_: App) bool { log.warn("quick terminal is not yet supported on X11", .{}); return false; @@ -317,7 +328,7 @@ pub const Window = struct { self.last_applied_decoration_hints = hints; } - pub fn addSubprocessEnv(self: *Window, env: *std.process.EnvMap) !void { + pub fn addSubprocessEnv(self: *Window, env: *std.process.Environ.Map) !void { var buf: [64]u8 = undefined; const window_id = try std.fmt.bufPrint( &buf, diff --git a/vendor/libghostty-vt/src/apprt/ipc.zig b/vendor/libghostty-vt/src/apprt/ipc.zig index dda794ae..d5d860a7 100644 --- a/vendor/libghostty-vt/src/apprt/ipc.zig +++ b/vendor/libghostty-vt/src/apprt/ipc.zig @@ -70,23 +70,82 @@ pub const Action = union(enum) { // entry. If the value type is void then only the key needs to be // added. Ensure the order matches exactly with the Zig code. - /// The arguments to pass to Ghostty as the command. + /// Create a new window. new_window: NewWindow, + /// Create a new tab. + new_tab: NewTab, + /// Toggle the quick terminal. toggle_quick_terminal: void, pub const NewWindow = struct { - /// A list of command arguments to launch in the new window. If this is - /// `null` the command configured in the config or the user's default - /// shell should be launched. + /// A list of configuration entries that will override the configuration + /// of the first surface of the new window. If this is `null` there + /// are no overrides. Note that not all configuration entries may be + /// overridden. /// /// It is an error for this to be non-`null`, but zero length. arguments: ?[][:0]const u8, pub const C = extern struct { - /// null terminated list of arguments - /// it will be null itself if there are no arguments + /// A list of configuration entries that will override the + /// configuration of the first surface of the new tab. If this is + /// `null` there are no overrides. Note that not all configuration + /// entries may be overridden. + /// + /// It is an error for this to be non-`null`, but zero length. + arguments: ?[*]?[*:0]const u8, + + pub fn deinit(self: *NewWindow.C, alloc: Allocator) void { + if (self.arguments) |arguments| alloc.free(arguments); + } + }; + + pub fn cval(self: *NewWindow, alloc: Allocator) Allocator.Error!NewWindow.C { + var result: NewWindow.C = undefined; + + if (self.arguments) |arguments| { + result.arguments = try alloc.alloc([*:0]const u8, arguments.len + 1); + + for (arguments, 0..) |argument, i| + result.arguments[i] = argument.ptr; + + // add null terminator + result.arguments[arguments.len] = null; + } else { + result.arguments = null; + } + + return result; + } + }; + + pub const NewTab = struct { + /// The unique ID of a surface. If the ID is zero the currently focused + /// surface is assumed. This will be used to identify the window to add + /// the tab to. + surface_id: u64, + + /// A list of configuration entries that will override the configuration + /// of the first surface of the new tab. If this is `null` there + /// are no overrides. Note that not all configuration entries may be + /// overridden. + /// + /// It is an error for this to be non-`null`, but zero length. + arguments: ?[][:0]const u8, + + pub const C = extern struct { + /// The unique ID of a surface. If the ID is zero the currently + /// focused surface is assumed. This will be used to identify the + /// window to add the tab to. + surface_id: u64, + /// A list of configuration entries that will override the + /// configuration of the first surface of the new tab. If this is + /// `null` there are no overrides. Note that not all configuration + /// entries may be overridden. + /// + /// It is an error for this to be non-`null`, but zero length. arguments: ?[*]?[*:0]const u8, pub fn deinit(self: *NewWindow.C, alloc: Allocator) void { @@ -116,6 +175,7 @@ pub const Action = union(enum) { /// Sync with: ghostty_ipc_action_tag_e pub const Key = enum(c_int) { new_window, + new_tab, toggle_quick_terminal, test "ghostty.h Action.Key" { @@ -126,8 +186,12 @@ pub const Action = union(enum) { /// Sync with: ghostty_ipc_action_u pub const CValue = cvalue: { const key_fields = @typeInfo(Key).@"enum".fields; - var union_fields: [key_fields.len]std.builtin.Type.UnionField = undefined; - for (key_fields, 0..) |field, i| { + + var names: [key_fields.len][]const u8 = undefined; + var types: [key_fields.len]type = undefined; + var attrs: [key_fields.len]std.builtin.Type.UnionField.Attributes = undefined; + + for (key_fields, &names, &types, &attrs) |field, *name, *ty, *attr| { const action = @unionInit(Action, field.name, undefined); const Type = t: { const Type = @TypeOf(@field(action, field.name)); @@ -135,20 +199,12 @@ pub const Action = union(enum) { if (Type != void and @hasDecl(Type, "C")) break :t Type.C; break :t Type; }; - - union_fields[i] = .{ - .name = field.name, - .type = Type, - .alignment = @alignOf(Type), - }; + name.* = field.name; + ty.* = Type; + attr.* = .{ .@"align" = @alignOf(Type) }; } - break :cvalue @Type(.{ .@"union" = .{ - .layout = .@"extern", - .tag_type = null, - .fields = &union_fields, - .decls = &.{}, - } }); + break :cvalue @Union(.@"extern", null, &names, &types, &attrs); }; /// Sync with: ghostty_ipc_action_s @@ -162,8 +218,8 @@ pub const Action = union(enum) { // At the time of writing, we don't promise ABI compatibility // so we can change this but I want to be aware of it. assert(@sizeOf(CValue) == switch (@sizeOf(usize)) { - 4 => 4, - 8 => 8, + 4 => 12, + 8 => 16, else => unreachable, }); } diff --git a/vendor/libghostty-vt/src/apprt/structs.zig b/vendor/libghostty-vt/src/apprt/structs.zig index 2c37dbd5..d8510fb8 100644 --- a/vendor/libghostty-vt/src/apprt/structs.zig +++ b/vendor/libghostty-vt/src/apprt/structs.zig @@ -1,4 +1,6 @@ +const std = @import("std"); const build_config = @import("../build_config.zig"); +const terminal = @import("../terminal/main.zig"); /// ContentScale is the ratio between the current DPI and the platform's /// default DPI. This is used to determine how much certain rendered elements @@ -67,13 +69,35 @@ pub const ClipboardRequestType = enum(u8) { paste, osc_52_read, osc_52_write, + kitty_read, + kitty_write, + list, +}; + +/// The result of starting a clipboard read request. This only reports +/// facts about the clipboard; how each state is answered on the wire +/// (if at all) is up to the protocol handling of the requester. +/// +/// If this is changed, you must also update ghostty.h +pub const ClipboardReadResult = enum(c_int) { + /// The request was started and will be completed asynchronously + /// via the core surface completeClipboardRequest API. + started = 0, + + /// The clipboard exists but has no contents the apprt can serve + /// (e.g. no text-like data). The request was not started. + unavailable = 1, + + /// The clipboard itself can't be read (e.g. a primary selection on + /// a platform without one). The request was not started. + unsupported = 2, }; /// Clipboard request. This is used to request clipboard contents and must /// be sent as a response to a ClipboardRequest event. pub const ClipboardRequest = union(ClipboardRequestType) { /// A direct paste of clipboard contents. - paste: void, + paste: Clipboard, /// A request to read clipboard contents via OSC 52. osc_52_read: Clipboard, @@ -81,6 +105,113 @@ pub const ClipboardRequest = union(ClipboardRequestType) { /// A request to write clipboard contents via OSC 52. osc_52_write: Clipboard, + /// A request to read clipboard contents via the Kitty clipboard + /// protocol (OSC 5522). + kitty_read: *KittyRead, + + /// A request to write clipboard contents via the Kitty clipboard + /// protocol (OSC 5522), carrying a fully committed transaction. + kitty_write: *KittyWrite, + + /// A request to list the available clipboard MIME types without + /// reading any of their data. + list: Clipboard, + + /// State for one in-flight Kitty clipboard protocol read. This is + /// created on the IO thread and completed on the app thread, so it + /// owns all of its memory: everything, including the struct itself, + /// is allocated from the arena. + pub const KittyRead = struct { + arena: std.heap.ArenaAllocator, + + /// The clipboard being read. The protocol can only name the + /// standard clipboard or the primary selection. + location: Clipboard, + + /// The requested MIME types in request order, already capped at + /// terminal.kitty.clipboard.max_read_mimes by the sender. Only + /// these representations may be served in the response. The + /// values are sentinel-terminated so they can cross a C apprt + /// boundary without copies. + mimes: []const [:0]const u8, + + /// True when the targets ('.') listing was requested. + list: bool, + + /// The sanitized request id, echoed in every response packet. + id: []const u8, + + /// The effective session password, empty when the request had + /// none. A non-empty password means the user's decision may be + /// remembered as a session grant. + pw: []const u8, + + /// The human friendly name of the requesting program, shown in + /// permission prompts. Empty when absent. Sentinel-terminated + /// so it can cross a C apprt boundary without copies. + name: [:0]const u8, + + /// True when a stored session grant already covers this + /// request, so any permission prompt is skipped. + granted: bool, + + /// The response terminator, matching the request's. + terminator: terminal.osc.Terminator, + + pub fn destroy(self: *KittyRead) void { + // The struct itself lives in the arena, so move the arena + // out before tearing it down. + var arena = self.arena; + arena.deinit(); + } + }; + + /// State for one committed Kitty clipboard protocol write + /// transaction. Like KittyRead, this is created on the IO thread + /// and completed on the app thread, so everything, including the + /// struct itself, is allocated from the arena. + pub const KittyWrite = struct { + arena: std.heap.ArenaAllocator, + + /// The clipboard being written. The protocol can only name the + /// standard clipboard or the primary selection. + location: Clipboard, + + /// The committed representations. These are the authoritative + /// contents of the write: completions apply these rather than + /// any contents echoed back by the apprt. The values are + /// sentinel-terminated so they can cross a C apprt boundary + /// without copies; data is binary-safe via its length. + contents: []const ClipboardContent, + + /// The sanitized request id, echoed in every response packet. + id: []const u8, + + /// The effective session password, empty when the request had + /// none. A non-empty password means the user's decision may be + /// remembered as a session grant. + pw: []const u8, + + /// The human friendly name of the requesting program, shown in + /// permission prompts. Empty when absent. Sentinel-terminated + /// so it can cross a C apprt boundary without copies. + name: [:0]const u8, + + /// True when a stored session grant already covers this + /// request, so any permission prompt is skipped. + granted: bool, + + /// The response terminator, matching the request's. + terminator: terminal.osc.Terminator, + + pub fn destroy(self: *KittyWrite) void { + // The struct itself lives in the arena, so move the arena + // out before tearing it down. + var arena = self.arena; + arena.deinit(); + } + }; + /// Make this a valid gobject if we're in a GTK environment. pub const getGObjectType = switch (build_config.app_runtime) { .gtk => @import("gobject").ext.defineBoxed( diff --git a/vendor/libghostty-vt/src/apprt/surface.zig b/vendor/libghostty-vt/src/apprt/surface.zig index 3cb0016f..51da3374 100644 --- a/vendor/libghostty-vt/src/apprt/surface.zig +++ b/vendor/libghostty-vt/src/apprt/surface.zig @@ -16,6 +16,47 @@ pub const Message = union(enum) { /// we want this union to be. pub const WriteReq = MessageData(u8, 255); + /// A fixed-size desktop notification payload sent to the app thread. + pub const DesktopNotification = struct { + /// Desktop notification title. + title: [63:0]u8, + + /// Desktop notification body. + body: [255:0]u8, + + pub fn init(title: []const u8, body: []const u8) DesktopNotification { + var result: DesktopNotification = undefined; + copyUtf8Z(result.title.len, &result.title, title); + copyUtf8Z(result.body.len, &result.body, body); + return result; + } + + /// UTF-8 continuation bytes occupy the range 0x80 through 0xBF. + fn isUtf8ContinuationByte(byte: u8) bool { + return switch (byte) { + 0x80...0xBF => true, + else => false, + }; + } + + /// Copy as much of `src` as fits, backing up from a UTF-8 continuation + /// byte so valid input is never truncated in the middle of a codepoint. + fn copyUtf8Z( + comptime capacity: usize, + dst: *[capacity:0]u8, + src: []const u8, + ) void { + var len = @min(src.len, capacity); + while (len > 0 and + len < src.len and + isUtf8ContinuationByte(src[len])) : (len -= 1) + {} + + @memcpy(dst[0..len], src[0..len]); + dst[len] = 0; + } + }; + /// Set the title of the surface. /// TODO: we should change this to a "WriteReq" style structure in /// the termio message so that we can more efficiently send strings @@ -31,6 +72,16 @@ pub const Message = union(enum) { /// Read the clipboard and write to the pty. clipboard_read: apprt.Clipboard, + /// A Kitty clipboard protocol (OSC 5522) read request. The receiver + /// takes ownership of the request state and must eventually destroy + /// it. + kitty_clipboard_read: *apprt.ClipboardRequest.KittyRead, + + /// A committed Kitty clipboard protocol (OSC 5522) write + /// transaction. The receiver takes ownership of the request state + /// and must eventually destroy it. + kitty_clipboard_write: *apprt.ClipboardRequest.KittyWrite, + /// Write the clipboard contents. clipboard_write: struct { clipboard_type: apprt.Clipboard, @@ -52,13 +103,7 @@ pub const Message = union(enum) { child_exited: ChildExited, /// Show a desktop notification. - desktop_notification: struct { - /// Desktop notification title. - title: [63:0]u8, - - /// Desktop notification body. - body: [255:0]u8, - }, + desktop_notification: DesktopNotification, /// Health status change for the renderer. renderer_health: renderer.Health, @@ -195,3 +240,78 @@ pub fn newConfig( return copy; } + +test "DesktopNotification init" { + const notification = Message.DesktopNotification.init("Title", "Body"); + + try std.testing.expectEqualStrings("Title", std.mem.sliceTo(¬ification.title, 0)); + try std.testing.expectEqualStrings("Body", std.mem.sliceTo(¬ification.body, 0)); +} + +test "copyUtf8Z handles len at the final byte of every UTF-8 sequence length" { + const DesktopNotification = Message.DesktopNotification; + + var dst_1_byte: [1:0]u8 = undefined; + const src_ending_in_1_byte_codepoint = "ab"; + try std.testing.expect(!DesktopNotification.isUtf8ContinuationByte( + src_ending_in_1_byte_codepoint[dst_1_byte.len], + )); + DesktopNotification.copyUtf8Z( + dst_1_byte.len, + &dst_1_byte, + src_ending_in_1_byte_codepoint, + ); + try std.testing.expectEqualStrings("a", std.mem.sliceTo(&dst_1_byte, 0)); + + var dst_2_bytes: [2:0]u8 = undefined; + const src_ending_in_2_byte_codepoint = "aЯ"; + try std.testing.expect(DesktopNotification.isUtf8ContinuationByte( + src_ending_in_2_byte_codepoint[dst_2_bytes.len], + )); + DesktopNotification.copyUtf8Z( + dst_2_bytes.len, + &dst_2_bytes, + src_ending_in_2_byte_codepoint, + ); + try std.testing.expectEqualStrings("a", std.mem.sliceTo(&dst_2_bytes, 0)); + + var dst_3_bytes: [3:0]u8 = undefined; + const src_ending_in_3_byte_codepoint = "a€"; + try std.testing.expect(DesktopNotification.isUtf8ContinuationByte( + src_ending_in_3_byte_codepoint[dst_3_bytes.len], + )); + DesktopNotification.copyUtf8Z( + dst_3_bytes.len, + &dst_3_bytes, + src_ending_in_3_byte_codepoint, + ); + try std.testing.expectEqualStrings("a", std.mem.sliceTo(&dst_3_bytes, 0)); + + var dst_4_bytes: [4:0]u8 = undefined; + const src_ending_in_4_byte_codepoint = "a😀"; + try std.testing.expect(DesktopNotification.isUtf8ContinuationByte( + src_ending_in_4_byte_codepoint[dst_4_bytes.len], + )); + DesktopNotification.copyUtf8Z( + dst_4_bytes.len, + &dst_4_bytes, + src_ending_in_4_byte_codepoint, + ); + try std.testing.expectEqualStrings("a", std.mem.sliceTo(&dst_4_bytes, 0)); +} + +test "copyUtf8Z keeps a complete codepoint at the truncation boundary" { + var dst: [5:0]u8 = undefined; + + Message.DesktopNotification.copyUtf8Z(dst.len, &dst, "abcЯz"); + + try std.testing.expectEqualStrings("abcЯ", std.mem.sliceTo(&dst, 0)); +} + +test "copyUtf8Z preserves UTF-8 that fits" { + var dst: [5:0]u8 = undefined; + + Message.DesktopNotification.copyUtf8Z(dst.len, &dst, "abcЯ"); + + try std.testing.expectEqualStrings("abcЯ", std.mem.sliceTo(&dst, 0)); +} diff --git a/vendor/libghostty-vt/src/benchmark/ApcParser.zig b/vendor/libghostty-vt/src/benchmark/ApcParser.zig index 73b7c57a..9efdc4fb 100644 --- a/vendor/libghostty-vt/src/benchmark/ApcParser.zig +++ b/vendor/libghostty-vt/src/benchmark/ApcParser.zig @@ -12,6 +12,7 @@ const Allocator = std.mem.Allocator; const terminalpkg = @import("../terminal/main.zig"); const Benchmark = @import("Benchmark.zig"); const options = @import("options.zig"); +const global = @import("../global.zig"); const log = std.log.scoped(.@"apc-parser-bench"); @@ -19,7 +20,7 @@ opts: Options, stream: Stream, /// The file, opened in the setup function. -data_f: ?std.fs.File = null, +data_f: ?std.Io.File = null, pub const Options = struct { /// The data to read as a filepath. If this is "-" then @@ -51,10 +52,10 @@ const Handler = struct { .apc_start => self.apc.start(), .apc_put => self.apc.feed(self.alloc, value), .apc_put_slice => self.apc.feedSlice(self.alloc, value.bytes), - .apc_end => if (self.apc.end()) |cmd| { - var c = cmd; - std.mem.doNotOptimizeAway(&c); - c.deinit(self.alloc); + .apc_end => if (self.apc.end()) |result| { + var r = result; + std.mem.doNotOptimizeAway(&r); + r.deinit(self.alloc); }, else => {}, } @@ -70,7 +71,10 @@ pub fn create( errdefer alloc.destroy(ptr); ptr.* = .{ .opts = opts, - .stream = .init(.{ .alloc = alloc }), + .stream = .init(.{ + .allocator = alloc, + .handler = .{ .alloc = alloc }, + }), }; return ptr; } @@ -103,7 +107,7 @@ fn setup(ptr: *anyopaque) Benchmark.Error!void { fn teardown(ptr: *anyopaque) void { const self: *ApcParser = @ptrCast(@alignCast(ptr)); if (self.data_f) |f| { - f.close(); + f.close(global.io()); self.data_f = null; } } @@ -114,7 +118,7 @@ fn step(ptr: *anyopaque) Benchmark.Error!void { const f = self.data_f orelse return; var read_buf: [64 * 1024]u8 align(std.atomic.cache_line) = undefined; - var f_reader = f.reader(&read_buf); + var f_reader = f.reader(global.io(), &read_buf); const r = &f_reader.interface; // This buffer size matches the read buffer size used by the diff --git a/vendor/libghostty-vt/src/benchmark/Benchmark.zig b/vendor/libghostty-vt/src/benchmark/Benchmark.zig index 41c3695d..d45ba181 100644 --- a/vendor/libghostty-vt/src/benchmark/Benchmark.zig +++ b/vendor/libghostty-vt/src/benchmark/Benchmark.zig @@ -6,6 +6,7 @@ const builtin = @import("builtin"); const assert = std.debug.assert; const macos = @import("macos"); const build_config = @import("../build_config.zig"); +const global = @import("../global.zig"); ptr: *anyopaque, vtable: VTable, @@ -64,21 +65,23 @@ pub fn run( signpost.log.release(); }; - const start = std.time.Instant.now() catch return error.BenchmarkFailed; + const start: std.Io.Timestamp = .now(global.io(), .awake); while (true) { // Run our step function. If it fails, we return the error. try self.vtable.stepFn(self.ptr); result.iterations += 1; // Get our current monotonic time and check our exit conditions. - const now = std.time.Instant.now() catch return error.BenchmarkFailed; + const now: std.Io.Timestamp = .now(global.io(), .awake); + const elapsed = start.durationTo(now).nanoseconds; + assert(elapsed >= 0); const exit = switch (mode) { .once => true, - .duration => |ns| now.since(start) >= ns, + .duration => |ns| elapsed >= ns, }; if (exit) { - result.duration = now.since(start); + result.duration = @as(u64, @intCast(std.math.clamp(elapsed, 0, std.math.maxInt(u64)))); return result; } } diff --git a/vendor/libghostty-vt/src/benchmark/CApi.zig b/vendor/libghostty-vt/src/benchmark/CApi.zig index 3bef8b26..c9840671 100644 --- a/vendor/libghostty-vt/src/benchmark/CApi.zig +++ b/vendor/libghostty-vt/src/benchmark/CApi.zig @@ -1,6 +1,6 @@ const std = @import("std"); const cli = @import("cli.zig"); -const state = &@import("../global.zig").state; +const global = @import("../global.zig"); const log = std.log.scoped(.benchmark); @@ -19,7 +19,7 @@ export fn ghostty_benchmark_cli( }; cli.mainAction( - state.alloc, + global.alloc(), action, .{ .string = std.mem.sliceTo(args, 0) }, ) catch |err| { diff --git a/vendor/libghostty-vt/src/benchmark/CodepointWidth.zig b/vendor/libghostty-vt/src/benchmark/CodepointWidth.zig index 30d3f91e..d0c6b808 100644 --- a/vendor/libghostty-vt/src/benchmark/CodepointWidth.zig +++ b/vendor/libghostty-vt/src/benchmark/CodepointWidth.zig @@ -14,13 +14,14 @@ const options = @import("options.zig"); const UTF8Decoder = @import("../terminal/UTF8Decoder.zig"); const simd = @import("../simd/main.zig"); const table = @import("../unicode/main.zig").table; +const global = @import("../global.zig"); const log = std.log.scoped(.@"terminal-stream-bench"); opts: Options, /// The file, opened in the setup function. -data_f: ?std.fs.File = null, +data_f: ?std.Io.File = null, pub const Options = struct { /// The type of codepoint width calculation to use. @@ -93,7 +94,7 @@ fn setup(ptr: *anyopaque) Benchmark.Error!void { fn teardown(ptr: *anyopaque) void { const self: *CodepointWidth = @ptrCast(@alignCast(ptr)); if (self.data_f) |f| { - f.close(); + f.close(global.io()); self.data_f = null; } } @@ -114,7 +115,7 @@ fn stepWcwidth(ptr: *anyopaque) Benchmark.Error!void { const f = self.data_f orelse return; var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; - var f_reader = f.reader(&read_buf); + var f_reader = f.reader(global.io(), &read_buf); var r = &f_reader.interface; var d: UTF8Decoder = .{}; @@ -141,7 +142,7 @@ fn stepTable(ptr: *anyopaque) Benchmark.Error!void { const f = self.data_f orelse return; var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; - var f_reader = f.reader(&read_buf); + var f_reader = f.reader(global.io(), &read_buf); var r = &f_reader.interface; var d: UTF8Decoder = .{}; @@ -173,7 +174,7 @@ fn stepSimd(ptr: *anyopaque) Benchmark.Error!void { const f = self.data_f orelse return; var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; - var f_reader = f.reader(&read_buf); + var f_reader = f.reader(global.io(), &read_buf); var r = &f_reader.interface; var d: UTF8Decoder = .{}; diff --git a/vendor/libghostty-vt/src/benchmark/GraphemeBreak.zig b/vendor/libghostty-vt/src/benchmark/GraphemeBreak.zig index 8278c5c2..8e5236fe 100644 --- a/vendor/libghostty-vt/src/benchmark/GraphemeBreak.zig +++ b/vendor/libghostty-vt/src/benchmark/GraphemeBreak.zig @@ -11,13 +11,14 @@ const options = @import("options.zig"); const UTF8Decoder = @import("../terminal/UTF8Decoder.zig"); const unicode = @import("../unicode/main.zig"); const uucode = @import("uucode"); +const global = @import("../global.zig"); const log = std.log.scoped(.@"terminal-stream-bench"); opts: Options, /// The file, opened in the setup function. -data_f: ?std.fs.File = null, +data_f: ?std.Io.File = null, pub const Options = struct { /// The type of codepoint width calculation to use. @@ -82,7 +83,7 @@ fn setup(ptr: *anyopaque) Benchmark.Error!void { fn teardown(ptr: *anyopaque) void { const self: *GraphemeBreak = @ptrCast(@alignCast(ptr)); if (self.data_f) |f| { - f.close(); + f.close(global.io()); self.data_f = null; } } @@ -92,7 +93,7 @@ fn stepNoop(ptr: *anyopaque) Benchmark.Error!void { const f = self.data_f orelse return; var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; - var f_reader = f.reader(&read_buf); + var f_reader = f.reader(global.io(), &read_buf); var r = &f_reader.interface; var d: UTF8Decoder = .{}; @@ -115,7 +116,7 @@ fn stepTable(ptr: *anyopaque) Benchmark.Error!void { const f = self.data_f orelse return; var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; - var f_reader = f.reader(&read_buf); + var f_reader = f.reader(global.io(), &read_buf); var r = &f_reader.interface; var d: UTF8Decoder = .{}; diff --git a/vendor/libghostty-vt/src/benchmark/IsSymbol.zig b/vendor/libghostty-vt/src/benchmark/IsSymbol.zig index 4fbffd1e..c99bc9ca 100644 --- a/vendor/libghostty-vt/src/benchmark/IsSymbol.zig +++ b/vendor/libghostty-vt/src/benchmark/IsSymbol.zig @@ -11,13 +11,14 @@ const options = @import("options.zig"); const UTF8Decoder = @import("../terminal/UTF8Decoder.zig"); const uucode = @import("uucode"); const symbols_table = @import("../unicode/symbols_table.zig").table; +const global = @import("../global.zig"); const log = std.log.scoped(.@"is-symbol-bench"); opts: Options, /// The file, opened in the setup function. -data_f: ?std.fs.File = null, +data_f: ?std.Io.File = null, pub const Options = struct { /// Which test to run. @@ -80,7 +81,7 @@ fn setup(ptr: *anyopaque) Benchmark.Error!void { fn teardown(ptr: *anyopaque) void { const self: *IsSymbol = @ptrCast(@alignCast(ptr)); if (self.data_f) |f| { - f.close(); + f.close(global.io()); self.data_f = null; } } @@ -90,7 +91,7 @@ fn stepUucode(ptr: *anyopaque) Benchmark.Error!void { const f = self.data_f orelse return; var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; - var f_reader = f.reader(&read_buf); + var f_reader = f.reader(global.io(), &read_buf); var r = &f_reader.interface; var d: UTF8Decoder = .{}; @@ -117,7 +118,7 @@ fn stepTable(ptr: *anyopaque) Benchmark.Error!void { const f = self.data_f orelse return; var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; - var f_reader = f.reader(&read_buf); + var f_reader = f.reader(global.io(), &read_buf); var r = &f_reader.interface; var d: UTF8Decoder = .{}; diff --git a/vendor/libghostty-vt/src/benchmark/OscParser.zig b/vendor/libghostty-vt/src/benchmark/OscParser.zig index d4b416de..9b21c37a 100644 --- a/vendor/libghostty-vt/src/benchmark/OscParser.zig +++ b/vendor/libghostty-vt/src/benchmark/OscParser.zig @@ -9,11 +9,12 @@ const Benchmark = @import("Benchmark.zig"); const options = @import("options.zig"); const Parser = @import("../terminal/osc.zig").Parser; const log = std.log.scoped(.@"osc-parser-bench"); +const global = @import("../global.zig"); opts: Options, /// The file, opened in the setup function. -data_f: ?std.fs.File = null, +data_f: ?std.Io.File = null, parser: Parser, @@ -70,7 +71,7 @@ fn setup(ptr: *anyopaque) Benchmark.Error!void { fn teardown(ptr: *anyopaque) void { const self: *OscParser = @ptrCast(@alignCast(ptr)); if (self.data_f) |f| { - f.close(); + f.close(global.io()); self.data_f = null; } } @@ -80,7 +81,7 @@ fn step(ptr: *anyopaque) Benchmark.Error!void { const f = self.data_f orelse return; var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; - var r = f.reader(&read_buf); + var r = f.reader(global.io(), &read_buf); var osc_buf: [4096]u8 align(std.atomic.cache_line) = undefined; while (true) { diff --git a/vendor/libghostty-vt/src/benchmark/PageCompression.zig b/vendor/libghostty-vt/src/benchmark/PageCompression.zig index 21153659..23ecf0bf 100644 --- a/vendor/libghostty-vt/src/benchmark/PageCompression.zig +++ b/vendor/libghostty-vt/src/benchmark/PageCompression.zig @@ -67,6 +67,8 @@ const options = @import("options.zig"); const compress = @import("../terminal/compress.zig"); const CompressedPage = compress.Page; const lz4 = compress.lz4; +const compat_file = @import("../lib/compat/file.zig"); +const global = @import("../global.zig"); const log = std.log.scoped(.@"page-compression-bench"); @@ -210,9 +212,9 @@ fn setupData(self: *PageCompression) !void { return error.InvalidRetainedPages; const data_file = try options.dataFile(self.opts.data) orelse return; - defer data_file.close(); + defer data_file.close(global.io()); - self.data = try data_file.readToEndAlloc(self.alloc, max_data_size); + self.data = try compat_file.readToEndAlloc(data_file, self.alloc, max_data_size); errdefer { self.alloc.free(self.data); self.data = &.{}; diff --git a/vendor/libghostty-vt/src/benchmark/ScreenClone.zig b/vendor/libghostty-vt/src/benchmark/ScreenClone.zig index 5176ce26..9b2012cc 100644 --- a/vendor/libghostty-vt/src/benchmark/ScreenClone.zig +++ b/vendor/libghostty-vt/src/benchmark/ScreenClone.zig @@ -11,6 +11,7 @@ const terminalpkg = @import("../terminal/main.zig"); const Benchmark = @import("Benchmark.zig"); const options = @import("options.zig"); const Terminal = terminalpkg.Terminal; +const global = @import("../global.zig"); const log = std.log.scoped(.@"terminal-stream-bench"); @@ -79,7 +80,7 @@ pub fn create( ptr.* = .{ .opts = opts, - .terminal = try .init(alloc, .{ + .terminal = try .init(global.io(), alloc, .{ .rows = opts.@"terminal-rows", .cols = opts.@"terminal-cols", }), @@ -122,7 +123,7 @@ fn setup(ptr: *anyopaque) Benchmark.Error!void { s.nextSlice("hello"); // Setup our terminal state - const data_f: std.fs.File = (options.dataFile( + const data_f: std.Io.File = (options.dataFile( self.opts.data, ) catch |err| { log.warn("error opening data file err={}", .{err}); @@ -133,7 +134,7 @@ fn setup(ptr: *anyopaque) Benchmark.Error!void { defer stream.deinit(); var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; - var f_reader = data_f.reader(&read_buf); + var f_reader = data_f.reader(global.io(), &read_buf); const r = &f_reader.interface; var buf: [4096]u8 = undefined; @@ -171,6 +172,7 @@ fn stepClone(ptr: *anyopaque) Benchmark.Error!void { for (0..1000) |_| { const s: *terminalpkg.Screen = self.terminal.screens.active; const copy = s.clone( + s.io, s.alloc, .{ .viewport = .{} }, null, diff --git a/vendor/libghostty-vt/src/benchmark/ScrollbackCompression.zig b/vendor/libghostty-vt/src/benchmark/ScrollbackCompression.zig index 40ec20f4..d971c551 100644 --- a/vendor/libghostty-vt/src/benchmark/ScrollbackCompression.zig +++ b/vendor/libghostty-vt/src/benchmark/ScrollbackCompression.zig @@ -74,6 +74,7 @@ const Benchmark = @import("Benchmark.zig"); const options = @import("options.zig"); const PageList = terminalpkg.PageList; const Terminal = terminalpkg.Terminal; +const global = @import("../global.zig"); const log = std.log.scoped(.@"scrollback-compression-bench"); @@ -134,10 +135,10 @@ pub fn create( ptr.* = .{ .opts = opts, - .terminal = try .init(alloc, .{ + .terminal = try .init(global.io(), alloc, .{ .rows = opts.@"terminal-rows", .cols = opts.@"terminal-cols", - .max_scrollback = opts.@"max-scrollback", + .max_scrollback_bytes = opts.@"max-scrollback", }), }; return ptr; @@ -182,13 +183,13 @@ fn setup(ptr: *anyopaque) Benchmark.Error!void { /// terminal-stream benchmark. Parser and file IO costs remain in setup. fn loadCorpus(self: *ScrollbackCompression) !void { const data_file = try options.dataFile(self.opts.data) orelse return; - defer data_file.close(); + defer data_file.close(global.io()); var stream = self.terminal.vtStream(); defer stream.deinit(); var read_buf: [64 * 1024]u8 align(std.atomic.cache_line) = undefined; - var file_reader = data_file.reader(&read_buf); + var file_reader = data_file.reader(global.io(), &read_buf); const reader = &file_reader.interface; var buf: [64 * 1024]u8 = undefined; diff --git a/vendor/libghostty-vt/src/benchmark/TerminalFormatter.zig b/vendor/libghostty-vt/src/benchmark/TerminalFormatter.zig new file mode 100644 index 00000000..fb763ab5 --- /dev/null +++ b/vendor/libghostty-vt/src/benchmark/TerminalFormatter.zig @@ -0,0 +1,482 @@ +//! Benchmarks the terminal formatter (`terminal/formatter.zig`). +//! +//! The formatter is the hot path for clipboard copy (plain/VT/HTML), +//! `write_screen_file`, `selectionString`, terminal search window +//! encoding, and the libghostty-vt formatter C API. This benchmark +//! measures formatting terminal contents that were built during setup +//! (outside the timed region) from a pre-generated VT stream. +//! +//! ## Input +//! +//! `--data` names a pre-generated VT byte stream (for example from +//! `ghostty-gen styled`). The stream is fed to a terminal of the +//! requested dimensions with unlimited scrollback during setup. The +//! resulting screen contents (scrollback included) are what each step +//! formats. +//! +//! ## Modes +//! +//! * `noop` performs no formatting and establishes loop/setup overhead. +//! Subtract this from `format` timings when using hyperfine. +//! * `format` formats the configured region once per loop into a +//! reusable buffer. Buffer growth happens on the first iteration only. +//! * `report` formats once and prints content/output sizes. It is for +//! computing throughput (cells/s, bytes/s), not timing comparisons. +//! +//! ## Examples +//! +//! Build benchmarks in ReleaseFast mode: +//! +//! zig build -Demit-bench -Doptimize=ReleaseFast -Demit-macos-app=false +//! +//! Generate a deterministic corpus, then measure: +//! +//! ghostty-gen styled --seed=42 | head -c 640000 > /tmp/plain.vt +//! hyperfine --warmup 3 \ +//! 'ghostty-bench +terminal-formatter --mode=noop --data=/tmp/plain.vt' \ +//! 'ghostty-bench +terminal-formatter --emit=plain --loops=50 --data=/tmp/plain.vt' \ +//! 'ghostty-bench +terminal-formatter --emit=vt --loops=50 --data=/tmp/plain.vt' +const TerminalFormatter = @This(); + +const std = @import("std"); +const assert = std.debug.assert; +const Allocator = std.mem.Allocator; +const terminalpkg = @import("../terminal/main.zig"); +const formatterpkg = terminalpkg.formatter; +const Benchmark = @import("Benchmark.zig"); +const options = @import("options.zig"); +const Terminal = terminalpkg.Terminal; +const Selection = terminalpkg.Selection; +const global = @import("../global.zig"); + +const log = std.log.scoped(.@"terminal-formatter-bench"); + +alloc: Allocator, +opts: Options, +terminal: ?Terminal = null, + +/// Reused across steps so buffer growth is a one-time setup cost. +output: std.Io.Writer.Allocating, + +/// Reused pin map storage for `--pin-map=true`. +pins: formatterpkg.PinMap.Map = .empty, + +pub const Options = struct { + /// Set by the shared CLI parser for string option ownership. + _arena: ?std.heap.ArenaAllocator = null, + + /// Select the operation performed inside the timed benchmark step. + mode: Mode = .format, + + /// The output format to emit. + emit: Emit = .vt, + + /// The region of the screen to format. + region: Region = .screen, + + /// Unwrap soft-wrapped lines. + unwrap: bool = false, + + /// Track the source pin of every emitted byte. This exercises the + /// (documented as expensive) pin_map path used by selectionString + /// and search. + @"pin-map": bool = false, + + /// Number of format operations per benchmark step. Increase this + /// when the content is too small for stable hyperfine measurements. + loops: u32 = 25, + + /// The size of the terminal. This affects wrapping and page sizes. + @"terminal-rows": u16 = 24, + @"terminal-cols": u16 = 80, + + /// Pre-generated VT stream fed to the terminal during setup. `-` + /// reads stdin, although a regular file is recommended so identical + /// state can be reused across runs. When unset, the terminal is + /// empty. + data: ?[]const u8 = null, + + pub fn deinit(self: *Options) void { + if (self._arena) |arena| arena.deinit(); + self.* = undefined; + } +}; + +pub const Mode = enum { + /// Establish the benchmark loop and setup overhead. + noop, + + /// Format the configured region once per loop. + format, + + /// Print content and output sizes. Not a timing benchmark. + report, + + /// Semantic verification, not a timing benchmark: format the + /// terminal (must be `--emit=vt`), feed the output into a fresh + /// terminal of the same dimensions, format that, and verify the + /// two outputs converge to identical bytes. This proves the VT + /// output faithfully reconstructs the terminal content even when + /// the exact byte encoding changes. + roundtrip, +}; + +pub const Emit = enum { + plain, + vt, + html, + + fn format(self: Emit) formatterpkg.Format { + return switch (self) { + .plain => .plain, + .vt => .vt, + .html => .html, + }; + } +}; + +pub const Region = enum { + /// Everything: scrollback and active screen. + screen, + + /// Only the active screen (bottom rows). + active, + + /// Only the scrollback. + history, +}; + +pub fn create( + alloc: Allocator, + opts: Options, +) !*TerminalFormatter { + const ptr = try alloc.create(TerminalFormatter); + errdefer alloc.destroy(ptr); + ptr.* = .{ + .alloc = alloc, + .opts = opts, + .output = .init(alloc), + }; + return ptr; +} + +pub fn destroy(self: *TerminalFormatter, alloc: Allocator) void { + if (self.terminal) |*t| t.deinit(self.alloc); + self.output.deinit(); + self.pins.deinit(self.alloc); + alloc.destroy(self); +} + +pub fn benchmark(self: *TerminalFormatter) Benchmark { + return .init(self, .{ + .stepFn = switch (self.opts.mode) { + .noop => stepNoop, + .format => stepFormat, + .report => stepReport, + .roundtrip => stepRoundtrip, + }, + .setupFn = setup, + .teardownFn = teardown, + }); +} + +/// Build the terminal state every mode shares. All of this is outside +/// the timed region for `Benchmark`, but is included in whole-process +/// timings, hence the `noop` mode. +fn setup(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalFormatter = @ptrCast(@alignCast(ptr)); + self.setupImpl() catch |err| { + log.warn("failed to prepare formatter benchmark err={}", .{err}); + return error.BenchmarkFailed; + }; +} + +fn setupImpl(self: *TerminalFormatter) !void { + if (self.terminal) |*t| t.deinit(self.alloc); + self.terminal = null; + self.terminal = try Terminal.init(global.io(), self.alloc, .{ + .cols = self.opts.@"terminal-cols", + .rows = self.opts.@"terminal-rows", + .max_scrollback_bytes = null, + .max_scrollback_lines = null, + }); + const terminal = &self.terminal.?; + + // Feed the input corpus through the standard VT stream. + if (try options.dataFile(self.opts.data)) |data_f| { + defer data_f.close(global.io()); + + var stream = terminal.vtStream(); + defer stream.deinit(); + + var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; + var f_reader = data_f.reader(global.io(), &read_buf); + const r = &f_reader.interface; + + var buf: [4096]u8 = undefined; + while (true) { + const n = try r.readSliceShort(&buf); + if (n == 0) break; // EOF reached + stream.nextSlice(buf[0..n]); + } + } +} + +fn teardown(ptr: *anyopaque) void { + const self: *TerminalFormatter = @ptrCast(@alignCast(ptr)); + if (self.terminal) |*t| t.deinit(self.alloc); + self.terminal = null; + self.output.shrinkRetainingCapacity(0); + self.pins.clearRetainingCapacity(); +} + +/// Build the screen formatter matching our options. This mirrors how +/// Surface clipboard copy and write_screen_file construct formatters. +fn formatter(self: *TerminalFormatter) ?formatterpkg.ScreenFormatter { + const screen = self.terminal.?.screens.active; + + var f: formatterpkg.ScreenFormatter = .init(screen, .{ + .emit = self.opts.emit.format(), + .unwrap = self.opts.unwrap, + }); + + f.content = switch (self.opts.region) { + .screen => .{ .selection = null }, + + inline .active, .history => |region| content: { + const tag: terminalpkg.point.Tag = switch (region) { + .active => .active, + .history => .history, + .screen => unreachable, + }; + const tl = screen.pages.getTopLeft(tag); + const br = screen.pages.getBottomRight(tag) orelse return null; + break :content .{ .selection = Selection.init(tl, br, false) }; + }, + }; + + return f; +} + +fn stepNoop(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalFormatter = @ptrCast(@alignCast(ptr)); + for (0..self.opts.loops) |_| { + std.mem.doNotOptimizeAway(self.output.written()); + } +} + +fn stepFormat(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalFormatter = @ptrCast(@alignCast(ptr)); + for (0..self.opts.loops) |_| { + self.output.shrinkRetainingCapacity(0); + + var f = self.formatter() orelse continue; + if (self.opts.@"pin-map") { + self.pins.clearRetainingCapacity(); + f.pin_map = .{ .alloc = self.alloc, .map = &self.pins }; + } + + f.format(&self.output.writer) catch |err| { + log.warn("formatting failed err={}", .{err}); + return error.BenchmarkFailed; + }; + std.mem.doNotOptimizeAway(self.output.written()); + } +} + +/// Print the content dimensions and emitted output size. This shares +/// the formatting code with format mode but deliberately makes no +/// timing claims. Use it to compute cells/s and bytes/s from timings. +fn stepReport(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalFormatter = @ptrCast(@alignCast(ptr)); + + self.output.shrinkRetainingCapacity(0); + if (self.formatter()) |f_init| { + var f = f_init; + if (self.opts.@"pin-map") { + self.pins.clearRetainingCapacity(); + f.pin_map = .{ .alloc = self.alloc, .map = &self.pins }; + } + f.format(&self.output.writer) catch |err| { + log.warn("formatting failed err={}", .{err}); + return error.BenchmarkFailed; + }; + } + + // Count the total pages and rows in the pagelist. + const screen = self.terminal.?.screens.active; + var pages: usize = 0; + var rows: usize = 0; + { + var node = screen.pages.pages.first; + while (node) |n| : (node = n.next) { + pages += 1; + rows += n.page().size.rows; + } + } + + // Hash the output (and the pin coordinates, which are stable across + // runs unlike the node pointers) so different implementations can be + // checked for identical output. + const out_hash = std.hash.Wyhash.hash(0, self.output.written()); + var pin_hasher = std.hash.Wyhash.init(0); + for (self.pins.points.items) |coord| { + const x: u16 = coord.x; + const y: u16 = @intCast(coord.y); + pin_hasher.update(std.mem.asBytes(&x)); + pin_hasher.update(std.mem.asBytes(&y)); + } + + std.debug.print( + "terminal-formatter emit={s} region={s} pages={d} rows={d} " ++ + "cols={d} cells={d} out_bytes={d} pin_bytes={d} " ++ + "out_hash={x} pin_hash={x}\n", + .{ + @tagName(self.opts.emit), + @tagName(self.opts.region), + pages, + rows, + self.opts.@"terminal-cols", + rows * self.opts.@"terminal-cols", + self.output.written().len, + self.pins.count(), + out_hash, + pin_hasher.final(), + }, + ); + + // Pin map storage details on a separate line so the main report + // line remains comparable across implementations. + if (self.opts.@"pin-map") { + std.debug.print( + "terminal-formatter-pins points={d} nodes={d}\n", + .{ self.pins.points.items.len, self.pins.nodes.items.len }, + ); + } +} + +fn stepRoundtrip(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalFormatter = @ptrCast(@alignCast(ptr)); + self.stepRoundtripImpl() catch |err| { + log.warn("roundtrip failed err={}", .{err}); + return error.BenchmarkFailed; + }; +} + +/// Format the terminal, replay the output into a fresh terminal of the +/// same dimensions, format that, and require both outputs to be +/// identical. This verifies that the emitted VT sequences faithfully +/// reconstruct the terminal contents (text, styles, wrapping) without +/// requiring any specific byte encoding of the first output. +fn stepRoundtripImpl(self: *TerminalFormatter) !void { + // Format the original terminal. + self.output.shrinkRetainingCapacity(0); + if (self.formatter()) |f_init| { + var f = f_init; + try f.format(&self.output.writer); + } + const first = self.output.written(); + + // Replay into a fresh terminal. + var t2 = try Terminal.init(global.io(), self.alloc, .{ + .cols = self.opts.@"terminal-cols", + .rows = self.opts.@"terminal-rows", + .max_scrollback_bytes = null, + .max_scrollback_lines = null, + }); + defer t2.deinit(self.alloc); + { + var stream = t2.vtStream(); + defer stream.deinit(); + stream.nextSlice(first); + } + + // Format the replayed terminal identically. + var out2: std.Io.Writer.Allocating = .init(self.alloc); + defer out2.deinit(); + var f2: formatterpkg.ScreenFormatter = .init(t2.screens.active, .{ + .emit = self.opts.emit.format(), + .unwrap = self.opts.unwrap, + }); + try f2.format(&out2.writer); + const second = out2.written(); + + const equal = std.mem.eql(u8, first, second); + std.debug.print( + "terminal-formatter roundtrip emit={s} bytes={d} replay_bytes={d} equal={}\n", + .{ @tagName(self.opts.emit), first.len, second.len, equal }, + ); + + if (!equal) { + // Find the first differing offset to ease debugging. + const n = @min(first.len, second.len); + var i: usize = 0; + while (i < n and first[i] == second[i]) i += 1; + std.debug.print( + "terminal-formatter roundtrip mismatch offset={d} " ++ + "first={f} second={f}\n", + .{ + i, + std.zig.fmtString(first[i -| 32..@min(first.len, i + 32)]), + std.zig.fmtString(second[i -| 32..@min(second.len, i + 32)]), + }, + ); + return error.RoundtripMismatch; + } +} + +test TerminalFormatter { + const testing = std.testing; + const impl: *TerminalFormatter = try .create(testing.allocator, .{}); + defer impl.destroy(testing.allocator); + + const bench = impl.benchmark(); + _ = try bench.run(.once); +} + +test "TerminalFormatter roundtrip" { + const testing = std.testing; + const impl: *TerminalFormatter = try .create(testing.allocator, .{ + .mode = .roundtrip, + .@"terminal-rows" = 4, + .@"terminal-cols" = 8, + }); + defer impl.destroy(testing.allocator); + + const bench = impl.benchmark(); + _ = try bench.run(.once); +} + +test "TerminalFormatter formats all emit formats and regions" { + const testing = std.testing; + + inline for (.{ Emit.plain, Emit.vt, Emit.html }) |emit| { + inline for (.{ Region.screen, Region.active, Region.history }) |region| { + const impl: *TerminalFormatter = try .create(testing.allocator, .{ + .emit = emit, + .region = region, + .loops = 1, + .@"terminal-rows" = 4, + .@"terminal-cols" = 8, + }); + defer impl.destroy(testing.allocator); + + const bench = impl.benchmark(); + _ = try bench.run(.once); + } + } +} + +test "TerminalFormatter pin map" { + const testing = std.testing; + const impl: *TerminalFormatter = try .create(testing.allocator, .{ + .@"pin-map" = true, + .loops = 1, + .@"terminal-rows" = 4, + .@"terminal-cols" = 8, + }); + defer impl.destroy(testing.allocator); + + const bench = impl.benchmark(); + _ = try bench.run(.once); +} diff --git a/vendor/libghostty-vt/src/benchmark/TerminalParser.zig b/vendor/libghostty-vt/src/benchmark/TerminalParser.zig index 78c93312..d393301c 100644 --- a/vendor/libghostty-vt/src/benchmark/TerminalParser.zig +++ b/vendor/libghostty-vt/src/benchmark/TerminalParser.zig @@ -7,13 +7,14 @@ const Allocator = std.mem.Allocator; const terminalpkg = @import("../terminal/main.zig"); const Benchmark = @import("Benchmark.zig"); const options = @import("options.zig"); +const global = @import("../global.zig"); const log = std.log.scoped(.@"terminal-stream-bench"); opts: Options, /// The file, opened in the setup function. -data_f: ?std.fs.File = null, +data_f: ?std.Io.File = null, pub const Options = struct { /// The data to read as a filepath. If this is "-" then @@ -61,7 +62,7 @@ fn setup(ptr: *anyopaque) Benchmark.Error!void { fn teardown(ptr: *anyopaque) void { const self: *TerminalParser = @ptrCast(@alignCast(ptr)); if (self.data_f) |f| { - f.close(); + f.close(global.io()); self.data_f = null; } } @@ -76,7 +77,7 @@ fn step(ptr: *anyopaque) Benchmark.Error!void { // aren't currently IO bound. const f = self.data_f orelse return; var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; - var f_reader = f.reader(&read_buf); + var f_reader = f.reader(global.io(), &read_buf); var r = &f_reader.interface; var p: terminalpkg.Parser = .init(); diff --git a/vendor/libghostty-vt/src/benchmark/TerminalResize.zig b/vendor/libghostty-vt/src/benchmark/TerminalResize.zig new file mode 100644 index 00000000..61b908c8 --- /dev/null +++ b/vendor/libghostty-vt/src/benchmark/TerminalResize.zig @@ -0,0 +1,357 @@ +//! This benchmark tests the performance of Terminal.resize, with a +//! primary focus on column resizes that reflow soft-wrapped text. +//! Resize happens on the IO thread while holding the terminal lock, +//! so a slow resize directly translates into dropped input and a +//! frozen-feeling UI while the user drags the window edge (which +//! produces a rapid stream of resizes). +//! +//! The terminal is populated once during setup (synthetic fill and/or +//! a data file replayed through the VT stream) and then each step +//! ping-pongs the terminal between two sizes. A full cycle returns the +//! terminal to its original dimensions so the state reaches a steady +//! state after the first cycle and every iteration performs +//! equivalent work. +const TerminalResize = @This(); + +const std = @import("std"); +const assert = std.debug.assert; +const Allocator = std.mem.Allocator; +const terminalpkg = @import("../terminal/main.zig"); +const Benchmark = @import("Benchmark.zig"); +const options = @import("options.zig"); +const Terminal = terminalpkg.Terminal; +const global = @import("../global.zig"); + +const log = std.log.scoped(.@"terminal-resize-bench"); + +opts: Options, +alloc: Allocator, +terminal: Terminal, + +pub const Options = struct { + /// The resize pattern to benchmark. See Mode. + mode: Mode = .cols, + + /// Multiplier on the number of resize cycles each step runs. This + /// is useful to make a benchmark run long enough for profiling. + loops: u32 = 1, + + /// The initial size of the terminal. This is also the size that + /// every resize cycle returns to. + @"terminal-rows": u16 = 80, + @"terminal-cols": u16 = 120, + + /// The dimensions to resize to for the cols/rows/both modes. If + /// unset, they default to half of the respective terminal + /// dimension, which forces every soft-wrapped line to rewrap. + @"resize-cols": ?u16 = null, + @"resize-rows": ?u16 = null, + + /// The number of synthetic lines written to the terminal during + /// setup. The content is deterministic: a mix of short lines, + /// soft-wrapped long lines, blank lines, styled cells, and wide + /// characters, since all of these hit different reflow paths. + /// Set to 0 to only use `data`. + @"fill-lines": u32 = 10_000, + + /// The maximum scrollback size in bytes. Defaults to the Ghostty + /// application default. Reflow cost scales with the amount of + /// scrollback, not just the visible screen. + @"scrollback-bytes": usize = 50_000_000, + + /// The data to read as a filepath. If this is "-" then + /// we will read stdin. If this is unset, only the synthetic fill + /// is used. The data is streamed into the terminal during setup + /// (not part of the benchmark) to build the screen contents that + /// get resized. + data: ?[]const u8 = null, +}; + +pub const Mode = enum { + /// Resize to the current dimensions. This measures the early-exit + /// path (mode updates, pixel geometry) and acts as a baseline. + noop, + + /// Alternate the column count between `terminal-cols` and + /// `resize-cols`. With wraparound enabled (the default), this + /// reflows text in both directions: shrinking wraps long lines + /// and growing unwraps them. This is the primary reflow benchmark. + cols, + + /// Like `cols`, but with wraparound mode disabled so the resize + /// does not reflow. Useful as a baseline to isolate the cost of + /// reflow itself from the rest of the resize. + @"cols-no-reflow", + + /// Alternate the row count between `terminal-rows` and + /// `resize-rows`. Column count is unchanged so no text reflows; + /// this measures growing/trimming rows against scrollback. + rows, + + /// Alternate both dimensions at once, like a diagonal window drag. + both, +}; + +pub fn create( + alloc: Allocator, + opts: Options, +) !*TerminalResize { + const ptr = try alloc.create(TerminalResize); + errdefer alloc.destroy(ptr); + + ptr.* = .{ + .opts = opts, + .alloc = alloc, + .terminal = try .init(global.io(), alloc, .{ + .rows = opts.@"terminal-rows", + .cols = opts.@"terminal-cols", + .max_scrollback_bytes = opts.@"scrollback-bytes", + }), + }; + + return ptr; +} + +pub fn destroy(self: *TerminalResize, alloc: Allocator) void { + self.terminal.deinit(alloc); + alloc.destroy(self); +} + +pub fn benchmark(self: *TerminalResize) Benchmark { + return .init(self, .{ + .stepFn = switch (self.opts.mode) { + .noop => stepNoop, + .cols, .@"cols-no-reflow" => stepCols, + .rows => stepRows, + .both => stepBoth, + }, + .setupFn = setup, + }); +} + +/// The column count used by the cols/both modes. +fn targetCols(self: *const TerminalResize) u16 { + return self.opts.@"resize-cols" orelse + @max(1, self.opts.@"terminal-cols" / 2); +} + +/// The row count used by the rows/both modes. +fn targetRows(self: *const TerminalResize) u16 { + return self.opts.@"resize-rows" orelse + @max(1, self.opts.@"terminal-rows" / 2); +} + +fn setup(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalResize = @ptrCast(@alignCast(ptr)); + + // Always reset our terminal state. Note this doesn't resize, but + // create initializes (and steps return) the terminal to the + // requested dimensions so we're always at terminal-rows/cols here. + self.terminal.fullReset(); + assert(self.terminal.cols == self.opts.@"terminal-cols"); + assert(self.terminal.rows == self.opts.@"terminal-rows"); + + // Fill with synthetic content first, then replay the data file on + // top if given. Both go through the VT stream so soft wraps, + // styles, etc. are all set exactly as they would be in a real + // session. + self.fill(); + try self.replayData(); + + // Reflow only happens when wraparound mode is set (it is by + // default). We only disable it after filling so the fill itself + // still soft-wraps identically in every mode. + if (self.opts.mode == .@"cols-no-reflow") { + self.terminal.modes.set(.wraparound, false); + } +} + +/// Write deterministic synthetic content to the terminal. The goal is +/// content that is representative of a real session so that reflow +/// touches its interesting paths: soft-wrapped lines (must rewrap), +/// short lines (copied as-is), blank lines, styled cells (styles must +/// be moved across pages), and wide characters (can't be split at the +/// wrap column). +fn fill(self: *TerminalResize) void { + if (self.opts.@"fill-lines" == 0) return; + + var s = self.terminal.vtStream(); + defer s.deinit(); + + var prng: std.Random.DefaultPrng = .init(0xB3); + const rand = prng.random(); + + const cols: usize = self.terminal.cols; + var line_buf: [8192]u8 = undefined; + + for (0..self.opts.@"fill-lines") |i| { + // Periodically toggle a background style so reflow has to + // carry styled cells into new pages. + if (i % 64 == 0) s.nextSlice("\x1b[48;2;20;40;60m"); + if (i % 64 == 32) s.nextSlice("\x1b[m"); + + // A small portion of lines are blank. + if (i % 16 == 15) { + s.nextSlice("\r\n"); + continue; + } + + // Line lengths between ~25% and ~250% of the terminal width + // so we get a mix of short lines and soft-wrapped lines. + const min = @max(1, cols / 4); + const max = @min(line_buf.len, cols * 5 / 2); + const len = min + rand.uintLessThan(usize, max - min); + + var j: usize = 0; + while (j < len) { + // Sprinkle wide characters into every 8th line. + if (i % 8 == 7 and j % 16 == 8 and j + 3 <= len) { + line_buf[j..][0..3].* = "漢".*; + j += 3; + continue; + } + + // Words of ASCII separated by spaces. + line_buf[j] = if (j % 8 == 7) + ' ' + else + rand.intRangeAtMost(u8, 'a', 'z'); + j += 1; + } + + s.nextSlice(line_buf[0..len]); + s.nextSlice("\r\n"); + } +} + +/// Stream the data file (if any) into the terminal. +fn replayData(self: *TerminalResize) Benchmark.Error!void { + const data_f: std.Io.File = (options.dataFile( + self.opts.data, + ) catch |err| { + log.warn("error opening data file err={}", .{err}); + return error.BenchmarkFailed; + }) orelse return; + defer data_f.close(global.io()); + + var stream = self.terminal.vtStream(); + defer stream.deinit(); + + var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; + var f_reader = data_f.reader(global.io(), &read_buf); + const r = &f_reader.interface; + + var buf: [4096]u8 = undefined; + while (true) { + const n = r.readSliceShort(&buf) catch { + log.warn("error reading data file err={?}", .{f_reader.err}); + return error.BenchmarkFailed; + }; + if (n == 0) break; // EOF reached + stream.nextSlice(buf[0..n]); + } +} + +fn resizeTerminal( + self: *TerminalResize, + cols: u16, + rows: u16, +) Benchmark.Error!void { + self.terminal.resize(self.alloc, .{ + .cols = cols, + .rows = rows, + // Realistic cell pixel geometry: real apprt resizes always + // carry it, and it exercises the pixel dimension updates. + .cell_size_px = .{ .width = 10, .height = 20 }, + }) catch |err| { + log.warn("error resizing terminal err={}", .{err}); + return error.BenchmarkFailed; + }; + std.mem.doNotOptimizeAway(&self.terminal); +} + +fn stepNoop(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalResize = @ptrCast(@alignCast(ptr)); + + const cols = self.opts.@"terminal-cols"; + const rows = self.opts.@"terminal-rows"; + + // We loop because it's so fast (a few ns) that a single resize + // doesn't properly capture our speeds. + for (0..50_000_000 * @as(u64, self.opts.loops)) |_| { + try self.resizeTerminal(cols, rows); + } +} + +fn stepCols(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalResize = @ptrCast(@alignCast(ptr)); + + const cols = self.opts.@"terminal-cols"; + const rows = self.opts.@"terminal-rows"; + const target = self.targetCols(); + + // Per-cycle cost differs by orders of magnitude between the two + // modes (a reflow resize walks the entire scrollback; a non-reflow + // resize doesn't), so pick a cycle count that makes each run long + // enough to measure well above process startup and setup cost. + const cycles: u64 = switch (self.opts.mode) { + .cols => 25, + .@"cols-no-reflow" => 1_500, + else => unreachable, + }; + + // Each cycle shrinks (rewrapping long lines) and grows back + // (unwrapping them), ending at the original size. + for (0..cycles * @as(u64, self.opts.loops)) |_| { + try self.resizeTerminal(target, rows); + try self.resizeTerminal(cols, rows); + } +} + +fn stepRows(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalResize = @ptrCast(@alignCast(ptr)); + + const cols = self.opts.@"terminal-cols"; + const rows = self.opts.@"terminal-rows"; + const target = self.targetRows(); + + // Row-only resizes don't reflow so they're much cheaper (tens of + // ns); loop a lot more so the measurement isn't dominated by + // process overhead. + for (0..2_500_000 * @as(u64, self.opts.loops)) |_| { + try self.resizeTerminal(cols, target); + try self.resizeTerminal(cols, rows); + } +} + +fn stepBoth(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalResize = @ptrCast(@alignCast(ptr)); + + const cols = self.opts.@"terminal-cols"; + const rows = self.opts.@"terminal-rows"; + const target_cols = self.targetCols(); + const target_rows = self.targetRows(); + + for (0..25 * @as(u64, self.opts.loops)) |_| { + try self.resizeTerminal(target_cols, target_rows); + try self.resizeTerminal(cols, rows); + } +} + +test TerminalResize { + const testing = std.testing; + const alloc = testing.allocator; + + // Small dimensions and fill so this is fast in debug builds while + // still exercising real reflow in both directions. + const impl: *TerminalResize = try .create(alloc, .{ + .mode = .cols, + .@"terminal-rows" = 10, + .@"terminal-cols" = 20, + .@"fill-lines" = 50, + }); + defer impl.destroy(alloc); + + const bench = impl.benchmark(); + _ = try bench.run(.once); +} diff --git a/vendor/libghostty-vt/src/benchmark/TerminalSnapshot.zig b/vendor/libghostty-vt/src/benchmark/TerminalSnapshot.zig new file mode 100644 index 00000000..aea5e1f9 --- /dev/null +++ b/vendor/libghostty-vt/src/benchmark/TerminalSnapshot.zig @@ -0,0 +1,350 @@ +//! Benchmarks the terminal binary snapshot codecs (`terminal/snapshot`). +//! +//! Encoding and decoding a snapshot are the hot paths for terminal +//! persistence and handoff, so both directions are measured against the +//! same terminal state. +//! +//! ## Input +//! +//! `--data` names a pre-generated VT byte stream (for example from +//! `ghostty-gen ascii`). The stream is fed to a terminal of the requested +//! dimensions during setup, outside the timed region. The resulting screen +//! and scrollback contents are what each step encodes or decodes. +//! +//! ## Modes +//! +//! * `noop` performs no codec work and establishes loop overhead. +//! * `encode` encodes one complete snapshot per loop into a reusable +//! buffer. Buffer growth happens on the first iteration only. +//! * `decode` restores one complete snapshot per loop from bytes prepared +//! during setup. The restored terminal is destroyed inside the step, so +//! this measures the complete restore lifecycle. +//! * `decode-ready` restores only the renderable prefix per loop using the +//! incremental decoder and stops at READY, skipping history. Compared +//! against `decode`, this is the time-to-interactive win of applying +//! history off the critical path. +//! * `report` encodes once and prints total and per-record-tag sizes. It +//! is for inspecting the wire shape, not timing comparisons. +//! +//! ## Examples +//! +//! Build benchmarks in ReleaseFast mode: +//! +//! zig build -Demit-bench -Doptimize=ReleaseFast -Demit-macos-app=false +//! +//! Generate a deterministic corpus, then measure both directions: +//! +//! ghostty-gen ascii | head -c 1000000 > /tmp/ascii.vt +//! hyperfine --warmup 3 \ +//! 'ghostty-bench +terminal-snapshot --mode=encode --loops=20 --data=/tmp/ascii.vt' \ +//! 'ghostty-bench +terminal-snapshot --mode=decode --loops=20 --data=/tmp/ascii.vt' +const TerminalSnapshot = @This(); + +const std = @import("std"); +const assert = std.debug.assert; +const Allocator = std.mem.Allocator; +const terminalpkg = @import("../terminal/main.zig"); +const snapshot = terminalpkg.snapshot; +const Benchmark = @import("Benchmark.zig"); +const options = @import("options.zig"); +const Terminal = terminalpkg.Terminal; +const global = @import("../global.zig"); + +const log = std.log.scoped(.@"terminal-snapshot-bench"); + +alloc: Allocator, +opts: Options, +terminal: ?Terminal = null, + +/// Reused across encode steps so buffer growth is a one-time setup cost. +encoded: std.Io.Writer.Allocating, + +pub const Options = struct { + /// Set by the shared CLI parser for string option ownership. + _arena: ?std.heap.ArenaAllocator = null, + + /// Select the operation performed inside the timed benchmark step. + mode: Mode = .encode, + + /// Number of codec operations per benchmark step. Increase this when + /// the state is too small for stable `hyperfine` measurements. + loops: u32 = 1, + + /// The size of the terminal. This affects wrapping, page sizes, and + /// the amount of state per encoded page. + @"terminal-rows": u16 = 24, + @"terminal-cols": u16 = 80, + + /// Pre-generated VT stream fed to the terminal during setup. `-` reads + /// stdin, although a regular file is recommended so identical state can + /// be reused across runs. When unset, the terminal is empty. + data: ?[]const u8 = null, + + pub fn deinit(self: *Options) void { + if (self._arena) |arena| arena.deinit(); + self.* = undefined; + } +}; + +pub const Mode = enum { + /// Establish the benchmark loop overhead. + noop, + + /// Encode one complete snapshot per loop. + encode, + + /// Restore one complete snapshot per loop, including its teardown. + decode, + + /// Restore one renderable READY prefix per loop, including teardown. + @"decode-ready", + + /// Print encoded sizes by record tag. Not a timing benchmark. + report, +}; + +pub fn create( + alloc: Allocator, + opts: Options, +) !*TerminalSnapshot { + const ptr = try alloc.create(TerminalSnapshot); + errdefer alloc.destroy(ptr); + ptr.* = .{ + .alloc = alloc, + .opts = opts, + .encoded = .init(alloc), + }; + return ptr; +} + +pub fn destroy(self: *TerminalSnapshot, alloc: Allocator) void { + if (self.terminal) |*t| t.deinit(self.alloc); + self.encoded.deinit(); + alloc.destroy(self); +} + +pub fn benchmark(self: *TerminalSnapshot) Benchmark { + return .init(self, .{ + .stepFn = switch (self.opts.mode) { + .noop => stepNoop, + .encode => stepEncode, + .decode => stepDecode, + .@"decode-ready" => stepDecodeReady, + .report => stepReport, + }, + .setupFn = setup, + .teardownFn = teardown, + }); +} + +/// Build the terminal state every mode shares and, for decode mode, the +/// encoded snapshot it restores. All of this is outside the timed region. +fn setup(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalSnapshot = @ptrCast(@alignCast(ptr)); + self.setupImpl() catch |err| { + log.warn("failed to prepare snapshot benchmark err={}", .{err}); + return error.BenchmarkFailed; + }; +} + +fn setupImpl(self: *TerminalSnapshot) !void { + if (self.terminal) |*t| t.deinit(self.alloc); + self.terminal = null; + self.terminal = try Terminal.init(global.io(), self.alloc, .{ + .cols = self.opts.@"terminal-cols", + .rows = self.opts.@"terminal-rows", + .max_scrollback_bytes = null, + .max_scrollback_lines = null, + }); + const terminal = &self.terminal.?; + + // Feed the input corpus through the standard VT stream. + if (try options.dataFile(self.opts.data)) |data_f| { + defer data_f.close(global.io()); + + var stream = terminal.vtStream(); + defer stream.deinit(); + + var read_buf: [4096]u8 align(std.atomic.cache_line) = undefined; + var f_reader = data_f.reader(global.io(), &read_buf); + const r = &f_reader.interface; + + var buf: [4096]u8 = undefined; + while (true) { + const n = try r.readSliceShort(&buf); + if (n == 0) break; // EOF reached + stream.nextSlice(buf[0..n]); + } + } + + // Decode restores the same bytes every step. Encode mode also uses + // this buffer, in which case this is its one-time growth. + self.encoded.shrinkRetainingCapacity(0); + try snapshot.encode( + self.alloc, + &self.encoded.writer, + terminal, + .{ .continuation = .ground }, + ); +} + +fn teardown(ptr: *anyopaque) void { + const self: *TerminalSnapshot = @ptrCast(@alignCast(ptr)); + if (self.terminal) |*t| t.deinit(self.alloc); + self.terminal = null; + self.encoded.shrinkRetainingCapacity(0); +} + +fn stepNoop(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalSnapshot = @ptrCast(@alignCast(ptr)); + for (0..self.opts.loops) |_| { + std.mem.doNotOptimizeAway(self.encoded.written()); + } +} + +fn stepEncode(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalSnapshot = @ptrCast(@alignCast(ptr)); + const terminal = &self.terminal.?; + for (0..self.opts.loops) |_| { + self.encoded.shrinkRetainingCapacity(0); + snapshot.encode( + self.alloc, + &self.encoded.writer, + terminal, + .{ .continuation = .ground }, + ) catch |err| { + log.warn("snapshot encoding failed err={}", .{err}); + return error.BenchmarkFailed; + }; + std.mem.doNotOptimizeAway(self.encoded.written()); + } +} + +fn stepDecode(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalSnapshot = @ptrCast(@alignCast(ptr)); + const bytes = self.encoded.written(); + for (0..self.opts.loops) |_| { + var reader: std.Io.Reader = .fixed(bytes); + var decoded = snapshot.decode( + self.alloc, + global.io(), + &reader, + .{ .max_continuation_bytes = 1024 * 1024 }, + ) catch |err| { + log.warn("snapshot decoding failed err={}", .{err}); + return error.BenchmarkFailed; + }; + std.mem.doNotOptimizeAway(&decoded); + decoded.deinit(self.alloc); + } +} + +/// The renderable-prefix half of decode: everything through READY, leaving +/// all history unread. The gap between this and `stepDecode` is the latency +/// class the incremental decoder removes from time-to-interactive. +fn stepDecodeReady(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalSnapshot = @ptrCast(@alignCast(ptr)); + const bytes = self.encoded.written(); + for (0..self.opts.loops) |_| { + var reader: std.Io.Reader = .fixed(bytes); + var decoder: snapshot.Decoder = .init(&reader); + var decoded = decoder.ready( + self.alloc, + global.io(), + .{ .max_continuation_bytes = 1024 * 1024 }, + ) catch |err| { + log.warn("snapshot READY decoding failed err={}", .{err}); + return error.BenchmarkFailed; + }; + std.mem.doNotOptimizeAway(&decoded); + decoded.deinit(self.alloc); + } +} + +/// Print the encoded size grouped by record tag. This shares the encoder +/// with encode mode but deliberately makes no timing claims. +fn stepReport(ptr: *anyopaque) Benchmark.Error!void { + const self: *TerminalSnapshot = @ptrCast(@alignCast(ptr)); + const bytes = self.encoded.written(); + + var payload_totals = std.enums.EnumArray( + snapshot.record.Tag, + u64, + ).initFill(0); + var record_counts = std.enums.EnumArray( + snapshot.record.Tag, + u64, + ).initFill(0); + var record_total: u64 = 0; + + var offset: usize = snapshot.envelope.encoded_len; + while (offset + snapshot.record.Header.len <= bytes.len) { + const tag_raw = std.mem.readInt(u16, bytes[offset..][0..2], .little); + const payload_len = std.mem.readInt( + u32, + bytes[offset + 2 ..][0..4], + .little, + ); + const tag = std.enums.fromInt(snapshot.record.Tag, tag_raw) orelse { + log.warn("unknown record tag {}", .{tag_raw}); + return error.BenchmarkFailed; + }; + payload_totals.getPtr(tag).* += payload_len; + record_counts.getPtr(tag).* += 1; + record_total += 1; + offset += snapshot.record.Header.len + payload_len; + } + + var it = payload_totals.iterator(); + while (it.next()) |entry| { + std.debug.print("terminal-snapshot tag={s} records={d} payload={d}\n", .{ + @tagName(entry.key), + record_counts.get(entry.key), + entry.value.*, + }); + } + std.debug.print( + "terminal-snapshot total records={d} framing={d} encoded={d}\n", + .{ + record_total, + record_total * snapshot.record.Header.len + + snapshot.envelope.encoded_len, + bytes.len, + }, + ); +} + +test TerminalSnapshot { + const testing = std.testing; + const impl: *TerminalSnapshot = try .create(testing.allocator, .{}); + defer impl.destroy(testing.allocator); + + const bench = impl.benchmark(); + _ = try bench.run(.once); +} + +test "TerminalSnapshot decode round trip" { + const testing = std.testing; + const impl: *TerminalSnapshot = try .create(testing.allocator, .{ + .mode = .decode, + .@"terminal-rows" = 4, + .@"terminal-cols" = 8, + }); + defer impl.destroy(testing.allocator); + + const bench = impl.benchmark(); + _ = try bench.run(.once); +} + +test "TerminalSnapshot decode READY prefix" { + const testing = std.testing; + const impl: *TerminalSnapshot = try .create(testing.allocator, .{ + .mode = .@"decode-ready", + .@"terminal-rows" = 4, + .@"terminal-cols" = 8, + }); + defer impl.destroy(testing.allocator); + + const bench = impl.benchmark(); + _ = try bench.run(.once); +} diff --git a/vendor/libghostty-vt/src/benchmark/TerminalStream.zig b/vendor/libghostty-vt/src/benchmark/TerminalStream.zig index a5302005..a16e36e0 100644 --- a/vendor/libghostty-vt/src/benchmark/TerminalStream.zig +++ b/vendor/libghostty-vt/src/benchmark/TerminalStream.zig @@ -19,6 +19,7 @@ const Benchmark = @import("Benchmark.zig"); const options = @import("options.zig"); const Terminal = terminalpkg.Terminal; const Stream = terminalpkg.TerminalStream; +const global = @import("../global.zig"); const log = std.log.scoped(.@"terminal-stream-bench"); @@ -27,7 +28,7 @@ terminal: Terminal, stream: Stream, /// The file, opened in the setup function. -data_f: ?std.fs.File = null, +data_f: ?std.Io.File = null, pub const Options = struct { /// The size of the terminal. This affects benchmarking when @@ -36,7 +37,13 @@ pub const Options = struct { @"terminal-rows": u16 = 80, @"terminal-cols": u16 = 120, - /// The data to read as a filepath. If this is "-" then + /// Enable opt-in continuation tracking on the stream. + @"continuation-enabled": bool = false, + + /// Maximum continuation suffix retained when tracking is enabled. + @"continuation-max-bytes": usize = 1024 * 1024, + + /// Pre-generated data from ghostty-gen. If this is "-" then /// we will read stdin. If this is unset, then we will /// do nothing (benchmark is a noop). It'd be more unixy to /// use stdin by default but I find that a hanging CLI command @@ -54,13 +61,21 @@ pub fn create( ptr.* = .{ .opts = opts, - .terminal = try .init(alloc, .{ + .terminal = try .init(global.io(), alloc, .{ .rows = opts.@"terminal-rows", .cols = opts.@"terminal-cols", }), .stream = undefined, }; - ptr.stream = .initAlloc(alloc, .init(&ptr.terminal)); + errdefer ptr.terminal.deinit(alloc); + ptr.stream = .init(.{ + .allocator = alloc, + .handler = .init(&ptr.terminal), + .continuation_max_bytes = if (opts.@"continuation-enabled") + opts.@"continuation-max-bytes" + else + null, + }); return ptr; } @@ -85,8 +100,8 @@ fn setup(ptr: *anyopaque) Benchmark.Error!void { // Always reset our terminal state self.terminal.fullReset(); - // Open our data file to prepare for reading. We can do more - // validation here eventually. + // Open our data file to prepare for reading. We can do more validation + // here eventually. assert(self.data_f == null); self.data_f = options.dataFile(self.opts.data) catch |err| { log.warn("error opening data file err={}", .{err}); @@ -97,7 +112,7 @@ fn setup(ptr: *anyopaque) Benchmark.Error!void { fn teardown(ptr: *anyopaque) void { const self: *TerminalStream = @ptrCast(@alignCast(ptr)); if (self.data_f) |f| { - f.close(); + f.close(global.io()); self.data_f = null; } } @@ -112,8 +127,10 @@ fn step(ptr: *anyopaque) Benchmark.Error!void { // aren't currently IO bound. const f = self.data_f orelse return; - var read_buf: [64 * 1024]u8 align(std.atomic.cache_line) = undefined; - var f_reader = f.reader(&read_buf); + // Unbuffered: readSliceShort below reads directly into `buf`, + // avoiding a per-chunk memcpy through an intermediate reader + // buffer that would pollute the measurement. + var f_reader = f.reader(global.io(), &.{}); const r = &f_reader.interface; // This buffer size matches the read buffer size used by the @@ -139,4 +156,12 @@ test TerminalStream { const bench = impl.benchmark(); _ = try bench.run(.once); + + const tracked: *TerminalStream = try .create(alloc, .{ + .@"continuation-enabled" = true, + }); + defer tracked.destroy(alloc); + + const tracked_bench = tracked.benchmark(); + _ = try tracked_bench.run(.once); } diff --git a/vendor/libghostty-vt/src/benchmark/cli.zig b/vendor/libghostty-vt/src/benchmark/cli.zig index dc4d7b8f..f76dfc4b 100644 --- a/vendor/libghostty-vt/src/benchmark/cli.zig +++ b/vendor/libghostty-vt/src/benchmark/cli.zig @@ -1,6 +1,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const cli = @import("../cli.zig"); +const global = @import("../global.zig"); /// The available actions for the CLI. This is the list of available /// benchmarks. View docs for each individual one in the predictably @@ -13,7 +14,10 @@ pub const Action = enum { @"page-compression", @"scrollback-compression", @"screen-clone", + @"terminal-formatter", @"terminal-parser", + @"terminal-resize", + @"terminal-snapshot", @"terminal-stream", @"is-symbol", @"osc-parser", @@ -36,7 +40,10 @@ pub const Action = enum { .@"terminal-stream" => @import("TerminalStream.zig"), .@"codepoint-width" => @import("CodepointWidth.zig"), .@"grapheme-break" => @import("GraphemeBreak.zig"), + .@"terminal-formatter" => @import("TerminalFormatter.zig"), .@"terminal-parser" => @import("TerminalParser.zig"), + .@"terminal-resize" => @import("TerminalResize.zig"), + .@"terminal-snapshot" => @import("TerminalSnapshot.zig"), .@"is-symbol" => @import("IsSymbol.zig"), .@"osc-parser" => @import("OscParser.zig"), }; @@ -44,19 +51,20 @@ pub const Action = enum { }; /// An entrypoint for the benchmark CLI. -pub fn main() !void { +pub fn main(minimal: std.process.Init.Minimal) !void { + try global.init(.{ .tool = minimal }); const alloc = std.heap.c_allocator; - const action_ = try cli.action.detectArgs(Action, alloc); + const action_ = try cli.action.detectArgs(Action, alloc, minimal.args); const action = action_ orelse return error.NoAction; - try mainAction(alloc, action, .cli); + try mainAction(alloc, action, .{ .cli = minimal.args }); } /// Arguments that can be passed to the benchmark. pub const Args = union(enum) { /// The arguments passed to the CLI via argc/argv. - cli, + cli: std.process.Args, - /// Simple string arguments, parsed via std.process.ArgIteratorGeneral. + /// Simple string arguments, parsed via ArgIteratorGeneral. string: []const u8, }; @@ -83,13 +91,13 @@ fn mainActionImpl( var opts: Options = .{}; defer if (@hasDecl(Options, "deinit")) opts.deinit(); switch (args) { - .cli => { - var iter = try cli.args.argsIterator(alloc); + .cli => |process_args| { + var iter = try cli.args.argsIterator(alloc, process_args); defer iter.deinit(); try cli.args.parse(Options, alloc, &opts, &iter); }, .string => |str| { - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, str, ); diff --git a/vendor/libghostty-vt/src/benchmark/main.zig b/vendor/libghostty-vt/src/benchmark/main.zig index f22891c7..2c1f31f5 100644 --- a/vendor/libghostty-vt/src/benchmark/main.zig +++ b/vendor/libghostty-vt/src/benchmark/main.zig @@ -6,7 +6,10 @@ pub const CodepointWidth = @import("CodepointWidth.zig"); pub const GraphemeBreak = @import("GraphemeBreak.zig"); pub const HyperlinkMap = @import("HyperlinkMap.zig"); pub const ScreenClone = @import("ScreenClone.zig"); +pub const TerminalFormatter = @import("TerminalFormatter.zig"); pub const TerminalParser = @import("TerminalParser.zig"); +pub const TerminalResize = @import("TerminalResize.zig"); +pub const TerminalSnapshot = @import("TerminalSnapshot.zig"); pub const IsSymbol = @import("IsSymbol.zig"); pub const PageCompression = @import("PageCompression.zig"); pub const ScrollbackCompression = @import("ScrollbackCompression.zig"); diff --git a/vendor/libghostty-vt/src/benchmark/options.zig b/vendor/libghostty-vt/src/benchmark/options.zig index 049e80f4..9322818d 100644 --- a/vendor/libghostty-vt/src/benchmark/options.zig +++ b/vendor/libghostty-vt/src/benchmark/options.zig @@ -1,20 +1,21 @@ //! This file contains helpers for CLI options. const std = @import("std"); +const global = @import("../global.zig"); /// Returns the data file for the given path in a way that is consistent /// across our CLI. If the path is not set then no file is returned. /// If the path is "-", then we will return stdin. If the path is /// a file then we will open and return the handle. -pub fn dataFile(path_: ?[]const u8) !?std.fs.File { +pub fn dataFile(path_: ?[]const u8) !?std.Io.File { const path = path_ orelse return null; // Stdin if (std.mem.eql(u8, path, "-")) return .stdin(); // Normal file - const file = try std.fs.cwd().openFile(path, .{}); - errdefer file.close(); + const file = try std.Io.Dir.cwd().openFile(global.io(), path, .{}); + errdefer file.close(global.io()); return file; } diff --git a/vendor/libghostty-vt/src/build/Config.zig b/vendor/libghostty-vt/src/build/Config.zig index 0a994731..71fa4d28 100644 --- a/vendor/libghostty-vt/src/build/Config.zig +++ b/vendor/libghostty-vt/src/build/Config.zig @@ -43,7 +43,7 @@ lib_version: std.SemanticVersion = .{ .major = 0, .minor = 0, .patch = 0 }, /// Binary properties pie: bool = false, strip: bool = false, -patch_rpath: ?[]const u8 = null, +patchelf: ?PatchElf = null, /// Artifacts flatpak: bool = false, @@ -62,17 +62,30 @@ emit_xcframework: bool = false, emit_webdata: bool = false, emit_unicode_table_gen: bool = false, +/// Feature gates for libghostty-vt artifacts (-Dvt-features). The full +/// Ghostty application ignores this and always enables everything. +vt_features: TerminalBuildOptions.Features = .{}, + /// True when Ghostty is being built as a dependency of another project /// rather than as the root project. is_dep: bool = false, /// Environmental properties -env: std.process.EnvMap, +env: *const std.process.Environ.Map, pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Config { // Setup our standard Zig target and optimize options, i.e. // `-Doptimize` and `-Dtarget`. const optimize = b.standardOptimizeOption(.{}); + + // Default dependency builds to libghostty-vt-only mode. Consumers can + // still explicitly disable this to request the full Ghostty build. + const is_dep = b.dep_prefix.len > 0; + const emit_lib_vt = b.option( + bool, + "emit-lib-vt", + "Set defaults for a libghostty-vt-only build (disables xcframework, macOS app, and docs).", + ) orelse is_dep; const target = target: { var result = b.standardTargetOptions(.{}); @@ -97,19 +110,48 @@ pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Conf result = b.resolveTargetQuery(query); } + // On wasm, default to enabling the simd128 feature. Every + // browser engine has supported it since 2023 or earlier + // (Chrome 91, Firefox 89, Safari 16.4) and it is a large + // performance win for the terminal hot paths (50%+ on + // print-heavy VT streams). Only apply when no explicit CPU + // was requested; targets for exotic non-browser runtimes + // can opt out with `-Dcpu=generic`. + if (result.result.cpu.arch.isWasm() and + result.query.cpu_model == .determined_by_arch_os and + result.query.cpu_features_add.isEmpty() and + result.query.cpu_features_sub.isEmpty()) + { + var query = result.query; + query.cpu_features_add.addFeature( + @intFromEnum(std.Target.wasm.Feature.simd128), + ); + result = b.resolveTargetQuery(query); + } + + // The full Ghostty build no longer supports iOS; Fail early + // with a clear message rather than partway through the build. + if (result.result.os.tag == .ios and !emit_lib_vt) { + std.log.err( + "iOS is not a supported target for the full Ghostty build; " ++ + "only libghostty-vt supports iOS (-Demit-lib-vt)", + .{}, + ); + return error.UnsupportedTarget; + } + // If we have no minimum OS version, we set the default based on // our tag. Not all tags have a minimum so this may be null. if (result.query.os_version_min == null) { - result.query.os_version_min = osVersionMin(result.result.os.tag); + result.query.os_version_min = if (emit_lib_vt) + osVersionMinLibVt(result.result.os.tag) + else + osVersionMin(result.result.os.tag); } break :target result; }; - // Detect if Ghostty is a dependency of another project. - // dep_prefix is non-empty when this build is running as a dependency. - const is_dep = b.dep_prefix.len > 0; - // This is set to true when we're building a system package. For now // this is trivially detected using the "system_package_mode" bool // but we may want to make this more sophisticated in the future. @@ -124,10 +166,10 @@ pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Conf // defaults. const gtk_targets = gtk.targets(b); - // We use env vars throughout the build so we grab them immediately here. - var env = try std.process.getEnvMap(b.allocator); - errdefer env.deinit(); + // Grab the environment from build state + const env = &b.graph.environ_map; + // We use env vars throughout the build so we grab them immediately here. var config: Config = .{ .optimize = optimize, .target = target, @@ -198,9 +240,10 @@ pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Conf "simd", "Build with SIMD-accelerated code paths. Results in significant performance improvements.", ) orelse simd: { - // We can't build our SIMD dependencies for Wasm. Note that we may - // still use SIMD features in the Wasm-builds. - if (target.result.cpu.arch.isWasm()) break :simd false; + // We can't build our SIMD dependencies for Wasm or freestanding + // targets. Note that we may still use SIMD features in the Wasm-builds. + if (target.result.cpu.arch.isWasm() or + target.result.os.tag == .freestanding) break :simd false; break :simd true; }; @@ -312,24 +355,55 @@ pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Conf //--------------------------------------------------------------- // Binary Properties - // On NixOS, the built binary from `zig build` needs to patch the rpath - // into the built binary for it to be portable across the NixOS system - // it was built for. We default this to true if we can detect we're in - // a Nix shell and have LD_LIBRARY_PATH set. - config.patch_rpath = b.option( + // On NixOS, the built binary from `zig build` needs to patch the interp + // and rpath into the built binary for it to be portable across the NixOS + // system it was built for. We default this to true if we can detect we're + // in a Nix shell. + // + // Note that this option is only available on Linux and if building + // natively. + // + // NOTE: Zig does now have an option to pass in the dynamic linker + // (-Ddynamic-linker), but it does seem to have some issues in 0.16.0 that + // may be fixed in 0.17.0. We may want to revisit this afterwards; although + // I'm not too sure if that helps to clean up rpath, this may just be the + // better option. See https://codeberg.org/ziglang/zig/issues/31760. + if (b.option( + []const u8, + "patch-interp", + "Inject the supplied path as the dynamic linker in the built binary. " ++ + "Under Nix, this defaults to the dynamic linker found in PATH.", + )) |interp| { + PatchElf.setInterp(&config, interp); + } else patch_interp: { + if (!(target.result.os.tag == .linux) or !target.query.isNativeCpu()) break :patch_interp; + if (env.get("IN_NIX_SHELL") == null) break :patch_interp; + + if (b.findProgram(&.{"ld.so"}, &.{})) |ld_so| { + PatchElf.setInterp( + &config, + std.Io.Dir.realPathFileAbsoluteAlloc(b.graph.io, ld_so, b.allocator) catch break :patch_interp, + ); + } else |_| {} + } + + if (b.option( []const u8, "patch-rpath", - "Inject the LD_LIBRARY_PATH as the rpath in the built binary. " ++ - "This defaults to LD_LIBRARY_PATH if we're in a Nix shell environment on NixOS.", - ) orelse patch_rpath: { - // We only do the patching if we're targeting our own CPU and its Linux. - if (!(target.result.os.tag == .linux) or !target.query.isNativeCpu()) break :patch_rpath null; - - // If we're in a nix shell we default to doing this. - // Note: we purposely never deinit envmap because we leak the strings - if (env.get("IN_NIX_SHELL") == null) break :patch_rpath null; - break :patch_rpath env.get("LD_LIBRARY_PATH"); - }; + "Inject the supplied colon-delimited search path as the rpath in the built binary. " ++ + "This defaults to LD_LIBRARY_PATH if we're in a Nix shell environment.", + )) |rpath| { + PatchElf.setRpath(&config, rpath); + } else patch_rpath: { + if (!(target.result.os.tag == .linux) or !target.query.isNativeCpu()) break :patch_rpath; + if (env.get("IN_NIX_SHELL") == null) break :patch_rpath; + + if (env.get("LD_LIBRARY_PATH")) |ld_library_path| { + if (ld_library_path.len > 0) { + PatchElf.setRpath(&config, ld_library_path); + } + } + } config.pie = b.option( bool, @@ -350,11 +424,31 @@ pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Conf //--------------------------------------------------------------- // Artifacts to Emit - config.emit_lib_vt = b.option( - bool, - "emit-lib-vt", - "Set defaults for a libghostty-vt-only build (disables xcframework, macOS app, and docs).", - ) orelse false; + config.emit_lib_vt = emit_lib_vt; + + config.vt_features = features: { + const list = b.option( + []const u8, + "vt-features", + "Comma-separated libghostty-vt feature modifications applied " ++ + "to the default all-enabled set, -Dcpu style: `+feature` " ++ + "or `feature` enables, `-feature` disables, and `all` " ++ + "means every feature (e.g. `-all,+render-state` for a " ++ + "render-only build). Only applies to lib artifacts.", + ) orelse break :features .{}; + break :features TerminalBuildOptions.Features.parse(list) catch { + var valid: std.ArrayList(u8) = .empty; + inline for (@typeInfo(TerminalBuildOptions.Features).@"struct".fields) |field| { + if (valid.items.len > 0) try valid.appendSlice(b.allocator, ", "); + try valid.appendSlice(b.allocator, field.name); + } + std.log.err( + "-Dvt-features={s} contains an unknown feature. Valid features: all, {s}", + .{ list, valid.items }, + ); + return error.UnknownVtFeature; + }; + }; config.emit_exe = b.option( bool, @@ -401,7 +495,7 @@ pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Conf if (system_package) break :emit_docs true; // We only default to true if we can find pandoc. - const path = expandPath(b.allocator, "pandoc") catch + const path = expandPath(b.graph.io, b.allocator, &b.graph.environ_map, "pandoc") catch break :emit_docs false; defer if (path) |p| b.allocator.free(p); break :emit_docs path != null; @@ -450,7 +544,7 @@ pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Conf if (config.emit_lib_vt) { // In lib-vt mode default to whether xcodebuild is available, // since xcodebuild is required to produce the XCFramework. - const path = expandPath(b.allocator, "xcodebuild") catch + const path = expandPath(b.graph.io, b.allocator, &b.graph.environ_map, "xcodebuild") catch break :emit_xcfw false; defer if (path) |p| b.allocator.free(p); break :emit_xcfw path != null; @@ -522,6 +616,45 @@ pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Conf return config; } +const PatchElf = struct { + interp: ?[]const u8 = null, + rpath: ?[]const u8 = null, + + fn setInterp(config: *Config, interp: []const u8) void { + if (config.patchelf) |*patchelf| { + patchelf.interp = interp; + return; + } + + config.patchelf = .{ .interp = interp }; + } + + fn setRpath(config: *Config, rpath: []const u8) void { + if (config.patchelf) |*patchelf| { + patchelf.rpath = rpath; + return; + } + + config.patchelf = .{ .rpath = rpath }; + } +}; + +/// Add a patchelf step for the supplied `artifact`, depending on the supplied +/// `step`, if `patchelf` is present in the config. +pub fn addPatchElf(self: *const Config, artifact: *std.Build.Step.Compile, step: *std.Build.Step) void { + const b = artifact.step.owner; + std.debug.assert(b == step.owner); + + if (self.patchelf) |patchelf| { + const run = std.Build.Step.Run.create(b, "patchelf"); + run.addArgs(&.{"patchelf"}); + if (patchelf.interp) |interp| run.addArgs(&.{ "--set-interpreter", interp }); + if (patchelf.rpath) |rpath| run.addArgs(&.{ "--set-rpath", rpath }); + run.addArtifactArg(artifact); + step.dependOn(&run.step); + } +} + /// Configure the build options with our values. pub fn addOptions(self: *const Config, step: *std.Build.Step.Options) !void { // We need to break these down individual because addOption doesn't @@ -570,17 +703,27 @@ pub fn addOptions(self: *const Config, step: *std.Build.Step.Options) !void { /// Returns the build options for the terminal module. This assumes a /// Ghostty executable being built. Callers should modify this as needed. -pub fn terminalOptions(self: *const Config, artifact: TerminalBuildOptions.Artifact) TerminalBuildOptions { +pub fn terminalOptions( + self: *const Config, + artifact: TerminalBuildOptions.Artifact, + optimize: std.builtin.OptimizeMode, +) TerminalBuildOptions { return .{ .artifact = artifact, .simd = self.simd, .oniguruma = true, .c_abi = false, + // The application requires every feature; only lib artifacts + // may trim them. + .features = switch (artifact) { + .ghostty => .{}, + .lib => self.vt_features, + }, .version = switch (artifact) { .ghostty => self.version, .lib => self.lib_version, }, - .slow_runtime_safety = switch (self.optimize) { + .slow_runtime_safety = switch (optimize) { .Debug => true, .ReleaseSafe, .ReleaseSmall, @@ -591,7 +734,7 @@ pub fn terminalOptions(self: *const Config, artifact: TerminalBuildOptions.Artif } /// Returns a baseline CPU target retaining all the other CPU configs. -pub fn baselineTarget(self: *const Config) std.Build.ResolvedTarget { +pub fn baselineTarget(self: *const Config, io: std.Io) std.Build.ResolvedTarget { // Set our cpu model as baseline. There may need to be other modifications // we need to make such as resetting CPU features but for now this works. var q = self.target.query; @@ -601,7 +744,7 @@ pub fn baselineTarget(self: *const Config) std.Build.ResolvedTarget { // handle the native case. return .{ .query = q, - .result = std.zig.system.resolveTargetQuery(q) catch + .result = std.zig.system.resolveTargetQuery(io, q) catch @panic("unable to resolve baseline query"), }; } @@ -630,6 +773,17 @@ pub fn fromOptions() Config { }; } +/// Whether release artifacts should omit frame pointers. +/// +/// Stripped release builds omit them in general, but we always keep frame +/// pointers on Apple platforms: the Apple arm64 ABI expects x29 to +/// be a valid frame pointer and Apple's profiling and crash reporting +/// tools rely on it for backtraces. +pub fn omitFramePointer(self: *const Config) bool { + if (self.target.result.os.tag.isDarwin()) return false; + return self.strip; +} + /// Returns the minimum OS version for the given OS tag. This shouldn't /// be used generally, it should only be used for Darwin-based OS currently. pub fn osVersionMin(tag: std.Target.Os.Tag) ?std.Target.Query.OsVersion { @@ -642,19 +796,22 @@ pub fn osVersionMin(tag: std.Target.Os.Tag) ?std.Target.Query.OsVersion { .patch = 0, } }, - // iOS 17 picked arbitrarily - .ios => .{ .semver = .{ - .major = 17, - .minor = 0, - .patch = 0, - } }, - // This should never happen currently. If we add a new target then // we should add a new case here. else => null, }; } +/// Returns the minimum OS version for lib-vt build. +/// +/// This should only be used for Darwin targets. +pub fn osVersionMinLibVt(tag: std.Target.Os.Tag) ?std.Target.Query.OsVersion { + // lib-vt is the only thing we still build for iOS, so its deployment + // target lives here rather than in osVersionMin. + if (tag == .ios) return .{ .semver = .{ .major = 13, .minor = 0, .patch = 0 } }; + return osVersionMin(tag); +} + // Returns a ResolvedTarget for a mac with a `target.result.cpu.model.name` of `generic`. // `b.standardTargetOptions()` returns a more specific cpu like `apple_a15`. // diff --git a/vendor/libghostty-vt/src/build/GhosttyBench.zig b/vendor/libghostty-vt/src/build/GhosttyBench.zig index 27dda880..fbf8029d 100644 --- a/vendor/libghostty-vt/src/build/GhosttyBench.zig +++ b/vendor/libghostty-vt/src/build/GhosttyBench.zig @@ -23,9 +23,9 @@ pub fn init( // We always want our datagen to be fast because it // takes awhile to run. .optimize = .ReleaseFast, + .link_libc = true, }), }); - exe.linkLibC(); _ = try deps.add(exe); try steps.append(b.allocator, exe); } @@ -39,9 +39,9 @@ pub fn init( .target = deps.config.target, // We always want our benchmarks to be in release mode. .optimize = .ReleaseFast, + .link_libc = true, }), }); - exe.linkLibC(); _ = try deps.add(exe); try steps.append(b.allocator, exe); } diff --git a/vendor/libghostty-vt/src/build/GhosttyDist.zig b/vendor/libghostty-vt/src/build/GhosttyDist.zig index 448047f4..fe8b863f 100644 --- a/vendor/libghostty-vt/src/build/GhosttyDist.zig +++ b/vendor/libghostty-vt/src/build/GhosttyDist.zig @@ -237,11 +237,11 @@ pub const Resource = struct { /// Returns true if the dist path exists at build time. pub fn exists(self: *const Resource, b: *std.Build) bool { - if (b.build_root.handle.access(self.dist, .{})) { + if (b.build_root.handle.access(b.graph.io, self.dist, .{})) { // If we have a ".git" directory then we're a git checkout // and we never want to use the dist path. This shouldn't happen // so show a warning to the user. - if (b.build_root.handle.access(".git", .{})) { + if (b.build_root.handle.access(b.graph.io, ".git", .{})) { std.log.warn( "dist resource '{s}' should not be in a git checkout", .{self.dist}, diff --git a/vendor/libghostty-vt/src/build/GhosttyDocs.zig b/vendor/libghostty-vt/src/build/GhosttyDocs.zig index cd75fc06..2b207f23 100644 --- a/vendor/libghostty-vt/src/build/GhosttyDocs.zig +++ b/vendor/libghostty-vt/src/build/GhosttyDocs.zig @@ -50,7 +50,7 @@ pub fn init( generate_markdown.root_module.addOptions("build_options", generate_markdown_options); const generate_markdown_step = b.addRunArtifact(generate_markdown); - const markdown_output = generate_markdown_step.captureStdOut(); + const markdown_output = generate_markdown_step.captureStdOut(.{}); try steps.append(b.allocator, &b.addInstallFile( markdown_output, @@ -68,7 +68,7 @@ pub fn init( generate_html.addFileArg(markdown_output); try steps.append(b.allocator, &b.addInstallFile( - generate_html.captureStdOut(), + generate_html.captureStdOut(.{}), "share/ghostty/doc/" ++ manpage.name ++ "." ++ manpage.section ++ ".html", ).step); @@ -83,7 +83,7 @@ pub fn init( generate_manpage.addFileArg(markdown_output); try steps.append(b.allocator, &b.addInstallFile( - generate_manpage.captureStdOut(), + generate_manpage.captureStdOut(.{}), "share/man/man" ++ manpage.section ++ "/" ++ manpage.name ++ "." ++ manpage.section, ).step); } diff --git a/vendor/libghostty-vt/src/build/GhosttyExe.zig b/vendor/libghostty-vt/src/build/GhosttyExe.zig index caa564bf..22f39b7b 100644 --- a/vendor/libghostty-vt/src/build/GhosttyExe.zig +++ b/vendor/libghostty-vt/src/build/GhosttyExe.zig @@ -18,7 +18,7 @@ pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !Ghostty .target = cfg.target, .optimize = cfg.optimize, .strip = cfg.strip, - .omit_frame_pointer = cfg.strip, + .omit_frame_pointer = cfg.omitFramePointer(), .unwind_tables = if (cfg.strip) .none else .sync, }), // Crashes on x86_64 self-hosted on 0.15.1 @@ -36,21 +36,14 @@ pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !Ghostty // Check for possible issues try checkNixShell(exe, cfg); - // Patch our rpath if that option is specified. - if (cfg.patch_rpath) |rpath| { - if (rpath.len > 0) { - const run = std.Build.Step.Run.create(b, "patchelf rpath"); - run.addArgs(&.{ "patchelf", "--set-rpath", rpath }); - run.addArtifactArg(exe); - install_step.step.dependOn(&run.step); - } - } + // Add patchelf step if that option is specified. + cfg.addPatchElf(exe, &install_step.step); // OS-specific switch (cfg.target.result.os.tag) { .windows => { exe.subsystem = .Windows; - exe.addWin32ResourceFile(.{ + exe.root_module.addWin32ResourceFile(.{ .file = b.path("dist/windows/ghostty.rc"), }); }, @@ -85,7 +78,7 @@ fn checkNixShell(exe: *std.Build.Step.Compile, cfg: *const Config) !void { if (!cfg.target.query.isNativeOs()) return; // Verify we're in NixOS - std.fs.accessAbsolute("/etc/NIXOS", .{}) catch return; + std.Io.Dir.accessAbsolute(exe.step.owner.graph.io, "/etc/NIXOS", .{}) catch return; // If we're in a nix shell, not a problem if (cfg.env.get("IN_NIX_SHELL") != null) return; diff --git a/vendor/libghostty-vt/src/build/GhosttyFrameData.zig b/vendor/libghostty-vt/src/build/GhosttyFrameData.zig index 8469759f..be61f029 100644 --- a/vendor/libghostty-vt/src/build/GhosttyFrameData.zig +++ b/vendor/libghostty-vt/src/build/GhosttyFrameData.zig @@ -40,16 +40,16 @@ pub fn distResources(b: *std.Build) struct { .name = "framegen", .root_module = b.createModule(.{ .target = b.graph.host, + .link_libc = true, }), }); - exe.addCSourceFile(.{ + exe.root_module.addCSourceFile(.{ .file = b.path("src/build/framegen/main.c"), .flags = &.{}, }); - exe.linkLibC(); if (b.systemIntegrationOption("zlib", .{})) { - exe.linkSystemLibrary2("zlib", .{ + exe.root_module.linkSystemLibrary("zlib", .{ .preferred_link_mode = .dynamic, .search_strategy = .mode_first, }); @@ -58,7 +58,7 @@ pub fn distResources(b: *std.Build) struct { .target = b.graph.host, .optimize = .ReleaseFast, })) |zlib_dep| { - exe.linkLibrary(zlib_dep.artifact("z")); + exe.root_module.linkLibrary(zlib_dep.artifact("z")); } } diff --git a/vendor/libghostty-vt/src/build/GhosttyI18n.zig b/vendor/libghostty-vt/src/build/GhosttyI18n.zig index 0874676c..eb6ee5ee 100644 --- a/vendor/libghostty-vt/src/build/GhosttyI18n.zig +++ b/vendor/libghostty-vt/src/build/GhosttyI18n.zig @@ -26,7 +26,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n { // so we need to remove it from `locale` to have a correct destination string. // (/usr/local/share/locale/en_AU/LC_MESSAGES) const target_locale = comptime if (builtin.target.os.tag == .freebsd) - std.mem.trimRight(u8, locale, ".UTF-8") + std.mem.trimEnd(u8, locale, ".UTF-8") else locale; @@ -34,7 +34,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n { msgfmt.addFileArg(b.path("po/" ++ locale ++ ".po")); try steps.append(b.allocator, &b.addInstallFile( - msgfmt.captureStdOut(), + msgfmt.captureStdOut(.{}), std.fmt.comptimePrint( "share/locale/{s}/LC_MESSAGES/{s}.mo", .{ target_locale, domain }, @@ -66,6 +66,7 @@ fn createUpdateStep(b: *std.Build) !*std.Build.Step { "--language=C", // Silence the "unknown extension" errors "--from-code=UTF-8", "--keyword=_", + "--keyword=N_", "--keyword=C_:1c,2", }); @@ -103,14 +104,15 @@ fn createUpdateStep(b: *std.Build) !*std.Build.Step { } var gtk_dir = try b.build_root.handle.openDir( + b.graph.io, "src/apprt/gtk", .{ .iterate = true }, ); - defer gtk_dir.close(); + defer gtk_dir.close(b.graph.io); var walk = try gtk_dir.walk(b.allocator); defer walk.deinit(); - while (try walk.next()) |src| { + while (try walk.next(b.graph.io)) |src| { switch (src.kind) { .file => if (!std.mem.endsWith( u8, @@ -147,6 +149,11 @@ fn createUpdateStep(b: *std.Build) !*std.Build.Step { } } + // For localization of command palette + const command_palette_path = "src/input/command.zig"; + xgettext.addArg(command_palette_path); + xgettext.addFileInput(b.path(command_palette_path)); + // Add support for localizing our `nautilus` integration const xgettext_py = b.addSystemCommand(&.{ "xgettext", @@ -178,15 +185,15 @@ fn createUpdateStep(b: *std.Build) !*std.Build.Step { xgettext_merge.addFileArg(gtk_pot); const usf = b.addUpdateSourceFiles(); usf.addCopyFileToSource( - xgettext_merge.captureStdOut(), + xgettext_merge.captureStdOut(.{}), "po/" ++ domain ++ ".pot", ); inline for (locales) |locale| { const msgmerge = b.addSystemCommand(&.{ "msgmerge", "--quiet", "--no-fuzzy-matching" }); msgmerge.addFileArg(b.path("po/" ++ locale ++ ".po")); - msgmerge.addFileArg(xgettext_merge.captureStdOut()); - usf.addCopyFileToSource(msgmerge.captureStdOut(), "po/" ++ locale ++ ".po"); + msgmerge.addFileArg(xgettext_merge.captureStdOut(.{})); + usf.addCopyFileToSource(msgmerge.captureStdOut(.{}), "po/" ++ locale ++ ".po"); } return &usf.step; diff --git a/vendor/libghostty-vt/src/build/GhosttyLib.zig b/vendor/libghostty-vt/src/build/GhosttyLib.zig index b762da8b..529bb282 100644 --- a/vendor/libghostty-vt/src/build/GhosttyLib.zig +++ b/vendor/libghostty-vt/src/build/GhosttyLib.zig @@ -1,9 +1,11 @@ const GhosttyLib = @This(); const std = @import("std"); +const builtin = @import("builtin"); const RunStep = std.Build.Step.Run; const CombineArchivesStep = @import("CombineArchivesStep.zig"); const Config = @import("Config.zig"); +const LibsystemOverrideStep = @import("LibsystemOverrideStep.zig"); const SharedDeps = @import("SharedDeps.zig"); const LipoStep = @import("LipoStep.zig"); @@ -27,14 +29,14 @@ pub fn initStatic( .target = deps.config.target, .optimize = deps.config.optimize, .strip = deps.config.strip, - .omit_frame_pointer = deps.config.strip, + .omit_frame_pointer = deps.config.omitFramePointer(), .unwind_tables = if (deps.config.strip) .none else .sync, + .link_libc = true, }), // Fails on self-hosted x86_64 on macOS .use_llvm = true, }); - lib.linkLibC(); // These must be bundled since we're compiling into a static lib. // Otherwise, you get undefined symbol errors. @@ -57,9 +59,19 @@ pub fn initStatic( const combined = CombineArchivesStep.create(b, deps.config.target, "ghostty-internal", lib_list.items); combined.step.dependOn(&lib.step); + // On Darwin, prefer libSystem's libc/libm over the bundled + // compiler-rt for consumers of this archive. See + // libsystem_override.sh for details. This is a no-op elsewhere. + const override = LibsystemOverrideStep.create( + b, + deps.config.target, + combined.output, + "libghostty-internal.a", + ); + return .{ - .step = combined.step, - .output = combined.output, + .step = override.step orelse combined.step, + .output = override.output, // Static libraries cannot have dSYMs because they aren't linked. .dsym = null, @@ -72,6 +84,14 @@ pub fn initShared( b: *std.Build, deps: *const SharedDeps, ) !GhosttyLib { + // For dynamic linking, we prefer dynamic linking and to search by + // mode first. Mode first will search all paths for a dynamic library + // before falling back to static. + const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ + .preferred_link_mode = .dynamic, + .search_strategy = .mode_first, + }; + const lib = b.addLibrary(.{ .name = "ghostty", .linkage = .dynamic, @@ -80,7 +100,7 @@ pub fn initShared( .target = deps.config.target, .optimize = deps.config.optimize, .strip = deps.config.strip, - .omit_frame_pointer = deps.config.strip, + .omit_frame_pointer = deps.config.omitFramePointer(), .unwind_tables = if (deps.config.strip) .none else .sync, }), @@ -99,12 +119,12 @@ pub fn initShared( { // The CRT initialization code in msvcrt.lib calls __vcrt_initialize // and __acrt_initialize, which are in the static CRT libraries. - lib.linkSystemLibrary("libvcruntime"); + lib.root_module.linkSystemLibrary("libvcruntime", dynamic_link_opts); // ucrt.lib is in the Windows SDK 'ucrt' dir. Detect the SDK // installation and add the UCRT library path. const arch = deps.config.target.result.cpu.arch; - const sdk = std.zig.WindowsSdk.find(b.allocator, arch) catch null; + const sdk = std.zig.WindowsSdk.find(b.allocator, b.graph.io, arch, &b.graph.environ_map) catch null; if (sdk) |s| { if (s.windows10sdk) |w10| { const arch_str: []const u8 = switch (arch) { @@ -120,11 +140,11 @@ pub fn initShared( ) catch null; if (ucrt_lib_path) |path| { - lib.addLibraryPath(.{ .cwd_relative = path }); + lib.root_module.addLibraryPath(.{ .cwd_relative = path }); } } } - lib.linkSystemLibrary("libucrt"); + lib.root_module.linkSystemLibrary("libucrt", dynamic_link_opts); } // Get our debug symbols diff --git a/vendor/libghostty-vt/src/build/GhosttyLibVt.zig b/vendor/libghostty-vt/src/build/GhosttyLibVt.zig index 65f945bf..690f864c 100644 --- a/vendor/libghostty-vt/src/build/GhosttyLibVt.zig +++ b/vendor/libghostty-vt/src/build/GhosttyLibVt.zig @@ -5,6 +5,7 @@ const builtin = @import("builtin"); const assert = std.debug.assert; const RunStep = std.Build.Step.Run; const CombineArchivesStep = @import("CombineArchivesStep.zig"); +const LibsystemOverrideStep = @import("LibsystemOverrideStep.zig"); const Config = @import("Config.zig"); const GhosttyZig = @import("GhosttyZig.zig"); const LipoStep = @import("LipoStep.zig"); @@ -57,6 +58,12 @@ pub fn initWasm( // There is no entrypoint for this wasm module. exe.entry = .disabled; + // Default Zig stack size in Zig 0.16 is 1MB. Lower to 128 KB since + // this has to be preallocated up front in Wasm linear memory. Peak + // stack under various artificial loads is 17 KB at the time of this + // comment but lets do 128KB to be safe. We can lower later. + exe.stack_size = 128 * 1024; + // Zig's WASM linker doesn't support --growable-table, so the table // is emitted with max == min and can't be grown from JS. Run a // small Zig build tool that patches the binary's table section to @@ -101,6 +108,16 @@ pub fn initShared( b: *std.Build, zig: *const GhosttyZig, ) !GhosttyLibVt { + const target = zig.vt.resolved_target.?; + + // Prefer Apple's linker for final Darwin dylibs when its toolchain is + // available. Besides producing the platform load commands expected by + // Apple distribution, this lets the static archive's libSystem symbol + // override take effect. Cross-compiled macOS dylibs continue through Zig. + if (@import("apple_sdk").nativeLink.available(target)) { + return initLibApple(b, zig); + } + return initLib(b, zig, .dynamic); } @@ -172,16 +189,21 @@ pub fn initStaticAppleUniversal( const target_query: std.Target.Query = .{ .cpu_arch = .aarch64, .os_tag = p.os_tag, - .os_version_min = Config.osVersionMin(p.os_tag), + .os_version_min = Config.osVersionMinLibVt(p.os_tag), }; - if (detectAppleSDK(b.resolveTargetQuery(target_query).result)) { + if (detectAppleSDK( + b.graph.io, + b.allocator, + &b.graph.environ_map, + b.resolveTargetQuery(target_query).result, + )) { const dev_zig = try zig.retarget(b, cfg, deps, b.resolveTargetQuery(target_query)); result.put(p.device, try initStatic(b, &dev_zig)); const sim_zig = try zig.retarget(b, cfg, deps, b.resolveTargetQuery(.{ .cpu_arch = .aarch64, .os_tag = p.os_tag, - .os_version_min = Config.osVersionMin(p.os_tag), + .os_version_min = Config.osVersionMinLibVt(p.os_tag), .abi = .simulator, .cpu_model = .{ .explicit = &std.Target.aarch64.cpu.apple_a17 }, })); @@ -224,13 +246,28 @@ fn initLib( // Enable PIC so the static library can be linked into PIE // executables, which is the default on most Linux distributions. - lib.root_module.pic = true; + // Native freestanding targets don't have a dynamic loader and some, + // such as Xtensa, don't support PIC relocations. + lib.root_module.pic = target.result.os.tag != .freestanding; } if (target.result.os.tag == .windows) { // Zig's ubsan emits /exclude-symbols linker directives that // are incompatible with the MSVC linker (LNK4229). lib.bundle_ubsan_rt = false; + + if (kind == .static) { + if (target.result.abi == .msvc) { + // Zig's compiler runtime doesn't provide MSVC's security + // cookie symbols when libc is linked. Disable stack-protector + // generation so static consumers don't need BufferOverflowU. + lib.root_module.stack_protector = false; + } + + // The Zig standard library uses NT and kernel32 symbols. + lib.root_module.linkSystemLibrary("ntdll", .{}); + lib.root_module.linkSystemLibrary("kernel32", .{}); + } } if (lib.rootModuleTarget().abi.isAndroid()) { @@ -290,28 +327,171 @@ fn initLib( const combined = CombineArchivesStep.create(b, target, "ghostty-vt", sources.items); combined.step.dependOn(&lib.step); + // On Darwin, prefer libSystem's libc/libm over the bundled + // compiler-rt for consumers of this archive. See GhosttyLib + // and libsystem_override.sh for details. + const override = LibsystemOverrideStep.create( + b, + target, + combined.output, + "libghostty-vt-fat.a", + ); + return .{ - .step = combined.step, + .step = override.step orelse combined.step, .artifact = &b.addInstallArtifact(lib, .{}).step, .kind = kind, - .output = combined.output, + .output = override.output, .dsym = dsymutil, .pkg_config = if (pcs) |v| v.shared else null, .pkg_config_static = if (pcs) |v| v.static else null, }; } + // Same libSystem preference for the plain (no vendored SIMD) + // static archive; a no-op off Darwin. + const override: LibsystemOverrideStep.Result = if (kind == .static) LibsystemOverrideStep.create( + b, + target, + lib.getEmittedBin(), + "libghostty-vt-static.a", + ) else .{ + .step = null, + .output = lib.getEmittedBin(), + }; + return .{ - .step = &lib.step, + .step = override.step orelse &lib.step, .artifact = &b.addInstallArtifact(lib, .{}).step, .kind = kind, - .output = lib.getEmittedBin(), + .output = override.output, .dsym = dsymutil, .pkg_config = if (pcs) |v| v.shared else null, .pkg_config_static = if (pcs) |v| v.static else null, }; } +/// Builds a shared Darwin library with Apple's linker. +fn initLibApple( + b: *std.Build, + zig: *const GhosttyZig, +) !GhosttyLibVt { + // Sorry, this function has a lot of comments because there are + // a lot of flags that aren't obvious. + + const target = zig.vt.resolved_target.?; + assert(target.result.os.tag.isDarwin()); + + // Build the combined archive through the normal static path first. + const static = try initStatic(b, zig); + + // Zig's module-level export metadata does not carry into this separate + // native link, so explicitly expose only libghostty-vt's public C ABI. + const exports = b.addWriteFiles().add( + "libghostty-vt.exports", + "_ghostty_*\n", + ); + + // Match Zig's versioned dylib naming so existing consumers and packaging + // continue to receive the same real name and compatibility symlinks. + const real_name = b.fmt("libghostty-vt.{d}.{d}.{d}.dylib", .{ + zig.version.major, + zig.version.minor, + zig.version.patch, + }); + const soname = b.fmt("libghostty-vt.{d}.dylib", .{zig.version.major}); + + const native_link = try @import("apple_sdk").nativeLink.addCommand( + b, + "link libghostty-vt with Apple ld", + target, + ); + + native_link.addArgs(&.{ + // Emit a Mach-O dynamic library instead of an executable. + "-dynamiclib", + // Pull every object from the combined static archive. + "-Wl,-all_load", + // Remove unreachable private code pulled in by all_load. + "-Wl,-dead_strip", + // Leave room for packaging tools to rewrite install names. + "-Wl,-headerpad_max_install_names", + }); + // Restrict exports to libghostty-vt's public C ABI. + native_link.addPrefixedFileArg("-Wl,-exported_symbols_list,", exports); + // Link the archive produced by the normal static-library path. + native_link.addFileArg(static.output); + native_link.addArgs(&.{ + // Give framework consumers a stable runtime-relative identity. + "-install_name", + "@rpath/libghostty-vt.dylib", + // Record the exact package version for runtime inspection. + "-current_version", + b.fmt("{d}.{d}.{d}", .{ + zig.version.major, + zig.version.minor, + zig.version.patch, + }), + // Preserve compatibility with the initial public ABI. + "-compatibility_version", + "1.0.0", + // Write the fully versioned dylib used by the install symlinks. + "-o", + }); + const output = native_link.addOutputFileArg(real_name); + + // Recreate addInstallArtifact's dylib layout: install the fully versioned + // file, then point the major-version and unversioned names at it. + const artifact_install = b.addInstallFileWithDir( + output, + .lib, + real_name, + ); + const soname_install = b.addSystemCommand(&.{ + "/bin/ln", + "-sf", + real_name, + b.getInstallPath(.lib, soname), + }); + soname_install.step.dependOn(&artifact_install.step); + const unversioned_install = b.addSystemCommand(&.{ + "/bin/ln", + "-sf", + soname, + b.getInstallPath(.lib, "libghostty-vt.dylib"), + }); + unversioned_install.step.dependOn(&soname_install.step); + + // The native link is a Run step rather than a Compile step, so install the + // public headers explicitly instead of relying on addInstallArtifact. + const headers_install = b.addInstallDirectory(.{ + .source_dir = b.path("include/ghostty"), + .install_dir = .header, + .install_subdir = "ghostty", + .include_extensions = &.{".h"}, + }); + unversioned_install.step.dependOn(&headers_install.step); + + // Preserve the debug-symbol output exposed by the normal shared-library + // path for framework and release packaging. + const dsymutil = RunStep.create(b, "dsymutil"); + dsymutil.addArgs(&.{"dsymutil"}); + dsymutil.addFileArg(output); + dsymutil.addArgs(&.{"-o"}); + const dsym = dsymutil.addOutputFileArg("libghostty-vt.dSYM"); + + const pcs = pkgConfigFiles(b, zig, target.result.os.tag); + return .{ + .step = &native_link.step, + .artifact = &unversioned_install.step, + .kind = .shared, + .output = output, + .dsym = dsym, + .pkg_config = pcs.shared, + .pkg_config_static = pcs.static, + }; +} + /// Returns the Libs.private value for the pkg-config file. /// Vendored C++ dependencies are built in no-libcxx mode so consumers /// don't need libc++. System-provided simdutf still requires it. @@ -438,12 +618,21 @@ pub fn xcframework( } /// Returns true if the Apple SDK for the given target is installed. -fn detectAppleSDK(target: std.Target) bool { - _ = std.zig.LibCInstallation.findNative(.{ - .allocator = std.heap.page_allocator, - .target = &target, - .verbose = false, - }) catch return false; +fn detectAppleSDK( + io: std.Io, + alloc: std.mem.Allocator, + environ_map: *const std.process.Environ.Map, + target: std.Target, +) bool { + _ = std.zig.LibCInstallation.findNative( + alloc, + io, + .{ + .environ_map = environ_map, + .target = &target, + .verbose = false, + }, + ) catch return false; return true; } diff --git a/vendor/libghostty-vt/src/build/GhosttyResources.zig b/vendor/libghostty-vt/src/build/GhosttyResources.zig index 6f857655..673c7e56 100644 --- a/vendor/libghostty-vt/src/build/GhosttyResources.zig +++ b/vendor/libghostty-vt/src/build/GhosttyResources.zig @@ -21,9 +21,9 @@ pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !Ghostty .strip = false, .omit_frame_pointer = false, .unwind_tables = .sync, + .link_libc = true, }), }); - build_data_exe.linkLibC(); deps.help_strings.addImport(build_data_exe); @@ -39,7 +39,7 @@ pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !Ghostty const run = b.addRunArtifact(build_data_exe); run.addArg("+terminfo"); const wf = b.addWriteFiles(); - const source = wf.addCopyFile(run.captureStdOut(), "ghostty.terminfo"); + const source = wf.addCopyFile(run.captureStdOut(.{}), "ghostty.terminfo"); if (cfg.emit_terminfo) { const source_install = b.addInstallFile( @@ -63,8 +63,8 @@ pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !Ghostty const run_step = RunStep.create(b, "infotocap"); run_step.addArg("infotocap"); run_step.addFileArg(source); - const out_source = run_step.captureStdOut(); - _ = run_step.captureStdErr(); // so we don't see stderr + const out_source = run_step.captureStdOut(.{}); + _ = run_step.captureStdErr(.{}); // so we don't see stderr const cap_install = b.addInstallFile( out_source, @@ -84,7 +84,7 @@ pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !Ghostty const path = run_step.addOutputFileArg(terminfo_share_dir); run_step.addFileArg(source); - _ = run_step.captureStdErr(); // so we don't see stderr + _ = run_step.captureStdErr(.{}); // so we don't see stderr // Ensure that `share/terminfo` is a directory, otherwise the `cp // -R` will create a file named `share/terminfo` @@ -143,7 +143,7 @@ pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !Ghostty const run = b.addRunArtifact(build_data_exe); run.addArg("+fish"); const wf = b.addWriteFiles(); - _ = wf.addCopyFile(run.captureStdOut(), "ghostty.fish"); + _ = wf.addCopyFile(run.captureStdOut(.{}), "ghostty.fish"); const install_step = b.addInstallDirectory(.{ .source_dir = wf.getDirectory(), @@ -158,7 +158,7 @@ pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !Ghostty const run = b.addRunArtifact(build_data_exe); run.addArg("+zsh"); const wf = b.addWriteFiles(); - _ = wf.addCopyFile(run.captureStdOut(), "_ghostty"); + _ = wf.addCopyFile(run.captureStdOut(.{}), "_ghostty"); const install_step = b.addInstallDirectory(.{ .source_dir = wf.getDirectory(), @@ -173,7 +173,7 @@ pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !Ghostty const run = b.addRunArtifact(build_data_exe); run.addArg("+bash"); const wf = b.addWriteFiles(); - _ = wf.addCopyFile(run.captureStdOut(), "ghostty.bash"); + _ = wf.addCopyFile(run.captureStdOut(.{}), "ghostty.bash"); const install_step = b.addInstallDirectory(.{ .source_dir = wf.getDirectory(), @@ -190,22 +190,22 @@ pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !Ghostty { const run = b.addRunArtifact(build_data_exe); run.addArg("+vim-syntax"); - _ = wf.addCopyFile(run.captureStdOut(), "syntax/ghostty.vim"); + _ = wf.addCopyFile(run.captureStdOut(.{}), "syntax/ghostty.vim"); } { const run = b.addRunArtifact(build_data_exe); run.addArg("+vim-ftdetect"); - _ = wf.addCopyFile(run.captureStdOut(), "ftdetect/ghostty.vim"); + _ = wf.addCopyFile(run.captureStdOut(.{}), "ftdetect/ghostty.vim"); } { const run = b.addRunArtifact(build_data_exe); run.addArg("+vim-ftplugin"); - _ = wf.addCopyFile(run.captureStdOut(), "ftplugin/ghostty.vim"); + _ = wf.addCopyFile(run.captureStdOut(.{}), "ftplugin/ghostty.vim"); } { const run = b.addRunArtifact(build_data_exe); run.addArg("+vim-compiler"); - _ = wf.addCopyFile(run.captureStdOut(), "compiler/ghostty.vim"); + _ = wf.addCopyFile(run.captureStdOut(.{}), "compiler/ghostty.vim"); } const vim_step = b.addInstallDirectory(.{ @@ -233,7 +233,7 @@ pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !Ghostty const run = b.addRunArtifact(build_data_exe); run.addArg("+sublime"); const wf = b.addWriteFiles(); - _ = wf.addCopyFile(run.captureStdOut(), "ghostty.sublime-syntax"); + _ = wf.addCopyFile(run.captureStdOut(.{}), "ghostty.sublime-syntax"); const install_step = b.addInstallDirectory(.{ .source_dir = wf.getDirectory(), @@ -358,10 +358,10 @@ fn addLinuxAppResources( // Template output has a single header line we want to remove. // We use `tail` to do it since its part of the POSIX standard. const tail = b.addSystemCommand(&.{ "tail", "-n", "+2" }); - tail.setStdIn(.{ .lazy_path = tpl.getOutput() }); + tail.setStdIn(.{ .lazy_path = tpl.getOutputFile() }); const copy = b.addInstallFile( - tail.captureStdOut(), + tail.captureStdOut(.{}), template[1], ); diff --git a/vendor/libghostty-vt/src/build/GhosttyWebdata.zig b/vendor/libghostty-vt/src/build/GhosttyWebdata.zig index e29b20c2..7057ad03 100644 --- a/vendor/libghostty-vt/src/build/GhosttyWebdata.zig +++ b/vendor/libghostty-vt/src/build/GhosttyWebdata.zig @@ -40,7 +40,7 @@ pub fn init( } const webgen_config_step = b.addRunArtifact(webgen_config); - const webgen_config_out = webgen_config_step.captureStdOut(); + const webgen_config_out = webgen_config_step.captureStdOut(.{}); try steps.append(b.allocator, &b.addInstallFile( webgen_config_out, @@ -71,7 +71,7 @@ pub fn init( } const webgen_actions_step = b.addRunArtifact(webgen_actions); - const webgen_actions_out = webgen_actions_step.captureStdOut(); + const webgen_actions_out = webgen_actions_step.captureStdOut(.{}); try steps.append(b.allocator, &b.addInstallFile( webgen_actions_out, @@ -102,7 +102,7 @@ pub fn init( } const webgen_commands_step = b.addRunArtifact(webgen_commands); - const webgen_commands_out = webgen_commands_step.captureStdOut(); + const webgen_commands_out = webgen_commands_step.captureStdOut(.{}); try steps.append(b.allocator, &b.addInstallFile( webgen_commands_out, diff --git a/vendor/libghostty-vt/src/build/GhosttyXCFramework.zig b/vendor/libghostty-vt/src/build/GhosttyXCFramework.zig index a19dd18a..3f3b97eb 100644 --- a/vendor/libghostty-vt/src/build/GhosttyXCFramework.zig +++ b/vendor/libghostty-vt/src/build/GhosttyXCFramework.zig @@ -24,35 +24,6 @@ pub fn init( Config.genericMacOSTarget(b, null), )); - // iOS - const ios = try GhosttyLib.initStatic(b, &try deps.retarget( - b, - b.resolveTargetQuery(.{ - .cpu_arch = .aarch64, - .os_tag = .ios, - .os_version_min = Config.osVersionMin(.ios), - .abi = null, - }), - )); - - // iOS Simulator - const ios_sim = try GhosttyLib.initStatic(b, &try deps.retarget( - b, - b.resolveTargetQuery(.{ - .cpu_arch = .aarch64, - .os_tag = .ios, - .os_version_min = Config.osVersionMin(.ios), - .abi = .simulator, - - // We force the Apple CPU model because the simulator - // doesn't support the generic CPU model as of Zig 0.14 due - // to missing "altnzcv" instructions, which is false. This - // surely can't be right but we can fix this if/when we get - // back to running simulator builds. - .cpu_model = .{ .explicit = &std.Target.aarch64.cpu.apple_a17 }, - }), - )); - // Generate a headers directory with only ghostty.h and the module // map. We can't use include/ directly because it also contains the // libghostty-vt headers under include/ghostty/, which would trigger @@ -75,16 +46,6 @@ pub fn init( .headers = headers, .dsym = macos_universal.dsym, }, - .{ - .library = ios.output, - .headers = headers, - .dsym = ios.dsym, - }, - .{ - .library = ios_sim.output, - .headers = headers, - .dsym = ios_sim.dsym, - }, }, .native => &.{.{ diff --git a/vendor/libghostty-vt/src/build/GhosttyXcodebuild.zig b/vendor/libghostty-vt/src/build/GhosttyXcodebuild.zig index 81af994c..6f7e18dc 100644 --- a/vendor/libghostty-vt/src/build/GhosttyXcodebuild.zig +++ b/vendor/libghostty-vt/src/build/GhosttyXcodebuild.zig @@ -48,21 +48,21 @@ pub fn init( }, }; - const env = try std.process.getEnvMap(b.allocator); + const env = b.graph.environ_map; const app_path = b.fmt("macos/build/{s}/Ghostty.app", .{xc_config}); // Our step to build the Ghostty macOS app. const build = build: { // External environment variables can mess up xcodebuild, so // we create a new empty environment. - const env_map = try b.allocator.create(std.process.EnvMap); + const env_map = try b.allocator.create(std.process.Environ.Map); env_map.* = .init(b.allocator); if (env.get("PATH")) |v| try env_map.put("PATH", v); const step = RunStep.create(b, "xcodebuild"); step.has_side_effects = true; step.cwd = b.path("macos"); - step.env_map = env_map; + step.environ_map = env_map; step.addArgs(&.{ "xcodebuild", "-target", @@ -91,14 +91,14 @@ pub fn init( }; const xctest = xctest: { - const env_map = try b.allocator.create(std.process.EnvMap); + const env_map = try b.allocator.create(std.process.Environ.Map); env_map.* = .init(b.allocator); if (env.get("PATH")) |v| try env_map.put("PATH", v); const step = RunStep.create(b, "xcodebuild test"); step.has_side_effects = true; step.cwd = b.path("macos"); - step.env_map = env_map; + step.environ_map = env_map; step.addArgs(&.{ "xcodebuild", "test", diff --git a/vendor/libghostty-vt/src/build/GhosttyZig.zig b/vendor/libghostty-vt/src/build/GhosttyZig.zig index 44c300e1..46ab05d5 100644 --- a/vendor/libghostty-vt/src/build/GhosttyZig.zig +++ b/vendor/libghostty-vt/src/build/GhosttyZig.zig @@ -64,7 +64,7 @@ fn initInner( vt_c_name: []const u8, ) !GhosttyZig { // Terminal module build options - var vt_options = cfg.terminalOptions(.lib); + var vt_options = cfg.terminalOptions(.lib, cfg.optimize); vt_options.artifact = .lib; // We presently don't allow Oniguruma in our Zig module at all. // We should expose this as a build option in the future so we can @@ -135,7 +135,21 @@ fn initVt( deps.unicode_tables.addModuleImport(vt); // We need uucode for grapheme break support - deps.addUucode(b, vt, cfg.target, cfg.optimize); + vt.addImport("uucode", deps.uucode_mod); + + // We need wuffs for Kitty graphics pixel operations (format + // conversion and alpha blending). Unlike pure Zig dependencies + // its C code is compiled whenever the module is in the build + // graph regardless of analysis, so only wire it in when Kitty + // graphics is actually enabled. + if (vt_options.kittyGraphics(cfg.target.result)) { + if (b.lazyDependency("wuffs", .{ + .target = cfg.target, + .optimize = cfg.optimize, + })) |dep| { + vt.addImport("wuffs", dep.module("wuffs")); + } + } // If SIMD is enabled, add all our SIMD dependencies. if (cfg.simd) { diff --git a/vendor/libghostty-vt/src/build/GitVersion.zig b/vendor/libghostty-vt/src/build/GitVersion.zig index 41cc7f84..2365a110 100644 --- a/vendor/libghostty-vt/src/build/GitVersion.zig +++ b/vendor/libghostty-vt/src/build/GitVersion.zig @@ -23,7 +23,7 @@ pub fn detect(b: *std.Build) !Version { const tmp: []u8 = b.runAllowFail( &[_][]const u8{ "git", "-C", b.build_root.path orelse ".", "rev-parse", "--abbrev-ref", "HEAD" }, &code, - .Ignore, + .ignore, ) catch |err| switch (err) { error.FileNotFound => return error.GitNotFound, error.ExitCodeFailure => return error.GitNotRepository, @@ -44,19 +44,19 @@ pub fn detect(b: *std.Build) !Version { const output = b.runAllowFail( &[_][]const u8{ "git", "-C", b.build_root.path orelse ".", "-c", "log.showSignature=false", "log", "--pretty=format:%h", "-n", "1" }, &code, - .Ignore, + .ignore, ) catch |err| switch (err) { error.FileNotFound => return error.GitNotFound, else => return err, }; - break :short_hash std.mem.trimRight(u8, output, "\r\n "); + break :short_hash std.mem.trimEnd(u8, output, "\r\n "); }; const tag = b.runAllowFail( &[_][]const u8{ "git", "-C", b.build_root.path orelse ".", "describe", "--exact-match", "--tags" }, &code, - .Ignore, + .ignore, ) catch |err| switch (err) { error.FileNotFound => return error.GitNotFound, error.ExitCodeFailure => "", // expected @@ -70,7 +70,7 @@ pub fn detect(b: *std.Build) !Version { "diff", "--quiet", "--exit-code", - }, &code, .Ignore) catch |err| switch (err) { + }, &code, .ignore) catch |err| switch (err) { error.FileNotFound => return error.GitNotFound, error.ExitCodeFailure => {}, // expected else => return err, @@ -80,7 +80,7 @@ pub fn detect(b: *std.Build) !Version { return .{ .short_hash = short_hash, .changes = changes, - .tag = if (tag.len > 0) std.mem.trimRight(u8, tag, "\r\n ") else null, - .branch = std.mem.trimRight(u8, branch, "\r\n "), + .tag = if (tag.len > 0) std.mem.trimEnd(u8, tag, "\r\n ") else null, + .branch = std.mem.trimEnd(u8, branch, "\r\n "), }; } diff --git a/vendor/libghostty-vt/src/build/HelpStrings.zig b/vendor/libghostty-vt/src/build/HelpStrings.zig index 96505cab..24ae82e2 100644 --- a/vendor/libghostty-vt/src/build/HelpStrings.zig +++ b/vendor/libghostty-vt/src/build/HelpStrings.zig @@ -34,7 +34,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !HelpStrings { // Generated Zig files have to end with .zig const wf = b.addWriteFiles(); - const output = wf.addCopyFile(help_run.captureStdOut(), "helpgen.zig"); + const output = wf.addCopyFile(help_run.captureStdOut(.{}), "helpgen.zig"); return .{ .exe = exe, diff --git a/vendor/libghostty-vt/src/build/LibsystemOverrideStep.zig b/vendor/libghostty-vt/src/build/LibsystemOverrideStep.zig new file mode 100644 index 00000000..3e1cafa5 --- /dev/null +++ b/vendor/libghostty-vt/src/build/LibsystemOverrideStep.zig @@ -0,0 +1,51 @@ +//! Wraps a Darwin static archive with the libsystem_override.sh +//! post-processing step so that consumers linking the archive bind +//! well-known libc/libm symbols (memcpy, memmove, memset, cos, sin, +//! ...) to Apple's libSystem instead of the bundled Zig compiler-rt. +//! See src/build/libsystem_override.sh for the full rationale. +//! +//! This applies to every static archive we produce, public +//! (e.g. libghostty-vt) and app-internal alike: the compiler-rt +//! bundle must stay because the few symbols libSystem does not +//! provide (f128 conversions, *q math, sincos*, ___zig_probe_stack) +//! have live references, e.g. from the bundled ubsan runtime and +//! x86_64 stack probing in Debug builds. +//! +//! Note shared libraries can't use either approach: Zig 0.16 links +//! compiler-rt as an eagerly-included object, so its definitions are +//! already bound into the dylib at link time and cannot be repaired +//! post-hoc. That needs an upstream Zig fix. +const std = @import("std"); +const builtin = @import("builtin"); + +pub const Result = struct { + /// The step performing the override, or null if the override + /// doesn't apply to this target/host (in which case `output` is + /// the unmodified input). + step: ?*std.Build.Step, + output: std.Build.LazyPath, +}; + +/// Post-process the given static archive on Darwin. Requires a Darwin +/// host for the Apple toolchain (nmedit); in all other configurations +/// this is a no-op and the input is returned unmodified, which is +/// functional (the bundled compiler-rt symbols are used), just slower. +pub fn create( + b: *std.Build, + target: std.Build.ResolvedTarget, + input: std.Build.LazyPath, + out_name: []const u8, +) Result { + if (!target.result.os.tag.isDarwin() or + comptime !builtin.os.tag.isDarwin()) + { + return .{ .step = null, .output = input }; + } + + const run = b.addSystemCommand(&.{"/bin/sh"}); + run.setName("libsystem override"); + run.addFileArg(b.path("src/build/libsystem_override.sh")); + run.addFileArg(input); + const output = run.addOutputFileArg(out_name); + return .{ .step = &run.step, .output = output }; +} diff --git a/vendor/libghostty-vt/src/build/MetallibStep.zig b/vendor/libghostty-vt/src/build/MetallibStep.zig index fcf3055f..81c7a4a9 100644 --- a/vendor/libghostty-vt/src/build/MetallibStep.zig +++ b/vendor/libghostty-vt/src/build/MetallibStep.zig @@ -24,20 +24,10 @@ output: LazyPath, pub fn create(b: *std.Build, opts: Options) ?*MetallibStep { const sdk = switch (opts.target.result.os.tag) { .macos => "macosx", - .ios => switch (opts.target.result.abi) { - // The iOS simulator uses the same SDK for Metal as the device, - // but the minimum version tag causes different behaviors. - .simulator => "iphoneos", - else => "iphoneos", - }, else => return null, }; const platform_version_arg = switch (opts.target.result.os.tag) { .macos => "-mmacos-version-min", - .ios => switch (opts.target.result.abi) { - .simulator => "-mios-simulator-version-min", - else => "-mios-version-min", - }, else => null, }; @@ -47,7 +37,6 @@ pub fn create(b: *std.Build, opts: Options) ?*MetallibStep { b.fmt("{f}", .{v.semver}) else switch (opts.target.result.os.tag) { .macos => "10.14", - .ios => "11.0", else => unreachable, }; diff --git a/vendor/libghostty-vt/src/build/SharedDeps.zig b/vendor/libghostty-vt/src/build/SharedDeps.zig index b68be92d..72abfb9a 100644 --- a/vendor/libghostty-vt/src/build/SharedDeps.zig +++ b/vendor/libghostty-vt/src/build/SharedDeps.zig @@ -9,6 +9,7 @@ const MetallibStep = @import("MetallibStep.zig"); const UnicodeTables = @import("UnicodeTables.zig"); const GhosttyFrameData = @import("GhosttyFrameData.zig"); const DistResource = @import("GhosttyDist.zig").Resource; +const gtk_helpers = @import("gtk.zig"); config: *const Config, @@ -19,6 +20,43 @@ unicode_tables: UnicodeTables, framedata: GhosttyFrameData, uucode_tables: std.Build.LazyPath, +/// Singleton uucode module, instantiated once in `init` and reused +/// everywhere so that ghostty and vaxis share the same compiled tables in +/// each final binary instead of each linking its own copy. +/// +/// Sharing one instance is also a hard requirement (not just an +/// optimization) for Zig 0.16's strict module model. `SharedDeps.add` runs +/// many times across different (target, optimize) tuples (macos-aarch64, +/// macos-x86_64, ios-aarch64, Debug + ReleaseFast, etc.), and on each +/// call we have to wire uucode into both the step's root module and into +/// vaxis_mod (because vaxis's `Parser.zig` does `@import("uucode")` and +/// we pass `external_uucode = true` to vaxis's build.zig so vaxis doesn't +/// instantiate its own uucode dep). If those two import bindings ever +/// resolve to *different* `*Module` pointers within a single Compile +/// step's analysis, Zig fails with: +/// +/// vaxis/src/Parser.zig: file exists in modules 'uucode' and 'uucode0' +/// +/// because all those uucode module instances share the same physical +/// `uucode/src/root.zig` file on disk, and Zig requires every file to belong +/// to exactly one module within a Compile graph. +/// +/// The natural way to keep them the same would be to call +/// `b.lazyDependency("uucode", .{ .tables_path, .build_config_path })` +/// from each call site and let Zig's dependency cache deduplicate +/// identical args. That fails because of a bug in Zig's +/// `userLazyPathsAreTheSame` (Build.zig) where the `.src_path` and +/// `.generated` equality checks are inverted: `if (std.mem.eql(...)) +/// return false` instead of `if (!std.mem.eql(...)) return false`. The +/// dep cache key therefore always misses whenever any arg is a +/// `b.path(...)` LazyPath, so each call returns a fresh `*Dependency` +/// with a fresh `*Module`. Hoisting the dep into one eager +/// `b.dependency` call here sidesteps the cache entirely. +/// +/// This conflict is independent of whether vaxis itself is acquired as a +/// singleton or per-target dep. +uucode_mod: *std.Build.Module, + /// Used to keep track of a list of file sources. pub const LazyPathList = std.ArrayList(std.Build.LazyPath); @@ -31,12 +69,26 @@ pub fn init(b: *std.Build, cfg: *const Config) !SharedDeps { break :blk uucode.namedLazyPath("tables.zig"); }; + // Instantiate the singleton uucode module that both ghostty and vaxis + // import. See the doc comment on `uucode_mod`. + const uucode_mod = b.dependency("uucode", .{ + .tables_path = uucode_tables, + .build_config_path = b.path("src/build/uucode_config.zig"), + }).module("uucode"); + + // Re-export the uucode module so that Zig programs that embed libgtostty-vt + // can use it. This is necessary to use libraries like libvaxis in + // the embedding program that need uucode as well (libvaxis provides + // -Dexternal_uucode for this). + try b.modules.put(b.allocator, b.dupe("uucode"), uucode_mod); + var result: SharedDeps = .{ .config = cfg, .help_strings = try .init(b, cfg), .unicode_tables = try .init(b, uucode_tables), .framedata = try .init(b), .uucode_tables = uucode_tables, + .uucode_mod = uucode_mod, // Setup by retarget .options = undefined, @@ -133,7 +185,10 @@ pub fn add( step.root_module.addOptions("build_options", self.options); // Every exe needs the terminal options - self.config.terminalOptions(.ghostty).add(b, step.root_module); + self.config.terminalOptions(.ghostty, optimize).add(b, step.root_module); + + // Every exe needs the uucode module + step.root_module.addImport("uucode", self.uucode_mod); // C imports for locale constants and functions { @@ -143,11 +198,15 @@ pub fn add( .optimize = optimize, }); if (target.result.os.tag.isDarwin()) { - const libc = try std.zig.LibCInstallation.findNative(.{ - .allocator = b.allocator, - .target = &target.result, - .verbose = false, - }); + const libc = try std.zig.LibCInstallation.findNative( + b.allocator, + b.graph.io, + .{ + .environ_map = &b.graph.environ_map, + .target = &target.result, + .verbose = false, + }, + ); c.addSystemIncludePath(.{ .cwd_relative = libc.sys_include_dir.? }); } step.root_module.addImport("locale-c", c.createModule()); @@ -166,11 +225,15 @@ pub fn add( }); switch (target.result.os.tag) { .macos => { - const libc = try std.zig.LibCInstallation.findNative(.{ - .allocator = b.allocator, - .target = &target.result, - .verbose = false, - }); + const libc = try std.zig.LibCInstallation.findNative( + b.allocator, + b.graph.io, + .{ + .environ_map = &b.graph.environ_map, + .target = &target.result, + .verbose = false, + }, + ); c.addSystemIncludePath(.{ .cwd_relative = libc.sys_include_dir.? }); }, else => {}, @@ -194,10 +257,10 @@ pub fn add( ); if (b.systemIntegrationOption("freetype", .{})) { - step.linkSystemLibrary2("bzip2", dynamic_link_opts); - step.linkSystemLibrary2("freetype2", dynamic_link_opts); + step.root_module.linkSystemLibrary("bzip2", dynamic_link_opts); + step.root_module.linkSystemLibrary("freetype2", dynamic_link_opts); } else { - step.linkLibrary(freetype_dep.artifact("freetype")); + step.root_module.linkLibrary(freetype_dep.artifact("freetype")); try static_libs.append( b.allocator, freetype_dep.artifact("freetype").getEmittedBin(), @@ -219,9 +282,9 @@ pub fn add( harfbuzz_dep.module("harfbuzz"), ); if (b.systemIntegrationOption("harfbuzz", .{})) { - step.linkSystemLibrary2("harfbuzz", dynamic_link_opts); + step.root_module.linkSystemLibrary("harfbuzz", dynamic_link_opts); } else { - step.linkLibrary(harfbuzz_dep.artifact("harfbuzz")); + step.root_module.linkLibrary(harfbuzz_dep.artifact("harfbuzz")); try static_libs.append( b.allocator, harfbuzz_dep.artifact("harfbuzz").getEmittedBin(), @@ -243,9 +306,9 @@ pub fn add( ); if (b.systemIntegrationOption("fontconfig", .{})) { - step.linkSystemLibrary2("fontconfig", dynamic_link_opts); + step.root_module.linkSystemLibrary("fontconfig", dynamic_link_opts); } else { - step.linkLibrary(fontconfig_dep.artifact("fontconfig")); + step.root_module.linkLibrary(fontconfig_dep.artifact("fontconfig")); try static_libs.append( b.allocator, fontconfig_dep.artifact("fontconfig").getEmittedBin(), @@ -263,7 +326,7 @@ pub fn add( .target = target, .optimize = optimize, })) |libpng_dep| { - step.linkLibrary(libpng_dep.artifact("png")); + step.root_module.linkLibrary(libpng_dep.artifact("png")); try static_libs.append( b.allocator, libpng_dep.artifact("png").getEmittedBin(), @@ -277,7 +340,7 @@ pub fn add( .target = target, .optimize = optimize, })) |zlib_dep| { - step.linkLibrary(zlib_dep.artifact("z")); + step.root_module.linkLibrary(zlib_dep.artifact("z")); try static_libs.append( b.allocator, zlib_dep.artifact("z").getEmittedBin(), @@ -295,9 +358,9 @@ pub fn add( oniguruma_dep.module("oniguruma"), ); if (b.systemIntegrationOption("oniguruma", .{})) { - step.linkSystemLibrary2("oniguruma", dynamic_link_opts); + step.root_module.linkSystemLibrary("oniguruma", dynamic_link_opts); } else { - step.linkLibrary(oniguruma_dep.artifact("oniguruma")); + step.root_module.linkLibrary(oniguruma_dep.artifact("oniguruma")); try static_libs.append( b.allocator, oniguruma_dep.artifact("oniguruma").getEmittedBin(), @@ -312,13 +375,13 @@ pub fn add( })) |glslang_dep| { step.root_module.addImport("glslang", glslang_dep.module("glslang")); if (b.systemIntegrationOption("glslang", .{})) { - step.linkSystemLibrary2("glslang", dynamic_link_opts); - step.linkSystemLibrary2( + step.root_module.linkSystemLibrary("glslang", dynamic_link_opts); + step.root_module.linkSystemLibrary( "glslang-default-resource-limits", dynamic_link_opts, ); } else { - step.linkLibrary(glslang_dep.artifact("glslang")); + step.root_module.linkLibrary(glslang_dep.artifact("glslang")); try static_libs.append( b.allocator, glslang_dep.artifact("glslang").getEmittedBin(), @@ -336,9 +399,9 @@ pub fn add( spirv_cross_dep.module("spirv_cross"), ); if (b.systemIntegrationOption("spirv-cross", .{})) { - step.linkSystemLibrary2("spirv-cross-c-shared", dynamic_link_opts); + step.root_module.linkSystemLibrary("spirv-cross-c-shared", dynamic_link_opts); } else { - step.linkLibrary(spirv_cross_dep.artifact("spirv_cross")); + step.root_module.linkLibrary(spirv_cross_dep.artifact("spirv_cross")); try static_libs.append( b.allocator, spirv_cross_dep.artifact("spirv_cross").getEmittedBin(), @@ -357,7 +420,7 @@ pub fn add( "sentry", sentry_dep.module("sentry"), ); - step.linkLibrary(sentry_dep.artifact("sentry")); + step.root_module.linkLibrary(sentry_dep.artifact("sentry")); try static_libs.append( b.allocator, sentry_dep.artifact("sentry").getEmittedBin(), @@ -404,18 +467,18 @@ pub fn add( if (step.rootModuleTarget().os.tag == .linux) { const triple = try step.rootModuleTarget().linuxTriple(b.allocator); const path = b.fmt("/usr/lib/{s}", .{triple}); - if (std.fs.accessAbsolute(path, .{})) { - step.addLibraryPath(.{ .cwd_relative = path }); + if (std.Io.Dir.accessAbsolute(b.graph.io, path, .{})) { + step.root_module.addLibraryPath(.{ .cwd_relative = path }); } else |_| {} } // C files - step.linkLibC(); - step.addIncludePath(b.path("src/stb")); + step.root_module.link_libc = true; + step.root_module.addIncludePath(b.path("src/stb")); // Disable ubsan for MSVC: Zig's ubsan runtime cannot be bundled // on Windows (LNK4229), leaving __ubsan_handle_* unresolved when // the static archive is consumed by an external linker. - step.addCSourceFiles(.{ + step.root_module.addCSourceFiles(.{ .files = &.{"src/stb/stb.c"}, .flags = if (step.rootModuleTarget().abi == .msvc) &.{ "-fno-sanitize=undefined", "-fno-sanitize-trap=undefined" } @@ -423,7 +486,7 @@ pub fn add( &.{}, }); if (step.rootModuleTarget().os.tag == .linux) { - step.addIncludePath(b.path("src/apprt/gtk")); + step.root_module.addIncludePath(b.path("src/apprt/gtk")); } // libcpp is required for various dependencies. On MSVC, we must @@ -433,7 +496,7 @@ pub fn add( // include directories (already added via linkLibC above) contain // both C and C++ headers, so linkLibCpp is not needed. if (step.rootModuleTarget().abi != .msvc) { - step.linkLibCpp(); + step.root_module.link_libcpp = true; } // We always require the system SDK so that our system headers are available. @@ -452,8 +515,14 @@ pub fn add( if (b.lazyDependency("opengl", .{})) |dep| { step.root_module.addImport("opengl", dep.module("opengl")); } - if (b.lazyDependency("vaxis", .{})) |dep| { - step.root_module.addImport("vaxis", dep.module("vaxis")); + if (b.lazyDependency("vaxis", .{ + .target = target, + .optimize = optimize, + .external_uucode = true, + })) |dep| { + const vaxis = dep.module("vaxis"); + step.root_module.addImport("vaxis", vaxis); + vaxis.addImport("uucode", self.uucode_mod); } if (b.lazyDependency("wuffs", .{ .target = target, @@ -473,7 +542,6 @@ pub fn add( })) |dep| { step.root_module.addImport("z2d", dep.module("z2d")); } - self.addUucode(b, step.root_module, target, optimize); if (b.lazyDependency("zf", .{ .target = target, .optimize = optimize, @@ -502,7 +570,7 @@ pub fn add( "macos", macos_dep.module("macos"), ); - step.linkLibrary( + step.root_module.linkLibrary( macos_dep.artifact("macos"), ); try static_libs.append( @@ -512,7 +580,7 @@ pub fn add( } if (self.config.renderer == .opengl) { - step.linkFramework("OpenGL"); + step.root_module.linkFramework("OpenGL", .{}); } // Apple platforms do not include libc libintl so we bundle it. @@ -523,7 +591,7 @@ pub fn add( .target = target, .optimize = optimize, })) |libintl_dep| { - step.linkLibrary(libintl_dep.artifact("intl")); + step.root_module.linkLibrary(libintl_dep.artifact("intl")); try static_libs.append( b.allocator, libintl_dep.artifact("intl").getEmittedBin(), @@ -543,7 +611,7 @@ pub fn add( .@"backend-opengl3" = !target.result.os.tag.isDarwin(), })) |dep| { step.root_module.addImport("dcimgui", dep.module("dcimgui")); - step.linkLibrary(dep.artifact("dcimgui")); + step.root_module.linkLibrary(dep.artifact("dcimgui")); try static_libs.append( b.allocator, dep.artifact("dcimgui").getEmittedBin(), @@ -592,15 +660,38 @@ pub fn add( // If we're building an exe then we have additional dependencies. if (step.kind != .lib) { // We always statically compile glad - step.addIncludePath(b.path("vendor/glad/include/")); - step.addCSourceFile(.{ + step.root_module.addIncludePath(b.path("vendor/glad/include/")); + step.root_module.addCSourceFile(.{ .file = b.path("vendor/glad/src/gl.c"), .flags = &.{}, }); // When we're targeting flatpak we ALWAYS link GTK so we // get access to glib for dbus. - if (self.config.flatpak) step.linkSystemLibrary2("gtk4", dynamic_link_opts); + if (self.config.flatpak) { + step.root_module.linkSystemLibrary("gtk4", dynamic_link_opts); + + // We need to translate gio headers too + gio_translate: { + // translate-c stuff + const translate_c = b.lazyImport(@import("../../build.zig"), "translate_c") orelse + break :gio_translate; + const translate_c_dep = b.lazyDependency("translate_c", .{}) orelse + break :gio_translate; + const translated: translate_c.Translator = .init(translate_c_dep, .{ + .c_source_file = b.addWriteFiles().add("gio_c.h", + \\#include + \\#include + ), + .target = target, + .optimize = optimize, + .link_system_libs = &.{ + .{ .name = "gio-2.0", .options = dynamic_link_opts }, + }, + }); + step.root_module.addImport("gio_c", translated.mod); + } + } switch (self.config.app_runtime) { .none => {}, @@ -634,6 +725,7 @@ fn addGtkNg( .{ "gdk", "gdk4" }, .{ "gio", "gio2" }, .{ "glib", "glib2" }, + .{ "glibunix", "glibunix2" }, .{ "gobject", "gobject2" }, .{ "gtk", "gtk4" }, .{ "xlib", "xlib2" }, @@ -643,12 +735,44 @@ fn addGtkNg( step.root_module.addImport(name, gobject.module(module)); } } - - step.linkSystemLibrary2("gtk4", dynamic_link_opts); - step.linkSystemLibrary2("libadwaita-1", dynamic_link_opts); + gtk_adw_translate: { + // translate-c stuff + const translate_c = b.lazyImport(@import("../../build.zig"), "translate_c") orelse break :gtk_adw_translate; + const translate_c_dep = b.lazyDependency("translate_c", .{}) orelse break :gtk_adw_translate; + const Translator = translate_c.Translator; + + { + // GTK headers + const translated: Translator = .init(translate_c_dep, .{ + .c_source_file = b.addWriteFiles().add("gtk_c.h", + \\#include + ), + .target = target, + .optimize = optimize, + .link_system_libs = &.{ + .{ .name = "gtk4", .options = dynamic_link_opts }, + }, + }); + step.root_module.addImport("gtk_c", translated.mod); + } + { + // Adwaita headers + const translated: Translator = .init(translate_c_dep, .{ + .c_source_file = b.addWriteFiles().add("adw_c.h", + \\#include + ), + .target = target, + .optimize = optimize, + .link_system_libs = &.{ + .{ .name = "libadwaita-1", .options = dynamic_link_opts }, + }, + }); + step.root_module.addImport("adw_c", translated.mod); + } + } if (self.config.x11) { - step.linkSystemLibrary2("X11", dynamic_link_opts); + step.root_module.linkSystemLibrary("X11", dynamic_link_opts); if (gobject_) |gobject| { step.root_module.addImport( "gdk_x11", @@ -699,13 +823,19 @@ fn addGtkNg( ); scanner.addSystemProtocol("staging/xdg-activation/xdg-activation-v1.xml"); scanner.addSystemProtocol("staging/ext-background-effect/ext-background-effect-v1.xml"); + scanner.addCustomProtocol( + b.path("src/apprt/gtk/winproto/wayland/protocols/vicinae-hotkey-v1.xml"), + ); scanner.generate("wl_compositor", 1); + // Only referenced by vicinae_hotkey_manager_v1.bind (nullable arg). + scanner.generate("wl_seat", 1); scanner.generate("org_kde_kwin_server_decoration_manager", 1); scanner.generate("org_kde_kwin_slide_manager", 1); scanner.generate("kde_output_order_v1", 1); scanner.generate("xdg_activation_v1", 1); scanner.generate("ext_background_effect_manager_v1", 1); + scanner.generate("vicinae_hotkey_manager_v1", 1); step.root_module.addImport("wayland", b.createModule(.{ .root_source_file = scanner.result, @@ -732,24 +862,39 @@ fn addGtkNg( // IMPORTANT: gtk4-layer-shell must be linked BEFORE // wayland-client, as it relies on shimming libwayland's APIs. if (b.systemIntegrationOption("gtk4-layer-shell", .{})) { - step.linkSystemLibrary2("gtk4-layer-shell-0", dynamic_link_opts); + step.root_module.linkSystemLibrary("gtk4-layer-shell-0", dynamic_link_opts); } else { // gtk4-layer-shell *must* be dynamically linked, // so we don't add it as a static library const shared_lib = gtk4_layer_shell.artifact("gtk4-layer-shell"); b.installArtifact(shared_lib); - step.linkLibrary(shared_lib); + step.root_module.linkLibrary(shared_lib); } } - step.linkSystemLibrary2("wayland-client", dynamic_link_opts); + step.root_module.linkSystemLibrary("wayland-client", dynamic_link_opts); } - { + ghostty_resources_translate: { // Get our gresource c/h files and add them to our build. const dist = gtkNgDistResources(b); - step.addCSourceFile(.{ .file = dist.resources_c.path(b), .flags = &.{} }); - step.addIncludePath(dist.resources_h.path(b).dirname()); + const translate_c = b.lazyImport(@import("../../build.zig"), "translate_c") orelse + break :ghostty_resources_translate; + const translate_c_dep = b.lazyDependency("translate_c", .{}) orelse + break :ghostty_resources_translate; + const translated: translate_c.Translator = .init(translate_c_dep, .{ + .c_source_file = b.addWriteFiles().add("c.h", + \\#include + ), + .target = target, + .optimize = optimize, + .link_system_libs = &.{ + .{ .name = "glib-2.0", .options = dynamic_link_opts }, + }, + }); + translated.addIncludePath(dist.resources_h.path(b).dirname()); + translated.mod.addCSourceFile(.{ .file = dist.resources_c.path(b), .flags = &.{} }); + step.root_module.addImport("ghostty_gtk_resources", translated.mod); } } @@ -853,6 +998,11 @@ pub fn addSimd( "-fno-sanitize=undefined", "-fno-sanitize-trap=undefined", }); + if (target.result.abi == .msvc) try flags.appendSlice(b.allocator, &.{ + // -fno-autolink also drops UCRT's /alternatename fallback. + "-D_Avx2WmemEnabledWeakValue=_Avx2WmemEnabled", + "-fno-autolink", + }); m.addCSourceFiles(.{ .files = &.{ @@ -890,11 +1040,25 @@ pub fn gtkNgDistResources( .root_module = b.createModule(.{ .root_source_file = b.path("src/apprt/gtk/build/blueprint.zig"), .target = b.graph.host, + .link_libc = true, }), }); - blueprint_exe.linkLibC(); - blueprint_exe.linkSystemLibrary2("gtk4", dynamic_link_opts); - blueprint_exe.linkSystemLibrary2("libadwaita-1", dynamic_link_opts); + adw_translate: { + // Adwaita headers + const translate_c = b.lazyImport(@import("../../build.zig"), "translate_c") orelse break :adw_translate; + const translate_c_dep = b.lazyDependency("translate_c", .{}) orelse break :adw_translate; + const translated: translate_c.Translator = .init(translate_c_dep, .{ + .c_source_file = b.addWriteFiles().add("adw_c.h", + \\#include + ), + .target = b.graph.host, + .optimize = .Debug, + .link_system_libs = &.{ + .{ .name = "libadwaita-1", .options = dynamic_link_opts }, + }, + }); + blueprint_exe.root_module.addImport("adw_c", translated.mod); + } for (gresource.blueprints) |bp| { const blueprint_run = b.addRunArtifact(blueprint_exe); @@ -923,7 +1087,7 @@ pub fn gtkNgDistResources( xml_run.addFileArg(ui_file); } - break :gresource_xml xml_run.captureStdOut(); + break :gresource_xml xml_run.captureStdOut(.{}); }; const generate_c = b.addSystemCommand(&.{ @@ -964,23 +1128,6 @@ pub fn gtkNgDistResources( }; } -pub fn addUucode( - self: *const SharedDeps, - b: *std.Build, - module: *std.Build.Module, - target: std.Build.ResolvedTarget, - optimize: std.builtin.OptimizeMode, -) void { - if (b.lazyDependency("uucode", .{ - .target = target, - .optimize = optimize, - .tables_path = self.uucode_tables, - .build_config_path = b.path("src/build/uucode_config.zig"), - })) |dep| { - module.addImport("uucode", dep.module("uucode")); - } -} - // For dynamic linking, we prefer dynamic linking and to search by // mode first. Mode first will search all paths for a dynamic library // before falling back to static. diff --git a/vendor/libghostty-vt/src/build/UnicodeTables.zig b/vendor/libghostty-vt/src/build/UnicodeTables.zig index 17a839ea..843ada51 100644 --- a/vendor/libghostty-vt/src/build/UnicodeTables.zig +++ b/vendor/libghostty-vt/src/build/UnicodeTables.zig @@ -54,8 +54,8 @@ pub fn init(b: *std.Build, uucode_tables: std.Build.LazyPath) !UnicodeTables { // Generated Zig files have to end with .zig const wf = b.addWriteFiles(); - const props_output = wf.addCopyFile(props_run.captureStdOut(), "props.zig"); - const symbols_output = wf.addCopyFile(symbols_run.captureStdOut(), "symbols.zig"); + const props_output = wf.addCopyFile(props_run.captureStdOut(.{}), "props.zig"); + const symbols_output = wf.addCopyFile(symbols_run.captureStdOut(.{}), "symbols.zig"); return .{ .props_exe = props_exe, diff --git a/vendor/libghostty-vt/src/build/XCFrameworkStep.zig b/vendor/libghostty-vt/src/build/XCFrameworkStep.zig index 39f0f9ba..5f1b676f 100644 --- a/vendor/libghostty-vt/src/build/XCFrameworkStep.zig +++ b/vendor/libghostty-vt/src/build/XCFrameworkStep.zig @@ -63,8 +63,8 @@ pub fn create(b: *std.Build, opts: Options) *XCFrameworkStep { run.addArg("-output"); run.addArg(opts.out_path); run.expectExitCode(0); - _ = run.captureStdOut(); - _ = run.captureStdErr(); + _ = run.captureStdOut(.{}); + _ = run.captureStdErr(.{}); break :run run; }; run_create.step.dependOn(&run_delete.step); diff --git a/vendor/libghostty-vt/src/build/combine_archives.zig b/vendor/libghostty-vt/src/build/combine_archives.zig index 04ec8e97..3df5ed0e 100644 --- a/vendor/libghostty-vt/src/build/combine_archives.zig +++ b/vendor/libghostty-vt/src/build/combine_archives.zig @@ -11,11 +11,10 @@ const std = @import("std"); -pub fn main() !void { - var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; - const alloc = gpa.allocator(); +pub fn main(init: std.process.Init) !void { + const alloc = init.arena.allocator(); - const args = try std.process.argsAlloc(alloc); + const args = try init.minimal.args.toSlice(alloc); if (args.len < 4) { std.log.err("usage: combine_archives ", .{}); std.process.exit(1); @@ -37,19 +36,20 @@ pub fn main() !void { } try script.appendSlice(alloc, "SAVE\nEND\n"); - var child: std.process.Child = .init(&.{ zig_exe, "ar", "-M" }, alloc); - child.stdin_behavior = .Pipe; - child.stdout_behavior = .Inherit; - child.stderr_behavior = .Inherit; + var child = try std.process.spawn(init.io, .{ + .argv = &.{ zig_exe, "ar", "-M" }, + .stdin = .pipe, + .stdout = .inherit, + .stderr = .inherit, + }); - try child.spawn(); - try child.stdin.?.writeAll(script.items); - child.stdin.?.close(); + try child.stdin.?.writeStreamingAll(init.io, script.items); + child.stdin.?.close(init.io); child.stdin = null; - const term = try child.wait(); - if (term.Exited != 0) { - std.log.err("zig ar -M exited with code {d}", .{term.Exited}); + const term = try child.wait(init.io); + if (term.exited != 0) { + std.log.err("zig ar -M exited with code {d}", .{term.exited}); std.process.exit(1); } } diff --git a/vendor/libghostty-vt/src/build/docker/lib-c-docs/Dockerfile b/vendor/libghostty-vt/src/build/docker/lib-c-docs/Dockerfile index a3cfdcc9..b5d17616 100644 --- a/vendor/libghostty-vt/src/build/docker/lib-c-docs/Dockerfile +++ b/vendor/libghostty-vt/src/build/docker/lib-c-docs/Dockerfile @@ -14,6 +14,7 @@ WORKDIR /ghostty COPY include/ ./include/ COPY images/ ./images/ COPY dist/doxygen/ ./dist/doxygen/ +COPY src/terminal/c/types.schema.json ./src/terminal/c/types.schema.json COPY example/ ./example/ COPY Doxyfile ./ COPY DoxygenLayout.xml ./ diff --git a/vendor/libghostty-vt/src/build/gtk.zig b/vendor/libghostty-vt/src/build/gtk.zig index 7adb3cdb..1035367e 100644 --- a/vendor/libghostty-vt/src/build/gtk.zig +++ b/vendor/libghostty-vt/src/build/gtk.zig @@ -14,7 +14,7 @@ pub fn targets(b: *std.Build) Targets { const output = b.runAllowFail( &.{ "pkg-config", "--variable=targets", "gtk4" }, &code, - .Ignore, + .ignore, ) catch return .{}; const x11 = std.mem.indexOf(u8, output, "x11") != null; diff --git a/vendor/libghostty-vt/src/build/libsystem_override.sh b/vendor/libghostty-vt/src/build/libsystem_override.sh new file mode 100755 index 00000000..14ed191b --- /dev/null +++ b/vendor/libghostty-vt/src/build/libsystem_override.sh @@ -0,0 +1,123 @@ +#!/bin/sh +# +# Darwin-only: rewrite a static archive so that consumers linking it bind +# libc/libm symbols to Apple's libSystem instead of the bundled Zig +# compiler-rt. This uses the Apple toolchain (xcrun, nmedit) and libSystem +# semantics, so it must run on a Darwin host for a Darwin target. +# +# Background: our static library bundles Zig's compiler-rt, which defines +# strong global implementations of libc/libm functions (memcpy, memmove, +# memset, cos, sin, ...). When a consumer (e.g. the macOS app via the +# XCFramework) links this archive, ld64 resolves those symbols from the +# archive instead of libSystem, silently replacing Apple's highly +# optimized implementations (_platform_memmove and friends, vectorized +# libm) with compiler-rt's generic ones. We measured Zig 0.16 (LLVM 21) +# compiler-rt memmove costing several percent of PTY throughput on +# scroll-region workloads versus libSystem's. +# +# The mechanism is to localize (make non-external) the libSystem-provided +# symbols defined by the compiler_rt.o archive member. This keeps +# compiler_rt.o functional for the intrinsics that libSystem does NOT +# provide (e.g. the f128 conversions ___extenddftf2/___extendxftf2, *q +# math, sincos*) while letting every other archive member bind the +# well-known libc/libm symbols to libSystem at final link. +# +# usage: libsystem_override.sh +set -eu + +in="$1" +out="$2" + +tmp="$(mktemp -d)" +trap 'rm -rf "$tmp"' EXIT + +cp -f "$in" "$out" +chmod u+w "$out" + +# The symbols to prefer from libSystem. Everything listed here is a +# stable macOS export (verified against libSystem's link surface). +# Notably NOT listed (not exported by libSystem): the *q (f128) +# variants, sincos/sincosf/sincosl, and all ___-prefixed compiler +# intrinsics except the fortify _chk wrappers below. +cat >"$tmp/localize.txt" <<'EOF' +_bcmp +_memcmp +_memcpy +_memmove +_memset +_strlen +___memcpy_chk +___memmove_chk +___memset_chk +___strcat_chk +___strcpy_chk +_ceil +_ceilf +_ceill +_cos +_cosf +_cosl +_exp +_exp2 +_exp2f +_exp2l +_expf +_expl +_fabs +_fabsf +_fabsl +_floor +_floorf +_floorl +_fma +_fmaf +_fmal +_fmax +_fmaxf +_fmaxl +_fmin +_fminf +_fminl +_fmod +_fmodf +_fmodl +_log +_log10 +_log10f +_log10l +_log2 +_log2f +_log2l +_logf +_logl +_round +_roundf +_roundl +_sin +_sinf +_sinl +_sqrt +_sqrtf +_sqrtl +_tan +_tanf +_tanl +_trunc +_truncf +_truncl +EOF + +cd "$tmp" + +xcrun ar x "$out" compiler_rt.o +chmod 644 compiler_rt.o + +# nmedit takes a keep-list (-s): all current global definitions except +# the ones we want to localize. +xcrun nm -g compiler_rt.o | awk '$2 ~ /^[A-TV-Z]$/ {print $3}' | sort -u >all.txt +sort -u localize.txt >loc.txt +comm -23 all.txt loc.txt >keep.txt +xcrun nmedit -s keep.txt compiler_rt.o + +xcrun ar r "$out" compiler_rt.o +xcrun ranlib "$out" 2>/dev/null || true diff --git a/vendor/libghostty-vt/src/build/mdgen/main_ghostty_1.zig b/vendor/libghostty-vt/src/build/mdgen/main_ghostty_1.zig index 2bb413d9..e511768c 100644 --- a/vendor/libghostty-vt/src/build/mdgen/main_ghostty_1.zig +++ b/vendor/libghostty-vt/src/build/mdgen/main_ghostty_1.zig @@ -1,12 +1,11 @@ const std = @import("std"); const gen = @import("mdgen.zig"); -pub fn main() !void { - var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; - const alloc = gpa.allocator(); +pub fn main(init: std.process.Init) !void { + const alloc = init.arena.allocator(); var buffer: [1024]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&buffer); + var stdout_writer = std.Io.File.stdout().writer(init.io, &buffer); const writer = &stdout_writer.interface; try gen.substitute(alloc, @embedFile("ghostty_1_header.md"), writer); try gen.genActions(writer); diff --git a/vendor/libghostty-vt/src/build/mdgen/main_ghostty_5.zig b/vendor/libghostty-vt/src/build/mdgen/main_ghostty_5.zig index 2123b0bc..4f7c4882 100644 --- a/vendor/libghostty-vt/src/build/mdgen/main_ghostty_5.zig +++ b/vendor/libghostty-vt/src/build/mdgen/main_ghostty_5.zig @@ -1,12 +1,11 @@ const std = @import("std"); const gen = @import("mdgen.zig"); -pub fn main() !void { - var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; - const alloc = gpa.allocator(); +pub fn main(init: std.process.Init) !void { + const alloc = init.arena.allocator(); var buffer: [1024]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&buffer); + var stdout_writer = std.Io.File.stdout().writer(init.io, &buffer); const writer = &stdout_writer.interface; try gen.substitute(alloc, @embedFile("ghostty_5_header.md"), writer); try gen.genConfig(writer, false); diff --git a/vendor/libghostty-vt/src/build/uucode_config.zig b/vendor/libghostty-vt/src/build/uucode_config.zig index 2bb0d450..20c42551 100644 --- a/vendor/libghostty-vt/src/build/uucode_config.zig +++ b/vendor/libghostty-vt/src/build/uucode_config.zig @@ -1,109 +1,162 @@ const std = @import("std"); const assert = std.debug.assert; const config = @import("config.zig"); -const config_x = @import("config.x.zig"); -const d = config.default; -const wcwidth = config_x.wcwidth; -const grapheme_break_no_control = config_x.grapheme_break_no_control; const Allocator = std.mem.Allocator; -fn computeWidth( - alloc: std.mem.Allocator, - cp: u21, - data: anytype, - backing: anytype, - tracking: anytype, -) Allocator.Error!void { - _ = alloc; - _ = cp; - _ = backing; - _ = tracking; - - // This condition is needed as Ghostty currently has a singular concept for - // the `width` of a code point, while `uucode` splits the concept into - // `wcwidth_standalone` and `wcwidth_zero_in_grapheme`. The two cases where - // we want to use the `wcwidth_standalone` despite the code point occupying - // zero width in a grapheme (`wcwidth_zero_in_grapheme`) are emoji - // modifiers and prepend code points. For emoji modifiers we want to - // support displaying them in isolation as color patches, and if prepend - // characters were to be width 0 they would disappear from the output with - // Ghostty's current width 0 handling. Future work will take advantage of - // the new uucode `wcwidth_standalone` vs `wcwidth_zero_in_grapheme` split. - if (data.wcwidth_zero_in_grapheme and !data.is_emoji_modifier and data.grapheme_break_no_control != .prepend) { - data.width = 0; - } else { - data.width = @min(2, data.wcwidth_standalone); - } -} - -const width = config.Extension{ - .inputs = &.{ - "wcwidth_standalone", - "wcwidth_zero_in_grapheme", - "is_emoji_modifier", - "grapheme_break_no_control", +pub const fields = &config.mergeFields(config.fields, &.{ + .{ .name = "width", .type = u2 }, + .{ .name = "is_symbol", .type = bool }, +}); +pub const build_components = &config.mergeComponents(config.build_components, &.{ + .{ + .Impl = WidthComponent, + .inputs = &.{ + "wcwidth_standalone", + "wcwidth_zero_in_grapheme", + "is_emoji_modifier", + "grapheme_break_no_control", + }, + .fields = &.{"width"}, }, - .compute = &computeWidth, - .fields = &.{ - .{ .name = "width", .type = u2 }, + .{ + .Impl = IsSymbolComponent, + .inputs = &.{ "block", "general_category" }, + .fields = &.{"is_symbol"}, }, -}; +}); -fn computeIsSymbol( - alloc: Allocator, - cp: u21, - data: anytype, - backing: anytype, - tracking: anytype, -) Allocator.Error!void { - _ = alloc; - _ = cp; - _ = backing; - _ = tracking; - const block = data.block; - data.is_symbol = data.general_category == .other_private_use or - block == .arrows or - block == .dingbats or - block == .emoticons or - block == .miscellaneous_symbols or - block == .enclosed_alphanumerics or - block == .enclosed_alphanumeric_supplement or - block == .miscellaneous_symbols_and_pictographs or - block == .transport_and_map_symbols; -} - -const is_symbol = config.Extension{ - .inputs = &.{ "block", "general_category" }, - .compute = &computeIsSymbol, - .fields = &.{ - .{ .name = "is_symbol", .type = bool }, - }, -}; +pub const get_components: []const config.Component = &.{}; pub const tables = [_]config.Table{ .{ .name = "runtime", - .extensions = &.{}, .fields = &.{ - d.field("is_emoji_presentation"), - d.field("case_folding_full"), + "is_emoji_presentation", + "case_folding_full", }, }, .{ - .name = "buildtime", - .extensions = &.{ - wcwidth, - grapheme_break_no_control, - width, - is_symbol, + // Fields that libvaxis needs that aren't included in the `runtime` + // table. + .name = "libvaxis_only", + .fields = &.{ + "east_asian_width", + "general_category", + "grapheme_break", }, + }, + .{ + .name = "buildtime", + // Unpacked, because a packed table this size cannot be evaluated + // at comptime by Zig 0.16.0 and this one has to be, whether or not + // anything reads it. + // + // `uucode.get.FieldEnum` is built by walking `@TypeOf(tables)`, so + // instantiating anything that names a field -- `grapheme.Iterator`, + // among others -- materialises every table including this one. In a + // packed layout its rows are a `@bitCast` of a 32000 element `[_]u10`, + // and the compiler gives up on it two different ways depending on + // build options: + // + // tables.zig: error: unable to evaluate comptime expression + // thread panic: TODO implement writeToPackedMemory for more types + // + // Ghostty does not hit this, because its own uses of these fields go + // through the tables generated at build time rather than through + // `uucode.get`. A downstream pairing this config with libvaxis does: + // vaxis measures grapheme widths with `grapheme.Iterator`, so any + // program calling `Vaxis.render` fails to compile. + // + // The cost is the size of a table nothing reads at runtime. The fix + // belongs upstream in uucode or in the compiler; this is what makes + // the pairing build today. + .packing = .unpacked, .fields = &.{ - width.field("width"), - wcwidth.field("wcwidth_zero_in_grapheme"), - grapheme_break_no_control.field("grapheme_break_no_control"), - is_symbol.field("is_symbol"), - d.field("is_emoji_vs_base"), + "width", + "wcwidth_zero_in_grapheme", + "grapheme_break_no_control", + "is_symbol", + "is_emoji_vs_base", }, }, }; + +const WidthComponent = struct { + pub fn build( + comptime InputRow: type, + comptime Row: type, + allocator: std.mem.Allocator, + io: std.Io, + inputs: config.MultiSlice(InputRow), + rows: *config.MultiSlice(Row), + backing: anytype, + tracking: anytype, + ) !void { + _ = allocator; + _ = io; + _ = backing; + _ = tracking; + + rows.len = config.num_code_points; + const items = rows.items(.width); + const standalone = inputs.items(.wcwidth_standalone); + const zero_in_grapheme = inputs.items(.wcwidth_zero_in_grapheme); + const is_emoji_modifier = inputs.items(.is_emoji_modifier); + const grapheme_break_no_control = inputs.items(.grapheme_break_no_control); + + // This condition is needed as Ghostty currently has a singular concept for + // the `width` of a code point, while `uucode` splits the concept into + // `wcwidth_standalone` and `wcwidth_zero_in_grapheme`. The two cases where + // we want to use the `wcwidth_standalone` despite the code point occupying + // zero width in a grapheme (`wcwidth_zero_in_grapheme`) are emoji + // modifiers and prepend code points. For emoji modifiers we want to + // support displaying them in isolation as color patches, and if prepend + // characters were to be width 0 they would disappear from the output with + // Ghostty's current width 0 handling. Future work will take advantage of + // the new uucode `wcwidth_standalone` vs `wcwidth_zero_in_grapheme` split. + for (0..config.num_code_points) |i| { + if (zero_in_grapheme[i] and !is_emoji_modifier[i] and grapheme_break_no_control[i] != .prepend) { + items[i] = 0; + } else { + items[i] = @min(2, standalone[i]); + } + } + } +}; + +const IsSymbolComponent = struct { + pub fn build( + comptime InputRow: type, + comptime Row: type, + allocator: std.mem.Allocator, + io: std.Io, + inputs: config.MultiSlice(InputRow), + rows: *config.MultiSlice(Row), + backing: anytype, + tracking: anytype, + ) !void { + _ = allocator; + _ = io; + _ = backing; + _ = tracking; + + rows.len = config.num_code_points; + const items = rows.items(.is_symbol); + const block = inputs.items(.block); + const general_category = inputs.items(.general_category); + + for (0..config.num_code_points) |i| { + items[i] = + general_category[i] == .other_private_use or + block[i] == .arrows or + block[i] == .dingbats or + block[i] == .emoticons or + block[i] == .miscellaneous_symbols or + block[i] == .enclosed_alphanumerics or + block[i] == .enclosed_alphanumeric_supplement or + block[i] == .miscellaneous_symbols_and_pictographs or + block[i] == .transport_and_map_symbols; + } + } +}; diff --git a/vendor/libghostty-vt/src/build/wasm_patch_growable_table.zig b/vendor/libghostty-vt/src/build/wasm_patch_growable_table.zig index c40c0a9c..555734ab 100644 --- a/vendor/libghostty-vt/src/build/wasm_patch_growable_table.zig +++ b/vendor/libghostty-vt/src/build/wasm_patch_growable_table.zig @@ -12,15 +12,13 @@ const std = @import("std"); const testing = std.testing; const Allocator = std.mem.Allocator; -pub fn main() !void { +pub fn main(init: std.process.Init) !void { // This is a one-off patcher, so we leak all our memory on purpose // and let the OS clean it up when we exit. - var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; - const alloc = gpa.allocator(); + const alloc = init.arena.allocator(); // Parse args: program input output - const args = try std.process.argsAlloc(alloc); - defer std.process.argsFree(alloc, args); + const args = try init.minimal.args.toSlice(alloc); if (args.len != 3) { std.log.err("usage: wasm_growable_table ", .{}); std.process.exit(1); @@ -30,17 +28,18 @@ pub fn main() !void { // Patch the file. const output: []const u8 = try patchTableGrowable( alloc, - try std.fs.cwd().readFileAlloc( - alloc, + try std.Io.Dir.cwd().readFileAlloc( + init.io, args[1], - std.math.maxInt(usize), + alloc, + .unlimited, ), ); // Write our output - const out_file = try std.fs.cwd().createFile(args[2], .{}); - defer out_file.close(); - try out_file.writeAll(output); + const out_file = try std.Io.Dir.cwd().createFile(init.io, args[2], .{}); + defer out_file.close(init.io); + try out_file.writePositionalAll(init.io, output, 0); } /// Patch the WASM binary's table section to remove the maximum size diff --git a/vendor/libghostty-vt/src/build/webgen/main_actions.zig b/vendor/libghostty-vt/src/build/webgen/main_actions.zig index b0de6537..38cda3f7 100644 --- a/vendor/libghostty-vt/src/build/webgen/main_actions.zig +++ b/vendor/libghostty-vt/src/build/webgen/main_actions.zig @@ -1,9 +1,9 @@ const std = @import("std"); const helpgen_actions = @import("../../input/helpgen_actions.zig"); -pub fn main() !void { +pub fn main(init: std.process.Init) !void { var buffer: [2048]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&buffer); + var stdout_writer = std.Io.File.stdout().writer(init.io, &buffer); const stdout = &stdout_writer.interface; try helpgen_actions.generate(stdout, .markdown, true, std.heap.page_allocator); } diff --git a/vendor/libghostty-vt/src/build/webgen/main_commands.zig b/vendor/libghostty-vt/src/build/webgen/main_commands.zig index 65f14452..c895948d 100644 --- a/vendor/libghostty-vt/src/build/webgen/main_commands.zig +++ b/vendor/libghostty-vt/src/build/webgen/main_commands.zig @@ -2,9 +2,9 @@ const std = @import("std"); const Action = @import("../../cli/ghostty.zig").Action; const help_strings = @import("help_strings"); -pub fn main() !void { +pub fn main(init: std.process.Init) !void { var buffer: [2048]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&buffer); + var stdout_writer = std.Io.File.stdout().writer(init.io, &buffer); const stdout = &stdout_writer.interface; try genActions(stdout); } diff --git a/vendor/libghostty-vt/src/build/webgen/main_config.zig b/vendor/libghostty-vt/src/build/webgen/main_config.zig index 1363fadc..82ecc950 100644 --- a/vendor/libghostty-vt/src/build/webgen/main_config.zig +++ b/vendor/libghostty-vt/src/build/webgen/main_config.zig @@ -2,9 +2,9 @@ const std = @import("std"); const Config = @import("../../config/Config.zig"); const help_strings = @import("help_strings"); -pub fn main() !void { +pub fn main(init: std.process.Init) !void { var buffer: [2048]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&buffer); + var stdout_writer = std.Io.File.stdout().writer(init.io, &buffer); const stdout = &stdout_writer.interface; try genConfig(stdout); } diff --git a/vendor/libghostty-vt/src/cli/Pager.zig b/vendor/libghostty-vt/src/cli/Pager.zig index 247c998e..1523c885 100644 --- a/vendor/libghostty-vt/src/cli/Pager.zig +++ b/vendor/libghostty-vt/src/cli/Pager.zig @@ -6,29 +6,31 @@ //! Setting either env var to an empty string disables paging. //! If stdout is not a TTY, writes go directly to stdout. const Pager = @This(); +const builtin = @import("builtin"); const std = @import("std"); const Allocator = std.mem.Allocator; const internal_os = @import("../os/main.zig"); +const global = @import("../global.zig"); /// The pager child process, if one was spawned. child: ?std.process.Child = null, /// The buffered file writer used for both the pager pipe and direct /// stdout paths. -file_writer: std.fs.File.Writer = undefined, +file_writer: std.Io.File.Writer = undefined, /// Initialize the pager. If stdout is a TTY, this spawns the pager /// process. Otherwise, output goes directly to stdout. -pub fn init(alloc: Allocator) Pager { - return .{ .child = initPager(alloc) }; +pub fn init() Pager { + return .{ .child = initPager() }; } /// Writes to the pager process if available; otherwise, stdout. pub fn writer(self: *Pager, buffer: []u8) *std.Io.Writer { if (self.child) |child| { - self.file_writer = child.stdin.?.writer(buffer); + self.file_writer = child.stdin.?.writer(global.io(), buffer); } else { - self.file_writer = std.fs.File.stdout().writer(buffer); + self.file_writer = std.Io.File.stdout().writer(global.io(), buffer); } return &self.file_writer.interface; } @@ -40,45 +42,44 @@ pub fn deinit(self: *Pager) void { // pager sees EOF, then wait for it to exit. self.file_writer.interface.flush() catch {}; if (child.stdin) |stdin| { - stdin.close(); + stdin.close(global.io()); child.stdin = null; } - _ = child.wait() catch {}; + _ = child.wait(global.io()) catch {}; } self.* = undefined; } -fn initPager(alloc: Allocator) ?std.process.Child { - const stdout_file: std.fs.File = .stdout(); - if (!stdout_file.isTty()) return null; +fn initPager() ?std.process.Child { + const stdout_file: std.Io.File = .stdout(); + if (!(stdout_file.isTty(global.io()) catch return null)) return null; + + var env = global.environMap() catch return null; + defer env.deinit(); // Resolve the pager command: $GHOSTTY_PAGER > $PAGER > `less`. // An empty value for either env var disables paging. - const ghostty_var = internal_os.getenv(alloc, "GHOSTTY_PAGER") catch null; - defer if (ghostty_var) |v| v.deinit(alloc); - const pager_var = internal_os.getenv(alloc, "PAGER") catch null; - defer if (pager_var) |v| v.deinit(alloc); - + const ghostty_var = env.get("GHOSTTY_PAGER"); + const pager_var = env.get("PAGER"); const cmd: ?[]const u8 = cmd: { - if (ghostty_var) |v| break :cmd if (v.value.len > 0) v.value else null; - if (pager_var) |v| break :cmd if (v.value.len > 0) v.value else null; + if (ghostty_var) |v| break :cmd if (v.len > 0) v else null; + if (pager_var) |v| break :cmd if (v.len > 0) v else null; break :cmd "less"; }; if (cmd == null) return null; - var child: std.process.Child = .init(&.{cmd.?}, alloc); - child.stdin_behavior = .Pipe; - child.stdout_behavior = .Inherit; - child.stderr_behavior = .Inherit; - - child.spawn() catch return null; - return child; + return std.process.spawn(global.io(), .{ + .argv = &.{cmd.?}, + .stdin = .pipe, + .stdout = .inherit, + .stderr = .inherit, + }) catch null; } test "pager: non-tty" { - var pager: Pager = .init(std.testing.allocator); + var pager: Pager = .init(); defer pager.deinit(); try std.testing.expect(pager.child == null); } diff --git a/vendor/libghostty-vt/src/cli/action.zig b/vendor/libghostty-vt/src/cli/action.zig index 41173a9f..6cedaa09 100644 --- a/vendor/libghostty-vt/src/cli/action.zig +++ b/vendor/libghostty-vt/src/cli/action.zig @@ -11,8 +11,8 @@ pub const DetectError = error{ }; /// Detect the action from CLI args. -pub fn detectArgs(comptime E: type, alloc: Allocator) !?E { - var iter = try std.process.argsWithAllocator(alloc); +pub fn detectArgs(comptime E: type, alloc: Allocator, args: std.process.Args) !?E { + var iter = try args.iterateAllocator(alloc); defer iter.deinit(); return try detectIter(E, &iter); } @@ -83,7 +83,7 @@ test "detect direct match" { const alloc = testing.allocator; const Enum = enum { foo, bar, baz }; - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "+foo", ); @@ -97,7 +97,7 @@ test "detect invalid match" { const alloc = testing.allocator; const Enum = enum { foo, bar, baz }; - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "+invalid", ); @@ -113,7 +113,7 @@ test "detect multiple actions" { const alloc = testing.allocator; const Enum = enum { foo, bar, baz }; - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "+foo +bar", ); @@ -129,7 +129,7 @@ test "detect no match" { const alloc = testing.allocator; const Enum = enum { foo, bar, baz }; - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "--some-flag", ); @@ -154,7 +154,7 @@ test "detect special case action" { }; { - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "--special +bar", ); @@ -164,7 +164,7 @@ test "detect special case action" { } { - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "+bar --special", ); @@ -174,7 +174,7 @@ test "detect special case action" { } { - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "+bar", ); @@ -200,7 +200,7 @@ test "detect special case fallback" { }; { - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "--special", ); @@ -210,7 +210,7 @@ test "detect special case fallback" { } { - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "+bar --special", ); @@ -220,7 +220,7 @@ test "detect special case fallback" { } { - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "--special +bar", ); @@ -246,7 +246,7 @@ test "detect special case abort_if_no_action" { }; { - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "-e", ); @@ -256,7 +256,7 @@ test "detect special case abort_if_no_action" { } { - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "+foo -e", ); @@ -266,7 +266,7 @@ test "detect special case abort_if_no_action" { } { - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( alloc, "-e +bar", ); diff --git a/vendor/libghostty-vt/src/cli/args.zig b/vendor/libghostty-vt/src/cli/args.zig index bd5060d6..38616fc0 100644 --- a/vendor/libghostty-vt/src/cli/args.zig +++ b/vendor/libghostty-vt/src/cli/args.zig @@ -489,18 +489,13 @@ pub fn parseTaggedUnion(comptime T: type, alloc: Allocator, v: []const u8) !T { // We need to create a struct that looks like this union field. // This lets us use parseIntoField as if its a dedicated struct. - const Target = @Type(.{ .@"struct" = .{ - .layout = .auto, - .fields = &.{.{ - .name = field.name, - .type = field.type, - .default_value_ptr = null, - .is_comptime = false, - .alignment = @alignOf(field.type), - }}, - .decls = &.{}, - .is_tuple = false, - } }); + const Target = @Struct( + .auto, + null, + &.{field.name}, + &.{field.type}, + &.{.{ .@"align" = @alignOf(field.type) }}, + ); // Parse the value into the struct var t: Target = undefined; @@ -677,7 +672,7 @@ test "parse: simple" { } = .{}; defer if (data._arena) |arena| arena.deinit(); - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( testing.allocator, "--a=42 --b --b-f=false", ); @@ -689,7 +684,7 @@ test "parse: simple" { try testing.expect(!data.@"b-f"); // Reparsing works - var iter2 = try std.process.ArgIteratorGeneral(.{}).init( + var iter2 = try std.process.Args.IteratorGeneral(.{}).init( testing.allocator, "--a=84", ); @@ -711,7 +706,7 @@ test "parse: quoted value" { } = .{}; defer if (data._arena) |arena| arena.deinit(); - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( testing.allocator, "--a=\"42\" --b=\"hello!\"", ); @@ -731,7 +726,7 @@ test "parse: empty value resets to default" { } = .{}; defer if (data._arena) |arena| arena.deinit(); - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( testing.allocator, "--a= --b=", ); @@ -750,7 +745,7 @@ test "parse: positional arguments are invalid" { } = .{}; defer if (data._arena) |arena| arena.deinit(); - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( testing.allocator, "--a=84 what", ); @@ -774,7 +769,7 @@ test "parse: diagnostic tracking" { } = .{}; defer if (data._arena) |arena| arena.deinit(); - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( testing.allocator, "--what --a=42", ); @@ -858,7 +853,7 @@ test "parse: compatibility handler" { } = .{}; defer if (data._arena) |arena| arena.deinit(); - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( testing.allocator, "--a=yuh", ); @@ -884,7 +879,7 @@ test "parse: compatibility renamed" { } = .{}; defer if (data._arena) |arena| arena.deinit(); - var iter = try std.process.ArgIteratorGeneral(.{}).init( + var iter = try std.process.Args.IteratorGeneral(.{}).init( testing.allocator, "--old=true --b=true", ); @@ -1363,8 +1358,11 @@ pub fn ArgsIterator(comptime Iterator: type) type { } /// Create an args iterator for the process args. This will skip argv0. -pub fn argsIterator(alloc_gpa: Allocator) internal_os.args.ArgIterator.InitError!ArgsIterator(internal_os.args.ArgIterator) { - var iter = try internal_os.args.iterator(alloc_gpa); +pub fn argsIterator( + alloc_gpa: Allocator, + args: std.process.Args, +) std.process.Args.Iterator.InitError!ArgsIterator(std.process.Args.Iterator) { + var iter: std.process.Args.Iterator = try .initAllocator(args, alloc_gpa); errdefer iter.deinit(); _ = iter.next(); // skip argv0 return .{ .iterator = iter }; @@ -1373,7 +1371,7 @@ pub fn argsIterator(alloc_gpa: Allocator) internal_os.args.ArgIterator.InitError test "ArgsIterator" { const testing = std.testing; - const child = try std.process.ArgIteratorGeneral(.{}).init( + const child = try std.process.Args.IteratorGeneral(.{}).init( testing.allocator, "--what +list-things --a=42", ); @@ -1456,8 +1454,15 @@ pub const LineIterator = struct { entry = entry[0..trim.len]; } - // Ignore blank lines and comments - if (entry.len == 0 or entry[0] == '#') continue; + // Ignore blank lines and comments. If this line consumed the + // remaining buffer, refill before the loop condition checks for + // more data. + if (entry.len == 0 or entry[0] == '#') { + if (self.r.seek == self.r.end) { + self.r.fillMore() catch {}; + } + continue; + } break entry; } else return null; @@ -1625,3 +1630,27 @@ test "LineIterator with buffered and primed reader" { try testing.expectEqual(@as(?[]const u8, null), iter.next()); try testing.expectEqual(@as(?[]const u8, null), iter.next()); } + +test "LineIterator refills after ignored line at buffer boundary" { + const testing = std.testing; + + { + var f: std.Io.Reader = .fixed("#\nA\n"); + var buf: [2]u8 = undefined; + var r = f.limited(.unlimited, &buf); + var iter: LineIterator = .init(&r.interface); + + try testing.expectEqualStrings("--A", iter.next().?); + try testing.expectEqual(@as(?[]const u8, null), iter.next()); + } + + { + var f: std.Io.Reader = .fixed("\nA\n"); + var buf: [1]u8 = undefined; + var r = f.limited(.unlimited, &buf); + var iter: LineIterator = .init(&r.interface); + + try testing.expectEqualStrings("--A", iter.next().?); + try testing.expectEqual(@as(?[]const u8, null), iter.next()); + } +} diff --git a/vendor/libghostty-vt/src/cli/boo.zig b/vendor/libghostty-vt/src/cli/boo.zig index 2834eadb..a33d56ae 100644 --- a/vendor/libghostty-vt/src/cli/boo.zig +++ b/vendor/libghostty-vt/src/cli/boo.zig @@ -3,6 +3,7 @@ const builtin = @import("builtin"); const args = @import("args.zig"); const Action = @import("ghostty.zig").Action; const Allocator = std.mem.Allocator; +const global = @import("../global.zig"); const vaxis = @import("vaxis"); const framedata = @import("framedata").compressed; @@ -173,6 +174,9 @@ const Boo = struct { /// The `boo` command is used to display the animation from the Ghostty website in the terminal pub fn run(gpa: Allocator) !u8 { + var env_map = try global.environMap(); + defer env_map.deinit(); + // Disable on non-desktop systems. switch (builtin.os.tag) { .windows, .macos, .linux, .freebsd => {}, @@ -183,7 +187,7 @@ pub fn run(gpa: Allocator) !u8 { defer opts.deinit(); { - var iter = try args.argsIterator(gpa); + var iter = try args.argsIterator(gpa, global.args()); defer iter.deinit(); try args.parse(Options, gpa, &opts, &iter); } @@ -194,7 +198,7 @@ pub fn run(gpa: Allocator) !u8 { gpa.free(decompressed_data); } - var app = try vxfw.App.init(gpa); + var app = try vxfw.App.init(global.io(), gpa, &env_map, &.{}); defer app.deinit(); var boo: Boo = undefined; diff --git a/vendor/libghostty-vt/src/cli/crash_report.zig b/vendor/libghostty-vt/src/cli/crash_report.zig index f0940fda..e189ddae 100644 --- a/vendor/libghostty-vt/src/cli/crash_report.zig +++ b/vendor/libghostty-vt/src/cli/crash_report.zig @@ -4,6 +4,7 @@ const args = @import("args.zig"); const Action = @import("ghostty.zig").Action; const Config = @import("../config.zig").Config; const crash = @import("../crash/main.zig"); +const global = @import("../global.zig"); pub const Options = struct { pub fn deinit(self: Options) void { @@ -33,32 +34,36 @@ pub fn run(alloc_gpa: Allocator) !u8 { defer opts.deinit(); { - var iter = try args.argsIterator(alloc_gpa); + var iter = try args.argsIterator(alloc_gpa, global.args()); defer iter.deinit(); try args.parse(Options, alloc_gpa, &opts, &iter); } var buffer: [1024]u8 = undefined; - var stdout_file: std.fs.File = .stdout(); - var stdout_writer = stdout_file.writer(&buffer); + var stdout_file: std.Io.File = .stdout(); + var stdout_writer = stdout_file.writer(global.io(), &buffer); const stdout = &stdout_writer.interface; - const result = runInner(alloc, &stdout_file, stdout); + var environ_map = try global.environMap(); + defer environ_map.deinit(); + const result = runInner(global.io(), alloc, &environ_map, &stdout_file, stdout); stdout.flush() catch {}; return result; } fn runInner( + io: std.Io, alloc: Allocator, - stdout_file: *std.fs.File, + environ_map: *const std.process.Environ.Map, + stdout_file: *std.Io.File, stdout: *std.Io.Writer, ) !u8 { - const crash_dir = try crash.defaultDir(alloc); + const crash_dir = try crash.defaultDir(io, alloc, environ_map); var reports: std.ArrayList(crash.Report) = .empty; errdefer reports.deinit(alloc); - var it = try crash_dir.iterator(); - while (try it.next()) |report| try reports.append(alloc, .{ + var it = try crash_dir.iterator(io); + while (try it.next(io)) |report| try reports.append(alloc, .{ .name = try alloc.dupe(u8, report.name), .mtime = report.mtime, }); @@ -66,7 +71,7 @@ fn runInner( // If we have no reports, then we're done. If we have a tty then we // print a message, otherwise we do nothing. if (reports.items.len == 0) { - if (std.posix.isatty(stdout_file.handle)) { + if (try stdout_file.isTty(global.io())) { try stdout.writeAll("No crash reports! 👻\n"); } return 0; @@ -76,7 +81,7 @@ fn runInner( for (reports.items) |report| { var buf: [128]u8 = undefined; - const now = std.time.nanoTimestamp(); + const now = std.Io.Timestamp.now(global.io(), .real).toNanoseconds(); const diff = now - report.mtime; const since = if (diff <= 0) "now" else s: { const d = Config.Duration{ .duration = @intCast(diff) }; diff --git a/vendor/libghostty-vt/src/cli/diagnostics.zig b/vendor/libghostty-vt/src/cli/diagnostics.zig index 7f4dcc45..0e4048a0 100644 --- a/vendor/libghostty-vt/src/cli/diagnostics.zig +++ b/vendor/libghostty-vt/src/cli/diagnostics.zig @@ -93,7 +93,7 @@ pub const Location = union(enum) { /// and potentially in the future structure them differently. pub const DiagnosticList = struct { /// The list of diagnostics. - list: std.ArrayListUnmanaged(Diagnostic) = .{}, + list: std.ArrayList(Diagnostic) = .empty, /// Precomputed data for diagnostics. This is used specifically /// when we build libghostty so that we can precompute the messages @@ -111,7 +111,7 @@ pub const DiagnosticList = struct { }; const Precompute = if (precompute_enabled) struct { - messages: std.ArrayListUnmanaged([:0]const u8) = .{}, + messages: std.ArrayList([:0]const u8) = .empty, pub fn clone( self: *const Precompute, diff --git a/vendor/libghostty-vt/src/cli/edit_config.zig b/vendor/libghostty-vt/src/cli/edit_config.zig index c08651a0..cc6aec6b 100644 --- a/vendor/libghostty-vt/src/cli/edit_config.zig +++ b/vendor/libghostty-vt/src/cli/edit_config.zig @@ -7,6 +7,7 @@ const Action = @import("ghostty.zig").Action; const configpkg = @import("../config.zig"); const internal_os = @import("../os/main.zig"); const Config = configpkg.Config; +const global = @import("../global.zig"); pub const Options = struct { pub fn deinit(self: Options) void { @@ -48,14 +49,14 @@ pub fn run(alloc: Allocator) !u8 { // critical where setting up the defer cleanup is a problem. var buffer: [1024]u8 = undefined; - var stderr_writer = std.fs.File.stderr().writer(&buffer); + var stderr_writer = std.Io.File.stderr().writer(global.io(), &buffer); const stderr = &stderr_writer.interface; var opts: Options = .{}; defer opts.deinit(); { - var iter = try args.argsIterator(alloc); + var iter = try args.argsIterator(alloc, global.args()); defer iter.deinit(); try args.parse(Options, alloc, &opts, &iter); } @@ -67,6 +68,12 @@ pub fn run(alloc: Allocator) !u8 { } fn runInner(alloc: Allocator, stderr: *std.Io.Writer) !u8 { + // We require libc because we want to use std.c.environ for envp + // and not have to build that ourselves. We can remove this + // limitation later but Ghostty already heavily requires libc + // so this is not a big deal. + comptime assert(builtin.link_libc); + // We load the configuration once because that will write our // default configuration files to disk. We don't use the config. var config = try Config.load(alloc); @@ -82,99 +89,74 @@ fn runInner(alloc: Allocator, stderr: *std.Io.Writer) !u8 { \\The `ghostty +edit-config` command is not supported on Windows. \\Please edit the configuration file manually at the following path: \\ - \\{s} - \\ - , - .{path}, - ); - return 1; - } - - // Get our editor - const get_env_: ?internal_os.GetEnvResult = env: { - // VISUAL vs. EDITOR: https://unix.stackexchange.com/questions/4859/visual-vs-editor-what-s-the-difference - if (try internal_os.getenv(alloc, "VISUAL")) |v| { - if (v.value.len > 0) break :env v; - v.deinit(alloc); - } - - if (try internal_os.getenv(alloc, "EDITOR")) |v| { - if (v.value.len > 0) break :env v; - v.deinit(alloc); - } - - break :env null; - }; - defer if (get_env_) |v| v.deinit(alloc); - const editor: []const u8 = if (get_env_) |v| v.value else ""; - - // If we don't have `$EDITOR` set then we can't do anything - // but we can still print a helpful message. - if (editor.len == 0) { - try stderr.print( - \\The $EDITOR or $VISUAL environment variable is not set or is empty. - \\This environment variable is required to edit the Ghostty configuration - \\via this CLI command. - \\ - \\Please set the environment variable to your preferred terminal - \\text editor and try again. - \\ - \\If you prefer to edit the configuration file another way, - \\you can find the configuration file at the following path: - \\ \\ , .{}, ); - - // Output the path using the OSC8 sequence so that it is linked. - try stderr.print( - "\x1b]8;;file://{s}\x1b\\{s}\x1b]8;;\x1b\\\n", - .{ path, path }, - ); - return 1; } - const command = command: { - var buffer: std.io.Writer.Allocating = .init(alloc); - defer buffer.deinit(); - const writer = &buffer.writer; - try writer.writeAll(editor); - try writer.writeByte(' '); - { - var sh: internal_os.ShellEscapeWriter = .init(writer); - try sh.writer.writeAll(path); - try sh.writer.flush(); + const command = internal_os.getConfigEditCommand(alloc, path, .{ .default_editor = .failure }) catch |err| { + switch (err) { + error.NoEditorConfigured => { + try stderr.print( + \\The $EDITOR or $VISUAL environment variable is not set or is empty. + \\This environment variable is required to edit the Ghostty configuration + \\via this CLI command. + \\ + \\Please set the environment variable to your preferred terminal + \\text editor and try again. + \\ + \\If you prefer to edit the configuration file another way, + \\you can find the configuration file at the following path: + \\ + \\ + , + .{}, + ); + + // Output the path using the OSC8 sequence so that it is linked. + try stderr.print( + "\x1b]8;;file://{s}\x1b\\{s}\x1b]8;;\x1b\\\n", + .{ path, path }, + ); + + return 1; + }, + error.WriteFailed, + error.OutOfMemory, + => |e| return e, } - try writer.flush(); - break :command try buffer.toOwnedSliceSentinel(0); }; defer alloc.free(command); - // We require libc because we want to use std.c.environ for envp - // and not have to build that ourselves. We can remove this - // limitation later but Ghostty already heavily requires libc - // so this is not a big deal. - comptime assert(builtin.link_libc); - - const err = std.posix.execvpeZ( + // Run/replace process (using execve) + const argv = [_:null]?[*:0]const u8{ "/bin/sh", - &.{ "/bin/sh", "-c", command }, - std.c.environ, - ); + "-c", + command.ptr, + }; + const envp = std.c.environ; + const err = std.posix.errno(std.posix.system.execve(argv[0].?, &argv, envp)); // If we reached this point then exec failed. try stderr.print( - \\Failed to execute the editor. Error code={}. + \\Failed to execute the editor (E{t}). \\ \\This is usually due to the executable path not existing, invalid \\permissions, or the shell environment not being set up \\correctly. \\ - \\Editor: {s} - \\Path: {s} + \\Command: {s} \\ - , .{ err, editor, path }); + , .{ + err, + command, + }); + // Output the path using the OSC8 sequence so that it is linked. + try stderr.print( + "Path: \x1b]8;;file://{s}\x1b\\{s}\x1b]8;;\x1b\\\n", + .{ path, path }, + ); return 1; } diff --git a/vendor/libghostty-vt/src/cli/explain_config.zig b/vendor/libghostty-vt/src/cli/explain_config.zig index 4f034afe..6f03256d 100644 --- a/vendor/libghostty-vt/src/cli/explain_config.zig +++ b/vendor/libghostty-vt/src/cli/explain_config.zig @@ -7,6 +7,7 @@ const Config = @import("../config/Config.zig"); const ConfigKey = @import("../config/key.zig").Key; const KeybindAction = @import("../input/Binding.zig").Action; const Pager = @import("Pager.zig"); +const global = @import("../global.zig"); pub const Options = struct { /// The config option to explain. For example: @@ -51,7 +52,7 @@ pub fn run(alloc: Allocator) !u8 { var positional: ?[]const u8 = null; var no_pager: bool = false; - var iter = try args.argsIterator(alloc); + var iter = try args.argsIterator(alloc, global.args()); defer iter.deinit(); defer if (option_name) |s| alloc.free(s); defer if (keybind_name) |s| alloc.free(s); @@ -75,9 +76,9 @@ pub fn run(alloc: Allocator) !u8 { // respective lookup. A bare positional argument tries config // options first, then keybind actions as a fallback. const name = keybind_name orelse option_name orelse positional orelse { - var stderr: std.fs.File = .stderr(); + var stderr: std.Io.File = .stderr(); var buffer: [4096]u8 = undefined; - var stderr_writer = stderr.writer(&buffer); + var stderr_writer = stderr.writer(global.io(), &buffer); try stderr_writer.interface.writeAll("Usage: ghostty +explain-config