فهرست منبع

This is purely to support .NET Core, as it lacks <dllmap> and thus
makes my life a living hell.

Support for bindings to different ncurses version

Since I just removed all the glue code and native detection
dependencies as well as having a single binary for the curses support,
I had to write this support.

.NET Core sadly does not support Mono's <dllmap> yet, so it is not
possible to do this in any decent form. This hell is imposed not only
on my curses binding, but on any library that needs to deal with Linux
packagin peculiarities - and we are inflicing this pain on every .NET
developer doing Unix variations.

Anyways, to make a long story short, now I have this ugly turd of a
binding to curses for the sole purpose of calling into one kind of
curses on MacOS, and another on Linux. This could have been a 3 line
XML configuration file if we had supported dllmap, but instead this
has devolved into what could be described as poster child of bikeshedding.

This is one of that many issues, lots more where this came from:

https://github.com/dotnet/coreclr/issues/930

Miguel de Icaza 7 سال پیش
والد
کامیت
5f0ea5d414
1فایلهای تغییر یافته به همراه372 افزوده شده و 127 حذف شده
  1. 372 127
      Terminal.Gui/MonoCurses/binding.cs

+ 372 - 127
Terminal.Gui/MonoCurses/binding.cs

@@ -2,6 +2,15 @@
 //
 // binding.cs.in: Core binding for curses.
 //
+// This file attempts to call into ncurses without relying on Mono's
+// dllmap, so it will work with .NET Core.  This means that it needs
+// two sets of bindings, one for "ncurses" which works on OSX, and one
+// that works against "libncursesw.so.5" which is what you find on
+// assorted Linux systems.
+//
+// Additionally, I do not want to rely on an external native library
+// which is why all this pain to bind two separate ncurses is here.
+//
 // Authors:
 //   Miguel de Icaza ([email protected])
 //
