rust: continue reworking the API & improve documentation

- remove _IO_FILE import and usage.
- create handy constructors for NcDirect & Notcurses.
  (but can't implement destructors for copy types…).
- when possible substitute mutable pointers `*mut` for mutable references `&mut`
  with associated lifetimes.
- new widgets module, starting with NcReader & NcReaderOptions constructors
dankamongmen/clock_nanosleep_portable
joseLuís 4 years ago
parent 965a0771d8
commit 08a0da358e

@ -7,7 +7,7 @@ use libnotcurses_sys as nc;
fn main() {
unsafe {
let ncd = nc::ncdirect_new();
let ncd = nc::NcDirect::new();
let cols = nc::ncdirect_dim_x(ncd);
let rows = nc::ncdirect_dim_y(ncd);

@ -4,7 +4,7 @@ use libnotcurses_sys as nc;
fn main() {
unsafe {
let ncd = nc::ncdirect_new();
let ncd = nc::NcDirect::new();
render_image(&mut *ncd, nc::NCBLIT_1x1);
render_image(&mut *ncd, nc::NCBLIT_2x1);

@ -1,7 +1,18 @@
//use cstr_core::CString;
//use libnotcurses_sys as nc;
use libnotcurses_sys as nc;
fn main() {
unsafe {
// let options = nc::NotcursesOptions::new();
// let app = nc::Notcurses::with_options(&options);
let app = nc::Notcurses::new();
nc::notcurses_stop(app);
}
}

@ -27,7 +27,6 @@ pub mod bindgen {
#[doc(inline)]
pub use bindgen::{
// structs
_IO_FILE,
__va_list_tag,
timespec,
};
@ -618,6 +617,15 @@ pub(crate) use bindgen::{
// 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)]
@ -662,15 +670,6 @@ pub use bindgen::{
notcurses_ucs32_to_utf8,
notcurses_version,
notcurses_version_components,
// 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,
};
// palette ---------------------------------------------------------------------

@ -66,8 +66,7 @@ use crate::{
channels_set_bg_default, channels_set_bg_rgb, channels_set_bg_rgb8, channels_set_fchannel,
channels_set_fg_alpha, channels_set_fg_default, channels_set_fg_rgb, channels_set_fg_rgb8,
types::{
AlphaBits, Cell, Channel, Channels, Color, Egc, IntResult, NcPlane,
PaletteIndex, StyleMask,
AlphaBits, Cell, Channel, Channels, Color, Egc, IntResult, NcPlane, PaletteIndex, StyleMask,
},
CELL_ALPHA_OPAQUE, CELL_BGDEFAULT_MASK, CELL_BG_PALETTE, CELL_FGDEFAULT_MASK, CELL_FG_PALETTE,
CELL_NOBACKGROUND_MASK, CELL_WIDEASIAN_MASK, NCSTYLE_MASK,

@ -40,34 +40,44 @@
// ncdirect_vline_interp
use crate::{
bindgen::_IO_FILE,
ncdirect_init,
types::{NcDirect, NcDirectFlags},
};
use core::ptr::{null, null_mut};
extern "C" {
fn libc_stdout() -> *mut _IO_FILE;
}
impl NcDirect {
/// A simple ncdirect_init() wrapper using the default options.
///
/// Initialize a direct-mode notcurses context on the tty.
///
/// Direct mode supports a limited subset of notcurses routines,
/// and neither supports nor requires notcurses_render(). This can be
/// used to add color and styling to text in the standard output paradigm.
//
// Returns NULL on error, including any failure initializing terminfo.
pub unsafe fn new<'a>() -> &'a mut NcDirect {
Self::with_flags(0)
}
/// A simple ncdirect_init() wrapper using the default options.
///
/// Initialize a direct-mode notcurses context on the tty.
///
/// Direct mode supports a limited subset of notcurses routines,
/// and neither supports nor requires notcurses_render(). This can be
/// used to add color and styling to text in the standard output paradigm.
///
/// Returns NULL on error, including any failure initializing terminfo.
pub unsafe fn ncdirect_new() -> *mut NcDirect {
ncdirect_with_flags(0)
/// A simple ncdirect_init() wrapper with optional flags.
///
/// `flags` is a bitmask over:
/// - NCDIRECT_OPTION_INHIBIT_CBREAK
/// - NCDIRECT_OPTION_INHIBIT_SETLOCALE
///
pub unsafe fn with_flags<'a>(flags: NcDirectFlags) -> &'a mut NcDirect {
&mut *ncdirect_init(null(), null_mut(), flags)
}
}
/// A simple ncdirect_init() wrapper with optional flags.
///
/// `flags` is a bitmask over:
/// - NCDIRECT_OPTION_INHIBIT_CBREAK
/// - NCDIRECT_OPTION_INHIBIT_SETLOCALE
///
pub unsafe fn ncdirect_with_flags(flags: NcDirectFlags) -> *mut NcDirect {
ncdirect_init(core::ptr::null(), libc_stdout(), flags)
}
// Explicitly implementing both `Drop` and `Copy` trait on a type is currently
// disallowed (rustc --explain E0184)
// https://github.com/rust-lang/rust/issues/20126
//
// impl Drop for NcDirect {
// fn drop(&mut self) {
// unsafe {
// ncdirect_stop(self);
// }
// }
// }

@ -26,6 +26,7 @@ mod palette;
mod pixel;
mod plane;
mod visual;
mod widgets;
pub use cells::*;
pub use channel::*;
@ -38,3 +39,4 @@ pub use palette::*;
pub use pixel::*;
pub use plane::*;
pub use visual::*;
pub use widgets::*;

@ -1,5 +1,4 @@
#[allow(unused_imports)]
use crate::Cell;
#[macro_export]

@ -52,7 +52,7 @@
// notcurses_stddim_yx_const
//+ notcurses_term_dim_yx
use core::ptr::null;
use core::ptr::{null, null_mut};
use crate::{
// NOTE: can't use libc::timespec nor libc::sigset_t
@ -60,13 +60,87 @@ use crate::{
bindings::{sigemptyset, sigfillset, sigset_t, timespec},
ncplane_dim_yx,
notcurses_getc,
notcurses_init,
notcurses_stdplane,
notcurses_stdplane_const,
types::{NcAlign, NcInput, NcPlane, Notcurses},
types::{NcAlign, NcInput, NcLogLevel, NcPlane, Notcurses, NotcursesOptions},
NCALIGN_CENTER,
NCALIGN_LEFT,
};
impl NotcursesOptions {
/// Simple `NotcursesOptions` constructor
pub fn new() -> Self {
Self::with_all_options(0, 0, 0, 0, 0, 0)
}
/// `NotcursesOptions` constructor with customizable margins
pub fn with_margins(top: i32, right: i32, bottom: i32, left: i32) -> Self {
Self::with_all_options(0, top, right, bottom, left, 0)
}
/// `NotcursesOptions` constructor with customizable flags
pub fn with_flags(flags: u64) -> Self {
Self::with_all_options(0, 0, 0, 0, 0, flags)
}
/// `NotcursesOptions` constructor with all the options available
///
/// ## 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; see NCOPTION_*. This is expressed as a bitfield so that
/// future options can be added without reshaping the struct.
/// Undefined bits must be set to 0.
///
pub fn with_all_options(
loglevel: NcLogLevel,
margin_t: i32,
margin_r: i32,
margin_b: i32,
margin_l: i32,
flags: u64,
) -> Self {
Self {
termtype: null(),
renderfp: null_mut(),
loglevel,
margin_t,
margin_r,
margin_b,
margin_l,
flags,
}
}
}
impl Notcurses {
/// `Notcurses` simple constructor
pub unsafe fn new<'a>() -> &'a mut Notcurses {
&mut *notcurses_init(&NotcursesOptions::new(), null_mut())
}
/// `Notcurses` constructor with options
pub unsafe fn with_options(options: &NotcursesOptions) -> &mut Notcurses {
&mut *notcurses_init(options, null_mut())
}
}
/// return the offset into 'availcols' at which 'cols' ought be output given the requirements of 'align'
#[inline]
pub fn notcurses_align(availcols: i32, align: NcAlign, cols: i32) -> i32 {
@ -127,11 +201,6 @@ pub fn notcurses_term_dim_yx(nc: &Notcurses, rows: &mut i32, cols: &mut i32) {
}
}
// TODO
// pub unsafe fn notcurses_new() -> *mut Notcurses {
// notcurses_init(core::ptr::null(), libc_stdout())
// }
#[cfg(test)]
mod test {
// use super::nc;

@ -332,7 +332,6 @@ pub type NcFdPlane = crate::ncfdplane;
/// `type in C: ncplane_options (struct)`
pub type NcFdPlaneOptions = crate::ncfdplane_options;
/// Palette structure consisting of an array of 256 [`Channel`](type.Channel.html)s
///
/// Some terminals only support 256 colors, but allow the full
@ -475,10 +474,56 @@ pub type Notcurses = crate::bindings::notcurses;
/// Options struct for [`Notcurses`](type.Notcurses.html)
pub type NotcursesOptions = crate::bindings::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::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::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::NCOPTION_NO_FONT_CHANGES as u64;
/// Do not handle SIG{ING, SEGV, ABRT, QUIT}
///
/// We typically install a signal handler for SIG{INT, SEGV, ABRT, QUIT} that
/// restores the screen, and then calls the old signal handler. Set to inhibit
/// registration of these signal handlers.
pub const NCOPTION_NO_QUIT_SIGHANDLERS: u64 = crate::bindings::NCOPTION_NO_QUIT_SIGHANDLERS as u64;
/// Do not handle SIGWINCH
///
/// We typically install a signal handler for SIGWINCH that generates a resize
/// event in the notcurses_getc() queue. Set to inhibit this handler
pub const NCOPTION_NO_WINCH_SIGHANDLER: u64 = crate::bindings::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::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::NCOPTION_VERIFY_SIXEL as u64;
/// Context for a palette fade operation
pub type NcFadeCtx = crate::ncfadectx;
// Widgets
/// `type in C: ncmenu (struct)`

@ -0,0 +1,5 @@
//! Widgets
//!
mod reader;
pub use reader::*;

@ -0,0 +1,52 @@
// 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
//
// static inline functions total: 0
// -------------------------------------------
use crate::{
ncreader_create,
types::{NcPlane, NcReader, NcReaderOptions},
};
/// `NcReader` constructor (wraps `ncreader_create`)
///
/// NcReader provides freeform input in a (possibly multiline) region, supporting
/// optional readline keybindings. takes ownership of its plane, destroying it
/// on any error (ncreader_destroy() otherwise destroys the ncplane).
impl NcReader {
/// Simple `NcReader` constructor
pub unsafe fn new<'a>(plane: &mut NcPlane) -> &'a mut Self {
Self::with_options(plane, &NcReaderOptions::new())
}
/// `NcReader` constructor with options
pub unsafe fn with_options<'a>(plane: &mut NcPlane, options: &NcReaderOptions) -> &'a mut Self {
&mut *ncreader_create(plane, options)
}
}
impl NcReaderOptions {
/// `NcReaderOptions` simple constructor
pub fn new() -> Self {
Self {
// channels used for input
tchannels: 0,
// attributes used for input
tattrword: 0,
// bitfield of NCREADER_OPTION_*
flags: 0,
}
}
}

@ -31,7 +31,7 @@ fn create_notcurses_context() {
margin_r: 0,
margin_b: 0,
margin_l: 0,
flags: (nc::NCOPTION_NO_ALTERNATE_SCREEN | nc::NCOPTION_INHIBIT_SETLOCALE) as u64,
flags: (nc::types::NCOPTION_NO_ALTERNATE_SCREEN | nc::types::NCOPTION_INHIBIT_SETLOCALE),
};
let nc = nc::notcurses_init(&opts, null_mut());
nc::notcurses_stop(nc);

Loading…
Cancel
Save