From fa693a89c1abcf4ad4667c46f85c1f25e868d57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?joseLu=C3=ADs?= Date: Tue, 22 Dec 2020 15:01:07 +0100 Subject: [PATCH] rust: add most Notcurses methods. - fix some comments. --- rust/src/channel/methods.rs | 4 +- rust/src/error.rs | 2 - rust/src/notcurses/methods.rs | 331 +++++++++++++++++++++++++++- rust/src/notcurses/mod.rs | 64 +++--- rust/src/notcurses/reimplemented.rs | 2 + 5 files changed, 364 insertions(+), 39 deletions(-) diff --git a/rust/src/channel/methods.rs b/rust/src/channel/methods.rs index d7f89cf9e..62f6d9394 100644 --- a/rust/src/channel/methods.rs +++ b/rust/src/channel/methods.rs @@ -2,7 +2,7 @@ use crate::{NcAlphaBits, NcChannel, NcChannelPair, NcColor, NcRgb}; -/// Enables the methods of [NcChannel]; +/// Enables the [NcChannel] methods. pub trait NcChannelMethods { fn alpha(&self) -> NcAlphaBits; fn set_alpha(&mut self, alpha: NcAlphaBits); @@ -22,7 +22,7 @@ pub trait NcChannelMethods { // } -/// Enables the methods of [NcChannelPair]; +/// Enables the [NcChannelPair] methods. pub trait NcChannelPairMethods { fn fg_alpha(&self) -> NcAlphaBits; fn bg_alpha(&self) -> NcAlphaBits; diff --git a/rust/src/error.rs b/rust/src/error.rs index 6c9dc5d67..a69baa9bb 100644 --- a/rust/src/error.rs +++ b/rust/src/error.rs @@ -16,6 +16,4 @@ pub const NCRESULT_OK: i32 = 0; pub const NCRESULT_ERR: i32 = -1; /// MAX value, for the functions that return [`NcResult`]. -/// -/// Used in [ncplane_align] pub const NCRESULT_MAX: i32 = i32::MAX; diff --git a/rust/src/notcurses/methods.rs b/rust/src/notcurses/methods.rs index f8aa1b05b..270539e74 100644 --- a/rust/src/notcurses/methods.rs +++ b/rust/src/notcurses/methods.rs @@ -1,10 +1,12 @@ //! `Notcurses*` methods and associated functions. use core::ptr::{null, null_mut}; +use std::ffi::CStr; use crate::{ - notcurses_init, sigset_t, NcInput, NcLogLevel, NcPlane, NcResult, NcTime, Notcurses, - NotcursesOptions, NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS, + notcurses_init, sigset_t, NcBlitter, NcChannelPair, NcDimension, NcEgc, NcInput, NcLogLevel, NcScale, NcFile, NcStats, cstring, + NcPlane, NcResult, NcStyleMask, NcTime, Notcurses, NotcursesOptions, NCRESULT_OK, + NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS, }; /// # `NotcursesOptions` Constructors @@ -116,42 +118,294 @@ impl Notcurses { /// # `Notcurses` methods impl Notcurses { + /// 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: NcDimension, + x: NcDimension, + 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 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 { + 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: NcDimension, x: NcDimension) -> NcResult { + 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); } + } + + /// + /// C style function: [notcurses_getc][crate::notcurses_getc] pub fn getc(&mut self, time: &NcTime, sigmask: &mut sigset_t, input: &mut NcInput) -> char { unsafe { core::char::from_u32_unchecked(crate::notcurses_getc(self, time, sigmask, input)) } } /// + /// 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) } /// + /// C style function: [notcurses_getc_nblocking][crate::notcurses_getc_nblocking] pub fn getc_nblocking(&mut self, input: &mut NcInput) -> char { crate::notcurses_getc_nblocking(self, input) } + /// Returns an [NcBlitter] from a string representation. + /// + /// C style function: [notcurses_lex_blitter][crate::notcurses_lex_blitter] + pub fn lex_blitter(op: &str) -> Option { + let mut blitter = 0; + let res = unsafe { crate::notcurses_lex_blitter(cstring![op], &mut blitter) }; + if res == NCRESULT_OK { + return Some(blitter); + } + None + } + + /// 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 { + 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) -> Option { + let mut scalemode = 0; + let res = unsafe { crate::notcurses_lex_scalemode(cstring![op], &mut scalemode) }; + if res == NCRESULT_OK { + return Some(scalemode); + } + None + } + /// 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 { 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 { 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 { + unsafe { crate::notcurses_mouse_disable(self) } + } + + /// Enable the mouse in "button-event tracking" mode with focus detection + /// and UTF8-style extended coordinates. + /// + /// On success, [NCRESULT_OK] is returned, and 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 { + unsafe { crate::notcurses_mouse_enable(self) } + } + + /// 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] + // + // TODO: try returning Result<(NcDimension, NcDimension), NcResult> + pub fn refresh(&mut self, y: &mut NcDimension, x: &mut NcDimension) -> NcResult { + unsafe { crate::notcurses_refresh(self, &mut (*y as i32), &mut (*x as i32)) } + } + + /// 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 { unsafe { crate::notcurses_render(self) } } + /// 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 { + 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); } + } + /// 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) } } @@ -160,12 +414,83 @@ impl Notcurses { /// /// 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) } } - /// Destroy the Notcurses context. + /// Destroys the Notcurses context. + /// + /// C style function: [notcurses_stop][crate::notcurses_stop] pub fn stop(&mut self) -> NcResult { 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 { + unsafe { + CStr::from_ptr(crate::notcurses_str_blitter(blitter)) + .to_string_lossy() + .into_owned() + } + } + + /// 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 { + unsafe { + CStr::from_ptr(crate::notcurses_str_scalemode(scalemode)) + .to_string_lossy() + .into_owned() + } + } + + /// 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 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 { + unsafe { + CStr::from_ptr(crate::notcurses_version()) + .to_string_lossy() + .into_owned() + } + } + + /// 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) + } } diff --git a/rust/src/notcurses/mod.rs b/rust/src/notcurses/mod.rs index 856edf994..f0b041c76 100644 --- a/rust/src/notcurses/mod.rs +++ b/rust/src/notcurses/mod.rs @@ -3,49 +3,49 @@ // functions already exported by bindgen : 41 // ------------------------------------------ // (#) test: 10 -// (W) wrap: 8 +// (W) wrap: 38 // ------------------------------------------ -// notcurses_at_yx -// notcurses_bottom -// # notcurses_canchangecolor -// # notcurses_canfade -// # notcurses_canopen_images -// # notcurses_canopen_videos -// # notcurses_cansixel -// # notcurses_cantruecolor -// # notcurses_canutf8 -// notcurses_cursor_disable -// notcurses_cursor_enable -// # notcurses_debug -// # notcurses_drop_planes +//W notcurses_at_yx +//W notcurses_bottom +//W# notcurses_canchangecolor +//W# notcurses_canfade +//W# notcurses_canopen_images +//W# notcurses_canopen_videos +//W# notcurses_cansixel +//W# notcurses_cantruecolor +//W# notcurses_canutf8 +//W notcurses_cursor_disable +//W notcurses_cursor_enable +//W# notcurses_debug +//W# notcurses_drop_planes //W notcurses_getc //W# notcurses_init // notcurses_inputready_fd -// notcurses_lex_blitter -// notcurses_lex_margins -// notcurses_lex_scalemode +//W notcurses_lex_blitter +//W notcurses_lex_margins +//W notcurses_lex_scalemode //W notcurses_linesigs_disable //W notcurses_linesigs_enable -// notcurses_mouse_disable -// notcurses_mouse_enable -// notcurses_palette_size -// notcurses_refresh +//W notcurses_mouse_disable +//W notcurses_mouse_enable +//W notcurses_palette_size +//W notcurses_refresh //W notcurses_render // notcurses_render_to_buffer -// notcurses_render_to_file -// notcurses_stats -// notcurses_stats_alloc -// notcurses_stats_reset +//W notcurses_render_to_file +//W notcurses_stats +//W notcurses_stats_alloc +//W notcurses_stats_reset //W notcurses_stdplane //W notcurses_stdplane_const //W# notcurses_stop -// notcurses_str_blitter -// notcurses_str_scalemode -// notcurses_supported_styles -// notcurses_top +//W notcurses_str_blitter +//W notcurses_str_scalemode +//W notcurses_supported_styles +//W notcurses_top // notcurses_ucs32_to_utf8 -// notcurses_version -// notcurses_version_components +//W notcurses_version +//W notcurses_version_components // // functions manually reimplemented: 6 // ----------------------------------------- @@ -67,7 +67,7 @@ mod methods; mod reimplemented; pub use reimplemented::*; -/// The main struct of the (full mode) TUI library +/// The main struct of the TUI library (full mode) /// /// Notcurses builds atop the terminfo abstraction layer to /// provide reasonably portable vivid character displays. diff --git a/rust/src/notcurses/reimplemented.rs b/rust/src/notcurses/reimplemented.rs index b80846b10..c0e3c7285 100644 --- a/rust/src/notcurses/reimplemented.rs +++ b/rust/src/notcurses/reimplemented.rs @@ -46,6 +46,8 @@ pub fn notcurses_align(availcols: NcDimension, align: NcAlign, cols: NcDimension /// 'input' may be NULL if the caller is uninterested in event details. /// If no event is ready, returns 0. +/// +/// Rust method: [Notcurses.getc_nblock][Notcurses#method.getc_nblock] #[inline] pub fn notcurses_getc_nblock(nc: &mut Notcurses, input: &mut NcInput) -> char { unsafe {