@@ -33,7 +42,6 @@ using System.Runtime.InteropServices;
 namespace Unix.Terminal {
 
 	internal partial class Curses {
-
 		[StructLayout (LayoutKind.Sequential)]
 		internal struct MouseEvent {
 			public short ID;
@@ -41,38 +49,46 @@ namespace Unix.Terminal {
 			public Event ButtonState;
 		}
 
-#region Screen initialization
-
-		[DllImport ("ncurses", EntryPoint="initscr")]
-		extern static internal IntPtr real_initscr ();
 		static int lines, cols;
-
 		static Window main_window;
 		static IntPtr curses_handle, curscr_ptr, lines_ptr, cols_ptr;
 
-		static void FindNCurses ()
+		// If true, uses the DllImport into "ncurses", otherwise "libncursesw.so.5"
+		static bool use_naked_driver;
+
+		//
+		// Ugly hack to P/Invoke into either libc, or libdl, again, because
+		// we can not have nice things - .NET Core in this day and age still
+		// does not have <dllmap>
+		//
+		static IntPtr DlOpen (string path)
 		{
-			try {
-				if (File.Exists ("/usr/lib/libncurses.dylib"))
-					curses_handle = dlopen ("libncurses.dylib", 1);
-				else
-					curses_handle = dlopen ("libncurses.so", 1);
-			} catch (DllNotFoundException) {
-				uselibc = true;
-				if (File.Exists ("/usr/lib/libncurses.dylib"))
-					curses_handle = libc_dlopen ("libncurses.dylib", 1);
-				else {
-					curses_handle = libc_dlopen ("libncurses.so", 1);
-					if (curses_handle == IntPtr.Zero) {
-						Console.WriteLine ("It is not possible to open libncurses.so, you might need to symlink libncurses.so.5 to libncurses.so");
-						Environment.Exit (1);
-					}
+			if (!uselibc){
+				try {
+					var handle = dlopen (path, 1);
+					return handle;
+				} catch (DllNotFoundException){
+					uselibc = true;
+					return DlOpen (path);
 				}
+			} else {
+				return libc_dlopen (path, 1);
+			}
+		}
+		
+		static void FindNCurses ()
+		{
+			if (File.Exists ("/usr/lib/libncurses.dylib")){
+				curses_handle = DlOpen ("libncurses.dylib");
+				use_naked_driver = true;
+			} else 
+				curses_handle = DlOpen ("libncursesw.so.5");
+
+			if (curses_handle == IntPtr.Zero) {
+				Console.WriteLine ("It is not possible to open the dynamic library ncurses, tried looking for libncurses.dylib on Mac, and libncursesw.so.5 on Linux");
+				Environment.Exit (1);
 			}
 			
-			if (curses_handle == IntPtr.Zero)
-				throw new Exception ("Could not dlopen ncurses");
-
 			stdscr = read_static_ptr ("stdscr");
 			curscr_ptr = get_ptr ("curscr");
 			lines_ptr = get_ptr ("LINES");
@@ -126,6 +142,172 @@ namespace Unix.Terminal {
 			return false;
 		}
 		
+		public static int addstr (string format, params object [] args)
+		{
+			var s = string.Format (format, args);
+			return addstr (s);
+		}
+
+		static char [] r = new char [1];
+
+		//
+		// Have to wrap the native addch, as it can not
+		// display unicode characters, we have to use addstr
+		// for that.   but we need addch to render special ACS
+		// characters
+		//
+		public static int addch (int ch)
+		{
+			if (ch < 127 || ch > 0xffff )
+				return _addch (ch);
+			char c = (char) ch;
+			return addstr (new String (c, 1));
+		}
+		
+		[DllImport ("dl")]
+		extern static IntPtr dlopen (string file, int mode);
+
+		[DllImport ("dl")]
+		extern static IntPtr dlsym (IntPtr handle, string symbol);
+
+		[DllImport ("libc", EntryPoint="dlopen")]
+		extern static IntPtr libc_dlopen (string file, int mode);
+
+		[DllImport ("libc", EntryPoint ="dlsym")]
+		extern static IntPtr libc_dlsym (IntPtr handle, string symbol);
+
+		static bool uselibc;
+
+		static IntPtr stdscr;
+
+		static IntPtr get_ptr (string key)
+		{
+			var ptr = uselibc ? libc_dlsym (curses_handle, key) : dlsym (curses_handle, key);
+
+			if (ptr == IntPtr.Zero)
+				throw new Exception ("Could not load the key " + key);
+			return ptr;
+		}
+		
+		internal static IntPtr read_static_ptr (string key)
+		{
+			var ptr = get_ptr (key);
+			return Marshal.ReadIntPtr (ptr);
+		}
+
+		internal static IntPtr console_sharp_get_stdscr () => stdscr;
+		
+		
+		internal static IntPtr console_sharp_get_curscr ()
+		{
+			return Marshal.ReadIntPtr (curscr_ptr);
+		}
+
+		internal static void console_sharp_get_dims (out int lines, out int cols)
+		{
+			lines = Marshal.ReadInt32 (lines_ptr);
+			cols = Marshal.ReadInt32 (cols_ptr);
+		}
+
+		[DllImport ("ncurses", EntryPoint="mousemask")]
+		extern static IntPtr call_mousemask (IntPtr newmask, out IntPtr oldmask);
+		
+		public static Event mousemask (Event newmask, out Event oldmask)
+		{
+			IntPtr e;
+			var ret = (Event) call_mousemask ((IntPtr) newmask, out e);
+			oldmask = (Event) e;
+			return ret;
+		}
+
+
+		// We encode ESC + char (what Alt-char generates) as 0x2000 + char
+		public const int KeyAlt = 0x2000;
+
+		static public int IsAlt (int key)
+		{
+			if ((key & KeyAlt) != 0)
+				return key & ~KeyAlt;
+			return 0;
+		}
+		public static int StartColor () => start_color ();
+		public static bool HasColors => has_colors ();
+		public static int InitColorPair (short pair, short foreground, short background) => init_pair (pair, foreground, background);
+		public static int UseDefaultColors () => use_default_colors ();
+		public static int ColorPairs => COLOR_PAIRS();
+
+
+		//
+		// The proxy methods to call into each version
+		//
+		static public IntPtr real_initscr () => use_naked_driver ? RegularCurses.real_initscr () : CursesLinux.real_initscr ();
+		static public int endwin () => use_naked_driver ? RegularCurses.endwin () : CursesLinux.endwin ();
+		static public bool isendwin () => use_naked_driver ? RegularCurses.isendwin () : CursesLinux.isendwin ();
+		static public IntPtr internal_newterm (string type, IntPtr file_outfd, IntPtr file_infd) => use_naked_driver ? RegularCurses.internal_newterm (type, file_outfd, file_infd) : CursesLinux.internal_newterm (type, file_outfd, file_infd);
+		static public IntPtr internal_set_term (IntPtr newscreen) => use_naked_driver ? RegularCurses.internal_set_term (newscreen) : CursesLinux.internal_set_term (newscreen);
+		static public void internal_delscreen (IntPtr sp) { if (use_naked_driver) RegularCurses.internal_delscreen (sp); else CursesLinux.internal_delscreen (sp); }
+		static public int cbreak () => use_naked_driver ? RegularCurses.cbreak () : CursesLinux.cbreak ();
+		static public int nocbreak () => use_naked_driver ? RegularCurses.nocbreak () : CursesLinux.nocbreak ();
+		static public int echo () => use_naked_driver ? RegularCurses.echo () : CursesLinux.echo ();
+		static public int noecho () => use_naked_driver ? RegularCurses.noecho () : CursesLinux.noecho ();
+		static public int halfdelay (int t) => use_naked_driver ? RegularCurses.halfdelay (t) : CursesLinux.halfdelay (t);
+		static public int raw () => use_naked_driver ? RegularCurses.raw () : CursesLinux.raw ();
+		static public int noraw () => use_naked_driver ? RegularCurses.noraw () : CursesLinux.noraw ();
+		static public void noqiflush () { if (use_naked_driver) RegularCurses.noqiflush (); else CursesLinux.noqiflush (); }
+		static public void qiflush () { if (use_naked_driver) RegularCurses.qiflush (); else CursesLinux.qiflush (); }
+		static public int typeahead (IntPtr fd) => use_naked_driver ? RegularCurses.typeahead (fd) : CursesLinux.typeahead (fd);
+		static public int timeout (int delay) => use_naked_driver ? RegularCurses.timeout (delay) : CursesLinux.timeout (delay);
+		static public int wtimeout (IntPtr win, int delay) => use_naked_driver ? RegularCurses.wtimeout (win, delay) : CursesLinux.wtimeout (win, delay);
+		static public int notimeout (IntPtr win, bool bf) => use_naked_driver ? RegularCurses.notimeout (win, bf) : CursesLinux.notimeout (win, bf);
+		static public int keypad (IntPtr win, bool bf) => use_naked_driver ? RegularCurses.keypad (win, bf) : CursesLinux.keypad (win, bf);
+		static public int meta (IntPtr win, bool bf) => use_naked_driver ? RegularCurses.meta (win, bf) : CursesLinux.meta (win, bf);
+		static public int intrflush (IntPtr win, bool bf) => use_naked_driver ? RegularCurses.intrflush (win, bf) : CursesLinux.intrflush (win, bf);
+		static public int clearok (IntPtr win, bool bf) => use_naked_driver ? RegularCurses.clearok (win, bf) : CursesLinux.clearok (win, bf);
+		static public int idlok (IntPtr win, bool bf) => use_naked_driver ? RegularCurses.idlok (win, bf) : CursesLinux.idlok (win, bf);
+		static public void idcok (IntPtr win, bool bf) { if (use_naked_driver) RegularCurses.idcok (win, bf); else CursesLinux.idcok (win, bf);}
+		static public void immedok (IntPtr win, bool bf) { if (use_naked_driver) RegularCurses.immedok (win, bf); else CursesLinux.immedok (win, bf);}
+		static public int leaveok (IntPtr win, bool bf) => use_naked_driver ? RegularCurses.leaveok (win, bf) : CursesLinux.leaveok (win, bf);
+		static public int wsetscrreg (IntPtr win, int top, int bot) => use_naked_driver ? RegularCurses.wsetscrreg (win, top, bot) : CursesLinux.wsetscrreg (win, top, bot);
+		static public int scrollok (IntPtr win, bool bf) => use_naked_driver ? RegularCurses.scrollok (win, bf) : CursesLinux.scrollok (win, bf);
+		static public int nl() => use_naked_driver ? RegularCurses.nl() : CursesLinux.nl();
+		static public int nonl() => use_naked_driver ? RegularCurses.nonl() : CursesLinux.nonl();
+		static public int setscrreg (int top, int bot) => use_naked_driver ? RegularCurses.setscrreg (top, bot) : CursesLinux.setscrreg (top, bot);
+		static public int refresh () => use_naked_driver ? RegularCurses.refresh () : CursesLinux.refresh ();
+		static public int doupdate() => use_naked_driver ? RegularCurses.doupdate() : CursesLinux.doupdate();
+		static public int wrefresh (IntPtr win) => use_naked_driver ? RegularCurses.wrefresh (win) : CursesLinux.wrefresh (win);
+		static public int redrawwin (IntPtr win) => use_naked_driver ? RegularCurses.redrawwin (win) : CursesLinux.redrawwin (win);
+		static public int wredrawwin (IntPtr win, int beg_line, int num_lines) => use_naked_driver ? RegularCurses.wredrawwin (win, beg_line, num_lines) : CursesLinux.wredrawwin (win, beg_line, lines);
+		static public int wnoutrefresh (IntPtr win) => use_naked_driver ? RegularCurses.wnoutrefresh (win) : CursesLinux.wnoutrefresh (win);
+		static public int move (int line, int col) => use_naked_driver ? RegularCurses.move (line, col) : CursesLinux.move (line, col);
+		static public int _addch (int ch) => use_naked_driver ? RegularCurses._addch (ch) : CursesLinux._addch (ch);
+		static public int addstr (string s) => use_naked_driver ? RegularCurses.addstr (s) : CursesLinux.addstr (s);
+		static public int wmove (IntPtr win, int line, int col) => use_naked_driver ? RegularCurses.wmove (win, line, col) : CursesLinux.wmove (win, line, col);
+		static public int waddch (IntPtr win, int ch) => use_naked_driver ? RegularCurses.waddch (win, ch) : CursesLinux.waddch (win, ch);
+		static public int attron (int attrs) => use_naked_driver ? RegularCurses.attron (attrs) : CursesLinux.attron (attrs);
+		static public int attroff (int attrs) => use_naked_driver ? RegularCurses.attroff (attrs) : CursesLinux.attroff (attrs);
+		static public int attrset (int attrs) => use_naked_driver ? RegularCurses.attrset (attrs) : CursesLinux.attrset (attrs);
+		static public int getch () => use_naked_driver ? RegularCurses.getch () : CursesLinux.getch ();
+		static public int get_wch (out int sequence) => use_naked_driver ? RegularCurses.get_wch (out sequence) : CursesLinux.get_wch (out sequence);
+		static public int ungetch (int ch) => use_naked_driver ? RegularCurses.ungetch (ch) : CursesLinux.ungetch (ch);
+		static public int mvgetch (int y, int x) => use_naked_driver ? RegularCurses.mvgetch (y, x) : CursesLinux.mvgetch (y, x);
+		static public bool has_colors () => use_naked_driver ? RegularCurses.has_colors () : CursesLinux.has_colors ();
+		static public int start_color () => use_naked_driver ? RegularCurses.start_color () : CursesLinux.start_color ();
+		static public int init_pair (short pair, short f, short b) => use_naked_driver ? RegularCurses.init_pair (pair, f, b) : CursesLinux.init_pair (pair, f, b);
+		static public int use_default_colors () => use_naked_driver ? RegularCurses.use_default_colors () : CursesLinux.use_default_colors ();
+		static public int COLOR_PAIRS() => use_naked_driver ? RegularCurses.COLOR_PAIRS() : CursesLinux.COLOR_PAIRS();
+		static public uint getmouse (out MouseEvent ev) => use_naked_driver ? RegularCurses.getmouse (out ev) : CursesLinux.getmouse (out ev);
+		static public uint ungetmouse (ref MouseEvent ev) => use_naked_driver ? RegularCurses.ungetmouse (ref ev) : CursesLinux.ungetmouse (ref ev);
+		static public int mouseinterval (int interval) => use_naked_driver ? RegularCurses.mouseinterval (interval) : CursesLinux.mouseinterval (interval);
+	}
+	
+	//
+	// P/Invoke definitions for looking up symbols in the "ncurses" library, as resolved
+	// by the dynamic linker, different than CursesLinux that looksup by "libncursesw.so.5"
+	//
+	internal class RegularCurses {
+		[DllImport ("ncurses", EntryPoint="initscr")]
+		extern static internal IntPtr real_initscr ();
+
 		[DllImport ("ncurses")]
 		extern static public int endwin ();
 
@@ -144,9 +326,7 @@ namespace Unix.Terminal {
 
 		[DllImport ("ncurses")]
 	        extern static internal void internal_delscreen (IntPtr sp);
-#endregion
 
-#region Input Options
 		[DllImport ("ncurses")]
 		extern static public int cbreak ();
 		
@@ -197,9 +377,7 @@ namespace Unix.Terminal {
 		
 		[DllImport ("ncurses")]
 		extern static internal int intrflush (IntPtr win, bool bf);
-#endregion
 
-#region Output Options
 		[DllImport ("ncurses")]
 		extern internal static int clearok (IntPtr win, bool bf);
 		[DllImport ("ncurses")]
@@ -222,9 +400,6 @@ namespace Unix.Terminal {
 		[DllImport ("ncurses")]
 		extern public static int setscrreg (int top, int bot);
 		
-#endregion
-
-#region refresh functions
 
 		[DllImport ("ncurses")]
 		extern public static int refresh ();
@@ -239,9 +414,7 @@ namespace Unix.Terminal {
 		extern internal static int wredrawwin (IntPtr win, int beg_line, int num_lines);
 		[DllImport ("ncurses")]
 		extern internal static int wnoutrefresh (IntPtr win);
-#endregion
 
-#region Output
 		[DllImport ("ncurses")]
 		extern public static int move (int line, int col);
 
@@ -251,45 +424,19 @@ namespace Unix.Terminal {
 		[DllImport ("ncurses")]
 		extern public static int addstr (string s);
 
-		public static int addstr (string format, params object [] args)
-		{
-			var s = string.Format (format, args);
-			return addstr (s);
-		}
-
-		static char [] r = new char [1];
-
-		//
-		// Have to wrap the native addch, as it can not
-		// display unicode characters, we have to use addstr
-		// for that.   but we need addch to render special ACS
-		// characters
-		//
-		public static int addch (int ch)
-		{
-			if (ch < 127 || ch > 0xffff )
-				return _addch (ch);
-			char c = (char) ch;
-			return addstr (new String (c, 1));
-		}
-		
 		[DllImport ("ncurses")]
 		extern internal static int wmove (IntPtr win, int line, int col);
 
 		[DllImport ("ncurses")]
 		extern internal static int waddch (IntPtr win, int ch);
-#endregion
 
-#region Attributes
 		[DllImport ("ncurses")]
 		extern public static int attron (int attrs);
 		[DllImport ("ncurses")]
 		extern public static int attroff (int attrs);
 		[DllImport ("ncurses")]
 		extern public static int attrset (int attrs);
-#endregion
 
-#region Input
 		[DllImport ("ncurses")]
 		extern public static int getch ();
 		
@@ -301,107 +448,205 @@ namespace Unix.Terminal {
 
 		[DllImport ("ncurses")]
 		extern public static int mvgetch (int y, int x);
-#endregion
-		
-#region Colors
+
 		[DllImport ("ncurses")]
 		extern internal static bool has_colors ();
-		public static bool HasColors => has_colors ();
 
 		[DllImport ("ncurses")]
 		extern internal static int start_color ();
-		public static int StartColor () => start_color ();
 
 		[DllImport ("ncurses")]
 		extern internal static int init_pair (short pair, short f, short b);
-		public static int InitColorPair (short pair, short foreground, short background) => init_pair (pair, foreground, background);
 
 		[DllImport ("ncurses")]
 		extern internal static int use_default_colors ();
-		public static int UseDefaultColors () => use_default_colors ();
 
 		[DllImport ("ncurses")]
 		extern internal static int COLOR_PAIRS();
-		public static int ColorPairs => COLOR_PAIRS();
 		
+		[DllImport ("ncurses")]
+		public extern static uint getmouse (out Curses.MouseEvent ev);
+
+		[DllImport ("ncurses")]
+		public extern static uint ungetmouse (ref Curses.MouseEvent ev);
+
+		[DllImport ("ncurses")]
+		public extern static int mouseinterval (int interval);
 		
-#endregion
-		
-		[DllImport ("dl")]
-		extern static IntPtr dlopen (string file, int mode);
+	}
+	
+	//
+	// P/Invoke definitions for looking up symbols in the "libncursesw.so.5" library, as resolved
+	// by the dynamic linker, different than RegularCurses that looksup by "ncurses"
+	//
+	internal class CursesLinux {
+		[DllImport ("libncursesw.so.5", EntryPoint="initscr")]
+		extern static internal IntPtr real_initscr ();
 
-		[DllImport ("dl")]
-		extern static IntPtr dlsym (IntPtr handle, string symbol);
+		[DllImport ("libncursesw.so.5")]
+		extern static public int endwin ();
 
-		[DllImport ("libc", EntryPoint="dlopen")]
-		extern static IntPtr libc_dlopen (string file, int mode);
+		[DllImport ("libncursesw.so.5")]
+		extern static public bool isendwin ();
 
-		[DllImport ("libc", EntryPoint ="dlsym")]
-		extern static IntPtr libc_dlsym (IntPtr handle, string symbol);
+		//
+		// Screen operations are flagged as internal, as we need to
+		// catch all changes so we can update newscr, curscr, stdscr
+		//
+		[DllImport ("libncursesw.so.5")]
+		extern static public IntPtr internal_newterm (string type, IntPtr file_outfd, IntPtr file_infd);
 
-		static bool uselibc;
+		[DllImport ("libncursesw.so.5")]
+		extern static public IntPtr internal_set_term (IntPtr newscreen);
 
-		static IntPtr stdscr;
+		[DllImport ("libncursesw.so.5")]
+	        extern static internal void internal_delscreen (IntPtr sp);
 
-		static IntPtr get_ptr (string key)
-		{
-			var ptr = uselibc ? libc_dlsym (curses_handle, key) : dlsym (curses_handle, key);
+		[DllImport ("libncursesw.so.5")]
+		extern static public int cbreak ();
+		
+		[DllImport ("libncursesw.so.5")]
+		extern static public int nocbreak ();
+		
+		[DllImport ("libncursesw.so.5")]
+		extern static public int echo ();
+		
+		[DllImport ("libncursesw.so.5")]
+		extern static public int noecho ();
+		
+		[DllImport ("libncursesw.so.5")]
+		extern static public int halfdelay (int t);
 
-			if (ptr == IntPtr.Zero)
-				throw new Exception ("Could not load the key " + key);
-			return ptr;
-		}
+		[DllImport ("libncursesw.so.5")]
+		extern static public int raw ();
+
+		[DllImport ("libncursesw.so.5")]
+		extern static public int noraw ();
 		
-		internal static IntPtr read_static_ptr (string key)
-		{
-			var ptr = get_ptr (key);
-			return Marshal.ReadIntPtr (ptr);
-		}
+		[DllImport ("libncursesw.so.5")]
+		extern static public void noqiflush ();
+		
+		[DllImport ("libncursesw.so.5")]
+		extern static public void qiflush ();
 
-		internal static IntPtr console_sharp_get_stdscr () => stdscr;
+		[DllImport ("libncursesw.so.5")]
+		extern static public int typeahead (IntPtr fd);
+
+		[DllImport ("libncursesw.so.5")]
+		extern static public int timeout (int delay);
+
+		//
+		// Internal, as they are exposed in Window
+		//
+		[DllImport ("libncursesw.so.5")]
+		extern static internal int wtimeout (IntPtr win, int delay);
+	       
+		[DllImport ("libncursesw.so.5")]
+		extern static internal int notimeout (IntPtr win, bool bf);
+
+		[DllImport ("libncursesw.so.5")]
+		extern static internal int keypad (IntPtr win, bool bf);
 		
+		[DllImport ("libncursesw.so.5")]
+		extern static internal int meta (IntPtr win, bool bf);
 		
-#region Helpers
-		internal static IntPtr console_sharp_get_curscr ()
-		{
-			return Marshal.ReadIntPtr (curscr_ptr);
-		}
+		[DllImport ("libncursesw.so.5")]
+		extern static internal int intrflush (IntPtr win, bool bf);
 
-		internal static void console_sharp_get_dims (out int lines, out int cols)
-		{
-			lines = Marshal.ReadInt32 (lines_ptr);
-			cols = Marshal.ReadInt32 (cols_ptr);
-		}
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int clearok (IntPtr win, bool bf);
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int idlok (IntPtr win, bool bf);
+		[DllImport ("libncursesw.so.5")]
+		extern internal static void idcok (IntPtr win, bool bf);
+		[DllImport ("libncursesw.so.5")]
+		extern internal static void immedok (IntPtr win, bool bf);
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int leaveok (IntPtr win, bool bf);
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int wsetscrreg (IntPtr win, int top, int bot);
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int scrollok (IntPtr win, bool bf);
+		
+		[DllImport ("libncursesw.so.5")]
+		extern public static int nl();
+		[DllImport ("libncursesw.so.5")]
+		extern public static int nonl();
+		[DllImport ("libncursesw.so.5")]
+		extern public static int setscrreg (int top, int bot);
+		
 
-		[DllImport ("ncurses", EntryPoint="mousemask")]
-		extern static IntPtr call_mousemask (IntPtr newmask, out IntPtr oldmask);
+		[DllImport ("libncursesw.so.5")]
+		extern public static int refresh ();
+		[DllImport ("libncursesw.so.5")]
+		extern public static int doupdate();
+
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int wrefresh (IntPtr win);
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int redrawwin (IntPtr win);
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int wredrawwin (IntPtr win, int beg_line, int num_lines);
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int wnoutrefresh (IntPtr win);
+
+		[DllImport ("libncursesw.so.5")]
+		extern public static int move (int line, int col);
+
+		[DllImport ("libncursesw.so.5", EntryPoint="addch")]
+		extern internal static int _addch (int ch);
 		
-		public static Event mousemask (Event newmask, out Event oldmask)
-		{
-			IntPtr e;
-			var ret = (Event) call_mousemask ((IntPtr) newmask, out e);
-			oldmask = (Event) e;
-			return ret;
-		}
+		[DllImport ("libncursesw.so.5")]
+		extern public static int addstr (string s);
 
-		[DllImport ("ncurses")]
-		public extern static uint getmouse (out MouseEvent ev);
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int wmove (IntPtr win, int line, int col);
 
-		[DllImport ("ncurses")]
-		public extern static uint ungetmouse (ref MouseEvent ev);
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int waddch (IntPtr win, int ch);
 
-		[DllImport ("ncurses")]
-		public extern static int mouseinterval (int interval);
-#endregion
+		[DllImport ("libncursesw.so.5")]
+		extern public static int attron (int attrs);
+		[DllImport ("libncursesw.so.5")]
+		extern public static int attroff (int attrs);
+		[DllImport ("libncursesw.so.5")]
+		extern public static int attrset (int attrs);
 
-		// We encode ESC + char (what Alt-char generates) as 0x2000 + char
-		public const int KeyAlt = 0x2000;
+		[DllImport ("libncursesw.so.5")]
+		extern public static int getch ();
+		
+		[DllImport ("libncursesw.so.5")]
+		extern public static int get_wch (out int sequence);
 
-		static public int IsAlt (int key)
-		{
-			if ((key & KeyAlt) != 0)
-				return key & ~KeyAlt;
-			return 0;
-		}
+		[DllImport ("libncursesw.so.5")]
+		extern public static int ungetch (int ch);
+
+		[DllImport ("libncursesw.so.5")]
+		extern public static int mvgetch (int y, int x);
+
+		[DllImport ("libncursesw.so.5")]
+		extern internal static bool has_colors ();
+
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int start_color ();
+
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int init_pair (short pair, short f, short b);
+
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int use_default_colors ();
+
+		[DllImport ("libncursesw.so.5")]
+		extern internal static int COLOR_PAIRS();
+		
+		[DllImport ("libncursesw.so.5")]
+		public extern static uint getmouse (out Curses.MouseEvent ev);
+
+		[DllImport ("libncursesw.so.5")]
+		public extern static uint ungetmouse (ref Curses.MouseEvent ev);
+
+		[DllImport ("libncursesw.so.5")]
+		public extern static int mouseinterval (int interval);
 	}
+	
 }