libnotcurses-sys-2.1.8/.cargo/config.toml010064400017500001750000000005211377416467000165630ustar 00000000000000[alias] d = "doc --no-deps" do = "doc --no-deps --open" re = "run --example" rre = "run --release --example" rqe = "run --quiet --example " req = "rqe" # TEST # fix IO errors: https://github.com/dankamongmen/notcurses/issues/766 t = "test -- --test-threads 1 --nocapture" t_all = "test --no-fail-fast -- --test-threads 1 --nocapture" libnotcurses-sys-2.1.8/.cargo_vcs_info.json0000644000000001121400652337300144270ustar { "git": { "sha1": "54ca2249dff8dbba602dbb070cad5e6b5d37cd9d" } } libnotcurses-sys-2.1.8/Cargo.lock0000644000000325271400652337300124210ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] name = "aho-corasick" version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" dependencies = [ "memchr", ] [[package]] name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ "winapi", ] [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", "winapi", ] [[package]] name = "bindgen" version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd4865004a46a0aafb2a0a5eb19d3c9fc46ee5f063a6cfc605c69ac9ecf5263d" dependencies = [ "bitflags", "cexpr", "clang-sys", "clap", "env_logger", "lazy_static", "lazycell", "log", "peeking_take_while", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", "which", ] [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "cexpr" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" dependencies = [ "nom", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clang-sys" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0659001ab56b791be01d4b729c44376edc6718cf389a502e579b77b758f3296c" dependencies = [ "glob", "libc", "libloading", ] [[package]] name = "clap" version = "2.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term", "atty", "bitflags", "strsim", "textwrap", "unicode-width", "vec_map", ] [[package]] name = "cty" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7313c0d620d0cb4dbd9d019e461a4beb501071ff46ec0ab933efb4daa76d73e3" [[package]] name = "env_logger" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e" dependencies = [ "atty", "humantime", "log", "regex", "termcolor", ] [[package]] name = "getrandom" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" dependencies = [ "cfg-if", "libc", "wasi", ] [[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "hermit-abi" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" dependencies = [ "libc", ] [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "instant" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" dependencies = [ "cfg-if", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" [[package]] name = "libloading" version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" dependencies = [ "cfg-if", "winapi", ] [[package]] name = "libnotcurses-sys" version = "2.1.8" dependencies = [ "bindgen", "cty", "libc", "pkg-config", "rand", "serial_test", "serial_test_derive", ] [[package]] name = "lock_api" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" dependencies = [ "scopeguard", ] [[package]] name = "log" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ "cfg-if", ] [[package]] name = "memchr" version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "nom" version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" dependencies = [ "memchr", "version_check", ] [[package]] name = "once_cell" version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" [[package]] name = "parking_lot" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" dependencies = [ "instant", "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272" dependencies = [ "cfg-if", "instant", "libc", "redox_syscall", "smallvec", "winapi", ] [[package]] name = "peeking_take_while" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pkg-config" version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" [[package]] name = "ppv-lite86" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "proc-macro2" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ "unicode-xid", ] [[package]] name = "quote" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" dependencies = [ "proc-macro2", ] [[package]] name = "rand" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" dependencies = [ "libc", "rand_chacha", "rand_core", "rand_hc", ] [[package]] name = "rand_chacha" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5" dependencies = [ "getrandom", ] [[package]] name = "rand_hc" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" dependencies = [ "rand_core", ] [[package]] name = "redox_syscall" version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "regex" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" dependencies = [ "aho-corasick", "memchr", "regex-syntax", "thread_local", ] [[package]] name = "regex-syntax" version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serial_test" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0bccbcf40c8938196944a3da0e133e031a33f4d6b72db3bda3cc556e361905d" dependencies = [ "lazy_static", "parking_lot", "serial_test_derive", ] [[package]] name = "serial_test_derive" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2acd6defeddb41eb60bb468f8825d0cfd0c2a76bc03bfd235b6a1dc4f6a1ad5" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "shlex" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" [[package]] name = "smallvec" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" dependencies = [ "proc-macro2", "quote", "unicode-xid", ] [[package]] name = "termcolor" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" dependencies = [ "winapi-util", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ "unicode-width", ] [[package]] name = "thread_local" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8208a331e1cb318dd5bd76951d2b8fc48ca38a69f5f4e4af1b6a9f8c6236915" dependencies = [ "once_cell", ] [[package]] name = "unicode-width" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "vec_map" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "which" version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" dependencies = [ "libc", ] [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" libnotcurses-sys-2.1.8/Cargo.toml0000644000000031011400652337300124260ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "libnotcurses-sys" version = "2.1.8" authors = ["nick black ", "José Luis Cruz "] build = "build/build.rs" links = "notcurses" description = "Low-level Rust bindings for the notcurses C library." homepage = "https://nick-black.com/dankwiki/index.php/Notcurses" documentation = "https://dankamongmen.github.io/notcurses/rustdoc/libnotcurses_sys/" keywords = ["tui", "cli", "terminal", "ncurses", "ffi"] categories = ["external-ffi-bindings", "command-line-interface", "visualization", "multimedia", "rendering"] license = "Apache-2.0" repository = "https://github.com/dankamongmen/notcurses" [profile.dev] [profile.release] [dependencies.cty] version = ">= 0.2.1" [dependencies.libc] version = ">= 0.2.80" default-features = false [dev-dependencies.rand] version = ">= 0.8" [dev-dependencies.serial_test] version = ">= 0.5.0" [dev-dependencies.serial_test_derive] version = ">= 0.5.0" [build-dependencies.bindgen] version = ">= 0.55.1" [build-dependencies.pkg-config] version = ">= 0.3.18" libnotcurses-sys-2.1.8/Cargo.toml.orig010064400017500001750000000023301400652310700161160ustar 00000000000000[package] name = "libnotcurses-sys" version = "2.1.8" authors = [ "nick black ", "José Luis Cruz " ] license = "Apache-2.0" edition = "2018" description = "Low-level Rust bindings for the notcurses C library." documentation = "https://dankamongmen.github.io/notcurses/rustdoc/libnotcurses_sys/" repository = "https://github.com/dankamongmen/notcurses" homepage = "https://nick-black.com/dankwiki/index.php/Notcurses" links = "notcurses" build = "build/build.rs" categories = [ "external-ffi-bindings", "command-line-interface", "visualization", "multimedia", "rendering", ] keywords = ["tui", "cli", "terminal", "ncurses", "ffi"] [dependencies] libc = {version = ">= 0.2.80", default-features = false} cty = ">= 0.2.1" [build-dependencies] bindgen = ">= 0.55.1" pkg-config = ">= 0.3.18" [dev-dependencies] serial_test = ">= 0.5.0" serial_test_derive = ">= 0.5.0" # for the examples rand = ">= 0.8" # https://doc.rust-lang.org/cargo/reference/profiles.html [profile.dev] # [profile.release] # opt-level = 0 # [0-*3 | s | z] # lto = "fat" # [*fat | thin] # debug = 1 # [*0/false | 1 | 2/true] # debug-assertions = true # [*false | true] libnotcurses-sys-2.1.8/LICENSE010064400017500001750000000236761400637712100142570ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS libnotcurses-sys-2.1.8/README.md010064400017500001750000000007611377422371100145250ustar 00000000000000# libnotcurses-sys [![Crate](https://img.shields.io/crates/v/libnotcurses-sys.svg)](https://crates.io/crates/libnotcurses-sys) [![API](https://docs.rs/libnotcurses-sys/badge.svg)](https://dankamongmen.github.io/notcurses/rustdoc/libnotcurses_sys/) [![dependency status](https://deps.rs/crate/libnotcurses-sys/2.1.2/status.svg)](https://deps.rs/crate/libnotcurses-sys/2.1.2) [![MSRV: 1.48.0](https://flat.badgen.net/badge/MSRV/1.48.0/purple)](https://blog.rust-lang.org/2020/11/19/Rust-1.48.html) libnotcurses-sys-2.1.8/build/build.rs010064400017500001750000000043541400652310700160030ustar 00000000000000extern crate bindgen; extern crate pkg_config; use std::env; use std::path::PathBuf; // largely taken from https://rust-lang.github.io/rust-bindgen/tutorial-3.html fn main() { let plib = pkg_config::Config::new() .atleast_version("2.1.8") .probe("notcurses") .unwrap(); // Tell cargo to invalidate the built crate whenever the wrapper changes println!("cargo:rerun-if-changed=build/wrapper.h"); // The bindgen::Builder is the main entry point to bindgen, and lets you // build up options for the resulting bindings. let mut builder = bindgen::Builder::default() .use_core() .ctypes_prefix("cty") .clang_arg("-D_XOPEN_SOURCE") // The input header we would like to generate builder for. .header("build/wrapper.h") // generate comments, also from headers and not just doc comments (///) .generate_comments(true) .clang_arg("-fretain-comments-from-system-headers") .clang_arg("-fparse-all-comments") // Remove warnings about improper_ctypes .blacklist_function("strtold") .blacklist_function("wcstold") // Don't derive the Copy trait on types with destructors. .no_copy("ncdirect") .no_copy("ncdplot") .no_copy("ncfdplane") .no_copy("ncmenu") .no_copy("ncmultiselector") .no_copy("ncplane") .no_copy("ncreader") .no_copy("ncreel") .no_copy("ncselector") .no_copy("ncuplot") .no_copy("ncvisual") .no_copy("notcurses") // Tell cargo to invalidate the built crate whenever any of the // included header files changed. .parse_callbacks(Box::new(bindgen::CargoCallbacks)); for d in plib.include_paths { builder = builder.clang_arg(format!("-I{}", d.to_string_lossy())); } // Finish the builder and generate the builder. let bindings = builder.generate() // Unwrap the Result and panic on failure. .expect("Unable to generate bindings"); // Write the bindings to the $OUT_DIR/bindings.rs file. let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); } libnotcurses-sys-2.1.8/build/wrapper.h010064400017500001750000000000771376441154400162000ustar 00000000000000#include #include libnotcurses-sys-2.1.8/examples/direct-cursor.rs010064400017500001750000000031031377416724100202150ustar 00000000000000//! Example 'direct-cursor' //! //! Explore cursor functions in direct mode //! use rand::{thread_rng, Rng}; use libnotcurses_sys::*; fn main() -> NcResult<()> { let mut rng = thread_rng(); let mut dm = DirectMode::new()?; let cols = dm.dim_x(); let rows = dm.dim_y(); println!("terminal size (rows, cols): {}, {}", rows, cols); let mut channels = NcChannelPair::combine(NcChannel::with_rgb(0xAA2244), NcChannel::with_rgb(0x112233)); dm.putstr(channels, "The current coordinates are")?; for _n in 0..40 { fsleep![&mut dm, 0, 30]; channels.set_fg_rgb8( rng.gen_range(0x66..=0xEE), rng.gen_range(0x66..=0xEE), rng.gen_range(0x66..=0xEE), ); channels.set_bg_rgb8( rng.gen_range(0..=0x9), rng.gen_range(0..=0x9), rng.gen_range(0..=0x9), ); dm.putstr(channels, ".")?; } let (cy, cx) = dm.cursor_yx()?; dm.putstr(channels, &format!(" ({},{})\n", cy, cx))?; sleep![1]; let sentence = vec![ "And", "now", "I", "will", "clear", "the", "screen", ".", ".", ".", ]; for word in sentence { channels.set_fg_rgb(channels.fg_rgb().wrapping_sub(0x050505)); channels.set_bg_rgb(channels.bg_rgb().wrapping_add(0x090909)); dm.putstr(channels, &format!["{} ", word])?; fsleep![&mut dm, 0, 150]; } sleep![0, 300]; channels.set_fg_rgb(0xFFFFFF); channels.set_bg_default(); dm.putstr(channels, "\nbye!\n\n")?; fsleep![&mut dm, 0, 600]; dm.clear()?; Ok(()) } libnotcurses-sys-2.1.8/examples/direct-image-c.rs010064400017500001750000000015771377416525400202210ustar 00000000000000//! Example 'direct-image' //! //! Explore image rendering in direct mode //! //! NOTE: This example uses the C style with functions. use core::ptr::{null, null_mut}; use libnotcurses_sys::*; fn main() { unsafe { let ncd = ncdirect_init(null(), null_mut(), 0); render_image(&mut *ncd, NCBLIT_1x1); render_image(&mut *ncd, NCBLIT_2x1); render_image(&mut *ncd, NCBLIT_BRAILLE); ncdirect_stop(ncd); } } fn render_image(ncd: &mut NcDirect, blit: NcBlitter) { unsafe { if ncdirect_render_image( ncd, cstring!["image-16x16.png"], NCALIGN_CENTER, blit, NCSCALE_NONE, ) != 0 { panic!( "ERROR: ncdirect_render_image(). Make sure you \ are running this example from the examples folder" ); } } } libnotcurses-sys-2.1.8/examples/direct-image-rust.rs010064400017500001750000000013661377416724100207660ustar 00000000000000//! Example 'direct-image' //! //! Explore image rendering in direct mode //! //! NOTE: This example uses the Rust style with methods. use libnotcurses_sys::*; fn main() -> NcResult<()> { let mut dm = DirectMode::new()?; render_image(&mut dm, NCBLIT_1x1)?; render_image(&mut dm, NCBLIT_2x1)?; render_image(&mut dm, NCBLIT_BRAILLE)?; Ok(()) } fn render_image(dm: &mut DirectMode, blit: NcBlitter) -> NcResult<()> { if let Err(nc_error) = dm.render_image("image-16x16.png", NCALIGN_CENTER, blit, NCSCALE_NONE) { return Err(NcError::with_msg( nc_error.int, "ERROR: dmirect_render_image(). Make sure you \ are running this example from the examples folder", )); } Ok(()) } libnotcurses-sys-2.1.8/examples/full-basics.rs010064400017500001750000000005001377422371100176250ustar 00000000000000use libnotcurses_sys::*; fn main() -> NcResult<()> { let mut nc = FullMode::new()?; let stdplane = nc.stdplane(); for ch in "Initializing cells...".chars() { let cell = NcCell::with_char7b(ch); stdplane.putc(&cell)?; rsleep![&mut nc, 0, 40]; } sleep![0, 900]; Ok(()) } libnotcurses-sys-2.1.8/examples/full-input.rs010064400017500001750000000013761377416724100175410ustar 00000000000000//! Input //! //! https://github.com/dankamongmen/notcurses/blob/master/USAGE.md#input //! use libnotcurses_sys::*; fn main() -> NcResult<()> { let mut nc = FullMode::with_flags( NCOPTION_SUPPRESS_BANNERS | NCOPTION_NO_WINCH_SIGHANDLER | NCOPTION_NO_QUIT_SIGHANDLERS, )?; println!("Exit with F1\n"); let mut input = NcInput::new_empty(); loop { let key = notcurses_getc_nblock(&mut nc, &mut input); if key as i32 != -1 { println!("'{0}' ({1:x})\n{2:?}", key, key as u32, input); } rsleep![&mut nc, 0, 10]; match key { NCKEY_F01 => break, _ => (), } } println!("\nExiting..."); rsleep![&mut nc, 1, 500]; nc.stop()?; Ok(()) } libnotcurses-sys-2.1.8/examples/image-16x16.png010064400017500001750000000006631376441154400174420ustar 00000000000000PNG  IHDRazIDATxP3Q=ضSM]ԥ v?jm۶mor-G$f ^w6d7A?)rR3^iZʿ;[NUO =Ǚ1h׮RFaX^K˗ySVb5L۸[0Sk2k&=DTan [a֬"օUe@Ӄl{6X1yyb^lV8,ܿ?L9`#%JQwk^]ȃiLY73kv2U-Z;vDy+ir~*Ijffvb=0 NcResult<()> { let mut nc = FullMode::new()?; let plane = nc.stdplane(); plane.set_scrolling(true); let mut wc = '\u{4e00}'; // 一 loop { plane.putchar(wc)?; wc = core::char::from_u32(wc as u32 + 1).expect("invalid char"); // 龣 if wc == '\u{9fa5}' { wc = '\u{4e00}'; } rsleep![&mut nc, 0, 0, 30]; } } libnotcurses-sys-2.1.8/examples/poc-direct.rs010064400017500001750000000027461377416724100174750ustar 00000000000000//! based on the proof of concept at ../../src/poc/direct.c use libnotcurses_sys::*; fn main() -> NcResult<()> { let mut dm = DirectMode::new()?; let dimy = dm.dim_y(); let dimx = dm.dim_x(); for _ in 0..dimy { for _ in 0..dimx { printf!("X"); } } dm.flush()?; dm.set_fg_rgb(0xff8080)?; dm.styles_on(NCSTYLE_STANDOUT)?; printf!(" erp erp \n"); dm.set_fg_rgb(0x80ff80)?; printf!(" erp erp \n"); dm.styles_off(NCSTYLE_STANDOUT)?; printf!(" erp erp \n"); dm.set_fg_rgb(0xff8080)?; printf!(" erp erp \n"); dm.cursor_right(dimx / 2)?; dm.cursor_up(dimy / 2)?; printf!(" erperperp! \n"); let (mut y, x); if let Ok((_y, _x)) = dm.cursor_yx() { y = _y; x = _x; printf!("\n\tRead cursor position: y: %d x: %d\n", y, x); y += 2; while y > 3 { let up = if y >= 3 { 3 } else { y }; dm.cursor_up(up)?; dm.flush()?; y -= up; let newy; if let Ok((_y, _)) = dm.cursor_yx() { newy = _y; } else { break; } if newy != y { eprintln!("Expected {}, got {}", y, newy); break; } printf!("\n\tRead cursor position: y: %d x: %d\n", newy, x); y += 2; } } else { return Err(NcError::with_msg(-10, "Couldn't read cursor position.")); } Ok(()) } libnotcurses-sys-2.1.8/examples/poc-kittyzapper.rs010064400017500001750000000007751377416724100206110ustar 00000000000000//! based on the proof of concept at ../../src/poc/kittyzapper.c use libnotcurses_sys::*; fn main() -> NcResult<()> { let mut dm = DirectMode::new()?; dm.set_fg_rgb8(100, 100, 100)?; dm.set_bg_rgb8(0xff, 0xff, 0xff)?; printf!("a"); dm.set_bg_rgb8(0, 0, 0)?; printf!("b"); printf!(" "); printf!(" "); dm.set_bg_rgb8(0, 0, 1)?; printf!("c"); printf!(" "); printf!(" "); dm.set_bg_rgb8(0xff, 0xff, 0xff)?; printf!("d"); printf!("\n"); Ok(()) } libnotcurses-sys-2.1.8/examples/poc-menu.rs010064400017500001750000000104371377422371100171560ustar 00000000000000//! based on the proof of concept at ../../src/poc/menu.c use libnotcurses_sys::*; fn main() -> NcResult<()> { let mut nc = FullMode::new()?; nc.mouse_enable()?; let mut demo_items = [ NcMenuItem::new("Restart", NcInput::with_ctrl('r')), NcMenuItem::new("Disabled", NcInput::with_ctrl('d')), ]; let mut file_items = [ NcMenuItem::new("New", NcInput::with_ctrl('n')), NcMenuItem::new("Open", NcInput::with_ctrl('o')), NcMenuItem::new("Close", NcInput::with_ctrl('c')), NcMenuItem::new_empty(), NcMenuItem::new("Quit", NcInput::with_ctrl('q')), ]; let mut help_items = [NcMenuItem::new("About", NcInput::with_ctrl('a'))]; let mut sections = [ NcMenuSection::new("Schwarzgerät", &mut demo_items, NcInput::with_alt('ä')), NcMenuSection::new("File", &mut file_items, NcInput::with_alt('f')), NcMenuSection::new_separator(), // DEBUG: remove alt modifier for now. NcMenuSection::new("Help", &mut help_items, NcInput::new('h')), ]; let mut mopts = NcMenuOptions::new(&mut sections); mopts.header_channels_mut().set_fg_rgb(0x00ff00); mopts.header_channels_mut().set_bg_rgb(0x440000); mopts.section_channels_mut().set_fg_rgb(0xb0d700); mopts.section_channels_mut().set_bg_rgb(0x002000); let stdplane = nc.stdplane(); let (dim_y, _dim_x) = stdplane.dim_yx(); let menu_top = NcMenu::new(stdplane, mopts)?; menu_top.item_set_status("Schwarzgerät", "Disabled", false)?; menu_top.item_set_status("Schwarzgerät", "Restart", false)?; let mut channels: NcChannelPair = 0; channels.set_fg_rgb(0x88aa00); channels.set_bg_rgb(0x000088); stdplane.set_base("x", 0, channels)?; nc.render()?; stdplane.set_fg_rgb(0x00dddd); stdplane.putstr_aligned( dim_y - 1, NCALIGN_RIGHT, " -=+ menu poc. press q to exit +=-", )?; run_menu(&mut nc, menu_top)?; stdplane.erase(); // is this needed? // BUG FIXME: this doesn't show over the menu (at row 0) stdplane.putstr_aligned(0, NCALIGN_RIGHT, " -=+ menu poc. press q to exit +=-")?; stdplane.putstr_aligned(1, NCALIGN_CENTER, " -=+ menu poc. press q to exit +=-")?; stdplane.putstr_aligned(2, NCALIGN_LEFT, " -=+ menu poc. press q to exit +=-")?; mopts.flags |= NCMENU_OPTION_BOTTOM; let menu_bottom = NcMenu::new(stdplane, mopts)?; run_menu(&mut nc, menu_bottom)?; Ok(()) } fn run_menu(nc: &mut FullMode, menu: &mut NcMenu) -> NcResult<()> { // yellow rectangle let planeopts = NcPlaneOptions::new_aligned(10, NCALIGN_CENTER, 3, 40); let stdplane = nc.stdplane(); let selplane = NcPlane::with_options_bound(stdplane, planeopts)?; selplane.set_fg_rgb(0); selplane.set_bg_rgb(0xdddddd); let mut channels = 0; channels.set_fg_rgb(0x000088); channels.set_bg_rgb(0x88aa00); selplane.set_base(" ", 0, channels)?; let mut ni = NcInput::new_empty(); let mut keypress: char; nc.render()?; loop { stdplane.erase(); selplane.erase(); keypress = nc.getc_blocking(Some(&mut ni))?; // DEBUG stdplane.putstr_yx(2, 0, &format!["{:?}", ni])?; nc.render()?; // BUG FIXME: always returns false: if !menu.offer_input(ni) { match keypress { 'q' => { menu.destroy()?; selplane.destroy()?; return Ok(()); } NCKEY_ENTER => { if let Some(selection) = menu.selected(Some(&mut ni)) { match selection.as_ref() { "Quit" => { menu.destroy()?; selplane.destroy()?; return Ok(()); } _ => (), } } } _ => (), } } let mut selni = NcInput::new_empty(); if let Some(selitem) = menu.selected(Some(&mut selni)) { selplane.putstr_aligned(1, NCALIGN_CENTER, &selitem)?; } else { // DEBUG selplane.putstr_aligned(1, NCALIGN_CENTER, "nothing opened")?; } nc.render()?; } } libnotcurses-sys-2.1.8/src/bindings.rs010064400017500001750000000367771400616507400162140ustar 00000000000000//! A selection of the [ffi] bindings intended to be used directly. //! //! The full list of bindings is under the [ffi] submodule. //! //! The current module publicly re-exports bindgen generated structs, functions, //! and constants, for their direct usage. // [clippy & bindgen](https://github.com/rust-lang/rust-bindgen/issues/1470) #[allow(clippy::all)] pub mod ffi { //! Rust FFI bindings, automatically generated with bindgen. //! //! Almost all of the notcurses API functions are reexported to the public //! API, while structs, enums and constants are type aliased or wrapped up. //! include!(concat!(env!("OUT_DIR"), "/bindings.rs")); } // Miscellaneous --------------------------------------------------------------- #[doc(inline)] pub use ffi::{ // structs __va_list_tag, // functions ncstrwidth, }; // blitset --------------------------------------------------------------------- // // already wrapped: // // // structs // blitset // cell ------------------------------------------------------------------------ // // already wrapped: // // // structs // cell, // // // constants // CELL_ALPHA_BLEND, // CELL_ALPHA_HIGHCONTRAST, // CELL_ALPHA_OPAQUE, // CELL_ALPHA_TRANSPARENT, // CELL_BGDEFAULT_MASK, // CELL_BG_ALPHA_MASK, // CELL_BG_PALETTE, // CELL_BG_RGB_MASK, // CELL_FGDEFAULT_MASK, // CELL_FG_ALPHA_MASK, // CELL_FG_PALETTE, // CELL_FG_RGB_MASK, #[doc(inline)] pub use ffi::{ // functions cell_duplicate, cell_extended_gcluster, cell_load, cell_release, cells_double_box, cells_rounded_box, }; // channel --------------------------------------------------------------------- // // already wrapped: // // // constants // CHANNEL_ALPHA_MASK // ncalign --------------------------------------------------------------------- // // already wrapped: // // // type definitions // ncalign_e, // // // constants // ncalign_e_NCALIGN_CENTER, // ncalign_e_NCALIGN_LEFT, // ncalign_e_NCALIGN_RIGHT, // ncalign_e_NCALIGN_UNALIGNED, // ncblitter ------------------------------------------------------------------- // // already wrapped: // // // type definitions // ncblitter_e, // // // constants // ncblitter_e_NCBLIT_1x1, // ncblitter_e_NCBLIT_2x1, // ncblitter_e_NCBLIT_2x2, // ncblitter_e_NCBLIT_3x2, // ncblitter_e_NCBLIT_4x1, // ncblitter_e_NCBLIT_8x1, // ncblitter_e_NCBLIT_BRAILLE, // ncblitter_e_NCBLIT_DEFAULT, // ncblitter_e_NCBLIT_SIXEL, // ncbox ----------------------------------------------------------------------- // // constants // NCBOXCORNER_MASK, // NCBOXCORNER_SHIFT, // NCBOXGRAD_BOTTOM, // NCBOXGRAD_LEFT, // NCBOXGRAD_RIGHT, // NCBOXGRAD_TOP, // NCBOXMASK_BOTTOM, // NCBOXMASK_LEFT, // NCBOXMASK_RIGHT, // NCBOXMASK_TOP, // ncdirect -------------------------------------------------------------------- // // already wrapped: // // // structs // ncdirect, // // // constants // NCDIRECT_OPTION_INHIBIT_CBREAK, // NCDIRECT_OPTION_INHIBIT_SETLOCALE, // NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS, #[doc(inline)] pub use ffi::{ // functions ncdirect_box, ncdirect_canopen_images, ncdirect_canutf8, ncdirect_clear, ncdirect_cursor_disable, ncdirect_cursor_down, ncdirect_cursor_enable, ncdirect_cursor_left, ncdirect_cursor_move_yx, ncdirect_cursor_pop, ncdirect_cursor_push, ncdirect_cursor_right, ncdirect_cursor_up, ncdirect_cursor_yx, ncdirect_dim_x, ncdirect_dim_y, ncdirect_double_box, ncdirect_flush, ncdirect_getc, ncdirect_hline_interp, ncdirect_init, ncdirect_inputready_fd, ncdirect_off_styles, ncdirect_on_styles, ncdirect_palette_size, ncdirect_printf_aligned, ncdirect_putstr, ncdirect_raster_frame, ncdirect_render_frame, ncdirect_render_image, ncdirect_rounded_box, ncdirect_set_bg_default, ncdirect_set_bg_palindex, ncdirect_set_bg_rgb, ncdirect_set_fg_default, ncdirect_set_fg_palindex, ncdirect_set_fg_rgb, ncdirect_set_styles, ncdirect_stop, ncdirect_vline_interp, }; // ncfadectx ------------------------------------------------------------------- // // already wrapped: // // // structs // ncfadectx, #[doc(inline)] pub use ffi::{ // functions ncfadectx_free, ncfadectx_iterations, ncfadectx_setup, }; // ncinput --------------------------------------------------------------------- // // already wrapped: // // // structs // ncinput, // ncloglevel ------------------------------------------------------------------ // // already wrapped: // // // type definitions // ncloglevel_e, // // // constants // ncloglevel_e_NCLOGLEVEL_DEBUG, // ncloglevel_e_NCLOGLEVEL_ERROR, // ncloglevel_e_NCLOGLEVEL_FATAL, // ncloglevel_e_NCLOGLEVEL_INFO, // ncloglevel_e_NCLOGLEVEL_PANIC, // ncloglevel_e_NCLOGLEVEL_SILENT, // ncloglevel_e_NCLOGLEVEL_TRACE, // ncloglevel_e_NCLOGLEVEL_VERBOSE, // ncloglevel_e_NCLOGLEVEL_WARNING, // ncfdplane ------------------------------------------------------------------- // // already wrapped: // // // structs // ncfdplane, // ncfdplane_options, #[doc(inline)] pub use ffi::{ // functions ncfdplane_create, ncfdplane_destroy, ncfdplane_plane, }; // ncmenu ---------------------------------------------------------------------- // // already wrapped: // // // structs // ncmenu, // ncmenu_item, // ncmenu_options, // ncmenu_section, // // // constants // NCMENU_OPTION_BOTTOM, // NCMENU_OPTION_HIDING, #[doc(inline)] pub use ffi::{ // functions ncmenu_create, ncmenu_destroy, ncmenu_item_set_status, ncmenu_mouse_selected, ncmenu_nextitem, ncmenu_nextsection, ncmenu_offer_input, ncmenu_plane, ncmenu_previtem, ncmenu_prevsection, ncmenu_rollup, ncmenu_selected, ncmenu_unroll, }; // ncmetric -------------------------------------------------------------------- // // already wrapped: // // // constants // PREFIXCOLUMNS, // PREFIXSTRLEN, // BPREFIXCOLUMNS, // BPREFIXSTRLEN, // IPREFIXCOLUMNS, // IPREFIXSTRLEN, #[doc(inline)] pub use ffi::ncmetric; // ncmultiselector ------------------------------------------------------------- // // already wrapped: // // // structs // ncmultiselector, // ncmselector_item, // ncmultiselector_options, #[doc(inline)] pub use ffi::{ // functions ncmultiselector_create, ncmultiselector_destroy, ncmultiselector_offer_input, ncmultiselector_plane, ncmultiselector_selected, }; // ncpile ---------------------------------------------------------------------- #[doc(inline)] pub use ffi::{ // functions ncpile_bottom, ncpile_create, ncpile_rasterize, ncpile_render, ncpile_top, }; // ncplane --------------------------------------------------------------------- // // already wrapped: // // // structs // ncplane, // ncplane_options, // // // constants // NCPLANE_OPTION_HORALIGNED, #[doc(inline)] pub use ffi::{ // functions ncplane_above, ncplane_at_cursor, ncplane_at_cursor_cell, ncplane_at_yx, ncplane_at_yx_cell, ncplane_base, ncplane_below, ncplane_box, ncplane_center_abs, ncplane_channels, ncplane_contents, ncplane_create, ncplane_cursor_move_yx, ncplane_cursor_yx, ncplane_destroy, ncplane_dim_yx, ncplane_dup, ncplane_erase, ncplane_fadein, ncplane_fadein_iteration, ncplane_fadeout, ncplane_fadeout_iteration, ncplane_format, ncplane_gradient, ncplane_greyscale, ncplane_highgradient, ncplane_highgradient_sized, ncplane_hline_interp, ncplane_home, ncplane_mergedown, ncplane_mergedown_simple, ncplane_move_above, ncplane_move_below, ncplane_move_bottom, ncplane_move_top, ncplane_move_yx, ncplane_notcurses, ncplane_notcurses_const, ncplane_off_styles, ncplane_on_styles, ncplane_parent, ncplane_parent_const, ncplane_polyfill_yx, ncplane_pulse, ncplane_putc_yx, ncplane_putchar_stained, ncplane_putegc_stained, ncplane_putegc_yx, ncplane_putnstr_aligned, ncplane_putnstr_yx, ncplane_putstr_aligned, ncplane_putstr_stained, ncplane_putstr_yx, ncplane_puttext, ncplane_putwegc_stained, ncplane_putwstr_stained, ncplane_qrcode, ncplane_reparent, ncplane_reparent_family, ncplane_resize, ncplane_resize_maximize, ncplane_resize_realign, ncplane_resizecb, ncplane_rgba, ncplane_rotate_ccw, ncplane_rotate_cw, ncplane_set_base, ncplane_set_base_cell, ncplane_set_bchannel, ncplane_set_bg_alpha, ncplane_set_bg_default, ncplane_set_bg_palindex, ncplane_set_bg_rgb, ncplane_set_bg_rgb8, ncplane_set_bg_rgb8_clipped, ncplane_set_channels, ncplane_set_fchannel, ncplane_set_fg_alpha, ncplane_set_fg_default, ncplane_set_fg_palindex, ncplane_set_fg_rgb, ncplane_set_fg_rgb8, ncplane_set_fg_rgb8_clipped, ncplane_set_resizecb, ncplane_set_scrolling, ncplane_set_styles, ncplane_set_userptr, ncplane_stain, ncplane_styles, ncplane_styles_off, ncplane_styles_on, ncplane_styles_set, ncplane_translate, ncplane_translate_abs, ncplane_userptr, ncplane_vline_interp, ncplane_vprintf_aligned, ncplane_vprintf_stained, ncplane_vprintf_yx, ncplane_x, ncplane_y, ncplane_yx, }; // ncplot ---------------------------------------------------------------------- // // already wrapped: // // // structs // ncdplot, // f64 // ncuplot, // u64 // ncplot_options, // // // constants // NCPLOT_OPTION_DETECTMAXONLY, // NCPLOT_OPTION_EXPONENTIALD, // NCPLOT_OPTION_LABELTICKSD, // NCPLOT_OPTION_NODEGRADE, // NCPLOT_OPTION_VERTICALI, #[doc(inline)] pub use ffi::{ // functions ncdplot_add_sample, ncdplot_create, ncdplot_destroy, ncdplot_plane, ncdplot_sample, ncdplot_set_sample, ncuplot_add_sample, ncuplot_create, ncuplot_destroy, ncuplot_plane, ncuplot_sample, ncuplot_set_sample, }; // ncreader -------------------------------------------------------------------- // // already wrapped: // // // structs // ncreader, // ncreader_options, // // // constants // NCREADER_OPTION_CURSOR, // NCREADER_OPTION_HORSCROLL, // NCREADER_OPTION_NOCMDKEYS, // NCREADER_OPTION_VERSCROLL, #[doc(inline)] pub use ffi::{ // functions ncreader_clear, ncreader_contents, ncreader_create, ncreader_destroy, ncreader_move_down, ncreader_move_left, ncreader_move_right, ncreader_move_up, ncreader_offer_input, ncreader_plane, ncreader_write_egc, }; // ncprogbar ------------------------------------------------------------------- // // already wrapped: // // // structs // ncprogbar, // ncprogbar_options, // // // constants // NCPROGBAR_OPTION_RETROGRADE #[doc(inline)] pub use ffi::{ // functions ncprogbar_create, ncprogbar_destroy, ncprogbar_plane, ncprogbar_progress, ncprogbar_set_progress, }; // ncreel ---------------------------------------------------------------------- // // already wrapped: // // // structs // ncreel, // ncreel_options, // // // constants // NCREEL_OPTION_CIRCULAR, // NCREEL_OPTION_INFINITESCROLL, #[doc(inline)] pub use ffi::{ // functions ncreel_add, ncreel_create, ncreel_del, ncreel_destroy, ncreel_focused, ncreel_next, ncreel_offer_input, ncreel_plane, ncreel_prev, ncreel_redraw, ncreel_tabletcount, }; // ncscale --------------------------------------------------------------------- // // already wrapped: // // // type definitions // ncscale_e, // // // constants // ncscale_e_NCSCALE_NONE, // ncscale_e_NCSCALE_SCALE, // ncscale_e_NCSCALE_STRETCH, // ncselector ------------------------------------------------------------------ // // already wrapped: // // // structs // ncselector, // ncselector_item, // ncselector_options, #[doc(inline)] pub use ffi::{ // functions ncselector_additem, ncselector_create, ncselector_delitem, ncselector_destroy, ncselector_nextitem, ncselector_offer_input, ncselector_plane, ncselector_previtem, ncselector_selected, }; // ncstats --------------------------------------------------------------------- // // already wrapped: // // // structs // ncstats, // ncstyle --------------------------------------------------------------------- // // already wrapped: // // // constants // NCSTYLE_BLINK, // NCSTYLE_BOLD, // NCSTYLE_DIM, // NCSTYLE_INVIS, // NCSTYLE_ITALIC, // NCSTYLE_MASK, // NCSTYLE_NONE, // NCSTYLE_PROTECT, // NCSTYLE_REVERSE, // NCSTYLE_STANDOUT, // NCSTYLE_STRUCK, // NCSTYLE_UNDERLINE, // nctablet -------------------------------------------------------------------- // // already wrapped: // // // structs // nctablet, #[doc(inline)] pub use ffi::{ // functions nctablet_plane, nctablet_userptr, }; // ncvisual -------------------------------------------------------------------- // // already wrapped: // // // structs // ncvisual, // ncvisual_options, // // // constants // NCVISUAL_OPTION_BLEND, // NCVISUAL_OPTION_NODEGRADE, #[doc(inline)] pub use ffi::{ // functions ncvisual_at_yx, ncvisual_decode, ncvisual_decode_loop, ncvisual_destroy, ncvisual_from_bgra, ncvisual_from_file, ncvisual_from_plane, ncvisual_from_rgba, ncvisual_geom, ncvisual_media_defblitter, ncvisual_polyfill_yx, ncvisual_render, ncvisual_resize, ncvisual_rotate, ncvisual_set_yx, ncvisual_simple_streamer, ncvisual_stream, ncvisual_subtitle, }; // notcurses ------------------------------------------------------------------- // // already wrapped: // // // structs // notcurses, // notcurses_options, // // // constants // NCOPTION_INHIBIT_SETLOCALE, // NCOPTION_NO_ALTERNATE_SCREEN, // NCOPTION_NO_FONT_CHANGES, // NCOPTION_NO_QUIT_SIGHANDLERS, // NCOPTION_NO_WINCH_SIGHANDLER, // NCOPTION_SUPPRESS_BANNERS, // NCOPTION_VERIFY_SIXEL, #[doc(inline)] pub use ffi::{ // functions notcurses_at_yx, notcurses_bottom, notcurses_canchangecolor, notcurses_canfade, notcurses_canopen_images, notcurses_canopen_videos, notcurses_cansextant, notcurses_cansixel, notcurses_cantruecolor, notcurses_canutf8, notcurses_cursor_disable, notcurses_cursor_enable, notcurses_debug, notcurses_drop_planes, notcurses_getc, notcurses_init, notcurses_inputready_fd, notcurses_lex_blitter, notcurses_lex_margins, notcurses_lex_scalemode, notcurses_linesigs_disable, notcurses_linesigs_enable, notcurses_mouse_disable, notcurses_mouse_enable, notcurses_palette_size, notcurses_refresh, notcurses_render, notcurses_render_to_buffer, notcurses_render_to_file, notcurses_stats, notcurses_stats_alloc, notcurses_stats_reset, notcurses_stdplane, notcurses_stdplane_const, notcurses_stop, notcurses_str_blitter, notcurses_str_scalemode, notcurses_supported_styles, notcurses_top, notcurses_ucs32_to_utf8, notcurses_version, notcurses_version_components, }; // palette --------------------------------------------------------------------- // // already wrapped: // // // structs // palette256, #[doc(inline)] pub use ffi::{ // functions palette256_free, palette256_new, palette256_use, // constants NCPALETTESIZE, }; // sig ------------------------------------------------------------------------- // // already wrapped: // // // structs // sigset_t, // sigaction, // // // functions // sigaddset, // sigdelset, // sigemptyset, // sigfillset, // sigismember, // sigpending, // sigprocmask, // sigsuspend, // fade callback --------------------------------------------------------------- // // already wrapped: // // // types // fadecb libnotcurses-sys-2.1.8/src/box.rs010064400017500001750000000051021376775765500152120ustar 00000000000000//! `NcBoxMask` /// Controls the drawing of borders, gradients and corners. /// /// NcBoxMax is defined in the least significant byte, where bits [3, 0] are /// are a border mask, and bits [7, 4] are a gradient mask. /// /// The drawing of the corners is defined in the second byte, /// see [`NCBOXCORNER_MASK`]. /// /// ## Diagram /// /// ```txt /// NCBOXMASK_TOP 0x0001 0b00000001 /// NCBOXMASK_RIGHT 0x0002 0b00000010 /// NCBOXMASK_BOTTOM 0x0004 0b00000100 /// NCBOXMASK_LEFT 0x0008 0b00001000 /// /// NCBOXGRAD_TOP 0x0010 0b00010000 /// NCBOXGRAD_RIGHT 0x0020 0b00100000 /// NCBOXGRAD_BOTTOM 0x0040 0b01000000 /// NCBOXGRAD_LEFT 0x0080 0b10000000 /// /// NCBOXCORNER_MASK 0x0300 0b00000111_00000000 /// /// NCBOXCORNER_SHIFT 8 /// ``` /// /// ## Bit masks /// /// - [NCBOXMASK_TOP] /// - [NCBOXMASK_RIGHT] /// - [NCBOXMASK_BOTTOM] /// - [NCBOXMASK_LEFT] /// /// - [NCBOXGRAD_TOP] /// - [NCBOXGRAD_RIGHT] /// - [NCBOXGRAD_BOTTOM] /// - [NCBOXGRAD_LEFT] /// /// - [NCBOXCORNER_MASK] /// - [NCBOXCORNER_SHIFT] /// pub type NcBoxMask = u32; /// [NcBoxMask] top gradient mask. pub const NCBOXGRAD_TOP: NcBoxMask = crate::bindings::ffi::NCBOXGRAD_TOP; /// [NcBoxMask] right gradient mask. pub const NCBOXGRAD_RIGHT: NcBoxMask = crate::bindings::ffi::NCBOXGRAD_RIGHT; /// [NcBoxMask] bottom gradient mask. pub const NCBOXGRAD_BOTTOM: NcBoxMask = crate::bindings::ffi::NCBOXGRAD_BOTTOM; /// [NcBoxMask] left gradient mask. pub const NCBOXGRAD_LEFT: NcBoxMask = crate::bindings::ffi::NCBOXGRAD_LEFT; /// [NcBoxMask] top border mask. pub const NCBOXMASK_TOP: NcBoxMask = crate::bindings::ffi::NCBOXMASK_TOP; /// [NcBoxMask] right border mask. pub const NCBOXMASK_RIGHT: NcBoxMask = crate::bindings::ffi::NCBOXMASK_RIGHT; /// [NcBoxMask] bottom border mask. pub const NCBOXMASK_BOTTOM: NcBoxMask = crate::bindings::ffi::NCBOXMASK_BOTTOM; /// [NcBoxMask] left border mask. pub const NCBOXMASK_LEFT: NcBoxMask = crate::bindings::ffi::NCBOXMASK_LEFT; /// [NcBoxMask] corner mask to control the drawing of boxes corners. /// /// By default, vertexes are drawn whether their connecting edges are drawn /// or not. The value of the bits control this, and are interpreted as the /// number of connecting edges necessary to draw a given corner. /// /// At 0 (the default), corners are always drawn. At 3, corners are never drawn /// (since at most 2 edges can touch a box's corner). pub const NCBOXCORNER_MASK: NcBoxMask = crate::bindings::ffi::NCBOXCORNER_MASK; /// The number of bits [NCBOXCORNER_MASK] is shifted in [NcBoxMask]. pub const NCBOXCORNER_SHIFT: NcBoxMask = crate::bindings::ffi::NCBOXCORNER_SHIFT; libnotcurses-sys-2.1.8/src/cells/methods.rs010064400017500001750000000413261377726434200171620ustar 00000000000000//! `NcCell` methods and associated functions. use crate::{ cell_load, cstring, error, NcAlphaBits, NcCell, NcChannel, NcChannelPair, NcColor, NcEgc, NcEgcBackstop, NcPaletteIndex, NcPlane, NcResult, NcRgb, NcStyleMask, NCRESULT_ERR, }; /// # NcCell constructors impl NcCell { /// New NcCell, expects a 7-bit [char]. #[inline] pub const fn with_char7b(ch: char) -> Self { NcCell { gcluster: (ch as u32).to_le(), gcluster_backstop: 0 as NcEgcBackstop, width: 0_u8, stylemask: 0 as NcStyleMask, channels: 0 as NcChannelPair, } } /// New NcCell, expects an [NcPlane] and a [char]. #[inline] pub fn with_char(ch: char, plane: &mut NcPlane) -> Self { let mut cell = Self::new(); let result = unsafe { cell_load(plane, &mut cell, cstring![ch.to_string()]) }; debug_assert_ne![NCRESULT_ERR, result]; cell } /// New NcCell, expects an [NcPlane] and a &[str]. #[inline] pub fn with_str(plane: &mut NcPlane, string: &str) -> Self { let mut cell = Self::new(); let result = unsafe { cell_load(plane, &mut cell, cstring![string]) }; debug_assert_ne![NCRESULT_ERR, result]; cell } /// New empty NcCell. #[inline] pub const fn new() -> Self { Self::with_char7b(0 as char) } /// Breaks the UTF-8 string in `egc` down, setting up this NcCell, /// and returns the number of bytes copied out of `egc`. /// /// The styling of the cell is left untouched, but any resources are released. /// *C style function: [cell_load()][crate::cell_load].* pub fn load(plane: &mut NcPlane, cell: &mut NcCell, egc: &str) -> NcResult { let bytes = unsafe { crate::cell_load(plane, cell, cstring![egc]) }; error![ bytes, &format!["NcCell.load(NcPlane, NcCell, {:?})", egc], bytes as u32 ] } /// Same as [load][NcCell#method.load], plus blasts the styling with /// `style` and `channels`. /// /// - Breaks the UTF-8 string in `gcluster` down, setting up this NcCell. /// - Returns the number of bytes copied out of `gcluster`. /// - The styling of the cell is left untouched, but any resources are released. /// - Blasts the styling with `style` and `channels`. /// /// *C style function: [cell_prime()][crate::cell_prime].* pub fn prime( plane: &mut NcPlane, cell: &mut NcCell, gcluster: &str, style: NcStyleMask, channels: NcChannelPair, ) -> NcResult { let bytes = crate::cell_prime(plane, cell, gcluster, style, channels); error![bytes, "", bytes as u32] } /// Duplicate this NcCell into another one. /// /// Both must be or will be bound to `common_plane`. /// /// *C style function: [cell_duplicate()][crate::cell_duplicate].* pub fn duplicate(&self, target: &mut NcCell, common_plane: &mut NcPlane) -> NcResult<()> { error![unsafe { crate::cell_duplicate(common_plane, target, self) }] } /// Initializes (zeroes out) the NcCell. /// /// *C style function: [cell_init()][crate::cell_init].* #[inline] pub fn init(&mut self) { crate::cell_init(self); } /// Releases resources held by the current cell in the [NcPlane] `plane`. /// /// *C style function: [cell_release()][crate::cell_release].* pub fn release(&mut self, plane: &mut NcPlane) { unsafe { crate::cell_release(plane, self); } } } // ----------------------------------------------------------------------------- /// ## NcCell methods: bg|fg `NcChannel`s manipulation. impl NcCell { /// Returns the [NcChannelPair] of the NcCell. /// /// *(No equivalent C style function)* pub fn channels(&mut self, plane: &mut NcPlane) -> NcChannelPair { let (mut _styles, mut channels) = (0, 0); let _char = crate::cell_extract(plane, self, &mut _styles, &mut channels); channels } /// Gets the background [NcChannel]. /// /// *C style function: [cell_bchannel()][crate::cell_bchannel].* pub fn bchannel(&self) -> NcChannel { crate::cell_bchannel(self) } /// Extracts the background [NcAlphaBits] (shifted to LSBs). /// /// *C style function: [cell_bg_alpha()][crate::cell_bg_alpha].* pub fn bg_alpha(&self) -> NcAlphaBits { crate::cell_bg_alpha(self) } /// Is the background [NcChannel] using the "default background color"? /// /// *C style function: [cell_bg_default_p()][crate::cell_bg_default_p].* pub fn bg_default_p(&self) -> bool { crate::cell_bg_default_p(self) } /// Gets the [NcPaletteIndex] of the background [NcChannel]. /// /// *C style function: [cell_bg_palindex()][crate::cell_bg_palindex].* pub fn bg_palindex(&self) -> NcPaletteIndex { crate::cell_bg_palindex(self) } /// Is the background [NcChannel] using an [NcPaletteIndex] indexed /// [NcPalette][crate::NcPalette] color? /// /// *C style function: [cell_bg_palindex_p()][crate::cell_bg_palindex_p].* pub fn bg_palindex_p(&self) -> bool { crate::cell_bg_palindex_p(self) } /// Gets the background [NcRgb] (shifted to LSBs). /// /// *C style function: [cell_bg_rgb()][crate::cell_bg_rgb].* pub fn bg_rgb(&self) -> NcRgb { crate::cell_bg_rgb(self) } /// Gets the background [NcColor] RGB components. /// /// *C style function: [cell_bg_rgb8()][crate::cell_bg_rgb8].* pub fn bg_rgb8(&self) -> (NcColor, NcColor, NcColor) { let (mut r, mut g, mut b) = (0, 0, 0); crate::cell_bg_rgb8(self, &mut r, &mut g, &mut b); (r, g, b) } /// Gets the foreground [NcChannel]. /// /// *C style function: [cell_fchannel()][crate::cell_fchannel].* pub fn fchannel(&self) -> NcChannel { crate::cell_fchannel(self) } /// Extracts the foreground [NcAlphaBits] (shifted to LSBs). /// /// *C style function: [cell_fg_alpha()][crate::cell_fg_alpha].* pub fn fg_alpha(&self) -> NcAlphaBits { crate::cell_fg_alpha(self) } /// Is the foreground [NcChannel] using the "default foreground color"? /// /// *C style function: [cell_fg_default_p()][crate::cell_fg_default_p].* pub fn fg_default_p(&self) -> bool { crate::cell_fg_default_p(self) } /// Gets the [NcPaletteIndex] of the foreground [NcChannel]. /// /// *C style function: [cell_fg_palindex()][crate::cell_fg_palindex].* pub fn fg_palindex(&self) -> NcPaletteIndex { crate::cell_fg_palindex(self) } /// Is the foreground [NcChannel] using an [NcPaletteIndex] indexed /// [NcPalette][crate::NcPalette] color? /// /// *C style function: [cell_fg_palindex_p()][crate::cell_fg_palindex_p].* pub fn fg_palindex_p(&self) -> bool { crate::cell_fg_palindex_p(self) } /// Gets the foreground [NcRgb] (shifted to LSBs). /// /// *C style function: [cell_fg_rgb()][crate::cell_fg_rgb].* pub fn fg_rgb(&self) -> NcRgb { crate::cell_fg_rgb(self) } /// Gets the foreground [NcColor] RGB components. /// /// *C style function: [cell_fg_rgb8()][crate::cell_fg_rgb8].* pub fn fg_rgb8(&self) -> (NcColor, NcColor, NcColor) { let (mut r, mut g, mut b) = (0, 0, 0); crate::cell_fg_rgb8(self, &mut r, &mut g, &mut b); (r, g, b) } /// Sets the background [NcChannel] and returns the new [NcChannelPair]. /// /// *C style function: [cell_set_bchannel()][crate::cell_set_bchannel].* pub fn set_bchannel(&mut self, channel: NcChannel) -> NcChannelPair { crate::cell_set_bchannel(self, channel) } /// Sets the background [NcAlphaBits]. /// /// *C style function: [cell_set_bg_alpha()][crate::cell_set_bg_alpha].* pub fn set_bg_alpha(&mut self, alpha: NcAlphaBits) { crate::cell_set_bg_alpha(self, alpha); } /// Indicates to use the "default color" for the background [NcChannel]. /// /// *C style function: [cell_set_bg_default()][crate::cell_set_bg_default].* pub fn set_bg_default(&mut self) { crate::cell_set_bg_default(self); } /// Sets the background [NcPaletteIndex]. /// /// Also sets [NCCELL_BG_PALETTE][crate::NCCELL_BG_PALETTE] and /// [NCCELL_ALPHA_OPAQUE][crate::NCCELL_ALPHA_OPAQUE], and clears out /// [NCCELL_BGDEFAULT_MASK][crate::NCCELL_BGDEFAULT_MASK]. /// /// *C style function: [cell_set_bg_palindex()][crate::cell_set_bg_palindex].* pub fn set_bg_palindex(&mut self, index: NcPaletteIndex) { crate::cell_set_bg_palindex(self, index); } /// Sets the background [NcRgb] and marks it as not using the default color. /// /// *C style function: [cell_set_bg_rgb()][crate::cell_set_bg_rgb].* pub fn set_bg_rgb(&mut self, rgb: NcRgb) { crate::cell_set_bg_rgb(self, rgb); } /// Sets the background [NcColor] RGB components, and marks it as not using /// the "default color". /// /// *C style function: [cell_set_bg_rgb8()][crate::cell_set_bg_rgb8].* pub fn set_bg_rgb8(&mut self, red: NcColor, green: NcColor, blue: NcColor) { crate::cell_set_bg_rgb8(self, red, green, blue); } /// Sets the foreground [NcChannel] and returns the new [NcChannelPair]. /// /// *C style function: [cell_set_fchannel()][crate::cell_set_fchannel].* pub fn set_fchannel(&mut self, channel: NcChannel) -> NcChannelPair { crate::cell_set_fchannel(self, channel) } /// Sets the foreground [NcAlphaBits]. /// /// *C style function: [cell_set_fg_alpha()][crate::cell_set_fg_alpha].* pub fn set_fg_alpha(&mut self, alpha: NcAlphaBits) { crate::cell_set_fg_alpha(self, alpha); } /// Indicates to use the "default color" for the foreground [NcChannel]. /// /// *C style function: [cell_set_fg_default()][crate::cell_set_fg_default].* pub fn set_fg_default(&mut self) { crate::cell_set_fg_default(self); } /// Sets the foreground [NcPaletteIndex]. /// /// Also sets [NCCELL_FG_PALETTE][crate::NCCELL_FG_PALETTE] and /// [NCCELL_ALPHA_OPAQUE][crate::NCCELL_ALPHA_OPAQUE], and clears out /// [NCCELL_BGDEFAULT_MASK][crate::NCCELL_BGDEFAULT_MASK]. /// /// *C style function: [cell_set_fg_palindex()][crate::cell_set_fg_palindex].* pub fn set_fg_palindex(&mut self, index: NcPaletteIndex) { crate::cell_set_fg_palindex(self, index); } /// Sets the foreground [NcRgb] and marks it as not using the default color. /// /// *C style function: [cell_set_fg_rgb()][crate::cell_set_fg_rgb].* pub fn set_fg_rgb(&mut self, rgb: NcRgb) { crate::cell_set_fg_rgb(self, rgb); } /// Sets the foreground [NcColor] RGB components, and marks it as not using /// the "default color". /// /// *C style function: [cell_set_fg_rgb8()][crate::cell_set_fg_rgb8].* pub fn set_fg_rgb8(&mut self, red: NcColor, green: NcColor, blue: NcColor) { crate::cell_set_fg_rgb8(self, red, green, blue); } } /// # `NcCell` methods: other components impl NcCell { /// Returns true if the two cells have distinct [NcEgc]s, attributes, /// or [NcChannel]s. /// /// The actual egcpool index needn't be the same--indeed, the planes /// needn't even be the same. Only the expanded NcEgc must be bit-equal. /// /// *C style function: [cellcmp()][crate::cellcmp].* pub fn compare(plane1: &NcPlane, cell1: &NcCell, plane2: &NcPlane, cell2: &NcCell) -> bool { crate::cellcmp(plane1, cell1, plane2, cell2) } /// Saves the [NcStyleMask] and the [NcChannelPair], and returns the [NcEgc]. /// (These are the three elements of an NcCell). /// /// *C style function: [cell_fg_alpha()][crate::cell_fg_alpha].* pub fn extract( &mut self, plane: &mut NcPlane, styles: &mut NcStyleMask, channels: &mut NcChannelPair, ) -> NcEgc { crate::cell_extract(plane, self, styles, channels) } /// Returns the [NcEgc] of the NcCell. /// /// See also: [extended_gcluster][NcCell#method.extended_gcluster] method. /// /// *(No equivalent C style function)* pub fn egc(&mut self, plane: &mut NcPlane) -> NcEgc { let (mut _styles, mut _channels) = (0, 0); crate::cell_extract(plane, self, &mut _styles, &mut _channels) } /// Returns the [NcStyleMask] bits. /// /// *C style function: [cell_styles()][crate::cell_styles].* pub fn styles(&mut self) -> NcStyleMask { crate::cell_styles(self) } /// Removes the specified [NcStyleMask] bits. /// /// *C style function: [cell_off()][crate::cell_off_styles].* pub fn off_styles(&mut self, stylebits: NcStyleMask) { crate::cell_off_styles(self, stylebits) } /// Adds the specified [NcStyleMask] bits. /// /// *C style function: [cell_on()][crate::cell_on_styles].* pub fn on_styles(&mut self, stylebits: NcStyleMask) { crate::cell_on_styles(self, stylebits) } /// Sets just the specified [NcStyleMask] bits. /// /// *C style function: [cell_set_styles()][crate::cell_set_styles].* pub fn set_styles(&mut self, stylebits: NcStyleMask) { crate::cell_set_styles(self, stylebits) } } /// # `NcCell` methods: text impl NcCell { // /// Returns a pointer to the [NcEgc] of this NcCell in the [NcPlane] `plane`. // /// // /// This pointer can be invalidated by any further operation on the referred // /// plane, so… watch out! // /// // /// *C style function: [cell_extended_gcluster()][crate::cell_wide_left_p].* // pub fn extended_gcluster(&self, plane: &NcPlane) -> u32 { // let egcpointer = unsafe { crate::cell_extended_gcluster(plane, self) }; // egcpointer // } /// Copies the UTF8-encoded [NcEgc] out of this NcCell, /// whether simple or complex. /// /// The result is not tied to the [NcPlane], /// and persists across erases and destruction. /// /// *C style function: [cell_strdup()][crate::cell_strdup].* pub fn strdup(&self, plane: &NcPlane) -> NcEgc { crate::cell_strdup(plane, self) } /// Does this NcCell contain a wide codepoint? /// /// *C style function: [cell_double_wide_p()][crate::cell_double_wide_p].* pub fn double_wide_p(&self) -> bool { crate::cell_double_wide_p(self) } /// Is this the left half of a wide character? /// /// *C style function: [cell_wide_left_p()][crate::cell_wide_left_p].* pub fn wide_left_p(&self) -> bool { crate::cell_wide_right_p(self) } /// Is this the right side of a wide character? /// /// *C style function: [cell_wide_right_p()][crate::cell_wide_right_p].* pub fn wide_right_p(&self) -> bool { crate::cell_wide_right_p(self) } } /// # `NcCell` methods: boxes impl NcCell { /// Loads up six cells with the [NcEgc]s necessary to draw a box. /// /// On error, any [NcCell]s this function might have loaded before the error /// are [release][NcCell#method.release]d. /// There must be at least six [NcEgc]s in `gcluster`. /// /// *C style function: [cells_load_box()][crate::cells_load_box].* pub fn load_box( plane: &mut NcPlane, style: NcStyleMask, channels: NcChannelPair, ul: &mut NcCell, ur: &mut NcCell, ll: &mut NcCell, lr: &mut NcCell, hl: &mut NcCell, vl: &mut NcCell, gcluster: &str, ) -> NcResult<()> { error![crate::cells_load_box( plane, style, channels, ul, ur, ll, lr, hl, vl, gcluster )] } /// NcCell.[load_box()][NcCell#method.box] with the double box-drawing characters. /// /// *C style function: [cells_double_box()][crate::cells_double_box].* pub fn double_box( plane: &mut NcPlane, style: NcStyleMask, channels: NcChannelPair, ul: &mut NcCell, ur: &mut NcCell, ll: &mut NcCell, lr: &mut NcCell, hl: &mut NcCell, vl: &mut NcCell, ) -> NcResult<()> { error![unsafe { crate::cells_double_box(plane, style as u32, channels, ul, ur, ll, lr, hl, vl) }] } /// NcCell.[load_box()][NcCell#method.box] with the rounded box-drawing characters. /// /// *C style function: [cells_rounded_box()][crate::cells_double_box].* pub fn rounded_box( plane: &mut NcPlane, style: NcStyleMask, channels: NcChannelPair, ul: &mut NcCell, ur: &mut NcCell, ll: &mut NcCell, lr: &mut NcCell, hl: &mut NcCell, vl: &mut NcCell, ) -> NcResult<()> { error![unsafe { crate::cells_rounded_box(plane, style as u32, channels, ul, ur, ll, lr, hl, vl) }] } } libnotcurses-sys-2.1.8/src/cells/mod.rs010064400017500001750000000330631400616507400162610ustar 00000000000000//! `NcCell` // functions already exported by bindgen : 6 // ----------------------------------------- // (W) wrap: 4 // (#) test: 0 // ------------------------------------------ //W cell_duplicate //… cell_extended_gcluster //… cell_load //W cell_release //W cells_double_box //W cells_rounded_box // // functions manually reimplemented: 43 // ------------------------------------------ // (X) wont: 2 // (+) done: 38 // (W) wrap: 40 // (#) test: 26 // ------------------------------------------ //W# cell_bchannel //W# cell_bg_alpha //W# cell_bg_default_p //W# cell_bg_palindex //W# cell_bg_palindex_p //W# cell_bg_rgb //W# cell_bg_rgb8 //W+ cellcmp //W+ cell_double_wide_p //W+ cell_extract //W# cell_fchannel //W# cell_fg_alpha //W# cell_fg_default_p //W# cell_fg_palindex //W# cell_fg_palindex_p //W# cell_fg_rgb //W# cell_fg_rgb8 //W+ cell_init //…… cell_load_char // cell_load_egc32 //W+ cell_off_styles //W+ cell_on_styles //W+ cell_prime //W# cell_set_bchannel //W# cell_set_bg_alpha //W# cell_set_bg_default //W# cell_set_bg_palindex //W# cell_set_bg_rgb //W# cell_set_bg_rgb8 // X cell_set_bg_rgb8_clipped // unneeded //W# cell_set_fchannel //W# cell_set_fg_alpha //W# cell_set_fg_default //W# cell_set_fg_palindex //W# cell_set_fg_rgb //W# cell_set_fg_rgb8 // X cell_set_fg_rgb8_clipped // unneeded //W+ cell_set_styles //W+ cells_load_box //W+ cell_strdup //W+ cell_styles //W+ cell_wide_left_p //W+ cell_wide_right_p #[cfg(test)] mod test; mod methods; mod reimplemented; pub use reimplemented::*; // NcCell /// A coordinate on an [`NcPlane`][crate::NcPlane] storing 128 bits of data. /// /// # Methods & Associated Functions /// /// - [Constructors & Destructors](#nccell-constructors-and-destructors) /// /// - [bg|fg `NcChannel`s manipulation](#nccell-methods-bgfg-ncchannels-manipulation) /// - [Other components](#nccell-methods-other-components) /// - [Text](#nccell-methods-text) /// /// # Description /// /// An `NcCell` corresponds to a single character cell on some NcPlane`, /// which can be occupied by a single [`NcEgc`] grapheme cluster (some root /// spacing glyph, along with possible combining characters, which might span /// multiple columns). /// /// An NcCell is bounded to an NcPlane, but the cell doesn't store anything /// about the plane. /// /// At any `NcCell`, we can have a theoretically arbitrarily long UTF-8 string, /// a foreground color, a background color, and an [`NcStyleMask`] attribute set. /// /// Valid grapheme cluster contents include: /// /// - A NUL terminator, /// - A single [control character](https://en.wikipedia.org/wiki/Control_character), /// followed by a NUL terminator, /// - At most one [spacing /// character](https://en.wikipedia.org/wiki/Graphic_character#Spacing_character), /// followed by zero or more nonspacing characters, followed by a NUL terminator. /// /// ## Diagram /// /// ```txt /// NcCell: 128 bits structure comprised of the following 5 elements: /// /// GCLUSTER GCLUSTER GCLUSTER GCLUSTER 1. NcEgc /// 00000000 ~~~~~~~~ 11111111 11111111 2. NcEgcBackstop + 3. width + 4. NcStyleMask /// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB 5. NcChannelPair /// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB | /// /// 1. (32b) Extended Grapheme Cluster, presented either as: /// /// 1.1. An NcEgc of up to 4 bytes: /// UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU /// /// 1.2. A `0x01` in the first byte, plus 3 bytes with a 24b address to an egcpool: /// 00000001 IIIIIIII IIIIIIII IIIIIIII /// /// 2. (8b) Backstop (zero) /// 00000000 /// /// 3. (8b) column width /// WWWWWWWW /// /// 4. (16b) NcStyleMask /// 11111111 11111111 /// /// 5. (64b) NcChannelPair /// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB|~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB /// ``` /// /// `type in C: cell (struct)` /// /// # More NcCell Information /// /// ## Size /// /// Multi-column characters can only have a single style/color throughout. /// [`wcwidth()`](https://www.man7.org/linux/man-pages/man3/wcwidth.3.html) /// is not reliable. It's just quoting whether or not the [`NcEgc`] /// contains a "Wide Asian" double-width character. /// This is set for some things, like most emoji, and not set for /// other things, like cuneiform. /// /// Each cell occupies 16 static bytes (128 bits). The surface is thus ~1.6MB /// for a (pretty large) 500x200 terminal. At 80x43, it's less than 64KB. /// Dynamic requirements (the egcpool) can add up to 16MB to an ncplane, but /// such large pools are unlikely in common use. /// /// ## Alpha Compositing /// /// We implement some small alpha compositing. Foreground and background both /// have two bits of inverted alpha. The actual grapheme written to a cell is /// the topmost non-zero grapheme. /// /// - If its alpha is 00 ([`NCCELL_ALPHA_OPAQUE`]) its foreground color is used unchanged. /// /// - If its alpha is 10 ([`NCCELL_ALPHA_TRANSPARENT`]) its foreground color is derived /// entirely from cells underneath it. /// /// - If its alpha is 01 ([`NCCELL_ALPHA_BLEND`]) the result will be a composite. /// /// Likewise for the background. If the bottom of a coordinate's zbuffer is /// reached with a cumulative alpha of zero, the default is used. In this way, /// a terminal configured with transparent background can be supported through /// multiple occluding ncplanes. /// /// A foreground alpha of 11 ([`NCCELL_ALPHA_HIGHCONTRAST`]) requests high-contrast /// text (relative to the computed background). /// A background alpha of 11 is currently forbidden. /// /// ## Precedence /// /// - Default color takes precedence over palette or RGB, and cannot be used with /// transparency. /// - Indexed palette takes precedence over RGB. It cannot meaningfully set /// transparency, but it can be mixed into a cascading color. /// - RGB is used if neither default terminal colors nor palette indexing are in /// play, and fully supports all transparency options. /// /// ## Column width *(WIP)* /// /// See [USAGE.md](https://github.com/dankamongmen/notcurses/blob/master/USAGE.md) /// /// We store the column width in this field. for a multicolumn EGC of N /// columns, there will be N nccells, and each has a width of N...for now. /// eventually, such an EGC will set more than one subsequent cell to /// WIDE_RIGHT, and this won't be necessary. it can then be used as a /// bytecount. see #1203. FIXME iff width >= 2, the cell is part of a /// multicolumn glyph. whether a cell is the left or right side of the glyph /// can be determined by checking whether ->gcluster is zero. /// pub type NcCell = crate::bindings::ffi::cell; #[allow(unused_imports)] use crate::{NcAlphaBits, NcChannel, NcPlane}; /// [`NcAlphaBits`] bits indicating /// [`NcCell`]'s foreground or background color will be a composite between /// its color and the `NcCell`s' corresponding colors underneath it pub const NCCELL_ALPHA_BLEND: u32 = crate::bindings::ffi::CELL_ALPHA_BLEND; /// [`NcAlphaBits`] bits indicating /// [`NcCell`]'s foreground color will be high-contrast (relative to the /// computed background). Background cannot be highcontrast pub const NCCELL_ALPHA_HIGHCONTRAST: u32 = crate::bindings::ffi::CELL_ALPHA_HIGHCONTRAST; /// [`NcAlphaBits`] bits indicating /// [`NcCell`]'s foreground or background color is used unchanged pub const NCCELL_ALPHA_OPAQUE: u32 = crate::bindings::ffi::CELL_ALPHA_OPAQUE; /// [`NcAlphaBits`] bits indicating /// [`NcCell`]'s foreground or background color is derived entirely from the /// `NcCell`s underneath it pub const NCCELL_ALPHA_TRANSPARENT: u32 = crate::bindings::ffi::CELL_ALPHA_TRANSPARENT; /// If this bit is set, we are *not* using the default background color /// /// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair] /// /// NOTE: This can also be used against a single [`NcChannel`] pub const NCCELL_BGDEFAULT_MASK: u32 = crate::bindings::ffi::CELL_BGDEFAULT_MASK; /// Extract these bits to get the background alpha mask /// ([`NcAlphaBits`]) /// /// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair] /// /// NOTE: This can also be used against a single [`NcChannel`] pub const NCCELL_BG_ALPHA_MASK: u32 = crate::bindings::ffi::CELL_BG_ALPHA_MASK; /// If this bit *and* [`NCCELL_BGDEFAULT_MASK`] are set, we're using a /// palette-indexed background color /// /// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair] /// /// NOTE: This can also be used against a single [`NcChannel`] pub const NCCELL_BG_PALETTE: u32 = crate::bindings::ffi::CELL_BG_PALETTE; /// Extract these bits to get the background [`NcRgb`][crate::NcRgb] value /// /// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair] /// /// NOTE: This can also be used against a single [`NcChannel`] pub const NCCELL_BG_RGB_MASK: u32 = crate::bindings::ffi::CELL_BG_RGB_MASK; /// If this bit is set, we are *not* using the default foreground color /// /// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair] /// /// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BGDEFAULT_MASK`]; pub const NCCELL_FGDEFAULT_MASK: u64 = crate::bindings::ffi::CELL_FGDEFAULT_MASK; /// Extract these bits to get the foreground alpha mask /// ([`NcAlphaBits`]) /// /// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair] /// /// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BG_ALPHA_MASK`]; pub const NCCELL_FG_ALPHA_MASK: u64 = crate::bindings::ffi::CELL_FG_ALPHA_MASK; /// If this bit *and* [`NCCELL_FGDEFAULT_MASK`] are set, we're using a /// palette-indexed background color /// /// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair] /// /// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BG_PALETTE`]; pub const NCCELL_FG_PALETTE: u64 = crate::bindings::ffi::CELL_FG_PALETTE; /// Extract these bits to get the foreground [`NcRgb`][crate::NcRgb] value /// /// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair] /// /// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BG_RGB_MASK`]; pub const NCCELL_FG_RGB_MASK: u64 = crate::bindings::ffi::CELL_FG_RGB_MASK; // NcEgc // /// Extended Grapheme Cluster. A 32-bit [`char`]-like type /// /// This 32 bit char, together with the associated plane's associated egcpool, /// completely define this cell's `NcEgc`. Unless the `NcEgc` requires more than /// four bytes to encode as UTF-8, it will be inlined here: /// /// ## Diagram 1 /// /// ```txt /// UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU /// extended grapheme cluster <= 4bytes /// ``` /// /// `type in C: uint32_t` /// /// If more than four bytes are required, it will be spilled into the egcpool. /// In either case, there's a NUL-terminated string available without copying, /// because (1) the egcpool is all NUL-terminated sequences and (2) the fifth /// byte of this struct (the GClusterBackStop field, see below) is /// guaranteed to be zero, as are any unused bytes in gcluster. /// /// A spilled `NcEgc` is indicated by the value `0x01iiiiii`. This cannot alias a /// true supra-ASCII NcEgc, because UTF-8 only encodes bytes <= 0x80 when they /// are single-byte ASCII-derived values. The `iiiiii` is interpreted as a 24-bit /// index into the egcpool (which may thus be up to 16MB): /// /// ## Diagram 2 /// /// ```txt /// 00000001 iiiiiiii iiiiiiii iiiiiiii /// sign 24bit index to egcpool /// ``` /// `type in C: uint32_t` /// /// The cost of this scheme is that the character 0x01 (`SOH`) cannot be encoded /// in a cell, and therefore it must not be allowed through the API. /// /// ----- /// NOTE that even if the `NcEgc` is <= 4 bytes and inlined, is still interpreted as /// a NUL-terminated char * (technically, &cell->gcluster is treated as a char*). /// If it is more than 4 bytes, cell->gcluster has a first byte of 0x01, /// and the remaining 24 bits are an index into the plane's egcpool, /// which is carved into NUL-terminated chunks of arbitrary length. /// /// ## Links /// /// - [Grapheme Cluster /// Boundaries](https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries) /// /// // TODO: there should be two types at least: // - an utf-8 string len 1 of type &str. // - a unicode codepoint of type char. pub type NcEgc = char; // NcEgcBackStop /// An `u8` always at zero, part of the [`NcCell`] struct /// /// ## Diagram /// /// ```txt /// 00000000 /// ``` /// /// `type in C: uint_8t` /// pub type NcEgcBackstop = u8; // NcStyleMask /// /// An `u16` of `NCSTYLE_*` boolean styling attribute flags /// /// ## Attributes /// /// - [`NCSTYLE_BLINK`] /// - [`NCSTYLE_BOLD`] /// - [`NCSTYLE_DIM`] /// - [`NCSTYLE_INVIS`] /// - [`NCSTYLE_ITALIC`] /// - [`NCSTYLE_MASK`] /// - [`NCSTYLE_NONE`] /// - [`NCSTYLE_PROTECT`] /// - [`NCSTYLE_REVERSE`] /// - [`NCSTYLE_STANDOUT`] /// - [`NCSTYLE_STRUCK`] /// - [`NCSTYLE_UNDERLINE`] /// /// /// ## Diagram /// /// ```txt /// 11111111 11111111 /// ``` /// /// `type in C: uint16_t` /// pub type NcStyleMask = u16; /// pub const NCSTYLE_BLINK: u16 = crate::bindings::ffi::NCSTYLE_BLINK as u16; /// pub const NCSTYLE_BOLD: u16 = crate::bindings::ffi::NCSTYLE_BOLD as u16; /// pub const NCSTYLE_DIM: u16 = crate::bindings::ffi::NCSTYLE_DIM as u16; /// pub const NCSTYLE_INVIS: u16 = crate::bindings::ffi::NCSTYLE_INVIS as u16; /// pub const NCSTYLE_ITALIC: u16 = crate::bindings::ffi::NCSTYLE_ITALIC as u16; /// pub const NCSTYLE_MASK: u16 = crate::bindings::ffi::NCSTYLE_MASK as u16; /// pub const NCSTYLE_NONE: u16 = crate::bindings::ffi::NCSTYLE_NONE as u16; /// pub const NCSTYLE_PROTECT: u16 = crate::bindings::ffi::NCSTYLE_PROTECT as u16; /// pub const NCSTYLE_REVERSE: u16 = crate::bindings::ffi::NCSTYLE_REVERSE as u16; /// pub const NCSTYLE_STANDOUT: u16 = crate::bindings::ffi::NCSTYLE_STANDOUT as u16; /// pub const NCSTYLE_STRUCK: u16 = crate::bindings::ffi::NCSTYLE_STRUCK as u16; /// pub const NCSTYLE_UNDERLINE: u16 = crate::bindings::ffi::NCSTYLE_UNDERLINE as u16; libnotcurses-sys-2.1.8/src/cells/reimplemented.rs010064400017500001750000000427041377466054000203470ustar 00000000000000//! `cell*_*` reimplemented functions. use libc::strcmp; use crate::{ cell_release, cstring, NcAlphaBits, NcCell, NcChannel, NcChannelPair, NcColor, NcEgc, NcIntResult, NcPaletteIndex, NcPlane, NcRgb, NcStyleMask, NCCELL_ALPHA_OPAQUE, NCCELL_BGDEFAULT_MASK, NCCELL_BG_PALETTE, NCCELL_FGDEFAULT_MASK, NCCELL_FG_PALETTE, NCRESULT_ERR, NCRESULT_OK, NCSTYLE_MASK, }; // Alpha ----------------------------------------------------------------------- /// Extracts the foreground [NcAlphaBits] from an [NcCell] (shifted to LSBs). /// /// *Method: NcCell.[fg_alpha()][NcCell#method.fg_alpha].* #[inline] pub fn cell_fg_alpha(cell: &NcCell) -> NcAlphaBits { crate::channels_fg_alpha(cell.channels) } /// Extracts the background [NcAlphaBits] from an [NcCell] (shifted to LSBs). /// /// *Method: NcCell.[bg_alpha()][NcCell#method.bg_alpha].* #[inline] pub fn cell_bg_alpha(cell: &NcCell) -> NcAlphaBits { crate::channels_bg_alpha(cell.channels) } /// Sets the foreground [NcAlphaBits] of an [NcCell]. /// /// *Method: NcCell.[set_fg_alpha()][NcCell#method.set_fg_alpha].* #[inline] pub fn cell_set_fg_alpha(cell: &mut NcCell, alpha: NcAlphaBits) { crate::channels_set_fg_alpha(&mut cell.channels, alpha); } /// Sets the background [NcAlphaBits] of an [NcCell]. /// /// *Method: NcCell.[set_bg_alpha()][NcCell#method.set_bg_alpha].* #[inline] pub fn cell_set_bg_alpha(cell: &mut NcCell, alpha: NcAlphaBits) { crate::channels_set_bg_alpha(&mut cell.channels, alpha); } // Channels -------------------------------------------------------------------- /// Gets the foreground [NcChannel] from an [NcCell]. /// /// *Method: NcCell.[fchannel()][NcCell#method.fchannel].* #[inline] pub fn cell_fchannel(cell: &NcCell) -> NcChannel { crate::channels_fchannel(cell.channels) } /// Gets the background [NcChannel] from an [NcCell]. /// /// *Method: NcCell.[bchannel()][NcCell#method.bchannel].* #[inline] pub fn cell_bchannel(cell: &NcCell) -> NcChannel { crate::channels_bchannel(cell.channels) } /// Sets the foreground [NcChannel] of an [NcCell] and returns the new /// [NcChannelPair]. /// /// *Method: NcCell.[set_fchannel()][NcCell#method.set_fchannel].* #[inline] pub fn cell_set_fchannel(cell: &mut NcCell, channel: NcChannel) -> NcChannelPair { crate::channels_set_fchannel(&mut cell.channels, channel) } /// Sets the background [NcChannel] of an [NcCell] and returns the new /// [NcChannelPair]. /// /// *Method: NcCell.[set_bchannel()][NcCell#method.set_bchannel].* #[inline] pub fn cell_set_bchannel(cell: &mut NcCell, channel: NcChannel) -> NcChannelPair { crate::channels_set_bchannel(&mut cell.channels, channel) } // NcColor --------------------------------------------------------------------- /// Gets the foreground [NcColor] RGB components of an [NcCell], /// and returns the [NcChannel] (which can have some extra bits set). /// /// *Method: NcCell.[fg_rgb8()][NcCell#method.fg_rgb8].* #[inline] pub fn cell_fg_rgb8( cell: &NcCell, red: &mut NcColor, green: &mut NcColor, blue: &mut NcColor, ) -> NcChannel { crate::channels_fg_rgb8(cell.channels, red, green, blue) } /// Gets the background [NcColor] RGB components of an [NcCell], /// and returns the [NcChannel] (which can have some extra bits set). /// /// *Method: NcCell.[bg_rgb8()][NcCell#method.bg_rgb8].* #[inline] pub fn cell_bg_rgb8( cell: &NcCell, red: &mut NcColor, green: &mut NcColor, blue: &mut NcColor, ) -> NcChannel { crate::channels_bg_rgb8(cell.channels, red, green, blue) } /// Sets the foreground [NcColor] RGB components of the [NcCell], /// and marks it as not using the "default color". /// /// *Method: NcCell.[set_fg_rgb8()][NcCell#method.set_fg_rgb8].* #[inline] pub fn cell_set_fg_rgb8(cell: &mut NcCell, red: NcColor, green: NcColor, blue: NcColor) { crate::channels_set_fg_rgb8(&mut cell.channels, red, green, blue); } /// Sets the background [NcColor] RGB components of the [NcCell], /// and marks it as not using the "default color". /// /// *Method: NcCell.[set_bg_rgb8()][NcCell#method.set_bg_rgb8].* #[inline] pub fn cell_set_bg_rgb8(cell: &mut NcCell, red: NcColor, green: NcColor, blue: NcColor) { crate::channels_set_bg_rgb8(&mut cell.channels, red, green, blue); } // NcRgb ----------------------------------------------------------------------- /// Gets the foreground [NcRgb] from an [NcCell] (shifted to LSBs). /// /// *Method: NcCell.[fg_rgb()][NcCell#method.fg_rgb].* #[inline] pub fn cell_fg_rgb(cell: &NcCell) -> NcRgb { crate::channels_fg_rgb(cell.channels) } /// Gets the background [NcRgb] from an [NcCell] (shifted to LSBs). /// /// *Method: NcCell.[bg_rgb()][NcCell#method.bg_rgb].* #[inline] pub fn cell_bg_rgb(cell: &NcCell) -> NcRgb { crate::channels_bg_rgb(cell.channels) } /// Sets the foreground [NcRgb] of an [NcCell], /// and marks it as not using the default color. /// /// *Method: NcCell.[set_fg_rgb()][NcCell#method.set_fg_rgb].* #[inline] pub fn cell_set_fg_rgb(cell: &mut NcCell, rgb: NcRgb) { crate::channels_set_fg_rgb(&mut cell.channels, rgb); } /// Sets the background [NcRgb] of an [NcCell], /// and marks it as not using the default color. /// /// *Method: NcCell.[set_bg_rgb()][NcCell#method.set_bg_rgb].* #[inline] pub fn cell_set_bg_rgb(cell: &mut NcCell, rgb: NcRgb) { crate::channels_set_bg_rgb(&mut cell.channels, rgb); } // Default --------------------------------------------------------------------- /// Indicates to use the "default color" for the foreground [NcChannel] /// of an [NcCell]. /// /// *Method: NcCell.[set_fg_default()][NcCell#method.set_fg_default].* #[inline] pub fn cell_set_fg_default(cell: &mut NcCell) { crate::channels_set_fg_default(&mut cell.channels); } /// Indicates to use the "default color" for the background [NcChannel] /// of an [NcCell]. /// /// *Method: NcCell.[set_bg_default()][NcCell#method.set_bg_default].* #[inline] pub fn cell_set_bg_default(cell: &mut NcCell) { crate::channels_set_bg_default(&mut cell.channels); } /// Is the foreground [NcChannel] of this [NcCell] using the /// "default foreground color"? /// /// *Method: NcCell.[fg_default_p()][NcCell#method.fg_default_p].* #[inline] pub fn cell_fg_default_p(cell: &NcCell) -> bool { crate::channels_fg_default_p(cell.channels) } /// Is the background [NcChannel] of this [NcCell] using the /// "default background color"? /// /// The "default background color" must generally be used to take advantage of /// terminal-effected transparency. /// /// *Method: NcCell.[bg_default_p()][NcCell#method.bg_default_p].* #[inline] pub fn cell_bg_default_p(cell: &NcCell) -> bool { crate::channels_bg_default_p(cell.channels) } // Palette --------------------------------------------------------------------- /// Is the foreground [NcChannel] of this [NcCell] using an /// [NcPaletteIndex] [indexed][NcPaletteIndex] [NcPalette][crate::NcPalette] color? /// /// *Method: NcCell.[fg_palindex_p()][NcCell#method.fg_palindex_p].* #[inline] pub fn cell_fg_palindex_p(cell: &NcCell) -> bool { crate::channels_fg_palindex_p(cell.channels) } /// Is the background [NcChannel] of this [NcCell] using an /// [NcPaletteIndex] [indexed][NcPaletteIndex] [NcPalette][crate::NcPalette] color? /// /// *Method: NcCell.[bg_palindex_p()][NcCell#method.bg_palindex_p].* #[inline] pub fn cell_bg_palindex_p(cell: &NcCell) -> bool { crate::channels_bg_palindex_p(cell.channels) } /// Gets the [NcPaletteIndex] of the foreground [NcChannel] of the [NcCell]. /// /// *Method: NcCell.[fg_palindex()][NcCell#method.fg_palindex].* #[inline] pub const fn cell_fg_palindex(cell: &NcCell) -> NcPaletteIndex { ((cell.channels & 0xff00000000 as NcChannelPair) >> 32) as NcPaletteIndex } /// Gets the [NcPaletteIndex] of the background [NcChannel] of the [NcCell]. /// /// *Method: NcCell.[bg_palindex()][NcCell#method.bg_palindex].* #[inline] pub const fn cell_bg_palindex(cell: &NcCell) -> NcPaletteIndex { (cell.channels & 0xff) as NcPaletteIndex } /// Sets an [NcCell]'s foreground [NcPaletteIndex]. /// /// Also sets [NCCELL_FG_PALETTE] and [NCCELL_ALPHA_OPAQUE], /// and clears out [NCCELL_FGDEFAULT_MASK]. /// /// *Method: NcCell.[set_fg_palindex()][NcCell#method.set_fg_palindex].* // // NOTE: unlike the original C function, this one can't fail #[inline] pub fn cell_set_fg_palindex(cell: &mut NcCell, index: NcPaletteIndex) { cell.channels |= NCCELL_FGDEFAULT_MASK; cell.channels |= NCCELL_FG_PALETTE; cell_set_fg_alpha(cell, NCCELL_ALPHA_OPAQUE); cell.channels &= 0xff000000ffffffff as NcChannelPair; cell.channels |= (index as NcChannelPair) << 32; } /// Sets an [NcCell]'s background [NcPaletteIndex]. /// /// Also sets [NCCELL_BG_PALETTE] and [NCCELL_ALPHA_OPAQUE], /// and clears out [NCCELL_BGDEFAULT_MASK]. /// /// *Method: NcCell.[set_bg_palindex()][NcCell#method.set_bg_palindex].* // // NOTE: unlike the original C function, this one can't fail #[inline] pub fn cell_set_bg_palindex(cell: &mut NcCell, index: NcPaletteIndex) { cell.channels |= NCCELL_BGDEFAULT_MASK as NcChannelPair; cell.channels |= NCCELL_BG_PALETTE as NcChannelPair; cell_set_bg_alpha(cell, NCCELL_ALPHA_OPAQUE); cell.channels &= 0xffffffffff000000; cell.channels |= index as NcChannelPair; } // Styles ---------------------------------------------------------------------- /// Extracts the [NcStyleMask] bits from an [NcCell]. /// /// *Method: NcCell.[cell_styles()][NcCell#method.cell_styles].* #[inline] pub const fn cell_styles(cell: &NcCell) -> NcStyleMask { cell.stylemask } /// Adds the specified [NcStyleMask] bits to an [NcCell]'s existing spec., /// whether they're actively supported or not. /// /// *Method: NcCell.[styles_on()][NcCell#method.styles_on].* #[inline] pub fn cell_on_styles(cell: &mut NcCell, stylebits: NcStyleMask) { cell.stylemask |= stylebits & NCSTYLE_MASK as u16; } /// Removes the specified [NcStyleMask] bits from an [NcCell]'s existing spec. /// /// *Method: NcCell.[styles_off()][NcCell#method.styles_off].* #[inline] pub fn cell_off_styles(cell: &mut NcCell, stylebits: NcStyleMask) { cell.stylemask &= !(stylebits & NCSTYLE_MASK as u16); } /// Sets *just* the specified [NcStyleMask] bits for an [NcCell], /// whether they're actively supported or not. /// /// *Method: NcCell.[styles_set()][NcCell#method.styles_set].* #[inline] pub fn cell_set_styles(cell: &mut NcCell, stylebits: NcStyleMask) { cell.stylemask = stylebits & NCSTYLE_MASK as u16; } // Chars ----------------------------------------------------------------------- /// Does the [NcCell] contain an East Asian Wide codepoint? /// /// *Method: NcCell.[double_wide_p()][NcCell#method.double_wide_p].* #[inline] pub const fn cell_double_wide_p(cell: &NcCell) -> bool { cell.width > 0 } /// Is this the right half of a wide character? /// /// *Method: NcCell.[wide_right_p()][NcCell#method.wide_right_p].* #[inline] pub const fn cell_wide_right_p(cell: &NcCell) -> bool { cell_double_wide_p(cell) && cell.gcluster == 0 } /// Is this the left half of a wide character? /// /// *Method: NcCell.[wide_left_p()][NcCell#method.wide_left_p].* #[inline] pub const fn cell_wide_left_p(cell: &NcCell) -> bool { cell_double_wide_p(cell) && cell.gcluster != 0 } // /// Loads a 7-bit [NcEgc] character into the [NcCell]. // /// // /// *Method: NcCell.[load_char()][NcCell#method.load_char].* // // // // TODO:CHECK is this necessary at all? // #[inline] // pub fn cell_load_char(plane: &mut NcPlane, cell: &mut NcCell, ch: NcEgc) /* -> i32 */ // { // let _ = unsafe { crate::cell_load(plane, cell, ch) }; // } // cell_load_char(struct ncplane* n, nccell* c, char ch){ // char gcluster[2]; // gcluster[0] = ch; // gcluster[1] = '\0'; // let _ = cell_load(n, c, gcluster); // } // /// Loads a UTF-8 grapheme cluster of up to 4 bytes into the cell `c`. // /// // /// *Method: NcCell.[load_egc32()][NcCell#method.load_egc32].* // // // // TODO // #[inline] // pub fn cell_load_egc32(plane: &mut NcPlane, cell: &mut NcCell, egc: &str) -> NcIntResult { // char gcluster[sizeof(egc) + 1]; // egc = egc.to_le(); // memcpy(gcluster, &egc, sizeof(egc)); // gcluster[4] = '\0'; // return cell_load(n, c, gcluster); // } // // Load a UTF-8 encoded EGC of up to 4 bytes into the nccell 'c'. Returns the // // number of bytes used, or -1 on error. // static inline int // cell_load_egc32(struct ncplane* n, nccell* c, uint32_t egc){ // char gcluster[sizeof(egc) + 1]; // egc = htole(egc); // memcpy(gcluster, &egc, sizeof(egc)); // gcluster[4] = '\0'; // return cell_load(n, c, gcluster); // } /// Copies the UTF8-encoded [NcEgc] out of the [NcCell], whether simple or complex. /// /// The result is not tied to the [NcPlane], /// and persists across erases and destruction. /// /// *Method: NcCell.[strdup()][NcCell#method.strdup].* #[inline] pub fn cell_strdup(plane: &NcPlane, cell: &NcCell) -> NcEgc { core::char::from_u32( unsafe { libc::strdup(crate::cell_extended_gcluster(plane, cell)) } as i32 as u32, ) .expect("wrong char") // Unsafer option B (maybe faster, TODO:BENCH): // unsafe { // core::char::from_u32_unchecked(libc::strdup(cell_extended_gcluster(plane, cell)) as i32 as u32) // } } // Misc. ----------------------------------------------------------------------- /// Saves the [NcStyleMask] and the [NcChannelPair], /// and returns the [NcEgc], of an [NcCell]. /// /// *Method: NcCell.[extract()][NcCell#method.extract].* #[inline] pub fn cell_extract( plane: &NcPlane, cell: &NcCell, stylemask: &mut NcStyleMask, channels: &mut NcChannelPair, ) -> NcEgc { if *stylemask != 0 { *stylemask = cell.stylemask; } if *channels != 0 { *channels = cell.channels; } cell_strdup(plane, cell) } /// Returns true if the two cells are distinct [NcEgc]s, attributes, or channels. /// /// The actual egcpool index needn't be the same--indeed, the planes needn't even /// be the same. Only the expanded NcEgc must be equal. The NcEgc must be bit-equal; /// /// *Method: NcCell.[compare()][NcCell#method.compare].* // // NOTE: FIXME: it would probably be better to test whether they're Unicode-equal #[inline] pub fn cellcmp(plane1: &NcPlane, cell1: &NcCell, plane2: &NcPlane, cell2: &NcCell) -> bool { if cell1.stylemask != cell2.stylemask { return true; } if cell1.channels != cell2.channels { return true; } unsafe { strcmp( crate::cell_extended_gcluster(plane1, cell1), crate::cell_extended_gcluster(plane2, cell2), ) != 0 } } /// Initializes (zeroes out) an [NcCell]. /// /// *Method: NcCell.[init()][NcCell#method.init].* #[inline] pub fn cell_init(cell: &mut NcCell) { *cell = unsafe { core::mem::zeroed() } } /// Same as [cell_load][crate::cell_load], plus blasts the styling with /// `style` and `channels`. /// /// - Breaks the UTF-8 string in `gcluster` down, setting up the cell `cell`. /// - Returns the number of bytes copied out of `gcluster`, or -1 on failure. /// - The styling of the cell is left untouched, but any resources are released. /// - Blasts the styling with `style` and `channels`. /// /// *Method: NcCell.[prime()][NcCell#method.prime].* pub fn cell_prime( plane: &mut NcPlane, cell: &mut NcCell, gcluster: &str, style: NcStyleMask, channels: NcChannelPair, ) -> NcIntResult { cell.stylemask = style; cell.channels = channels; unsafe { crate::cell_load(plane, cell, cstring![gcluster]) } } /// Loads up six cells with the [NcEgc]s necessary to draw a box. /// /// Returns [NCRESULT_OK] on success or [NCRESULT_ERR] on error. /// /// On error, any [NcCell]s this function might have loaded before the error /// are [cell_release]d. There must be at least six [NcEgc]s in `gcluster`. /// /// *Method: NcCell.[load_box()][NcCell#method.load_box].* pub fn cells_load_box( plane: &mut NcPlane, style: NcStyleMask, channels: NcChannelPair, ul: &mut NcCell, ur: &mut NcCell, ll: &mut NcCell, lr: &mut NcCell, hl: &mut NcCell, vl: &mut NcCell, gcluster: &str, ) -> NcIntResult { // TODO: CHECK: mutable copy for pointer arithmetics: let mut gclu = cstring![gcluster]; let mut ulen: NcIntResult; ulen = cell_prime(plane, ul, gcluster, style, channels); if ulen > 0 { gclu = unsafe { gclu.offset(ulen as isize) }; ulen = cell_prime(plane, ur, gcluster, style, channels); if ulen > 0 { gclu = unsafe { gclu.offset(ulen as isize) }; ulen = cell_prime(plane, ll, gcluster, style, channels); if ulen > 0 { gclu = unsafe { gclu.offset(ulen as isize) }; ulen = cell_prime(plane, lr, gcluster, style, channels); if ulen > 0 { gclu = unsafe { gclu.offset(ulen as isize) }; ulen = cell_prime(plane, hl, gcluster, style, channels); if ulen > 0 { let _gclu = unsafe { gclu.offset(ulen as isize) }; ulen = cell_prime(plane, vl, gcluster, style, channels); if ulen > 0 { return NCRESULT_OK; } unsafe { cell_release(plane, hl); } } unsafe { cell_release(plane, lr); } } unsafe { cell_release(plane, ll); } } unsafe { cell_release(plane, ur); } } unsafe { cell_release(plane, ul); } } NCRESULT_ERR } libnotcurses-sys-2.1.8/src/cells/test/methods.rs010064400017500001750000000006201377726434200201310ustar 00000000000000//! Test `NcCell` methods and associated functions. use crate::{FullMode, NcCell, NcPlane}; use serial_test::serial; #[test] #[serial] fn constructors() -> crate::NcResult<()> { let _c1 = NcCell::new(); let _c2 = NcCell::with_char7b('C'); let mut nc = FullMode::new()?; let plane = NcPlane::new(&mut nc, 0, 0, 10, 10)?; let _c3 = NcCell::with_char('௵', plane); Ok(()) } libnotcurses-sys-2.1.8/src/cells/test/mod.rs010064400017500001750000000001171376441154400172400ustar 00000000000000//! `NcCell` tests #[cfg(test)] mod methods; #[cfg(test)] mod reimplemented; libnotcurses-sys-2.1.8/src/cells/test/reimplemented.rs010064400017500001750000000072011377156272500213220ustar 00000000000000//! Test `cell*_*` reimplemented functions use serial_test::serial; use crate::NcCell; #[test] #[serial] fn channels() { let mut c1 = NcCell::new(); assert_eq![0, crate::cell_fchannel(&c1)]; assert_eq![0, crate::cell_bchannel(&c1)]; let mut channels = crate::cell_set_fchannel(&mut c1, 0xAA112233); assert_eq![0xAA112233, crate::cell_fchannel(&c1)]; assert_eq![0xAA11223300000000, channels]; channels = crate::cell_set_bchannel(&mut c1, 0xBB445566); assert_eq![0xBB445566, crate::cell_bchannel(&c1)]; assert_eq![0xAA112233BB445566, channels]; let _c2 = NcCell::with_char7b('@'); } #[test] #[serial] fn rgb() { // rgb let mut c1 = NcCell::new(); assert_eq![0, crate::cell_fg_rgb(&c1)]; assert_eq![0, crate::cell_bg_rgb(&c1)]; crate::cell_set_fg_rgb(&mut c1, 0x99112233); assert_eq![0x112233, crate::cell_fg_rgb(&c1)]; crate::cell_set_bg_rgb(&mut c1, 0x99445566); assert_eq![0x445566, crate::cell_bg_rgb(&c1)]; // rgb8 let mut c2 = NcCell::new(); let (mut r, mut g, mut b) = (0, 0, 0); crate::cell_set_fg_rgb8(&mut c2, 0x11, 0x22, 0x33); let fchannel = crate::cell_fg_rgb8(&c2, &mut r, &mut g, &mut b); assert_eq!((0x11, 0x22, 0x33), (r, g, b)); assert_eq![0x112233, fchannel & !crate::NCCELL_BGDEFAULT_MASK]; crate::cell_set_bg_rgb8(&mut c2, 0x44, 0x55, 0x66); let bchannel = crate::cell_bg_rgb8(&c2, &mut r, &mut g, &mut b); assert_eq!((0x44, 0x55, 0x66), (r, g, b)); assert_eq![0x445566, bchannel & !crate::NCCELL_BGDEFAULT_MASK]; } #[test] #[serial] fn alpha() { let mut c1 = NcCell::new(); assert_eq![0, crate::cell_fg_alpha(&c1)]; assert_eq![0, crate::cell_bg_alpha(&c1)]; crate::cell_set_fg_alpha(&mut c1, crate::NCCELL_ALPHA_TRANSPARENT); assert_eq![crate::NCCELL_ALPHA_TRANSPARENT, crate::cell_fg_alpha(&c1)]; crate::cell_set_bg_alpha(&mut c1, crate::NCCELL_ALPHA_BLEND); assert_eq![crate::NCCELL_ALPHA_BLEND, crate::cell_bg_alpha(&c1)]; } #[test] #[serial] fn default() { let mut c1 = NcCell::new(); assert_eq![true, crate::cell_fg_default_p(&c1)]; assert_eq![true, crate::cell_bg_default_p(&c1)]; // rgb crate::cell_set_fg_rgb(&mut c1, 0x112233); crate::cell_set_bg_rgb(&mut c1, 0x445566); assert_eq![false, crate::cell_fg_default_p(&c1)]; assert_eq![false, crate::cell_bg_default_p(&c1)]; // reset crate::cell_set_fg_default(&mut c1); crate::cell_set_bg_default(&mut c1); assert_eq![true, crate::cell_fg_default_p(&c1)]; assert_eq![true, crate::cell_bg_default_p(&c1)]; // rgb8 crate::cell_set_fg_rgb8(&mut c1, 0x11, 0x22, 0x33); crate::cell_set_bg_rgb8(&mut c1, 0x44, 0x55, 0x66); assert_eq![false, crate::cell_fg_default_p(&c1)]; assert_eq![false, crate::cell_bg_default_p(&c1)]; // reset crate::cell_set_fg_default(&mut c1); crate::cell_set_bg_default(&mut c1); // palette crate::cell_set_fg_palindex(&mut c1, 5); crate::cell_set_bg_palindex(&mut c1, 6); assert_eq![false, crate::cell_fg_default_p(&c1)]; assert_eq![false, crate::cell_bg_default_p(&c1)]; } #[test] #[serial] fn palette() { let mut c1 = NcCell::new(); assert_eq![false, crate::cell_fg_palindex_p(&c1)]; assert_eq![false, crate::cell_bg_palindex_p(&c1)]; assert_eq![0, crate::cell_fg_palindex(&c1)]; assert_eq![0, crate::cell_bg_palindex(&c1)]; crate::cell_set_fg_palindex(&mut c1, 5); crate::cell_set_bg_palindex(&mut c1, 6); assert_eq![true, crate::cell_fg_palindex_p(&c1)]; assert_eq![true, crate::cell_bg_palindex_p(&c1)]; assert_eq![5, crate::cell_fg_palindex(&c1)]; assert_eq![6, crate::cell_bg_palindex(&c1)]; } libnotcurses-sys-2.1.8/src/channel/methods.rs010064400017500001750000000457131377416525400174730ustar 00000000000000//! `NcChannel*` methods and associated functions. use crate::{NcAlphaBits, NcChannel, NcChannelPair, NcColor, NcPaletteIndex, NcRgb}; /// Enables the [NcChannel] methods. pub trait NcChannelMethods { // constructors fn new() -> Self; fn with_default() -> Self; fn with_rgb(rgb: NcRgb) -> Self; fn with_rgb_alpha(rgb: NcRgb, alpha: NcAlphaBits) -> Self; fn with_rgb8(r: NcColor, g: NcColor, b: NcColor) -> Self; fn with_rgb8_alpha(r: NcColor, g: NcColor, b: NcColor, alpha: NcAlphaBits) -> Self; // methods fn fcombine(&self, bchannel: NcChannel) -> NcChannelPair; fn bcombine(&self, fchannel: NcChannel) -> NcChannelPair; fn alpha(&self) -> NcAlphaBits; fn set_alpha(&mut self, alpha: NcAlphaBits); fn set(&mut self, rgb: NcRgb); fn rgb8(&self) -> (NcColor, NcColor, NcColor); fn set_rgb8(&mut self, r: NcColor, g: NcColor, b: NcColor); fn r(&self) -> NcColor; fn g(&self) -> NcColor; fn b(&self) -> NcColor; fn set_r(&mut self, r: NcColor) -> NcChannel; fn set_g(&mut self, g: NcColor) -> NcChannel; fn set_b(&mut self, b: NcColor) -> NcChannel; fn rgb(&self) -> NcRgb; fn set_rgb(&mut self, rgb: NcRgb); fn default_p(&self) -> bool; fn set_default(&mut self) -> NcChannel; fn palindex_p(&self) -> bool; } /// Enables the [NcChannelPair] methods. pub trait NcChannelPairMethods { // constructors // … // methods fn combine(fchannel: NcChannel, bchannel: NcChannel) -> NcChannelPair; fn fchannel(&self) -> NcChannel; fn bchannel(&self) -> NcChannel; fn set_fchannel(&mut self, fchannel: NcChannel) -> NcChannelPair; fn set_bchannel(&mut self, bchannel: NcChannel) -> NcChannelPair; fn fg_alpha(&self) -> NcAlphaBits; fn bg_alpha(&self) -> NcAlphaBits; fn set_fg_alpha(&mut self, alpha: NcAlphaBits); fn set_bg_alpha(&mut self, alpha: NcAlphaBits); fn fg_rgb(&self) -> NcRgb; fn bg_rgb(&self) -> NcRgb; fn set_fg_rgb(&mut self, alpha: NcAlphaBits); fn set_bg_rgb(&mut self, alpha: NcAlphaBits); fn fg_rgb8(&self) -> (NcColor, NcColor, NcColor); fn bg_rgb8(&self) -> (NcColor, NcColor, NcColor); fn set_fg_rgb8(&mut self, r: NcColor, g: NcColor, b: NcColor) -> NcChannelPair; fn set_bg_rgb8(&mut self, r: NcColor, g: NcColor, b: NcColor) -> NcChannelPair; fn fg_r(&self) -> NcColor; fn fg_g(&self) -> NcColor; fn fg_b(&self) -> NcColor; fn bg_r(&self) -> NcColor; fn bg_g(&self) -> NcColor; fn bg_b(&self) -> NcColor; fn fg_set_r(&mut self, r: NcColor) -> NcChannelPair; fn fg_set_g(&mut self, g: NcColor) -> NcChannelPair; fn fg_set_b(&mut self, b: NcColor) -> NcChannelPair; fn bg_set_r(&mut self, r: NcColor) -> NcChannelPair; fn bg_set_g(&mut self, g: NcColor) -> NcChannelPair; fn bg_set_b(&mut self, b: NcColor) -> NcChannelPair; fn fg_default_p(&self) -> bool; fn bg_default_p(&self) -> bool; fn set_fg_default(&mut self) -> NcChannelPair; fn set_bg_default(&mut self) -> NcChannelPair; fn fg_palindex_p(&self) -> bool; fn bg_palindex_p(&self) -> bool; fn set_fg_palindex(&mut self, index: NcPaletteIndex); fn set_bg_palindex(&mut self, index: NcPaletteIndex); } // NcChannel ------------------------------------------------------------------- /// # `NcChannel` Methods impl NcChannelMethods for NcChannel { // Constructors /// New NcChannel, set to black and NOT using the default color. fn new() -> Self { 0 as NcChannel | crate::NCCELL_BGDEFAULT_MASK } /// New NcChannel, set to black but using the default color. fn with_default() -> Self { 0 as NcChannel } /// New NcChannel, expects [NcRgb]. fn with_rgb(rgb: NcRgb) -> Self { let mut channel = 0; crate::channel_set(&mut channel, rgb); channel } /// New NcChannel, expects [NcRgb] & [NcAlphaBits]. fn with_rgb_alpha(rgb: NcRgb, alpha: NcAlphaBits) -> Self { let mut channel = 0; crate::channel_set(&mut channel, rgb); crate::channel_set_alpha(&mut channel, alpha); channel } /// New NcChannel, expects three RGB [NcColor] components. fn with_rgb8(r: NcColor, g: NcColor, b: NcColor) -> Self { let mut channel = 0; crate::channel_set_rgb8(&mut channel, r, g, b); channel } /// New NcChannel, expects three RGB [NcColor] components. fn with_rgb8_alpha(r: NcColor, g: NcColor, b: NcColor, alpha: NcAlphaBits) -> Self { let mut channel = 0; crate::channel_set_rgb8(&mut channel, r, g, b); crate::channel_set_alpha(&mut channel, alpha); channel } // Combine /// Combines this [NcChannel] as foreground, with another as background /// into an [NcChannelPair]. /// /// *C style function: [channels_combine()][crate::channels_combine].* // // Not in the C API fn fcombine(&self, bchannel: NcChannel) -> NcChannelPair { crate::channels_combine(*self, bchannel) } /// Combines this [NcChannel] as background, with another as foreground /// into an [NcChannelPair]. /// /// *C style function: [channels_combine()][crate::channels_combine].* // // Not in the C API fn bcombine(&self, fchannel: NcChannel) -> NcChannelPair { crate::channels_combine(fchannel, *self) } // Alpha /// Gets the [NcAlphaBits]. /// /// *C style function: [channel_alpha()][crate::channel_alpha].* fn alpha(&self) -> NcAlphaBits { crate::channel_alpha(*self) } /// Sets the [NcAlphaBits]. /// /// *C style function: [channel_set_alpha()][crate::channel_set_alpha].* fn set_alpha(&mut self, alpha: NcAlphaBits) { crate::channel_set_alpha(self, alpha) } // NcRgb /// Sets the [NcRgb], and marks the NcChannel as NOT using the /// "default color", retaining the other bits unchanged. /// /// *C style function: [channel_set()][crate::channel_set].* fn set(&mut self, rgb: NcRgb) { crate::channel_set(self, rgb); } // NcColor /// Gets the three [NcColor]s. /// /// *C style function: [channel_rgb8()][crate::channel_rgb8].* fn rgb8(&self) -> (NcColor, NcColor, NcColor) { let (mut r, mut g, mut b) = (0, 0, 0); crate::channel_rgb8(*self, &mut r, &mut g, &mut b); (r, g, b) } /// Sets the three [NcColor]s, and /// marks the NcChannel as NOT using the default color. /// /// *C style function: [channel_set_rgb8()][crate::channel_set_rgb8].* fn set_rgb8(&mut self, r: NcColor, g: NcColor, b: NcColor) { crate::channel_set_rgb8(self, r, g, b); } /// Gets the red [NcColor]. /// /// *C style function: [channel_r()][crate::channel_r].* fn r(&self) -> NcColor { crate::channel_r(*self) } /// Gets the green [NcColor]. /// /// *C style function: [channel_g()][crate::channel_g].* fn g(&self) -> NcColor { crate::channel_g(*self) } /// Gets the blue [NcColor]. /// /// *C style function: [channel_b()][crate::channel_b].* fn b(&self) -> NcColor { crate::channel_b(*self) } /// Sets the red [NcColor], and returns the new NcChannel. /// /// *C style function: [channel_set_r()][crate::channel_set_r].* // // Not in the C API fn set_r(&mut self, r: NcColor) -> NcChannel { crate::channel_set_r(self, r) } /// Sets the green [NcColor], and returns the new NcChannel. /// /// *C style function: [channel_set_g()][crate::channel_set_g].* // // Not in the C API fn set_g(&mut self, g: NcColor) -> NcChannel { crate::channel_set_g(self, g) } /// Sets the blue [NcColor], and returns the new NcChannel. /// /// *C style function: [channel_set_b()][crate::channel_set_b].* // // Not in the C API fn set_b(&mut self, b: NcColor) -> NcChannel { crate::channel_set_b(self, b) } // NcRgb /// Gets the [NcRgb]. /// /// *C style function: [channel_rgb()][crate::channel_rgb].* // // Not in the C API fn rgb(&self) -> NcRgb { crate::channel_rgb(*self) } /// Sets the [NcRgb] and marks it as NOT using the default color, /// retaining the other bits unchanged. /// /// *C style function: [channel_set()][crate::channel_set].* fn set_rgb(&mut self, rgb: NcRgb) { crate::channel_set(self, rgb); } // default color /// Is this NcChannel using the "default color" rather than RGB/palette-indexed? /// /// *C style function: [channel_default_p()][crate::channel_default_p].* fn default_p(&self) -> bool { crate::channel_default_p(*self) } /// Marks an NcChannel as using its "default color", which also marks it opaque. /// /// *C style function: [channel_set_default()][crate::channel_set_default].* fn set_default(&mut self) -> NcChannel { crate::channel_set_default(self) } // NcPaletteIndex /// Is this NcChannel using palette-indexed color rather than RGB? /// /// *C style function: [channel_set_default()][crate::channel_set_default].* fn palindex_p(&self) -> bool { crate::channel_palindex_p(*self) } } // NcChannelPair --------------------------------------------------------------- /// # `NcChannelPair` Methods impl NcChannelPairMethods for NcChannelPair { // Combine /// Combines two [NcChannel]s into an [NcChannelPair]. /// /// *C style function: [channels_combine()][crate::channels_combine].* fn combine(fchannel: NcChannel, bchannel: NcChannel) -> NcChannelPair { crate::channels_combine(fchannel, bchannel) } // NcChannel /// Extracts the foreground [NcChannel]. /// /// *C style function: [channels_fchannel()][crate::channels_fchannel].* fn fchannel(&self) -> NcChannel { crate::channels_fchannel(*self) } /// Extracts the background [NcChannel]. /// /// *C style function: [channels_bchannel()][crate::channels_bchannel].* fn bchannel(&self) -> NcChannel { crate::channels_bchannel(*self) } /// Sets the foreground [NcChannel]. /// /// *C style function: [channels_set_fchannel()][crate::channels_set_fchannel].* fn set_fchannel(&mut self, fchannel: NcChannel) -> NcChannelPair { crate::channels_set_fchannel(self, fchannel) } /// Sets the background [NcChannel]. /// /// *C style function: [channels_set_bchannel()][crate::channels_set_bchannel].* fn set_bchannel(&mut self, bchannel: NcChannel) -> NcChannelPair { crate::channels_set_bchannel(self, bchannel) } // Alpha /// Gets the foreground [NcAlphaBits]. /// /// *C style function: [channels_fg_alpha()][crate::channels_fg_alpha].* fn fg_alpha(&self) -> NcAlphaBits { crate::channels_fg_alpha(*self) } /// Gets the background [NcAlphaBits]. /// /// *C style function: [channels_bg_alpha()][crate::channels_bg_alpha].* fn bg_alpha(&self) -> NcAlphaBits { crate::channels_bg_alpha(*self) } /// Sets the foreground [NcAlphaBits]. /// /// *C style function: [channels_set_fg_alpha()][crate::channels_set_fg_alpha].* fn set_fg_alpha(&mut self, alpha: NcAlphaBits) { crate::channels_set_fg_alpha(self, alpha) } /// Sets the background [NcAlphaBits]. /// /// *C style function: [channels_set_bg_alpha()][crate::channels_set_bg_alpha].* fn set_bg_alpha(&mut self, alpha: NcAlphaBits) { crate::channels_set_bg_alpha(self, alpha) } // NcRgb /// Gets the foreground [NcRgb]. /// /// *C style function: [channels_fg_rgb()][crate::channels_fg_rgb].* fn fg_rgb(&self) -> NcRgb { crate::channels_fg_rgb(*self) } /// Gets the background [NcRgb]. /// /// *C style function: [channels_bg_rgb()][crate::channels_bg_rgb].* fn bg_rgb(&self) -> NcRgb { crate::channels_bg_rgb(*self) } /// Sets the foreground [NcRgb]. /// /// *C style function: [channels_set_fg_rgb()][crate::channels_set_fg_rgb].* fn set_fg_rgb(&mut self, rgb: NcRgb) { crate::channels_set_fg_rgb(self, rgb) } /// Sets the background [NcRgb]. /// /// *C style function: [channels_set_bg_rgb()][crate::channels_set_bg_rgb].* fn set_bg_rgb(&mut self, rgb: NcRgb) { crate::channels_set_bg_rgb(self, rgb) } // NcColor /// Gets the three foreground [NcColor]s (r, g, b). /// /// *C style function: [channels_fg_rgb8()][crate::channels_fg_rgb8].* fn fg_rgb8(&self) -> (NcColor, NcColor, NcColor) { let (mut r, mut g, mut b) = (0, 0, 0); crate::channels_fg_rgb8(*self, &mut r, &mut g, &mut b); (r, g, b) } /// Gets the three background [NcColor]s (r, g, b). /// /// *C style function: [channels_bg_rgb8()][crate::channels_bg_rgb8].* fn bg_rgb8(&self) -> (NcColor, NcColor, NcColor) { let (mut r, mut g, mut b) = (0, 0, 0); crate::channels_bg_rgb8(*self, &mut r, &mut g, &mut b); (r, g, b) } /// Sets the three foreground [NcColor]s (r, g, b), and /// marks the foreground [NcChannel] as not using the "default color". /// /// *C style function: [channels_set_fg_rgb8()][crate::channels_set_fg_rgb8].* fn set_fg_rgb8(&mut self, r: NcColor, g: NcColor, b: NcColor) -> NcChannelPair { crate::channels_set_fg_rgb8(self, r, g, b) } /// Sets the three background [NcColor]s (r, g, b), and /// marks the background [NcChannel] as not using the "default color". /// /// *C style function: [channels_set_bg_rgb8()][crate::channels_set_bg_rgb8].* fn set_bg_rgb8(&mut self, r: NcColor, g: NcColor, b: NcColor) -> NcChannelPair { crate::channels_set_bg_rgb8(self, r, g, b) } /// Gets the foreground red [NcColor]. /// /// *(No equivalent C style function)* fn fg_r(&self) -> NcColor { crate::channel_r(crate::channels_fchannel(*self)) } /// Gets the foreground green [NcColor]. /// /// *(No equivalent C style function)* fn fg_g(&self) -> NcColor { crate::channel_g(crate::channels_fchannel(*self)) } /// Gets the foreground blue [NcColor]. /// /// *(No equivalent C style function)* fn fg_b(&self) -> NcColor { crate::channel_b(crate::channels_fchannel(*self)) } /// Gets the background red [NcColor]. /// /// *(No equivalent C style function)* fn bg_r(&self) -> NcColor { crate::channel_r(crate::channels_bchannel(*self)) } /// Gets the background green [NcColor]. /// /// *(No equivalent C style function)* fn bg_g(&self) -> NcColor { crate::channel_g(crate::channels_bchannel(*self)) } /// Gets the background blue [NcColor]. /// /// *(No equivalent C style function)* fn bg_b(&self) -> NcColor { crate::channel_b(crate::channels_bchannel(*self)) } /// Sets the foreground red [NcColor], and returns the new NcChannelPair. /// /// *(No equivalent C style function)* fn fg_set_r(&mut self, r: NcColor) -> NcChannelPair { let (_, g, b) = self.bg_rgb8(); crate::channels_set_fg_rgb8(self, r, g, b) } /// Sets the foreground green [NcColor], and returns the new NcChannelPair. /// /// *(No equivalent C style function)* fn fg_set_g(&mut self, g: NcColor) -> NcChannelPair { let (r, _, b) = self.bg_rgb8(); crate::channels_set_fg_rgb8(self, r, g, b) } /// Sets the foreground blue [NcColor], and returns the new NcChannelPair. /// /// *(No equivalent C style function)* fn fg_set_b(&mut self, b: NcColor) -> NcChannelPair { let (r, g, _) = self.bg_rgb8(); crate::channels_set_fg_rgb8(self, r, g, b) } /// Sets the background red [NcColor], and returns the new NcChannelPair. /// /// *(No equivalent C style function)* fn bg_set_r(&mut self, r: NcColor) -> NcChannelPair { let (_, g, b) = self.bg_rgb8(); crate::channels_set_bg_rgb8(self, r, g, b) } /// Sets the background green [NcColor], and returns the new NcChannelPair. /// /// *(No equivalent C style function)* fn bg_set_g(&mut self, g: NcColor) -> NcChannelPair { let (r, _, b) = self.bg_rgb8(); crate::channels_set_bg_rgb8(self, r, g, b) } /// Sets the background blue [NcColor], and returns the new NcChannelPair. /// /// *(No equivalent C style function)* fn bg_set_b(&mut self, b: NcColor) -> NcChannelPair { let (r, g, _) = self.bg_rgb8(); crate::channels_set_bg_rgb8(self, r, g, b) } // default color /// Is the background using the "default background color"? /// /// *C style function: [channels_fg_default_p()][crate::channels_fg_default_p].* fn fg_default_p(&self) -> bool { crate::channels_fg_default_p(*self) } /// Is the background using the "default background color"? /// /// The "default background color" must generally be used to take advantage /// of terminal-effected transparency. /// /// *C style function: [channels_bg_default_p()][crate::channels_bg_default_p].* fn bg_default_p(&self) -> bool { crate::channels_bg_default_p(*self) } /// Marks the foreground as using its "default color", and /// returns the new [NcChannelPair]. /// /// *C style function: [channels_set_fg_default()][crate::channels_set_fg_default].* fn set_fg_default(&mut self) -> NcChannelPair { crate::channels_set_fg_default(self) } /// Marks the background as using its "default color", and /// returns the new [NcChannelPair]. /// /// *C style function: [channels_set_bg_default()][crate::channels_set_bg_default].* fn set_bg_default(&mut self) -> NcChannelPair { crate::channels_set_bg_default(self) } // NcPaletteIndex /// Is the foreground of using an [indexed][NcPaletteIndex] /// [NcPalette][crate::NcPalette] color? /// /// *C style function: [channels_fg_palindex_p()][crate::channels_fg_palindex_p].* fn fg_palindex_p(&self) -> bool { crate::channels_fg_palindex_p(*self) } /// Is the background of using an [indexed][NcPaletteIndex] /// [NcPalette][crate::NcPalette] color? /// /// *C style function: [channels_bg_palindex_p()][crate::channels_bg_palindex_p].* fn bg_palindex_p(&self) -> bool { crate::channels_bg_palindex_p(*self) } /// Sets the foreground of an [NcChannelPair] as using an /// [indexed][NcPaletteIndex] [NcPalette][crate::NcPalette] color. /// /// *C style function: [channels_set_fg_palindex()][crate::channels_set_fg_palindex].* fn set_fg_palindex(&mut self, index: NcPaletteIndex) { crate::channels_set_fg_palindex(self, index) } /// Sets the background of an [NcChannelPair] as using an /// [indexed][NcPaletteIndex] [NcPalette][crate::NcPalette] color. /// /// *C style function: [channels_set_bg_palindex()][crate::channels_set_bg_palindex].* fn set_bg_palindex(&mut self, index: NcPaletteIndex) { crate::channels_set_bg_palindex(self, index) } } libnotcurses-sys-2.1.8/src/channel/mod.rs010064400017500001750000000205521400616507400165660ustar 00000000000000//! `NcChannel*` // ----------------------------------------------------------------------------- // - The channel components are u8 instead of u32. // Because of type enforcing, some runtime checks are now unnecessary. // // - None of the functions can't fail now. The original checks for dirty bits // have been substitued by mask cleaning (bitwise and) // // - These functions were deemed unnecessary to implement: // - `channel_set_rgb_clipped()` // - `channels_set_fg_rgb8_clipped()` // - `channels_set_bg_rgb8_clipped()` // ----------------------------------------------------------------------------- // // functions manually reimplemented: 39 // ------------------------------------------ // (X) wont: 3 // (+) done: 36 / 0 // (#) test: 19 // (W) wrap: 36 // ------------------------------------------ //W# channel_alpha //W# channel_b //W# channel_default_p //W# channel_g //W# channel_palindex_p //W# channel_r //W# channel_rgb8 //W+ channel_set //W# channel_set_alpha //W# channel_set_default //W# channel_set_rgb8 // X channel_set_rgb_clipped // not needed //W# channels_bchannel //W+ channels_bg_alpha //W+ channels_bg_default_p //W# channels_bg_palindex_p //W+ channels_bg_rgb //W+ channels_bg_rgb8 //W# channels_combine //W# channels_fchannel //W+ channels_fg_alpha //W+ channels_fg_default_p //W# channels_fg_palindex_p //W+ channels_fg_rgb //W+ channels_fg_rgb8 //W# channels_set_bchannel //W+ channels_set_bg_alpha //W+ channels_set_bg_default //W# channels_set_bg_palindex //W+ channels_set_bg_rgb //W+ channels_set_bg_rgb8 // X channels_set_bg_rgb8_clipped // not needed //W# channels_set_fchannel //W+ channels_set_fg_alpha //W+ channels_set_fg_default //W# channels_set_fg_palindex //W+ channels_set_fg_rgb //W+ channels_set_fg_rgb8 // X channels_set_fg_rgb8_clipped // not needed #[cfg(test)] mod test; mod methods; mod reimplemented; pub use methods::{NcChannelMethods, NcChannelPairMethods}; pub use reimplemented::*; // NcChannel // /// 32 bits of context-dependent info /// containing RGB + 2 bits of alpha + extra /// /// It is: /// - a 24-bit [`NcRgb`] value /// - plus 8 bits divided in: /// - 2 bits of [`NcAlphaBits`] /// - 6 bits of context-dependent info /// /// The context details are documented in [`NcChannelPair`] /// /// ## Diagram /// /// ```txt /// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB /// ``` /// `type in C: channel (uint32_t)` /// pub type NcChannel = u32; /// Extract these bits to get a channel's alpha value pub const NCCHANNEL_ALPHA_MASK: u32 = crate::bindings::ffi::CHANNEL_ALPHA_MASK; // NcAlphaBits // /// 2 bits of alpha (surrounded by context dependent bits). /// It is part of an [`NcChannel`]. /// /// ## Diagram /// /// ```txt /// ~~AA~~~~ -------- -------- -------- /// ``` /// /// `type in C: no data type` /// pub type NcAlphaBits = u32; // NcChannelPair // /// 64 bits containing a foreground and background [`NcChannel`] /// /// At render time, both 24-bit [`NcRgb`] values are quantized down to terminal /// capabilities, if necessary. There's a clear path to 10-bit support should /// we one day need it. /// /// ## Default Color /// /// The "default color" is best explained by /// [color(3NCURSES)](https://manpages.debian.org/stretch/ncurses-doc/color.3ncurses.en.html) /// and [default_colors(3NCURSES)](https://manpages.debian.org/stretch/ncurses-doc/default_colors.3ncurses.en.html). /// Ours is the same concept. /// /// **Until the "not default color" bit is set, any color you load will be ignored.** /// /// ## Diagram /// /// ```txt /// ~~AA~~~~|RRRRRRRR|GGGGGGGG|BBBBBBBB|~~AA~~~~|RRRRRRRR|GGGGGGGG|BBBBBBBB /// ↑↑↑↑↑↑↑↑↑↑↑↑ foreground ↑↑↑↑↑↑↑↑↑↑↑|↑↑↑↑↑↑↑↑↑↑↑↑ background ↑↑↑↑↑↑↑↑↑↑↑ /// ``` /// /// Detailed info (specially on the context-dependent bits on each /// [`NcChannel`]'s 4th byte): /// /// ```txt /// ~foreground channel~ /// NCCELL_WIDEASIAN_MASK: part of a wide glyph ↓bits view↓ ↓hex mask↓ /// 1······· ········ ········ ········ ········ ········ ········ ········ = 8······· ········ /// /// NCCELL_FGDEFAULT_MASK: foreground is NOT "default color" /// ·1······ ········ ········ ········ ········ ········ ········ ········ = 4······· ········ /// /// NCCELL_FG_ALPHA_MASK: foreground alpha (2bits) /// ··11···· ········ ········ ········ ········ ········ ········ ········ = 3······· ········ /// /// NCCELL_FG_PALETTE: foreground uses palette index /// ····1··· ········ ········ ········ ········ ········ ········ ········ = ·8······ ········ /// /// NCCELL_NOBACKGROUND_MASK: glyph is entirely foreground /// ·····1·· ········ ········ ········ ········ ········ ········ ········ = ·4······ ········ /// /// reserved, must be 0 /// ······00 ········ ········ ········ ········ ········ ········ ········ = ·3······ ········ /// /// NCCELL_FG_RGB_MASK: foreground in 3x8 RGB (rrggbb) /// ········ 11111111 11111111 11111111 ········ ········ ········ ········ = ··FFFFFF ········ /// ``` /// ```txt /// ~background channel~ /// reserved, must be 0 ↓bits view↓ ↓hex mask↓ /// ········ ········ ········ ········ 0······· ········ ········ ········ = ········ 8······· /// /// NCCELL_BGDEFAULT_MASK: background is NOT "default color" /// ········ ········ ········ ········ ·1······ ········ ········ ········ = ········ 4······· /// /// NCCELL_BG_ALPHA_MASK: background alpha (2 bits) /// ········ ········ ········ ········ ··11···· ········ ········ ········ = ········ 3······· /// /// NCCELL_BG_PALETTE: background uses palette index /// ········ ········ ········ ········ ····1··· ········ ········ ········ = ········ ·8······ /// /// reserved, must be 0 /// ········ ········ ········ ········ ·····000 ········ ········ ········ = ········ ·7······ /// /// NCCELL_BG_RGB_MASK: background in 3x8 RGB (rrggbb) /// 0········ ········ ········ ········ ········11111111 11111111 11111111 = ········ ··FFFFFF /// ``` /// `type in C: channels (uint64_t)` /// /// ## `NcCell` Mask Flags /// /// - [`NCCELL_BGDEFAULT_MASK`][crate::NCCELL_BGDEFAULT_MASK] /// - [`NCCELL_BG_ALPHA_MASK`][crate::NCCELL_BG_ALPHA_MASK] /// - [`NCCELL_BG_PALETTE`][crate::NCCELL_BG_PALETTE] /// - [`NCCELL_BG_RGB_MASK`][crate::NCCELL_BG_RGB_MASK] /// - [`NCCELL_FGDEFAULT_MASK`][crate::NCCELL_FGDEFAULT_MASK] /// - [`NCCELL_FG_ALPHA_MASK`][crate::NCCELL_FG_ALPHA_MASK] /// - [`NCCELL_FG_PALETTE`][crate::NCCELL_FG_PALETTE] /// - [`NCCELL_FG_RGB_MASK`][crate::NCCELL_FG_RGB_MASK] /// pub type NcChannelPair = u64; // NcRgb // /// 24 bits broken into 3x 8bpp channels. /// /// Unlike with [`NcChannel`], operations involving `NcRgb` ignores the last 4th byte /// /// ## Diagram /// /// ```txt /// -------- RRRRRRRR GGGGGGGG BBBBBBBB /// ``` /// /// `type in C: no data type` /// pub type NcRgb = u32; // NcColor // /// 8 bits representing a R/G/B color or alpha channel /// /// ## Diagram /// /// ```txt /// CCCCCCCC (1 Byte) /// ``` /// /// `type in C: no data type` /// pub type NcColor = u8; /// the [NcEgc][crate::NcEgc] which form the various levels of a given geometry. /// /// If the geometry is wide, things are arranged with the rightmost side /// increasing most quickly, i.e. it can be indexed as height arrays of /// 1 + height glyphs. /// i.e. The first five braille EGCs are all 0 on the left, /// [0..4] on the right. /// /// `type in C: blitset (struct)` /// pub type NcBlitSet = crate::bindings::ffi::blitset; libnotcurses-sys-2.1.8/src/channel/reimplemented.rs010064400017500001750000000362341377416500600206530ustar 00000000000000//! `channel*_*` reimplemented functions. use crate::{ NcAlphaBits, NcChannel, NcChannelPair, NcColor, NcPaletteIndex, NcRgb, NCCELL_ALPHA_HIGHCONTRAST, NCCELL_ALPHA_OPAQUE, NCCELL_BGDEFAULT_MASK, NCCELL_BG_PALETTE, NCCELL_BG_RGB_MASK, NCCELL_FGDEFAULT_MASK, NCCELL_FG_PALETTE, NCCHANNEL_ALPHA_MASK, }; // Alpha ----------------------------------------------------------------------- /// Gets the [NcAlphaBits] from an [NcChannel]. /// /// *Method: NcChannel.[alpha()][NcChannel#method.alpha]* #[inline] pub const fn channel_alpha(channel: NcChannel) -> NcAlphaBits { channel & NCCHANNEL_ALPHA_MASK } /// Sets the [NcAlphaBits] of an [NcChannel]. /// /// *Method: NcChannel.[set_alpha()][NcChannel#method.set_alpha]* #[inline] pub fn channel_set_alpha(channel: &mut NcChannel, alpha: NcAlphaBits) { let alpha_clean = alpha & NCCHANNEL_ALPHA_MASK; *channel = alpha_clean | (*channel & !NCCHANNEL_ALPHA_MASK); if alpha != NCCELL_ALPHA_OPAQUE { // indicate that we are *not* using the default background color *channel |= NCCELL_BGDEFAULT_MASK; } } /// Gets the foreground [NcAlphaBits] from an [NcChannelPair], shifted to LSBs. /// /// *Method: NcChannelPair.[fg_alpha()][NcChannelPair#method.fg_alpha]* #[inline] pub const fn channels_fg_alpha(channels: NcChannelPair) -> NcAlphaBits { channel_alpha(channels_fchannel(channels)) } /// Gets the background [NcAlphaBits] from an [NcChannelPair], shifted to LSBs. /// /// *Method: NcChannelPair.[bg_alpha()][NcChannelPair#method.bg_alpha]* #[inline] pub const fn channels_bg_alpha(channels: NcChannelPair) -> NcAlphaBits { channel_alpha(channels_bchannel(channels)) } /// Sets the [NcAlphaBits] of the foreground [NcChannel] of an [NcChannelPair]. /// /// *Method: NcChannelPair.[set_fg_alpha()][NcChannelPair#method.set_fg_alpha]* #[inline] pub fn channels_set_fg_alpha(channels: &mut NcChannelPair, alpha: NcAlphaBits) { let mut channel = channels_fchannel(*channels); channel_set_alpha(&mut channel, alpha); *channels = (channel as NcChannelPair) << 32 | *channels & 0xffffffff_u64; } /// Sets the [NcAlphaBits] of the background [NcChannel] of an [NcChannelPair]. /// /// *Method: NcChannelPair.[set_bg_alpha()][NcChannelPair#method.set_bg_alpha]* #[inline] pub fn channels_set_bg_alpha(channels: &mut NcChannelPair, alpha: NcAlphaBits) { let mut alpha_clean = alpha; if alpha == NCCELL_ALPHA_HIGHCONTRAST { // forbidden for background alpha, so makes it opaque alpha_clean = NCCELL_ALPHA_OPAQUE; } let mut channel = channels_bchannel(*channels); channel_set_alpha(&mut channel, alpha_clean); channels_set_bchannel(channels, channel); } // Channels -------------------------------------------------------------------- /// Extracts the background [NcChannel] from a [NcChannelPair]. /// /// *Method: NcChannelPair.[bchannel()][NcChannelPair#method.bchannel]* #[inline] pub const fn channels_bchannel(channels: NcChannelPair) -> NcChannel { (channels & 0xffffffff_u64) as NcChannel } /// Extracts the foreground [NcChannel] from an [NcChannelPair]. /// /// *Method: NcChannelPair.[fchannel()][NcChannelPair#method.fchannel]* #[inline] pub const fn channels_fchannel(channels: NcChannelPair) -> NcChannel { channels_bchannel(channels >> 32) } /// Sets the background [NcChannel] of an [NcChannelPair]. /// /// *Method: NcChannelPair.[set_bchannel()][NcChannelPair#method.set_bchannel]* #[inline] pub fn channels_set_bchannel(channels: &mut NcChannelPair, bchannel: NcChannel) -> NcChannelPair { *channels = (*channels & 0xffffffff00000000_u64) | bchannel as u64; *channels } /// Sets the foreground [NcChannel] of an [NcChannelPair]. /// /// *Method: NcChannelPair.[set_fchannel()][NcChannelPair#method.set_fchannel]* #[inline] pub fn channels_set_fchannel(channels: &mut NcChannelPair, fchannel: NcChannel) -> NcChannelPair { *channels = (*channels & 0xffffffff_u64) | (fchannel as u64) << 32; *channels } /// Combines two [NcChannel]s into an [NcChannelPair]. /// /// *Method: NcChannelPair.[combine()][NcChannelPair#method.combine]* #[inline] pub fn channels_combine(fchannel: NcChannel, bchannel: NcChannel) -> NcChannelPair { let mut channels: NcChannelPair = 0; channels_set_fchannel(&mut channels, fchannel); channels_set_bchannel(&mut channels, bchannel); channels } // NcColor --------------------------------------------------------------------- /// Gets the red [NcColor] from an [NcChannel]. /// /// *Method: NcChannel.[r()][NcChannel#method.r]* #[inline] pub const fn channel_r(channel: NcChannel) -> NcColor { ((channel & 0xff0000) >> 16) as NcColor } /// Gets the green [NcColor] from an [NcChannel]. /// /// *Method: NcChannel.[g()][NcChannel#method.g]* #[inline] pub const fn channel_g(channel: NcChannel) -> NcColor { ((channel & 0x00ff00) >> 8) as NcColor } /// Gets the blue [NcColor] from an [NcChannel]. /// /// *Method: NcChannel.[b()][NcChannel#method.b]* #[inline] pub const fn channel_b(channel: NcChannel) -> NcColor { (channel & 0x0000ff) as NcColor } /// Sets the red [NcColor] of an [NcChannel], and returns it. /// /// *Method: NcChannel.[set_r()][NcChannel#method.set_r]* // // Not in the C API. #[inline] pub fn channel_set_r(channel: &mut NcChannel, r: NcColor) -> NcChannel { *channel = (r as NcChannel) << 16 | (*channel & 0xff00) | (*channel & 0xff); *channel } /// Sets the green [NcColor] of an [NcChannel], and returns it. /// /// *Method: NcChannel.[set_g()][NcChannel#method.set_g]* // // Not in the C API. #[inline] pub fn channel_set_g(channel: &mut NcChannel, g: NcColor) -> NcChannel { *channel = (*channel & 0xff0000) | (g as NcChannel) << 8 | (*channel & 0xff); *channel } /// Sets the blue [NcColor] of an [NcChannel], and returns it. /// /// *Method: NcChannel.[set_b()][NcChannel#method.set_b]* // // Not in the C API. #[inline] pub fn channel_set_b(channel: &mut NcChannel, b: NcColor) -> NcChannel { *channel = (*channel & 0xff0000) | (*channel & 0xff00) | (b as NcChannel); *channel } /// Gets the three RGB [NcColor]s from an [NcChannel], and returns it. /// /// *Method: NcChannel.[rgb8()][NcChannel#method.rgb8]* #[inline] pub fn channel_rgb8( channel: NcChannel, r: &mut NcColor, g: &mut NcColor, b: &mut NcColor, ) -> NcChannel { *r = channel_r(channel); *g = channel_g(channel); *b = channel_b(channel); channel } /// Sets the three RGB [NcColor]s an [NcChannel], and marks it as not using the /// "default color", retaining the other bits unchanged. /// /// *Method: NcChannel.[set_rgb8()][NcChannel#method.set_rgb8]* #[inline] pub fn channel_set_rgb8(channel: &mut NcChannel, r: NcColor, g: NcColor, b: NcColor) { let rgb: NcRgb = (r as NcChannel) << 16 | (g as NcChannel) << 8 | (b as NcChannel); *channel = (*channel & !NCCELL_BG_RGB_MASK) | NCCELL_BGDEFAULT_MASK | rgb; } /// Gets the three foreground RGB [NcColor]s from an [NcChannelPair], and /// returns the foreground [NcChannel] (which can have some extra bits set). /// /// *Method: NcChannelPair.[fg_rgb8()][NcChannelPair#method.fg_rgb8]* #[inline] pub fn channels_fg_rgb8( channels: NcChannelPair, r: &mut NcColor, g: &mut NcColor, b: &mut NcColor, ) -> NcChannel { channel_rgb8(channels_fchannel(channels), r, g, b) } /// Gets the three background RGB [NcColor]s from an [NcChannelPair], and /// returns the background [NcChannel] (which can have some extra bits set). /// /// *Method: NcChannelPair.[bg_rgb8()][NcChannelPair#method.bg_rgb8]* #[inline] pub fn channels_bg_rgb8( channels: NcChannelPair, r: &mut NcColor, g: &mut NcColor, b: &mut NcColor, ) -> NcChannel { channel_rgb8(channels_bchannel(channels), r, g, b) } /// Sets the three foreground RGB [NcColor]s of an [NcChannelPair], and /// marks it as not using the "default color". /// /// Unlike the original C API, it also returns the new NcChannelPair. /// /// *Method: NcChannelPair.[set_fg_rgb8()][NcChannelPair#method.set_fg_rgb8]* #[inline] pub fn channels_set_fg_rgb8( channels: &mut NcChannelPair, r: NcColor, g: NcColor, b: NcColor, ) -> NcChannelPair { let mut channel = channels_fchannel(*channels); channel_set_rgb8(&mut channel, r, g, b); *channels = (channel as u64) << 32 | *channels & 0xffffffff_u64; *channels } /// Sets the three background RGB [NcColor]s of an [NcChannelPair], and /// marks it as not using the "default color". /// /// Unlike the original C API, it also returns the new NcChannelPair. /// /// *Method: NcChannelPair.[set_bg_rgb8()][NcChannelPair#method.set_bg_rgb8]* #[inline] pub fn channels_set_bg_rgb8( channels: &mut NcChannelPair, r: NcColor, g: NcColor, b: NcColor, ) -> NcChannelPair { let mut channel = channels_bchannel(*channels); channel_set_rgb8(&mut channel, r, g, b); channels_set_bchannel(channels, channel); *channels } // NcRgb ----------------------------------------------------------------------- /// Gets the foreground [NcRgb] from an [NcChannelPair], shifted to LSBs. /// /// *Method: NcChannelPair.[fg_rgb()][NcChannelPair#method.fg_rgb]* #[inline] pub fn channels_fg_rgb(channels: NcChannelPair) -> NcRgb { channels_fchannel(channels) & NCCELL_BG_RGB_MASK } /// Gets the background [NcRgb] from an [NcChannelPair], shifted to LSBs. /// /// *Method: NcChannelPair.[bg_rgb()][NcChannelPair#method.bg_rgb]* #[inline] pub fn channels_bg_rgb(channels: NcChannelPair) -> NcRgb { channels_bchannel(channels) & NCCELL_BG_RGB_MASK } /// Gets the [NcRgb] of an [NcChannel]. /// /// This function basically removes the 4th byte of the NcChannel. /// /// *Method: NcChannel.[rgb()][NcChannel#method.rgb]* // // Not in the C API #[inline] pub const fn channel_rgb(channel: NcChannel) -> NcRgb { channel & NCCELL_BG_RGB_MASK } /// Sets the [NcRgb] of an [NcChannel], and marks it /// as not using the "default color", retaining the other bits unchanged. /// /// *Method: NcChannel.[set()][NcChannel#method.set]* #[inline] pub fn channel_set(channel: &mut NcChannel, rgb: NcRgb) { *channel = (*channel & !NCCELL_BG_RGB_MASK) | NCCELL_BGDEFAULT_MASK | (rgb & 0x00ffffff); } /// Sets the foreground [NcRgb] of an [NcChannelPair], /// and marks it as not using the the "default color". /// /// *Method: NcChannelPair.[set_fg_rgb()][NcChannelPair#method.set_fg_rgb]* #[inline] pub fn channels_set_fg_rgb(channels: &mut NcChannelPair, rgb: NcRgb) { let mut channel = channels_fchannel(*channels); channel_set(&mut channel, rgb); *channels = (channel as u64) << 32 | *channels & 0xffffffff_u64; } /// Sets the foreground [NcRgb] of an [NcChannelPair], /// and marks it as not using the the "default color". /// /// *Method: NcChannelPair.[set_bg_rgb()][NcChannelPair#method.set_bg_rgb]* #[inline] pub fn channels_set_bg_rgb(channels: &mut NcChannelPair, rgb: NcRgb) { let mut channel = channels_bchannel(*channels); channel_set(&mut channel, rgb); channels_set_bchannel(channels, channel); } // Default --------------------------------------------------------------------- /// Is this [NcChannel] using the "default color" rather than RGB/palette-indexed? /// /// *Method: NcChannel.[default_p()][NcChannel#method.default_p]* #[inline] pub const fn channel_default_p(channel: NcChannel) -> bool { (channel & NCCELL_BGDEFAULT_MASK) == 0 } /// Marks an [NcChannel] as using its "default color", which also marks it opaque. /// /// *Method: NcChannel.[set_default()][NcChannel#method.set_default]* #[inline] pub fn channel_set_default(channel: &mut NcChannel) -> NcChannel { *channel &= !(NCCELL_BGDEFAULT_MASK | NCCELL_ALPHA_HIGHCONTRAST); *channel } /// Is the foreground of an [NcChannelPair] using the "default foreground color"? /// /// *Method: NcChannelPair.[fg_default_p()][NcChannelPair#method.fg_default_p]* #[inline] pub fn channels_fg_default_p(channels: NcChannelPair) -> bool { channel_default_p(channels_fchannel(channels)) } /// Is the background using the "default background color"? /// /// The "default background color" must generally be used to take advantage of /// terminal-effected transparency. /// /// *Method: NcChannelPair.[bg_default_p()][NcChannelPair#method.bg_default_p]* #[inline] pub fn channels_bg_default_p(channels: NcChannelPair) -> bool { channel_default_p(channels_bchannel(channels)) } /// Marks the foreground of an [NcChannelPair] as using its "default color", /// and returns the new [NcChannelPair]. /// /// *Method: NcChannelPair.[set_fg_default()][NcChannelPair#method.set_fg_default]* #[inline] pub fn channels_set_fg_default(channels: &mut NcChannelPair) -> NcChannelPair { let mut channel = channels_fchannel(*channels); channel_set_default(&mut channel); *channels = (channel as u64) << 32 | *channels & 0xffffffff_u64; *channels } /// Marks the background of an [NcChannelPair] as using its "default color", /// and returns the new [NcChannelPair]. /// /// *Method: NcChannelPair.[set_bg_default()][NcChannelPair#method.set_bg_default]* #[inline] pub fn channels_set_bg_default(channels: &mut NcChannelPair) -> NcChannelPair { let mut channel = channels_bchannel(*channels); channel_set_default(&mut channel); channels_set_bchannel(channels, channel); *channels } // Palette --------------------------------------------------------------------- /// Is this [NcChannel] using palette-indexed color rather than RGB? /// /// *Method: NcChannel.[palindex_p()][NcChannel#method.palindex_p]* #[inline] pub fn channel_palindex_p(channel: NcChannel) -> bool { !(channel_default_p(channel) && (channel & NCCELL_BG_PALETTE) == 0) } /// Is the foreground of an [NcChannelPair] using an [indexed][NcPaletteIndex] /// [NcPalette][crate::NcPalette] color? /// /// *Method: NcChannelPair.[fg_palindex_p()][NcChannelPair#method.fg_palindex_p]* #[inline] pub fn channels_fg_palindex_p(channels: NcChannelPair) -> bool { channel_palindex_p(channels_fchannel(channels)) } /// Is the background of an [NcChannelPair] using an [indexed][NcPaletteIndex] /// [NcPalette][crate::NcPalette] color? /// /// *Method: NcChannelPair.[bg_palindex_p()][NcChannelPair#method.bg_palindex_p]* #[inline] pub fn channels_bg_palindex_p(channels: NcChannelPair) -> bool { channel_palindex_p(channels_bchannel(channels)) } /// Sets the foreground of an [NcChannelPair] as using an /// [indexed][NcPaletteIndex] [NcPalette][crate::NcPalette] color. /// /// *Method: NcChannelPair.[set_fg_palindex()][NcChannelPair#method.set_fg_palindex]* #[inline] pub fn channels_set_fg_palindex(channels: &mut NcChannelPair, index: NcPaletteIndex) { *channels |= NCCELL_FGDEFAULT_MASK; *channels |= NCCELL_FG_PALETTE as NcChannelPair; channels_set_fg_alpha(channels, NCCELL_ALPHA_OPAQUE); *channels &= 0xff000000ffffffff as NcChannelPair; *channels |= (index as NcChannelPair) << 32; } /// Sets the background of an [NcChannelPair] as using an /// [indexed][NcPaletteIndex] [NcPalette][crate::NcPalette] color. /// /// *Method: NcChannelPair.[set_bg_palindex()][NcChannelPair#method.set_bg_palindex]* #[inline] pub fn channels_set_bg_palindex(channels: &mut NcChannelPair, index: NcPaletteIndex) { *channels |= NCCELL_BGDEFAULT_MASK as NcChannelPair; *channels |= NCCELL_BG_PALETTE as NcChannelPair; channels_set_bg_alpha(channels, NCCELL_ALPHA_OPAQUE); *channels &= 0xffffffffff000000; *channels |= index as NcChannelPair; } libnotcurses-sys-2.1.8/src/channel/test/methods.rs010064400017500001750000000002551376441154400204350ustar 00000000000000//! Test `NcChannel*` methods and associated functions. // use crate::{NcChannel, NcChannelPair}; // // use serial_test::serial; // // #[test] // #[serial] // fn () { // } libnotcurses-sys-2.1.8/src/channel/test/mod.rs010064400017500001750000000001241376441154400175440ustar 00000000000000//! `NcChannel*` tests. #[cfg(test)] mod methods; #[cfg(test)] mod reimplemented; libnotcurses-sys-2.1.8/src/channel/test/reimplemented.rs010064400017500001750000000076411376441154400216320ustar 00000000000000//! Test `channel*_*` reimplemented functions. use serial_test::serial; use crate::{ NcChannel, NcChannelPair, NCCELL_ALPHA_BLEND, NCCELL_ALPHA_HIGHCONTRAST, NCCELL_ALPHA_OPAQUE, NCCELL_ALPHA_TRANSPARENT, }; #[test] #[serial] fn channel_r() { let c: NcChannel = 0x112233; assert_eq!(crate::channel_r(c), 0x11); } #[test] #[serial] fn channel_g() { let c: NcChannel = 0x112233; assert_eq!(crate::channel_g(c), 0x22); } #[test] #[serial] fn channel_b() { let c: NcChannel = 0x112233; assert_eq!(crate::channel_b(c), 0x33); } #[test] #[serial] fn channel_rgb8() { let c: NcChannel = 0x112233; let mut r = 0; let mut g = 0; let mut b = 0; crate::channel_rgb8(c, &mut r, &mut g, &mut b); assert_eq!(r, 0x11); assert_eq!(g, 0x22); assert_eq!(b, 0x33); } #[test] #[serial] fn channel_set_rgb8() { let mut c: NcChannel = 0x000000; crate::channel_set_rgb8(&mut c, 0x11, 0x22, 0x33); assert_eq!(crate::channel_r(c), 0x11); assert_eq!(crate::channel_g(c), 0x22); assert_eq!(crate::channel_b(c), 0x33); } #[test] #[serial] fn channel_alpha() { let c: NcChannel = 0x112233 | NCCELL_ALPHA_TRANSPARENT; assert_eq!(crate::channel_alpha(c), NCCELL_ALPHA_TRANSPARENT); } #[test] #[serial] fn channel_set_alpha() { let mut c: NcChannel = 0x112233; crate::channel_set_alpha(&mut c, NCCELL_ALPHA_HIGHCONTRAST); assert_eq!(NCCELL_ALPHA_HIGHCONTRAST, crate::channel_alpha(c)); crate::channel_set_alpha(&mut c, NCCELL_ALPHA_TRANSPARENT); assert_eq!(NCCELL_ALPHA_TRANSPARENT, crate::channel_alpha(c)); crate::channel_set_alpha(&mut c, NCCELL_ALPHA_BLEND); assert_eq!(NCCELL_ALPHA_BLEND, crate::channel_alpha(c)); crate::channel_set_alpha(&mut c, NCCELL_ALPHA_OPAQUE); assert_eq!(NCCELL_ALPHA_OPAQUE, crate::channel_alpha(c)); // TODO: CHECK for NCCELL_BGDEFAULT_MASK } #[test] #[serial] fn channel_set_default() { const DEFAULT: NcChannel = 0x112233; let mut c: NcChannel = DEFAULT | NCCELL_ALPHA_TRANSPARENT; assert!(c != DEFAULT); crate::channel_set_default(&mut c); assert_eq!(c, DEFAULT); } #[test] #[serial] fn channel_default_p() { let mut c: NcChannel = 0x112233; assert_eq!(true, crate::channel_default_p(c)); let _ = crate::channel_set_alpha(&mut c, NCCELL_ALPHA_OPAQUE); assert_eq!(true, crate::channel_default_p(c)); crate::channel_set(&mut c, 0x112233); assert_eq!(false, crate::channel_default_p(c)); } #[test] #[serial] #[allow(non_snake_case)] fn channels_set_fchannel__channels_fchannel() { let fc: NcChannel = 0x112233; let mut cp: NcChannelPair = 0; crate::channels_set_fchannel(&mut cp, fc); assert_eq!(crate::channels_fchannel(cp), fc); } #[test] #[serial] #[allow(non_snake_case)] fn channels_set_bchannel__channels_bchannel() { let bc: NcChannel = 0x112233; let mut cp: NcChannelPair = 0; crate::channels_set_bchannel(&mut cp, bc); assert_eq!(crate::channels_bchannel(cp), bc); } #[test] #[serial] fn channels_combine() { let bc: NcChannel = 0x112233; let fc: NcChannel = 0x445566; let mut cp1: NcChannelPair = 0; let mut _cp2: NcChannelPair = 0; crate::channels_set_bchannel(&mut cp1, bc); crate::channels_set_fchannel(&mut cp1, fc); _cp2 = crate::channels_combine(fc, bc); assert_eq!(cp1, _cp2); } #[test] #[serial] fn channels_palette() { let bc: NcChannel = 0x112233; let fc: NcChannel = 0x445566; assert_eq!(false, crate::channel_palindex_p(bc)); assert_eq!(false, crate::channel_palindex_p(fc)); let mut channels = crate::channels_combine(fc, bc); assert_eq!(false, crate::channels_fg_palindex_p(channels)); assert_eq!(false, crate::channels_bg_palindex_p(channels)); crate::channels_set_fg_palindex(&mut channels, 5); crate::channels_set_bg_palindex(&mut channels, 6); assert_eq!(true, crate::channels_fg_palindex_p(channels)); assert_eq!(true, crate::channels_bg_palindex_p(channels)); } libnotcurses-sys-2.1.8/src/dimension.rs010064400017500001750000000003111377726434200163670ustar 00000000000000//! `NcDim`, `NcOffset` /// Represents a dimension in rows or columns. Can't be negative. pub type NcDim = u32; /// Represents an offset in rows or columns. Can be negative. pub type NcOffset = i32; libnotcurses-sys-2.1.8/src/direct/methods.rs010064400017500001750000000542071377726434200173340ustar 00000000000000//! `NcDirect` methods and associated functions. use core::ptr::{null, null_mut}; use crate::ffi::sigset_t; use crate::{ cstring, error, error_ref_mut, NcAlign, NcBlitter, NcChannelPair, NcColor, NcDim, NcDirect, NcDirectFlags, NcEgc, NcError, NcInput, NcPaletteIndex, NcPlane, NcResult, NcRgb, NcScale, NcStyleMask, NcTime, NCRESULT_ERR, }; /// # `NcDirect` constructors and destructors impl NcDirect { /// New NcDirect with the default options. /// /// Initializes a direct-mode notcurses context on the tty. /// /// Direct mode supports a limited subset of notcurses routines, /// and neither supports nor requires /// [notcurses_render()][crate::notcurses_render]. This can be used to add /// color and styling to text in the standard output paradigm. /// /// *C style function: [ncdirect_init()][crate::ncdirect_init].* pub fn new<'a>() -> NcResult<&'a mut NcDirect> { Self::with_flags(0) } /// New NcDirect with optional flags. /// /// `flags` is a bitmask over: /// - [NCDIRECT_OPTION_INHIBIT_CBREAK][crate::NCDIRECT_OPTION_INHIBIT_CBREAK] /// - [NCDIRECT_OPTION_INHIBIT_SETLOCALE][crate::NCDIRECT_OPTION_INHIBIT_SETLOCALE] /// /// *C style function: [ncdirect_init()][crate::ncdirect_init].* pub fn with_flags<'a>(flags: NcDirectFlags) -> NcResult<&'a mut NcDirect> { let res = unsafe { crate::ncdirect_init(null(), null_mut(), flags) }; error_ref_mut![res, "Initializing NcDirect"] } /// Releases this NcDirect and any associated resources. /// /// *C style function: [ncdirect_stop()][crate::ncdirect_stop].* pub fn stop(&mut self) -> NcResult<()> { error![unsafe { crate::ncdirect_stop(self) }, "NcDirect.stop()"] } } /// ## NcDirect methods: clear, flush, render impl NcDirect { /// Clears the screen. /// /// *C style function: [ncdirect_clear()][crate::ncdirect_clear].* pub fn clear(&mut self) -> NcResult<()> { error![unsafe { crate::ncdirect_clear(self) }, "NcDirect.clear()"] } /// Forces a flush. /// /// *C style function: [ncdirect_flush()][crate::ncdirect_flush].* pub fn flush(&self) -> NcResult<()> { error![unsafe { crate::ncdirect_flush(self) }, "NcDirect.clear()"] } /// Takes the result of [render_frame()][NcDirect#method.render_frame] /// and writes it to the output. /// /// The `align`, `blitter`, and `scale` arguments must be the same as those /// passed to render_frame(). /// /// *C style function: [ncdirect_raster_frame()][crate::ncdirect_raster_frame].* pub fn raster_frame(&mut self, faken: &mut NcPlane, align: NcAlign) -> NcResult<()> { error![ unsafe { crate::ncdirect_raster_frame(self, faken, align) }, "NcDirect.raster_frame()" ] } /// Renders an image using the specified blitter and scaling, /// but do not write the result. /// /// The image may be arbitrarily many rows -- the output will scroll -- /// but will only occupy the column of the cursor, and those to the right. /// /// To actually write (and free) this, invoke ncdirect_raster_frame(). /// and writes it to the output. /// /// The `align`, `blitter`, and `scale` arguments must be the same as those /// passed to render_frame(). /// /// *C style function: [ncdirect_render_frame()][crate::ncdirect_render_frame].* pub fn render_frame<'a>( &mut self, filename: &str, blitter: NcBlitter, scale: NcScale, ) -> NcResult<&'a mut NcPlane> { let res = unsafe { crate::ncdirect_render_frame(self, cstring![filename], blitter, scale) }; error_ref_mut![ res, &format!( "NcDirect.render_frame({:?}, {:?}, {:?})", filename, blitter, scale ) ] } /// Displays an image using the specified blitter and scaling. /// /// The image may be arbitrarily many rows -- the output will scroll -- but /// will only occupy the column of the cursor, and those to the right. /// /// The render/raster process can be split by using /// [render_frame()][#method.render_frame] and /// [raster_frame()][#method.raster_frame]. /// /// *C style function: [ncdirect_render_image()][crate::ncdirect_render_image].* pub fn render_image( &mut self, filename: &str, align: NcAlign, blitter: NcBlitter, scale: NcScale, ) -> NcResult<()> { error![ unsafe { crate::ncdirect_render_image(self, cstring![filename], align, blitter, scale) }, &format!( "NcDirect.render_image({:?}, {:?}, {:?}, {:?})", filename, align, blitter, scale ) ] } } /// ## NcDirect methods: `NcPaletteIndex`, `NcRgb`, `NcStyleMask` & default color impl NcDirect { /// Sets the foreground [NcPaletteIndex]. /// /// *C style function: [ncdirect_set_fg_palindex()][crate::ncdirect_set_fg_palindex].* pub fn set_fg_palindex(&mut self, index: NcPaletteIndex) -> NcResult<()> { error![ unsafe { crate::ncdirect_set_fg_palindex(self, index as i32) }, &format!("NcDirect.set_fg_palindex({})", index) ] } /// Sets the background [NcPaletteIndex]. /// /// *C style function: [ncdirect_set_bg_palindex()][crate::ncdirect_set_bg_palindex].* pub fn set_bg_palindex(&mut self, index: NcPaletteIndex) -> NcResult<()> { error![ unsafe { crate::ncdirect_set_bg_palindex(self, index as i32) }, &format!("NcDirect.set_fg_palindex({})", index) ] } /// Returns the number of simultaneous colors claimed to be supported. /// /// Note that several terminal emulators advertise more colors than they /// actually support, downsampling internally. /// /// *C style function: [ncdirect_palette_size()][crate::ncdirect_palette_size].* pub fn palette_size(&self) -> NcResult { let res = unsafe { crate::ncdirect_palette_size(self) }; if res == 1 { return Err(NcError::with_msg( 1, "No color support ← NcDirect.palette_size()", )); } Ok(res) } /// Sets the foreground [NcRgb]. /// /// *C style function: [ncdirect_set_fg_rgb()][crate::ncdirect_set_fg_rgb].* pub fn set_fg_rgb(&mut self, rgb: NcRgb) -> NcResult<()> { error![ unsafe { crate::ncdirect_set_fg_rgb(self, rgb) }, &format!("NcDirect.set_fg_rgb({})", rgb) ] } /// Sets the background [NcRgb]. /// /// *C style function: [ncdirect_set_bg_rgb()][crate::ncdirect_set_bg_rgb].* pub fn set_bg_rgb(&mut self, rgb: NcRgb) -> NcResult<()> { error![ unsafe { crate::ncdirect_set_bg_rgb(self, rgb) }, &format!("NcDirect.set_bg_rgb({})", rgb) ] } /// Sets the foreground [NcColor] components. /// /// *C style function: [ncdirect_set_fg_rgb8()][crate::ncdirect_set_fg_rgb8].* pub fn set_fg_rgb8(&mut self, red: NcColor, green: NcColor, blue: NcColor) -> NcResult<()> { error![ crate::ncdirect_set_fg_rgb8(self, red, green, blue), &format!("NcDirect.set_fg_rgb8({}, {}, {})", red, green, blue) ] } /// Sets the background [NcColor] components. /// /// *C style function: [ncdirect_set_bg_rgb()][crate::ncdirect_set_bg_rgb].* pub fn set_bg_rgb8(&mut self, red: NcColor, green: NcColor, blue: NcColor) -> NcResult<()> { error![ crate::ncdirect_set_bg_rgb8(self, red, green, blue), &format!("NcDirect.set_bg_rgb8({}, {}, {})", red, green, blue) ] } /// Removes the specified styles. /// /// *C style function: [ncdirect_off_styles()][crate::ncdirect_off_styles].* pub fn styles_off(&mut self, stylebits: NcStyleMask) -> NcResult<()> { error![ unsafe { crate::ncdirect_off_styles(self, stylebits.into()) }, &format!("NcDirect.styles_off({:0X})", stylebits) ] } /// Adds the specified styles. /// /// *C style function: [ncdirect_on_styles()][crate::ncdirect_on_styles].* pub fn styles_on(&mut self, stylebits: NcStyleMask) -> NcResult<()> { error![ unsafe { crate::ncdirect_on_styles(self, stylebits.into()) }, &format!("NcDirect.styles_on({:0X})", stylebits) ] } /// Sets just the specified styles. /// /// *C style function: [ncdirect_set_styles()][crate::ncdirect_set_styles].* pub fn styles_set(&mut self, stylebits: NcStyleMask) -> NcResult<()> { error![ unsafe { crate::ncdirect_set_styles(self, stylebits.into()) }, &format!("NcDirect.styles_set({:0X})", stylebits) ] } /// Indicates to use the "default color" for the foreground. /// /// *C style function: [ncdirect_set_fg_default()][crate::ncdirect_set_fg_default].* pub fn set_fg_default(&mut self) -> NcResult<()> { error![ unsafe { crate::ncdirect_set_fg_default(self) }, "NcDirect.set_fg_default()" ] } /// Indicates to use the "default color" for the background. /// /// *C style function: [ncdirect_set_bg_default()][crate::ncdirect_set_bg_default].* pub fn set_bg_default(&mut self) -> NcResult<()> { error![ unsafe { crate::ncdirect_set_bg_default(self) }, "NcDirect.set_bg_default()" ] } } /// ## NcDirect methods: capabilities, cursor, dimensions impl NcDirect { /// Can we load images? /// /// Requires being built against FFmpeg/OIIO. /// /// *C style function: [ncdirect_canopen_images()][crate::ncdirect_canopen_images].* pub fn canopen_images(&self) -> bool { unsafe { crate::ncdirect_canopen_images(self) } } /// Is our encoding UTF-8? /// /// Requires LANG being set to a UTF8 locale. /// /// *C style function: [ncdirect_canutf8()][crate::ncdirect_canutf8].* pub fn canutf8(&self) -> bool { unsafe { crate::ncdirect_canutf8(self) } } /// Disables the terminal's cursor, if supported. /// /// *C style function: [ncdirect_cursor_disable()][crate::ncdirect_cursor_disable].* pub fn cursor_disable(&mut self) -> NcResult<()> { error![ unsafe { crate::ncdirect_cursor_disable(self) }, "NcDirect.cursor_disable()" ] } /// Enables the terminal's cursor, if supported. /// /// *C style function: [ncdirect_cursor_enable()][crate::ncdirect_cursor_enable].* pub fn cursor_enable(&mut self) -> NcResult<()> { error![ unsafe { crate::ncdirect_cursor_enable(self) }, "NcDirect.cursor_enable()" ] } /// Moves the cursor down, `num` rows. /// /// *C style function: [ncdirect_cursor_down()][crate::ncdirect_cursor_down].* pub fn cursor_down(&mut self, num: NcDim) -> NcResult<()> { error![ unsafe { crate::ncdirect_cursor_down(self, num as i32) }, &format!("NcDirect.cursor_down({})", num) ] } /// Moves the cursor left, `num` columns. /// /// *C style function: [ncdirect_cursor_left()][crate::ncdirect_cursor_left].* pub fn cursor_left(&mut self, num: NcDim) -> NcResult<()> { error![ unsafe { crate::ncdirect_cursor_left(self, num as i32) }, &format!("NcDirect.cursor_left({})", num) ] } /// Moves the cursor right, `num` columns. /// /// *C style function: [ncdirect_cursor_right()][crate::ncdirect_cursor_right].* pub fn cursor_right(&mut self, num: NcDim) -> NcResult<()> { error![ unsafe { crate::ncdirect_cursor_right(self, num as i32) }, &format!("NcDirect.cursor_right({})", num) ] } /// Moves the cursor up, `num` rows. /// /// *C style function: [ncdirect_cursor_up()][crate::ncdirect_cursor_up].* pub fn cursor_up(&mut self, num: NcDim) -> NcResult<()> { error![ unsafe { crate::ncdirect_cursor_up(self, num as i32) }, &format!("NcDirect.cursor_up({})", num) ] } /// Moves the cursor in direct mode to the specified row, column. /// /// *C style function: [ncdirect_cursor_move_yx()][crate::ncdirect_cursor_move_yx].* pub fn cursor_move_yx(&mut self, y: NcDim, x: NcDim) -> NcResult<()> { error![unsafe { crate::ncdirect_cursor_move_yx(self, y as i32, x as i32) }] } /// Moves the cursor in direct mode to the specified row. /// /// *(No equivalent C style function)* pub fn cursor_move_y(&mut self, y: NcDim) -> NcResult<()> { error![unsafe { crate::ncdirect_cursor_move_yx(self, y as i32, -1) }] } /// Moves the cursor in direct mode to the specified column. /// /// *(No equivalent C style function)* pub fn cursor_move_x(&mut self, x: NcDim) -> NcResult<()> { error![unsafe { crate::ncdirect_cursor_move_yx(self, -1, x as i32) }] } /// Gets the cursor position, when supported. /// /// This requires writing to the terminal, and then reading from it. /// If the terminal doesn't reply, or doesn't reply in a way we understand, /// the results might be detrimental. /// /// *C style function: [ncdirect_cursor_yx()][crate::ncdirect_cursor_yx].* pub fn cursor_yx(&mut self) -> NcResult<(NcDim, NcDim)> { let (mut y, mut x) = (0, 0); error![ unsafe { crate::ncdirect_cursor_yx(self, &mut y, &mut x) }, "", (y as NcDim, x as NcDim) ] } /// Pushes the cursor location to the terminal's stack. /// /// The depth of this stack, and indeed its existence, is terminal-dependent. /// /// *C style function: [ncdirect_cursor_push()][crate::ncdirect_cursor_push].* pub fn cursor_push(&mut self) -> NcResult<()> { error![unsafe { crate::ncdirect_cursor_push(self) }] } /// Pops the cursor location from the terminal's stack. /// /// The depth of this stack, and indeed its existence, is terminal-dependent. /// /// *C style function: [ncdirect_cursor_pop()][crate::ncdirect_cursor_pop].* pub fn cursor_pop(&mut self) -> NcResult<()> { error![unsafe { crate::ncdirect_cursor_pop(self) }] } /// Gets the current number of rows. /// /// *C style function: [ncdirect_dim_y()][crate::ncdirect_dim_y].* pub fn dim_y(&self) -> NcDim { unsafe { crate::ncdirect_dim_y(self) as NcDim } } /// Gets the current number of columns. /// /// *C style function: [ncdirect_dim_x()][crate::ncdirect_dim_x].* pub fn dim_x(&self) -> NcDim { unsafe { crate::ncdirect_dim_x(self) as NcDim } } /// Gets the current number of rows and columns. /// /// *C style function: [ncdirect_dim_y()][crate::ncdirect_dim_y].* pub fn dim_yx(&self) -> (NcDim, NcDim) { let y = unsafe { crate::ncdirect_dim_y(self) as NcDim }; let x = unsafe { crate::ncdirect_dim_x(self) as NcDim }; (y, x) } } /// ## NcDirect methods: I/O impl NcDirect { /// Returns a [char] representing a single unicode point. /// /// If an event is processed, the return value is the `id` field from that /// event. /// /// Provide a None `time` to block at length, a `time` of 0 for non-blocking /// operation, and otherwise a timespec to bound blocking. /// /// Signals in sigmask (less several we handle internally) will be atomically /// masked and unmasked per [ppoll(2)](https://linux.die.net/man/2/ppoll). /// /// `*sigmask` should generally contain all signals. /// /// *C style function: [ncdirect_getc()][crate::ncdirect_getc].* // // CHECK returns 0 on a timeout. pub fn getc( &mut self, time: Option, sigmask: Option<&mut sigset_t>, input: Option<&mut NcInput>, ) -> NcResult { let ntime; if let Some(time) = time { ntime = &time as *const _; } else { ntime = null(); } let nsigmask; if let Some(sigmask) = sigmask { nsigmask = sigmask as *mut _; } else { nsigmask = null_mut() as *mut _; } let ninput; if let Some(input) = input { ninput = input as *mut _; } else { ninput = null_mut(); } let c = unsafe { core::char::from_u32_unchecked(crate::ncdirect_getc(self, ntime, nsigmask, ninput)) }; if c as u32 as i32 == NCRESULT_ERR { return Err(NcError::new(NCRESULT_ERR)); } Ok(c) } /// /// *C style function: [ncdirect_getc_nblock()][crate::ncdirect_getc_nblock].* pub fn getc_nblock(&mut self, input: &mut NcInput) -> char { crate::ncdirect_getc_nblock(self, input) } /// /// *C style function: [ncdirect_getc_blocking()][crate::ncdirect_getc_blocking].* pub fn getc_blocking(&mut self, input: &mut NcInput) -> char { crate::ncdirect_getc_blocking(self, input) } /// Get a file descriptor suitable for input event poll()ing. /// /// When this descriptor becomes available, you can call /// [getc_nblock()][NcDirect#method.getc_nblock], and input ought be ready. /// /// This file descriptor is not necessarily the file descriptor associated /// with stdin (but it might be!). /// /// *C style function: [ncdirect_inputready_fd()][crate::ncdirect_inputready_fd].* pub fn inputready_fd(&mut self) -> NcResult<()> { error![unsafe { crate::ncdirect_inputready_fd(self) }] } /// Outputs the `string` according to the `channels`, and /// returns the total number of characters written on success. /// /// Note that it does not explicitly flush output buffers, so it will not /// necessarily be immediately visible. /// /// It will fail if the NcDirect context and the foreground channel /// are both marked as using the default color. /// /// *C style function: [ncdirect_putstr()][crate::ncdirect_putstr].* pub fn putstr(&mut self, channels: NcChannelPair, string: &str) -> NcResult<()> { error![ unsafe { crate::ncdirect_putstr(self, channels, cstring![string]) }, &format!("NcDirect.putstr({:0X}, {:?})", channels, string) ] } /// Draws a box with its upper-left corner at the current cursor position, /// having dimensions `ylen` * `xlen`. /// /// See NcPlane.[box()][crate::NcPlane#method.box] for more information. /// /// The minimum box size is 2x2, and it cannot be drawn off-screen. /// /// `wchars` is an array of 6 characters: UL, UR, LL, LR, HL, VL. /// /// *C style function: [ncdirect_box()][crate::ncdirect_box].* // TODO: CHECK, specially wchars. pub fn r#box( &mut self, ul: NcChannelPair, ur: NcChannelPair, ll: NcChannelPair, lr: NcChannelPair, wchars: &[char; 6], y_len: NcDim, x_len: NcDim, ctlword: u32, ) -> NcResult<()> { error![ unsafe { let wchars = core::mem::transmute(wchars); crate::ncdirect_box( self, ul, ur, ll, lr, wchars, y_len as i32, x_len as i32, ctlword, ) }, &format!( "NcDirect.box({:0X}, {:0X}, {:0X}, {:0X}, {:?}, {}, {}, {})", ul, ur, ll, lr, wchars, y_len, x_len, ctlword ) ] } /// NcDirect.[box()][NcDirect#method.box] with the double box-drawing characters. /// /// *C style function: [ncdirect_double_box()][crate::ncdirect_double_box].* pub fn double_box( &mut self, ul: NcChannelPair, ur: NcChannelPair, ll: NcChannelPair, lr: NcChannelPair, y_len: NcDim, x_len: NcDim, ctlword: u32, ) -> NcResult<()> { error![unsafe { crate::ncdirect_double_box(self, ul, ur, ll, lr, y_len as i32, x_len as i32, ctlword) }] } /// NcDirect.[box()][NcDirect#method.box] with the rounded box-drawing characters. /// /// *C style function: [ncdirect_rounded_box()][crate::ncdirect_rounded_box].* pub fn rounded_box( &mut self, ul: NcChannelPair, ur: NcChannelPair, ll: NcChannelPair, lr: NcChannelPair, y_len: NcDim, x_len: NcDim, ctlword: u32, ) -> NcResult<()> { error![unsafe { crate::ncdirect_rounded_box(self, ul, ur, ll, lr, y_len as i32, x_len as i32, ctlword) }] } /// Draws horizontal lines using the specified [NcChannelPair]s, interpolating /// between them as we go. /// /// All lines start at the current cursor position. /// /// The [NcEgc] at `egc` may not use more than one column. /// /// For a horizontal line, `len` cannot exceed the screen width minus the /// cursor's offset. /// /// *C style function: [ncdirect_hline_interp()][crate::ncdirect_hline_interp].* #[inline] pub fn hline_interp( &mut self, egc: &NcEgc, len: NcDim, h1: NcChannelPair, h2: NcChannelPair, ) -> NcResult<()> { error![unsafe { crate::ncdirect_hline_interp(self, &(*egc as i8), len as i32, h1, h2) }] } /// Draws horizontal lines using the specified [NcChannelPair]s, interpolating /// between them as we go. /// /// All lines start at the current cursor position. /// /// The [NcEgc] at `egc` may not use more than one column. /// /// For a vertical line, `len` may be as long as you'd like; the screen /// will scroll as necessary. /// /// *C style function: [ncdirect_vline_interp()][crate::ncdirect_vline_interp].* #[inline] pub fn vline_interp( &mut self, egc: &NcEgc, len: NcDim, h1: NcChannelPair, h2: NcChannelPair, ) -> NcResult<()> { error![unsafe { crate::ncdirect_vline_interp(self, &(*egc as i8), len as i32, h1, h2) }] } } libnotcurses-sys-2.1.8/src/direct/mod.rs010064400017500001750000000065071377726434200164500ustar 00000000000000//! `NcDirect` // --- --------------------------------------------------------- // col 0: // -------------- // 4 X: wont do // ~: WIP // // col 1: 43 // -------------- // 39 f: ffi function imported by bindgen // F: ffi function wrapped safely // 4 r: static function reimplemented in Rust // // col 2: 43 // -------------- // 41 m: impl as an `NcDirect` method // 2 M: impl for the `DirectMode` wrapper struct too // // col 3: // -------------- // t: tests done for the ffi or reimplemented funtion // T: tests done also for the m method // Ŧ: tests done also for the M method wrapper struct // --- --------------------------------------------------------- // // fm ncdirect_bg_default // fm ncdirect_bg_palindex // fm ncdirect_bg_rgb // fm ncdirect_box // fm ncdirect_canopen_images // fm ncdirect_canutf8 // fm ncdirect_clear // fm ncdirect_cursor_disable // fm ncdirect_cursor_down // fm ncdirect_cursor_enable // fm ncdirect_cursor_left // fm ncdirect_cursor_move_yx // fm ncdirect_cursor_pop // fm ncdirect_cursor_push // fm ncdirect_cursor_right // fm ncdirect_cursor_up // fm ncdirect_cursor_yx // fm ncdirect_dim_x // fm ncdirect_dim_y // fm ncdirect_double_box // fm ncdirect_fg_default // fm ncdirect_fg_palindex // fm ncdirect_fg_rgb // fm ncdirect_flush // fm ncdirect_getc // fm ncdirect_hline_interp // fM ncdirect_init // fm ncdirect_inputready_fd // fm ncplane_on_styles // fm ncplane_off_styles // fm ncdirect_palette_size //X ncdirect_printf_aligned // fm ncdirect_putstr // fm ncdirect_raster_frame // fm ncdirect_render_frame // fm ncdirect_render_image // fm ncdirect_rounded_box // fm ncplane_set_styles // fM ncdirect_stop //X ncdirect_styles_off // deprecated //X ncdirect_styles_on // deprecated //X ncdirect_styles_set // deprecated // fm ncdirect_vline_interp // // rm ncdirect_bg_rgb8 // rm ncdirect_fg_rgb8 // rm ncdirect_getc_nblock // rm ncdirect_getc_nblocking #[cfg(test)] mod test; mod methods; mod reimplemented; mod wrapper; pub use reimplemented::*; pub use wrapper::*; /// Minimal notcurses instance for styling text. /// /// This is the internal type safely wrapped by [DirectMode]. pub type NcDirect = crate::bindings::ffi::ncdirect; /// Flags (options) for [`NcDirect`] pub type NcDirectFlags = u64; /// Flag that avoids placing the terminal into cbreak mode /// (disabling echo and line buffering) /// pub const NCDIRECT_OPTION_INHIBIT_CBREAK: NcDirectFlags = crate::bindings::ffi::NCDIRECT_OPTION_INHIBIT_CBREAK as NcDirectFlags; /// Flag that avoids calling setlocale(LC_ALL, NULL) /// /// If the result is either "C" or "POSIX", it will print a /// diagnostic to stderr, and then call setlocale(LC_ALL, ""). /// /// This will attempt to set the locale based off the LANG /// environment variable. Your program should call setlocale(3) /// itself, usually as one of the first lines. /// pub const NCDIRECT_OPTION_INHIBIT_SETLOCALE: NcDirectFlags = crate::bindings::ffi::NCDIRECT_OPTION_INHIBIT_SETLOCALE as NcDirectFlags; /// Flag that inhibits registration of the SIGINT, SIGSEGV, SIGABRT & SIGQUIT /// signal handlers. pub const NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS: NcDirectFlags = crate::bindings::ffi::NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS as NcDirectFlags; libnotcurses-sys-2.1.8/src/direct/reimplemented.rs010064400017500001750000000036371377416525400205230ustar 00000000000000//! `ncdirect_*` reimplemented functions. use core::ptr::null; use crate::{NcColor, NcDirect, NcInput, NcIntResult, NcRgb, NcSignalSet, NcTime}; /// 'input' may be NULL if the caller is uninterested in event details. /// Blocks until an event is processed or a signal is received. /// /// *Method: NcDirect.[getc_blocking()][NcDirect#method.getc_blocking].* // TODO: use from_u32 & return Option. #[inline] pub fn ncdirect_getc_blocking(nc: &mut NcDirect, input: &mut NcInput) -> char { unsafe { let mut sigmask = NcSignalSet::new(); sigmask.emptyset(); core::char::from_u32_unchecked(crate::ncdirect_getc(nc, null(), &mut sigmask, input)) } } /// /// If no event is ready, returns 0. /// /// *Method: NcDirect.[getc_nblock()][NcDirect#method.getc_nblock].* // // `input` may be NULL if the caller is uninterested in event details. #[inline] pub fn ncdirect_getc_nblock(nc: &mut NcDirect, input: &mut NcInput) -> char { unsafe { let mut sigmask = NcSignalSet::new(); sigmask.fillset(); let ts = NcTime::new(); core::char::from_u32_unchecked(crate::ncdirect_getc(nc, &ts, &mut sigmask, input)) } } /// Sets the foreground [NcColor] components. /// /// *Method: NcDirect.[set_fg_rgb8()][NcDirect#method.set_fg_rgb8].* #[inline] pub fn ncdirect_set_fg_rgb8( ncd: &mut NcDirect, red: NcColor, green: NcColor, blue: NcColor, ) -> NcIntResult { let rgb = (red as NcRgb) << 16 | (green as NcRgb) << 8 | blue as NcRgb; unsafe { crate::ncdirect_set_fg_rgb(ncd, rgb) } } /// Sets the background [NcColor] components. /// /// *Method: NcDirect.[set_bg_rgb8()][NcDirect#method.set_bg_rgb8].* #[inline] pub fn ncdirect_set_bg_rgb8( ncd: &mut NcDirect, red: NcColor, green: NcColor, blue: NcColor, ) -> NcIntResult { let rgb = (red as NcRgb) << 16 | (green as NcRgb) << 8 | blue as NcRgb; unsafe { crate::ncdirect_set_bg_rgb(ncd, rgb) } } libnotcurses-sys-2.1.8/src/direct/test/mod.rs010064400017500001750000000000011376441154400174000ustar 00000000000000 libnotcurses-sys-2.1.8/src/direct/wrapper.rs010064400017500001750000000027301377726434200173430ustar 00000000000000//! `DirectMode` wrapper struct and traits implementations. use std::ops::{Deref, DerefMut}; use crate::{raw_wrap, NcDirect, NcResult}; /// Safe wrapper around [NcDirect], minimal notcurses instance for styling text. pub struct DirectMode<'a> { pub(crate) raw: &'a mut NcDirect, } impl<'a> AsRef for DirectMode<'a> { fn as_ref(&self) -> &NcDirect { self.raw } } impl<'a> AsMut for DirectMode<'a> { fn as_mut(&mut self) -> &mut NcDirect { self.raw } } impl<'a> Deref for DirectMode<'a> { type Target = NcDirect; fn deref(&self) -> &Self::Target { self.as_ref() } } impl<'a> DerefMut for DirectMode<'a> { fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut() } } impl<'a> Drop for DirectMode<'a> { /// Destroys the DirectMode context. fn drop(&mut self) { let _ = self.raw.stop(); } } /// # Constructors and methods overriden from NcDirect impl<'a> DirectMode<'a> { // wrap constructors /// New DirectMode (without banners). pub fn new() -> NcResult { raw_wrap![NcDirect::new()] } /// New DirectMode, expects `NCOPTION_*` flags. pub fn with_flags(flags: u64) -> NcResult { raw_wrap![NcDirect::with_flags(flags)] } // disable destructor /// Since DirectMode already implements [Drop](#impl-Drop), /// this function is made no-op. pub fn stop(&mut self) -> NcResult<()> { Ok(()) } } libnotcurses-sys-2.1.8/src/error.rs010064400017500001750000000027441377416467000155470ustar 00000000000000//! Error handling with `Error`, `NcResult` & `NcIntResult` for error handling use std::{self, error, fmt}; /// The [`i32`] value used to return errors by the underlying C API. /// /// A value < 0 means error, (usually -1). /// /// # Defined constants: /// /// - [`NCRESULT_OK`] /// - [`NCRESULT_ERR`] /// - [`NCRESULT_MAX`] pub type NcIntResult = i32; /// OK value, for the functions that return [`NcIntResult`]. pub const NCRESULT_OK: i32 = 0; /// ERROR value, for the functions that return an [`NcIntResult`]. pub const NCRESULT_ERR: i32 = -1; /// MAX value, for the functions that return [`NcIntResult`]. pub const NCRESULT_MAX: i32 = i32::MAX; /// The error type for the Rust methods API. #[derive(Debug, Clone, Default)] pub struct NcError { /// [NcIntResult]. pub int: i32, pub msg: String, } impl fmt::Display for NcError { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "NcError {}: {}", self.int, self.msg) } } impl error::Error for NcError { fn description(&self) -> &str { &self.msg } } impl NcError { /// New NcError. pub fn new(int: NcIntResult) -> Self { Self { int, ..Default::default() } } /// New NcError with message. pub fn with_msg(int: NcIntResult, msg: &str) -> Self { Self { int, msg: msg.to_string(), } } } /// The result type for the Rust methods API. pub type NcResult = Result; libnotcurses-sys-2.1.8/src/fade.rs010064400017500001750000000027321377726434200153120ustar 00000000000000//! `NcFadeCb` & `NcFadeCtx` // functions already exported by bindgen : 3 // ------------------------------------------- // (#) test: 0 // (W) wrap: 3 / 0 // ------------------------------------------- //W ncfadectx_free //W ncfadectx_iterations //W ncfadectx_setup use std::ffi::c_void; use crate::{NcIntResult, NcPlane, NcTime, Notcurses}; /// Called for each fade iteration on the NcPlane. /// /// If anything but 0 is returned, the fading operation ceases immediately, /// and that value is propagated out. /// /// The recommended absolute display time target is passed in 'tspec'. pub type NcFadeCb = Option< unsafe extern "C" fn(*mut Notcurses, *mut NcPlane, *const NcTime, *mut c_void) -> NcIntResult, >; /// Context for a palette fade operation pub type NcFadeCtx = crate::bindings::ffi::ncfadectx; impl NcFadeCtx { /// NcFadeCtx constructor. /// /// Rather than the simple ncplane_fade{in/out}(), /// ncfadectx_setup() can be paired with a loop over /// ncplane_fade{in/out}_iteration() + ncfadectx_free(). pub fn setup<'a>(plane: &'a mut NcPlane) -> &'a mut NcFadeCtx { unsafe { &mut *crate::ncfadectx_setup(plane) } } /// Releases the resources associated. pub fn free(&mut self) { unsafe { crate::ncfadectx_free(self); } } /// Returns the number of iterations through which will fade. pub fn iterations(&self) -> u32 { unsafe { crate::ncfadectx_iterations(self) as u32 } } } libnotcurses-sys-2.1.8/src/file.rs010064400017500001750000000253251376441154400153270ustar 00000000000000//! Wrapper for `libc::FILE`, both as used by notcurses and the libc crate //! //! The interface is largely based on the implementation of the //! [cfile-rs crate](https://github.com/jkarns275/cfile) by Joshua Karns use core::ptr::{null_mut, NonNull}; use std::io::{Error, ErrorKind, Read, Seek, SeekFrom}; use libc::{c_long, c_void, fclose, feof, fread, fseek, ftell, SEEK_CUR, SEEK_END, SEEK_SET}; /// See [NcFile]. Notcurses functions expects this type of `*FILE` (a struct) pub type FILE_NC = crate::ffi::_IO_FILE; /// See [NcFile]. The [`libc`](https://docs.rs/libc/) crate expects this type /// of `*FILE` (an opaque enum) pub type FILE_LIBC = libc::FILE; // TODO: the following static strings aren't made public /// Intended to be passed into the CFile::open method. /// It will open the file in a way that will allow reading and writing, /// including overwriting old data. /// It will not create the file if it does not exist. pub static RANDOM_ACCESS_MODE: &'static str = "rb+"; /// Intended to be passed into the CFile::open method. /// It will open the file in a way that will allow reading and writing, /// including overwriting old data pub static UPDATE: &'static str = "rb+"; /// Intended to be passed into the CFile::open method. /// It will only allow reading. pub static READ_ONLY: &'static str = "r"; /// Intended to be passed into the CFile::open method. /// It will only allow writing. pub static WRITE_ONLY: &'static str = "w"; /// Intended to be passed into the CFile::open method. /// It will only allow data to be appended to the end of the file. pub static APPEND_ONLY: &'static str = "a"; /// Intended to be passed into the CFile::open method. /// It will allow data to be appended to the end of the file, and data to be /// read from the file. It will create the file if it doesn't exist. pub static APPEND_READ: &'static str = "a+"; /// Intended to be passed into the CFile::open method. /// It will open the file in a way that will allow reading and writing, /// including overwriting old data. It will create the file if it doesn't exist pub static TRUNCATE_RANDOM_ACCESS_MODE: &'static str = "wb+"; /// A utility function to pull the current value of errno and put it into an /// Error::Errno fn get_error() -> Result { Err(Error::last_os_error()) } /// A wrapper struct around /// [`libc::FILE`](https://docs.rs/libc/0.2.80/libc/enum.FILE.html) /// /// The notcurses `FILE` type [`FILE_NC`] a struct imported through bindgen, /// while the equivalent [`libc`][https://docs.rs/libc] crate FILE /// ([`FILE_LIBC`]) is an opaque enum. /// /// Several methods are provided to cast back and forth between both types, /// in order to allow both rust libc operations and notcurses file operations /// over the same underlying `*FILE`. #[derive(Debug)] pub struct NcFile { file_ptr: NonNull, } impl NcFile { // constructors -- /// `NcFile` constructor from a file produced by notcurses pub fn from_nc(file: *mut FILE_NC) -> Self { NcFile { file_ptr: unsafe { NonNull::new_unchecked(NcFile::nc2libc(file)) }, } } /// `NcFile` constructor from a file produced by the libc crate pub fn from_libc(file: *mut FILE_LIBC) -> Self { NcFile { file_ptr: unsafe { NonNull::new_unchecked(file) }, } } // methods -- /// Returns the file pointer in the format expected by the [`libc`] crate #[inline] pub fn as_libc_ptr(&self) -> *mut FILE_LIBC { self.file_ptr.as_ptr() } /// Returns the file pointer in the format expected by notcurses #[inline] pub fn as_nc_ptr(&self) -> *mut FILE_NC { Self::libc2nc(self.file_ptr.as_ptr()) } /// Returns the current position in the file. /// /// On error `Error::Errno(errno)` is returned. pub fn current_pos(&self) -> Result { unsafe { let pos = ftell(self.as_libc_ptr()); if pos != -1 { Ok(pos as u64) } else { get_error() } } } /// Reads the file from start to end. Convenience method /// #[inline] pub fn read_all(&mut self, buf: &mut Vec) -> Result { let _ = self.seek(SeekFrom::Start(0)); self.read_to_end(buf) } // private methods -- /// Converts a file pointer from the struct notcurses uses to the /// opaque enum type libc expects #[inline] fn nc2libc(file: *mut FILE_NC) -> *mut FILE_LIBC { file as *mut _ as *mut FILE_LIBC } /// Converts a file pointer from the libc opaque enum format to the struct /// expected by notcurses #[inline] fn libc2nc(file: *mut FILE_LIBC) -> *mut FILE_NC { file as *mut _ as *mut FILE_NC } /// A utility function to expand a vector without increasing its capacity /// more than it needs to be expanded. fn expand_buffer(buff: &mut Vec, by: usize) { if buff.capacity() < buff.len() + by { buff.reserve(by); } for _ in 0..by { buff.push(0u8); } } } impl Read for NcFile { /// Reads exactly the number of bytes required to fill buf. /// /// If the end of the file is reached before buf is filled, /// `Err(EndOfFile(bytes_read))` will be returned. The data that was read /// before that will still have been placed into buf. /// /// Upon some other error, `Err(Errno(errno))` will be returned. fn read(&mut self, buf: &mut [u8]) -> Result { unsafe { let result = fread( buf.as_ptr() as *mut c_void, 1, buf.len(), self.as_libc_ptr(), ); if result != buf.len() { match get_error::() { Err(err) => { if err.kind() == ErrorKind::UnexpectedEof { Ok(result) } else { Err(err) } } Ok(_) => panic!("This is impossible"), } } else { Ok(result) } } } /// Reads the entire file starting from the current_position /// expanding buf as needed. /// /// On a successful read, this function will return `Ok(bytes_read)`. /// /// If an error occurs during reading, some varient of error will be returned. fn read_to_end(&mut self, buf: &mut Vec) -> Result { let pos = self.current_pos(); let _ = self.seek(SeekFrom::End(0)); let end = self.current_pos(); match pos { Ok(cur_pos) => match end { Ok(end_pos) => { if end_pos == cur_pos { return Ok(0); } let to_read = (end_pos - cur_pos) as usize; if buf.len() < to_read { let to_reserve = to_read - buf.len(); Self::expand_buffer(buf, to_reserve); } let _ = self.seek(SeekFrom::Start(cur_pos as u64)); match self.read_exact(buf) { Ok(()) => Ok(to_read), Err(e) => Err(e), } } Err(e) => Err(e), }, Err(e) => Err(e), } } /// Reads the entire file from the beginning and stores it in a string /// /// On a successful read, this function will return `Ok(bytes_read)`. /// /// If an error occurs during reading, some varient of error will be returned. fn read_to_string(&mut self, strbuf: &mut String) -> Result { let mut bytes_read = 0_usize; let mut buffer = vec![0u8]; let result = self.read_all(&mut buffer); if let Ok(bytes) = result { bytes_read = bytes; } if let Err(e) = result { return Err(e); } let result = std::str::from_utf8(&buffer); if let Ok(strslice) = result { *strbuf = strslice.to_string(); Ok(bytes_read) } else { get_error() } } /// Reads exactly the number of bytes required to fill buf. /// /// If the end of the file is reached before buf is filled, /// `Err(EndOfFile(bytes_read))` will be returned. The data that was read /// before that will still have been placed into buf. /// /// Upon some other error, `Err(Errno(errno))` will be returned. fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error> { unsafe { let result = fread( buf.as_ptr() as *mut c_void, 1, buf.len(), self.as_libc_ptr(), ); if result == buf.len() { Ok(()) } else { // Check if we hit the end of the file if feof(self.as_libc_ptr()) != 0 { get_error() } else { get_error() } } } } } impl Seek for NcFile { /// Changes the current position in the file using the [`SeekFrom`] enum. /// /// To set relative to the beginning of the file (i.e. index is 0 + offset): /// ```ignore /// SeekFrom::Start(offset) /// ``` /// To set relative to the end of the file (i.e. index is file_lenth - 1 - offset): /// ```ignore /// SeekFrom::End(offset) /// ``` /// To set relative to the current position: /// ```ignore /// SeekFrom::End(offset) /// ``` /// /// On error `Error::Errno(errno)` is returned. fn seek(&mut self, pos: SeekFrom) -> Result { unsafe { let result = match pos { SeekFrom::Start(from) => fseek(self.as_libc_ptr(), from as c_long, SEEK_SET), SeekFrom::End(from) => fseek(self.as_libc_ptr(), from as c_long, SEEK_END), SeekFrom::Current(delta) => fseek(self.as_libc_ptr(), delta as c_long, SEEK_CUR), }; if result == 0 { self.current_pos() } else { get_error() } } } } impl Drop for NcFile { /// Ensures the file stream is closed before abandoning the data. fn drop(&mut self) { let _ = unsafe { if !(self.as_libc_ptr()).is_null() { let res = fclose(self.as_libc_ptr()); if res == 0 { self.file_ptr = NonNull::new_unchecked(null_mut::()); Ok(()) } else { get_error() } } else { Ok(()) } }; } } libnotcurses-sys-2.1.8/src/input/key.rs010064400017500001750000000013071377056154100163310ustar 00000000000000// functions manually reimplemented: 2 // ------------------------------------------ // (+) done: 2 / 0 // (#) test: 0 / 2 // ------------------------------------------ // + nckey_mouse_p // + nckey_supppuab_p use crate::{NCKEY_BUTTON1, NCKEY_RELEASE}; /// Is this [char] a Supplementary Private Use Area-B codepoint? /// /// Links: /// - https://en.wikipedia.org/wiki/Private_Use_Areas /// - https://codepoints.net/supplementary_private_use_area-b #[inline] pub fn nckey_supppuab_p(w: char) -> bool { w as u32 >= 0x100000_u32 && w as u32 <= 0x10fffd_u32 } /// Is the event a synthesized mouse event? #[inline] pub const fn nckey_mouse_p(r: char) -> bool { r >= NCKEY_BUTTON1 && r <= NCKEY_RELEASE } libnotcurses-sys-2.1.8/src/input/keycodes.rs010064400017500001750000000174531377056154100173600ustar 00000000000000//! Special composed key definitions. These values are added to 0x100000. use std::mem::transmute; // NOTE: Waiting for: https://github.com/rust-lang/rust/issues/53605 // const fn suppuabize(w: u32) -> char { const fn suppuabize(w: u32) -> u32 { // unsafe { transmute(w + 0x100000) } w + 0x100000 } pub const NCKEY_INVALID: char = unsafe { transmute(suppuabize(0)) }; ///generated interally in response to SIGWINCH pub const NCKEY_RESIZE: char = unsafe { transmute(suppuabize(1)) }; pub const NCKEY_UP: char = unsafe { transmute(suppuabize(2)) }; pub const NCKEY_RIGHT: char = unsafe { transmute(suppuabize(3)) }; pub const NCKEY_DOWN: char = unsafe { transmute(suppuabize(4)) }; pub const NCKEY_LEFT: char = unsafe { transmute(suppuabize(5)) }; pub const NCKEY_INS: char = unsafe { transmute(suppuabize(6)) }; pub const NCKEY_DEL: char = unsafe { transmute(suppuabize(7)) }; /// backspace (sometimes) pub const NCKEY_BACKSPACE: char = unsafe { transmute(suppuabize(8)) }; pub const NCKEY_PGDOWN: char = unsafe { transmute(suppuabize(9)) }; pub const NCKEY_PGUP: char = unsafe { transmute(suppuabize(10)) }; pub const NCKEY_HOME: char = unsafe { transmute(suppuabize(11)) }; pub const NCKEY_END: char = unsafe { transmute(suppuabize(12)) }; pub const NCKEY_F00: char = unsafe { transmute(suppuabize(20)) }; pub const NCKEY_F01: char = unsafe { transmute(suppuabize(21)) }; pub const NCKEY_F02: char = unsafe { transmute(suppuabize(22)) }; pub const NCKEY_F03: char = unsafe { transmute(suppuabize(23)) }; pub const NCKEY_F04: char = unsafe { transmute(suppuabize(24)) }; pub const NCKEY_F05: char = unsafe { transmute(suppuabize(25)) }; pub const NCKEY_F06: char = unsafe { transmute(suppuabize(26)) }; pub const NCKEY_F07: char = unsafe { transmute(suppuabize(27)) }; pub const NCKEY_F08: char = unsafe { transmute(suppuabize(28)) }; pub const NCKEY_F09: char = unsafe { transmute(suppuabize(29)) }; pub const NCKEY_F10: char = unsafe { transmute(suppuabize(30)) }; pub const NCKEY_F11: char = unsafe { transmute(suppuabize(31)) }; pub const NCKEY_F12: char = unsafe { transmute(suppuabize(32)) }; pub const NCKEY_F13: char = unsafe { transmute(suppuabize(33)) }; pub const NCKEY_F14: char = unsafe { transmute(suppuabize(34)) }; pub const NCKEY_F15: char = unsafe { transmute(suppuabize(35)) }; pub const NCKEY_F16: char = unsafe { transmute(suppuabize(36)) }; pub const NCKEY_F17: char = unsafe { transmute(suppuabize(37)) }; pub const NCKEY_F18: char = unsafe { transmute(suppuabize(38)) }; pub const NCKEY_F19: char = unsafe { transmute(suppuabize(39)) }; pub const NCKEY_F20: char = unsafe { transmute(suppuabize(40)) }; pub const NCKEY_F21: char = unsafe { transmute(suppuabize(41)) }; pub const NCKEY_F22: char = unsafe { transmute(suppuabize(42)) }; pub const NCKEY_F23: char = unsafe { transmute(suppuabize(43)) }; pub const NCKEY_F24: char = unsafe { transmute(suppuabize(44)) }; pub const NCKEY_F25: char = unsafe { transmute(suppuabize(45)) }; pub const NCKEY_F26: char = unsafe { transmute(suppuabize(46)) }; pub const NCKEY_F27: char = unsafe { transmute(suppuabize(47)) }; pub const NCKEY_F28: char = unsafe { transmute(suppuabize(48)) }; pub const NCKEY_F29: char = unsafe { transmute(suppuabize(49)) }; pub const NCKEY_F30: char = unsafe { transmute(suppuabize(50)) }; pub const NCKEY_F31: char = unsafe { transmute(suppuabize(51)) }; pub const NCKEY_F32: char = unsafe { transmute(suppuabize(52)) }; pub const NCKEY_F33: char = unsafe { transmute(suppuabize(53)) }; pub const NCKEY_F34: char = unsafe { transmute(suppuabize(54)) }; pub const NCKEY_F35: char = unsafe { transmute(suppuabize(55)) }; pub const NCKEY_F36: char = unsafe { transmute(suppuabize(56)) }; pub const NCKEY_F37: char = unsafe { transmute(suppuabize(57)) }; pub const NCKEY_F38: char = unsafe { transmute(suppuabize(58)) }; pub const NCKEY_F39: char = unsafe { transmute(suppuabize(59)) }; pub const NCKEY_F40: char = unsafe { transmute(suppuabize(60)) }; pub const NCKEY_F41: char = unsafe { transmute(suppuabize(61)) }; pub const NCKEY_F42: char = unsafe { transmute(suppuabize(62)) }; pub const NCKEY_F43: char = unsafe { transmute(suppuabize(63)) }; pub const NCKEY_F44: char = unsafe { transmute(suppuabize(64)) }; pub const NCKEY_F45: char = unsafe { transmute(suppuabize(65)) }; pub const NCKEY_F46: char = unsafe { transmute(suppuabize(66)) }; pub const NCKEY_F47: char = unsafe { transmute(suppuabize(67)) }; pub const NCKEY_F48: char = unsafe { transmute(suppuabize(68)) }; pub const NCKEY_F49: char = unsafe { transmute(suppuabize(69)) }; pub const NCKEY_F50: char = unsafe { transmute(suppuabize(70)) }; pub const NCKEY_F51: char = unsafe { transmute(suppuabize(71)) }; pub const NCKEY_F52: char = unsafe { transmute(suppuabize(72)) }; pub const NCKEY_F53: char = unsafe { transmute(suppuabize(73)) }; pub const NCKEY_F54: char = unsafe { transmute(suppuabize(74)) }; pub const NCKEY_F55: char = unsafe { transmute(suppuabize(75)) }; pub const NCKEY_F56: char = unsafe { transmute(suppuabize(76)) }; pub const NCKEY_F57: char = unsafe { transmute(suppuabize(77)) }; pub const NCKEY_F58: char = unsafe { transmute(suppuabize(78)) }; pub const NCKEY_F59: char = unsafe { transmute(suppuabize(79)) }; pub const NCKEY_F60: char = unsafe { transmute(suppuabize(80)) }; // ... leave room for up to 100 function keys, egads pub const NCKEY_ENTER: char = unsafe { transmute(suppuabize(121)) }; /// "clear-screen or erase" pub const NCKEY_CLS: char = unsafe { transmute(suppuabize(122)) }; /// down + left on keypad pub const NCKEY_DLEFT: char = unsafe { transmute(suppuabize(123)) }; pub const NCKEY_DRIGHT: char = unsafe { transmute(suppuabize(124)) }; /// up + left on keypad pub const NCKEY_ULEFT: char = unsafe { transmute(suppuabize(125)) }; pub const NCKEY_URIGHT: char = unsafe { transmute(suppuabize(126)) }; /// the most truly neutral of keypresses pub const NCKEY_CENTER: char = unsafe { transmute(suppuabize(127)) }; pub const NCKEY_BEGIN: char = unsafe { transmute(suppuabize(128)) }; pub const NCKEY_CANCEL: char = unsafe { transmute(suppuabize(129)) }; pub const NCKEY_CLOSE: char = unsafe { transmute(suppuabize(130)) }; pub const NCKEY_COMMAND: char = unsafe { transmute(suppuabize(131)) }; pub const NCKEY_COPY: char = unsafe { transmute(suppuabize(132)) }; pub const NCKEY_EXIT: char = unsafe { transmute(suppuabize(133)) }; pub const NCKEY_PRINT: char = unsafe { transmute(suppuabize(134)) }; pub const NCKEY_REFRESH: char = unsafe { transmute(suppuabize(135)) }; // Mouse events. We try to encode some details into the char32_t (i.e. which // button was pressed);, but some is embedded in the ncinput event. The release // event is generic across buttons; callers must maintain state, if they care. pub const NCKEY_BUTTON1: char = unsafe { transmute(suppuabize(201)) }; pub const NCKEY_BUTTON2: char = unsafe { transmute(suppuabize(202)) }; pub const NCKEY_BUTTON3: char = unsafe { transmute(suppuabize(203)) }; /// scrollwheel up pub const NCKEY_BUTTON4: char = unsafe { transmute(suppuabize(204)) }; /// scrollwheel down pub const NCKEY_BUTTON5: char = unsafe { transmute(suppuabize(205)) }; pub const NCKEY_BUTTON6: char = unsafe { transmute(suppuabize(206)) }; pub const NCKEY_BUTTON7: char = unsafe { transmute(suppuabize(207)) }; pub const NCKEY_BUTTON8: char = unsafe { transmute(suppuabize(208)) }; pub const NCKEY_BUTTON9: char = unsafe { transmute(suppuabize(209)) }; pub const NCKEY_BUTTON10: char = unsafe { transmute(suppuabize(210)) }; pub const NCKEY_BUTTON11: char = unsafe { transmute(suppuabize(211)) }; pub const NCKEY_RELEASE: char = unsafe { transmute(suppuabize(212)) }; // Synonyms (so far as we're concerned) pub const NCKEY_SCROLL_UP: char = NCKEY_BUTTON4; pub const NCKEY_SCROLL_DOWN: char = NCKEY_BUTTON5; pub const NCKEY_RETURN: char = NCKEY_ENTER; // Aliases, from the 128 characters common to ASCII+UTF8 pub const NCKEY_ESC: char = unsafe { transmute(0x1b) }; pub const NCKEY_SPACE: char = unsafe { transmute(0x20) }; libnotcurses-sys-2.1.8/src/input/mod.rs010064400017500001750000000071141377726434200163300ustar 00000000000000//! `NcInput` & `NcKey` // functions manually reimplemented: 1 // ------------------------------------------ // (+) done: 3 / 0 // (#) test: 0 / 3 // ------------------------------------------ // + ncinput_equal_p // + nckey_mouse_p // + nckey_supppuab_p use crate::NcDim; mod keycodes; pub use keycodes::*; /// Reads and decodes input events /// /// Reads from stdin and decodes the input to stdout, /// including synthesized events and mouse events. /// /// /// Notcurses provides input from keyboards and mice. /// Single Unicode codepoints are received from the keyboard, directly encoded /// as `u32`. /// /// The input system must deal with numerous keyboard signals which do not map /// to Unicode code points. This includes the keypad arrows and function keys. /// These "synthesized" codepoints are enumerated in , and mapped into the /// Supplementary Private Use Area-B (U+100000..U+10FFFD). /// Mouse button events are similarly mapped into the SPUA-B. /// /// All events carry a ncinput structure with them. /// For mouse events, the x and y coordinates are reported within this struct. /// For all events, modifiers (e.g. "Alt") are carried as bools in this struct. pub type NcInput = crate::bindings::ffi::ncinput; /// Compares two ncinput structs for data equality by doing a field-by-field /// comparison for equality (excepting seqnum). /// /// Returns true if the two are data-equivalent. pub const fn ncinput_equal_p(n1: NcInput, n2: NcInput) -> bool { if n1.id != n2.id { return false; } if n1.y != n2.y || n1.x != n2.x { return false; } // do not check seqnum true } /// New NcInput. impl NcInput { /// New empty NcInput. pub const fn new_empty() -> NcInput { NcInput { id: 0, y: 0, x: 0, alt: false, shift: false, ctrl: false, seqnum: 0, } } /// New NcInput. pub const fn new(id: char) -> NcInput { Self::with_all_args(id, None, None, false, false, false, 0) } /// New NcInput with alt key. pub const fn with_alt(id: char) -> NcInput { Self::with_all_args(id, None, None, true, false, false, 0) } /// New NcInput with shift key. pub const fn with_shift(id: char) -> NcInput { Self::with_all_args(id, None, None, false, true, false, 0) } /// New NcInput with ctrl key. pub const fn with_ctrl(id: char) -> NcInput { Self::with_all_args(id, None, None, false, false, true, 0) } /// New NcInput, expecting all the arguments. pub const fn with_all_args( id: char, x: Option, y: Option, alt: bool, shift: bool, ctrl: bool, seqnum: u64, ) -> NcInput { let (ix, iy); if let Some(x) = x { ix = x as i32 } else { ix = -1 }; if let Some(y) = y { iy = y as i32 } else { iy = -1 }; NcInput { id: id as u32, y: ix, x: iy, alt, shift, ctrl, seqnum, } } } /// Is this [char] a Supplementary Private Use Area-B codepoint? /// /// Links: /// - https://en.wikipedia.org/wiki/Private_Use_Areas /// - https://codepoints.net/supplementary_private_use_area-b #[inline] pub const fn nckey_supppuab_p(w: char) -> bool { w as u32 >= 0x100000_u32 && w as u32 <= 0x10fffd_u32 } /// Is the event a synthesized mouse event? #[inline] pub const fn nckey_mouse_p(r: char) -> bool { r >= NCKEY_BUTTON1 && r <= NCKEY_RELEASE } libnotcurses-sys-2.1.8/src/lib.rs010064400017500001750000000116051377441112000151410ustar 00000000000000//! `libnotcurses-sys` is a Rust wrapper for the [notcurses //! C library](https://www.github.com/dankamongmen/notcurses/) //! //! *This is a work in progress.* //! //! This library is built with several layers of zero-overhead abstractions //! over the C functions and pointers accessed through FFI. //! //! # How to use this library //! //! There are basically two ways: The [**Rust way**](#1-the-rust-way), //! and the [**C way**](#2-the-c-way). (Or a mix of both). //! //! ## 1. The Rust way //! //! Where you use the safely wrapped types, with its methods and constructors, //! and painless error handling, like this: //! //! ### Example //! //! ```rust //! use libnotcurses_sys::*; //! //! fn main() -> NcResult<()> { //! let mut nc = FullMode::with_flags(NCOPTION_NO_ALTERNATE_SCREEN)?; //! let plane = nc.stdplane(); //! plane.putstr("hello world")?; //! nc.render()?; //! Ok(()) //! } //! ``` //! //! Specifically [`FullMode`] and [`DirectMode`] are safe wrappers //! over [`Notcurses`] and [`NcDirect`], respectively. //! //! `FullMode` and `DirectMode` both implement the [Drop], [AsRef], [AsMut], //! [Deref][std::ops::Deref] and [DerefMut][std::ops::DerefMut] traits. //! //! Their destructors are called automatically at the end of their scope. //! //! Methods are directly implemented for `Notcurses` and `NcDirect`, and //! are made automatically available to `FullMode` & `DirectMode`, //! minus some function overrides, like their destructors, //! plus the static methods that have to be recreated. //! //! The rest of the types that allocate, like [`NcPlane`], [`NcMenu`], [`NcReader`]… //! have no higher level wrapping struct, they don't implement Drop, //! so they have to be `*.destroy()`ed manually. //! //! But they do implement methods and use [`NcResult`] as the return type, //! for handling errors in the way we are used to in Rust. //! //! For the types that don't allocate, most are based on primitives like `i32`, //! `u32`, `u64`… without a name in the C library. In Rust they are type aliased //! (e.g.: [`NcChannel`], [`NcChannelPair`], [`NcRgb`], [`NcColor`]…), to //! leverage type checking, and they implement methods through [traits](#traits) //! (e.g. [`NcChannelMethods`] must be in scope to use the `NcChannel` methods. //! //! //! ## 2. The C way //! //! You can always use the C API functions directly if you prefer, //! in a very similar way as the C library is used. //! //! It requires the use of unsafe, since most functions are wrapped directly //! by `bindgen` marked as such. //! //! Error handling is done this way by checking the returned [`NcIntResult`], //! or in case of receiving a pointer, by comparing it //! to [null_mut()][core::ptr::null_mut]. //! //! ### Example //! //! ```rust //! use core::ptr::{null, null_mut}; //! use std::process::exit; //! //! use libnotcurses_sys::*; //! //! fn main() { //! let options = ffi::notcurses_options { //! termtype: null(), //! renderfp: null_mut(), //! loglevel: 0, //! margin_t: 0, //! margin_r: 0, //! margin_b: 0, //! margin_l: 0, //! flags: NCOPTION_NO_ALTERNATE_SCREEN, //! }; //! unsafe { //! let nc = notcurses_init(&options, null_mut()); //! if nc == null_mut() { //! exit(1); //! } //! let plane = notcurses_stdplane(nc); //! let cols = ncplane_putstr(&mut *plane, "hello world"); //! if cols < NCRESULT_OK { //! notcurses_stop(nc); //! exit(cols.abs()); //! } //! if notcurses_stop(nc) < NCRESULT_OK { //! exit(2); //! } //! } //! } //! //! ``` //! //! ### The `notcurses` C API docs //! //! - [API reference (man pages)](https://notcurses.com/) //! - [Wiki Page](https://nick-black.com/dankwiki/index.php/Notcurses) //! - [The Book Guide (pdf)](https://nick-black.com/htp-notcurses.pdf) //! - [USAGE.md](https://github.com/dankamongmen/notcurses/blob/master/USAGE.md) //! - [HACKING.md](https://github.com/dankamongmen/notcurses/blob/master/doc/HACKING.md) //! - [Doxygen Documentation](https://nick-black.com/notcurses/html/index.html) //! #![allow(non_upper_case_globals, non_camel_case_types, non_snake_case)] #![allow(clippy::too_many_arguments)] mod bindings; #[doc(inline)] pub use bindings::*; mod r#box; mod cells; mod channel; mod dimension; mod direct; mod error; mod fade; mod file; mod input; mod macros; mod metric; mod notcurses; mod palette; mod pixel; mod plane; mod resizecb; mod signal; mod stats; mod time; mod visual; mod widgets; pub use crate::input::*; pub use cells::*; pub use channel::*; pub use dimension::*; pub use direct::*; pub use error::*; pub use fade::*; pub use file::*; pub use macros::*; pub use metric::*; pub use notcurses::*; pub use palette::*; pub use pixel::*; pub use plane::*; pub use r#box::*; pub use resizecb::*; pub use signal::*; pub use stats::*; pub use time::*; pub use visual::*; pub use widgets::*; libnotcurses-sys-2.1.8/src/macros.rs010064400017500001750000000143011377726434200156720ustar 00000000000000//! Macros //! // // NOTE: Use full paths everywhere. Don't assume anything will be in scope. #[allow(unused_imports)] // enjoy briefer doc comments use crate::{NcDirect, NcError, NcResult, Notcurses, NCRESULT_ERR, NCRESULT_OK}; // Sleep, Render & Flush Macros ------------------------------------------------ /// Sleeps for `$ns` seconds + `$ms` milliseconds /// + `$us` microseconds + `$ns` nanoseconds #[macro_export] macro_rules! sleep { ($s:expr) => { std::thread::sleep(std::time::Duration::from_secs($s)); }; ($s:expr, $ms:expr) => { std::thread::sleep(std::time::Duration::from_millis($s * 1000 + $ms)); }; ($s:expr, $ms:expr, $us:expr) => { std::thread::sleep(std::time::Duration::from_micros( $s * 1_000_000 + $ms * 1_000 + $us, )); }; ($s:expr, $ms:expr, $us:expr, $ns:expr) => { std::thread::sleep(std::time::Duration::from_nanos( $s * 1_000_000_000 + $ms * 1_000_000 + $us * 1_000 + $ns, )); }; } /// [`Notcurses.render`][Notcurses#method.render]\(`$nc`\)? plus [`sleep!`]`[$sleep_args]`. /// /// Renders the `$nc` [Notcurses] object and, if there's no error, /// calls the sleep macro with the rest of the arguments. /// /// Returns [NcResult]. #[macro_export] macro_rules! rsleep { ($nc:expr, $( $sleep_args:expr),+ ) => { // Rust style, with methods & NcResult Notcurses::render($nc)?; sleep![$( $sleep_args ),+]; }; ($nc:expr, $( $sleep_args:expr),+ ,) => { rsleep![$nc, $( $sleep_args ),* ] }; } /// [`NcDirect.flush`][NcDirect#method.flush]\(`$ncd`\)? plus [`sleep!`]`[$sleep_args]`. /// /// Flushes the `$ncd` [NcDirect] object and, if there's no error, /// calls the sleep macro with the rest of the arguments. /// /// Returns [NcResult]. #[macro_export] macro_rules! fsleep { ($ncd:expr, $( $sleep_args:expr),+ ) => { // Rust style, with methods & NcResult NcDirect::flush($ncd)?; sleep![$( $sleep_args ),+]; }; ($ncd:expr, $( $sleep_args:expr),+ ,) => { rsleep![$ncd, $( $sleep_args ),* ] }; } // String & Print Macros ------------------------------------------------------- /// Converts an `&str` into `*const c_char`. #[macro_export] macro_rules! cstring { ($s:expr) => { std::ffi::CString::new($s).unwrap().as_ptr(); }; } /// Converts an `&str` into `*mut c_char`. #[macro_export] macro_rules! cstring_mut { ($s:expr) => { std::ffi::CString::new($s).unwrap().into_raw(); }; } /// Converts a `*const c_char` into an `&str`. #[macro_export] macro_rules! rstring { ($s:expr) => { unsafe { std::ffi::CStr::from_ptr($s).to_str().unwrap() } // possible alternative: // unsafe { std::ffi::CStr::from_ptr($s).to_string_lossy() } }; } /// Wrapper around [libc::printf]. #[macro_export] macro_rules! printf { ($s:expr) => { unsafe { libc::printf(cstring![$s]) } }; ($s:expr $(, $opt:expr)*) => { unsafe { libc::printf(cstring![$s], $($opt),*) } }; } // Error Wrappers Macros ------------------------------------------------------- /// Returns an `Ok($ok)`, /// or an `Err(`[`NcError`]`)` if `$res` < [`NCRESULT_OK`]. /// /// In other words: /// Returns Ok(`$ok`) if `$res` >= [NCRESULT_OK], otherwise returns /// Err([NcError]::[new][NcError#method.new](`$res`, `$msg`)). /// /// `$ok` & `$msg` are optional. By default they will be the unit /// type `()`, and an empty `&str` `""`, respectively. #[macro_export] macro_rules! error { ($res:expr, $msg:expr, $ok:expr) => { if $res >= crate::NCRESULT_OK { return Ok($ok); } else { return Err(crate::NcError::with_msg($res, $msg)); } }; ($res:expr, $msg:expr) => { error![$res, $msg, ()]; }; ($res:expr) => { error![$res, "", ()]; }; } /// Returns an `Ok(&T)` from a `*const T` pointer, /// or an `Err(`[`NcError`]`)` if the pointer is null. /// /// In other words: /// Returns Ok(&*`$ptr`) if `$ptr` != `null()`, otherwise returns /// Err([NcError]]::[new][NcError#method.new]([NCRESULT_ERR], `$msg`)). /// /// `$msg` is optional. By default it will be an empty `&str` `""`. #[macro_export] macro_rules! error_ref { ($ptr:expr, $msg:expr) => { if $ptr != core::ptr::null() { #[allow(unused_unsafe)] return Ok(unsafe { &*$ptr }); } else { return Err(crate::NcError::with_msg(crate::NCRESULT_ERR, $msg)); } }; ($ptr:expr) => { error_ref![$ptr, ""]; }; } /// Returns an `Ok(&mut T)` from a `*mut T` pointer, /// or an `Err(`[`NcError`]`)` if the pointer is null. /// /// In other words: /// Returns Ok(&mut *`$ptr`) if `$ptr` != `null_mut()`, otherwise returns /// Err([NcError]]::[new][NcError#method.new]([NCRESULT_ERR], `$msg`)). /// /// `$msg` is optional. By default it will be an empty `&str` `""`. #[macro_export] macro_rules! error_ref_mut { ($ptr:expr, $msg:expr) => { if $ptr != core::ptr::null_mut() { #[allow(unused_unsafe)] return Ok(unsafe { &mut *$ptr }); } else { return Err(crate::NcError::with_msg(crate::NCRESULT_ERR, $msg)); } }; ($ptr:expr) => { error_ref_mut![$ptr, ""]; }; } /// Returns an `Ok(String)` from a `*const` pointer to a C string, /// or an `Err(`[`NcError`]`)` if the pointer is null. /// /// In other words: /// Returns Ok((&*`$str`).to_string()) if `$str` != `null()`, otherwise returns /// Err([NcError]]::[new][NcError#method.new]([NCRESULT_ERR], `$msg`)). /// /// `$msg` is optional. By default it will be an empty `&str` `""`. #[macro_export] macro_rules! error_str { ($str:expr, $msg:expr) => { if $str != core::ptr::null_mut() { #[allow(unused_unsafe)] return Ok(unsafe { (&*$str).to_string() }); } else { return Err(crate::NcError::with_msg(crate::NCRESULT_ERR, $msg)); } }; ($str:expr) => { error_str![$str, ""]; }; } /// Returns an [`NcResult`]`` from an [`NcResult`]``. #[macro_export] macro_rules! raw_wrap { ($res:expr) => { match $res { Ok(raw) => return Ok(Self { raw }), Err(e) => return Err(e), } }; } libnotcurses-sys-2.1.8/src/metric.rs010064400017500001750000000023731376441154400156710ustar 00000000000000//! `NcMetric` // TODO: clarify, update and visibilize doc-comments // The number of columns is one fewer, as the STRLEN expressions must leave // an extra byte open in case 'µ' (U+00B5, 0xC2 0xB5) shows up. // This is the true number of columns; // // to set up a printf()-style maximum field width, // you should use [IB]PREFIXFMT (see below). pub const NCMETRIC_PREFIXCOLUMNS: u32 = crate::bindings::ffi::PREFIXCOLUMNS; // The maximum number of columns used by a mult == 1000 (standard) // ncmetric() call. pub const NCMETRIC_BPREFIXCOLUMNS: u32 = crate::bindings::ffi::BPREFIXCOLUMNS; // IPREFIXCOLUMNS is the maximum number of columns used by a mult == 1024 // (digital information) ncmetric(). pub const NCMETRIC_IPREFIXCOLUMNS: u32 = crate::bindings::ffi::IPREFIXCOLUMNS; // // Does not include a '\0' (xxx.xxU) pub const NCMETRIC_PREFIXSTRLEN: u32 = crate::bindings::ffi::PREFIXSTRLEN; // The maximum number of columns used by a mult == 1024 call making use of // the 'i' suffix. // Does not include a '\0' (xxxx.xxUi), i == prefix pub const NCMETRIC_BPREFIXSTRLEN: u32 = crate::bindings::ffi::BPREFIXSTRLEN; // Does not include a '\0' (xxxx.xxU) pub const NCMETRIC_IPREFIXSTRLEN: u32 = crate::bindings::ffi::IPREFIXSTRLEN; // TODO:? // WCHAR_MAX_UTF8BYTES libnotcurses-sys-2.1.8/src/notcurses/helpers.rs010064400017500001750000000005641377422371100200730ustar 00000000000000use crate::{notcurses_init, Notcurses, NotcursesOptions, NCOPTION_SUPPRESS_BANNERS}; /// Helper function for initializing Notcurses on C style tests. #[allow(dead_code)] pub(crate) unsafe fn notcurses_init_test<'a>() -> &'a mut Notcurses { &mut *notcurses_init( &NotcursesOptions::with_flags(NCOPTION_SUPPRESS_BANNERS), core::ptr::null_mut(), ) } libnotcurses-sys-2.1.8/src/notcurses/methods.rs010064400017500001750000000567661377726434200201230ustar 00000000000000//! `Notcurses*` methods and associated functions. use core::ptr::{null, null_mut}; use crate::{ cstring, error, error_ref_mut, notcurses_init, rstring, NcAlign, NcBlitter, NcChannelPair, NcDim, NcEgc, NcError, NcFile, NcInput, NcLogLevel, NcPlane, NcResult, NcScale, NcSignalSet, NcStats, NcStyleMask, NcTime, Notcurses, NotcursesOptions, NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS, NCRESULT_ERR, }; /// # `NotcursesOptions` Constructors impl NotcursesOptions { /// New NotcursesOptions. pub const fn new() -> Self { Self::with_all_options(0, 0, 0, 0, 0, 0) } /// New NotcursesOptions, with margins. pub const fn with_margins(top: NcDim, right: NcDim, bottom: NcDim, left: NcDim) -> Self { Self::with_all_options(0, top, right, bottom, left, 0) } /// New NotcursesOptions, with flags. pub const fn with_flags(flags: u64) -> Self { Self::with_all_options(0, 0, 0, 0, 0, flags) } /// New NotcursesOptions, with all the options. /// /// ## Arguments /// /// - loglevel /// /// Progressively higher log levels result in more logging to stderr. By /// default, nothing is printed to stderr once fullscreen service begins. /// /// - margin_t, margin_r, margin_b, margin_l /// /// Desirable margins (top, right, bottom, left). /// /// If all are 0 (default), we will render to the entirety of the screen. /// If the screen is too small, we do what we can. /// Absolute coordinates are relative to the rendering area /// ((0, 0) is always the origin of the rendering area). /// /// - flags /// /// General flags; This is expressed as a bitfield so that future options /// can be added without reshaping the struct. /// Undefined bits must be set to 0. /// /// - [`NCOPTION_INHIBIT_SETLOCALE`][crate::NCOPTION_INHIBIT_SETLOCALE] /// - [`NCOPTION_NO_ALTERNATE_SCREEN`] /// - [`NCOPTION_NO_FONT_CHANGES`][crate::NCOPTION_NO_FONT_CHANGES] /// - [`NCOPTION_NO_QUIT_SIGHANDLERS`][crate::NCOPTION_NO_QUIT_SIGHANDLERS] /// - [`NCOPTION_NO_WINCH_SIGHANDLER`][crate::NCOPTION_NO_WINCH_SIGHANDLER] /// - [`NCOPTION_SUPPRESS_BANNERS`] /// pub const fn with_all_options( loglevel: NcLogLevel, margin_t: NcDim, margin_r: NcDim, margin_b: NcDim, margin_l: NcDim, flags: u64, ) -> Self { Self { termtype: null(), renderfp: null_mut(), loglevel, margin_t: margin_t as i32, margin_r: margin_r as i32, margin_b: margin_b as i32, margin_l: margin_l as i32, flags, } } } /// # `Notcurses` Constructors impl Notcurses { /// New Notcurses (without banners). pub fn new<'a>() -> NcResult<&'a mut Notcurses> { Self::with_flags(NCOPTION_SUPPRESS_BANNERS) } /// New Notcurses, with banners. /// /// This is the default in the C library. pub fn with_banners<'a>() -> NcResult<&'a mut Notcurses> { Self::with_flags(0) } /// New Notcurses, without an alternate screen (nor banners). pub fn without_altscreen<'a>() -> NcResult<&'a mut Notcurses> { Self::with_flags(NCOPTION_NO_ALTERNATE_SCREEN | NCOPTION_SUPPRESS_BANNERS) } /// New Notcurses, expects `NCOPTION_*` flags. pub fn with_flags<'a>(flags: u64) -> NcResult<&'a mut Notcurses> { Self::with_options(NotcursesOptions::with_flags(flags)) } /// New Notcurses, expects [NotcursesOptions]. pub fn with_options<'a>(options: NotcursesOptions) -> NcResult<&'a mut Notcurses> { let res = unsafe { notcurses_init(&options, null_mut()) }; error_ref_mut![res, "Notcurses.with_options()"] } /// New Notcurses, expects [NcLogLevel] and flags. pub fn with_debug<'a>(loglevel: NcLogLevel, flags: u64) -> NcResult<&'a mut Notcurses> { Self::with_options(NotcursesOptions::with_all_options( loglevel, 0, 0, 0, 0, flags, )) } } /// # `Notcurses` methods impl Notcurses { /// Returns the offset into `availcols` at which `cols` ought be output given /// the requirements of `align`. /// /// Returns `-`[`NCRESULT_MAX`][crate::NCRESULT_MAX] if /// [NCALIGN_UNALIGNED][crate::NCALIGN_UNALIGNED] or invalid [NcAlign]. /// /// *C style function: [notcurses_align()][crate::notcurses_align].* // // TODO: handle error rightfully. pub fn align(availcols: NcDim, align: NcAlign, cols: NcDim) -> NcResult<()> { error![crate::notcurses_align(availcols, align, cols)] } /// Retrieves the current contents of the specified [NcCell][crate::NcCell] /// as last rendered, returning the [NcEgc] (or None on error) and writing /// out the [NcStyleMask] and the [NcChannelPair]. /// /// This NcEgc must be freed by the caller. /// /// *C style function: [notcurses_at_yx()][crate::notcurses_at_yx].* pub fn at_yx( &mut self, y: NcDim, x: NcDim, stylemask: &mut NcStyleMask, channels: &mut NcChannelPair, ) -> Option { let egc = unsafe { crate::notcurses_at_yx(self, x as i32, y as i32, stylemask, channels) }; if egc.is_null() { return None; } let egc = core::char::from_u32(unsafe { *egc } as u32).expect("wrong char"); Some(egc) } /// Returns the bottommost [NcPlane], of which there is always at least one. /// /// *C style function: [notcurses_bottom()][crate::notcurses_bottom].* pub fn bottom<'a>(&'a mut self) -> &'a mut NcPlane { unsafe { &mut *crate::notcurses_bottom(self) } } /// Returns true if it's possible to set the "hardware" palette. /// /// Requires the "ccc" terminfo capability. /// /// *C style function: [notcurses_canchangecolor()][crate::notcurses_canchangecolor].* pub fn canchangecolor(&self) -> bool { unsafe { crate::notcurses_canchangecolor(self) } } /// Returns true if fading is possible. /// /// Fading requires either the "rgb" or "ccc" terminfo capability. /// /// *C style function: [notcurses_canfade()][crate::notcurses_canfade].* pub fn canfade(&self) -> bool { unsafe { crate::notcurses_canfade(self) } } /// Returns true if loading images is possible. /// /// This requires being built against FFmpeg/OIIO. /// /// *C style function: [notcurses_canopen_images()][crate::notcurses_canopen_images].* pub fn canopen_images(&self) -> bool { unsafe { crate::notcurses_canopen_images(self) } } /// Returns true if loading videos is possible. /// /// This requires being built against FFmpeg. /// /// *C style function: [notcurses_canopen_videos()][crate::notcurses_canopen_videos].* pub fn canopen_videos(&self) -> bool { unsafe { crate::notcurses_canopen_videos(self) } } /// Returns true if sixel blitting is supported. /// /// See [NCBLIT_SIXEL][crate::NCBLIT_SIXEL]. /// /// *C style function: [notcurses_cansixel()][crate::notcurses_cansixel].* pub fn cansixel(&self) -> bool { unsafe { crate::notcurses_cansixel(self) } } /// Returns true if we can reliably use Unicode 13 sextants. /// /// *C style function: [notcurses_cansextant()][crate::notcurses_cansextant].* pub fn cansextant(&self) -> bool { unsafe { crate::notcurses_cansextant(self) } } /// Returns true if it's possible to directly specify RGB values per cell, /// or false if it's only possible to use palettes. /// /// *C style function: [notcurses_cantruecolor()][crate::notcurses_cantruecolor].* pub fn cantruecolor(&self) -> bool { unsafe { crate::notcurses_cantruecolor(self) } } /// Returns true if the encoding is UTF-8. /// /// Requires `LANG` being set to a UTF-8 locale. /// /// *C style function: [notcurses_canutf8()][crate::notcurses_canutf8].* pub fn canutf8(&self) -> bool { unsafe { crate::notcurses_canutf8(self) } } /// Disables the terminal's cursor, if supported. /// /// Immediate effect (no need for a call to notcurses_render()). /// /// *C style function: [notcurses_cursor_disable()][crate::notcurses_cursor_disable].* pub fn cursor_disable(&mut self) -> NcResult<()> { error![unsafe { crate::notcurses_cursor_disable(self) }] } /// Enables the terminal's cursor, if supported, placing it at `y`, `x`. /// /// Immediate effect (no need for a call to notcurses_render()). /// It is an error if `y`, `x` lies outside the standard plane. /// /// *C style function: [notcurses_cursor_enable()][crate::notcurses_cursor_enable].* pub fn cursor_enable(&mut self, y: NcDim, x: NcDim) -> NcResult<()> { error![unsafe { crate::notcurses_cursor_enable(self, y as i32, x as i32) }] } /// Dumps Notcurses state to the supplied `debugfp`. /// /// Output is freeform, and subject to change. It includes geometry of all /// planes, from all piles. /// /// *C style function: [notcurses_debug()][crate::notcurses_debug].* pub fn debug(&mut self, debugfp: &mut NcFile) { unsafe { crate::notcurses_debug(self, debugfp.as_nc_ptr()); } } /// Destroys all [NcPlane]s other than the stdplane. /// /// *C style function: [notcurses_drop_planes()][crate::notcurses_drop_planes].* pub fn drop_planes(&mut self) { unsafe { crate::notcurses_drop_planes(self); } } /// Returns a [char] representing a single unicode point. /// /// If an event is processed, the return value is the `id` field from that /// event. /// /// Provide a None `time` to block at length, a `time` of 0 for non-blocking /// operation, and otherwise a timespec to bound blocking. /// /// Signals in sigmask (less several we handle internally) will be atomically /// masked and unmasked per [ppoll(2)](https://linux.die.net/man/2/ppoll). /// /// `*sigmask` should generally contain all signals. /// /// *C style function: [notcurses_getc()][crate::notcurses_getc].* pub fn getc( &mut self, time: Option, sigmask: Option<&mut NcSignalSet>, input: Option<&mut NcInput>, ) -> NcResult { let ntime; if let Some(time) = time { ntime = &time as *const _; } else { ntime = null(); } let nsigmask; if let Some(sigmask) = sigmask { nsigmask = sigmask as *mut _; } else { nsigmask = null_mut() as *mut _; } let ninput; if let Some(input) = input { ninput = input as *mut _; } else { ninput = null_mut(); } let c = unsafe { core::char::from_u32_unchecked(crate::notcurses_getc(self, ntime, nsigmask, ninput)) }; if c as u32 as i32 == NCRESULT_ERR { return Err(NcError::new(NCRESULT_ERR)); } Ok(c) } /// If no event is ready, returns 0. /// /// *C style function: [notcurses_getc_nblock()][crate::notcurses_getc_nblock].* pub fn getc_nblock(&mut self, input: &mut NcInput) -> char { crate::notcurses_getc_nblock(self, input) } /// Blocks until a codepoint or special key is read, /// or until interrupted by a signal. /// /// In the case of a valid read, a 32-bit Unicode codepoint is returned. /// /// Optionally writes the event details in `input`. /// /// *C style function: [notcurses_getc_blocking()][crate::notcurses_getc_blocking].* pub fn getc_blocking(&mut self, input: Option<&mut NcInput>) -> NcResult { let input_txt; if cfg!(debug_assertions) { input_txt = format!("{:?}", input); } else { input_txt = String::from(""); } let res = crate::notcurses_getc_blocking(self, input); // An invalid read is indicated with -1 if res as u32 as i32 != -1 { return Ok(res); } else { error![ -1, &format!("Notcurses.getc_blocking({:?})", input_txt), res ] } } /// Gets a file descriptor suitable for input event poll()ing. /// /// When this descriptor becomes available, you can call /// [getc_nblock()][Notcurses#method.getc_nblock], and input ought be ready. /// /// This file descriptor is not necessarily the file descriptor associated /// with stdin (but it might be!). /// /// *C style function: [notcurses_inputready_fd()][crate::notcurses_inputready_fd].* pub fn inputready_fd(&mut self) -> NcResult<()> { error![unsafe { crate::notcurses_inputready_fd(self) }] } /// Returns an [NcBlitter] from a string representation. /// /// *C style function: [notcurses_lex_blitter()][crate::notcurses_lex_blitter].* pub fn lex_blitter(op: &str) -> NcResult { let mut blitter = 0; error![ unsafe { crate::notcurses_lex_blitter(cstring![op], &mut blitter) }, "Invalid blitter name", blitter ] } /// Lexes a margin argument according to the standard Notcurses definition. /// /// There can be either a single number, which will define all margins equally, /// or there can be four numbers separated by commas. /// /// *C style function: [notcurses_lex_margins()][crate::notcurses_lex_margins].* pub fn lex_margins(op: &str, options: &mut NotcursesOptions) -> NcResult<()> { error![unsafe { crate::notcurses_lex_margins(cstring![op], options) }] } /// Returns an [NcScale] from a string representation. /// /// *C style function: [notcurses_lex_scalemode()][crate::notcurses_lex_scalemode].* pub fn lex_scalemode(op: &str) -> NcResult { let mut scalemode = 0; error![ unsafe { crate::notcurses_lex_scalemode(cstring![op], &mut scalemode) }, "", scalemode ] } /// Disables signals originating from the terminal's line discipline, i.e. /// SIGINT (^C), SIGQUIT (^), and SIGTSTP (^Z). They are enabled by default. /// /// *C style function: [notcurses_linesigs_disable()][crate::notcurses_linesigs_disable].* pub fn linesigs_disable(&mut self) -> NcResult<()> { error![unsafe { crate::notcurses_linesigs_disable(self) }] } /// Restores signals originating from the terminal's line discipline, i.e. /// SIGINT (^C), SIGQUIT (^), and SIGTSTP (^Z), if disabled. /// /// *C style function: [notcurses_linesigs_enable()][crate::notcurses_linesigs_enable].* pub fn linesigs_enable(&mut self) -> NcResult<()> { error![unsafe { crate::notcurses_linesigs_enable(self) }] } /// Disables mouse events. /// /// Any events in the input queue can still be delivered. /// /// *C style function: [notcurses_mouse_disable()][crate::notcurses_mouse_disable].* pub fn mouse_disable(&mut self) -> NcResult<()> { error![unsafe { crate::notcurses_mouse_disable(self) }] } /// Enable the mouse in "button-event tracking" mode with focus detection /// and UTF8-style extended coordinates. /// /// On success, mouse events will be published to [getc()][Notcurses#method.getc]. /// /// *C style function: [notcurses_mouse_enable()][crate::notcurses_mouse_enable].* pub fn mouse_enable(&mut self) -> NcResult<()> { error![ unsafe { crate::notcurses_mouse_enable(self) }, "Notcurses.mouse_enable()" ] } /// Returns the number of simultaneous colors claimed to be supported, /// or 1 if there is no color support. /// /// Note that several terminal emulators advertise more colors than they /// actually support, downsampling internally. /// /// *C style function: [notcurses_palette_size()][crate::notcurses_palette_size].* pub fn palette_size(&mut self) -> u32 { unsafe { crate::notcurses_palette_size(self) } } /// Refreshes the physical screen to match what was last rendered (i.e., /// without reflecting any changes since the last call to /// [render][crate::Notcurses#method.render]). /// /// This is primarily useful if the screen is externally corrupted, or if an /// [NCKEY_RESIZE][crate::NCKEY_RESIZE] event has been read and you're not /// yet ready to render. /// /// *C style function: [notcurses_refresh()][crate::notcurses_refresh].* // pub fn refresh(&mut self) -> NcResult<(NcDim, NcDim)> { let (mut y, mut x) = (0, 0); error![ unsafe { crate::notcurses_refresh(self, &mut y, &mut x) }, "", (y as NcDim, x as NcDim) ] } /// Renders and rasterizes the standard pile in one shot. Blocking call. /// /// *C style function: [notcurses_render()][crate::notcurses_render].* pub fn render(&mut self) -> NcResult<()> { error![ unsafe { crate::notcurses_render(self) }, "Notcurses.render()" ] } /// Performs the rendering and rasterization portion of /// [render][Notcurses#method.render] but do not write the resulting buffer /// out to the terminal. /// /// Using this function, the user can control the writeout process, /// and render a second frame while writing another. /// /// The returned buffer must be freed by the caller. /// /// *C style function: [notcurses_render_to_buffer()][crate::notcurses_render_to_buffer].* // // CHECK that this works. pub fn render_to_buffer(&mut self, buffer: &mut Vec) -> NcResult<()> { let mut len = buffer.len() as u64; let mut buf = buffer.as_mut_ptr() as *mut i8; error![unsafe { crate::notcurses_render_to_buffer(self, &mut buf, &mut len) }] } /// Writes the last rendered frame, in its entirety, to 'fp'. /// /// If [render()][Notcurses#method.render] has not yet been called, /// nothing will be written. /// /// *C style function: [notcurses_render_to_file()][crate::notcurses_render_to_file].* pub fn render_to_file(&mut self, fp: &mut NcFile) -> NcResult<()> { error![unsafe { crate::notcurses_render_to_file(self, fp.as_nc_ptr()) }] } /// Acquires an atomic snapshot of the Notcurses object's stats. /// /// *C style function: [notcurses_stats()][crate::notcurses_stats].* pub fn stats(&mut self, stats: &mut NcStats) { unsafe { crate::notcurses_stats(self, stats); } } /// Allocates an ncstats object. /// /// Use this rather than allocating your own, since future versions of /// Notcurses might enlarge this structure. /// /// *C style function: [notcurses_stats_alloc()][crate::notcurses_stats_alloc].* pub fn stats_alloc<'a>(&'a mut self) -> &'a mut NcStats { unsafe { &mut *crate::notcurses_stats_alloc(self) } } /// Resets all cumulative stats (immediate ones, such as fbbytes, are not reset). /// /// *C style function: [notcurses_stats_reset()][crate::notcurses_stats_reset].* pub fn stats_reset(&mut self, stats: &mut NcStats) { unsafe { crate::notcurses_stats_reset(self, stats); } } // TODO: decide what to do with these two: // // /// [notcurses_stdplane()][crate::notcurses_stdplane], plus free bonus // /// dimensions written to non-NULL y/x! // /// // /// *C style function: [notcurses_stddim_yx()][crate::notcurses_stddim_yx].* // #[inline] // pub fn stddim_yx<'a>( // &'a mut self, // y: &mut NcDim, // x: &mut NcDim, // ) -> NcResult<&'a mut NcPlane> { // crate::notcurses_stddim_yx(self, y, x) // } // /// [stdplane_const()][Notcurses#method.stdplane_const], plus free // /// bonus dimensions written to non-NULL y/x! // /// // /// *C style function: [notcurses_stddim_yx()][crate::notcurses_stddim_yx].* // #[inline] // pub fn stddim_yx_const<'a>( // &'a self, // y: &mut NcDim, // x: &mut NcDim, // ) -> NcResult<&'a NcPlane> { // crate::notcurses_stddim_yx_const(self, y, x) // } /// Returns a mutable reference to the standard [NcPlane] for this terminal. /// /// The standard plane always exists, and its origin is always at the /// uppermost, leftmost cell. /// /// *C style function: [notcurses_stdplane()][crate::notcurses_stdplane].* pub fn stdplane<'a>(&mut self) -> &'a mut NcPlane { unsafe { &mut *crate::notcurses_stdplane(self) } } /// Returns a reference to the standard [NcPlane] for this terminal. /// /// The standard plane always exists, and its origin is always at the /// uppermost, leftmost cell. /// /// *C style function: [notcurses_stdplane_const()][crate::notcurses_stdplane_const].* pub fn stdplane_const<'a>(&self) -> &'a NcPlane { unsafe { &*crate::notcurses_stdplane_const(self) } } /// Destroys the Notcurses context. /// /// *C style function: [notcurses_stop()][crate::notcurses_stop].* pub fn stop(&mut self) -> NcResult<()> { error![unsafe { crate::notcurses_stop(self) }] } /// Gets the name of an [NcBlitter] blitter. /// /// *C style function: [notcurses_str_blitter()][crate::notcurses_str_blitter].* pub fn str_blitter(blitter: NcBlitter) -> String { rstring![crate::notcurses_str_blitter(blitter)].to_string() } /// Gets the name of an [NcScale] scaling mode. /// /// *C style function: [notcurses_str_scalemode()][crate::notcurses_str_scalemode].* pub fn str_scalemode(scalemode: NcScale) -> String { rstring![crate::notcurses_str_scalemode(scalemode)].to_string() } /// Returns an [NcStyleMask] with the supported curses-style attributes. /// /// The attribute is only indicated as supported if the terminal can support /// it together with color. /// /// For more information, see the "ncv" capability in terminfo(5). /// /// *C style function: [notcurses_supported_styles()][crate::notcurses_supported_styles].* pub fn supported_styles(&self) -> NcStyleMask { unsafe { crate::notcurses_supported_styles(self) as NcStyleMask } } /// Returns our current idea of the terminal dimensions in rows and cols. /// /// *C style function: [notcurses_supported_styles()][crate::notcurses_supported_styles].* pub fn term_dim_yx(&self) -> (NcDim, NcDim) { crate::notcurses_term_dim_yx(self) } /// Returns the topmost [NcPlane], of which there is always at least one. /// /// *C style function: [notcurses_top()][crate::notcurses_top].* pub fn top<'a>(&'a mut self) -> &'a mut NcPlane { unsafe { &mut *crate::notcurses_top(self) } } /// Returns a human-readable string describing the running notcurses version. /// /// *C style function: [notcurses_version()][crate::notcurses_version].* pub fn version() -> String { rstring![crate::notcurses_version()].to_string() } /// Returns the running Notcurses version components /// (major, minor, patch, tweak). /// /// *C style function: [notcurses_version_components()][crate::notcurses_version_components].* pub fn version_components() -> (u32, u32, u32, u32) { let (mut major, mut minor, mut patch, mut tweak) = (0, 0, 0, 0); unsafe { crate::notcurses_version_components(&mut major, &mut minor, &mut patch, &mut tweak); } (major as u32, minor as u32, patch as u32, tweak as u32) } } libnotcurses-sys-2.1.8/src/notcurses/mod.rs010064400017500001750000000203611377520444700172130ustar 00000000000000//! `Notcurses` // --- ------------------------------------------------------------------------- // col 0: // -------------- // 1 X: wont do // 2 ~: WIP // // col 1: 48 // -------------- // 42 f: ffi function imported by bindgen // F: ffi function wrapped safely // 6 r: static function reimplemented in Rust // // col 2: 45 // -------------- // 38 m: impl as a `Notcurses` method // 7 M: impl for the `FullMode` wrapper struct too // // col 3: 14 // -------------- // 14 t: tests done for the ffi or reimplemented funtion // T: tests done also for the m method // Ŧ: tests done also for the M method wrapper struct // --- ------------------------------------------------------------------------- // // fm notcurses_at_yx // fm notcurses_bottom // fmt notcurses_canchangecolor // fmt notcurses_canfade // fmt notcurses_canopen_images // fmt notcurses_canopen_videos // fmt notcurses_cansixel // fmt notcurses_cansextant // fmt notcurses_cantruecolor // fmt notcurses_canutf8 // fm notcurses_cursor_disable // fm notcurses_cursor_enable // fmt notcurses_debug // fmt notcurses_drop_planes // fm notcurses_getc // fMt notcurses_init // fm notcurses_inputready_fd // fM notcurses_lex_blitter // fM notcurses_lex_margins // fM notcurses_lex_scalemode // fm notcurses_linesigs_disable // fm notcurses_linesigs_enable // fm notcurses_mouse_disable // fm notcurses_mouse_enable // fm notcurses_palette_size // fm notcurses_refresh // fm notcurses_render // fm notcurses_render_to_buffer // fm notcurses_render_to_file // fm notcurses_stats // fm notcurses_stats_alloc // fm notcurses_stats_reset // fm notcurses_stdplane // fm notcurses_stdplane_const // fMt notcurses_stop // fM notcurses_str_blitter // fM notcurses_str_scalemode // fm notcurses_supported_styles // fm notcurses_top //X notcurses_ucs32_to_utf8 (not needed in rust) // fMt notcurses_version // fM notcurses_version_components // // rMt notcurses_align // rm notcurses_getc_blocking // rm notcurses_getc_nblock //~r notcurses_stddim_yx // multiple mutable references errors //~r notcurses_stddim_yx_const // // rm notcurses_term_dim_yx #[cfg(test)] mod test; mod helpers; mod methods; mod reimplemented; mod wrapper; #[allow(unused_imports)] pub(crate) use helpers::*; pub use reimplemented::*; pub use wrapper::*; /// Notcurses builds atop the terminfo abstraction layer to /// provide reasonably portable vivid character displays. /// /// This is the internal type safely wrapped by [FullMode]. pub type Notcurses = crate::bindings::ffi::notcurses; /// Options struct for [`Notcurses`] pub type NotcursesOptions = crate::bindings::ffi::notcurses_options; /// Do not call setlocale() /// /// notcurses_init() will call setlocale() to inspect the current locale. If /// that locale is "C" or "POSIX", it will call setlocale(LC_ALL, "") to set /// the locale according to the LANG environment variable. Ideally, this will /// result in UTF8 being enabled, even if the client app didn't call /// setlocale() itself. Unless you're certain that you're invoking setlocale() /// prior to notcurses_init(), you should not set this bit. Even if you are /// invoking setlocale(), this behavior shouldn't be an issue unless you're /// doing something weird (setting a locale not based on LANG). pub const NCOPTION_INHIBIT_SETLOCALE: u64 = crate::bindings::ffi::NCOPTION_INHIBIT_SETLOCALE as u64; /// Do not enter alternate mode. /// /// If smcup/rmcup capabilities are indicated, Notcurses defaults to making use /// of the "alternate screen". This flag inhibits use of smcup/rmcup. pub const NCOPTION_NO_ALTERNATE_SCREEN: u64 = crate::bindings::ffi::NCOPTION_NO_ALTERNATE_SCREEN as u64; /// Do not modify the font. /// /// Notcurses might attempt to change the font slightly, to support certain /// glyphs (especially on the Linux console). If this is set, no such /// modifications will be made. Note that font changes will not affect anything /// but the virtual console/terminal in which Notcurses is running. pub const NCOPTION_NO_FONT_CHANGES: u64 = crate::bindings::ffi::NCOPTION_NO_FONT_CHANGES as u64; /// Do not handle SIG{ING, SEGV, ABRT, QUIT} /// /// A signal handler will usually be installed for SIGINT, SIGQUIT, SIGSEGV, /// SIGTERM, and SIGABRT, cleaning up the terminal on such exceptions. /// With this flag, the handler will not be installed. pub const NCOPTION_NO_QUIT_SIGHANDLERS: u64 = crate::bindings::ffi::NCOPTION_NO_QUIT_SIGHANDLERS as u64; /// Do not handle SIGWINCH /// /// A signal handler will usually be installed for SIGWINCH, resulting in /// NCKEY_RESIZE events being generated on input. /// With this flag, the handler will not be installed. pub const NCOPTION_NO_WINCH_SIGHANDLER: u64 = crate::bindings::ffi::NCOPTION_NO_WINCH_SIGHANDLER as u64; /// Do not print banners /// /// Notcurses typically prints version info in notcurses_init() and performance /// info in notcurses_stop(). This inhibits that output. pub const NCOPTION_SUPPRESS_BANNERS: u64 = crate::bindings::ffi::NCOPTION_SUPPRESS_BANNERS as u64; /// Test for Sixel support /// /// Checking for Sixel support requires writing an escape, and then reading an /// inline reply from the terminal. Since this can interact poorly with actual /// user input, it's not done unless Sixel will actually be used. Set this flag /// to unconditionally test for Sixel support in notcurses_init(). pub const NCOPTION_VERIFY_SIXEL: u64 = crate::bindings::ffi::NCOPTION_VERIFY_SIXEL as u64; // NcLogLevel ------------------------------------------------------------------ /// Log level for [`NotcursesOptions`] /// /// These log levels consciously map cleanly to those of libav; Notcurses itself /// does not use this full granularity. The log level does not affect the opening /// and closing banners, which can be disabled via the `NotcursesOptions` /// `NCOPTION_SUPPRESS_BANNERS`. /// Note that if stderr is connected to the same terminal on which we're /// rendering, any kind of logging will disrupt the output. pub type NcLogLevel = crate::bindings::ffi::ncloglevel_e; /// this is honestly a bit much pub const NCLOGLEVEL_DEBUG: NcLogLevel = crate::bindings::ffi::ncloglevel_e_NCLOGLEVEL_DEBUG; /// we can't keep doin' this, but we can do other things pub const NCLOGLEVEL_ERROR: NcLogLevel = crate::bindings::ffi::ncloglevel_e_NCLOGLEVEL_ERROR; /// we're hanging around, but we've had a horrible fault pub const NCLOGLEVEL_FATAL: NcLogLevel = crate::bindings::ffi::ncloglevel_e_NCLOGLEVEL_FATAL; /// "detailed information pub const NCLOGLEVEL_INFO: NcLogLevel = crate::bindings::ffi::ncloglevel_e_NCLOGLEVEL_INFO; /// print diagnostics immediately related to crashing pub const NCLOGLEVEL_PANIC: NcLogLevel = crate::bindings::ffi::ncloglevel_e_NCLOGLEVEL_PANIC; /// default. print nothing once fullscreen service begins pub const NCLOGLEVEL_SILENT: NcLogLevel = crate::bindings::ffi::ncloglevel_e_NCLOGLEVEL_SILENT; /// there's probably a better way to do what you want pub const NCLOGLEVEL_TRACE: NcLogLevel = crate::bindings::ffi::ncloglevel_e_NCLOGLEVEL_TRACE; /// "detailed information pub const NCLOGLEVEL_VERBOSE: NcLogLevel = crate::bindings::ffi::ncloglevel_e_NCLOGLEVEL_VERBOSE; /// you probably don't want what's happening to happen pub const NCLOGLEVEL_WARNING: NcLogLevel = crate::bindings::ffi::ncloglevel_e_NCLOGLEVEL_WARNING; // NcAlign -- ------------------------------------------------------------------ /// Alignment within a plane or terminal. /// Left/right-justified, or centered. /// /// ## Defined constants /// /// - [NCALIGN_UNALIGNED] /// - [NCALIGN_LEFT] /// - [NCALIGN_CENTER] /// - [NCALIGN_RIGHT] pub type NcAlign = crate::bindings::ffi::ncalign_e; /// Left alignment within an [`NcPlane`][crate::NcPlane] or terminal. pub const NCALIGN_LEFT: NcAlign = crate::bindings::ffi::ncalign_e_NCALIGN_LEFT; /// Right alignment within an [`NcPlane`][crate::NcPlane] or terminal. pub const NCALIGN_RIGHT: NcAlign = crate::bindings::ffi::ncalign_e_NCALIGN_RIGHT; /// Center alignment within an [`NcPlane`][crate::NcPlane] or terminal. pub const NCALIGN_CENTER: NcAlign = crate::bindings::ffi::ncalign_e_NCALIGN_CENTER; /// Do not align an [`NcPlane`][crate::NcPlane] or terminal. pub const NCALIGN_UNALIGNED: NcAlign = crate::bindings::ffi::ncalign_e_NCALIGN_UNALIGNED; libnotcurses-sys-2.1.8/src/notcurses/reimplemented.rs010064400017500001750000000072711377726434200212750ustar 00000000000000//! `notcurses_*` reimplemented functions. use core::ptr::{null, null_mut}; use crate::{ NcAlign, NcDim, NcError, NcInput, NcOffset, NcPlane, NcResult, NcSignalSet, NcTime, Notcurses, NCALIGN_CENTER, NCALIGN_LEFT, NCALIGN_RIGHT, NCRESULT_ERR, NCRESULT_MAX, }; /// Returns the offset into `availcols` at which `cols` ought be output given /// the requirements of `align`. /// /// Returns `-`[`NCRESULT_MAX`] if [NCALIGN_UNALIGNED][crate::NCALIGN_UNALIGNED] /// or invalid [NcAlign]. /// /// *Method: Notcurses.[align()][Notcurses#method.align].* #[inline] pub fn notcurses_align(availcols: NcDim, align: NcAlign, cols: NcDim) -> NcOffset { if align == NCALIGN_LEFT { return 0; } if cols > availcols { return 0; } if align == NCALIGN_CENTER { return ((availcols - cols) / 2) as NcOffset; } if align == NCALIGN_RIGHT { return (availcols - cols) as NcOffset; } -NCRESULT_MAX // NCALIGN_UNALIGNED } /// /// If no event is ready, returns 0. /// /// *Method: Notcurses.[getc_nblock()][Notcurses#method.getc_nblock].* // // TODO: use from_u32 & return Option. #[inline] pub fn notcurses_getc_nblock(nc: &mut Notcurses, input: &mut NcInput) -> char { unsafe { let mut sigmask = NcSignalSet::new(); sigmask.fillset(); let ts = NcTime { tv_sec: 0, tv_nsec: 0, }; core::char::from_u32_unchecked(crate::notcurses_getc(nc, &ts, &mut sigmask, input)) } } /// Blocks until an event is processed or a signal is received. /// /// Optionally writes the event details in `input`. /// /// In case of an invalid read (including on EOF) *-1 as char* is returned. /// /// *Method: Notcurses.[getc_blocking()][Notcurses#method.getc_blocking].* #[inline] pub fn notcurses_getc_blocking(nc: &mut Notcurses, input: Option<&mut NcInput>) -> char { let input_ptr; if let Some(i) = input { input_ptr = i as *mut _; } else { input_ptr = null_mut(); } unsafe { let mut sigmask = NcSignalSet::new(); sigmask.emptyset(); core::char::from_u32_unchecked(crate::notcurses_getc(nc, null(), &mut sigmask, input_ptr)) } } /// [notcurses_stdplane()][crate::notcurses_stdplane], plus free bonus /// dimensions written to non-NULL y/x! /// /// *Method: Notcurses.[getc_stddim_yx()][Notcurses#method.stddim_yx].* #[inline] pub fn notcurses_stddim_yx<'a>( nc: &'a mut Notcurses, y: &mut NcDim, x: &mut NcDim, ) -> NcResult<&'a mut NcPlane> { unsafe { let sp = crate::notcurses_stdplane(nc); if sp != null_mut() { crate::ncplane_dim_yx(sp, &mut (*y as i32), &mut (*x as i32)); return Ok(&mut *sp); } } Err(NcError::new(NCRESULT_ERR)) } /// [notcurses_stdplane_const()][crate::notcurses_stdplane_const], plus free /// bonus dimensions written to non-NULL y/x! /// /// *Method: Notcurses.[getc_stddim_yx_const()][Notcurses#method.stddim_yx_const].* #[inline] pub fn notcurses_stddim_yx_const<'a>( nc: &'a Notcurses, y: &mut NcDim, x: &mut NcDim, ) -> NcResult<&'a NcPlane> { unsafe { let sp = crate::notcurses_stdplane_const(nc); if sp != null() { crate::ncplane_dim_yx(sp, &mut (*y as i32), &mut (*x as i32)); return Ok(&*sp); } } Err(NcError::new(NCRESULT_ERR)) } /// Returns our current idea of the terminal dimensions in rows and cols. /// /// *Method: Notcurses.[getc_term_yx()][Notcurses#method.term_yx].* #[inline] pub fn notcurses_term_dim_yx(nc: &Notcurses) -> (NcDim, NcDim) { let (mut y, mut x) = (0, 0); unsafe { crate::ncplane_dim_yx(crate::notcurses_stdplane_const(nc), &mut y, &mut x); } (y as NcDim, x as NcDim) } libnotcurses-sys-2.1.8/src/notcurses/test/methods.rs010064400017500001750000000001551376441154400210510ustar 00000000000000//! Test `Notcurses` methods and associated functions. // use crate::Notcurses; // use serial_test::serial; libnotcurses-sys-2.1.8/src/notcurses/test/mod.rs010064400017500001750000000001231376441154400201600ustar 00000000000000//! `Notcurses` tests. #[cfg(test)] mod methods; #[cfg(test)] mod reimplemented; libnotcurses-sys-2.1.8/src/notcurses/test/reimplemented.rs010064400017500001750000000102141377416467000222430ustar 00000000000000//! Test `notcurses_*` reimplemented functions. use serial_test::serial; use std::io::Read; use crate::{notcurses_init_test, notcurses_stop, NcFile, NCRESULT_MAX}; #[test] #[serial] fn notcurses_align() { unsafe { let nc = notcurses_init_test(); assert_eq![0, crate::notcurses_align(30, crate::NCALIGN_LEFT, 20)]; assert_eq![5, crate::notcurses_align(30, crate::NCALIGN_CENTER, 20)]; assert_eq![10, crate::notcurses_align(30, crate::NCALIGN_RIGHT, 20)]; assert_eq![ -NCRESULT_MAX, crate::notcurses_align(30, crate::NCALIGN_UNALIGNED, 20) ]; notcurses_stop(nc); } } #[test] #[serial] fn notcurses_canchangecolor() { unsafe { let nc = notcurses_init_test(); let res = crate::notcurses_canchangecolor(nc); notcurses_stop(nc); print!("[{}] ", res); } } #[test] #[serial] fn notcurses_canfade() { unsafe { let nc = notcurses_init_test(); let res = crate::notcurses_canfade(nc); notcurses_stop(nc); print!("[{}] ", res); } } #[test] #[serial] fn notcurses_canopen_images() { unsafe { let nc = notcurses_init_test(); let res = crate::notcurses_canopen_images(nc); notcurses_stop(nc); print!("[{}] ", res); } } #[test] #[serial] fn notcurses_canopen_videos() { unsafe { let nc = notcurses_init_test(); let res = crate::notcurses_canopen_videos(nc); notcurses_stop(nc); print!("[{}] ", res); } } #[test] #[serial] fn notcurses_cansixel() { unsafe { let nc = notcurses_init_test(); let res = crate::notcurses_cansixel(nc); notcurses_stop(nc); print!("[{}] ", res); } } #[test] #[serial] fn notcurses_cansextant() { unsafe { let nc = notcurses_init_test(); let res = crate::notcurses_cansextant(nc); notcurses_stop(nc); print!("[{}] ", res); } } #[test] #[serial] fn notcurses_cantruecolor() { unsafe { let nc = notcurses_init_test(); let res = crate::notcurses_cantruecolor(nc); notcurses_stop(nc); print!("[{}] ", res); } } #[test] #[serial] fn notcurses_canutf8() { unsafe { let nc = notcurses_init_test(); let res = crate::notcurses_canutf8(nc); notcurses_stop(nc); print!("[{}] ", res); } } #[test] #[serial] fn notcurses_drop_planes() { unsafe { let nc = notcurses_init_test(); let stdplane = crate::notcurses_stdplane(nc); let plane1 = crate::ncplane_new_bound_test(&mut *stdplane, 0, 0, 10, 10); let _plane2 = crate::ncplane_new_bound_test(plane1, 0, 0, 10, 10); crate::notcurses_drop_planes(nc); // TODO: CHECK that planes are really dropped. notcurses_stop(nc); } } #[test] #[serial] fn notcurses_initialization() { unsafe { let nc = notcurses_init_test(); assert![nc as *mut _ != core::ptr::null_mut()]; notcurses_stop(nc); } } #[test] #[serial] #[ignore] // FIXME: always return null fn notcurses_at_yx() { unsafe { let nc = notcurses_init_test(); let mut sm = 0; let mut ch = 0; let res = crate::notcurses_at_yx(nc, 0, 0, &mut sm, &mut ch); notcurses_stop(nc); assert![!res.is_null()]; //print!("[{}] ", res); } } #[test] #[serial] fn notcurses_debug() { unsafe { let nc = notcurses_init_test(); let mut _p: *mut i8 = &mut 0; let mut _size: *mut usize = &mut 0; let mut file = NcFile::from_libc(libc::open_memstream(&mut _p, _size)); crate::notcurses_debug(nc, file.as_nc_ptr()); notcurses_stop(nc); let mut string1 = String::new(); let _result = file.read_to_string(&mut string1); let string2 = " -------------------------- notcurses debug state -----------------------------"; assert_eq![&string1[0..string2.len()], &string2[..]]; } } #[test] #[serial] // TODO test version_components fn notcurses_version() { let c_str = unsafe { crate::notcurses_version() }; assert!(!c_str.is_null()); print!("v{} ", crate::rstring![c_str]); } libnotcurses-sys-2.1.8/src/notcurses/wrapper.rs010064400017500001750000000074461377726434200201270ustar 00000000000000//! `FullMode` wrapper struct and traits implementations. use std::ops::{Deref, DerefMut}; use crate::{ raw_wrap, NcAlign, NcBlitter, NcDim, NcLogLevel, NcResult, NcScale, Notcurses, NotcursesOptions, }; /// Safe wrapper around [Notcurses], the main struct of the TUI library. pub struct FullMode<'a> { pub(crate) raw: &'a mut Notcurses, } impl<'a> AsRef for FullMode<'a> { fn as_ref(&self) -> &Notcurses { self.raw } } impl<'a> AsMut for FullMode<'a> { fn as_mut(&mut self) -> &mut Notcurses { self.raw } } impl<'a> Deref for FullMode<'a> { type Target = Notcurses; fn deref(&self) -> &Self::Target { self.as_ref() } } impl<'a> DerefMut for FullMode<'a> { fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut() } } impl<'a> Drop for FullMode<'a> { /// Destroys the FullMode context. fn drop(&mut self) { let _ = self.raw.stop(); } } /// # Constructors and methods overriden from Notcurses impl<'a> FullMode<'a> { // wrap constructors /// New FullMode (without banners). pub fn new() -> NcResult { raw_wrap![Notcurses::new()] } /// New FullMode, without banners. pub fn with_banners() -> NcResult { raw_wrap![Notcurses::with_banners()] } /// New FullMode, without an alternate screen (nor banners). pub fn without_altscreen() -> NcResult { raw_wrap![Notcurses::without_altscreen()] } /// New FullMode, expects `NCOPTION_*` flags. pub fn with_flags(flags: u64) -> NcResult { raw_wrap![Notcurses::with_flags(flags)] } /// New FullMode, expects [NotcursesOptions]. pub fn with_options(options: NotcursesOptions) -> NcResult { raw_wrap![Notcurses::with_options(options)] } /// New FullMode, expects [NcLogLevel] and flags. pub fn with_debug(loglevel: NcLogLevel, flags: u64) -> NcResult { raw_wrap![Notcurses::with_debug(loglevel, flags)] } // disable destructor /// Since FullMode already implements [Drop](#impl-Drop), /// this function is made no-op. pub fn stop(&mut self) -> NcResult<()> { Ok(()) } // wrap associated functions /// Returns the offset into `availcols` at which `cols` ought be output given /// the requirements of `align`. pub fn align(availcols: NcDim, align: NcAlign, cols: NcDim) -> NcResult<()> { Notcurses::align(availcols, align, cols) } /// Gets the name of an [NcBlitter] blitter. pub fn str_blitter(blitter: NcBlitter) -> String { Notcurses::str_blitter(blitter) } /// Gets the name of an [NcScale] scaling mode. pub fn str_scalemode(scalemode: NcScale) -> String { Notcurses::str_scalemode(scalemode) } /// Returns an [NcBlitter] from a string representation. pub fn lex_blitter(op: &str) -> NcResult { Notcurses::lex_blitter(op) } /// Lexes a margin argument according to the standard Notcurses definition. /// /// There can be either a single number, which will define all margins equally, /// or there can be four numbers separated by commas. /// pub fn lex_margins(op: &str, options: &mut NotcursesOptions) -> NcResult<()> { Notcurses::lex_margins(op, options) } /// Returns an [NcScale] from a string representation. pub fn lex_scalemode(op: &str) -> NcResult { Notcurses::lex_scalemode(op) } /// Returns a human-readable string describing the running FullMode version. pub fn version() -> String { Notcurses::version() } /// Returns the running Notcurses version components /// (major, minor, patch, tweak). pub fn version_components() -> (u32, u32, u32, u32) { Notcurses::version_components() } } libnotcurses-sys-2.1.8/src/palette/methods.rs010064400017500001750000000037341377726434200175170ustar 00000000000000//! `NcPalette` methods and associated functions. use crate::{error, NcChannel, NcColor, NcPalette, NcPaletteIndex, NcResult, NcRgb, Notcurses}; impl NcPalette { /// New NcPalette. /// /// *C style function: [palette256_new()][crate::palette256_new].* pub fn new<'a>(nc: &mut Notcurses) -> &'a mut Self { unsafe { &mut *crate::palette256_new(nc) } } /// Frees this NcPalette. /// /// *C style function: [palette256_free()][crate::palette256_free].* pub fn free(&mut self) { unsafe { crate::palette256_free(self); } } /// Attempts to configure the terminal with this NcPalette. /// /// *C style function: [palette256_use()][crate::palette256_use].* pub fn r#use(&self, nc: &mut Notcurses) -> NcResult<()> { error![unsafe { crate::palette256_use(nc, self) }] } /// Returns the [NcColor] RGB components from the [NcChannel] in this NcPalette. /// /// *C style function: [palette256_get_rgb()][crate::palette256_get_rgb].* pub fn get_rgb8(&self, index: NcPaletteIndex) -> (NcColor, NcColor, NcColor) { let (mut r, mut g, mut b) = (0, 0, 0); crate::channel_rgb8(self.chans[index as usize], &mut r, &mut g, &mut b); (r, g, b) } /// Extracts the [NcColor] RGB components from an [NcChannel] entry inside /// this NcPalette, and returns the NcChannel. /// /// *C style function: [palette256_get_rgb()][crate::palette256_get_rgb].* pub fn get_rgb(&self, index: NcPaletteIndex) -> NcChannel { let (mut r, mut g, mut b) = (0, 0, 0); crate::channel_rgb8(self.chans[index as usize], &mut r, &mut g, &mut b) } /// Sets the [NcRgb] value of the [NcChannel][crate::NcChannel] entry /// inside this NcPalette. /// /// *C style function: [palette256_set()][crate::palette256_set].* pub fn set(&mut self, index: NcPaletteIndex, rgb: NcRgb) { crate::channel_set(&mut self.chans[index as usize], rgb); } } libnotcurses-sys-2.1.8/src/palette/mod.rs010064400017500001750000000026451377156272500166330ustar 00000000000000//! `NcPalette*` // ----------------------------------------------------------------------------- // Now none of these functions can't fail and therefore don't return errors. // ----------------------------------------------------------------------------- // // functions already exported by bindgen : 3 // ----------------------------------------- // (#) test: 0 // (W) wrap: 3 / 0 // ----------------------------------------- //W palette256_free //W palette256_new //W palette256_use // // functions manually reimplemented: 3 // ----------------------------------------- // (+) done: 3 / 0 // (#) test: 0 // (W) wrap: 3 / 0 // ----------------------------------------- //W+ palette256_get_rgb //W+ palette256_set //W+ palette256_set_rgb mod methods; mod reimplemented; pub use methods::*; pub use reimplemented::*; /// NcPalette structure consisting of an array of 256 /// [`NcChannel`][crate::NcChannel]s. /// /// See also [NcPaletteIndex]. /// /// Some terminals only support 256 colors, but allow the full /// palette to be specified with arbitrary RGB colors. In all cases, it's more /// performant to use indexed colors, since it's much less data to write to the /// terminal. If you can limit yourself to 256 colors, that's probably best. /// /// `type in C: ncpalette256 (struct)` /// pub type NcPalette = crate::bindings::ffi::palette256; /// 8-bit value used for indexing into a [`NcPalette`] /// pub type NcPaletteIndex = u8; libnotcurses-sys-2.1.8/src/palette/reimplemented.rs010064400017500001750000000024301377156272500206760ustar 00000000000000//! `palette256_*` reimplemented functions. use crate::{NcChannel, NcColor, NcPalette, NcPaletteIndex, NcRgb}; /// Extracts the [NcColor] RGB components from an [NcChannel] entry inside /// an [NcPalette], and returns the NcChannel. /// /// *Method: NcPalette.[get_rgb()][NcPalette#method.get_rgb].* /// *Method: NcPalette.[get_rgb8()][NcPalette#method.get_rgb8].* #[inline] pub fn palette256_get_rgb( palette: &NcPalette, index: NcPaletteIndex, red: &mut NcColor, green: &mut NcColor, blue: &mut NcColor, ) -> NcChannel { crate::channel_rgb8(palette.chans[index as usize], red, green, blue) } /// Sets the [NcRgb] value of the [NcChannel] entry inside an [NcPalette]. /// /// *Method: NcPalette.[set()][NcPalette#method.set].* #[inline] pub fn palette256_set(palette: &mut NcPalette, index: NcPaletteIndex, rgb: NcRgb) { crate::channel_set(&mut palette.chans[index as usize], rgb); } /// Sets the [NcColor] components of the [NcChannel] entry inside an [NcPalette]. /// /// *Method: NcPalette.[set_rgb()][NcPalette#method.set_rgb].* #[inline] pub fn palette256_set_rgb( palette: &mut NcPalette, index: NcPaletteIndex, red: NcColor, green: NcColor, blue: NcColor, ) { crate::channel_set_rgb8(&mut palette.chans[index as usize], red, green, blue) } libnotcurses-sys-2.1.8/src/pixel.rs010064400017500001750000000134601377025637400155330ustar 00000000000000//! The ncpixel API facilitates direct management of the pixels within an //! ncvisual (ncvisuals keep a backing store of 32-bit RGBA pixels, and render //! them down to terminal graphics in ncvisual_render()). // // - NOTE: The pixel color & alpha components are u8 instead of u32. // Because of type enforcing, some runtime checks are now unnecessary. // // - NOTE: None of the functions can't fail anymore and don't have to return an error. // // functions manually reimplemented: 10 // ------------------------------------------ // (+) done: 10 / 0 // (#) test: 0 // (W) wrap: 10 // ------------------------------------------ //W+ ncpixel //W+ ncpixel_a //W+ ncpixel_b //W+ ncpixel_g //W+ ncpixel_r //W+ ncpixel_set_a //W+ ncpixel_set_b //W+ ncpixel_set_g //W+ ncpixel_set_r //W+ ncpixel_set_rgb8 use crate::NcColor; // NcPixel (RGBA) /// An ABGR pixel. /// /// ## Diagram /// /// ```txt /// AAAAAAAA GGGGGGGG BBBBBBBB RRRRRRRR /// ``` /// /// `type in C: ncpixel (uint32_t)` /// /// NcPixel has 8 bits of alpha, more or less linear, contributing /// directly to the usual alpha blending equation. /// /// We map the 8 bits of alpha to 2 bits of alpha via a [level /// function](https://nick-black.com/dankwiki/index.php?title=Notcurses#Transparency.2FContrasting) /// /// The ncpixel API facilitates direct management of the pixels within an /// ncvisual (ncvisuals keep a backing store of 32-bit RGBA pixels, and render /// them down to terminal graphics in ncvisual_render()). /// /// Per libav, we "store as BGRA on little-endian, and ARGB on big-endian". /// This is an RGBA *byte-order* scheme. libav emits bytes, not words. Those /// bytes are R-G-B-A. When read as words, on little endian this will be ABGR, /// and on big-endian this will be RGBA. force everything to LE ABGR. /// pub type NcPixel = u32; /// Constructs a libav-compatible ABGR pixel from [NcColor] RGB components. #[inline] pub const fn ncpixel(red: NcColor, green: NcColor, blue: NcColor) -> NcPixel { 0xff000000 as NcPixel | red as NcPixel | (blue as NcPixel) << 8 | (green as NcPixel) << 16 } /// Extracts the 8-bit alpha component from an ABGR pixel. #[inline] pub const fn ncpixel_a(pixel: NcPixel) -> NcColor { ((pixel.to_le() & 0xff000000) >> 24) as NcColor } /// Extracts the 8 bit blue component from an ABGR pixel. #[inline] pub const fn ncpixel_b(pixel: NcPixel) -> NcColor { ((pixel.to_le() & 0x00ff0000) >> 16) as NcColor } /// Extracts the 8 bit green component from an ABGR pixel. #[inline] pub const fn ncpixel_g(pixel: NcPixel) -> NcColor { ((pixel.to_le() & 0x0000ff00) >> 8) as NcColor } /// Extracts the 8 bit red component from an ABGR pixel. #[inline] pub const fn ncpixel_r(pixel: NcPixel) -> NcColor { (pixel.to_le() & 0x000000ff) as NcColor } /// Sets the 8-bit alpha component of an ABGR pixel. #[inline] pub fn ncpixel_set_a(pixel: &mut NcPixel, alpha: NcColor) { *pixel = (((*pixel).to_le() & 0x00ffffff) | ((alpha as NcPixel) << 24)).to_le(); } /// Sets the 8-bit blue component of an ABGR pixel. #[inline] pub fn ncpixel_set_b(pixel: &mut NcPixel, blue: NcColor) { *pixel = (((*pixel).to_le() & 0xffff00ff) | ((blue as NcPixel) << 8)).to_le(); } /// Sets the 8-bit green component of an ABGR pixel. #[inline] pub fn ncpixel_set_g(pixel: &mut NcPixel, green: NcColor) { *pixel = (((*pixel).to_le() & 0xff00ffff) | ((green as NcPixel) << 16)).to_le(); } /// Sets the 8-bit red component of an ABGR pixel. #[inline] pub fn ncpixel_set_r(pixel: &mut NcPixel, red: NcColor) { *pixel = (((*pixel).to_le() & 0xffffff00) | red as NcPixel).to_le(); } /// Sets the [NcColor] RGB components of an ABGR pixel. #[inline] pub fn ncpixel_set_rgb8(pixel: &mut NcPixel, red: NcColor, green: NcColor, blue: NcColor) { ncpixel_set_r(pixel, red); ncpixel_set_g(pixel, green); ncpixel_set_b(pixel, blue); } /// Enables the [NcPixel] methods. // // NOTE: waiting for: https://github.com/rust-lang/rust/issues/56546 // to move doc comments to the trait and appear unhidden at the implementation. pub trait NcPixelMethods { fn new(r: NcColor, g: NcColor, b: NcColor) -> NcPixel; fn a(self) -> NcColor; fn b(self) -> NcColor; fn g(self) -> NcColor; fn r(self) -> NcColor; fn set_a(&mut self, green: NcColor); fn set_b(&mut self, blue: NcColor); fn set_g(&mut self, green: NcColor); fn set_r(&mut self, red: NcColor); fn set_rgb8(&mut self, red: NcColor, green: NcColor, blue: NcColor); } impl NcPixelMethods for NcPixel { /// Constructs a libav-compatible ABGR pixel from [NcColor] RGB components. fn new(red: NcColor, green: NcColor, blue: NcColor) -> NcPixel { ncpixel(red, green, blue) } /// Extracts the 8-bit alpha component from an ABGR pixel. fn a(self) -> NcColor { ncpixel_a(self) } /// Extracts the 8 bit blue component from an ABGR pixel. fn b(self) -> NcColor { ncpixel_b(self) } /// Extracts the 8 bit green component from an ABGR pixel. fn g(self) -> NcColor { ncpixel_g(self) } /// Extracts the 8 bit red component from an ABGR pixel. fn r(self) -> NcColor { ncpixel_r(self) } /// Sets the 8-bit alpha component of an ABGR pixel. fn set_a(&mut self, alpha: NcColor) { ncpixel_set_a(self, alpha) } /// Sets the 8-bit green component of an ABGR pixel. fn set_g(&mut self, green: NcColor) { ncpixel_set_b(self, green) } /// Sets the 8-bit blue component of an ABGR pixel. fn set_b(&mut self, blue: NcColor) { ncpixel_set_b(self, blue) } /// Sets the 8-bit red component of an ABGR pixel. fn set_r(&mut self, red: NcColor) { ncpixel_set_r(self, red) } /// Sets the [NcColor] RGB components of an ABGR pixel. fn set_rgb8(&mut self, red: NcColor, green: NcColor, blue: NcColor) { ncpixel_set_rgb8(self, red, green, blue); } } libnotcurses-sys-2.1.8/src/plane/helpers.rs010064400017500001750000000013031377726434200171450ustar 00000000000000use crate::{NcDim, NcOffset, NcPlane, NcPlaneOptions, Notcurses}; /// Helper function for a new NcPlane on C style tests. #[allow(dead_code)] pub(crate) unsafe fn ncplane_new_test<'a>( nc: &mut Notcurses, y: NcOffset, x: NcOffset, rows: NcDim, cols: NcDim, ) -> &'a mut NcPlane { &mut *crate::ncpile_create(nc, &NcPlaneOptions::new(y, x, rows, cols)) } /// Helper function for a new bound NcPlane on C style tests. #[allow(dead_code)] pub(crate) unsafe fn ncplane_new_bound_test<'a>( plane: &mut NcPlane, y: NcOffset, x: NcOffset, rows: NcDim, cols: NcDim, ) -> &'a mut NcPlane { &mut *crate::ncplane_create(plane, &NcPlaneOptions::new(y, x, rows, cols)) } libnotcurses-sys-2.1.8/src/plane/methods.rs010064400017500001750000001763041377726434200171640ustar 00000000000000//! `NcPlane*` methods and associated functions. use core::ptr::{null, null_mut}; use crate::{ cstring, error, error_ref, error_ref_mut, rstring, NcAlign, NcAlphaBits, NcBoxMask, NcCell, NcChannel, NcChannelPair, NcColor, NcDim, NcEgc, NcError, NcFadeCb, NcOffset, NcPaletteIndex, NcPlane, NcPlaneOptions, NcResizeCb, NcResult, NcRgb, NcStyleMask, NcTime, Notcurses, NCRESULT_ERR, }; /// # NcPlaneOptions Constructors impl NcPlaneOptions { /// New NcPlaneOptions using the horizontal x. pub fn new(y: NcOffset, x: NcOffset, rows: NcDim, cols: NcDim) -> Self { Self::with_flags(y, x, rows, cols, None, 0) } /// New NcPlaneOptions with horizontal alignment. pub fn new_aligned(y: NcOffset, align: NcAlign, rows: NcDim, cols: NcDim) -> Self { Self::with_flags_aligned(y, align, rows, cols, None, crate::NCPLANE_OPTION_HORALIGNED) } /// New NcPlaneOptions, with flags. pub fn with_flags( y: NcOffset, x: NcOffset, rows: NcDim, cols: NcDim, resizecb: Option, flags: u64, ) -> Self { NcPlaneOptions { y: y as i32, x: x as i32, rows: rows as i32, cols: cols as i32, userptr: null_mut(), name: null(), resizecb: crate::ncresizecb_to_c(resizecb), flags, } } /// New NcPlaneOptions, with flags and horizontal alignment. /// /// Note: Already includes the /// [NCPLANE_OPTION_HORALIGNED][crate::NCPLANE_OPTION_HORALIGNED] flag. pub fn with_flags_aligned( y: NcOffset, align: NcAlign, rows: NcDim, cols: NcDim, resizecb: Option, flags: u64, ) -> Self { let flags = crate::NCPLANE_OPTION_HORALIGNED | flags; NcPlaneOptions { y: y as i32, x: align as i32, rows: rows as i32, cols: cols as i32, userptr: null_mut(), name: null(), resizecb: crate::ncresizecb_to_c(resizecb), flags, } } } /// # NcPlane constructors & destructors impl NcPlane { /// New NcPlane. /// /// The returned plane will be the top, bottom, and root of this new pile. /// /// *C style function: [ncpile_create()][crate::ncpile_create].* pub fn new<'a>( nc: &mut Notcurses, y: NcOffset, x: NcOffset, rows: NcDim, cols: NcDim, ) -> NcResult<&'a mut NcPlane> { Self::with_options(nc, NcPlaneOptions::new(y, x, rows, cols)) } /// New NcPlane, expects an [NcPlaneOptions] struct. /// /// The returned plane will be the top, bottom, and root of this new pile. /// /// *C style function: [ncpile_create()][crate::ncpile_create].* pub fn with_options<'a>( nc: &mut Notcurses, options: NcPlaneOptions, ) -> NcResult<&'a mut NcPlane> { error_ref_mut![ unsafe { crate::ncpile_create(nc, &options) }, &format!["NcPlane::with_options(Notcurses, {:?})", options] ] } /// New NcPlane, bound to another NcPlane. /// /// *C style function: [ncplane_create()][crate::ncplane_create].* pub fn new_bound<'a>( bound_to: &mut NcPlane, y: NcOffset, x: NcOffset, rows: NcDim, cols: NcDim, ) -> NcResult<&'a mut NcPlane> { Self::with_options_bound(bound_to, NcPlaneOptions::new(y, x, rows, cols)) } /// New NcPlane, bound to another plane, expects an [NcPlaneOptions] struct. /// /// *C style function: [ncplane_create()][crate::ncplane_create].* pub fn with_options_bound<'a>( bound_to: &mut NcPlane, options: NcPlaneOptions, ) -> NcResult<&'a mut NcPlane> { error_ref_mut![ unsafe { crate::ncplane_create(bound_to, &options) }, &format!("NcPlane::with_options_bound(NcPlane, {:?})", options) ] } /// New NcPlane, with the same dimensions of the terminal. /// /// The returned plane will be the top, bottom, and root of this new pile. /// /// *(No equivalent C style function)* pub fn with_termsize<'a>(nc: &mut Notcurses) -> NcResult<&'a mut NcPlane> { let (trows, tcols) = crate::notcurses_term_dim_yx(nc); assert![(trows > 0) & (tcols > 0)]; Self::with_options( nc, NcPlaneOptions::new(0, 0, trows as NcDim, tcols as NcDim), ) } /// Destroys this NcPlane. /// /// None of its contents will be visible after the next render call. /// It is an error to attempt to destroy the standard plane. /// /// *C style function: [ncplane_destroy()][crate::ncplane_destroy].* pub fn destroy(&mut self) -> NcResult<()> { error![unsafe { crate::ncplane_destroy(self) }, "NcPlane.destroy()"] } } // ----------------------------------------------------------------------------- /// ## NcPlane methods: `NcAlphaBits` impl NcPlane { /// Gets the foreground [NcAlphaBits] from this NcPlane, shifted to LSBs. /// /// *C style function: [ncplane_fg_alpha()][crate::ncplane_fg_alpha].* #[inline] pub fn fg_alpha(&self) -> NcAlphaBits { crate::channels_fg_alpha(unsafe { crate::ncplane_channels(self) }) } /// Gets the background [NcAlphaBits] for this NcPlane, shifted to LSBs. /// /// *C style function: [ncplane_bg_alpha()][crate::ncplane_bg_alpha].* #[inline] pub fn bg_alpha(&self) -> NcAlphaBits { crate::channels_bg_alpha(unsafe { crate::ncplane_channels(self) }) } /// Sets the foreground [NcAlphaBits] from this NcPlane. /// /// *C style function: [ncplane_set_fg_alpha()][crate::ncplane_set_fg_alpha].* pub fn set_fg_alpha(&mut self, alpha: NcAlphaBits) -> NcResult<()> { error![ unsafe { crate::ncplane_set_fg_alpha(self, alpha as i32) }, &format!("NcPlane.set_fg_alpha({:0X})", alpha) ] } /// Sets the background [NcAlphaBits] for this NcPlane. /// /// *C style function: [ncplane_set_bg_alpha()][crate::ncplane_set_bg_alpha].* pub fn set_bg_alpha(&mut self, alpha: NcAlphaBits) -> NcResult<()> { error![ unsafe { crate::ncplane_set_bg_alpha(self, alpha as i32) }, &format!("NcPlane.set_bg_alpha({:0X})", alpha) ] } } // ----------------------------------------------------------------------------- /// ## NcPlane methods: `NcChannel` impl NcPlane { /// Gets the current [NcChannelPair] from this NcPlane. /// /// *C style function: [ncplane_channels()][crate::ncplane_channels].* pub fn channels(&self) -> NcChannelPair { unsafe { crate::ncplane_channels(self) } } /// Gets the foreground [NcChannel] from an [NcPlane]. /// /// *C style function: [ncplane_fchannel()][crate::ncplane_fchannel].* #[inline] pub fn fchannel(&self) -> NcChannel { crate::channels_fchannel(unsafe { crate::ncplane_channels(self) }) } /// Gets the background [NcChannel] from an [NcPlane]. /// /// *C style function: [ncplane_bchannel()][crate::ncplane_bchannel].* #[inline] pub fn bchannel(&self) -> NcChannel { crate::channels_bchannel(unsafe { crate::ncplane_channels(self) }) } /// Sets the current [NcChannelPair] for this NcPlane. /// /// *C style function: [ncplane_set_channels()][crate::ncplane_set_channels].* pub fn set_channels(&mut self, channels: NcChannelPair) { unsafe { crate::ncplane_set_channels(self, channels) } } /// Sets the current foreground [NcChannel] for this NcPlane. /// Returns the updated [NcChannelPair]. /// /// *C style function: [ncplane_set_fchannel()][crate::ncplane_set_fchannel].* pub fn set_fchannel(&mut self, channel: NcChannel) -> NcChannelPair { unsafe { crate::ncplane_set_fchannel(self, channel) } } /// Sets the current background [NcChannel] for this NcPlane. /// Returns the updated [NcChannelPair]. /// /// *C style function: [ncplane_set_bchannel()][crate::ncplane_set_bchannel].* pub fn set_bchannel(&mut self, channel: NcChannel) -> NcChannelPair { unsafe { crate::ncplane_set_bchannel(self, channel) } } /// Sets the given [NcChannelPair]s throughout the specified region, /// keeping content and attributes unchanged. /// /// Returns the number of cells set. /// /// *C style function: [ncplane_stain()][crate::ncplane_stain].* pub fn stain( &mut self, y_stop: NcDim, x_stop: NcDim, ul: NcChannelPair, ur: NcChannelPair, ll: NcChannelPair, lr: NcChannelPair, ) -> NcResult { let res = unsafe { crate::ncplane_stain(self, y_stop as i32, x_stop as i32, ul, ur, ll, lr) }; error![ res, &format!( "NcPlane.stain({}, {}, {:0X}, {:0X}, {:0X}, {:0X})", y_stop, x_stop, ul, ur, ll, lr ), res as u32 ] } } // ----------------------------------------------------------------------------- /// ## NcPlane methods: `NcColor`, `NcRgb` & default color impl NcPlane { /// Gets the foreground [NcColor] RGB components from this NcPlane. /// /// *C style function: [ncplane_fg_rgb8()][crate::ncplane_fg_rgb8].* #[inline] pub fn fg_rgb8(&self) -> (NcColor, NcColor, NcColor) { let (mut r, mut g, mut b) = (0, 0, 0); let _ = crate::channels_fg_rgb8( unsafe { crate::ncplane_channels(self) }, &mut r, &mut g, &mut b, ); (r, g, b) } /// Gets the background [NcColor] RGB components from this NcPlane. /// /// *C style function: [ncplane_bg_rgb8()][crate::ncplane_bg_rgb8].* #[inline] pub fn bg_rgb8(&self) -> (NcColor, NcColor, NcColor) { let (mut r, mut g, mut b) = (0, 0, 0); let _ = crate::channels_bg_rgb8( unsafe { crate::ncplane_channels(self) }, &mut r, &mut g, &mut b, ); (r, g, b) } /// Sets the foreground [NcColor] RGB components for this NcPlane. /// /// If the terminal does not support directly-specified 3x8b cells /// (24-bit "TrueColor", indicated by the "RGB" terminfo capability), /// the provided values will be interpreted in some lossy fashion. /// /// "HP-like" terminals require setting foreground and background at the same /// time using "color pairs"; Notcurses will manage color pairs transparently. /// /// *C style function: [ncplane_set_fg_rgb8()][crate::ncplane_set_fg_rgb8].* pub fn set_fg_rgb8(&mut self, red: NcColor, green: NcColor, blue: NcColor) { unsafe { // Can't fail because of type enforcing. let _ = crate::ncplane_set_fg_rgb8(self, red as i32, green as i32, blue as i32); } } /// Sets the background [NcColor] RGB components for this NcPlane. /// /// If the terminal does not support directly-specified 3x8b cells /// (24-bit "TrueColor", indicated by the "RGB" terminfo capability), /// the provided values will be interpreted in some lossy fashion. /// /// "HP-like" terminals require setting foreground and background at the same /// time using "color pairs"; Notcurses will manage color pairs transparently. /// /// *C style function: [ncplane_set_bg_rgb8()][crate::ncplane_set_bg_rgb8].* pub fn set_bg_rgb8(&mut self, red: NcColor, green: NcColor, blue: NcColor) { unsafe { // Can't fail because of type enforcing. let _ = crate::ncplane_set_bg_rgb8(self, red as i32, green as i32, blue as i32); } } /// Gets the foreground [NcRgb] from this NcPlane, shifted to LSBs. /// /// *C style function: [ncplane_fg_rgb()][crate::ncplane_fg_rgb].* #[inline] pub fn fg_rgb(&self) -> NcRgb { crate::channels_fg_rgb(unsafe { crate::ncplane_channels(self) }) } /// Gets the background [NcRgb] from this NcPlane, shifted to LSBs. /// /// *C style function: [ncplane_bg_rgb()][crate::ncplane_bg_rgb].* #[inline] pub fn bg_rgb(&self) -> NcRgb { crate::channels_bg_rgb(unsafe { crate::ncplane_channels(self) }) } /// Sets the foreground [NcRgb] for this NcPlane. /// /// *C style function: [ncplane_set_fg_rgb()][crate::ncplane_set_fg_rgb].* #[inline] pub fn set_fg_rgb(&mut self, rgb: NcRgb) { unsafe { crate::ncplane_set_fg_rgb(self, rgb); } } /// Sets the backround [NcRgb] for this NcPlane. /// /// *C style function: [ncplane_set_bg_rgb()][crate::ncplane_set_bg_rgb].* #[inline] pub fn set_bg_rgb(&mut self, rgb: NcRgb) { unsafe { crate::ncplane_set_bg_rgb(self, rgb); } } /// Is this NcPlane's foreground using the "default foreground color"? /// /// *C style function: [ncplane_fg_default_p()][crate::ncplane_fg_default_p].* #[inline] pub fn fg_default_p(&self) -> bool { crate::channels_fg_default_p(unsafe { crate::ncplane_channels(self) }) } /// Is this NcPlane's background using the "default background color"? /// /// *C style function: [ncplane_bg_default_p()][crate::ncplane_bg_default_p].* #[inline] pub fn bg_default_p(&self) -> bool { crate::channels_bg_default_p(unsafe { crate::ncplane_channels(self) }) } /// Uses the default color for the foreground. /// /// *C style function: [ncplane_set_fg_default()][crate::ncplane_set_fg_default].* #[inline] pub fn set_fg_default(&mut self) { unsafe { crate::ncplane_set_fg_default(self); } } /// Uses the default color for the background. /// /// *C style function: [ncplane_set_bg_default()][crate::ncplane_set_bg_default].* #[inline] pub fn set_bg_default(&mut self) { unsafe { crate::ncplane_set_bg_default(self); } } } // ----------------------------------------------------------------------------- /// ## NcPlane methods: `NcStyleMask` & `PaletteIndex` impl NcPlane { /// Sets the given style throughout the specified region, keeping content /// and channels unchanged. /// /// Returns the number of cells set. /// /// *C style function: [ncplane_format()][crate::ncplane_format].* pub fn format( &mut self, y_stop: NcDim, x_stop: NcDim, stylemask: NcStyleMask, ) -> NcResult { let res = unsafe { crate::ncplane_format(self, y_stop as i32, x_stop as i32, stylemask as u32) }; error![ res, &format!("NcPlane.format({}, {}, {:0X})", y_stop, x_stop, stylemask), res as u32 ] } /// Returns the current styling for this NcPlane. /// /// *C style function: [ncplane_styles()][crate::ncplane_styles].* pub fn styles(&self) -> NcStyleMask { unsafe { crate::ncplane_styles(self) } } /// Removes the specified styles from this NcPlane's existing spec. /// /// *C style function: [ncplane_off_styles()][crate::ncplane_off_styles].* pub fn off_styles(&mut self, stylemask: NcStyleMask) { unsafe { crate::ncplane_off_styles(self, stylemask as u32); } } /// Adds the specified styles to this NcPlane's existing spec. /// /// *C style function: [ncplane_on_styles()][crate::ncplane_on_styles].* pub fn on_styles(&mut self, stylemask: NcStyleMask) { unsafe { crate::ncplane_on_styles(self, stylemask as u32); } } /// Sets just the specified styles for this NcPlane. /// /// *C style function: [ncplane_set_styles()][crate::ncplane_set_styles].* pub fn set_styles(&mut self, stylemask: NcStyleMask) { unsafe { crate::ncplane_set_styles(self, stylemask as u32); } } /// Sets this NcPlane's foreground [NcPaletteIndex]. /// /// Also sets the foreground palette index bit, sets it foreground-opaque, /// and clears the foreground default color bit. /// /// *C style function: [ncplane_set_fg_palindex()][crate::ncplane_set_fg_palindex].* pub fn set_fg_palindex(&mut self, palindex: NcPaletteIndex) { unsafe { crate::ncplane_set_fg_palindex(self, palindex as i32); } } /// Sets this NcPlane's background [NcPaletteIndex]. /// /// Also sets the background palette index bit, sets it background-opaque, /// and clears the background default color bit. /// /// *C style function: [ncplane_set_bg_palindex()][crate::ncplane_set_bg_palindex].* pub fn set_bg_palindex(&mut self, palindex: NcPaletteIndex) { unsafe { crate::ncplane_set_bg_palindex(self, palindex as i32); } } } // ----------------------------------------------------------------------------- /// ## NcPlane methods: `NcCell` & `NcEgc` impl NcPlane { /// Retrieves the current contents of the [NcCell] under the cursor, /// returning the [NcEgc] and writing out the [NcStyleMask] and the [NcChannelPair]. /// /// This NcEgc must be freed by the caller. /// /// *C style function: [ncplane_at_cursor()][crate::ncplane_at_cursor].* pub fn at_cursor( &mut self, stylemask: &mut NcStyleMask, channels: &mut NcChannelPair, ) -> NcResult { let egc = unsafe { crate::ncplane_at_cursor(self, stylemask, channels) }; if egc.is_null() { return Err(NcError::with_msg( NCRESULT_ERR, &format!("NcPlane.at_cursor({:0X}, {:0X})", stylemask, channels), )); } let egc = core::char::from_u32(unsafe { *egc } as u32).expect("wrong char"); Ok(egc) } /// Retrieves the current contents of the [NcCell] under the cursor /// into `cell`. Returns the number of bytes in the [NcEgc]. /// /// This NcCell is invalidated if the associated NcPlane is destroyed. /// /// *C style function: [ncplane_at_cursor_cell()][crate::ncplane_at_cursor_cell].* #[inline] pub fn at_cursor_cell(&mut self, cell: &mut NcCell) -> NcResult { let bytes = unsafe { crate::ncplane_at_cursor_cell(self, cell) }; error![ bytes, &format!("NcPlane.at_cursor_cell({:?})", cell), bytes as u32 ] } /// Retrieves the current contents of the specified [NcCell], returning the /// [NcEgc] and writing out the [NcStyleMask] and the [NcChannelPair]. /// /// This NcEgc must be freed by the caller. /// /// *C style function: [ncplane_at_yx()][crate::ncplane_at_yx].* pub fn at_yx( &mut self, y: NcDim, x: NcDim, stylemask: &mut NcStyleMask, channels: &mut NcChannelPair, ) -> NcResult { let egc = unsafe { crate::ncplane_at_yx(self, y as i32, x as i32, stylemask, channels) }; if egc.is_null() { return Err(NcError::with_msg( NCRESULT_ERR, &format!( "NcPlane.at_yx({}, {}, {:0X}, {:0X})", y, x, stylemask, channels ), )); } let egc = core::char::from_u32(unsafe { *egc } as u32).expect("wrong char"); Ok(egc) } /// Retrieves the current contents of the specified [NcCell] into `cell`. /// Returns the number of bytes in the [NcEgc]. /// /// This NcCell is invalidated if the associated plane is destroyed. /// /// *C style function: [ncplane_at_yx_cell()][crate::ncplane_at_yx_cell].* #[inline] pub fn ncplane_at_yx_cell(&mut self, y: NcDim, x: NcDim, cell: &mut NcCell) -> NcResult { let bytes = unsafe { crate::ncplane_at_yx_cell(self, y as i32, x as i32, cell) }; error![ bytes, &format!("NcPlane.at_yx_cell({}, {}, {:?})", y, x, cell), bytes as u32 ] } /// Extracts this NcPlane's base [NcCell] into `cell`. /// /// The reference is invalidated if this NcPlane is destroyed. /// /// *C style function: [ncplane_base()][crate::ncplane_base].* pub fn base(&mut self) -> NcResult { let mut cell = NcCell::new(); let res = unsafe { crate::ncplane_base(self, &mut cell) }; error![res, "NcPlane.base()", cell] } /// Sets this NcPlane's base [NcCell] from its components. /// /// It will be used for purposes of rendering anywhere that the NcPlane's /// gcluster is 0. /// /// Erasing the NcPlane does not reset the base cell. /// /// *C style function: [ncplane_set_base()][crate::ncplane_set_base].* // call stack: // - ncplane_set_base calls cell_prime: // return cell_prime(ncp, &ncp->basecell, egc, stylemask, channels); // - cell_prime calls notcurses.c/cell_load: // return cell_load(n, c, gcluster); // - cell-load calls internal.h/pool load: // return pool_load(&n->pool, c, gcluster); pub fn set_base( &mut self, egc: &str, stylemask: NcStyleMask, channels: NcChannelPair, ) -> NcResult { let res = unsafe { crate::ncplane_set_base(self, cstring![egc], stylemask as u32, channels) }; error![ res, &format!( "NcPlane.set_base({:?}, {:0X}, {:0X})", egc, stylemask, channels ), res as u32 ] } /// Sets this NcPlane's base NcCell. /// /// It will be used for purposes of rendering anywhere that the NcPlane's /// gcluster is 0. /// /// Erasing the NcPlane does not reset the base cell. /// /// *C style function: [ncplane_set_base_cell()][crate::ncplane_set_base_cell].* pub fn set_base_cell(&mut self, cell: &NcCell) -> NcResult<()> { error![ unsafe { crate::ncplane_set_base_cell(self, cell) }, &format!("NcPlane.base({:?})", cell) ] } /// Creates a flat string from the NcEgc's of the selected region of the /// NcPlane. /// /// Starts at the plane's `beg_y` * `beg_x` coordinates (which must lie on /// the plane), continuing for `len_y` x `len_x` cells. /// /// If either `through_y` or `through_x` are true, then `len_y` or `len_x`, /// will be respectively ignored, and will go through the boundary of the plane. /// /// *C style function: [ncplane_contents()][crate::ncplane_contents].* pub fn contents( &self, beg_y: NcDim, beg_x: NcDim, len_y: NcDim, len_x: NcDim, through_y: bool, through_x: bool, ) -> String { let (mut len_y, mut len_x) = (len_y as i32, len_x as i32); if through_y { len_y = -1; } if through_x { len_x = -1; } rstring![crate::ncplane_contents( self, beg_y as i32, beg_x as i32, len_y, len_x )] .to_string() } /// Erases every NcCell in this NcPlane, resetting all attributes to normal, /// all colors to the default color, and all cells to undrawn. /// /// All cells associated with this NcPlane are invalidated, and must not be /// used after the call, excluding the base cell. The cursor is homed. /// /// *C style function: [ncplane_erase()][crate::ncplane_erase].* pub fn erase(&mut self) { unsafe { crate::ncplane_erase(self); } } /// Replaces the NcCell at the specified coordinates with the provided NcCell, /// advancing the cursor by its width (but not past the end of the plane). /// /// The new NcCell must already be associated with the Plane. /// On success, returns the number of columns the cursor was advanced. /// /// *C style function: [ncplane_putc_yx()][crate::ncplane_putc_yx].* pub fn putc_yx(&mut self, y: NcDim, x: NcDim, cell: &NcCell) -> NcResult { let res = unsafe { crate::ncplane_putc_yx(self, y as i32, x as i32, cell) }; error![ res, &format!("NcPlane.putc_yx({}, {}, {:?})", y, x, cell), res as NcDim ] } /// Replaces the NcCell at the current coordinates with the provided NcCell, /// advancing the cursor by its width (but not past the end of the plane). /// /// The new NcCell must already be associated with the Plane. /// On success, returns the number of columns the cursor was advanced. /// /// *C style function: [ncplane_putc()][crate::ncplane_putc].* pub fn putc(&mut self, cell: &NcCell) -> NcResult { let res = crate::ncplane_putc(self, cell); error![res, &format!("NcPlane.putc({:?})", cell), res as NcDim] } /// Calls [putchar_yx][NcPlane#method.putchar_yx] at the current cursor location. /// /// On success, returns the number of columns the cursor was advanced. /// /// *C style function: [ncplane_putchar()][crate::ncplane_putchar].* pub fn putchar(&mut self, ch: char) -> NcResult { let res = crate::ncplane_putchar(self, ch); error![res, &format!("NcPlane.putchar({:?})", ch), res as NcDim] } // TODO: call put_egc // /// Replaces the [NcEgc][crate::NcEgc] to the current location, but retain // /// the styling. The current styling of the plane will not be changed. // pub fn putchar_stained(&mut self, y: NcDim, x: NcDim, ch: char) -> // NcResult { // error![crate::ncplane_putchar_stained(self, ch)] // } /// Replaces the [NcEgc][crate::NcEgc], but retain the styling. /// The current styling of the plane will not be changed. /// /// On success, returns the number of columns the cursor was advanced. /// /// *C style function: [ncplane_putchar_yx()][crate::ncplane_putchar_yx].* pub fn putchar_yx(&mut self, y: NcDim, x: NcDim, ch: char) -> NcResult { let res = crate::ncplane_putchar_yx(self, y, x, ch); error![ res, &format!("NcPlane.putchar_yx({}, {}, {:?})", y, x, ch), res as NcDim ] } /// Writes a series of [NcEgc][crate::NcEgc]s to the current location, /// using the current style. /// /// Advances the cursor by some positive number of columns /// (though not beyond the end of the plane), /// and this number is returned on success. /// /// On error, a non-positive number is returned, indicating /// the number of columns which were written before the error. /// /// *C style function: [ncplane_putstr()][crate::ncplane_putstr].* #[inline] pub fn putstr(&mut self, string: &str) -> NcResult { let res = crate::ncplane_putstr(self, string); error![res, &format!("NcPlane.putstr({:?})", string), res as NcDim] } /// Same as [putstr][NcPlane#method.putstr], but it also tries to move the /// cursor to the beginning of the next row. /// /// Advances the cursor by some positive number of columns (though not beyond /// the end of the plane); this number is returned on success. /// /// On error, a non-positive number is returned, indicating the number of /// columns which were written before the error. /// /// *(No equivalent C style function)* pub fn putstrln(&mut self, string: &str) -> NcResult { let cols = self.putstr(string)?; let (y, _x) = self.cursor_yx(); self.cursor_move_yx(y + 1, 0)?; return Ok(cols); } /// Same as [putstr_yx()][NcPlane#method.putstr_yx] but [NcAlign]ed on x. /// /// *C style function: [ncplane_putstr_aligned()][crate::ncplane_putstr_aligned].* pub fn putstr_aligned(&mut self, y: NcDim, align: NcAlign, string: &str) -> NcResult { let res = unsafe { crate::ncplane_putstr_aligned(self, y as i32, align, cstring![string]) }; error![ res, &format!("NcPlane.putstr_aligned({}, {}, {:?})", y, align, string), res as NcDim ] } /// Writes a series of [NcEgc][crate::NcEgc]s to the current location, but /// retain the styling. /// The current styling of the plane will not be changed. /// /// Advances the cursor by some positive number of columns (though not beyond /// the end of the plane); this number is returned on success. /// /// On error, a non-positive number is returned, indicating the number of /// columns which were written before the error. /// /// *C style function: [ncplane_putstr_stained()][crate::ncplane_putstr_stained].* pub fn putstr_stained(&mut self, string: &str) -> NcResult { let res = unsafe { crate::ncplane_putstr_stained(self, cstring![string]) }; error![ res, &format!("NcPlane.putstr_stained({:?})", string), res as NcDim ] } /// Write a string, which is a series of [NcEgc][crate::NcEgc]s, to the /// current location, using the current style. /// /// They will be interpreted as a series of columns. /// /// Advances the cursor by some positive number of columns (though not /// beyond the end of the plane); this number is returned on success. /// /// On error, a non-positive number is returned, indicating the number of /// columns which were written before the error. /// /// *C style function: [ncplane_putstr_yx()][crate::ncplane_putstr_yx].* pub fn putstr_yx(&mut self, y: NcDim, x: NcDim, string: &str) -> NcResult { let res = unsafe { crate::ncplane_putstr_yx(self, y as i32, x as i32, cstring![string]) }; error![ res, &format!("NcPlane.putstr_yx({}, {}, {:?})", y, x, string), res as NcDim ] } } // ----------------------------------------------------------------------------- /// ## NcPlane methods: `NcPlane` & `Notcurses` impl NcPlane { /// Duplicates this NcPlane. /// /// The new NcPlane will have the same geometry, the same rendering state, /// and all the same duplicated content. /// /// The new plane will be immediately above the old one on the z axis, /// and will be bound to the same parent. Bound planes are not duplicated; /// the new plane is bound to the current parent, but has no bound planes. /// /// *C style function: [ncplane_dup()][crate::ncplane_dup].* // // TODO: deal with the opaque field. pub fn dup<'a>(&'a mut self) -> &'a mut NcPlane { unsafe { &mut *crate::ncplane_dup(self, null_mut()) } } /// Returns the topmost NcPlane of the current pile. /// /// *C style function: [ncpile_top()][crate::ncpile_top].* pub fn top<'a>(&mut self) -> &'a mut NcPlane { unsafe { &mut *crate::ncpile_top(self) } } /// Returns the bottommost NcPlane of the current pile. /// /// *C style function: [ncpile_bottom()][crate::ncpile_bottom].* pub fn bottom<'a>(&mut self) -> &'a mut NcPlane { unsafe { &mut *crate::ncpile_bottom(self) } } /// Relocates this NcPlane at the top of the z-buffer. /// /// *C style function: [ncplane_move_top()][crate::ncplane_move_top].* pub fn move_top(&mut self) { unsafe { crate::ncplane_move_top(self); } } /// Relocates this NcPlane at the bottom of the z-buffer. /// /// *C style function: [ncplane_move_bottom()][crate::ncplane_move_bottom].* pub fn move_bottom(&mut self) { unsafe { crate::ncplane_move_bottom(self); } } /// Moves this NcPlane relative to the standard plane, or the plane to /// which it is bound. /// /// It is an error to attempt to move the standard plane. /// /// *C style function: [ncplane_move_yx()][crate::ncplane_move_yx].* // // CHECK: whether a negative offset is valid pub fn move_yx(&mut self, y: NcOffset, x: NcOffset) -> NcResult<()> { error![ unsafe { crate::ncplane_move_yx(self, y, x) }, &format!("NcPlane.move_yx({}, {})", y, x) ] } /// Returns the NcPlane above this one, or None if already at the top. /// /// *C style function: [ncplane_above()][crate::ncplane_above].* pub fn above<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> { error_ref_mut![unsafe { crate::ncplane_above(self) }, "NcPlane.above()"] } /// Returns the NcPlane below this one, or None if already at the bottom. /// /// *C style function: [ncplane_below()][crate::ncplane_below].* pub fn below<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> { error_ref_mut![unsafe { crate::ncplane_below(self) }, "NcPlane.below()"] } /// Relocates this NcPlane above the `above` NcPlane, in the z-buffer. /// /// Returns [NCRESULT_ERR] if the current plane is /// already in the desired location. Both planes must not be the same. /// /// *C style function: [ncplane_move_above()][crate::ncplane_move_above].* pub fn move_above(&mut self, above: &mut NcPlane) -> NcResult<()> { error![ unsafe { crate::ncplane_move_above(self, above) }, "NcPlane.move_above(NcPlane)" ] } /// Relocates this NcPlane below the `below` NcPlane, in the z-buffer. /// /// Returns [NCRESULT_ERR] if the current plane is /// already in the desired location. Both planes must not be the same. /// /// *C style function: [ncplane_move_below()][crate::ncplane_move_below].* pub fn move_below(&mut self, below: &mut NcPlane) -> NcResult<()> { error![ unsafe { crate::ncplane_move_below(self, below) }, "NcPlane.move_below(NcPlane)" ] } /// Merges `source` down onto this NcPlane. /// /// Merging is independent of the position of both NcPlanes on the z-axis. /// /// It is an error to define a subregion of zero area, or that is not /// entirely contained within `source`. /// /// It is an error to define a target origin such that the projected /// subregion is not entirely contained within 'dst'. /// /// Behavior is undefined if both NcPlanes are equivalent. /// /// *C style function: [ncplane_mergedown()][crate::ncplane_mergedown].* pub fn mergedown( &mut self, source: &NcPlane, source_y: NcDim, source_x: NcDim, len_y: NcDim, len_x: NcDim, target_y: NcDim, target_x: NcDim, ) -> NcResult<()> { error![ unsafe { crate::ncplane_mergedown( source, self, source_y as i32, source_x as i32, len_y as i32, len_x as i32, target_y as i32, target_x as i32, ) }, &format!( "NcPlane.mergedown(NcPlane, {}, {}, {}, {}, {}, {})", source_y, source_x, len_y, len_x, target_y, target_x ) ] } /// Merges `source` down onto this NcPlane. /// /// If `source` does not intersect, this plane will not be changed, /// but it is not an error. /// /// See [`mergedown`][NcPlane#method.mergedown] /// for more information. /// /// *C style function: [ncplane_mergedown_simple()][crate::ncplane_mergedown_simple].* // // TODO: maybe create a reversed method, and/or an associated function, // for `mergedown` too. pub fn mergedown_simple(&mut self, source: &NcPlane) -> NcResult<()> { error![ unsafe { crate::ncplane_mergedown_simple(source, self) }, "NcPlane.mergedown_simple(NcPlane)" ] } /// Gets the parent to which this NcPlane is bound, if any. /// /// *C style function: [ncplane_parent()][crate::ncplane_parent].* // // TODO: CHECK: what happens when it's bound to itself. pub fn parent<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> { error_ref_mut![unsafe { crate::ncplane_parent(self) }, "NcPlane.parent()"] } /// Gets the parent to which this NcPlane is bound, if any. /// /// *C style function: [ncplane_parent_const()][crate::ncplane_parent_const].* // // CHECK: what happens when it's bound to itself. pub fn parent_const<'a>(&'a self) -> NcResult<&'a NcPlane> { error_ref![ unsafe { crate::ncplane_parent_const(self) }, "NcPlane.parent_const()" ] } /// Unbounds this NcPlane from its parent, makes it a bound child of /// 'newparent', and returns itself. /// /// Any planes bound to this NcPlane are reparented to the previous parent. /// /// If this NcPlane is equal to `newparent`, then becomes the root of a new /// pile, unless it is already the root of a pile, in which case this is a /// no-op. /// /// The standard plane cannot be reparented. /// /// *C style function: [ncplane_reparent()][crate::ncplane_reparent].* pub fn reparent<'a>(&mut self, newparent: &'a mut NcPlane) -> NcResult<&'a mut NcPlane> { error_ref_mut![ unsafe { crate::ncplane_reparent(self, newparent) }, "NcPlane.reparent(NcPlane)" ] } /// Like [`reparent`][NcPlane#method.reparent], except any bound /// planes comes along with this NcPlane to its new destination. /// /// Their z-order is maintained. /// /// *C style function: [ncplane_reparent_family()][crate::ncplane_reparent_family].* // // TODO:CHECK: If 'newparent' is an ancestor, NULL is returned & no changes're made. pub fn reparent_family<'a>(&mut self, newparent: &'a mut NcPlane) -> NcResult<&'a mut NcPlane> { error_ref_mut![ unsafe { crate::ncplane_reparent_family(self, newparent) }, "NcPlane.reparent_family(NcPlane)" ] } /// Makes the physical screen match the last rendered frame from the pile of /// which this NcPlane is a part. /// /// This is a blocking call. Don't call this before the pile has been /// rendered (doing so will likely result in a blank screen). /// /// *C style function: [ncpile_rasterize()][crate::ncpile_rasterize].* pub fn rasterize<'a>(&mut self) -> NcResult<()> { error![ unsafe { crate::ncpile_rasterize(self) }, "NcPlane.rasterize()" ] } /// Renders the pile of which this NcPlane is a part. /// Rendering this pile again will blow away the render. /// To actually write out the render, call ncpile_rasterize(). /// /// *C style function: [ncpile_render()][crate::ncpile_render].* pub fn render<'a>(&mut self) -> NcResult<()> { error![unsafe { crate::ncpile_render(self) }, "NcPlane.render()"] } /// Gets a mutable reference to the [Notcurses] context of this NcPlane. /// /// *C style function: [ncplane_notcurses()][crate::ncplane_notcurses].* pub fn notcurses<'a>(&mut self) -> NcResult<&'a mut Notcurses> { error_ref_mut![ unsafe { crate::ncplane_notcurses(self) }, "NcPlane.notcurses()" ] } /// Gets an immutable reference to the [Notcurses] context of this NcPlane. /// /// *C style function: [ncplane_notcurses_const()][crate::ncplane_notcurses_const].* pub fn notcurses_const<'a>(&self) -> NcResult<&'a Notcurses> { error_ref![ unsafe { crate::ncplane_notcurses_const(self) }, "NcPlane.notcurses()" ] } } // ----------------------------------------------------------------------------- /// ## NcPlane methods: cursor impl NcPlane { /// Moves the cursor to 0, 0. /// /// *C style function: [ncplane_home()][crate::ncplane_home].* pub fn home(&mut self) { unsafe { crate::ncplane_home(self); } } /// Returns the current position of the cursor within this NcPlane. /// /// *C style function: [ncplane_cursor_yx()][crate::ncplane_cursor_yx].* // // NOTE: y and/or x may be NULL. // check for null and return NcResult pub fn cursor_yx(&self) -> (NcDim, NcDim) { let (mut y, mut x) = (0, 0); unsafe { crate::ncplane_cursor_yx(self, &mut y, &mut x) }; (y as NcDim, x as NcDim) } /// Returns the current row of the cursor within this NcPlane. /// /// *(No equivalent C style function)* pub fn cursor_y(&self) -> NcDim { self.cursor_yx().0 } /// Returns the current column of the cursor within this NcPlane. /// /// *(No equivalent C style function)* pub fn cursor_x(&self) -> NcDim { self.cursor_yx().1 } /// Moves the cursor to the specified position within this NcPlane. /// /// The cursor doesn't need to be visible. /// /// Parameters exceeding the plane's dimensions will result in an error, /// and the cursor position will remain unchanged. /// /// *C style function: [ncplane_cursor_move_yx()][crate::ncplane_cursor_move_yx].* pub fn cursor_move_yx(&mut self, y: NcDim, x: NcDim) -> NcResult<()> { error![ unsafe { crate::ncplane_cursor_move_yx(self, y as i32, x as i32) }, &format!("NcPlane.move_yx({}, {})", y, x) ] } /// Moves the cursor to the specified row within this NcPlane. /// /// *(No equivalent C style function)* pub fn cursor_move_y(&mut self, y: NcDim) -> NcResult<()> { let x = self.cursor_x(); error![ unsafe { crate::ncplane_cursor_move_yx(self, y as i32, x as i32) }, &format!("NcPlane.move_y({})", y) ] } /// Moves the cursor to the specified column within this NcPlane. /// /// *(No equivalent C style function)* pub fn cursor_move_x(&mut self, x: NcDim) -> NcResult<()> { let y = self.cursor_y(); error![ unsafe { crate::ncplane_cursor_move_yx(self, y as i32, x as i32) }, &format!("NcPlane.move_x({})", x) ] } /// Moves the cursor the number of rows specified (forward or backwards). /// /// It will error if the target row exceeds the plane dimensions. /// /// *(No equivalent C style function)* pub fn cursor_move_rows(&mut self, rows: NcOffset) -> NcResult<()> { let (y, x) = self.cursor_yx(); self.cursor_move_yx((y as NcOffset + rows) as NcDim, x) } /// Moves the cursor the number of columns specified (forward or backwards). /// /// It will error if the target column exceeds the plane dimensions. /// /// *(No equivalent C style function)* pub fn cursor_move_cols(&mut self, cols: NcOffset) -> NcResult<()> { let (y, x) = self.cursor_yx(); self.cursor_move_yx(y, (x as NcOffset + cols) as NcDim) } } // ----------------------------------------------------------------------------- /// ## NcPlane methods: size, position & alignment impl NcPlane { /// Returns the column at which `cols` columns ought start in order to be /// aligned according to `align` within this NcPlane. /// /// Returns `-`[NCRESULT_MAX][crate::NCRESULT_MAX] if /// [NCALIGN_UNALIGNED][crate::NCALIGN_UNALIGNED] or invalid [NcAlign]. /// /// *C style function: [ncplane_align()][crate::ncplane_align].* #[inline] pub fn align(&mut self, align: NcAlign, cols: NcDim) -> NcResult<()> { error![ crate::ncplane_align(self, align, cols), &format!("NcPlane.align({:?}, {})", align, cols) ] } /// /// /// *C style function: [ncplane_center_abs()][crate::ncplane_center_abs].* // // TODO: doc. pub fn center_abs(&self, y: &mut NcDim, x: &mut NcDim) { unsafe { crate::ncplane_center_abs(self, &mut (*y as i32), &mut (*x as i32)); } } /// Returns the dimensions of this NcPlane. /// /// *C style function: [ncplane_dim_yx()][crate::ncplane_dim_yx].* pub fn dim_yx(&self) -> (NcDim, NcDim) { let (mut y, mut x) = (0, 0); unsafe { crate::ncplane_dim_yx(self, &mut y, &mut x) }; (y as NcDim, x as NcDim) } /// Return the rows of this NcPlane. /// /// *C style function: [ncplane_dim_y()][crate::ncplane_dim_y].* #[inline] pub fn dim_y(&self) -> NcDim { self.dim_yx().0 } /// Return the columns of this NcPlane. /// /// *C style function: [ncplane_dim_x()][crate::ncplane_dim_x].* #[inline] pub fn dim_x(&self) -> NcDim { self.dim_yx().1 } /// Return the rows of this NcPlane. /// /// Alias of [dim_y][NcPlane#method.dim_y] /// /// *C style function: [ncplane_dim_y()][crate::ncplane_dim_y].* #[inline] pub fn rows(&self) -> NcDim { self.dim_yx().0 } /// Return the cols of this NcPlane. /// /// Alias of [dim_x][NcPlane#method.dim_x] /// /// *C style function: [ncplane_dim_x()][crate::ncplane_dim_x].* #[inline] pub fn cols(&self) -> NcDim { self.dim_yx().1 } /// Resizes this NcPlane. /// /// The four parameters `keep_y`, `keep_x`, `keep_len_y`, and `keep_len_x` /// defines a subset of this NcPlane to keep unchanged. This may be a section /// of size 0. /// /// `keep_x` and `keep_y` are relative to this NcPlane. They must specify a /// coordinate within the ncplane's totality. If either of `keep_len_y` or /// `keep_len_x` is non-zero, both must be non-zero. /// /// `y_off` and `x_off` are relative to `keep_y` and `keep_x`, and place the /// upper-left corner of the resized NcPlane. /// /// `y_len` and `x_len` are the dimensions of this NcPlane after resizing. /// `y_len` must be greater than or equal to `keep_len_y`, /// and `x_len` must be greater than or equal to `keeplenx`. /// /// It is an error to attempt to resize the standard plane. /// /// *C style function: [ncplane_resize()][crate::ncplane_resize].* pub fn resize( &mut self, keep_y: NcDim, keep_x: NcDim, keep_len_y: NcDim, keep_len_x: NcDim, y_off: NcOffset, x_off: NcOffset, y_len: NcDim, x_len: NcDim, ) -> NcResult<()> { error![ unsafe { crate::ncplane_resize( self, keep_y as i32, keep_x as i32, keep_len_y as i32, keep_len_x as i32, y_off as i32, x_off as i32, y_len as i32, x_len as i32, ) }, &format!( "NcPlane.resize({}, {}, {}, {}, {}, {}, {}, {})", keep_y, keep_x, keep_len_y, keep_len_x, y_off, x_off, y_len, x_len ) ] } /// Realigns this NcPlane against its parent, using the alignment specified /// at creation time. /// /// Suitable for use as an [NcResizeCb]. /// /// *C style function: [ncplane_resize_realign()][crate::ncplane_resize_realign].* // // TODO: suitable for use as an NcResizeCb? pub fn resize_realign(&mut self) -> NcResult<()> { error![unsafe { crate::ncplane_resize_realign(self) }] } /// Resizes this NcPlane, retaining what data we can (everything, unless we're /// shrinking in some dimension). Keeps the origin where it is. /// /// *C style function: [ncplane_resize_simple()][crate::ncplane_resize_simple].* #[inline] pub fn resize_simple(&mut self, y_len: NcDim, x_len: NcDim) -> NcResult<()> { error![crate::ncplane_resize_simple( self, y_len as u32, x_len as u32 )] } /// Returns this NcPlane's current resize callback. /// /// *C style function: [ncplane_resizecb()][crate::ncplane_resizecb].* pub fn resizecb(&self) -> Option { unsafe { crate::ncresizecb_to_rust(crate::ncplane_resizecb(self)) } } /// Replaces this NcPlane's existing resize callback (which may be [None]). /// /// The standard plane's resizecb may not be changed. /// /// *C style function: [ncplane_set_resizecb()][crate::ncplane_set_resizecb].* pub fn set_resizecb(&mut self, resizecb: Option) { unsafe { crate::ncplane_set_resizecb(self, crate::ncresizecb_to_c(resizecb)) } } /// Rotate the plane π/2 radians clockwise. /// /// This cannot be performed on arbitrary planes, because glyphs cannot be /// arbitrarily rotated. /// /// The glyphs which can be rotated are limited: line-drawing characters, /// spaces, half blocks, and full blocks. /// /// The plane must have an even number of columns. /// /// Use the ncvisual rotation for a more flexible approach. /// /// *C style function: [ncplane_rotate_cw()][crate::ncplane_rotate_cw].* pub fn rotate_cw(&mut self) -> NcResult<()> { error![unsafe { crate::ncplane_rotate_cw(self) }] } /// Rotate the plane π/2 radians counter-clockwise. /// /// See [`rotate_cw`][NcPlane#method.rotate_cw] /// for more information. /// /// *C style function: [ncplane_rotate_ccw()][crate::ncplane_rotate_ccw].* pub fn rotate_ccw(&mut self) -> NcResult<()> { error![unsafe { crate::ncplane_rotate_ccw(self) }] } /// Maps the provided coordinates relative to the origin of this NcPlane, /// to the same absolute coordinates relative to the origin of `target`. /// /// *C style function: [ncplane_translate()][crate::ncplane_translate].* // // TODO: API change, return the coordinates as a tuple instead of being &mut pub fn translate(&self, target: &NcPlane, y: &mut NcDim, x: &mut NcDim) { unsafe { crate::ncplane_translate(self, target, &mut (*y as i32), &mut (*x as i32)) } } /// Returns true if the provided absolute `y`/`x` coordinates are within /// this NcPlane, or false otherwise. /// /// Either way, translates the absolute coordinates relative to this NcPlane. /// /// *C style function: [ncplane_translate_abs()][crate::ncplane_translate_abs].* // // TODO: API change, return a tuple (y,x,bool) pub fn translate_abs(&self, y: &mut NcDim, x: &mut NcDim) -> bool { unsafe { crate::ncplane_translate_abs(self, &mut (*y as i32), &mut (*x as i32)) } } /// Gets the `y`, `x` origin of this NcPlane relative to the standard plane, /// or the NcPlane to which it is bound. /// /// *C style function: [ncplane_yx()][crate::ncplane_yx].* // // CHECK: negative offsets pub fn yx(&self) -> (NcOffset, NcOffset) { let (mut y, mut x) = (0, 0); unsafe { crate::ncplane_yx(self, &mut y, &mut x) }; (y as NcOffset, x as NcOffset) } /// Gets the `x` origin of this NcPlane relative to the standard plane, /// or the NcPlane to which it is bound. /// /// *C style function: [ncplane_x()][crate::ncplane_x].* pub fn x(&self) -> NcOffset { unsafe { crate::ncplane_x(self) as NcOffset } } /// Gets the `y` origin of this NcPlane relative to the standard plane, /// or the NcPlane to which it is bound. /// /// *C style function: [ncplane_y()][crate::ncplane_y].* pub fn y(&self) -> NcOffset { unsafe { crate::ncplane_y(self) as NcOffset } } /// Sets the scrolling behaviour of the plane, and /// returns true if scrolling was previously enabled, of false, if disabled. /// /// All planes are created with scrolling disabled. Attempting to print past /// the end of a line will stop at the plane boundary, and indicate an error. /// /// On a plane 10 columns wide and two rows high, printing "0123456789" /// at the origin should succeed, but printing "01234567890" will by default /// fail at the eleventh character. In either case, the cursor will be left /// at location 0x10; it must be moved before further printing can take place. I /// /// *C style function: [ncplane_set_scrolling()][crate::ncplane_set_scrolling].* pub fn set_scrolling(&mut self, scroll: bool) -> bool { unsafe { crate::ncplane_set_scrolling(self, scroll) } } } // ----------------------------------------------------------------------------- /// ## NcPlane methods: boxes & perimeters impl NcPlane { /// Draws a box with its upper-left corner at the current cursor position, /// and its lower-right corner at `y_stop` * `x_stop`. /// /// The 6 cells provided are used to draw the upper-left, ur, ll, and lr corners, /// then the horizontal and vertical lines. /// /// See [NcBoxMask] for information about the border and gradient masks, /// and the drawing of corners. /// /// If the gradient bit is not set, the styling from the hline/vlline cells /// is used for the horizontal and vertical lines, respectively. /// /// If the gradient bit is set, the color is linearly interpolated between /// the two relevant corner cells. /// /// *C style function: [ncplane_box()][crate::ncplane_box].* pub fn r#box( &mut self, ul: &NcCell, ur: &NcCell, ll: &NcCell, lr: &NcCell, hline: &NcCell, vline: &NcCell, y_stop: NcDim, x_stop: NcDim, boxmask: NcBoxMask, ) -> NcResult<()> { error![unsafe { crate::ncplane_box( self, ul, ur, ll, lr, hline, vline, y_stop as i32, x_stop as i32, boxmask, ) }] } /// Draws a box with its upper-left corner at the current cursor position, /// having dimensions `y_len` * `x_len`. /// The minimum box size is 2x2, and it cannot be drawn off-screen. /// /// See the [`box`][NcPlane#method.box] method for more information. /// /// *C style function: [ncplane_box_sized()][crate::ncplane_box_sized].* #[inline] pub fn box_sized( &mut self, ul: &NcCell, ur: &NcCell, ll: &NcCell, lr: &NcCell, hline: &NcCell, vline: &NcCell, y_len: NcDim, x_len: NcDim, boxmask: NcBoxMask, ) -> NcResult<()> { error![crate::ncplane_box_sized( self, ul, ur, ll, lr, hline, vline, y_len, x_len, boxmask )] } /// NcPlane.[box()][NcPlane#method.box] with the double box-drawing characters. /// /// *C style function: [ncplane_double_box()][crate::ncplane_double_box].* #[inline] pub fn double_box( &mut self, stylemask: NcStyleMask, channels: NcChannelPair, y_stop: NcDim, x_stop: NcDim, boxmask: NcBoxMask, ) -> NcResult<()> { error![crate::ncplane_double_box( self, stylemask, channels, y_stop, x_stop, boxmask )] } /// /// /// *C style function: [ncplane_double_box_sized()][crate::ncplane_double_box_sized].* #[inline] pub fn double_box_sized( &mut self, stylemask: NcStyleMask, channels: NcChannelPair, y_len: NcDim, x_len: NcDim, boxmask: NcBoxMask, ) -> NcResult<()> { error![crate::ncplane_double_box( self, stylemask, channels, y_len, x_len, boxmask )] } /// Draws the perimeter around this NcPlane. /// /// *C style function: [ncplane_perimeter()][crate::ncplane_perimeter].* #[inline] pub fn perimeter( &mut self, ul: &NcCell, ur: &NcCell, ll: &NcCell, lr: &NcCell, hline: &NcCell, vline: &NcCell, boxmask: NcBoxMask, ) -> NcResult<()> { error![crate::ncplane_perimeter( self, ul, ur, ll, lr, hline, vline, boxmask )] } /// NcPlane.[perimeter()][NcPlane#method.perimeter] with the double box-drawing characters. /// /// *C style function: [ncplane_perimeter_double()][crate::ncplane_perimeter_double].* #[inline] pub fn perimeter_double( &mut self, stylemask: NcStyleMask, channels: NcChannelPair, boxmask: NcBoxMask, ) -> NcResult<()> { error![crate::ncplane_perimeter_double( self, stylemask, channels, boxmask )] } /// NcPlane.[perimeter()][NcPlane#method.perimeter] with the rounded box-drawing characters. /// /// /// *C style function: [ncplane_perimeter_rounded()][crate::ncplane_perimeter_rounded].* #[inline] pub fn perimeter_rounded( &mut self, stylemask: NcStyleMask, channels: NcChannelPair, boxmask: NcBoxMask, ) -> NcResult<()> { error![crate::ncplane_perimeter_rounded( self, stylemask, channels, boxmask )] } } // ----------------------------------------------------------------------------- /// ## NcPlane methods: fading, gradients & greyscale impl NcPlane { /// Fades this NcPlane in, over the specified time, calling 'fader' at /// each iteration. /// /// Usage: /// 1. Load this NcPlane with the target cells without rendering. /// 2. call this function. /// /// When it's done, the NcPlane will have reached the target levels, /// starting from zeroes. /// /// *C style function: [ncplane_fadein()][crate::ncplane_fadein].* pub fn fadein(&mut self, time: &NcTime, fader: NcFadeCb) -> NcResult<()> { error![unsafe { crate::ncplane_fadein(self, time, fader, null_mut()) }] } /// Fades in through 'iter' iterations, /// where 'iter' < 'ncfadectx_iterations(nctx)'. /// /// *C style function: [ncplane_fadein_iteration()][crate::ncplane_fadein_iteration].* pub fn fadein_iteration(&mut self, time: &NcTime, fader: NcFadeCb) -> NcResult<()> { error![unsafe { crate::ncplane_fadein(self, time, fader, null_mut()) }] } /// Fades this NcPlane out, over the specified time, calling 'fader' at /// each iteration. /// /// Requires a terminal which supports truecolor, or at least palette /// modification (if the terminal uses a palette, our ability to fade planes /// is limited, and affected by the complexity of the rest of the screen). /// /// *C style function: [ncplane_fadeout()][crate::ncplane_fadeout].* pub fn fadeout(&mut self, time: &NcTime, fader: NcFadeCb) -> NcResult<()> { error![unsafe { crate::ncplane_fadeout(self, time, fader, null_mut()) }] } /// Fades out through 'iter' iterations, /// where 'iter' < 'ncfadectx_iterations(nctx)'. /// /// *C style function: [ncplane_fadeout_iteration()][crate::ncplane_fadeout_iteration].* pub fn fadeout_iteration(&mut self, time: &NcTime, fader: NcFadeCb) -> NcResult<()> { error![unsafe { crate::ncplane_fadeout(self, time, fader, null_mut()) }] } /// Pulses this NcPlane in and out until the callback returns non-zero, /// relying on the callback 'fader' to initiate rendering. /// /// `time` defines the half-period (i.e. the transition from black to full /// brightness, or back again). /// /// Proper use involves preparing (but not rendering) the NcPlane, /// then calling this method, which will fade in from black to the /// specified colors. /// /// *C style function: [ncplane_pulse()][crate::ncplane_pulse].* pub fn pulse(&mut self, time: &NcTime, fader: NcFadeCb) -> NcResult<()> { error![unsafe { crate::ncplane_pulse(self, time, fader, null_mut()) }] } /// Draws a gradient with its upper-left corner at the current cursor /// position, stopping at `y_stop` * `xstop`. /// /// Returns the number of cells filled on success, /// or [NCRESULT_ERR] on error. /// /// The glyph composed of `egc` and `stylemask` is used for all cells. /// The channels specified by `ul`, `ur`, `ll`, and `lr` are composed into /// foreground and background gradients. /// /// To do a vertical gradient, `ul` ought equal `ur` and `ll` ought equal /// `lr`. To do a horizontal gradient, `ul` ought equal `ll` and `ur` ought /// equal `ul`. /// /// To color everything the same, all four channels should be equivalent. /// The resulting alpha values are equal to incoming alpha values. /// /// Palette-indexed color is not supported. /// /// Preconditions for gradient operations (error otherwise): /// /// all: only RGB colors, unless all four channels match as default /// all: all alpha values must be the same /// 1x1: all four colors must be the same /// 1xN: both top and both bottom colors must be the same (vertical gradient) /// Nx1: both left and both right colors must be the same (horizontal gradient) /// /// *C style function: [ncplane_gradient()][crate::ncplane_gradient].* pub fn gradient( &mut self, egc: &NcEgc, stylemask: NcStyleMask, ul: NcChannelPair, ur: NcChannelPair, ll: NcChannelPair, lr: NcChannelPair, y_stop: NcDim, x_stop: NcDim, ) -> NcResult { let res = unsafe { crate::ncplane_gradient( self, &(*egc as i8), stylemask as u32, ul, ur, ll, lr, y_stop as i32, x_stop as i32, ) }; error![res, "", res as NcDim] } /// Draw a gradient with its upper-left corner at the current cursor position, /// having dimensions `y_len` * `x_len`. /// /// See [gradient][NcPlane#method.gradient] for more information. /// /// *C style function: [ncplane_gradient_sized()][crate::ncplane_gradient_sized].* #[inline] pub fn gradient_sized( &mut self, egc: &NcEgc, stylemask: NcStyleMask, ul: NcChannel, ur: NcChannel, ll: NcChannel, lr: NcChannel, y_len: NcDim, x_len: NcDim, ) -> NcResult { let res = crate::ncplane_gradient_sized(self, egc, stylemask, ul, ur, ll, lr, y_len, x_len); error![res, "", res as NcDim] } /// Draws a high-resolution gradient using upper blocks and synced backgrounds. /// /// Returns the number of cells filled on success, /// or [NCRESULT_ERR] on error. /// /// This doubles the number of vertical gradations, but restricts you to /// half blocks (appearing to be full blocks). /// /// *C style function: [ncplane_highgradient()][crate::ncplane_highgradient].* pub fn highgradient( &mut self, ul: NcChannel, ur: NcChannel, ll: NcChannel, lr: NcChannel, y_stop: NcDim, x_stop: NcDim, ) -> NcResult { let res = unsafe { crate::ncplane_highgradient(self, ul, ur, ll, lr, y_stop as i32, x_stop as i32) }; error![res, "", res as NcDim] } /// [`gradient_sized`][NcPlane#method.gradient_sized] /// meets [`highgradient`][NcPlane#method.highgradient]. /// /// *C style function: [ncplane_highgradient_sized()][crate::ncplane_highgradient_sized].* pub fn highgradient_sized( &mut self, ul: NcChannel, ur: NcChannel, ll: NcChannel, lr: NcChannel, y_stop: NcDim, x_stop: NcDim, ) -> NcResult { let res = unsafe { crate::ncplane_highgradient_sized(self, ul, ur, ll, lr, y_stop as i32, x_stop as i32) }; error![res, "", res as NcDim] } /// Converts this NcPlane's content to greyscale. /// /// *C style function: [ncplane_greyscale()][crate::ncplane_greyscale].* pub fn greyscale(&mut self) { unsafe { crate::ncplane_greyscale(self); } } } libnotcurses-sys-2.1.8/src/plane/mod.rs010064400017500001750000000231401377416525400162640ustar 00000000000000//! `NcPlane` // functions already exported by bindgen : 108 (5 + 103) // ----------------------------------------------------- // (X) wont: 6 // (D) depr: 4 // (#) test: 13 // (W) wrap: 79 of 98 // ------------------------------------------- //W ncpile_bottom //W# ncpile_create //W ncpile_rasterize //W ncpile_render //W ncpile_top //W ncplane_above //W ncplane_at_cursor //W ncplane_at_cursor_cell //W ncplane_at_yx //W ncplane_at_yx_cell //W ncplane_base //W ncplane_below //W ncplane_box //W ncplane_center_abs //W# ncplane_channels //W ncplane_contents //W ncplane_create //W# ncplane_cursor_move_yx //W# ncplane_cursor_yx //W ncplane_destroy //W# ncplane_dim_yx //W ncplane_dup //W# ncplane_erase //W ncplane_fadein //W ncplane_fadein_iteration //W ncplane_fadeout //W ncplane_fadeout_iteration //W ncplane_format //W ncplane_gradient //W ncplane_greyscale //W ncplane_highgradient //W ncplane_highgradient_sized // ncplane_hline_interp //W# ncplane_home //W ncplane_mergedown //W ncplane_mergedown_simple //W ncplane_move_above //W ncplane_move_below //W ncplane_move_bottom //W ncplane_move_top //W ncplane_move_yx // X ncplane_new // deprecated //W# ncplane_notcurses //W# ncplane_notcurses_const //W ncplane_off_styles //W ncplane_on_styles //W ncplane_parent //W ncplane_parent_const // ncplane_polyfill_yx //W ncplane_pulse // ncplane_putchar_stained // ncplane_putc_yx // X ncplane_putegc_stained // unneeded // X ncplane_putegc_yx // unneeded // ncplane_putnstr_aligned // ncplane_putnstr_yx //W ncplane_putstr_aligned //W ncplane_putstr_stained //W ncplane_putstr_yx // ncplane_puttext // X ncplane_putwegc_stained // unneeded // X ncplane_putwstr_stained // unneeded // ncplane_qrcode //W ncplane_reparent //W ncplane_reparent_family //W# ncplane_resize //W ncplane_resizecb // ncplane_resize_maximize //W ncplane_resize_realign // ncplane_rgba //W ncplane_rotate_ccw //W ncplane_rotate_cw //W ncplane_set_base //W ncplane_set_base_cell //W# ncplane_set_bchannel //W ncplane_set_bg_alpha //W ncplane_set_bg_default //W ncplane_set_bg_palindex //W ncplane_set_bg_rgb //W ncplane_set_bg_rgb8 // X ncplane_set_bg_rgb8_clipped // unneeded //W# ncplane_set_channels //W# ncplane_set_fchannel //W ncplane_set_fg_alpha //W ncplane_set_fg_default //W ncplane_set_fg_palindex //W ncplane_set_fg_rgb //W ncplane_set_fg_rgb8 // X ncplane_set_fg_rgb8_clipped // unneeded //W ncplane_set_resizecb //W ncplane_set_scrolling //W ncplane_set_styles // ncplane_set_userptr //W ncplane_stain //W ncplane_styles // X ncplane_styles_off // deprecated // X ncplane_styles_on // deprecated // X ncplane_styles_set // deprecated //W ncplane_translate //W ncplane_translate_abs // ncplane_userptr // ncplane_vline_interp // ncplane_vprintf_aligned // ncplane_vprintf_stained // ncplane_vprintf_yx //W ncplane_x //W ncplane_y //W ncplane_yx // // functions manually reimplemented: 39 // ------------------------------------------ // (X) wont: 9 // (+) done: 32 / 0 // (W) wrap: 24 // (#) test: 5 // ------------------------------------------ //W+ ncplane_align //W+ ncplane_bchannel //W+ ncplane_bg_alpha //W# ncplane_bg_default_p //W+ ncplane_bg_rgb //W+ ncplane_bg_rgb8 //W+ ncplane_box_sized //W# ncplane_dim_x //W# ncplane_dim_y //W+ ncplane_double_box //W+ ncplane_double_box_sized //W+ ncplane_fchannel //W+ ncplane_fg_alpha //W# ncplane_fg_default_p //W+ ncplane_fg_rgb //W+ ncplane_fg_rgb8 //W+ ncplane_gradient_sized // + ncplane_hline //W+ ncplane_perimeter //W+ ncplane_perimeter_double //W+ ncplane_perimeter_rounded // + ncplane_putc // + ncplane_putchar // + ncplane_putchar_yx // X ncplane_putegc // unneeded // + ncplane_putnstr //W+ ncplane_putstr // X ncplane_putwc // unneeded // X ncplane_putwc_stained // unneeded // X ncplane_putwc_yx // unneeded // X ncplane_putwegc // unneeded // X ncplane_putwegc_yx // unneeded // X ncplane_putwstr // unneeded // X ncplane_putwstr_aligned // unneeded // X ncplane_putwstr_yx // unneeded //W# ncplane_resize_simple // + ncplane_rounded_box // + ncplane_rounded_box_sized // + ncplane_vline // + ncplane_vprintf // // NOTE: TODO: Still remains all the ncplane_printf* functions/macros (at the end) #[cfg(test)] mod test; mod helpers; mod methods; mod reimplemented; #[allow(unused_imports)] pub(crate) use helpers::*; pub use reimplemented::*; // NcPlane /// Fundamental drawing surface. /// /// Unites a: /// - CellMatrix /// - EgcPool /// /// `type in C: ncplane (struct)` /// /// /// # Piles /// /// A single notcurses context is made up of one or more piles. /// /// A pile is a set of one or more ncplanes, including the partial orderings /// made up of their binding and z-axis pointers. /// /// A pile has a top and bottom ncplane (this might be a single plane), /// and one or more root planes (planes which are bound to themselves). /// /// Multiple threads can concurrently operate on distinct piles, even changing /// one while rendering another. /// /// Each plane is part of one and only one pile. By default, a plane is part of /// the same pile containing that plane to which it is bound. /// /// If ncpile_create is used in the place of ncplane_create, the returned plane /// becomes the root plane, top, and bottom of a new pile. As a root plane, /// it is bound to itself. /// /// A new pile can also be created by reparenting a plane to itself, /// though if the plane is already a root plane, this is a no-op. /// /// When a plane is moved to a different pile (whether new or preexisting), /// any planes which were bound to it are rebound to its previous parent. /// If the plane was a root plane of some pile, any bound planes become root /// planes. The new plane is placed immediately atop its new parent on its new /// pile's z-axis. When ncplane_reparent_family() is used, all planes bound to /// the reparented plane are moved along with it. Their relative z-order is maintained. /// /// /// # Methods & Associated Functions /// /// - [Constructors & Destructors](#ncplane-constructors--destructors) /// /// Methods: /// - [`NcAlphaBits`](#ncplane-methods-ncalphabits) /// - [`NcChannel` & `NcChannelPair`](#ncplane-methods-ncchannel) /// - [`NcColor`, `NcRgb` & default color](#ncplane-methods-nccolor-ncrgb--default-color) /// - [`NcStyleMask` & `NcPaletteIndex`](#ncplane-methods-ncstylemask--paletteindex) /// - [`NcCell` & `NcEgc`](#ncplane-methods-nccell--ncegc) /// - [cursor](#ncplane-methods-cursor) /// - [`NcPlane` & `Notcurses`](#ncplane-methods-ncplane--notcurses) /// - [boxes & perimeters](#ncplane-methods-boxes--perimeters) /// - [Size, position & alignment](#ncplane-methods-size-position--alignment) /// - [fading, gradients & greyscale](#ncplane-methods-fading-gradients--greyscale) /// pub type NcPlane = crate::bindings::ffi::ncplane; /// Options struct for [`NcPlane`] pub type NcPlaneOptions = crate::bindings::ffi::ncplane_options; /// Horizontal alignment relative to the parent plane. Set alignment in 'x'. pub const NCPLANE_OPTION_HORALIGNED: u64 = crate::bindings::ffi::NCPLANE_OPTION_HORALIGNED as u64; /// I/O wrapper to dump file descriptor to [`NcPlane`] /// /// `type in C: ncfdplane (struct)` pub type NcFdPlane = crate::bindings::ffi::ncfdplane; /// Options struct for [`NcFdPlane`] /// /// `type in C: ncplane_options (struct)` pub type NcFdPlaneOptions = crate::bindings::ffi::ncfdplane_options; /// Blitter Mode (`NCBLIT_*`) /// /// We never blit full blocks, but instead spaces (more efficient) with the /// background set to the desired foreground. /// /// ## Modes /// /// - [`NCBLIT_1x1`] /// - [`NCBLIT_2x1`] /// - [`NCBLIT_2x2`] /// - [`NCBLIT_3x2`] /// - [`NCBLIT_4x1`] /// - [`NCBLIT_8x1`] /// - [`NCBLIT_BRAILLE`] /// - [`NCBLIT_DEFAULT`] /// - [`NCBLIT_SIXEL`] /// pub type NcBlitter = crate::bindings::ffi::ncblitter_e; /// [`NcBlitter`] mode using: space, compatible with ASCII pub const NCBLIT_1x1: NcBlitter = crate::bindings::ffi::ncblitter_e_NCBLIT_1x1; /// [`NcBlitter`] mode using: halves + 1x1 (space) /// ▄▀ pub const NCBLIT_2x1: NcBlitter = crate::bindings::ffi::ncblitter_e_NCBLIT_2x1; /// [`NcBlitter`] mode using: quadrants + 2x1 /// ▗▐ ▖▀▟▌▙ pub const NCBLIT_2x2: NcBlitter = crate::bindings::ffi::ncblitter_e_NCBLIT_2x2; /// [`NcBlitter`] mode using: sextants /// 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬉🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞🬟🬠🬡🬢🬣🬤🬥🬦🬧🬨🬩🬪🬫🬬🬭🬮🬯🬰🬱🬲🬳🬴🬵🬶🬷🬸🬹🬺🬻 pub const NCBLIT_3x2: NcBlitter = crate::bindings::ffi::ncblitter_e_NCBLIT_3x2; /// [`NcBlitter`] mode using: four vertical levels /// █▆▄▂ pub const NCBLIT_4x1: NcBlitter = crate::bindings::ffi::ncblitter_e_NCBLIT_4x1; /// [`NcBlitter`] mode using: eight vertical levels /// █▇▆▅▄▃▂▁ pub const NCBLIT_8x1: NcBlitter = crate::bindings::ffi::ncblitter_e_NCBLIT_8x1; /// [`NcBlitter`] mode using: 4 rows, 2 cols (braille) /// ⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿ pub const NCBLIT_BRAILLE: NcBlitter = crate::bindings::ffi::ncblitter_e_NCBLIT_BRAILLE; /// [`NcBlitter`] mode where the blitter is automatically chosen pub const NCBLIT_DEFAULT: NcBlitter = crate::bindings::ffi::ncblitter_e_NCBLIT_DEFAULT; /// [`NcBlitter`] mode (not yet implemented) /// /// See [Sixel in Wikipedia](https://en.wikipedia.org/wiki/Sixel). pub const NCBLIT_SIXEL: NcBlitter = crate::bindings::ffi::ncblitter_e_NCBLIT_SIXEL; libnotcurses-sys-2.1.8/src/plane/reimplemented.rs010064400017500001750000000447211377726434200203500ustar 00000000000000//! `ncplane_*` reimplemented functions. use core::ptr::null_mut; use crate::ffi::__va_list_tag; use crate::{ cell_release, cstring, ncplane_channels, NcAlign, NcAlphaBits, NcBoxMask, NcCell, NcChannel, NcChannelPair, NcColor, NcDim, NcEgc, NcIntResult, NcPlane, NcRgb, NcStyleMask, NCRESULT_ERR, NCRESULT_OK, }; // Alpha ----------------------------------------------------------------------- /// Gets the foreground [NcAlphaBits] from the [NcPlane], shifted to LSBs. /// /// *Method: NcPlane.[fg_alpha()][NcPlane#method.fg_alpha].* #[inline] pub fn ncplane_fg_alpha(plane: &NcPlane) -> NcAlphaBits { crate::channels_fg_alpha(unsafe { ncplane_channels(plane) }) } /// Gets the background [NcAlphaBits] from the [NcPlane], shifted to LSBs. /// /// *Method: NcPlane.[bg_alpha()][NcPlane#method.bg_alpha].* #[inline] pub fn ncplane_bg_alpha(plane: &NcPlane) -> NcAlphaBits { crate::channels_bg_alpha(unsafe { ncplane_channels(plane) }) } // NcChannel ------------------------------------------------------------------- /// Gets the foreground [NcChannel] from an [NcPlane]. /// /// *Method: NcPlane.[fchannel()][NcPlane#method.fchannel].* #[inline] pub fn ncplane_fchannel(plane: &NcPlane) -> NcChannel { crate::channels_fchannel(unsafe { ncplane_channels(plane) }) } /// Gets the background [NcChannel] from an [NcPlane]. /// /// *Method: NcPlane.[bchannel()][NcPlane#method.bchannel].* #[inline] pub fn ncplane_bchannel(plane: &NcPlane) -> NcChannel { crate::channels_bchannel(unsafe { ncplane_channels(plane) }) } // NcColor --------------------------------------------------------------------- /// Gets the foreground [NcColor] RGB components from an [NcPlane]. /// and returns the background [NcChannel]. /// /// *Method: NcPlane.[fg_rgb8()][NcPlane#method.fg_rgb8].* #[inline] pub fn ncplane_fg_rgb8( plane: &NcPlane, red: &mut NcColor, green: &mut NcColor, blue: &mut NcColor, ) -> NcChannel { crate::channels_fg_rgb8(unsafe { ncplane_channels(plane) }, red, green, blue) } /// Gets the background [NcColor] RGB components from an [NcPlane], /// and returns the background [NcChannel]. /// /// *Method: NcPlane.[bg_rgb8()][NcPlane#method.bg_rgb8].* #[inline] pub fn ncplane_bg_rgb8( plane: &NcPlane, red: &mut NcColor, green: &mut NcColor, blue: &mut NcColor, ) -> NcChannel { crate::channels_bg_rgb8(unsafe { ncplane_channels(plane) }, red, green, blue) } // NcRgb ----------------------------------------------------------------------- /// Gets the foreground [NcRgb] from an [NcPlane], shifted to LSBs. /// /// *Method: NcPlane.[fg_rgb()][NcPlane#method.fg_rgb].* #[inline] pub fn ncplane_fg_rgb(plane: &NcPlane) -> NcRgb { crate::channels_fg_rgb(unsafe { ncplane_channels(plane) }) } /// Gets the background [NcRgb] from an [NcPlane], shifted to LSBs. /// /// *Method: NcPlane.[bg_rgb()][NcPlane#method.bg_rgb].* #[inline] pub fn ncplane_bg_rgb(plane: &NcPlane) -> NcRgb { crate::channels_bg_rgb(unsafe { ncplane_channels(plane) }) } // Default --------------------------------------------------------------------- /// Is the plane's foreground using the "default foreground color"? /// /// *Method: NcPlane.[fg_default_p()][NcPlane#method.fg_default_p].* #[inline] pub fn ncplane_fg_default_p(plane: &NcPlane) -> bool { crate::channels_fg_default_p(unsafe { ncplane_channels(plane) }) } /// Is the plane's background using the "default background color"? /// /// *Method: NcPlane.[bg_default_p()][NcPlane#method.bg_default_p].* #[inline] pub fn ncplane_bg_default_p(plane: &NcPlane) -> bool { crate::channels_bg_default_p(unsafe { ncplane_channels(plane) }) } // put & print ----------------------------------------------------------------- /// Calls [ncplane_putc_yx()][crate::ncplane_putc_yx] for the current cursor location. /// /// *Method: NcPlane.[putc()][NcPlane#method.putc].* #[inline] pub fn ncplane_putc(plane: &mut NcPlane, cell: &NcCell) -> NcIntResult { unsafe { crate::ncplane_putc_yx(plane, -1, -1, cell) } } /// Calls ncplane_putchar_yx() at the current cursor location. /// /// *Method: NcPlane.[putchar()][NcPlane#method.putchar].* #[inline] pub fn ncplane_putchar(plane: &mut NcPlane, ch: char) -> NcIntResult { unsafe { let cell = NcCell::with_char(ch, plane); crate::ncplane_putc_yx(plane, -1, -1, &cell) } } /// Replaces the [NcCell] at the specified coordinates with the provided char. /// Advances the cursor by 1. /// /// *Method: NcPlane.[putchar_yx()][NcPlane#method.putchar_yx].* #[inline] pub fn ncplane_putchar_yx(plane: &mut NcPlane, y: NcDim, x: NcDim, ch: char) -> NcIntResult { unsafe { let cell = NcCell::with_char(ch, plane); crate::ncplane_putc_yx(plane, y as i32, x as i32, &cell) } } /// Writes a series of [NcEgc]s to the current location, using the current style. /// /// Advances the cursor by some positive number of columns /// (though not beyond the end of the plane), /// and this number is returned on success. /// /// On error, a non-positive number is returned, indicating /// the number of columns which were written before the error. /// /// *Method: NcPlane.[putstr()][NcPlane#method.putstr].* #[inline] pub fn ncplane_putstr(plane: &mut NcPlane, string: &str) -> NcIntResult { unsafe { crate::ncplane_putstr_yx(plane, -1, -1, cstring![string]) } } /// /// /// *Method: NcPlane.[putnstr()][NcPlane#method.putnstr].* #[inline] pub fn ncplane_putnstr(plane: &mut NcPlane, size: u64, gclustarr: &[u8]) -> NcIntResult { unsafe { crate::ncplane_putnstr_yx(plane, -1, -1, size, cstring![gclustarr]) } } /// The [NcPlane] equivalent of `vprintf(3)`. /// /// *Method: NcPlane.[vprintf()][NcPlane#method.vprintf].* #[inline] pub fn ncplane_vprintf(plane: &mut NcPlane, format: &str, ap: &mut __va_list_tag) -> NcIntResult { unsafe { crate::ncplane_vprintf_yx(plane, -1, -1, cstring![format], ap) } } // size & alignment ------------------------------------------------------------ /// Gets the columns of the [NcPlane]. /// /// *Method: NcPlane.[dim_x()][NcPlane#method.dim_x].* #[inline] pub fn ncplane_dim_x(plane: &NcPlane) -> NcDim { unsafe { let mut x = 0; crate::ncplane_dim_yx(plane, null_mut(), &mut x); x as NcDim } } /// Gets the rows of the [NcPlane]. /// /// *Method: NcPlane.[dim_y()][NcPlane#method.dim_y].* #[inline] #[inline] pub fn ncplane_dim_y(plane: &NcPlane) -> NcDim { unsafe { let mut y = 0; crate::ncplane_dim_yx(plane, &mut y, null_mut()); y as NcDim } } /// Resizes the plane, retaining what data we can (everything, unless we're /// shrinking in some dimension). Keep the origin where it is. /// /// *Method: NcPlane.[resize_simple()][NcPlane#method.resize_simple].* #[inline] pub fn ncplane_resize_simple(plane: &mut NcPlane, y_len: NcDim, x_len: NcDim) -> NcIntResult { let (mut old_y, mut old_x) = (0, 0); unsafe { crate::ncplane_dim_yx(plane, &mut old_y, &mut old_x); } let keep_len_y = { if old_y > y_len as i32 { y_len as i32 } else { old_y } }; let keep_len_x = { if old_x > x_len as i32 { x_len as i32 } else { old_x } }; unsafe { crate::ncplane_resize( plane, 0, 0, keep_len_y, keep_len_x, 0, 0, y_len as i32, x_len as i32, ) } } /// Returns the column at which `cols` columns ought start in order to be aligned /// according to `align` within this NcPlane. /// /// Returns `-`[`NCRESULT_MAX`][crate::NCRESULT_MAX] if /// [NCALIGN_UNALIGNED][crate::NCALIGN_UNALIGNED] or invalid [NcAlign]. /// /// *Method: NcPlane.[align()][NcPlane#method.align].* #[inline] pub fn ncplane_align(plane: &NcPlane, align: NcAlign, cols: NcDim) -> NcIntResult { crate::notcurses_align(ncplane_dim_x(plane), align, cols) } // line ------------------------------------------------------------------------ /// Draws horizontal lines using the specified NcCell, starting at the current /// cursor position. /// /// The cursor will end at the cell following the last cell output, /// just as if ncplane_putc() was called at that spot. /// /// Returns the number of cells drawn on success. On error, returns the negative /// number of cells drawn. /// /// *Method: NcPlane.[hline()][NcPlane#method.hline].* #[inline] pub fn ncplane_hline(plane: &mut NcPlane, cell: &NcCell, len: NcDim) -> NcIntResult { unsafe { crate::ncplane_hline_interp(plane, cell, len as i32, cell.channels, cell.channels) } } /// Draws vertical lines using the specified NcCell, starting at the current /// cursor position. /// /// The cursor will end at the cell following the last cell output, /// just as if ncplane_putc() was called at that spot. /// /// Returns the number of cells drawn on success. On error, returns the negative /// number of cells drawn. /// /// *Method: NcPlane.[vline()][NcPlane#method.vline].* #[inline] pub fn ncplane_vline(plane: &mut NcPlane, cell: &NcCell, len: NcDim) -> NcIntResult { unsafe { crate::ncplane_vline_interp(plane, cell, len as i32, cell.channels, cell.channels) } } // perimeter ------------------------------------------------------------------- /// /// /// *Method: NcPlane.[perimeter()][NcPlane#method.perimeter].* #[inline] pub fn ncplane_perimeter( plane: &mut NcPlane, ul: &NcCell, ur: &NcCell, ll: &NcCell, lr: &NcCell, hline: &NcCell, vline: &NcCell, boxmask: NcBoxMask, ) -> NcIntResult { unsafe { crate::ncplane_cursor_move_yx(plane, 0, 0); let (mut dimy, mut dimx) = (0, 0); crate::ncplane_dim_yx(plane, &mut dimy, &mut dimx); ncplane_box_sized( plane, ul, ur, ll, lr, hline, vline, dimy as NcDim, dimx as NcDim, boxmask, ) } } /// /// /// *Method: NcPlane.[perimeter_double()][NcPlane#method.perimeter_double].* #[inline] pub fn ncplane_perimeter_double( plane: &mut NcPlane, stylemask: NcStyleMask, channels: NcChannelPair, boxmask: NcBoxMask, ) -> NcIntResult { if unsafe { crate::ncplane_cursor_move_yx(plane, 0, 0) } != NCRESULT_OK { return NCRESULT_ERR; } let (mut dimy, mut dimx) = (0, 0); unsafe { crate::ncplane_dim_yx(plane, &mut dimy, &mut dimx); } let mut ul = NcCell::new(); let mut ur = NcCell::new(); let mut ll = NcCell::new(); let mut lr = NcCell::new(); let mut hl = NcCell::new(); let mut vl = NcCell::new(); if unsafe { crate::cells_double_box( plane, stylemask as u32, channels, &mut ul, &mut ur, &mut ll, &mut lr, &mut hl, &mut vl, ) } != NCRESULT_OK { return NCRESULT_ERR; } let ret = ncplane_box_sized( plane, &ul, &ur, &ll, &lr, &hl, &vl, dimy as NcDim, dimx as NcDim, boxmask, ); unsafe { cell_release(plane, &mut ul); cell_release(plane, &mut ur); cell_release(plane, &mut ll); cell_release(plane, &mut lr); cell_release(plane, &mut hl); cell_release(plane, &mut vl); } ret } /// /// /// *Method: NcPlane.[perimeter_rounded()][NcPlane#method.perimeter_rounded].* #[inline] pub fn ncplane_perimeter_rounded( plane: &mut NcPlane, stylemask: NcStyleMask, channels: NcChannelPair, boxmask: NcBoxMask, ) -> NcIntResult { if unsafe { crate::ncplane_cursor_move_yx(plane, 0, 0) } != NCRESULT_OK { return NCRESULT_ERR; } let (mut dimy, mut dimx) = (0, 0); unsafe { crate::ncplane_dim_yx(plane, &mut dimy, &mut dimx); } let mut ul = NcCell::new(); let mut ur = NcCell::new(); let mut ll = NcCell::new(); let mut lr = NcCell::new(); let mut hl = NcCell::new(); let mut vl = NcCell::new(); if unsafe { crate::cells_rounded_box( plane, stylemask as u32, channels, &mut ul, &mut ur, &mut ll, &mut lr, &mut hl, &mut vl, ) } != NCRESULT_OK { return NCRESULT_ERR; } let ret = ncplane_box_sized( plane, &ul, &ur, &ll, &lr, &hl, &vl, dimy as NcDim, dimx as NcDim, boxmask, ); unsafe { cell_release(plane, &mut ul); cell_release(plane, &mut ur); cell_release(plane, &mut ll); cell_release(plane, &mut lr); cell_release(plane, &mut hl); cell_release(plane, &mut vl); } ret } // box ------------------------------------------------------------------------- /// Draws a box with its upper-left corner at the current cursor position, /// having dimensions `y_len` * `x_len`. /// /// The minimum box size is 2x2, and it cannot be drawn off-screen. /// /// See [ncplane_box()](crate::ncplane_box) for more information. /// /// *Method: NcPlane.[box_sized()][NcPlane#method.box_sized].* #[inline] pub fn ncplane_box_sized( plane: &mut NcPlane, ul: &NcCell, ur: &NcCell, ll: &NcCell, lr: &NcCell, hline: &NcCell, vline: &NcCell, y_len: NcDim, x_len: NcDim, boxmask: NcBoxMask, ) -> NcIntResult { let (mut y, mut x) = (0, 0); unsafe { crate::ncplane_cursor_yx(plane, &mut y, &mut x); crate::ncplane_box( plane, ul, ur, ll, lr, hline, vline, y + y_len as i32 - 1, x + x_len as i32 - 1, boxmask, ) } } /// /// /// *Method: NcPlane.[double_box()][NcPlane#method.double_box].* #[inline] pub fn ncplane_double_box( plane: &mut NcPlane, stylemask: NcStyleMask, channels: NcChannelPair, y_stop: NcDim, x_stop: NcDim, boxmask: NcBoxMask, ) -> NcIntResult { #[allow(unused_assignments)] let mut ret = NCRESULT_OK; let mut ul = NcCell::new(); let mut ur = NcCell::new(); let mut ll = NcCell::new(); let mut lr = NcCell::new(); let mut hl = NcCell::new(); let mut vl = NcCell::new(); unsafe { ret = crate::cells_double_box( plane, stylemask as u32, channels, &mut ul, &mut ur, &mut ll, &mut lr, &mut hl, &mut vl, ); if ret == NCRESULT_OK { ret = crate::ncplane_box( plane, &ul, &ur, &ll, &lr, &hl, &vl, y_stop as i32, x_stop as i32, boxmask, ); } cell_release(plane, &mut ul); cell_release(plane, &mut ur); cell_release(plane, &mut ll); cell_release(plane, &mut lr); cell_release(plane, &mut hl); cell_release(plane, &mut vl); } ret } /// /// /// *Method: NcPlane.[double_box_sized()][NcPlane#method.double_box_sized].* #[inline] pub fn ncplane_double_box_sized( plane: &mut NcPlane, stylemask: NcStyleMask, channels: NcChannelPair, y_len: NcDim, x_len: NcDim, boxmask: NcBoxMask, ) -> NcIntResult { let (mut y, mut x) = (0, 0); unsafe { crate::ncplane_cursor_yx(plane, &mut y, &mut x); } crate::ncplane_double_box( plane, stylemask, channels, y as NcDim + y_len - 1, x as NcDim + x_len - 1, boxmask, ) } /// /// /// *Method: NcPlane.[rounded_box()][NcPlane#method.rounded_box].* #[inline] pub fn ncplane_rounded_box( plane: &mut NcPlane, stylemask: NcStyleMask, channels: NcChannelPair, y_stop: NcDim, x_stop: NcDim, boxmask: NcBoxMask, ) -> NcIntResult { #[allow(unused_assignments)] let mut ret = NCRESULT_OK; let mut ul = NcCell::new(); let mut ur = NcCell::new(); let mut ll = NcCell::new(); let mut lr = NcCell::new(); let mut hl = NcCell::new(); let mut vl = NcCell::new(); unsafe { ret = crate::cells_rounded_box( plane, stylemask as u32, channels, &mut ul, &mut ur, &mut ll, &mut lr, &mut hl, &mut vl, ); if ret == NCRESULT_OK { ret = crate::ncplane_box( plane, &ul, &ur, &ll, &lr, &hl, &vl, y_stop as i32, x_stop as i32, boxmask, ); } cell_release(plane, &mut ul); cell_release(plane, &mut ur); cell_release(plane, &mut ll); cell_release(plane, &mut lr); cell_release(plane, &mut hl); cell_release(plane, &mut vl); } ret } /// /// /// *Method: NcPlane.[rounded_box_sized()][NcPlane#method.rounded_box_sized].* #[inline] pub fn ncplane_rounded_box_sized( plane: &mut NcPlane, stylemask: NcStyleMask, channels: NcChannelPair, y_len: NcDim, x_len: NcDim, boxmask: NcBoxMask, ) -> NcIntResult { let (mut y, mut x) = (0, 0); unsafe { crate::ncplane_cursor_yx(plane, &mut y, &mut x); } ncplane_rounded_box( plane, stylemask, channels, y as NcDim + y_len - 1, x as NcDim + x_len - 1, boxmask, ) } // gradient -------------------------------------------------------------------- /// Draw a gradient with its upper-left corner at the current cursor position, /// having dimensions `y_len` * `x_len`. /// /// See [ncplane_gradient][crate::ncplane_gradient] for more information. /// /// *Method: NcPlane.[gradient_sized()][NcPlane#method.gradient_sized].* #[inline] pub fn ncplane_gradient_sized( plane: &mut NcPlane, egc: &NcEgc, stylemask: NcStyleMask, ul: NcChannel, ur: NcChannel, ll: NcChannel, lr: NcChannel, y_len: NcDim, x_len: NcDim, ) -> NcIntResult { if y_len < 1 || x_len < 1 { return NCRESULT_ERR; } let (mut y, mut x) = (0, 0); unsafe { crate::ncplane_cursor_yx(plane, &mut y, &mut x); crate::ncplane_gradient( plane, &(*egc as i8), stylemask as u32, ul as u64, ur as u64, ll as u64, lr as u64, y + y_len as i32 - 1, x + x_len as i32 - 1, ) } } libnotcurses-sys-2.1.8/src/plane/test/methods.rs010064400017500001750000000001511376441154400201170ustar 00000000000000//! Test `NcPlane` methods and associated functions. // use crate::NcPlane; // use serial_test::serial; libnotcurses-sys-2.1.8/src/plane/test/mod.rs010064400017500001750000000001211376441154400172300ustar 00000000000000//! `NcPlane` tests. #[cfg(test)] mod methods; #[cfg(test)] mod reimplemented; libnotcurses-sys-2.1.8/src/plane/test/reimplemented.rs010064400017500001750000000146761377156272500213350ustar 00000000000000//! Test `ncplane_*` reimplemented functions. use crate::{ncplane_new_test, notcurses_init_test, notcurses_stop, NCRESULT_OK}; use serial_test::serial; #[test] #[serial] fn ncplane_notcurses() { unsafe { let nc = notcurses_init_test(); let plane = ncplane_new_test(nc, 0, 0, 20, 20); let nc2 = crate::ncplane_notcurses(plane); assert_eq![nc as *mut _, nc2]; let nc3 = crate::ncplane_notcurses_const(plane); assert_eq![nc as *const _, nc3]; notcurses_stop(nc); } } #[test] #[serial] fn ncplane_cursor() { unsafe { let nc = notcurses_init_test(); let plane = ncplane_new_test(nc, 0, 0, 20, 20); let (mut y, mut x) = (0, 0); crate::ncplane_cursor_yx(plane, &mut y, &mut x); assert_eq![x, 0]; assert_eq![y, 0]; let res = crate::ncplane_cursor_move_yx(plane, 10, 15); assert_eq![res, 0]; crate::ncplane_cursor_yx(plane, &mut y, &mut x); assert_eq![x, 15]; assert_eq![y, 10]; crate::ncplane_home(plane); crate::ncplane_cursor_yx(plane, &mut y, &mut x); assert_eq![x, 0]; assert_eq![y, 0]; let _res = crate::ncplane_cursor_move_yx(plane, 10, 15); crate::ncplane_erase(plane); // has to move the cursor to 0,0 crate::ncplane_cursor_yx(plane, &mut y, &mut x); assert_eq![x, 0]; assert_eq![y, 0]; notcurses_stop(nc); } } #[test] #[serial] fn ncplane_channels() { unsafe { let nc = notcurses_init_test(); let plane = ncplane_new_test(nc, 0, 0, 20, 20); let channels = crate::ncplane_channels(plane); assert_eq![channels, 0]; crate::ncplane_set_channels(plane, 0x1122334455667788); assert_eq![0x1122334455667788, crate::ncplane_channels(plane)]; notcurses_stop(nc); } } #[test] #[serial] fn ncplane_fchannel() { unsafe { let nc = notcurses_init_test(); let plane = ncplane_new_test(nc, 0, 0, 20, 20); crate::ncplane_set_channels(plane, 0x1122334455667788); let channels = crate::ncplane_channels(plane); assert_eq![0x11223344, crate::channels_fchannel(channels)]; let channels = crate::ncplane_set_fchannel(plane, 0x10203040); assert_eq![0x10203040, crate::channels_fchannel(channels)]; assert_eq![0x1020304055667788, channels]; notcurses_stop(nc); } } #[test] #[serial] fn ncplane_bchannel() { unsafe { let nc = notcurses_init_test(); let plane = ncplane_new_test(nc, 0, 0, 20, 20); crate::ncplane_set_channels(plane, 0x1122334455667788); let channels = crate::ncplane_channels(plane); assert_eq![0x55667788, crate::channels_bchannel(channels)]; // BUG? ncplane_set_bchannel and ncplane_set_fchannel don't get // applied unless they are assigned to a variable. Weird. let channels = crate::ncplane_set_bchannel(plane, 0x50607080); assert_eq![0x50607080, crate::channels_bchannel(channels)]; assert_eq![0x1122334450607080, channels]; notcurses_stop(nc); } } #[test] #[serial] fn ncplane_rgb() { unsafe { let nc = notcurses_init_test(); let plane = ncplane_new_test(nc, 0, 0, 20, 20); crate::ncplane_set_fg_rgb(plane, 0x112233); assert_eq![0x112233, crate::ncplane_fg_rgb(plane)]; notcurses_stop(nc); } } #[test] #[serial] fn ncplane_default() { unsafe { let nc = notcurses_init_test(); let plane = ncplane_new_test(nc, 0, 0, 20, 20); assert_eq![true, crate::ncplane_bg_default_p(plane)]; assert_eq![true, crate::ncplane_fg_default_p(plane)]; crate::ncplane_set_bg_rgb8(plane, 11, 22, 33); crate::ncplane_set_fg_rgb8(plane, 44, 55, 66); assert_eq![false, crate::ncplane_bg_default_p(plane)]; assert_eq![false, crate::ncplane_fg_default_p(plane)]; crate::ncplane_set_bg_default(plane); crate::ncplane_set_fg_default(plane); assert_eq![true, crate::ncplane_bg_default_p(plane)]; assert_eq![true, crate::ncplane_fg_default_p(plane)]; notcurses_stop(nc); } } #[test] #[serial] fn ncplane_dimensions() { unsafe { let nc = notcurses_init_test(); let plane = ncplane_new_test(nc, 0, 0, 10, 20); let (mut y, mut x) = (0, 0); crate::ncplane_dim_yx(plane, &mut y, &mut x); assert_eq!((10, 20), (y, x)); assert_eq!(10, crate::ncplane_dim_y(plane)); assert_eq!(20, crate::ncplane_dim_x(plane)); notcurses_stop(nc); } } #[test] #[serial] fn ncplane_resize() { unsafe { let nc = notcurses_init_test(); let plane = ncplane_new_test(nc, 0, 0, 20, 20); let res = crate::ncplane_resize_simple(plane, 40, 40); assert_eq![NCRESULT_OK, res]; let (mut y, mut x) = (0, 0); crate::ncplane_dim_yx(plane, &mut y, &mut x); assert_eq!((40, 40), (y, x)); // TODO: test further plane subset keeping unchanged features let res = crate::ncplane_resize(plane, 0, 0, 0, 0, 0, 0, 60, 70); assert_eq![NCRESULT_OK, res]; assert_eq!(60, crate::ncplane_dim_y(plane)); assert_eq!(70, crate::ncplane_dim_x(plane)); notcurses_stop(nc); } } // TODO: resizecb #[test] #[serial] // TODO: CHECK: zeroes out every cell of the plane, dumps the egcpool, // The base cell is preserved. fn ncplane_erase() { unsafe { let nc = notcurses_init_test(); let plane = ncplane_new_test(nc, 0, 0, 20, 20); crate::ncplane_set_bg_rgb(plane, 0x112233); crate::ncplane_set_fg_rgb(plane, 0x445566); assert_eq![false, crate::ncplane_bg_default_p(plane)]; assert_eq![false, crate::ncplane_fg_default_p(plane)]; // FIXME? DEBUG crate::ncplane_erase(plane); // assert_eq![true, crate::ncplane_bg_default_p(plane)]; // assert_eq![true, crate::ncplane_fg_default_p(plane)]; //print!(" C: {:#0x} ", crate::ncplane_channels(plane)); notcurses_stop(nc); } } // #[test] // #[serial] // fn ncplane_at_cursor() { // unsafe { // let nc = notcurses_init_test(); // let plane = ncplane_new_test(nc, 0, 0, 20, 20); // // notcurses_stop(nc); // } // } // // #[test] // #[serial] // fn ncplane_at_cursor_cell() { // unsafe { // let nc = notcurses_init_test(); // let plane = ncplane_new_test(nc, 0, 0, 20, 20); // // notcurses_stop(nc); // } // } libnotcurses-sys-2.1.8/src/resizecb.rs010064400017500001750000000035261377416467000162230ustar 00000000000000//! `NcResizeCb` use crate::{NcIntResult, NcPlane}; /// A callback function called when an [NcPlane] is resized. /// /// See also [ncresizecb_to_rust] & [ncresizecb_to_c]. /// pub type NcResizeCb = fn(&mut NcPlane) -> NcIntResult; /// The unsafe version of [NcResizeCb] expected by the notcurses C API. pub type NcResizeCbUnsafe = unsafe extern "C" fn(*mut NcPlane) -> NcIntResult; /// Converts [NcResizeCbUnsafe] to [NcResizeCb]. pub fn ncresizecb_to_rust(resizecb: Option) -> Option { if let Some(cb) = resizecb { return Some(unsafe { core::mem::transmute(cb) }); } else { None } } /// Converts [NcResizeCb] to [NcResizeCbUnsafe]. /// // waiting for https://github.com/rust-lang/rust/issues/53605 // to make this function const, and then NcPlaneOptions constructors. pub fn ncresizecb_to_c(resizecb: Option) -> Option { if let Some(cb) = resizecb { return Some(unsafe { core::mem::transmute(cb) }); } else { None } } /// Enables the [NcResizeCb] methods. pub trait NcResizeCbMethods { fn to_rust(&self) -> Option; fn to_c(&self) -> Option; } impl NcResizeCbMethods for NcResizeCb { /// Returns [NcResizeCbUnsafe]. /// /// *C style function: [ncresizecb_to_c()][ncresizecb_to_c].* fn to_c(&self) -> Option { ncresizecb_to_c(Some(*self)) } /// no-op. fn to_rust(&self) -> Option { Some(*self) } } impl NcResizeCbMethods for NcResizeCbUnsafe { /// no-op. fn to_c(&self) -> Option { Some(*self) } /// Returns [NcResizeCb]. /// /// *C style function: [ncresizecb_to_rust()][ncresizecb_to_rust].* fn to_rust(&self) -> Option { ncresizecb_to_rust(Some(*self)) } } libnotcurses-sys-2.1.8/src/signal.rs010064400017500001750000000040101377156272500156570ustar 00000000000000//! `NcSigSet` use crate::NcIntResult; /// A wrapper over /// [sigset_t](https://www.gnu.org/software/libc/manual/html_node/Signal-Sets.html). // // Expected by [`notcurses_getc`], [`notcurses_getc_nblock`], // [`ncdirect_getc`] & [`ncdirect_getc_nblock`], that can't use libc::sigset_t pub type NcSignalSet = crate::bindings::ffi::sigset_t; impl NcSignalSet { /// New NcSignalSet. pub fn new() -> Self { Self { __val: [0; 16] } } /// Adds `signum` to this set. pub fn addset(&mut self, signum: i32) -> NcIntResult { unsafe { crate::bindings::ffi::sigaddset(self, signum) } } /// Removes `signum` from this set. pub fn delset(&mut self, signum: i32) -> NcIntResult { unsafe { crate::bindings::ffi::sigdelset(self, signum) } } /// Clears all signals from this set. pub fn emptyset(&mut self) -> NcIntResult { unsafe { crate::bindings::ffi::sigemptyset(self) } } /// Sets all signals in this set. pub fn fillset(&mut self) -> NcIntResult { unsafe { crate::bindings::ffi::sigfillset(self) } } /// Is `signum` a member of this set? pub fn ismember(&self, signum: i32) -> bool { if unsafe { crate::bindings::ffi::sigismember(self, signum) } == 1 { return true; } false } /// Puts in this set all signals that are blocked and waiting to be delivered. pub fn pending(&mut self) -> NcIntResult { unsafe { crate::bindings::ffi::sigpending(self) } } /// Gets and/or changes the set of blocked signals. // // https://linux.die.net/man/2/sigprocmask pub fn procmask(how: i32, set: &NcSignalSet, old_set: &mut NcSignalSet) -> NcIntResult { unsafe { crate::bindings::ffi::sigprocmask(how, set, old_set) } } /// Changes the set of blocked signals to the ones in this set, /// waits until a signal arrives, and restores the set of blocked signals. pub fn suspend(&self) -> NcIntResult { unsafe { crate::bindings::ffi::sigsuspend(self) } } } libnotcurses-sys-2.1.8/src/stats.rs010064400017500001750000000012461377422371100155400ustar 00000000000000//! `NcStats` use crate::Notcurses; /// notcurses runtime statistics pub type NcStats = crate::bindings::ffi::ncstats; /// # `NcStats` Methods. impl NcStats { /// Allocates an NcStats object. pub fn new<'a>(nc: &'a Notcurses) -> &'a mut Self { unsafe { &mut *crate::notcurses_stats_alloc(nc) } } /// Acquires an atomic snapshot of the Notcurses object's stats. pub fn stats(&mut self, nc: &Notcurses) { unsafe { crate::notcurses_stats(nc, self) } } /// Resets all cumulative stats (immediate ones are not reset). pub fn reset(&mut self, nc: &mut Notcurses) { unsafe { crate::notcurses_stats_reset(nc, self) } } } libnotcurses-sys-2.1.8/src/time.rs010064400017500001750000000004361377156272500153500ustar 00000000000000//! `NcTime` /// // Expected by [`notcurses_getc`] & [`notcurses_getc_nblock`], that can't use // libc::timespec pub type NcTime = crate::bindings::ffi::timespec; impl NcTime { pub fn new() -> Self { Self { tv_sec: 0, tv_nsec: 0, } } } libnotcurses-sys-2.1.8/src/visual.rs010064400017500001750000000042311377416500600157040ustar 00000000000000//! `ncvisual` // TODO: implement constructors // functions already exported by bindgen : 18 // ----------------------------------------- // (W) wrap: 0 // (#) test: 0 // ----------------------------------------- // ncvisual_at_yx // ncvisual_decode // ncvisual_decode_loop // ncvisual_destroy // ncvisual_from_bgra // ncvisual_from_file // ncvisual_from_plane // ncvisual_from_rgba // ncvisual_geom // ncvisual_media_defblitter // ncvisual_polyfill_yx // ncvisual_render // ncvisual_resize // ncvisual_rotate // ncvisual_set_yx // ncvisual_simple_streamer // ncvisual_stream // ncvisual_subtitle /// How to scale an [`NcVisual`] during rendering /// /// - NCSCALE_NONE will apply no scaling. /// - NCSCALE_SCALE scales a visual to the plane's size, /// maintaining aspect ratio. /// - NCSCALE_STRETCH stretches and scales the image in an /// attempt to fill the entirety of the plane. /// pub type NcScale = crate::bindings::ffi::ncscale_e; /// Maintain original size. pub const NCSCALE_NONE: NcScale = crate::bindings::ffi::ncscale_e_NCSCALE_NONE; /// Maintain aspect ratio. pub const NCSCALE_SCALE: NcScale = crate::bindings::ffi::ncscale_e_NCSCALE_SCALE; /// Throw away aspect ratio. pub const NCSCALE_STRETCH: NcScale = crate::bindings::ffi::ncscale_e_NCSCALE_STRETCH; /// Maintain original size, admitting high-resolution blitters /// that don't preserve aspect ratio. pub const NCSCALE_NONE_HIRES: NcScale = crate::bindings::ffi::ncscale_e_NCSCALE_NONE_HIRES; /// Maintain aspect ratio, admitting high-resolution blitters /// that don't preserve aspect ratio. pub const NCSCALE_SCALE_HIRES: NcScale = crate::bindings::ffi::ncscale_e_NCSCALE_SCALE_HIRES; /// A visual bit of multimedia opened with LibAV|OIIO pub type NcVisual = crate::bindings::ffi::ncvisual; /// Options struct for [`NcVisual`] pub type NcVisualOptions = crate::bindings::ffi::ncvisual_options; /// Uses [`NCCELL_ALPHA_BLEND`][crate::NCCELL_ALPHA_BLEND] with visual. pub const NCVISUAL_OPTION_BLEND: u32 = crate::bindings::ffi::NCVISUAL_OPTION_BLEND; /// Fails rather than degrade. pub const NCVISUAL_OPTION_NODEGRADE: u32 = crate::bindings::ffi::NCVISUAL_OPTION_NODEGRADE; libnotcurses-sys-2.1.8/src/widgets/menu/methods/menu.rs010064400017500001750000000145531377441112000214210ustar 00000000000000use core::ptr::null_mut; use crate::{ cstring, error, error_ref_mut, error_str, ncmenu_create, NcInput, NcMenu, NcMenuOptions, NcPlane, NcResult, }; /// # `NcMenu` constructors & destructors impl NcMenu { /// Creates an [NcMenu] with the specified options. /// /// Menus are currently bound to an overall [FullMode][crate::FullMode] /// object (as opposed to a particular plane), and are implemented as /// [NcPlane]s kept atop other NcPlanes. /// /// *C style function: [ncmenu_create()][crate::ncmenu_create].* pub fn new<'a>(plane: &mut NcPlane, options: NcMenuOptions) -> NcResult<&'a mut Self> { error_ref_mut![unsafe { ncmenu_create(plane, &options) }, "Creating NcMenu"] } /// Destroys an NcMenu created with [new()][NcMenu#method.new]. /// /// *C style function: [ncmenu_destroy()][crate::ncmenu_destroy].* pub fn destroy(&mut self) -> NcResult<()> { error![unsafe { crate::ncmenu_destroy(self) }] } } /// # `NcMenu` methods impl NcMenu { /// Disables or enables an [NcMenuItem][crate::NcMenuItem]. /// /// *C style function: [ncmenu_item_set_status()][crate::ncmenu_item_set_status].* pub fn item_set_status(&mut self, section: &str, item: &str, enabled: bool) -> NcResult<()> { error![ unsafe { crate::ncmenu_item_set_status(self, cstring![section], cstring![item], enabled) }, &format!( ".item_set_status({:?}, {:?}, {:?}, {})", self, section, item, enabled ) ] } /// Returns the [NcMenuItem][crate::NcMenuItem] description /// corresponding to the mouse `click`. /// /// The NcMenuItem must be on an actively unrolled section, and the click /// must be in the area of a valid item. /// /// If `ninput` is provided, and the selected item has a shortcut, /// it will be filled in with that shortcut. /// /// *C style function: [ncmenu_mouse_selected()][crate::ncmenu_mouse_selected].* pub fn mouse_selected( &self, click: NcInput, shortcut: Option<&mut NcInput>, ) -> NcResult { let ninput; if let Some(i) = shortcut { ninput = i as *mut _; } else { ninput = null_mut(); } error_str![ unsafe { crate::ncmenu_mouse_selected(self, &click, ninput) }, "Getting NcMenuItem description" ] } /// Moves to the next item within the currently unrolled section. /// /// If no section is unrolled, the first section will be unrolled. /// /// *C style function: [ncmenu_nextitem()][crate::ncmenu_nextitem].* pub fn nextitem(&mut self) -> NcResult<()> { error![unsafe { crate::ncmenu_nextitem(self) }] } /// Unrolls the next section (relative to current unrolled). /// /// If no section is unrolled, the first section will be unrolled. /// /// *C style function: [ncmenu_nextsection()][crate::ncmenu_nextsection].* pub fn nextsection(&mut self) -> NcResult<()> { error![unsafe { crate::ncmenu_nextsection(self) }] } /// Offers the `input` to this NcMenu. /// /// If it's relevant, this function returns true, /// and the input ought not be processed further. /// If it's irrelevant to the menu, false is returned. /// /// Relevant inputs include: /// - mouse movement over a hidden menu /// - a mouse click on a menu section (the section is unrolled) /// - a mouse click outside of an unrolled menu (the menu is rolled up) /// - left or right on an unrolled menu (navigates among sections) /// - up or down on an unrolled menu (navigates among items) /// - escape on an unrolled menu (the menu is rolled up) /// /// *C style function: [ncmenu_offer_input()][crate::ncmenu_offer_input].* pub fn offer_input(&mut self, input: NcInput) -> bool { unsafe { crate::ncmenu_offer_input(self, &input) } } /// Returns the [NcPlane] backing this NcMenu. /// /// *C style function: [ncmenu_plane()][crate::ncmenu_plane].* pub fn plane(&mut self) -> NcResult<&NcPlane> { error_ref_mut![ unsafe { crate::ncmenu_plane(self) }, "Getting the backing NcPlane" ] } /// Moves to the previous item within the currently unrolled section. /// /// If no section is unrolled, the first section will be unrolled. /// /// *C style function: [ncmenu_previtem()][crate::ncmenu_previtem].* pub fn previtem(&mut self) -> NcResult<()> { error![unsafe { crate::ncmenu_previtem(self) }] } /// Unrolls the previous section (relative to current unrolled). /// /// If no section is unrolled, the first section will be unrolled. /// /// *C style function: [ncmenu_prevsection()][crate::ncmenu_prevsection].* pub fn prevsection(&mut self) -> NcResult<()> { error![unsafe { crate::ncmenu_prevsection(self) }] } /// Rolls up any unrolled [NcMenuSection][crate::NcMenuSection], /// and hides this NcMenu if using hiding. /// /// *C style function: [ncmenu_rollup()][crate::ncmenu_rollup].* pub fn rollup(&mut self) -> NcResult<()> { error![unsafe { crate::ncmenu_rollup(self) }] } /// Returns the selected item description, if there's an unrolled section. /// /// If `shortcut` is provided, and the selected item has a shortcut, /// it will be filled in with that shortcut--this can allow faster matching. /// /// *C style function: [ncmenu_selected()][crate::ncmenu_selected].* pub fn selected(&mut self, shortcut: Option<&mut NcInput>) -> Option { let ninput; if let Some(i) = shortcut { ninput = i as *mut _; } else { ninput = null_mut(); } let res = unsafe { crate::ncmenu_selected(self, ninput) }; if res != null_mut() { return Some(unsafe { (&*res).to_string() }); } None } /// Unrolls the specified [NcMenuSection][crate::NcMenuSection], /// making the menu visible if it was invisible, /// and rolling up any NcMenuSection that is already unrolled. /// /// *C style function: [ncmenu_unroll()][crate::ncmenu_unroll].* pub fn unroll(&mut self, sectionindex: u32) -> NcResult<()> { error![unsafe { crate::ncmenu_unroll(self, sectionindex as i32) }] } } libnotcurses-sys-2.1.8/src/widgets/menu/methods/mod.rs010064400017500001750000000031221377416525400212400ustar 00000000000000//! `NcMenu*` methods and associated functions. use core::ptr::null_mut; use crate::{cstring_mut, NcInput, NcMenuItem, NcMenuSection}; mod menu; mod options; pub use menu::*; pub use options::*; /// # `NcMenuItem` Constructors impl NcMenuItem { /// New NcMenuItem for [NcMenu][crate::NcMenu]. pub fn new(desc: &str, shortcut: NcInput) -> Self { Self { // utf-8 menu item, NULL for horizontal separator desc: cstring_mut![desc], // ´NcInput´ shortcut, all should be distinct shortcut, } } /// New empty NcMenuItem for [NcMenu][crate::NcMenu]. pub fn new_empty() -> Self { Self { desc: null_mut(), shortcut: NcInput::new_empty(), } } } /// # `NcMenuSection` Constructors /// // Must contain at least 1 NcMenuItem. impl NcMenuSection { /// New NcMenuSection for [NcMenu][crate::NcMenu]. pub fn new(name: &str, items: &mut [NcMenuItem], shortcut: NcInput) -> Self { Self { // utf-8 name string name: cstring_mut![name], // array of itemcount `NcMenuItem`s items: items.as_mut_ptr(), // itemcount: items.len() as i32, // shortcut, will be underlined if present in name shortcut, } } /// New NcMenuSection separator for [NcMenu][crate::NcMenu]. /// pub fn new_separator() -> Self { Self { name: null_mut(), items: null_mut(), itemcount: 0, shortcut: NcInput::new_empty(), } } } libnotcurses-sys-2.1.8/src/widgets/menu/methods/options.rs010064400017500001750000000037661377416467000221730ustar 00000000000000use crate::{NcChannelPair, NcMenuOptions, NcMenuSection}; /// # `NcMenuOptions` constructors impl NcMenuOptions { /// New NcMenuOptions for [NcMenu][crate::NcMenu]. /// /// `sections` must contain at least 1 [NcMenuSection]. pub fn new(sections: &mut [NcMenuSection]) -> Self { Self::with_all_args(sections, 0, 0, 0) } /// New NcMenuOptions for [NcMenu][crate::NcMenu], with all args. /// /// `sections` must contain at least 1 [NcMenuSection]. pub fn with_all_args( sections: &mut [NcMenuSection], style_header: NcChannelPair, style_sections: NcChannelPair, flags: u64, ) -> Self { assert![sections.len() > 0]; Self { // array of 'sectioncount' `MenuSection`s sections: sections.as_mut_ptr(), // sectioncount: sections.len() as i32, // styling for header headerchannels: style_header, // styling for sections sectionchannels: style_sections, // flag word of NCMENU_OPTION_* flags: flags, } } } /// # `NcMenuOptions` methods impl NcMenuOptions { /// Returns the styling for the header. /// /// *(No equivalent C style function)* pub const fn header_channels(&self) -> NcChannelPair { self.headerchannels } /// Returns a mutable reference of the styling for the sections. /// /// *(No equivalent C style function)* pub fn header_channels_mut<'a>(&'a mut self) -> &'a mut NcChannelPair { &mut self.headerchannels } /// Returns the styling for the sections. /// /// *(No equivalent C style function)* pub const fn section_channels(&self) -> NcChannelPair { self.sectionchannels } /// Returns a mutable reference of the styling for the sections. /// /// *(No equivalent C style function)* pub fn section_channels_mut<'a>(&'a mut self) -> &'a mut NcChannelPair { &mut self.sectionchannels } } libnotcurses-sys-2.1.8/src/widgets/menu/mod.rs010064400017500001750000000034071377416724100176010ustar 00000000000000//! `NcMenu` widget // functions already exported by bindgen : 13 // ------------------------------------------ // (#) test: 0 // (W) wrap: 13 // ------------------------------------------ //W ncmenu_create //W ncmenu_destroy //W ncmenu_item_set_status //W ncmenu_mouse_selected //W ncmenu_nextitem //W ncmenu_nextsection //W ncmenu_offer_input //W ncmenu_plane //W ncmenu_previtem //W ncmenu_prevsection //W ncmenu_rollup //W ncmenu_selected //W ncmenu_unroll mod methods; /// menus on the top or bottom rows /// /// A [FullMode][crate::FullMode] instance supports menu bars /// on the top or bottom row of the true screen. /// /// An NcMenu is composed of [NcMenuSection]s, which are in turn composed of /// [NcMenuItem]s. /// /// Either no sections are visible, and the menu is rolled up, or exactly one /// section is unrolled. /// /// - [rollup()][NcMenu#method.rollup] /// places an `NcMenu` in the rolled up state. /// - [unroll()][NcMenu#method.unroll] /// rolls up any unrolled section and unrolls the specified one. /// - [destroy()][NcMenu#method.destroy] /// removes a menu bar, and frees all associated resources. /// /// `type in C: ncmenu (struct)` pub type NcMenu = crate::bindings::ffi::ncmenu; /// Options struct for [`NcMenu`] pub type NcMenuOptions = crate::bindings::ffi::ncmenu_options; /// Item for [`NcMenu`] pub type NcMenuItem = crate::bindings::ffi::ncmenu_item; /// Section for [`NcMenu`] pub type NcMenuSection = crate::bindings::ffi::ncmenu_section; /// [NcMenuOptions] flag: Bottom row (as opposed to top row). pub const NCMENU_OPTION_BOTTOM: u64 = crate::bindings::ffi::NCMENU_OPTION_BOTTOM as u64; /// [NcMenuOptions] flag: Hide the menu when not unrolled pub const NCMENU_OPTION_HIDING: u64 = crate::bindings::ffi::NCMENU_OPTION_HIDING as u64; libnotcurses-sys-2.1.8/src/widgets/mod.rs010064400017500001750000000003571377056154100166330ustar 00000000000000//! Widgets mod menu; mod multiselector; mod plot; mod progbar; mod reader; mod reel; mod selector; pub use menu::*; pub use multiselector::*; pub use plot::*; pub use progbar::*; pub use reader::*; pub use reel::*; pub use selector::*; libnotcurses-sys-2.1.8/src/widgets/multiselector/mod.rs010064400017500001750000000006021376441154400215170ustar 00000000000000//! `NcMultiSelector` widget. /// high-level widget for selecting items from a set pub type NcMultiSelector = crate::bindings::ffi::ncmultiselector; /// an item for [`NcMultiSelector`] pub type NcMultiSelectorItem = crate::bindings::ffi::ncmselector_item; /// Options structure for [`NcMultiSelector`] pub type NcMultiSelectorOptions = crate::bindings::ffi::ncmultiselector_options; libnotcurses-sys-2.1.8/src/widgets/plot/mod.rs010064400017500001750000000020351376441154400176040ustar 00000000000000//! `NcPlot[F|U]64` widget. /// A histogram, bound to an [`NcPlane`][crate::NcPlane] /// (uses non-negative `f64`s) pub type NcPlotF64 = crate::bindings::ffi::ncdplot; /// A histogram, bound to an [`NcPlane`][crate::NcPlane] (uses `u64`s) pub type NcPlotU64 = crate::bindings::ffi::ncuplot; /// Options struct for /// [`NcPlotF64`] or [`NcPlotU64`] pub type NcPlotOptions = crate::bindings::ffi::ncplot_options; /// Use domain detection only for max pub const NCPLOT_OPTION_DETECTMAXONLY: u32 = crate::bindings::ffi::NCPLOT_OPTION_DETECTMAXONLY; /// Exponential dependent axis pub const NCPLOT_OPTION_EXPONENTIALD: u32 = crate::bindings::ffi::NCPLOT_OPTION_EXPONENTIALD; /// Show labels for dependent axis pub const NCPLOT_OPTION_LABELTICKSD: u32 = crate::bindings::ffi::NCPLOT_OPTION_LABELTICKSD; /// Use domain detection only for max pub const NCPLOT_OPTION_NODEGRADE: u32 = crate::bindings::ffi::NCPLOT_OPTION_NODEGRADE; /// Independent axis is vertical pub const NCPLOT_OPTION_VERTICALI: u32 = crate::bindings::ffi::NCPLOT_OPTION_VERTICALI; libnotcurses-sys-2.1.8/src/widgets/progbar/methods.rs010064400017500001750000000043131377416467000211550ustar 00000000000000//! `NcProgBar` & `NcProgBarOptions` methods and associated functions. use crate::{error, NcPlane, NcProgBar, NcProgBarOptions, NcResult}; /// # `NcProgBarOptions` Methods impl NcProgBarOptions { /// New NcProgBarOptions for [NcProgBar]. pub fn new() -> Self { Self { ulchannel: 0, urchannel: 0, blchannel: 0, brchannel: 0, flags: 0, } } } /// # `NcProgBar` Methods impl NcProgBar { /// New NcProgBar. /// /// Takes ownership of the `plane`, which will be destroyed by /// [destroy][NcProgBar#method.destroy](). The progress bar is initially at 0%. pub fn new<'a>(plane: &mut NcPlane) -> &'a mut Self { Self::with_options(plane, &NcProgBarOptions::new()) } /// New NcProgBar. Expects an [NcProgBarOptions] struct. /// /// *C style function: [ncprogbar_create()][crate::ncprogbar_create].* pub fn with_options<'a>(plane: &mut NcPlane, options: &NcProgBarOptions) -> &'a mut Self { unsafe { &mut *crate::ncprogbar_create(plane, options) } } /// Destroy the progress bar and its underlying ncplane. /// /// *C style function: [ncprogbar_destroy()][crate::ncprogbar_destroy].* pub fn destroy(&mut self) { unsafe { crate::ncprogbar_destroy(self); } } /// Return a reference to the ncprogbar's underlying ncplane. /// /// *C style function: [ncprogbar_plane()][crate::ncprogbar_plane].* pub fn plane<'a>(&'a mut self) -> &'a mut NcPlane { unsafe { &mut *crate::ncprogbar_plane(self) } } /// Get the progress bar's completion, an [f64] on [0, 1]. /// /// *C style function: [ncprogbar_progress()][crate::ncprogbar_progress].* pub fn progress(&self) -> f64 { unsafe { crate::ncprogbar_progress(self) } } /// Sets the progress bar's completion, an 0 <= [f64] <= 1. /// /// Returns [NCRESULT_ERR][crate::NCRESULT_ERR] if progress is < 0 || > 1. /// /// *C style function: [ncprogbar_set_progress()][crate::ncprogbar_set_progress].* pub fn set_progress(&mut self, progress: f64) -> NcResult<()> { error![unsafe { crate::ncprogbar_set_progress(self, progress) }] } } libnotcurses-sys-2.1.8/src/widgets/progbar/mod.rs010064400017500001750000000026351377056154100202700ustar 00000000000000//! `NcProgbar` widget. // functions already exported by bindgen : 5 // ----------------------------------------- // (#) test: 0 // (W) wrap: 5 / 0 // ----------------------------------------- //W ncprogbar_create, //W ncprogbar_destroy, //W ncprogbar_plane, //W ncprogbar_progress, //W ncprogbar_set_progress, mod methods; /// Progress bars. They proceed linearly in any of four directions. /// /// The entirety of the plane will be used -- any border should be provided by /// the caller on another plane. /// /// The plane will not be erased; text preloaded into the plane will be consumed /// by the progress indicator. /// /// The bar is redrawn for each provided progress report (a double between 0 /// and 1), and can regress with lower values. /// /// The procession will take place along the longer dimension at the time of each /// redraw, with the horizontal length scaled by 2 for purposes of comparison. /// I.e. for a plane of 20 rows and 50 columns, the progress will be to the /// right (50 > 40), or left with [NCPROGBAR_OPTION_RETROGRADE]. /// /// `type in C: ncprogbar (struct)` /// pub type NcProgBar = crate::bindings::ffi::ncprogbar; /// Options struct for [`NcProgBar`] /// /// `type in C: ncprogbar_options (struct)` /// pub type NcProgBarOptions = crate::bindings::ffi::ncprogbar_options; /// proceed left/down pub const NCPROGBAR_OPTION_RETROGRADE: u32 = crate::bindings::ffi::NCPROGBAR_OPTION_RETROGRADE; libnotcurses-sys-2.1.8/src/widgets/reader/methods.rs010064400017500001750000000017211377416467000207630ustar 00000000000000//! `NcReader*` methods and associated functions. use crate::{error_ref_mut, ncreader_create, NcPlane, NcReader, NcReaderOptions, NcResult}; /// # `NcReaderOptions` Constructors impl NcReaderOptions { /// `NcReaderOptions` simple constructor pub const fn new() -> Self { Self { // channels used for input tchannels: 0, // attributes used for input tattrword: 0, // bitfield of NCREADER_OPTION_* flags: 0, } } } /// # `NcReader` Constructors impl NcReader { /// `NcReader` simple constructor pub fn new<'a>(plane: &mut NcPlane) -> NcResult<&'a mut Self> { Self::with_options(plane, NcReaderOptions::new()) } /// `NcReader` constructor with options pub fn with_options<'a>( plane: &mut NcPlane, options: NcReaderOptions, ) -> NcResult<&'a mut Self> { error_ref_mut![unsafe { ncreader_create(plane, &options) }] } } libnotcurses-sys-2.1.8/src/widgets/reader/mod.rs010064400017500001750000000031771376441154400201000ustar 00000000000000//! `NcReader` widget. // functions already exported by bindgen : 11 // ------------------------------------------ // ncreader_clear // ncreader_contents // ncreader_create // ncreader_destroy // ncreader_move_down // ncreader_move_left // ncreader_move_right // ncreader_move_up // ncreader_offer_input // ncreader_plane // ncreader_write_egc mod methods; /// Provides a freeform input in a (possibly multiline) region /// /// Supports optional readline keybindings (opt out using /// NCREADER_OPTION_NOCMDKEYS flag) /// /// Takes ownership of its [`NcPlane`][crate::NcPlane], destroying it on any /// error (`ncreader_destroy`() otherwise destroys the ncplane). /// /// `type in C: ncreader (struct)` /// pub type NcReader = crate::bindings::ffi::ncreader; /// Options struct for [`NcReader`] /// /// `type in C: ncreader_options (struct)` /// pub type NcReaderOptions = crate::bindings::ffi::ncreader_options; /// Make the terminal cursor visible across the lifetime of the ncreader, and /// have the ncreader manage the cursor's placement. pub const NCREADER_OPTION_CURSOR: u32 = crate::bindings::ffi::NCREADER_OPTION_CURSOR; /// Enable horizontal scrolling. Virtual lines can then grow arbitrarily long. pub const NCREADER_OPTION_HORSCROLL: u32 = crate::bindings::ffi::NCREADER_OPTION_HORSCROLL; /// Disable all editing shortcuts. By default, emacs-style keys are available. pub const NCREADER_OPTION_NOCMDKEYS: u32 = crate::bindings::ffi::NCREADER_OPTION_NOCMDKEYS; /// Enable vertical scrolling. You can then use arbitrarily many virtual lines. pub const NCREADER_OPTION_VERSCROLL: u32 = crate::bindings::ffi::NCREADER_OPTION_VERSCROLL; libnotcurses-sys-2.1.8/src/widgets/reel/mod.rs010064400017500001750000000027201377422371100175540ustar 00000000000000//! `NcReel` widget. /// A wheel with [`NcTablet`]s on the outside. /// /// An `NcReel` is projected onto the 2d rendering area, showing some portion of /// the `NcReel`, and zero or more `NcTablet`s. /// /// An `NcReel` is a [`FullMode`][crate::FullMode] region devoted to displaying /// zero or more line-oriented, contained [`NcTablet`]s /// between which the user may navigate. /// /// If at least one `NcTablet`s exists, there is a "focused tablet". /// As much of the focused tablet as is possible is always displayed. /// /// If there is space left over, other tablets are included in the display. /// Tablets can come and go at any time, and can grow or shrink at any time. pub type NcReel = crate::bindings::ffi::ncreel; /// Options struct for [`NcReel`] pub type NcReelOptions = crate::bindings::ffi::ncreel_options; /// Visual tablet for [`NcReel`] pub type NcTablet = crate::bindings::ffi::nctablet; /// is navigation circular (does moving down from the last tablet move to the /// first, and vice versa)? only meaningful when infinitescroll is true. if /// infinitescroll is false, this must be false. pub const NCREEL_OPTION_CIRCULAR: u32 = crate::bindings::ffi::NCREEL_OPTION_CIRCULAR; /// is scrolling infinite (can one move down or up forever, or is an end /// reached?). if true, 'circular' specifies how to handle the special case of /// an incompletely-filled reel. pub const NCREEL_OPTION_INFINITESCROLL: u32 = crate::bindings::ffi::NCREEL_OPTION_INFINITESCROLL; libnotcurses-sys-2.1.8/src/widgets/selector/mod.rs010064400017500001750000000005331376441154400204470ustar 00000000000000//! `NcSelector` widget. /// high-level widget for selecting one item from a set pub type NcSelector = crate::bindings::ffi::ncselector; /// an item for [`NcSelector`] pub type NcSelectorItem = crate::bindings::ffi::ncselector_item; /// Options structur for [`NcSelector`] pub type NcSelectorOptions = crate::bindings::ffi::ncselector_options;