diff --git a/rust/src/bindings.rs b/rust/src/bindings.rs index 0093ca894..feef18b67 100644 --- a/rust/src/bindings.rs +++ b/rust/src/bindings.rs @@ -126,6 +126,16 @@ pub use ffi::{ // NCBOXMASK_RIGHT, // NCBOXMASK_TOP, +// nccapabilit* ---------------------------------------------------------------- +// +// already wrapped: +// +// // structs +// nccapabilities, +// +// // functions +// nccapability_canchangecolor, + // ncdirect -------------------------------------------------------------------- // // already wrapped: @@ -133,6 +143,16 @@ pub use ffi::{ // // structs // ncdirect, // +// // functions +// ncdirect_canbraille, +// ncdirect_canopen_videos +// ncdirect_canchangecolor, +// ncdirect_canfade, +// ncdirect_canhalfblock, +// ncdirect_canquadrant, +// ncdirect_cantruecolor, +// ncdirect_capabilities, +// // // constants // NCDIRECT_OPTION_INHIBIT_CBREAK, // NCDIRECT_OPTION_INHIBIT_SETLOCALE, diff --git a/rust/src/capabilities.rs b/rust/src/capabilities.rs new file mode 100644 index 000000000..42b107fb0 --- /dev/null +++ b/rust/src/capabilities.rs @@ -0,0 +1,26 @@ +//! `NcCapabilities` + +use crate::NcPalette; + +use core::mem::size_of; + +/// Capabilities, derived from terminfo, environment variables, and queries. +pub type NcCapabilities = crate::bindings::ffi::nccapabilities; + +/// Can we set the "hardware" palette? +/// +/// Requires the "ccc" terminfo capability, and that the number of colors +/// supported is at least the size of our `NcPalette` structure. +#[inline] +pub fn nccapability_canchangecolor(caps: &NcCapabilities) -> bool { + if !caps.can_change_colors { + return false; + } + // CHECK this does the same as: + // if(caps.colors < sizeof(p->chans) / sizeof(*p->chans)){ + // + if (caps.colors as usize) < size_of::() / size_of::() { + return false; + } + true +} diff --git a/rust/src/direct/methods.rs b/rust/src/direct/methods.rs index b9b91c424..eda8ffbdf 100644 --- a/rust/src/direct/methods.rs +++ b/rust/src/direct/methods.rs @@ -4,9 +4,9 @@ use core::ptr::{null, null_mut}; use crate::ffi::sigset_t; use crate::{ - cstring, error, error_ref_mut, rstring, NcAlign, NcBlitter, NcChannels, NcComponent, NcDim, - NcDirect, NcDirectFlags, NcDirectV, NcEgc, NcError, NcInput, NcPaletteIndex, NcResult, NcRgb, - NcScale, NcStyle, NcTime, NCRESULT_ERR, + cstring, error, error_ref_mut, rstring, NcAlign, NcBlitter, NcCapabilities, NcChannels, + NcComponent, NcDim, NcDirect, NcDirectFlags, NcDirectV, NcEgc, NcError, NcInput, + NcPaletteIndex, NcResult, NcRgb, NcScale, NcStyle, NcTime, NCRESULT_ERR, }; /// # `NcDirect` constructors and destructors @@ -280,6 +280,38 @@ impl NcDirect { /// ## NcDirect methods: capabilities, cursor, dimensions impl NcDirect { + /// Can we reliably use Unicode braille? + /// + /// *C style function: [ncdirect_canbraille()][crate::ncdirect_canbraille].* + pub fn canbraille(&self) -> bool { + crate::ncdirect_canbraille(self) + } + + /// Can we set the "hardware" palette? + /// + /// Requires the "ccc" terminfo capability. + /// + /// *C style function: [ncdirect_canchangecolor()][crate::ncdirect_canchangecolor].* + pub fn canchangecolor(&self) -> bool { + crate::ncdirect_canchangecolor(self) + } + + /// Can we fade? + /// + /// Requires either the "rgb" or "ccc" terminfo capability. + /// + /// *C style function: [ncdirect_canfade()][crate::ncdirect_canfade].* + pub fn canfade(&self) -> bool { + crate::ncdirect_canfade(self) + } + + /// Can we reliably use Unicode halfblocks? + /// + /// *C style function: [ncdirect_canhalfblock()][crate::ncdirect_canhalfblock].* + pub fn canhalfblock(&self) -> bool { + crate::ncdirect_canhalfblock(self) + } + /// Can we load images? /// /// Requires being built against FFmpeg/OIIO. @@ -289,6 +321,29 @@ impl NcDirect { unsafe { crate::ncdirect_canopen_images(self) } } + /// Can we load videos? + /// + /// Requires being built against FFmpeg/OIIO. + /// + /// *C style function: [ncdirect_canopen_videos()][crate::ncdirect_canopen_videos].* + pub fn canopen_videos(&self) -> bool { + crate::ncdirect_canopen_videos(self) + } + + /// Can we reliably use Unicode quadrants? + /// + /// *C style function: [ncdirect_canquadrant()][crate::ncdirect_canquadrant].* + pub fn canquadrant(&self) -> bool { + crate::ncdirect_canquadrant(self) + } + + /// Can we directly specify RGB values per cell, or only use palettes? + /// + /// *C style function: [ncdirect_cantruecolor()][crate::ncdirect_cantruecolor].* + pub fn cantruecolor(&self) -> bool { + crate::ncdirect_cantruecolor(self) + } + /// Is our encoding UTF-8? /// /// Requires LANG being set to a UTF8 locale. @@ -298,6 +353,13 @@ impl NcDirect { unsafe { crate::ncdirect_canutf8(self) } } + /// Returns the [`NcCapabilities`]. + /// + /// *C style function: [ncdirect_capabilities()][crate::ncdirect_capabilities].* + pub fn capabilities(&self) -> NcCapabilities { + crate::ncdirect_capabilities(self) + } + /// Checks for pixel support. /// /// Returns `false` for no support, or `true` if pixel output is supported. diff --git a/rust/src/direct/mod.rs b/rust/src/direct/mod.rs index a177979a8..cd6b08700 100644 --- a/rust/src/direct/mod.rs +++ b/rust/src/direct/mod.rs @@ -1,13 +1,13 @@ //! `NcDirect` -// total: 53 +// total: 61 // --------------------------------------------------- // (X) 1 : wont do // (~) 3 : TODO / WIP // // (f) 45 : unsafe ffi function exported by bindgen -// (w) 0 : safely wrapped ffi function -// (r) 4 : static function manually reimplemented +// (w) 1 : safely wrapped ffi function +// (r) 11 : static function manually reimplemented // // (m) 45 : method implemented // @@ -18,8 +18,16 @@ // fm ncdirect_bg_palindex // fm ncdirect_bg_rgb // fm ncdirect_box +// r ncdirect_canbraille +// r ncdirect_canchangecolor +// r ncdirect_canfade +// r ncdirect_canhalfblock // fm ncdirect_canopen_images +// rm ncdirect_canopen_videos +// r ncdirect_canquadrant +// r ncdirect_cantruecolor // fm ncdirect_canutf8 +// wm ncdirect_capabilities // fm ncdirect_check_pixel_support // fm ncdirect_clear //~f ncdirect_core_init diff --git a/rust/src/direct/reimplemented.rs b/rust/src/direct/reimplemented.rs index 561ebd588..21fdea585 100644 --- a/rust/src/direct/reimplemented.rs +++ b/rust/src/direct/reimplemented.rs @@ -2,7 +2,63 @@ use core::ptr::null; -use crate::{NcComponent, NcDirect, NcInput, NcIntResult, NcRgb, NcSignalSet, NcTime}; +use crate::{ + NcCapabilities, NcComponent, NcDirect, NcInput, NcIntResult, NcRgb, NcSignalSet, NcTime, +}; + +/// Can we directly specify RGB values per cell, or only use palettes? +#[inline] +pub fn ncdirect_cantruecolor(ncd: &NcDirect) -> bool { + ncdirect_capabilities(ncd).rgb +} + +/// Can we set the "hardware" palette? Requires the "ccc" terminfo capability. +#[inline] +pub fn ncdirect_canchangecolor(ncd: &NcDirect) -> bool { + crate::nccapability_canchangecolor(&ncdirect_capabilities(ncd)) +} + +/// Can we fade? Fading requires either the "rgb" or "ccc" terminfo capability. +#[inline] +pub fn ncdirect_canfade(ncd: &NcDirect) -> bool { + ncdirect_canchangecolor(ncd) || ncdirect_cantruecolor(ncd) +} + +/// Can we load videos? This requires being built against FFmpeg. +#[inline] +pub fn ncdirect_canopen_videos(_ncd: &NcDirect) -> bool { + unsafe { crate::notcurses_canopen_videos(null()) } +} + +/// Can we reliably use Unicode halfblocks? +#[inline] +pub fn ncdirect_canhalfblock(ncd: &NcDirect) -> bool { + unsafe { crate::ncdirect_canutf8(ncd) } +} + +/// Can we reliably use Unicode quadrants? +#[inline] +pub fn ncdirect_canquadrant(ncd: &NcDirect) -> bool { + (unsafe { crate::ncdirect_canutf8(ncd) }) && ncdirect_capabilities(ncd).quadrants +} + +/// Can we reliably use Unicode 13 sextants? +#[inline] +pub fn ncdirect_cansextant(ncd: &NcDirect) -> bool { + (unsafe { crate::ncdirect_canutf8(ncd) }) && ncdirect_capabilities(ncd).sextants +} + +/// Can we reliably use Unicode Braille? +#[inline] +pub fn ncdirect_canbraille(_ncd: &NcDirect) -> bool { + unsafe { crate::notcurses_canbraille(null()) } +} + +/// Returns the detected [`NcCapabilities`]. +#[inline] +pub fn ncdirect_capabilities(ncd: &NcDirect) -> NcCapabilities { + unsafe { *crate::bindings::ffi::ncdirect_capabilities(ncd) } +} /// 'input' may be NULL if the caller is uninterested in event details. /// Blocks until an event is processed or a signal is received. @@ -10,11 +66,11 @@ use crate::{NcComponent, NcDirect, NcInput, NcIntResult, NcRgb, NcSignalSet, NcT /// *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 { +pub fn ncdirect_getc_blocking(ncd: &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)) + core::char::from_u32_unchecked(crate::ncdirect_getc(ncd, null(), &mut sigmask, input)) } } @@ -25,12 +81,12 @@ pub fn ncdirect_getc_blocking(nc: &mut NcDirect, input: &mut NcInput) -> char { // // `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 { +pub fn ncdirect_getc_nblock(ncd: &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)) + core::char::from_u32_unchecked(crate::ncdirect_getc(ncd, &ts, &mut sigmask, input)) } } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 2781dc476..3fb84f052 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -113,6 +113,7 @@ mod bindings; pub use bindings::*; mod r#box; +mod capabilities; mod cells; mod channel; mod dimension; @@ -135,6 +136,7 @@ mod visual; mod widgets; pub use crate::input::*; +pub use capabilities::*; pub use cells::*; pub use channel::*; pub use dimension::*;