Repository: jeaye/ncurses-rs (language: rust)

Issue:
Crash with ncurses 6.1 with the "wide" feature
In this case the executable is linked to libncursesw.so.6 and to libtinfo.so.6
This did not cause a problem before ncurses 6.1, but now it crashes.
libtinfo.so.6 is coming from pkg_config which is looking for "ncurses" instead of "ncursesw".
Other projects have this same issue as well: https://github.com/vifm/vifm/issues/325#issuecomment-379552487

I think the proper fix would be to check "ncursesw", "ncursesw5" (and possible "ncursesw6") with pkg_config if the "wide" feature is enabled (and not on macosx) instead of the current ones. In `src/ll.rs` it should be unnecessary to specify the shared library again.


Discussion / hints:

Fix patch:
diff --git a/build.rs b/build.rs
index 3fdfaf2c..bb6090e8 100644
--- a/build.rs
+++ b/build.rs
@@ -1,17 +1,52 @@
 extern crate gcc;
 extern crate pkg_config;
 
+use pkg_config::Library;
 use std::env;
 use std::fs::File;
 use std::io::Write;
 use std::path::Path;
 use std::process::Command;
 
+fn find_library(names: &[&str]) -> Option<Library> {
+    for name in names {
+        if let Ok(lib) = pkg_config::probe_library(name) {
+            return Some(lib);
+        }
+    }
+    println!("cargo:rustc-link-lib={}", names.last().unwrap());
+    None
+}
+
 fn main() {
-    check_chtype_size();
+    let wide = cfg!(all(feature = "wide", not(target_os = "macos")));
+
+    let ncurses_lib = if wide {
+        find_library(&["ncursesw5", "ncursesw"])
+    } else {
+        find_library(&["ncurses5", "ncurses"])
+    };
+
+    if cfg!(feature = "menu") {
+        if wide {
+            find_library(&["menuw5", "menuw"]);
+        } else {
+            find_library(&["menu5", "menu"]);
+        }
+    }
+
+    if cfg!(feature = "panel") {
+        if wide {
+            find_library(&["panelw5", "panelw"]);
+        } else {
+            find_library(&["panel5", "panel"]);
+        }
+    }
+
+    check_chtype_size(&ncurses_lib);
 }
 
-fn check_chtype_size() {
+fn check_chtype_size(ncurses_lib: &Option<Library>) {
     let out_dir = env::var("OUT_DIR").expect("cannot get OUT_DIR");
     let src = format!("{}", Path::new(&out_dir).join("chtype_size.c").display());
     let bin = format!("{}", Path::new(&out_dir).join("chtype_size").display());
@@ -36,22 +71,20 @@ int main(void)
 }
     ").expect(&format!("cannot write into {}", src));
 
-    let cfg = gcc::Config::new();
-    let compiler = cfg.get_compiler();
+    let compiler = gcc::Build::new().get_compiler();
 
-    Command::new(compiler.path()).arg(&src).arg("-o").arg(&bin)
-                                 .status().expect("compilation failed");
+    let mut compile_cmd = Command::new(compiler.path());
+    compile_cmd.arg(&src).arg("-o").arg(&bin);
+    if let Some(lib) = ncurses_lib {
+        for path in lib.include_paths.iter() {
+            compile_cmd.arg("-I").arg(path);
+        }
+    }
+    compile_cmd.status().expect("compilation failed");
     let features = Command::new(&bin).output()
                    .expect(&format!("{} failed", bin));
     print!("{}", String::from_utf8_lossy(&features.stdout));
 
-    let ncurses_names = ["ncurses5", "ncurses"];
-    for ncurses_name in &ncurses_names {
-        if pkg_config::probe_library(ncurses_name).is_ok() {
-            break;
-        }
-    }
-
     std::fs::remove_file(&src).expect(&format!("cannot delete {}", src));
     std::fs::remove_file(&bin).expect(&format!("cannot delete {}", bin));
 }
diff --git a/src/ll.rs b/src/ll.rs
index 0ae91812..c29a3a41 100644
--- a/src/ll.rs
+++ b/src/ll.rs
@@ -42,347 +42,338 @@ pub type va_list = *mut u8;
 #[derive(Clone, Copy)]
 pub struct MEVENT { pub id: c_short, pub x: c_int, pub y: c_int, pub z: c_int, pub bstate: mmask_t}
 
