From 27c5468a105fbf301dc6a160af21a29afa08034e Mon Sep 17 00:00:00 2001 From: miguel Date: Tue, 18 Sep 2018 22:45:20 -0400 Subject: [PATCH 1/4] Dynamic library loader work --- Terminal.Gui/Drivers/ConsoleDriver.cs | 1 + Terminal.Gui/MonoCurses/UnmanagedLibrary.cs | 262 ++++++++++++++++++++ Terminal.Gui/MonoCurses/binding.cs | 121 +++++++++ Terminal.Gui/Terminal.Gui.csproj | 4 + 4 files changed, 388 insertions(+) create mode 100644 Terminal.Gui/MonoCurses/UnmanagedLibrary.cs diff --git a/Terminal.Gui/Drivers/ConsoleDriver.cs b/Terminal.Gui/Drivers/ConsoleDriver.cs index c7c36f2ab..85cfddad8 100644 --- a/Terminal.Gui/Drivers/ConsoleDriver.cs +++ b/Terminal.Gui/Drivers/ConsoleDriver.cs @@ -141,6 +141,7 @@ namespace Terminal.Gui { /// The base color scheme, for the default toplevel views. /// public static ColorScheme Base; + /// /// The dialog color scheme, for standard popup dialog boxes /// diff --git a/Terminal.Gui/MonoCurses/UnmanagedLibrary.cs b/Terminal.Gui/MonoCurses/UnmanagedLibrary.cs new file mode 100644 index 000000000..b3158c813 --- /dev/null +++ b/Terminal.Gui/MonoCurses/UnmanagedLibrary.cs @@ -0,0 +1,262 @@ + + +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#define GUICS + +using System; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading; + + + +namespace Mono.Terminal.Internal { + /// + /// Represents a dynamically loaded unmanaged library in a (partially) platform independent manner. + /// First, the native library is loaded using dlopen (on Unix systems) or using LoadLibrary (on Windows). + /// dlsym or GetProcAddress are then used to obtain symbol addresses. Marshal.GetDelegateForFunctionPointer + /// transforms the addresses into delegates to native methods. + /// See http://stackoverflow.com/questions/13461989/p-invoke-to-dynamically-loaded-library-on-mono. + /// + internal class UnmanagedLibrary { + const string UnityEngineApplicationClassName = "UnityEngine.Application, UnityEngine"; + const string XamarinAndroidObjectClassName = "Java.Lang.Object, Mono.Android"; + const string XamarinIOSObjectClassName = "Foundation.NSObject, Xamarin.iOS"; + static bool IsWindows, IsLinux, IsMacOS; + static bool Is64Bit; + static bool IsMono, IsUnity, IsXamarinIOS, IsXamarinAndroid, IsXamarin; + static bool IsNetCore; + + public static bool IsMacOSPlatform => IsMacOS; + + [DllImport ("libc")] + static extern int uname (IntPtr buf); + + static string GetUname () + { + var buffer = Marshal.AllocHGlobal (8192); + try { + if (uname (buffer) == 0) { + return Marshal.PtrToStringAnsi (buffer); + } + return string.Empty; + } catch { + return string.Empty; + } finally { + if (buffer != IntPtr.Zero) { + Marshal.FreeHGlobal (buffer); + } + } + } + + static UnmanagedLibrary () + { + var platform = Environment.OSVersion.Platform; + + IsMacOS = (platform == PlatformID.Unix && GetUname () == "Darwin"); + IsLinux = (platform == PlatformID.Unix && !IsMacOS); + IsWindows = (platform == PlatformID.Win32NT || platform == PlatformID.Win32S || platform == PlatformID.Win32Windows); + Is64Bit = Marshal.SizeOf (typeof (IntPtr)) == 8; + IsMono = Type.GetType ("Mono.Runtime") != null; + if (!IsMono) { + IsNetCore = Type.GetType ("System.MathF") != null; + } +#if GUICS + IsUnity = IsXamarinIOS = IsXamarinAndroid = IsXamarin = false; +#else + IsUnity = Type.GetType (UnityEngineApplicationClassName) != null; + IsXamarinIOS = Type.GetType (XamarinIOSObjectClassName) != null; + IsXamarinAndroid = Type.GetType (XamarinAndroidObjectClassName) != null; + IsXamarin = IsXamarinIOS || IsXamarinAndroid; +#endif + + } + + // flags for dlopen + const int RTLD_LAZY = 1; + const int RTLD_GLOBAL = 8; + + readonly string libraryPath; + readonly IntPtr handle; + + // + // if isFullPath is set to true, the provided array of libraries are full paths + // and are tested for the file existing, otherwise the file is merely the name + // of the shared library that we pass to dlopen + // + public UnmanagedLibrary (string [] libraryPathAlternatives, bool isFullPath) + { + if (isFullPath){ + this.libraryPath = FirstValidLibraryPath (libraryPathAlternatives); + this.handle = PlatformSpecificLoadLibrary (this.libraryPath); + } else { + foreach (var lib in libraryPathAlternatives){ + this.handle = PlatformSpecificLoadLibrary (lib); + if (this.handle != IntPtr.Zero) + break; + } + } + + if (this.handle == IntPtr.Zero) { + throw new IOException (string.Format ("Error loading native library \"{0}\"", this.libraryPath)); + } + } + + /// + /// Loads symbol in a platform specific way. + /// + /// + /// + private IntPtr LoadSymbol (string symbolName) + {s + if (IsWindows) { + // See http://stackoverflow.com/questions/10473310 for background on this. + if (Is64Bit) { + return Windows.GetProcAddress (this.handle, symbolName); + } else { + // Yes, we could potentially predict the size... but it's a lot simpler to just try + // all the candidates. Most functions have a suffix of @0, @4 or @8 so we won't be trying + // many options - and if it takes a little bit longer to fail if we've really got the wrong + // library, that's not a big problem. This is only called once per function in the native library. + symbolName = "_" + symbolName + "@"; + for (int stackSize = 0; stackSize < 128; stackSize += 4) { + IntPtr candidate = Windows.GetProcAddress (this.handle, symbolName + stackSize); + if (candidate != IntPtr.Zero) { + return candidate; + } + } + // Fail. + return IntPtr.Zero; + } + } + if (IsLinux) { + if (IsMono) { + return Mono.dlsym (this.handle, symbolName); + } + if (IsNetCore) { + return CoreCLR.dlsym (this.handle, symbolName); + } + return Linux.dlsym (this.handle, symbolName); + } + if (IsMacOS) { + return MacOSX.dlsym (this.handle, symbolName); + } + throw new InvalidOperationException ("Unsupported platform."); + } + + public T GetNativeMethodDelegate (string methodName) + where T : class + { + var ptr = LoadSymbol (methodName); + if (ptr == IntPtr.Zero) { + throw new MissingMethodException (string.Format ("The native method \"{0}\" does not exist", methodName)); + } + return Marshal.GetDelegateForFunctionPointer(ptr); // non-generic version is obsolete + } + + /// + /// Loads library in a platform specific way. + /// + private static IntPtr PlatformSpecificLoadLibrary (string libraryPath) + { + if (IsWindows) { + return Windows.LoadLibrary (libraryPath); + } + if (IsLinux) { + if (IsMono) { + return Mono.dlopen (libraryPath, RTLD_GLOBAL + RTLD_LAZY); + } + if (IsNetCore) { + return CoreCLR.dlopen (libraryPath, RTLD_GLOBAL + RTLD_LAZY); + } + return Linux.dlopen (libraryPath, RTLD_GLOBAL + RTLD_LAZY); + } + if (IsMacOS) { + return MacOSX.dlopen (libraryPath, RTLD_GLOBAL + RTLD_LAZY); + } + throw new InvalidOperationException ("Unsupported platform."); + } + + private static string FirstValidLibraryPath (string [] libraryPathAlternatives) + { + foreach (var path in libraryPathAlternatives) { + if (File.Exists (path)) { + return path; + } + } + throw new FileNotFoundException ( + String.Format ("Error loading native library. Not found in any of the possible locations: {0}", + string.Join (",", libraryPathAlternatives))); + } + + private static class Windows + { + [DllImport ("kernel32.dll")] + internal static extern IntPtr LoadLibrary (string filename); + + [DllImport ("kernel32.dll")] + internal static extern IntPtr GetProcAddress (IntPtr hModule, string procName); + } + + private static class Linux + { + [DllImport ("libdl.so")] + internal static extern IntPtr dlopen (string filename, int flags); + + [DllImport ("libdl.so")] + internal static extern IntPtr dlsym (IntPtr handle, string symbol); + } + + private static class MacOSX + { + [DllImport ("libSystem.dylib")] + internal static extern IntPtr dlopen (string filename, int flags); + + [DllImport ("libSystem.dylib")] + internal static extern IntPtr dlsym (IntPtr handle, string symbol); + } + + /// + /// On Linux systems, using using dlopen and dlsym results in + /// DllNotFoundException("libdl.so not found") if libc6-dev + /// is not installed. As a workaround, we load symbols for + /// dlopen and dlsym from the current process as on Linux + /// Mono sure is linked against these symbols. + /// + private static class Mono + { + [DllImport ("__Internal")] + internal static extern IntPtr dlopen (string filename, int flags); + + [DllImport ("__Internal")] + internal static extern IntPtr dlsym (IntPtr handle, string symbol); + } + + /// + /// Similarly as for Mono on Linux, we load symbols for + /// dlopen and dlsym from the "libcoreclr.so", + /// to avoid the dependency on libc-dev Linux. + /// + private static class CoreCLR + { + [DllImport ("libcoreclr.so")] + internal static extern IntPtr dlopen (string filename, int flags); + + [DllImport ("libcoreclr.so")] + internal static extern IntPtr dlsym (IntPtr handle, string symbol); + } + } +} diff --git a/Terminal.Gui/MonoCurses/binding.cs b/Terminal.Gui/MonoCurses/binding.cs index b238cc6eb..7c4c4a7f2 100644 --- a/Terminal.Gui/MonoCurses/binding.cs +++ b/Terminal.Gui/MonoCurses/binding.cs @@ -40,6 +40,121 @@ using System.IO; using System.Runtime.InteropServices; namespace Unix.Terminal { + internal class Delegates { + public delegate IntPtr initscr (); + public delegate int endwin (); + public delegate bool isendwin (); + public delegate int cbreak (); + public delegate int nocbreak (); + public delegate int echo (); + public delegate int noecho (); + public delegate int halfdelay (int t); + public delegate int raw (); + public delegate int noraw (); + public delegate void noqiflush (); + public delegate void qiflush (); + public delegate int typeahead (IntPtr fd); + public delegate int timeout (int delay); + public delegate int wtimeout (IntPtr win, int delay); + public delegate int notimeout (IntPtr win, bool bf); + public delegate int keypad (IntPtr win, bool bf); + public delegate int meta (IntPtr win, bool bf); + public delegate int intrflush (IntPtr win, bool bf); + public delegate int clearok (IntPtr win, bool bf); + public delegate int idlok (IntPtr win, bool bf); + public delegate void idcok (IntPtr win, bool bf); + public delegate void immedok (IntPtr win, bool bf); + public delegate int leaveok (IntPtr win, bool bf); + public delegate int wsetscrreg (IntPtr win, int top, int bot); + public delegate int scrollok (IntPtr win, bool bf); + public delegate int nl(); + public delegate int nonl(); + public delegate int setscrreg (int top, int bot); + public delegate int refresh (); + public delegate int doupdate(); + public delegate int wrefresh (IntPtr win); + public delegate int redrawwin (IntPtr win); + public delegate int wredrawwin (IntPtr win, int beg_line, int num_lines); + public delegate int wnoutrefresh (IntPtr win); + public delegate int move (int line, int col); + public delegate int addch (int ch); + public delegate int addstr (string s); + public delegate int wmove (IntPtr win, int line, int col); + public delegate int waddch (IntPtr win, int ch); + public delegate int attron (int attrs); + public delegate int attroff (int attrs); + public delegate int attrset (int attrs); + public delegate int getch (); + public delegate int get_wch (out int sequence); + public delegate int ungetch (int ch); + public delegate int mvgetch (int y, int x); + public delegate bool has_colors (); + public delegate int start_color (); + public delegate int init_pair (short pair, short f, short b); + public delegate int use_default_colors (); + public delegate int COLOR_PAIRS(); + public delegate uint getmouse (out MouseEvent ev); + public delegate uint ungetmouse (ref MouseEvent ev); + public delegate int mouseinterval (int interval); + } + + internal class NativeMethods { + public readonly Delegates.initscr initscr; + public readonly Delegates.endwin endwin; + public readonly Delegates.isendwin isendwin; + public readonly Delegates.cbreak cbreak; + public readonly Delegates.nocbreak nocbreak; + public readonly Delegates.echo echo; + public readonly Delegates.noecho noecho; + public readonly Delegates.halfdelay halfdelay; + public readonly Delegates.raw raw; + public readonly Delegates.noraw noraw; + public readonly Delegates.noqiflush noqiflush; + public readonly Delegates.qiflush qiflush; + public readonly Delegates.typeahead typeahead; + public readonly Delegates.timeout timeout; + public readonly Delegates.wtimeout wtimeout; + public readonly Delegates.notimeout notimeout; + public readonly Delegates.keypad keypad; + public readonly Delegates.meta meta; + public readonly Delegates.intrflush intrflush; + public readonly Delegates.clearok clearok; + public readonly Delegates.idlok idlok; + public readonly Delegates.idcok idcok; + public readonly Delegates.immedok immedok; + public readonly Delegates.leaveok leaveok; + public readonly Delegates.wsetscrreg wsetscrreg; + public readonly Delegates.scrollok scrollok; + public readonly Delegates.nl nl; + public readonly Delegates.nonl nonl; + public readonly Delegates.setscrreg setscrreg; + public readonly Delegates.refresh refresh; + public readonly Delegates.doupdate doupdate; + public readonly Delegates.wrefresh wrefresh; + public readonly Delegates.redrawwin redrawwin; + public readonly Delegates.wredrawwin wredrawwin; + public readonly Delegates.wnoutrefresh wnoutrefresh; + public readonly Delegates.move move; + public readonly Delegates.addch addch; + public readonly Delegates.addstr addstr; + public readonly Delegates.wmove wmove; + public readonly Delegates.waddch waddch; + public readonly Delegates.attron attron; + public readonly Delegates.attroff attroff; + public readonly Delegates.attrset attrset; + public readonly Delegates.getch getch; + public readonly Delegates.get_wch get_wch; + public readonly Delegates.ungetch ungetch; + public readonly Delegates.mvgetch mvgetch; + public readonly Delegates.has_colors has_colors; + public readonly Delegates.start_color start_color; + public readonly Delegates.init_pair init_pair; + public readonly Delegates.use_default_colors use_default_colors; + public readonly Delegates.COLOR_PAIR COLOR_PAIR; + public readonly Delegates.getmouse getmouse; + public readonly Delegates.ungetmouse ungetmouse; + public readonly Delegates.mouseinterval mouseinterval; + } internal partial class Curses { [StructLayout (LayoutKind.Sequential)] @@ -56,6 +171,12 @@ namespace Unix.Terminal { // If true, uses the DllImport into "ncurses", otherwise "libncursesw.so.5" static bool use_naked_driver; + static void LoadMethods () + { + var libs = UnmanagedLibrary.IsMacOSPlatform ? new string [] { "libncurses.dylib" } : new string { "libncursesw.so.6", "libncursesw.so.5" }; + var lib = new UnmanagedLibrary (libs); + } + // // 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 diff --git a/Terminal.Gui/Terminal.Gui.csproj b/Terminal.Gui/Terminal.Gui.csproj index d215faaa5..ec1e6131d 100644 --- a/Terminal.Gui/Terminal.Gui.csproj +++ b/Terminal.Gui/Terminal.Gui.csproj @@ -6,6 +6,7 @@ full bin\Release\Terminal.Gui.xml true + net47 true @@ -64,4 +65,7 @@ ..\..\..\Users\miguel\.nuget\packages\nstack.core\0.11.0\lib\netstandard1.5\NStack.dll + + + From 4a17f5cd5d28b57cf1eb71302ce60afed434baa6 Mon Sep 17 00:00:00 2001 From: miguel Date: Tue, 18 Sep 2018 22:56:02 -0400 Subject: [PATCH 2/4] Use nativemethods --- Terminal.Gui/MonoCurses/binding.cs | 196 +++++++++++++++++++---------- 1 file changed, 130 insertions(+), 66 deletions(-) diff --git a/Terminal.Gui/MonoCurses/binding.cs b/Terminal.Gui/MonoCurses/binding.cs index 7c4c4a7f2..3791a2bd1 100644 --- a/Terminal.Gui/MonoCurses/binding.cs +++ b/Terminal.Gui/MonoCurses/binding.cs @@ -1,4 +1,10 @@ - +// +// TODO: +// * FindNCurses needs to remove the old probing code +// * Removal of that proxy code +// * Need to implement reading pointers with the new API +// * Can remove the manual Dlopen features +// * initscr() diagnostics based on DLL can be fixed // // binding.cs.in: Core binding for curses. // @@ -154,6 +160,65 @@ namespace Unix.Terminal { public readonly Delegates.getmouse getmouse; public readonly Delegates.ungetmouse ungetmouse; public readonly Delegates.mouseinterval mouseinterval; + + public void NativeMethods (UnmanagedLibrary lib) + { + initscr = lib.GetMethodDelegate ("initscr"); + endwin = lib.GetMethodDelegate ("endwin"); + isendwin = lib.GetMethodDelegate ("isendwin"); + cbreak = lib.GetMethodDelegate ("cbreak"); + nocbreak = lib.GetMethodDelegate ("nocbreak"); + echo = lib.GetMethodDelegate ("echo"); + noecho = lib.GetMethodDelegate ("noecho"); + halfdelay = lib.GetMethodDelegate ("halfdelay"); + raw = lib.GetMethodDelegate ("raw"); + noraw = lib.GetMethodDelegate ("noraw"); + noqiflush = lib.GetMethodDelegate ("noqiflush"); + qiflush = lib.GetMethodDelegate ("qiflush"); + typeahead = lib.GetMethodDelegate ("typeahead"); + timeout = lib.GetMethodDelegate ("timeout"); + wtimeout = lib.GetMethodDelegate ("wtimeout"); + notimeout = lib.GetMethodDelegate ("notimeout"); + keypad = lib.GetMethodDelegate ("keypad"); + meta = lib.GetMethodDelegate ("meta"); + intrflush = lib.GetMethodDelegate ("intrflush"); + clearok = lib.GetMethodDelegate ("clearok"); + idlok = lib.GetMethodDelegate ("idlok"); + idcok = lib.GetMethodDelegate ("idcok"); + immedok = lib.GetMethodDelegate ("immedok"); + leaveok = lib.GetMethodDelegate ("leaveok"); + wsetscrreg = lib.GetMethodDelegate ("wsetscrreg"); + scrollok = lib.GetMethodDelegate ("scrollok"); + nl = lib.GetMethodDelegate ("nl"); + nonl = lib.GetMethodDelegate ("nonl"); + setscrreg = lib.GetMethodDelegate ("setscrreg"); + refresh = lib.GetMethodDelegate ("refresh"); + doupdate = lib.GetMethodDelegate ("doupdate"); + wrefresh = lib.GetMethodDelegate ("wrefresh"); + redrawwin = lib.GetMethodDelegate ("redrawwin"); + wredrawwin = lib.GetMethodDelegate ("wredrawwin"); + wnoutrefresh = lib.GetMethodDelegate ("wnoutrefresh"); + move = lib.GetMethodDelegate ("move"); + addch = lib.GetMethodDelegate ("addch"); + addstr = lib.GetMethodDelegate ("addstr"); + wmove = lib.GetMethodDelegate ("wmove"); + waddch = lib.GetMethodDelegate ("waddch"); + attron = lib.GetMethodDelegate ("attron"); + attroff = lib.GetMethodDelegate ("attroff"); + attrset = lib.GetMethodDelegate ("attrset"); + getch = lib.GetMethodDelegate ("getch"); + get_wch = lib.GetMethodDelegate ("get_wch"); + ungetch = lib.GetMethodDelegate ("ungetch"); + mvgetch = lib.GetMethodDelegate ("mvgetch"); + has_colors = lib.GetMethodDelegate ("has_colors"); + start_color = lib.GetMethodDelegate ("start_color"); + init_pair = lib.GetMethodDelegate ("init_pair"); + use_default_colors = lib.GetMethodDelegate ("use_default_colors"); + COLOR_PAIR = lib.GetMethodDelegate ("COLOR_PAIR"); + getmouse = lib.GetMethodDelegate ("getmouse"); + ungetmouse = lib.GetMethodDelegate ("ungetmouse"); + mouseinterval = lib.GetMethodDelegate ("mouseinterval"); + } } internal partial class Curses { @@ -171,10 +236,13 @@ namespace Unix.Terminal { // If true, uses the DllImport into "ncurses", otherwise "libncursesw.so.5" static bool use_naked_driver; + NativeMethods methods; + static void LoadMethods () { var libs = UnmanagedLibrary.IsMacOSPlatform ? new string [] { "libncurses.dylib" } : new string { "libncursesw.so.6", "libncursesw.so.5" }; var lib = new UnmanagedLibrary (libs); + methods = new NativeMethods (lib); } // @@ -220,9 +288,9 @@ namespace Unix.Terminal { { FindNCurses (); - main_window = new Window (real_initscr ()); + main_window = new Window (methods.initscr ()); try { - console_sharp_get_dims (out lines, out cols); + console_sharp_get_dims (out lines, out bcols); } catch (DllNotFoundException){ endwin (); Console.Error.WriteLine ("Unable to find the @MONO_CURSES@ native library\n" + @@ -333,7 +401,7 @@ namespace Unix.Terminal { public static Event mousemask (Event newmask, out Event oldmask) { IntPtr e; - var ret = (Event) (use_naked_driver ? RegularCurses.call_mousemask ((IntPtr) newmask, out e) : CursesLinux.call_mousemask ((IntPtr) newmask, out e)); + var ret = (Event) (methods.call_mousemask ((IntPtr) newmask, out e)); oldmask = (Event) e; return ret; } @@ -348,74 +416,70 @@ namespace Unix.Terminal { 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(); - + public static int StartColor () => methods.start_color (); + public static bool HasColors => methods.has_colors (); + public static int InitColorPair (short pair, short foreground, short background) => methods.init_pair (pair, foreground, background); + public static int UseDefaultColors () => methods.use_default_colors (); + public static int ColorPairs => methods.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 IntPtr real_initscr () => methods.real_initscr (); + static public int endwin () => methods.endwin (); + static public bool isendwin () => methods.isendwin (); + static public int cbreak () => methods.cbreak (); + static public int nocbreak () => methods.nocbreak (); + static public int echo () => methods.echo (); + static public int noecho () => methods.noecho (); + static public int halfdelay (int t) => methods.halfdelay (t); + static public int raw () => methods.raw (); + static public int noraw () => methods.noraw (); + static public void noqiflush () => { methods.noqiflush (); }; + static public void qiflush () => { methods.qiflush (); }; + static public int typeahead (IntPtr fd) => methods.typeahead (fd); + static public int timeout (int delay) => methods.timeout (delay); + static public int wtimeout (IntPtr win, int delay) => methods.wtimeout (win, delay); + static public int notimeout (IntPtr win, bool bf) => methods.notimeout (win, bf); + static public int keypad (IntPtr win, bool bf) => methods.keypad (win, bf); + static public int meta (IntPtr win, bool bf) => methods.meta (win, bf); + static public int intrflush (IntPtr win, bool bf) => methods.intrflush (win, bf); + static public int clearok (IntPtr win, bool bf) => methods.clearok (win, bf); + static public int idlok (IntPtr win, bool bf) => methods.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); + static public int leaveok (IntPtr win, bool bf) => methods.leaveok (win, bf); + static public int wsetscrreg (IntPtr win, int top, int bot) => methods.wsetscrreg (win, top, bot); + static public int scrollok (IntPtr win, bool bf) => methods.scrollok (win, bf); + static public int nl() => methods.nl(); + static public int nonl() => methods.nonl(); + static public int setscrreg (int top, int bot) => methods.setscrreg (top, bot); + static public int refresh () => methods.refresh (); + static public int doupdate() => methods.doupdate(); + static public int wrefresh (IntPtr win) => methods.wrefresh (win); + static public int redrawwin (IntPtr win) => methods.redrawwin (win); + static public int wredrawwin (IntPtr win, int beg_line, int num_lines) => methods.wredrawwin (win, beg_line, num_lines); + static public int wnoutrefresh (IntPtr win) => methods.wnoutrefresh (win); + static public int move (int line, int col) => methods.move (line, col); + static public int _addch (int ch) => methods._addch (ch); + static public int addstr (string s) => methods.addstr (s); + static public int wmove (IntPtr win, int line, int col) => methods.wmove (win, line, col); + static public int waddch (IntPtr win, int ch) => methods.waddch (win, ch); + static public int attron (int attrs) => methods.attron (attrs); + static public int attroff (int attrs) => methods.attroff (attrs); + static public int attrset (int attrs) => methods.attrset (attrs); + static public int getch () => methods.getch (); + static public int get_wch (out int sequence) => methods.get_wch (out sequence); + static public int ungetch (int ch) => methods.ungetch (ch); + static public int mvgetch (int y, int x) => methods.mvgetch (y, x); + static public bool has_colors () => methods.has_colors (); + static public int start_color () => methods.start_color (); + static public int init_pair (short pair, short f, short b) => methods.init_pair (pair, f, b); + static public int use_default_colors () => methods.use_default_colors (); + static public int COLOR_PAIRS() => methods.COLOR_PAIRS(); + static public uint getmouse (out MouseEvent ev) => methods.getmouse (out ev); + static public uint ungetmouse (ref MouseEvent ev) => methods.ungetmouse (ref ev); + static public int mouseinterval (int interval) => methods.mouseinterval (interval); } // From 1c7faba15df424cce085cb18344c1717cdad57ce Mon Sep 17 00:00:00 2001 From: miguel Date: Fri, 21 Sep 2018 23:50:32 -0400 Subject: [PATCH 3/4] Make this work --- Example/demo.cs | 3 +- Terminal.Gui/MonoCurses/UnmanagedLibrary.cs | 6 +- Terminal.Gui/MonoCurses/binding.cs | 779 +++++--------------- Terminal.Gui/MonoCurses/handles.cs | 45 +- 4 files changed, 223 insertions(+), 610 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index 3d5405c43..1d127b979 100755 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -291,7 +291,8 @@ static class Demo { ml.Text = $"Mouse: ({me.X},{me.Y}) - {me.Flags} {count++}"; }; - + var test = new Label (3, 18, "Se iniciarĂ¡ el anĂ¡lisis"); + win.Add (test); win.Add (ml); // ShowTextAlignments (win); diff --git a/Terminal.Gui/MonoCurses/UnmanagedLibrary.cs b/Terminal.Gui/MonoCurses/UnmanagedLibrary.cs index b3158c813..1fce883e9 100644 --- a/Terminal.Gui/MonoCurses/UnmanagedLibrary.cs +++ b/Terminal.Gui/MonoCurses/UnmanagedLibrary.cs @@ -92,6 +92,8 @@ namespace Mono.Terminal.Internal { readonly string libraryPath; readonly IntPtr handle; + public IntPtr NativeLibraryHandle => handle; + // // if isFullPath is set to true, the provided array of libraries are full paths // and are tested for the file existing, otherwise the file is merely the name @@ -120,8 +122,8 @@ namespace Mono.Terminal.Internal { /// /// /// - private IntPtr LoadSymbol (string symbolName) - {s + public IntPtr LoadSymbol (string symbolName) + { if (IsWindows) { // See http://stackoverflow.com/questions/10473310 for background on this. if (Is64Bit) { diff --git a/Terminal.Gui/MonoCurses/binding.cs b/Terminal.Gui/MonoCurses/binding.cs index 3791a2bd1..d8224e802 100644 --- a/Terminal.Gui/MonoCurses/binding.cs +++ b/Terminal.Gui/MonoCurses/binding.cs @@ -44,182 +44,9 @@ using System; using System.IO; using System.Runtime.InteropServices; +using Mono.Terminal.Internal; namespace Unix.Terminal { - internal class Delegates { - public delegate IntPtr initscr (); - public delegate int endwin (); - public delegate bool isendwin (); - public delegate int cbreak (); - public delegate int nocbreak (); - public delegate int echo (); - public delegate int noecho (); - public delegate int halfdelay (int t); - public delegate int raw (); - public delegate int noraw (); - public delegate void noqiflush (); - public delegate void qiflush (); - public delegate int typeahead (IntPtr fd); - public delegate int timeout (int delay); - public delegate int wtimeout (IntPtr win, int delay); - public delegate int notimeout (IntPtr win, bool bf); - public delegate int keypad (IntPtr win, bool bf); - public delegate int meta (IntPtr win, bool bf); - public delegate int intrflush (IntPtr win, bool bf); - public delegate int clearok (IntPtr win, bool bf); - public delegate int idlok (IntPtr win, bool bf); - public delegate void idcok (IntPtr win, bool bf); - public delegate void immedok (IntPtr win, bool bf); - public delegate int leaveok (IntPtr win, bool bf); - public delegate int wsetscrreg (IntPtr win, int top, int bot); - public delegate int scrollok (IntPtr win, bool bf); - public delegate int nl(); - public delegate int nonl(); - public delegate int setscrreg (int top, int bot); - public delegate int refresh (); - public delegate int doupdate(); - public delegate int wrefresh (IntPtr win); - public delegate int redrawwin (IntPtr win); - public delegate int wredrawwin (IntPtr win, int beg_line, int num_lines); - public delegate int wnoutrefresh (IntPtr win); - public delegate int move (int line, int col); - public delegate int addch (int ch); - public delegate int addstr (string s); - public delegate int wmove (IntPtr win, int line, int col); - public delegate int waddch (IntPtr win, int ch); - public delegate int attron (int attrs); - public delegate int attroff (int attrs); - public delegate int attrset (int attrs); - public delegate int getch (); - public delegate int get_wch (out int sequence); - public delegate int ungetch (int ch); - public delegate int mvgetch (int y, int x); - public delegate bool has_colors (); - public delegate int start_color (); - public delegate int init_pair (short pair, short f, short b); - public delegate int use_default_colors (); - public delegate int COLOR_PAIRS(); - public delegate uint getmouse (out MouseEvent ev); - public delegate uint ungetmouse (ref MouseEvent ev); - public delegate int mouseinterval (int interval); - } - - internal class NativeMethods { - public readonly Delegates.initscr initscr; - public readonly Delegates.endwin endwin; - public readonly Delegates.isendwin isendwin; - public readonly Delegates.cbreak cbreak; - public readonly Delegates.nocbreak nocbreak; - public readonly Delegates.echo echo; - public readonly Delegates.noecho noecho; - public readonly Delegates.halfdelay halfdelay; - public readonly Delegates.raw raw; - public readonly Delegates.noraw noraw; - public readonly Delegates.noqiflush noqiflush; - public readonly Delegates.qiflush qiflush; - public readonly Delegates.typeahead typeahead; - public readonly Delegates.timeout timeout; - public readonly Delegates.wtimeout wtimeout; - public readonly Delegates.notimeout notimeout; - public readonly Delegates.keypad keypad; - public readonly Delegates.meta meta; - public readonly Delegates.intrflush intrflush; - public readonly Delegates.clearok clearok; - public readonly Delegates.idlok idlok; - public readonly Delegates.idcok idcok; - public readonly Delegates.immedok immedok; - public readonly Delegates.leaveok leaveok; - public readonly Delegates.wsetscrreg wsetscrreg; - public readonly Delegates.scrollok scrollok; - public readonly Delegates.nl nl; - public readonly Delegates.nonl nonl; - public readonly Delegates.setscrreg setscrreg; - public readonly Delegates.refresh refresh; - public readonly Delegates.doupdate doupdate; - public readonly Delegates.wrefresh wrefresh; - public readonly Delegates.redrawwin redrawwin; - public readonly Delegates.wredrawwin wredrawwin; - public readonly Delegates.wnoutrefresh wnoutrefresh; - public readonly Delegates.move move; - public readonly Delegates.addch addch; - public readonly Delegates.addstr addstr; - public readonly Delegates.wmove wmove; - public readonly Delegates.waddch waddch; - public readonly Delegates.attron attron; - public readonly Delegates.attroff attroff; - public readonly Delegates.attrset attrset; - public readonly Delegates.getch getch; - public readonly Delegates.get_wch get_wch; - public readonly Delegates.ungetch ungetch; - public readonly Delegates.mvgetch mvgetch; - public readonly Delegates.has_colors has_colors; - public readonly Delegates.start_color start_color; - public readonly Delegates.init_pair init_pair; - public readonly Delegates.use_default_colors use_default_colors; - public readonly Delegates.COLOR_PAIR COLOR_PAIR; - public readonly Delegates.getmouse getmouse; - public readonly Delegates.ungetmouse ungetmouse; - public readonly Delegates.mouseinterval mouseinterval; - - public void NativeMethods (UnmanagedLibrary lib) - { - initscr = lib.GetMethodDelegate ("initscr"); - endwin = lib.GetMethodDelegate ("endwin"); - isendwin = lib.GetMethodDelegate ("isendwin"); - cbreak = lib.GetMethodDelegate ("cbreak"); - nocbreak = lib.GetMethodDelegate ("nocbreak"); - echo = lib.GetMethodDelegate ("echo"); - noecho = lib.GetMethodDelegate ("noecho"); - halfdelay = lib.GetMethodDelegate ("halfdelay"); - raw = lib.GetMethodDelegate ("raw"); - noraw = lib.GetMethodDelegate ("noraw"); - noqiflush = lib.GetMethodDelegate ("noqiflush"); - qiflush = lib.GetMethodDelegate ("qiflush"); - typeahead = lib.GetMethodDelegate ("typeahead"); - timeout = lib.GetMethodDelegate ("timeout"); - wtimeout = lib.GetMethodDelegate ("wtimeout"); - notimeout = lib.GetMethodDelegate ("notimeout"); - keypad = lib.GetMethodDelegate ("keypad"); - meta = lib.GetMethodDelegate ("meta"); - intrflush = lib.GetMethodDelegate ("intrflush"); - clearok = lib.GetMethodDelegate ("clearok"); - idlok = lib.GetMethodDelegate ("idlok"); - idcok = lib.GetMethodDelegate ("idcok"); - immedok = lib.GetMethodDelegate ("immedok"); - leaveok = lib.GetMethodDelegate ("leaveok"); - wsetscrreg = lib.GetMethodDelegate ("wsetscrreg"); - scrollok = lib.GetMethodDelegate ("scrollok"); - nl = lib.GetMethodDelegate ("nl"); - nonl = lib.GetMethodDelegate ("nonl"); - setscrreg = lib.GetMethodDelegate ("setscrreg"); - refresh = lib.GetMethodDelegate ("refresh"); - doupdate = lib.GetMethodDelegate ("doupdate"); - wrefresh = lib.GetMethodDelegate ("wrefresh"); - redrawwin = lib.GetMethodDelegate ("redrawwin"); - wredrawwin = lib.GetMethodDelegate ("wredrawwin"); - wnoutrefresh = lib.GetMethodDelegate ("wnoutrefresh"); - move = lib.GetMethodDelegate ("move"); - addch = lib.GetMethodDelegate ("addch"); - addstr = lib.GetMethodDelegate ("addstr"); - wmove = lib.GetMethodDelegate ("wmove"); - waddch = lib.GetMethodDelegate ("waddch"); - attron = lib.GetMethodDelegate ("attron"); - attroff = lib.GetMethodDelegate ("attroff"); - attrset = lib.GetMethodDelegate ("attrset"); - getch = lib.GetMethodDelegate ("getch"); - get_wch = lib.GetMethodDelegate ("get_wch"); - ungetch = lib.GetMethodDelegate ("ungetch"); - mvgetch = lib.GetMethodDelegate ("mvgetch"); - has_colors = lib.GetMethodDelegate ("has_colors"); - start_color = lib.GetMethodDelegate ("start_color"); - init_pair = lib.GetMethodDelegate ("init_pair"); - use_default_colors = lib.GetMethodDelegate ("use_default_colors"); - COLOR_PAIR = lib.GetMethodDelegate ("COLOR_PAIR"); - getmouse = lib.GetMethodDelegate ("getmouse"); - ungetmouse = lib.GetMethodDelegate ("ungetmouse"); - mouseinterval = lib.GetMethodDelegate ("mouseinterval"); - } - } internal partial class Curses { [StructLayout (LayoutKind.Sequential)] @@ -236,48 +63,21 @@ namespace Unix.Terminal { // If true, uses the DllImport into "ncurses", otherwise "libncursesw.so.5" static bool use_naked_driver; - NativeMethods methods; + static UnmanagedLibrary curses_library; + static NativeMethods methods; static void LoadMethods () { - var libs = UnmanagedLibrary.IsMacOSPlatform ? new string [] { "libncurses.dylib" } : new string { "libncursesw.so.6", "libncursesw.so.5" }; - var lib = new UnmanagedLibrary (libs); - methods = new NativeMethods (lib); + var libs = UnmanagedLibrary.IsMacOSPlatform ? new string [] { "libncurses.dylib" } : new string [] { "libncursesw.so.6", "libncursesw.so.5" }; + curses_library = new UnmanagedLibrary (libs, false); + methods = new NativeMethods (curses_library); } - - // - // 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 - // - static IntPtr DlOpen (string path) - { - 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"); + LoadMethods (); + curses_handle = methods.UnmanagedLibrary.NativeLibraryHandle; - 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); - } - stdscr = read_static_ptr ("stdscr"); curscr_ptr = get_ptr ("curscr"); lines_ptr = get_ptr ("LINES"); @@ -290,7 +90,7 @@ namespace Unix.Terminal { main_window = new Window (methods.initscr ()); try { - console_sharp_get_dims (out lines, out bcols); + console_sharp_get_dims (out lines, out cols); } catch (DllNotFoundException){ endwin (); Console.Error.WriteLine ("Unable to find the @MONO_CURSES@ native library\n" + @@ -348,30 +148,16 @@ namespace Unix.Terminal { public static int addch (int ch) { if (ch < 127 || ch > 0xffff ) - return _addch (ch); + return methods.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); + var ptr = curses_library.LoadSymbol (key); if (ptr == IntPtr.Zero) throw new Exception ("Could not load the key " + key); @@ -401,7 +187,7 @@ namespace Unix.Terminal { public static Event mousemask (Event newmask, out Event oldmask) { IntPtr e; - var ret = (Event) (methods.call_mousemask ((IntPtr) newmask, out e)); + var ret = (Event) (methods.mousemask ((IntPtr) newmask, out e)); oldmask = (Event) e; return ret; } @@ -425,7 +211,6 @@ namespace Unix.Terminal { // // The proxy methods to call into each version // - static public IntPtr real_initscr () => methods.real_initscr (); static public int endwin () => methods.endwin (); static public bool isendwin () => methods.isendwin (); static public int cbreak () => methods.cbreak (); @@ -435,8 +220,8 @@ namespace Unix.Terminal { static public int halfdelay (int t) => methods.halfdelay (t); static public int raw () => methods.raw (); static public int noraw () => methods.noraw (); - static public void noqiflush () => { methods.noqiflush (); }; - static public void qiflush () => { methods.qiflush (); }; + static public void noqiflush () => methods.noqiflush (); + static public void qiflush () => methods.qiflush (); static public int typeahead (IntPtr fd) => methods.typeahead (fd); static public int timeout (int delay) => methods.timeout (delay); static public int wtimeout (IntPtr win, int delay) => methods.wtimeout (win, delay); @@ -446,8 +231,8 @@ namespace Unix.Terminal { static public int intrflush (IntPtr win, bool bf) => methods.intrflush (win, bf); static public int clearok (IntPtr win, bool bf) => methods.clearok (win, bf); static public int idlok (IntPtr win, bool bf) => methods.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 void idcok (IntPtr win, bool bf) => methods.idcok (win, bf); + static public void immedok (IntPtr win, bool bf) => methods.immedok (win, bf); static public int leaveok (IntPtr win, bool bf) => methods.leaveok (win, bf); static public int wsetscrreg (IntPtr win, int top, int bot) => methods.wsetscrreg (win, top, bot); static public int scrollok (IntPtr win, bool bf) => methods.scrollok (win, bf); @@ -458,10 +243,10 @@ namespace Unix.Terminal { static public int doupdate() => methods.doupdate(); static public int wrefresh (IntPtr win) => methods.wrefresh (win); static public int redrawwin (IntPtr win) => methods.redrawwin (win); - static public int wredrawwin (IntPtr win, int beg_line, int num_lines) => methods.wredrawwin (win, beg_line, num_lines); + //static public int wredrawwin (IntPtr win, int beg_line, int num_lines) => methods.wredrawwin (win, beg_line, num_lines); static public int wnoutrefresh (IntPtr win) => methods.wnoutrefresh (win); static public int move (int line, int col) => methods.move (line, col); - static public int _addch (int ch) => methods._addch (ch); + //static public int addch (int ch) => methods.addch (ch); static public int addstr (string s) => methods.addstr (s); static public int wmove (IntPtr win, int line, int col) => methods.wmove (win, line, col); static public int waddch (IntPtr win, int ch) => methods.waddch (win, ch); @@ -481,360 +266,184 @@ namespace Unix.Terminal { static public uint ungetmouse (ref MouseEvent ev) => methods.ungetmouse (ref ev); static public int mouseinterval (int interval) => methods.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 (); - - [DllImport ("ncurses")] - extern static public bool isendwin (); - - // - // Screen operations are flagged as internal, as we need to - // catch all changes so we can update newscr, curscr, stdscr - // - [DllImport ("ncurses")] - extern static public IntPtr internal_newterm (string type, IntPtr file_outfd, IntPtr file_infd); - - [DllImport ("ncurses")] - extern static public IntPtr internal_set_term (IntPtr newscreen); - - [DllImport ("ncurses")] - extern static internal void internal_delscreen (IntPtr sp); - - [DllImport ("ncurses")] - extern static public int cbreak (); - - [DllImport ("ncurses")] - extern static public int nocbreak (); - - [DllImport ("ncurses")] - extern static public int echo (); - - [DllImport ("ncurses")] - extern static public int noecho (); - - [DllImport ("ncurses")] - extern static public int halfdelay (int t); - - [DllImport ("ncurses")] - extern static public int raw (); - - [DllImport ("ncurses")] - extern static public int noraw (); - - [DllImport ("ncurses")] - extern static public void noqiflush (); - - [DllImport ("ncurses")] - extern static public void qiflush (); - - [DllImport ("ncurses")] - extern static public int typeahead (IntPtr fd); - - [DllImport ("ncurses")] - extern static public int timeout (int delay); - - // - // Internal, as they are exposed in Window - // - [DllImport ("ncurses")] - extern static internal int wtimeout (IntPtr win, int delay); - - [DllImport ("ncurses")] - extern static internal int notimeout (IntPtr win, bool bf); - - [DllImport ("ncurses")] - extern static internal int keypad (IntPtr win, bool bf); - - [DllImport ("ncurses")] - extern static internal int meta (IntPtr win, bool bf); - - [DllImport ("ncurses")] - extern static internal int intrflush (IntPtr win, bool bf); - - [DllImport ("ncurses")] - extern internal static int clearok (IntPtr win, bool bf); - [DllImport ("ncurses")] - extern internal static int idlok (IntPtr win, bool bf); - [DllImport ("ncurses")] - extern internal static void idcok (IntPtr win, bool bf); - [DllImport ("ncurses")] - extern internal static void immedok (IntPtr win, bool bf); - [DllImport ("ncurses")] - extern internal static int leaveok (IntPtr win, bool bf); - [DllImport ("ncurses")] - extern internal static int wsetscrreg (IntPtr win, int top, int bot); - [DllImport ("ncurses")] - extern internal static int scrollok (IntPtr win, bool bf); - - [DllImport ("ncurses")] - extern public static int nl(); - [DllImport ("ncurses")] - extern public static int nonl(); - [DllImport ("ncurses")] - extern public static int setscrreg (int top, int bot); - - - [DllImport ("ncurses")] - extern public static int refresh (); - [DllImport ("ncurses")] - extern public static int doupdate(); - - [DllImport ("ncurses")] - extern internal static int wrefresh (IntPtr win); - [DllImport ("ncurses")] - extern internal static int redrawwin (IntPtr win); - [DllImport ("ncurses")] - extern internal static int wredrawwin (IntPtr win, int beg_line, int num_lines); - [DllImport ("ncurses")] - extern internal static int wnoutrefresh (IntPtr win); - - [DllImport ("ncurses")] - extern public static int move (int line, int col); - - [DllImport ("ncurses", EntryPoint="addch")] - extern internal static int _addch (int ch); - - [DllImport ("ncurses")] - extern public static int addstr (string s); - - [DllImport ("ncurses")] - extern internal static int wmove (IntPtr win, int line, int col); - - [DllImport ("ncurses")] - extern internal static int waddch (IntPtr win, int ch); - - [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); - - [DllImport ("ncurses")] - extern public static int getch (); - - [DllImport ("ncurses")] - extern public static int get_wch (out int sequence); - - [DllImport ("ncurses")] - extern public static int ungetch (int ch); - - [DllImport ("ncurses")] - extern public static int mvgetch (int y, int x); - - [DllImport ("ncurses")] - extern internal static bool has_colors (); - - [DllImport ("ncurses")] - extern internal static int start_color (); - - [DllImport ("ncurses")] - extern internal static int init_pair (short pair, short f, short b); - - [DllImport ("ncurses")] - extern internal static int use_default_colors (); - - [DllImport ("ncurses")] - extern internal static int 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); - - [DllImport ("ncurses", EntryPoint="mousemask")] - public extern static IntPtr call_mousemask (IntPtr newmask, out IntPtr oldmask); - + internal class Delegates { + public delegate IntPtr initscr (); + public delegate int endwin (); + public delegate bool isendwin (); + public delegate int cbreak (); + public delegate int nocbreak (); + public delegate int echo (); + public delegate int noecho (); + public delegate int halfdelay (int t); + public delegate int raw (); + public delegate int noraw (); + public delegate void noqiflush (); + public delegate void qiflush (); + public delegate int typeahead (IntPtr fd); + public delegate int timeout (int delay); + public delegate int wtimeout (IntPtr win, int delay); + public delegate int notimeout (IntPtr win, bool bf); + public delegate int keypad (IntPtr win, bool bf); + public delegate int meta (IntPtr win, bool bf); + public delegate int intrflush (IntPtr win, bool bf); + public delegate int clearok (IntPtr win, bool bf); + public delegate int idlok (IntPtr win, bool bf); + public delegate void idcok (IntPtr win, bool bf); + public delegate void immedok (IntPtr win, bool bf); + public delegate int leaveok (IntPtr win, bool bf); + public delegate int wsetscrreg (IntPtr win, int top, int bot); + public delegate int scrollok (IntPtr win, bool bf); + public delegate int nl (); + public delegate int nonl (); + public delegate int setscrreg (int top, int bot); + public delegate int refresh (); + public delegate int doupdate (); + public delegate int wrefresh (IntPtr win); + public delegate int redrawwin (IntPtr win); + //public delegate int wredrawwin (IntPtr win, int beg_line, int num_lines); + public delegate int wnoutrefresh (IntPtr win); + public delegate int move (int line, int col); + public delegate int addch (int ch); + public delegate int addstr (string s); + public delegate int wmove (IntPtr win, int line, int col); + public delegate int waddch (IntPtr win, int ch); + public delegate int attron (int attrs); + public delegate int attroff (int attrs); + public delegate int attrset (int attrs); + public delegate int getch (); + public delegate int get_wch (out int sequence); + public delegate int ungetch (int ch); + public delegate int mvgetch (int y, int x); + public delegate bool has_colors (); + public delegate int start_color (); + public delegate int init_pair (short pair, short f, short b); + public delegate int use_default_colors (); + public delegate int COLOR_PAIRS (); + public delegate uint getmouse (out Curses.MouseEvent ev); + public delegate uint ungetmouse (ref Curses.MouseEvent ev); + public delegate int mouseinterval (int interval); + public delegate IntPtr mousemask (IntPtr newmask, out IntPtr oldMask); } - - // - // 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="mousemask")] - public extern static IntPtr call_mousemask (IntPtr newmask, out IntPtr oldmask); - - [DllImport ("libncursesw.so.5", EntryPoint="initscr")] - extern static internal IntPtr real_initscr (); - [DllImport ("libncursesw.so.5")] - extern static public int endwin (); + internal class NativeMethods { + public readonly Delegates.initscr initscr; + public readonly Delegates.endwin endwin; + public readonly Delegates.isendwin isendwin; + public readonly Delegates.cbreak cbreak; + public readonly Delegates.nocbreak nocbreak; + public readonly Delegates.echo echo; + public readonly Delegates.noecho noecho; + public readonly Delegates.halfdelay halfdelay; + public readonly Delegates.raw raw; + public readonly Delegates.noraw noraw; + public readonly Delegates.noqiflush noqiflush; + public readonly Delegates.qiflush qiflush; + public readonly Delegates.typeahead typeahead; + public readonly Delegates.timeout timeout; + public readonly Delegates.wtimeout wtimeout; + public readonly Delegates.notimeout notimeout; + public readonly Delegates.keypad keypad; + public readonly Delegates.meta meta; + public readonly Delegates.intrflush intrflush; + public readonly Delegates.clearok clearok; + public readonly Delegates.idlok idlok; + public readonly Delegates.idcok idcok; + public readonly Delegates.immedok immedok; + public readonly Delegates.leaveok leaveok; + public readonly Delegates.wsetscrreg wsetscrreg; + public readonly Delegates.scrollok scrollok; + public readonly Delegates.nl nl; + public readonly Delegates.nonl nonl; + public readonly Delegates.setscrreg setscrreg; + public readonly Delegates.refresh refresh; + public readonly Delegates.doupdate doupdate; + public readonly Delegates.wrefresh wrefresh; + public readonly Delegates.redrawwin redrawwin; + //public readonly Delegates.wredrawwin wredrawwin; + public readonly Delegates.wnoutrefresh wnoutrefresh; + public readonly Delegates.move move; + public readonly Delegates.addch addch; + public readonly Delegates.addstr addstr; + public readonly Delegates.wmove wmove; + public readonly Delegates.waddch waddch; + public readonly Delegates.attron attron; + public readonly Delegates.attroff attroff; + public readonly Delegates.attrset attrset; + public readonly Delegates.getch getch; + public readonly Delegates.get_wch get_wch; + public readonly Delegates.ungetch ungetch; + public readonly Delegates.mvgetch mvgetch; + public readonly Delegates.has_colors has_colors; + public readonly Delegates.start_color start_color; + public readonly Delegates.init_pair init_pair; + public readonly Delegates.use_default_colors use_default_colors; + public readonly Delegates.COLOR_PAIRS COLOR_PAIRS; + public readonly Delegates.getmouse getmouse; + public readonly Delegates.ungetmouse ungetmouse; + public readonly Delegates.mouseinterval mouseinterval; + public readonly Delegates.mousemask mousemask; - [DllImport ("libncursesw.so.5")] - extern static public bool isendwin (); - - // - // 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); - - [DllImport ("libncursesw.so.5")] - extern static public IntPtr internal_set_term (IntPtr newscreen); - - [DllImport ("libncursesw.so.5")] - extern static internal void internal_delscreen (IntPtr sp); - - [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); - - [DllImport ("libncursesw.so.5")] - extern static public int raw (); - - [DllImport ("libncursesw.so.5")] - extern static public int noraw (); - - [DllImport ("libncursesw.so.5")] - extern static public void noqiflush (); - - [DllImport ("libncursesw.so.5")] - extern static public void qiflush (); - - [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); - - [DllImport ("libncursesw.so.5")] - extern static internal int intrflush (IntPtr win, bool bf); - - [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 ("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); - - [DllImport ("libncursesw.so.5")] - extern public static int addstr (string s); - - [DllImport ("libncursesw.so.5")] - extern internal static int wmove (IntPtr win, int line, int col); - - [DllImport ("libncursesw.so.5")] - extern internal static int waddch (IntPtr win, int ch); - - [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); - - [DllImport ("libncursesw.so.5")] - extern public static int getch (); - - [DllImport ("libncursesw.so.5")] - extern public static int get_wch (out int sequence); - - [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); + public UnmanagedLibrary UnmanagedLibrary; + public NativeMethods (UnmanagedLibrary lib) + { + this.UnmanagedLibrary = lib; + initscr = lib.GetNativeMethodDelegate ("initscr"); + endwin = lib.GetNativeMethodDelegate ("endwin"); + isendwin = lib.GetNativeMethodDelegate ("isendwin"); + cbreak = lib.GetNativeMethodDelegate ("cbreak"); + nocbreak = lib.GetNativeMethodDelegate ("nocbreak"); + echo = lib.GetNativeMethodDelegate ("echo"); + noecho = lib.GetNativeMethodDelegate ("noecho"); + halfdelay = lib.GetNativeMethodDelegate ("halfdelay"); + raw = lib.GetNativeMethodDelegate ("raw"); + noraw = lib.GetNativeMethodDelegate ("noraw"); + noqiflush = lib.GetNativeMethodDelegate ("noqiflush"); + qiflush = lib.GetNativeMethodDelegate ("qiflush"); + typeahead = lib.GetNativeMethodDelegate ("typeahead"); + timeout = lib.GetNativeMethodDelegate ("timeout"); + wtimeout = lib.GetNativeMethodDelegate ("wtimeout"); + notimeout = lib.GetNativeMethodDelegate ("notimeout"); + keypad = lib.GetNativeMethodDelegate ("keypad"); + meta = lib.GetNativeMethodDelegate ("meta"); + intrflush = lib.GetNativeMethodDelegate ("intrflush"); + clearok = lib.GetNativeMethodDelegate ("clearok"); + idlok = lib.GetNativeMethodDelegate ("idlok"); + idcok = lib.GetNativeMethodDelegate ("idcok"); + immedok = lib.GetNativeMethodDelegate ("immedok"); + leaveok = lib.GetNativeMethodDelegate ("leaveok"); + wsetscrreg = lib.GetNativeMethodDelegate ("wsetscrreg"); + scrollok = lib.GetNativeMethodDelegate ("scrollok"); + nl = lib.GetNativeMethodDelegate ("nl"); + nonl = lib.GetNativeMethodDelegate ("nonl"); + setscrreg = lib.GetNativeMethodDelegate ("setscrreg"); + refresh = lib.GetNativeMethodDelegate ("refresh"); + doupdate = lib.GetNativeMethodDelegate ("doupdate"); + wrefresh = lib.GetNativeMethodDelegate ("wrefresh"); + redrawwin = lib.GetNativeMethodDelegate ("redrawwin"); + //wredrawwin = lib.GetNativeMethodDelegate ("wredrawwin"); + wnoutrefresh = lib.GetNativeMethodDelegate ("wnoutrefresh"); + move = lib.GetNativeMethodDelegate ("move"); + addch = lib.GetNativeMethodDelegate ("addch"); + addstr = lib.GetNativeMethodDelegate ("addstr"); + wmove = lib.GetNativeMethodDelegate ("wmove"); + waddch = lib.GetNativeMethodDelegate ("waddch"); + attron = lib.GetNativeMethodDelegate ("attron"); + attroff = lib.GetNativeMethodDelegate ("attroff"); + attrset = lib.GetNativeMethodDelegate ("attrset"); + getch = lib.GetNativeMethodDelegate ("getch"); + get_wch = lib.GetNativeMethodDelegate ("get_wch"); + ungetch = lib.GetNativeMethodDelegate ("ungetch"); + mvgetch = lib.GetNativeMethodDelegate ("mvgetch"); + has_colors = lib.GetNativeMethodDelegate ("has_colors"); + start_color = lib.GetNativeMethodDelegate ("start_color"); + init_pair = lib.GetNativeMethodDelegate ("init_pair"); + use_default_colors = lib.GetNativeMethodDelegate ("use_default_colors"); + COLOR_PAIRS = lib.GetNativeMethodDelegate ("COLOR_PAIRS"); + getmouse = lib.GetNativeMethodDelegate ("getmouse"); + ungetmouse = lib.GetNativeMethodDelegate ("ungetmouse"); + mouseinterval = lib.GetNativeMethodDelegate ("mouseinterval"); + mousemask = lib.GetNativeMethodDelegate ("mousemask"); + } } - } diff --git a/Terminal.Gui/MonoCurses/handles.cs b/Terminal.Gui/MonoCurses/handles.cs index e91887256..7562cb2ae 100644 --- a/Terminal.Gui/MonoCurses/handles.cs +++ b/Terminal.Gui/MonoCurses/handles.cs @@ -35,107 +35,108 @@ namespace Unix.Terminal { public readonly IntPtr Handle; static Window curscr; static Window stdscr; - + static Window () { Curses.initscr (); stdscr = new Window (Curses.console_sharp_get_stdscr ()); curscr = new Window (Curses.console_sharp_get_curscr ()); } - - internal Window (IntPtr handle) + + internal Window (IntPtr handle) { Handle = handle; } - + static public Window Standard { get { return stdscr; } } - + static public Window Current { get { return curscr; } } - - + + public int wtimeout (int delay) { return Curses.wtimeout (Handle, delay); } - + public int notimeout (bool bf) { return Curses.notimeout (Handle, bf); } - + public int keypad (bool bf) { return Curses.keypad (Handle, bf); } - + public int meta (bool bf) { return Curses.meta (Handle, bf); } - + public int intrflush (bool bf) { return Curses.intrflush (Handle, bf); } - + public int clearok (bool bf) { return Curses.clearok (Handle, bf); } - + public int idlok (bool bf) { return Curses.idlok (Handle, bf); } - + public void idcok (bool bf) { Curses.idcok (Handle, bf); } - + public void immedok (bool bf) { Curses.immedok (Handle, bf); } - + public int leaveok (bool bf) { return Curses.leaveok (Handle, bf); } - + public int setscrreg (int top, int bot) { return Curses.wsetscrreg (Handle, top, bot); } - + public int scrollok (bool bf) { return Curses.scrollok (Handle, bf); } - + public int wrefresh () { return Curses.wrefresh (Handle); } - + public int redrawwin () { return Curses.redrawwin (Handle); } - + +#if false public int wredrawwin (int beg_line, int num_lines) { return Curses.wredrawwin (Handle, beg_line, num_lines); } - +#endif public int wnoutrefresh () { return Curses.wnoutrefresh (Handle); From 8e45d02ad076d8c0aed90c90afcbde2889400d56 Mon Sep 17 00:00:00 2001 From: miguel Date: Mon, 24 Sep 2018 22:23:40 -0400 Subject: [PATCH 4/4] Do not target 4.7 --- Terminal.Gui/Terminal.Gui.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/Terminal.Gui/Terminal.Gui.csproj b/Terminal.Gui/Terminal.Gui.csproj index ec1e6131d..7e1e67514 100644 --- a/Terminal.Gui/Terminal.Gui.csproj +++ b/Terminal.Gui/Terminal.Gui.csproj @@ -6,7 +6,6 @@ full bin\Release\Terminal.Gui.xml true - net47 true