libnotcurses_sys/direct/
reimplemented.rs

1//! `ncdirect_*` reimplemented functions.
2
3use core::{
4    ffi::c_char,
5    ptr::{null, null_mut},
6};
7
8use crate::{
9    c_api::{self, NcChannels_u64, NcResult_i32, NcRgb_u32},
10    cstring, NcCapabilities, NcDirect, NcInput, NcTime,
11};
12
13/// Can we directly specify RGB values per cell, or only use palettes?
14#[inline]
15pub fn ncdirect_cantruecolor(ncd: &NcDirect) -> bool {
16    ncdirect_capabilities(ncd).rgb
17}
18
19/// Can we set the "hardware" palette? Requires the "ccc" terminfo capability.
20#[inline]
21pub fn ncdirect_canchangecolor(ncd: &NcDirect) -> bool {
22    c_api::nccapability_canchangecolor(&ncdirect_capabilities(ncd))
23}
24
25/// Can we fade? Fading requires either the "rgb" or "ccc" terminfo capability.
26#[inline]
27pub fn ncdirect_canfade(ncd: &NcDirect) -> bool {
28    ncdirect_canchangecolor(ncd) || ncdirect_cantruecolor(ncd)
29}
30
31/// Can we load videos? This requires being built against FFmpeg.
32#[inline]
33pub fn ncdirect_canopen_videos(_ncd: &NcDirect) -> bool {
34    unsafe { c_api::notcurses_canopen_videos(null()) }
35}
36
37/// Can we open images? This requires being built against FFmpeg.
38#[inline]
39pub fn ncdirect_canopen_images(_ncd: &NcDirect) -> bool {
40    unsafe { c_api::notcurses_canopen_images(null()) }
41}
42
43/// Can we reliably use Unicode halfblocks?
44#[inline]
45pub fn ncdirect_canhalfblock(ncd: &NcDirect) -> bool {
46    unsafe { c_api::ncdirect_canutf8(ncd) }
47}
48
49/// Can we reliably use Unicode quadrants?
50#[inline]
51pub fn ncdirect_canquadrant(ncd: &NcDirect) -> bool {
52    (unsafe { c_api::ncdirect_canutf8(ncd) }) && ncdirect_capabilities(ncd).quadrants
53}
54
55/// Can we reliably use Unicode 13 sextants?
56#[inline]
57pub fn ncdirect_cansextant(ncd: &NcDirect) -> bool {
58    (unsafe { c_api::ncdirect_canutf8(ncd) }) && ncdirect_capabilities(ncd).sextants
59}
60
61/// Can we reliably use Unicode Braille?
62#[inline]
63pub fn ncdirect_canbraille(ncd: &NcDirect) -> bool {
64    (unsafe { c_api::ncdirect_canutf8(ncd) }) && ncdirect_capabilities(ncd).braille
65}
66
67/// Returns the detected [`NcCapabilities`].
68#[inline]
69pub fn ncdirect_capabilities(ncd: &NcDirect) -> NcCapabilities {
70    unsafe { *crate::c_api::ffi::ncdirect_capabilities(ncd) }
71}
72
73/// Reads input blocking until an event is processed or a signal is received.
74///
75/// Will optionally write the event details in `input`.
76///
77/// In case of an invalid read (including on EOF) *-1* is returned.
78///
79/// *Method: NcDirect.[get_blocking()][NcDirect#method.get_blocking].*
80#[inline]
81pub fn ncdirect_get_blocking(ncd: &mut NcDirect, input: Option<&mut NcInput>) -> NcResult_i32 {
82    let input_ptr = if let Some(i) = input { i as *mut _ } else { null_mut() };
83    unsafe { c_api::ncdirect_get(ncd, null(), input_ptr) as NcResult_i32 }
84}
85
86/// Reads input without blocking.
87///
88/// Will optionally write the event details in `input`.
89///
90/// If no event is ready, returns 0.
91///
92/// In case of an invalid read (including on EOF) *-1* is returned.
93///
94/// *Method: NcDirect.[get_nblock()][NcDirect#method.get_nblock].*
95#[inline]
96pub fn ncdirect_get_nblock(ncd: &mut NcDirect, input: Option<&mut NcInput>) -> NcResult_i32 {
97    let input_ptr = if let Some(i) = input { i as *mut _ } else { null_mut() };
98    unsafe {
99        let ts = NcTime::new(0, 0);
100        c_api::ncdirect_get(ncd, &ts, input_ptr) as NcResult_i32
101    }
102}
103
104/// Sets the foreground component components.
105///
106/// *Method: NcDirect.[set_fg_rgb()][NcDirect#method.set_fg_rgb].*
107#[inline]
108pub fn ncdirect_set_fg_rgb8(ncd: &mut NcDirect, red: u8, green: u8, blue: u8) -> NcResult_i32 {
109    let rgb = (red as NcRgb_u32) << 16 | (green as NcRgb_u32) << 8 | blue as NcRgb_u32;
110    unsafe { c_api::ncdirect_set_fg_rgb(ncd, rgb) }
111}
112
113/// Sets the background component components.
114///
115/// *Method: NcDirect.[set_bg_rgb()][NcDirect#method.set_bg_rgb].*
116#[inline]
117pub fn ncdirect_set_bg_rgb8(ncd: &mut NcDirect, red: u8, green: u8, blue: u8) -> NcResult_i32 {
118    let rgb = (red as NcRgb_u32) << 16 | (green as NcRgb_u32) << 8 | blue as NcRgb_u32;
119    unsafe { c_api::ncdirect_set_bg_rgb(ncd, rgb) }
120}
121
122/// Draws horizontal lines using the specified [`NcChannels_u64`]s, interpolating
123/// between them as we go.
124///
125/// The string at `egc` may not use more than one column.
126///
127/// All lines start at the current cursor position.
128///
129/// For a horizontal line, `len` cannot exceed the screen width minus the
130/// cursor's offset.
131// TODO:MAYBE saturate the `len` value
132///
133/// *Method: NcDirect.[hline_interp()][NcDirect#method.hline_interp].*
134#[inline]
135pub fn ncdirect_hline_interp(
136    ncd: &mut NcDirect,
137    egc: &str,
138    len: u32,
139    h1: impl Into<NcChannels_u64>,
140    h2: impl Into<NcChannels_u64>,
141) -> NcResult_i32 {
142    let cs = cstring![egc];
143    let egc_ptr = cs.as_ptr() as *const c_char;
144
145    unsafe { crate::c_api::ffi::ncdirect_hline_interp(ncd, egc_ptr, len, h1.into(), h2.into()) }
146}
147
148/// Draws horizontal lines using the specified [`NcChannels_u64`]s, interpolating
149/// between them as we go.
150///
151/// The string at `egc` may not use more than one column.
152///
153/// All lines start at the current cursor position.
154///
155/// For a vertical line, `len` may be as long as you'd like; the screen
156/// will scroll as necessary.
157///
158/// *Method: NcDirect.[vline_interp()][NcDirect#method.vline_interp].*
159#[inline]
160pub fn ncdirect_vline_interp(
161    ncd: &mut NcDirect,
162    egc: &str,
163    len: u32,
164    h1: impl Into<NcChannels_u64>,
165    h2: impl Into<NcChannels_u64>,
166) -> NcResult_i32 {
167    let cs = cstring![egc];
168    let egc_ptr = cs.as_ptr() as *const c_char;
169
170    unsafe { crate::c_api::ffi::ncdirect_vline_interp(ncd, egc_ptr, len, h1.into(), h2.into()) }
171}