-macro_rules! define_sharedffi(
-    ($cfgopt: meta, $link: meta) => {
-        #[$cfgopt] #[$link] extern {
-            pub fn addch(_:chtype) -> c_int;
-            pub fn addchnstr(_:*const chtype, _:c_int) -> c_int;
-            pub fn addchstr(_:*const chtype) -> c_int;
-            pub fn addnstr(_:*const c_char, _:c_int) -> c_int;
-            pub fn addstr(_:*const c_char) -> c_int;
-            pub fn assume_default_colors(_:c_int, _:c_int) -> c_int;
-            pub fn attroff(_:NCURSES_ATTR_T) -> c_int;
-            pub fn attron(_:NCURSES_ATTR_T) -> c_int;
-            pub fn attrset(_:NCURSES_ATTR_T) -> c_int;
-            pub fn attr_get(_:attr_t_p, _:short_p, _:void_p) -> c_int;
-            pub fn attr_off(_:attr_t, _:void_p) -> c_int;
-            pub fn attr_on(_:attr_t, _:void_p) -> c_int;
-            pub fn attr_set(_:attr_t, _:c_short, _:void_p) -> c_int;
-            pub fn baudrate() -> c_int;
-            pub fn beep() -> c_int;
-            pub fn bkgd(_:chtype) -> c_int;
-            pub fn bkgdset(_:chtype);
-            pub fn border(_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype) -> c_int;
-            pub fn box_(_:WINDOW, _:chtype, _:chtype) -> c_int;
-            pub fn can_change_color() -> c_bool;
-            pub fn cbreak() -> c_int;
-            pub fn chgat(_:c_int, _:attr_t, _:c_short, _:void_p) -> c_int;
-            pub fn clear() -> c_int;
-            pub fn clearok(_:WINDOW,_:c_bool) -> c_int;
-            pub fn clrtobot() -> c_int;
-            pub fn clrtoeol() -> c_int;
-            pub fn color_content(_:c_short,_:short_p,_:short_p,_:short_p) -> c_int;
-            pub fn color_set(_:c_short,_:void_p) -> c_int;
-            pub fn COLOR_PAIR(_:c_int) -> c_int;
-            pub fn copywin(_:WINDOW,_:WINDOW,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int) -> c_int;
-            pub fn curs_set(_:c_int) -> c_int;
-            pub fn def_prog_mode() -> c_int;
-            pub fn def_shell_mode() -> c_int;
-            pub fn delay_output(_:c_int) -> c_int;
-            pub fn delch() -> c_int;
-            pub fn delscreen(_:SCREEN);
-            pub fn delwin(_:WINDOW) -> c_int;
-            pub fn deleteln() -> c_int;
-            pub fn derwin(_:WINDOW,_:c_int,_:c_int,_:c_int,_:c_int) -> WINDOW;
-            pub fn doupdate() -> c_int;
-            pub fn dupwin(_:WINDOW) -> WINDOW;
-            pub fn echo() -> c_int;
-            pub fn echochar(_:chtype) -> c_int;
-            pub fn erase() -> c_int;
-            pub fn endwin() -> c_int;
-            pub fn erasechar() -> c_char;
-            pub fn filter();
-            pub fn flash() -> c_int;
-            pub fn flushinp() -> c_int;
-            pub fn getbkgd(_:WINDOW) -> chtype;
-            pub fn getch() -> c_int;
-            pub fn getnstr(_:*mut c_char, _:c_int) -> c_int;
-            pub fn getstr(_:char_p) -> c_int;
-            pub fn getwin(_:FILE_p) -> WINDOW;
-            pub fn halfdelay(_:c_int) -> c_int;
-            pub fn has_colors() -> c_bool;
-            pub fn has_ic() -> c_bool;
-            pub fn has_il() -> c_bool;
-            pub fn hline(_:chtype, _:c_int) -> c_int;
-            pub fn idcok(_:WINDOW, _:c_bool);
-            pub fn idlok(_:WINDOW, _:c_bool) -> c_int;
-            pub fn immedok(_:WINDOW, _:c_bool);
-            pub fn inch() -> chtype;
-            pub fn inchnstr(_:chtype_p, _:c_int) -> c_int;
-            pub fn inchstr(_:chtype_p) -> c_int;
-            pub fn initscr() -> WINDOW;
-            pub fn init_color(_:c_short,_:c_short,_:c_short,_:c_short) -> c_int;
-            pub fn init_pair(_:c_short,_:c_short,_:c_short) -> c_int;
-            pub fn innstr(_:char_p, _:c_int) -> c_int;
-            pub fn insch(_:chtype) -> c_int;
-            pub fn insdelln(_:c_int) -> c_int;
-            pub fn insertln() -> c_int;
-            pub fn insnstr(_:char_p, _:c_int) -> c_int;
-            pub fn insstr(_:char_p) -> c_int;
-            pub fn instr(_:char_p) -> c_int;
-            pub fn intrflush(_:WINDOW,_:c_bool) -> c_int;
-            pub fn isendwin() -> c_bool;
-            pub fn is_linetouched(_:WINDOW,_:c_int) -> c_bool;
-            pub fn is_term_resized(_:c_int, _:c_int) -> c_bool;
-            pub fn is_wintouched(_:WINDOW) -> c_bool;
-            pub fn keyname(_:c_int) -> *const c_char;
-            pub fn keypad(_:WINDOW, _:c_bool) -> c_int;
-            pub fn killchar() -> c_char;
-            pub fn leaveok(_:WINDOW,_:c_bool) -> c_int;
-            pub fn longname() -> *mut c_char;
-            pub fn meta(_:WINDOW,_:c_bool) -> c_int;
-            #[link_name = "move"]
-            pub fn mv(_:c_int, _:c_int) -> c_int;
-            pub fn mvaddch(_:c_int, _:c_int, _:chtype) -> c_int;
-            pub fn mvaddchnstr(_:c_int, _:c_int, _:chtype_p, _:c_int) -> c_int;
-            pub fn mvaddchstr(_:c_int, _:c_int, _:chtype_p) -> c_int;
-            pub fn mvaddnstr(_:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
-            pub fn mvaddstr(_:c_int, _:c_int, _:char_p) -> c_int;
-            pub fn mvchgat(_:c_int, _:c_int, _:c_int, _:attr_t, _:c_short, _:void_p) -> c_int;
-            pub fn mvcur(_:c_int,_:c_int,_:c_int,_:c_int) -> c_int;
-            pub fn mvdelch(_:c_int, _:c_int) -> c_int;
-            pub fn mvderwin(_:WINDOW, _:c_int, _:c_int) -> c_int;
-            pub fn mvgetch(_:c_int, _:c_int) -> c_int;
-            pub fn mvgetnstr(_:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
-            pub fn mvgetstr(_:c_int, _:c_int, _:char_p) -> c_int;
-            pub fn mvhline(_:c_int, _:c_int, _:chtype, _:c_int) -> c_int;
-            pub fn mvinch(_:c_int, _:c_int) -> chtype;
-            pub fn mvinchnstr(_:c_int, _:c_int, _:chtype_p, _:c_int) -> c_int;
-            pub fn mvinchstr(_:c_int, _:c_int, _:chtype_p) -> c_int;
-            pub fn mvinnstr(_:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
-            pub fn mvinsch(_:c_int, _:c_int, _:chtype) -> c_int;
-            pub fn mvinsnstr(_:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
-            pub fn mvinsstr(_:c_int, _:c_int, _:char_p) -> c_int;
-            pub fn mvinstr(_:c_int, _:c_int, _:char_p) -> c_int;
-            pub fn mvprintw(_:c_int, _:c_int, _:char_p) -> c_int;
-            //  fn mvscanw(_:c_int,_:c_int, _:char_p) -> c_int;
-            pub fn mvvline(_:c_int, _:c_int, _:chtype, _:c_int) -> c_int;
-            pub fn mvwaddch(_:WINDOW, _:c_int, _:c_int, _:chtype) -> c_int;
-            pub fn mvwaddchnstr(_:WINDOW, _:c_int, _:c_int, _:chtype_p, _:c_int) -> c_int;
-            pub fn mvwaddchstr(_:WINDOW, _:c_int, _:c_int, _:chtype_p) -> c_int;
-            pub fn mvwaddnstr(_:WINDOW, _:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
-            pub fn mvwaddstr(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
-            pub fn mvwchgat(_:WINDOW, _:c_int, _:c_int, _:c_int, _:attr_t, _:c_short, _:void_p) -> c_int;
-            pub fn mvwdelch(_:WINDOW, _:c_int, _:c_int) -> c_int;
-            pub fn mvwgetch(_:WINDOW, _:c_int, _:c_int) -> c_int;
-            pub fn mvwgetnstr(_:WINDOW, _:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
-            pub fn mvwgetstr(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
-            pub fn mvwhline(_:WINDOW, _:c_int, _:c_int, _:chtype, _:c_int) -> c_int;
-            pub fn mvwin(_:WINDOW,_:c_int,_:c_int) -> c_int;
-            pub fn mvwinch(_:WINDOW, _:c_int, _:c_int) -> chtype;
-            pub fn mvwinchnstr(_:WINDOW, _:c_int, _:c_int, _:chtype_p, _:c_int) -> c_int;
-            pub fn mvwinchstr(_:WINDOW, _:c_int, _:c_int, _:chtype_p) -> c_int;
-            pub fn mvwinnstr(_:WINDOW, _:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
-            pub fn mvwinsch(_:WINDOW, _:c_int, _:c_int, _:chtype) -> c_int;
-            pub fn mvwinsnstr(_:WINDOW, _:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
-            pub fn mvwinsstr(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
-            pub fn mvwinstr(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
-            pub fn mvwprintw(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
+extern {
+    pub fn addch(_:chtype) -> c_int;
+    pub fn addchnstr(_:*const chtype, _:c_int) -> c_int;
+    pub fn addchstr(_:*const chtype) -> c_int;
+    pub fn addnstr(_:*const c_char, _:c_int) -> c_int;
+    pub fn addstr(_:*const c_char) -> c_int;
+    pub fn assume_default_colors(_:c_int, _:c_int) -> c_int;
+    pub fn attroff(_:NCURSES_ATTR_T) -> c_int;
+    pub fn attron(_:NCURSES_ATTR_T) -> c_int;
+    pub fn attrset(_:NCURSES_ATTR_T) -> c_int;
+    pub fn attr_get(_:attr_t_p, _:short_p, _:void_p) -> c_int;
+    pub fn attr_off(_:attr_t, _:void_p) -> c_int;
+    pub fn attr_on(_:attr_t, _:void_p) -> c_int;
+    pub fn attr_set(_:attr_t, _:c_short, _:void_p) -> c_int;
+    pub fn baudrate() -> c_int;
+    pub fn beep() -> c_int;
+    pub fn bkgd(_:chtype) -> c_int;
+    pub fn bkgdset(_:chtype);
+    pub fn border(_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype) -> c_int;
+    pub fn box_(_:WINDOW, _:chtype, _:chtype) -> c_int;
+    pub fn can_change_color() -> c_bool;
+    pub fn cbreak() -> c_int;
+    pub fn chgat(_:c_int, _:attr_t, _:c_short, _:void_p) -> c_int;
+    pub fn clear() -> c_int;
+    pub fn clearok(_:WINDOW,_:c_bool) -> c_int;
+    pub fn clrtobot() -> c_int;
+    pub fn clrtoeol() -> c_int;
+    pub fn color_content(_:c_short,_:short_p,_:short_p,_:short_p) -> c_int;
+    pub fn color_set(_:c_short,_:void_p) -> c_int;
+    pub fn COLOR_PAIR(_:c_int) -> c_int;
+    pub fn copywin(_:WINDOW,_:WINDOW,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int) -> c_int;
+    pub fn curs_set(_:c_int) -> c_int;
+    pub fn def_prog_mode() -> c_int;
+    pub fn def_shell_mode() -> c_int;
+    pub fn delay_output(_:c_int) -> c_int;
+    pub fn delch() -> c_int;
+    pub fn delscreen(_:SCREEN);
+    pub fn delwin(_:WINDOW) -> c_int;
+    pub fn deleteln() -> c_int;
+    pub fn derwin(_:WINDOW,_:c_int,_:c_int,_:c_int,_:c_int) -> WINDOW;
+    pub fn doupdate() -> c_int;
+    pub fn dupwin(_:WINDOW) -> WINDOW;
+    pub fn echo() -> c_int;
+    pub fn echochar(_:chtype) -> c_int;
+    pub fn erase() -> c_int;
+    pub fn endwin() -> c_int;
+    pub fn erasechar() -> c_char;
+    pub fn filter();
+    pub fn flash() -> c_int;
+    pub fn flushinp() -> c_int;
+    pub fn getbkgd(_:WINDOW) -> chtype;
+    pub fn getch() -> c_int;
+    pub fn getnstr(_:*mut c_char, _:c_int) -> c_int;
+    pub fn getstr(_:char_p) -> c_int;
+    pub fn getwin(_:FILE_p) -> WINDOW;
+    pub fn halfdelay(_:c_int) -> c_int;
+    pub fn has_colors() -> c_bool;
+    pub fn has_ic() -> c_bool;
+    pub fn has_il() -> c_bool;
+    pub fn hline(_:chtype, _:c_int) -> c_int;
+    pub fn idcok(_:WINDOW, _:c_bool);
+    pub fn idlok(_:WINDOW, _:c_bool) -> c_int;
+    pub fn immedok(_:WINDOW, _:c_bool);
+    pub fn inch() -> chtype;
+    pub fn inchnstr(_:chtype_p, _:c_int) -> c_int;
+    pub fn inchstr(_:chtype_p) -> c_int;
+    pub fn initscr() -> WINDOW;
+    pub fn init_color(_:c_short,_:c_short,_:c_short,_:c_short) -> c_int;
+    pub fn init_pair(_:c_short,_:c_short,_:c_short) -> c_int;
+    pub fn innstr(_:char_p, _:c_int) -> c_int;
+    pub fn insch(_:chtype) -> c_int;
+    pub fn insdelln(_:c_int) -> c_int;
+    pub fn insertln() -> c_int;
+    pub fn insnstr(_:char_p, _:c_int) -> c_int;
+    pub fn insstr(_:char_p) -> c_int;
+    pub fn instr(_:char_p) -> c_int;
+    pub fn intrflush(_:WINDOW,_:c_bool) -> c_int;
+    pub fn isendwin() -> c_bool;
+    pub fn is_linetouched(_:WINDOW,_:c_int) -> c_bool;
+    pub fn is_term_resized(_:c_int, _:c_int) -> c_bool;
+    pub fn is_wintouched(_:WINDOW) -> c_bool;
+    pub fn keyname(_:c_int) -> *const c_char;
+    pub fn keypad(_:WINDOW, _:c_bool) -> c_int;
+    pub fn killchar() -> c_char;
+    pub fn leaveok(_:WINDOW,_:c_bool) -> c_int;
+    pub fn longname() -> *mut c_char;
+    pub fn meta(_:WINDOW,_:c_bool) -> c_int;
+    #[link_name = "move"]
+    pub fn mv(_:c_int, _:c_int) -> c_int;
+    pub fn mvaddch(_:c_int, _:c_int, _:chtype) -> c_int;
+    pub fn mvaddchnstr(_:c_int, _:c_int, _:chtype_p, _:c_int) -> c_int;
+    pub fn mvaddchstr(_:c_int, _:c_int, _:chtype_p) -> c_int;
+    pub fn mvaddnstr(_:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
+    pub fn mvaddstr(_:c_int, _:c_int, _:char_p) -> c_int;
+    pub fn mvchgat(_:c_int, _:c_int, _:c_int, _:attr_t, _:c_short, _:void_p) -> c_int;
+    pub fn mvcur(_:c_int,_:c_int,_:c_int,_:c_int) -> c_int;
+    pub fn mvdelch(_:c_int, _:c_int) -> c_int;
+    pub fn mvderwin(_:WINDOW, _:c_int, _:c_int) -> c_int;
+    pub fn mvgetch(_:c_int, _:c_int) -> c_int;
+    pub fn mvgetnstr(_:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
+    pub fn mvgetstr(_:c_int, _:c_int, _:char_p) -> c_int;
+    pub fn mvhline(_:c_int, _:c_int, _:chtype, _:c_int) -> c_int;
+    pub fn mvinch(_:c_int, _:c_int) -> chtype;
+    pub fn mvinchnstr(_:c_int, _:c_int, _:chtype_p, _:c_int) -> c_int;
+    pub fn mvinchstr(_:c_int, _:c_int, _:chtype_p) -> c_int;
+    pub fn mvinnstr(_:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
+    pub fn mvinsch(_:c_int, _:c_int, _:chtype) -> c_int;
+    pub fn mvinsnstr(_:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
+    pub fn mvinsstr(_:c_int, _:c_int, _:char_p) -> c_int;
+    pub fn mvinstr(_:c_int, _:c_int, _:char_p) -> c_int;
+    pub fn mvprintw(_:c_int, _:c_int, _:char_p) -> c_int;
+    //  fn mvscanw(_:c_int,_:c_int, _:char_p) -> c_int;
+    pub fn mvvline(_:c_int, _:c_int, _:chtype, _:c_int) -> c_int;
+    pub fn mvwaddch(_:WINDOW, _:c_int, _:c_int, _:chtype) -> c_int;
+    pub fn mvwaddchnstr(_:WINDOW, _:c_int, _:c_int, _:chtype_p, _:c_int) -> c_int;
+    pub fn mvwaddchstr(_:WINDOW, _:c_int, _:c_int, _:chtype_p) -> c_int;
+    pub fn mvwaddnstr(_:WINDOW, _:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
+    pub fn mvwaddstr(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
+    pub fn mvwchgat(_:WINDOW, _:c_int, _:c_int, _:c_int, _:attr_t, _:c_short, _:void_p) -> c_int;
+    pub fn mvwdelch(_:WINDOW, _:c_int, _:c_int) -> c_int;
+    pub fn mvwgetch(_:WINDOW, _:c_int, _:c_int) -> c_int;
+    pub fn mvwgetnstr(_:WINDOW, _:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
+    pub fn mvwgetstr(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
+    pub fn mvwhline(_:WINDOW, _:c_int, _:c_int, _:chtype, _:c_int) -> c_int;
+    pub fn mvwin(_:WINDOW,_:c_int,_:c_int) -> c_int;
+    pub fn mvwinch(_:WINDOW, _:c_int, _:c_int) -> chtype;
+    pub fn mvwinchnstr(_:WINDOW, _:c_int, _:c_int, _:chtype_p, _:c_int) -> c_int;
+    pub fn mvwinchstr(_:WINDOW, _:c_int, _:c_int, _:chtype_p) -> c_int;
+    pub fn mvwinnstr(_:WINDOW, _:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
+    pub fn mvwinsch(_:WINDOW, _:c_int, _:c_int, _:chtype) -> c_int;
+    pub fn mvwinsnstr(_:WINDOW, _:c_int, _:c_int, _:char_p, _:c_int) -> c_int;
+    pub fn mvwinsstr(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
+    pub fn mvwinstr(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
+    pub fn mvwprintw(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
 
-            //  fn mvwscanw(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
-            pub fn mvwvline(_:WINDOW, _:c_int, _:c_int, _:chtype, _:c_int) -> c_int;
-            pub fn napms(_:c_int) -> c_int;
-            pub fn newpad(_:c_int,_:c_int) -> WINDOW;
-            pub fn newterm(_:char_p,_:FILE_p,_:FILE_p) -> SCREEN;
-            pub fn newwin(_:c_int,_:c_int,_:c_int,_:c_int) -> WINDOW;
-            pub fn nl() -> c_int;
-            pub fn nocbreak() -> c_int;
-            pub fn nodelay(_:WINDOW,_:c_bool) -> c_int;
-            pub fn noecho() -> c_int;
-            pub fn nonl() -> c_int;
-            pub fn noqiflush();
-            pub fn noraw() -> c_int;
-            pub fn notimeout(_:WINDOW,_:c_bool) -> c_int;
-            pub fn overlay(_:WINDOW,_:WINDOW) -> c_int;
-            pub fn overwrite(_:WINDOW,_:WINDOW) -> c_int;
-            pub fn pair_content(_:c_short,_:short_p,_:short_p) -> c_int;
-            pub fn PAIR_NUMBER(_:c_int) -> c_int;
-            pub fn pechochar(_:WINDOW, _:chtype) -> c_int;
-            pub fn pnoutrefresh(_:WINDOW,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int) -> c_int;
-            pub fn prefresh(_:WINDOW,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int) -> c_int;
+    //  fn mvwscanw(_:WINDOW, _:c_int, _:c_int, _:char_p) -> c_int;
+    pub fn mvwvline(_:WINDOW, _:c_int, _:c_int, _:chtype, _:c_int) -> c_int;
+    pub fn napms(_:c_int) -> c_int;
+    pub fn newpad(_:c_int,_:c_int) -> WINDOW;
+    pub fn newterm(_:char_p,_:FILE_p,_:FILE_p) -> SCREEN;
+    pub fn newwin(_:c_int,_:c_int,_:c_int,_:c_int) -> WINDOW;
+    pub fn nl() -> c_int;
+    pub fn nocbreak() -> c_int;
+    pub fn nodelay(_:WINDOW,_:c_bool) -> c_int;
+    pub fn noecho() -> c_int;
+    pub fn nonl() -> c_int;
+    pub fn noqiflush();
+    pub fn noraw() -> c_int;
+    pub fn notimeout(_:WINDOW,_:c_bool) -> c_int;
+    pub fn overlay(_:WINDOW,_:WINDOW) -> c_int;
+    pub fn overwrite(_:WINDOW,_:WINDOW) -> c_int;
+    pub fn pair_content(_:c_short,_:short_p,_:short_p) -> c_int;
+    pub fn PAIR_NUMBER(_:c_int) -> c_int;
+    pub fn pechochar(_:WINDOW, _:chtype) -> c_int;
+    pub fn pnoutrefresh(_:WINDOW,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int) -> c_int;
+    pub fn prefresh(_:WINDOW,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int,_:c_int) -> c_int;
 
-            pub fn printw(_:char_p) -> c_int;
-            pub fn putwin(_:WINDOW, _:FILE_p) -> c_int;
-            pub fn qiflush();
-            pub fn raw() -> c_int;
-            pub fn redrawwin(_:WINDOW) -> c_int;
-            pub fn refresh() -> c_int;
-            pub fn resizeterm(_:c_int, _:c_int) -> c_int;
-            pub fn resize_term(_:c_int, _:c_int) -> c_int;
-            pub fn resetty() -> c_int;
-            pub fn reset_prog_mode() -> c_int;
-            pub fn reset_shell_mode() -> c_int;
-            // fn ripoffline(_:c_int, extern  fn f(WINDOW, c_int) -> c_int) -> c_int;
-            pub fn savetty() -> c_int;
-            // fn scanw(_:NCURSES_CONST char_p,...) -> c_int;
-            pub fn scr_dump(_:char_p) -> c_int;
-            pub fn scr_init(_:char_p) -> c_int;
-            pub fn scrl(_:c_int) -> c_int;
-            pub fn scroll(_:WINDOW) -> c_int;
-            pub fn scrollok(_:WINDOW,_:c_bool) -> c_int;
-            pub fn scr_restore(_:char_p) -> c_int;
-            pub fn scr_set(_:char_p) -> c_int;
-            pub fn setlocale(_:c_int, _:char_p) -> char_p;
-            pub fn setscrreg(_:c_int,_:c_int) -> c_int;
-            pub fn set_term(_:SCREEN) -> SCREEN;
-            pub fn set_escdelay(_:c_int) -> c_int;
-            pub fn set_tabsize(_:c_int) -> c_int;
-            pub fn slk_attroff(_:chtype) -> c_int;
-            pub fn slk_attr_off(_:attr_t, _:void_p) -> c_int;
-            pub fn slk_attron(_:chtype) -> c_int;
-            pub fn slk_attr_on(_:attr_t,_:void_p) -> c_int;
-            pub fn slk_attrset(_:chtype) -> c_int;
-            pub fn slk_attr() -> attr_t;
-            pub fn slk_attr_set(_:attr_t,_:c_short,_:void_p) -> c_int;
-            pub fn slk_clear() -> c_int;
-            pub fn slk_color(_:c_short) -> c_int;
-            pub fn slk_init(_:c_int) -> c_int;
-            pub fn slk_label(_:c_int) -> char_p;
-            pub fn slk_noutrefresh() -> c_int;
-            pub fn slk_refresh() -> c_int;
-            pub fn slk_restore() -> c_int;
-            pub fn slk_set(_:c_int,_:char_p,_:c_int) -> c_int;
-            pub fn slk_touch() -> c_int;
-            pub fn standout() -> c_int;
-            pub fn standend() -> c_int;
-            pub fn start_color() -> c_int;
-            pub fn subpad(_:WINDOW, _:c_int, _:c_int, _:c_int, _:c_int) -> WINDOW;
-            pub fn subwin(_:WINDOW, _:c_int, _:c_int, _:c_int, _:c_int) -> WINDOW;
-            pub fn syncok(_:WINDOW, _:c_bool) -> c_int;
-            pub fn termattrs() -> chtype;
-            pub fn termname() -> char_p;
-            pub fn timeout(_:c_int);
-            pub fn touchline(_:WINDOW, _:c_int, _:c_int) -> c_int;
-            pub fn touchwin(_:WINDOW) -> c_int;
-            pub fn typeahead(_:c_int) -> c_int;
-            pub fn ungetch(_:c_int) -> c_int;
-            pub fn untouchwin(_:WINDOW) -> c_int;
-            pub fn use_env(_:c_bool);
-            pub fn use_default_colors() -> c_int;
-            pub fn vidattr(_:chtype) -> c_int;
-            //  fn vidputs(_:chtype, extern  fn f(c_int) -> c_int) -> c_int;
-            //pub fn vidputs(_:chtype, f:*mut c_char) -> c_int;
-            pub fn vline(_:chtype, _:c_int) -> c_int;
-            pub fn vwprintw(_:WINDOW, _:char_p, _:va_list) -> c_int;
-            pub fn vw_printw(_:WINDOW, _:char_p,_:va_list) -> c_int;
-            //  fn vwscanw(_:WINDOW, _:char_p, _:va_list) -> c_int;
-            //  fn vw_scanw(_:WINDOW, _:char_p, _:va_list) -> c_int;
-            pub fn waddch(_:WINDOW, _:chtype) -> c_int;
-            pub fn waddchnstr(_:WINDOW,_:chtype_p,_:c_int) -> c_int;
-            pub fn waddchstr(_:WINDOW,_:chtype_p) -> c_int;
-            pub fn waddnstr(_:WINDOW,_:char_p,_:c_int) -> c_int;
-            pub fn waddstr(_:WINDOW,_:char_p) -> c_int;
-            pub fn wattron(_:WINDOW, _:NCURSES_ATTR_T) -> c_int;
-            pub fn wattroff(_:WINDOW, _:NCURSES_ATTR_T) -> c_int;
-            pub fn wattrset(_:WINDOW, _:NCURSES_ATTR_T) -> c_int;
-            pub fn wattr_get(_:WINDOW, _:attr_t_p, _:short_p, _:void_p) -> c_int;
-            pub fn wattr_on(_:WINDOW, _:attr_t, _:void_p) -> c_int;
-            pub fn wattr_off(_:WINDOW, _:attr_t, _:void_p) -> c_int;
-            pub fn wattr_set(_:WINDOW, _:attr_t, _:c_short, _:void_p) -> c_int;
-            pub fn wbkgd(_:WINDOW, _:chtype) -> c_int;
-            pub fn wbkgdset(_:WINDOW,_:chtype);
-            pub fn wborder(_:WINDOW,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype) -> c_int;
-            pub fn wchgat(_:WINDOW, _:c_int, _:attr_t, _:c_short, _:void_p) -> c_int;
-            pub fn wclear(_:WINDOW) -> c_int;
-            pub fn wclrtobot(_:WINDOW) -> c_int;
-            pub fn wclrtoeol(_:WINDOW) -> c_int;
-            pub fn wcolor_set(_:WINDOW,_:c_short,_:void_p) -> c_int;
-            pub fn wcursyncup(_:WINDOW);
-            pub fn wdelch(_:WINDOW) -> c_int;
-            pub fn wdeleteln(_:WINDOW) -> c_int;
-            pub fn wechochar(_:WINDOW, _:chtype) -> c_int;
-            pub fn werase(_:WINDOW) -> c_int;
-            pub fn wgetch(_:WINDOW) -> c_int;
-            pub fn wget_wch(_:WINDOW, _:*mut winttype) -> c_int;
-            pub fn mvwget_wch(_:WINDOW, _:c_int, _:c_int, _:*mut winttype) -> c_int;
-            pub fn mvget_wch(_:c_int, _: c_int, _:*mut winttype) -> c_int;
-            pub fn get_wch(_:*mut winttype) -> c_int;
-            pub fn unget_wch(_:winttype) -> c_int;
-            pub fn wgetnstr(_:WINDOW,_:*const u8,_:c_int) -> c_int;
-            pub fn wgetstr(_:WINDOW, _:char_p) -> c_int;
-            pub fn whline(_:WINDOW, _:chtype, _:c_int) -> c_int;
-            pub fn winch(_:WINDOW) -> chtype;
-            pub fn winchnstr(_:WINDOW, _:chtype_p, _:c_int) -> c_int;
-            pub fn winchstr(_:WINDOW, _:chtype_p) -> c_int;
-            pub fn winnstr(_:WINDOW, _:char_p, _:c_int) -> c_int;
-            pub fn winsch(_:WINDOW, _:chtype) -> c_int;
-            pub fn winsdelln(_:WINDOW,_:c_int) -> c_int;
-            pub fn winsertln(_:WINDOW) -> c_int;
-            pub fn winsnstr(_:WINDOW, _:char_p,_:c_int) -> c_int;
-            pub fn winsstr(_:WINDOW, _:char_p) -> c_int;
-            pub fn winstr(_:WINDOW, _:char_p) -> c_int;
-            pub fn wmove(_:WINDOW,_:c_int,_:c_int) -> c_int;
-            pub fn wnoutrefresh(_:WINDOW) -> c_int;
-            pub fn wprintw(_:WINDOW, _:char_p) -> c_int;
-            pub fn wredrawln(_:WINDOW,_:c_int,_:c_int) -> c_int;
-            pub fn wrefresh(_:WINDOW) -> c_int;
-            pub fn wresize(_:WINDOW, _:c_int, _:c_int) -> c_int;
-            //  fn wscanw(_:WINDOW, _:NCURSES_CONST char_p) -> c_int;
-            pub fn wscrl(_:WINDOW,_:c_int) -> c_int;
-            pub fn wsetscrreg(_:WINDOW,_:c_int,_:c_int) -> c_int;
-            pub fn wstandout(_:WINDOW) -> c_int;
-            pub fn wstandend(_:WINDOW) -> c_int;
-            pub fn wsyncdown(_:WINDOW);
-            pub fn wsyncup(_:WINDOW);
-            pub fn wtimeout(_:WINDOW,_:c_int);
-            pub fn wtouchln(_:WINDOW,_:c_int,_:c_int,_:c_int) -> c_int;
-            pub fn wvline(_:WINDOW,_:chtype,_:c_int) -> c_int;
+    pub fn printw(_:char_p) -> c_int;
+    pub fn putwin(_:WINDOW, _:FILE_p) -> c_int;
+    pub fn qiflush();
+    pub fn raw() -> c_int;
+    pub fn redrawwin(_:WINDOW) -> c_int;
+    pub fn refresh() -> c_int;
+    pub fn resizeterm(_:c_int, _:c_int) -> c_int;
+    pub fn resize_term(_:c_int, _:c_int) -> c_int;
+    pub fn resetty() -> c_int;
+    pub fn reset_prog_mode() -> c_int;
+    pub fn reset_shell_mode() -> c_int;
+    // fn ripoffline(_:c_int, extern  fn f(WINDOW, c_int) -> c_int) -> c_int;
+    pub fn savetty() -> c_int;
+    // fn scanw(_:NCURSES_CONST char_p,...) -> c_int;
+    pub fn scr_dump(_:char_p) -> c_int;
+    pub fn scr_init(_:char_p) -> c_int;
+    pub fn scrl(_:c_int) -> c_int;
+    pub fn scroll(_:WINDOW) -> c_int;
+    pub fn scrollok(_:WINDOW,_:c_bool) -> c_int;
+    pub fn scr_restore(_:char_p) -> c_int;
+    pub fn scr_set(_:char_p) -> c_int;
+    pub fn setlocale(_:c_int, _:char_p) -> char_p;
+    pub fn setscrreg(_:c_int,_:c_int) -> c_int;
+    pub fn set_term(_:SCREEN) -> SCREEN;
+    pub fn set_escdelay(_:c_int) -> c_int;
+    pub fn set_tabsize(_:c_int) -> c_int;
+    pub fn slk_attroff(_:chtype) -> c_int;
+    pub fn slk_attr_off(_:attr_t, _:void_p) -> c_int;
+    pub fn slk_attron(_:chtype) -> c_int;
+    pub fn slk_attr_on(_:attr_t,_:void_p) -> c_int;
+    pub fn slk_attrset(_:chtype) -> c_int;
+    pub fn slk_attr() -> attr_t;
+    pub fn slk_attr_set(_:attr_t,_:c_short,_:void_p) -> c_int;
+    pub fn slk_clear() -> c_int;
+    pub fn slk_color(_:c_short) -> c_int;
+    pub fn slk_init(_:c_int) -> c_int;
+    pub fn slk_label(_:c_int) -> char_p;
+    pub fn slk_noutrefresh() -> c_int;
+    pub fn slk_refresh() -> c_int;
+    pub fn slk_restore() -> c_int;
+    pub fn slk_set(_:c_int,_:char_p,_:c_int) -> c_int;
+    pub fn slk_touch() -> c_int;
+    pub fn standout() -> c_int;
+    pub fn standend() -> c_int;
+    pub fn start_color() -> c_int;
+    pub fn subpad(_:WINDOW, _:c_int, _:c_int, _:c_int, _:c_int) -> WINDOW;
+    pub fn subwin(_:WINDOW, _:c_int, _:c_int, _:c_int, _:c_int) -> WINDOW;
+    pub fn syncok(_:WINDOW, _:c_bool) -> c_int;
+    pub fn termattrs() -> chtype;
+    pub fn termname() -> char_p;
+    pub fn timeout(_:c_int);
+    pub fn touchline(_:WINDOW, _:c_int, _:c_int) -> c_int;
+    pub fn touchwin(_:WINDOW) -> c_int;
+    pub fn typeahead(_:c_int) -> c_int;
+    pub fn ungetch(_:c_int) -> c_int;
+    pub fn untouchwin(_:WINDOW) -> c_int;
+    pub fn use_env(_:c_bool);
+    pub fn use_default_colors() -> c_int;
+    pub fn vidattr(_:chtype) -> c_int;
+    //  fn vidputs(_:chtype, extern  fn f(c_int) -> c_int) -> c_int;
+    //pub fn vidputs(_:chtype, f:*mut c_char) -> c_int;
+    pub fn vline(_:chtype, _:c_int) -> c_int;
+    pub fn vwprintw(_:WINDOW, _:char_p, _:va_list) -> c_int;
+    pub fn vw_printw(_:WINDOW, _:char_p,_:va_list) -> c_int;
+    //  fn vwscanw(_:WINDOW, _:char_p, _:va_list) -> c_int;
+    //  fn vw_scanw(_:WINDOW, _:char_p, _:va_list) -> c_int;
+    pub fn waddch(_:WINDOW, _:chtype) -> c_int;
+    pub fn waddchnstr(_:WINDOW,_:chtype_p,_:c_int) -> c_int;
+    pub fn waddchstr(_:WINDOW,_:chtype_p) -> c_int;
+    pub fn waddnstr(_:WINDOW,_:char_p,_:c_int) -> c_int;
+    pub fn waddstr(_:WINDOW,_:char_p) -> c_int;
+    pub fn wattron(_:WINDOW, _:NCURSES_ATTR_T) -> c_int;
+    pub fn wattroff(_:WINDOW, _:NCURSES_ATTR_T) -> c_int;
+    pub fn wattrset(_:WINDOW, _:NCURSES_ATTR_T) -> c_int;
+    pub fn wattr_get(_:WINDOW, _:attr_t_p, _:short_p, _:void_p) -> c_int;
+    pub fn wattr_on(_:WINDOW, _:attr_t, _:void_p) -> c_int;
+    pub fn wattr_off(_:WINDOW, _:attr_t, _:void_p) -> c_int;
+    pub fn wattr_set(_:WINDOW, _:attr_t, _:c_short, _:void_p) -> c_int;
+    pub fn wbkgd(_:WINDOW, _:chtype) -> c_int;
+    pub fn wbkgdset(_:WINDOW,_:chtype);
+    pub fn wborder(_:WINDOW,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype,_:chtype) -> c_int;
+    pub fn wchgat(_:WINDOW, _:c_int, _:attr_t, _:c_short, _:void_p) -> c_int;
+    pub fn wclear(_:WINDOW) -> c_int;
+    pub fn wclrtobot(_:WINDOW) -> c_int;
+    pub fn wclrtoeol(_:WINDOW) -> c_int;
+    pub fn wcolor_set(_:WINDOW,_:c_short,_:void_p) -> c_int;
+    pub fn wcursyncup(_:WINDOW);
+    pub fn wdelch(_:WINDOW) -> c_int;
+    pub fn wdeleteln(_:WINDOW) -> c_int;
+    pub fn wechochar(_:WINDOW, _:chtype) -> c_int;
+    pub fn werase(_:WINDOW) -> c_int;
+    pub fn wgetch(_:WINDOW) -> c_int;
+    pub fn wget_wch(_:WINDOW, _:*mut winttype) -> c_int;
+    pub fn mvwget_wch(_:WINDOW, _:c_int, _:c_int, _:*mut winttype) -> c_int;
+    pub fn mvget_wch(_:c_int, _: c_int, _:*mut winttype) -> c_int;
+    pub fn get_wch(_:*mut winttype) -> c_int;
+    pub fn unget_wch(_:winttype) -> c_int;
+    pub fn wgetnstr(_:WINDOW,_:*const u8,_:c_int) -> c_int;
+    pub fn wgetstr(_:WINDOW, _:char_p) -> c_int;
+    pub fn whline(_:WINDOW, _:chtype, _:c_int) -> c_int;
+    pub fn winch(_:WINDOW) -> chtype;
+    pub fn winchnstr(_:WINDOW, _:chtype_p, _:c_int) -> c_int;
+    pub fn winchstr(_:WINDOW, _:chtype_p) -> c_int;
+    pub fn winnstr(_:WINDOW, _:char_p, _:c_int) -> c_int;
+    pub fn winsch(_:WINDOW, _:chtype) -> c_int;
+    pub fn winsdelln(_:WINDOW,_:c_int) -> c_int;
+    pub fn winsertln(_:WINDOW) -> c_int;
+    pub fn winsnstr(_:WINDOW, _:char_p,_:c_int) -> c_int;
+    pub fn winsstr(_:WINDOW, _:char_p) -> c_int;
+    pub fn winstr(_:WINDOW, _:char_p) -> c_int;
+    pub fn wmove(_:WINDOW,_:c_int,_:c_int) -> c_int;
+    pub fn wnoutrefresh(_:WINDOW) -> c_int;
+    pub fn wprintw(_:WINDOW, _:char_p) -> c_int;
+    pub fn wredrawln(_:WINDOW,_:c_int,_:c_int) -> c_int;
+    pub fn wrefresh(_:WINDOW) -> c_int;
+    pub fn wresize(_:WINDOW, _:c_int, _:c_int) -> c_int;
+    //  fn wscanw(_:WINDOW, _:NCURSES_CONST char_p) -> c_int;
+    pub fn wscrl(_:WINDOW,_:c_int) -> c_int;
+    pub fn wsetscrreg(_:WINDOW,_:c_int,_:c_int) -> c_int;
+    pub fn wstandout(_:WINDOW) -> c_int;
+    pub fn wstandend(_:WINDOW) -> c_int;
+    pub fn wsyncdown(_:WINDOW);
+    pub fn wsyncup(_:WINDOW);
+    pub fn wtimeout(_:WINDOW,_:c_int);
+    pub fn wtouchln(_:WINDOW,_:c_int,_:c_int,_:c_int) -> c_int;
+    pub fn wvline(_:WINDOW,_:chtype,_:c_int) -> c_int;
 
-            /*
-             * These are also declared in <term.h>:
-             */
-            pub fn tigetflag(_:char_p) -> c_int;
-            pub fn tigetnum(_:char_p) -> c_int;
-            pub fn tigetstr(_:char_p) -> *mut c_char;
-            pub fn putp(_:char_p) -> c_int;
+    /*
+     * These are also declared in <term.h>:
+     */
+    pub fn tigetflag(_:char_p) -> c_int;
+    pub fn tigetnum(_:char_p) -> c_int;
+    pub fn tigetstr(_:char_p) -> *mut c_char;
+    pub fn putp(_:char_p) -> c_int;
 
-            pub fn tparm(_:char_p) -> *mut c_char;
+    pub fn tparm(_:char_p) -> *mut c_char;
 
-            /*
-             * These functions are not in X/Open, but we use them in macro definitions:
-             */
-            pub fn getattrs(_:WINDOW) -> c_int;
-            pub fn getcurx(_:WINDOW) -> c_int;
-            pub fn getcury(_:WINDOW) -> c_int;
-            pub fn getbegx(_:WINDOW) -> c_int;
-            pub fn getbegy(_:WINDOW) -> c_int;
-            pub fn getmaxx(_:WINDOW) -> c_int;
-            pub fn getmaxy(_:WINDOW) -> c_int;
-            pub fn getparx(_:WINDOW) -> c_int;
-            pub fn getpary(_:WINDOW) -> c_int;
+    /*
+     * These functions are not in X/Open, but we use them in macro definitions:
+     */
+    pub fn getattrs(_:WINDOW) -> c_int;
+    pub fn getcurx(_:WINDOW) -> c_int;
+    pub fn getcury(_:WINDOW) -> c_int;
+    pub fn getbegx(_:WINDOW) -> c_int;
+    pub fn getbegy(_:WINDOW) -> c_int;
+    pub fn getmaxx(_:WINDOW) -> c_int;
+    pub fn getmaxy(_:WINDOW) -> c_int;
+    pub fn getparx(_:WINDOW) -> c_int;
+    pub fn getpary(_:WINDOW) -> c_int;
 
-            /*
-             * These extensions provide access to information stored in the WINDOW even
-             * when NCURSES_OPAQUE is set:
-             */
-            pub fn wgetparent(_:WINDOW) -> WINDOW;
-            pub fn is_cleared(_:WINDOW) -> c_bool;
-            pub fn is_idcok(_:WINDOW) -> c_bool;
-            pub fn is_idlok(_:WINDOW) -> c_bool;
-            pub fn is_immedok(_:WINDOW) -> c_bool;
-            pub fn is_keypad(_:WINDOW) -> c_bool;
-            pub fn is_leaveok(_:WINDOW) -> c_bool;
-            pub fn is_nodelay(_:WINDOW) -> c_bool;
-            pub fn is_notimeout(_:WINDOW) -> c_bool;
-            pub fn is_scrollok(_:WINDOW) -> c_bool;
-            pub fn is_syncok(_:WINDOW) -> c_bool;
-            pub fn wgetscrreg(_:WINDOW, _:*mut c_int, _:*mut c_int) -> c_int;
-            /*
-             * Added mouse support
-             */
-            pub fn has_mouse() -> c_bool;
-            pub fn getmouse(_:*mut MEVENT) -> c_int;
-            pub fn ungetmouse(_:*mut MEVENT) -> c_int;
-            pub fn mousemask(_:mmask_t,_:*mut mmask_t) -> mmask_t;
-            pub fn wenclose(_:WINDOW,_:c_int,_:c_int) -> c_bool;
-            pub fn mouseinterval(_:c_int) -> c_int;
-            pub fn wmouse_trafo(_:*mut WINDOW,_:*mut c_int,_:*mut c_int,_:c_bool) -> c_bool;
-            pub fn mouse_trafo(_:*mut c_int,_:*mut c_int,_:c_bool) -> c_bool;
-        }
-    });
-
-//end macro rules
-
-// Don't link ncursesw on macos
-define_sharedffi!(cfg(all(feature="wide", not(target_os="macos"))), link(name="ncursesw"));
-define_sharedffi!(cfg(any(not(feature="wide"), target_os="macos")), link(name="ncurses"));
+    /*
+     * These extensions provide access to information stored in the WINDOW even
+     * when NCURSES_OPAQUE is set:
+     */
+    pub fn wgetparent(_:WINDOW) -> WINDOW;
+    pub fn is_cleared(_:WINDOW) -> c_bool;
+    pub fn is_idcok(_:WINDOW) -> c_bool;
+    pub fn is_idlok(_:WINDOW) -> c_bool;
+    pub fn is_immedok(_:WINDOW) -> c_bool;
+    pub fn is_keypad(_:WINDOW) -> c_bool;
+    pub fn is_leaveok(_:WINDOW) -> c_bool;
+    pub fn is_nodelay(_:WINDOW) -> c_bool;
+    pub fn is_notimeout(_:WINDOW) -> c_bool;
+    pub fn is_scrollok(_:WINDOW) -> c_bool;
+    pub fn is_syncok(_:WINDOW) -> c_bool;
+    pub fn wgetscrreg(_:WINDOW, _:*mut c_int, _:*mut c_int) -> c_int;
+    /*
+     * Added mouse support
+     */
+    pub fn has_mouse() -> c_bool;
+    pub fn getmouse(_:*mut MEVENT) -> c_int;
+    pub fn ungetmouse(_:*mut MEVENT) -> c_int;
+    pub fn mousemask(_:mmask_t,_:*mut mmask_t) -> mmask_t;
+    pub fn wenclose(_:WINDOW,_:c_int,_:c_int) -> c_bool;
+    pub fn mouseinterval(_:c_int) -> c_int;
+    pub fn wmouse_trafo(_:*mut WINDOW,_:*mut c_int,_:*mut c_int,_:c_bool) -> c_bool;
+    pub fn mouse_trafo(_:*mut c_int,_:*mut c_int,_:c_bool) -> c_bool;
+}
diff --git a/src/menu/ll.rs b/src/menu/ll.rs
index aa58eae9..1541ab80 100644
--- a/src/menu/ll.rs
+++ b/src/menu/ll.rs
@@ -8,80 +8,74 @@ pub type MENU = *mut i8;
 pub type ITEM = *mut i8;
 pub type HOOK = Option<extern "C" fn(MENU)>;
 
-macro_rules! define_sharedffi(
-    ($cfgopt: meta, $link: meta) => {
-        #[$cfgopt] #[$link] extern {
-            pub fn menu_items(_:MENU) -> *mut ITEM;
-            pub fn current_item(_:MENU) -> ITEM;
-            pub fn new_item(_:*const c_char, _:*const c_char) -> ITEM;
-            pub fn free_item(_:ITEM);
-            pub fn new_menu(_:*mut ITEM) -> MENU;
-            pub fn item_opts(_:ITEM) -> c_int;
-            pub fn menu_opts(_:MENU) -> c_int;
+#[cfg(feature="menu")]
+extern {
+    pub fn menu_items(_:MENU) -> *mut ITEM;
+    pub fn current_item(_:MENU) -> ITEM;
+    pub fn new_item(_:*const c_char, _:*const c_char) -> ITEM;
+    pub fn free_item(_:ITEM);
+    pub fn new_menu(_:*mut ITEM) -> MENU;
+    pub fn item_opts(_:ITEM) -> c_int;
+    pub fn menu_opts(_:MENU) -> c_int;
 
-            pub fn item_init(_:MENU) -> HOOK;
-            pub fn item_term(_:MENU) -> HOOK;
-            pub fn menu_init(_:MENU) -> HOOK;
-            pub fn menu_term(_:MENU) -> HOOK;
+    pub fn item_init(_:MENU) -> HOOK;
+    pub fn item_term(_:MENU) -> HOOK;
+    pub fn menu_init(_:MENU) -> HOOK;
+    pub fn menu_term(_:MENU) -> HOOK;
 
-            pub fn menu_sub(_:MENU) -> WINDOW;
-            pub fn menu_win(_:MENU) -> WINDOW;
+    pub fn menu_sub(_:MENU) -> WINDOW;
+    pub fn menu_win(_:MENU) -> WINDOW;
 
-            pub fn item_description(_:ITEM) -> *const c_char;
-            pub fn item_name(_:ITEM) -> *const c_char;
-            pub fn menu_mark(_:MENU) -> *const c_char;
-            pub fn menu_request_name(_:c_int) -> *const c_char;
+    pub fn item_description(_:ITEM) -> *const c_char;
+    pub fn item_name(_:ITEM) -> *const c_char;
+    pub fn menu_mark(_:MENU) -> *const c_char;
+    pub fn menu_request_name(_:c_int) -> *const c_char;
 
-            pub fn menu_pattern(_:MENU) -> *mut c_char;
+    pub fn menu_pattern(_:MENU) -> *mut c_char;
 
-            pub fn menu_back(_:MENU) -> chtype;
-            pub fn menu_fore(_:MENU) -> chtype;
-            pub fn menu_grey(_:MENU) -> chtype;
+    pub fn menu_back(_:MENU) -> chtype;
+    pub fn menu_fore(_:MENU) -> chtype;
+    pub fn menu_grey(_:MENU) -> chtype;
 
-            pub fn free_menu(_:MENU) -> c_int;
-            pub fn item_count(_:MENU) -> c_int;
-            pub fn item_index(_:ITEM) -> c_int;
-            pub fn item_opts_off(_:ITEM, _:c_int) -> c_int;
-            pub fn item_opts_on(_:ITEM, _:c_int) -> c_int;
-            pub fn menu_driver(_:MENU, _:c_int) -> c_int;
-            pub fn menu_opts_off(_:MENU, _:c_int) -> c_int;
-            pub fn menu_opts_on(_:MENU, _:c_int) -> c_int;
-            pub fn menu_pad(_:MENU) -> c_int;
-            pub fn pos_menu_cursor(_:MENU) -> c_int;
-            pub fn post_menu(_:MENU) -> c_int;
-            pub fn scale_menu(_:MENU, _:*mut c_int, _:*mut c_int) -> c_int;
-            pub fn set_current_item(_:MENU, _:ITEM) -> c_int;
-            pub fn set_item_init(_:MENU, _:HOOK) -> c_int;
-            pub fn set_item_opts(_:ITEM, _:c_int) -> c_int;
-            pub fn set_item_term(_:MENU, _:HOOK) -> c_int;
-            pub fn set_item_value(_:ITEM, _:c_bool) -> c_int;
-            pub fn set_menu_back(_:MENU, _:chtype) -> c_int;
-            pub fn set_menu_fore(_:MENU, _:chtype) -> c_int;
-            pub fn set_menu_format(_:MENU, _:c_int, _:c_int) -> c_int;
-            pub fn set_menu_grey(_:MENU, _:chtype) -> c_int;
-            pub fn set_menu_init(_:MENU, _:HOOK) -> c_int;
-            pub fn set_menu_items(_:MENU, _:*mut ITEM) -> c_int;
-            pub fn set_menu_mark(_:MENU, _:*const c_char) -> c_int;
-            pub fn set_menu_opts(_:MENU, _:c_int) -> c_int;
-            pub fn set_menu_pad(_:MENU, _:c_int) -> c_int;
-            pub fn set_menu_pattern(_:MENU, _:*const c_char) -> c_int;
-            pub fn set_menu_sub(_:MENU, _:WINDOW) -> c_int;
-            pub fn set_menu_term(_:MENU, _:HOOK) -> c_int;
-            pub fn set_menu_win(_:MENU, _:WINDOW) -> c_int;
-            pub fn set_top_row(_:MENU, _:c_int) -> c_int;
-            pub fn top_row(_:MENU) -> c_int;
-            pub fn unpost_menu(_:MENU) -> c_int;
-            pub fn menu_request_by_name(_:*const c_char) -> c_int;
-            pub fn set_menu_spacing(_:MENU, _:c_int, _:c_int, _:c_int) -> c_int;
-            pub fn menu_spacing(_:MENU, _:*mut c_int, _:*mut c_int, _:*mut c_int) -> c_int;
+    pub fn free_menu(_:MENU) -> c_int;
+    pub fn item_count(_:MENU) -> c_int;
+    pub fn item_index(_:ITEM) -> c_int;
+    pub fn item_opts_off(_:ITEM, _:c_int) -> c_int;
+    pub fn item_opts_on(_:ITEM, _:c_int) -> c_int;
+    pub fn menu_driver(_:MENU, _:c_int) -> c_int;
+    pub fn menu_opts_off(_:MENU, _:c_int) -> c_int;
+    pub fn menu_opts_on(_:MENU, _:c_int) -> c_int;
+    pub fn menu_pad(_:MENU) -> c_int;
+    pub fn pos_menu_cursor(_:MENU) -> c_int;
+    pub fn post_menu(_:MENU) -> c_int;
+    pub fn scale_menu(_:MENU, _:*mut c_int, _:*mut c_int) -> c_int;
+    pub fn set_current_item(_:MENU, _:ITEM) -> c_int;
+    pub fn set_item_init(_:MENU, _:HOOK) -> c_int;
+    pub fn set_item_opts(_:ITEM, _:c_int) -> c_int;
+    pub fn set_item_term(_:MENU, _:HOOK) -> c_int;
+    pub fn set_item_value(_:ITEM, _:c_bool) -> c_int;
+    pub fn set_menu_back(_:MENU, _:chtype) -> c_int;
+    pub fn set_menu_fore(_:MENU, _:chtype) -> c_int;
+    pub fn set_menu_format(_:MENU, _:c_int, _:c_int) -> c_int;
+    pub fn set_menu_grey(_:MENU, _:chtype) -> c_int;
+    pub fn set_menu_init(_:MENU, _:HOOK) -> c_int;
+    pub fn set_menu_items(_:MENU, _:*mut ITEM) -> c_int;
+    pub fn set_menu_mark(_:MENU, _:*const c_char) -> c_int;
+    pub fn set_menu_opts(_:MENU, _:c_int) -> c_int;
+    pub fn set_menu_pad(_:MENU, _:c_int) -> c_int;
+    pub fn set_menu_pattern(_:MENU, _:*const c_char) -> c_int;
+    pub fn set_menu_sub(_:MENU, _:WINDOW) -> c_int;
+    pub fn set_menu_term(_:MENU, _:HOOK) -> c_int;
+    pub fn set_menu_win(_:MENU, _:WINDOW) -> c_int;
+    pub fn set_top_row(_:MENU, _:c_int) -> c_int;
+    pub fn top_row(_:MENU) -> c_int;
+    pub fn unpost_menu(_:MENU) -> c_int;
+    pub fn menu_request_by_name(_:*const c_char) -> c_int;
+    pub fn set_menu_spacing(_:MENU, _:c_int, _:c_int, _:c_int) -> c_int;
+    pub fn menu_spacing(_:MENU, _:*mut c_int, _:*mut c_int, _:*mut c_int) -> c_int;
 
-            pub fn item_value(_:ITEM) -> c_bool;
-            pub fn item_visible(_:ITEM) -> c_bool;
+    pub fn item_value(_:ITEM) -> c_bool;
+    pub fn item_visible(_:ITEM) -> c_bool;
 
-            pub fn menu_format(_:MENU, _:*mut c_int, _:*mut c_int);
-        }
-    }
-);
-
-define_sharedffi!(cfg(all(feature="menu", feature="wide", not(target_os="macos"))), link(name="menuw"));
-define_sharedffi!(cfg(all(feature="menu", any(not(feature="wide"), target_os="macos"))), link(name="menu"));
+    pub fn menu_format(_:MENU, _:*mut c_int, _:*mut c_int);
+}
diff --git a/src/panel/ll.rs b/src/panel/ll.rs
index 839c3041..30f312ef 100644
--- a/src/panel/ll.rs
+++ b/src/panel/ll.rs
@@ -6,7 +6,7 @@ use ll::WINDOW;
 
 pub type PANEL = *mut i8;
 
-#[cfg(feature="panel")] #[link(name="panel")]
+#[cfg(feature="panel")]
 extern {
       pub fn panel_window(_:PANEL) -> WINDOW;
       pub fn update_panels() -> c_void;


Test patch: