/// Initializes curses.
///
/// * Automatically enables color, if available.
/// * Automatically enables keypad keys (arrow keys, function keys, etc).
///
/// ## Panics
/// * If you double-initialize curses this will panic.
/// * If your previous curses handle has been dropped it **is** legal to init
///   another one. Curses mode will resume just fine.
/// ## Other
/// * If this fails on the curses side, curses will "helpfully" print an error
///   and abort the process for you.
/// * This installs a custom panic hook that ends curses mode before printing
///   the panic message. Otherwise your panic messages get eaten. The normal
///   panic hook is restored when `Curses` drops.
Initializes curses.
Automatically enables color, if available.
Initializes curses . Automatically enables color if available .
pub fn init() -> Self {
    if CURSES_ACTIVE
      .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
      .is_ok()
    {
      // If we're about to go into curses mode, grab the current hook to
      // save for later and install a hook that will turn off curses, print the
      // panic info, and then restore curses.
      let old_hook = std::panic::take_hook();
      std::panic::set_hook(Box::new(|panic_info| {
        unsafe_always_ok!(def_prog_mode());
        let _ = unsafe_call_result!("", endwin());
        eprintln!("{}", panic_info);
      }));
      if unsafe { isendwin() } {
        let mut w = Self { ptr: unsafe { stdscr }, old_hook };
        w.refresh().unwrap();
        w
      } else {
        let win = Self { ptr: unsafe { initscr() }, old_hook };
        assert!(!win.ptr.is_null());
        // technically this could fail to allocate the color table, but if so
        // we'll just get other errors if people do use color later on. If we
        // failed to allocate the color table but color isn't used, then there's
        // no reason to raise a fuss.
        let _ = unsafe_call_result!("", start_color());
        // this only fails if curses isn't init or the ptr is null, so it should
        // never fail here since we checked for null already. However, if it
        // somehow does fail anyway, then the worst that happens is that the
        // user can't use the keypad keys.
        let _ = unsafe_call_result!("", keypad(win.ptr, true));
        // We always want to operate in cbreak mode, so set it here and don't
        // expose this option to the user. In this case, if `cbreak` isn't set
        // then things will be weird as hell, so we panic on failure.
        unsafe_call_result!("", cbreak()).expect("Couldn't set `cbreak` mode.");
        win
      }
    } else {
      panic!("Curses is already active.")
    }
  }
pub fn init ( ) -> Self { if CURSES_ACTIVE . compare_exchange ( false , true , Ordering :: SeqCst , Ordering :: SeqCst ) . is_ok ( ) { // If we're about to go into curses mode, grab the current hook to // save for later and install a hook that will turn off curses, print the // panic info, and then restore curses. let old_hook = std :: panic :: take_hook ( ) ; std :: panic :: set_hook ( Box :: new ( | panic_info | { unsafe_always_ok ! ( def_prog_mode ( ) ) ; let _ = unsafe_call_result ! ( " " endwin ( ) ) ; eprintln ! ( " " panic_info ) ; } ) ) ; if unsafe { isendwin ( ) } { let mut w = Self { ptr : unsafe { stdscr } , old_hook } ; w . refresh ( ) . unwrap ( ) ; w } else { let win = Self { ptr : unsafe { initscr ( ) } , old_hook } ; assert ! ( win ptr is_null ( ) ) ; // technically this could fail to allocate the color table, but if so // we'll just get other errors if people do use color later on. If we // failed to allocate the color table but color isn't used, then there's // no reason to raise a fuss. let _ = unsafe_call_result ! ( " " start_color ( ) ) ; // this only fails if curses isn't init or the ptr is null, so it should // never fail here since we checked for null already. However, if it // somehow does fail anyway, then the worst that happens is that the // user can't use the keypad keys. let _ = unsafe_call_result ! ( " " keypad ( win ptr true ) ) ; // We always want to operate in cbreak mode, so set it here and don't // expose this option to the user. In this case, if `cbreak` isn't set // then things will be weird as hell, so we panic on failure. unsafe_call_result ! ( " " cbreak ( ) ) . expect ( " " ) ; win } } else { panic ! ( " " ) } }
Initializes curses.
Initializes curses .
panics
If you double-initialize curses this will panic.
If your previous curses handle has been dropped it **is** legal to init
another one. Curses mode will resume just fine.
If you double - initialize curses this will panic . If your previous curses handle has been dropped it ** is ** legal to init another one . Curses mode will resume just fine .
other
If this fails on the curses side, curses will "helpfully" print an error
and abort the process for you.
This installs a custom panic hook that ends curses mode before printing
the panic message. Otherwise your panic messages get eaten. The normal
panic hook is restored when `Curses` drops.
If this fails on the curses side curses will " helpfully " print an error and abort the process for you . This installs a custom panic hook that ends curses mode before printing the panic message . Otherwise your panic messages get eaten . The normal panic hook is restored when ` Curses ` drops .