2 // System.ConsoleDriver
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // (C) 2005,2006 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
35 using System.Runtime.InteropServices;
37 class TermInfoDriver : IConsoleDriver {
38 /* Do not rename this field, its looked up from the runtime */
39 static bool need_window_dimensions = true;
41 static string [] locations = { "/etc/terminfo", "/usr/share/terminfo", "/usr/lib/terminfo" };
43 TermInfoReader reader;
46 string title = String.Empty;
47 string titleFormat = String.Empty;
48 bool cursorVisible = true;
69 string keypadXmit, keypadLocal;
76 ConsoleColor fgcolor = ConsoleColor.White;
77 ConsoleColor bgcolor = ConsoleColor.Black;
78 string setafcolor; // TODO: use setforeground/setbackground if available for better
79 string setabcolor; // color mapping.
83 bool home_1_1; // if true, we have to add 1 to x and y when using cursorAddress
84 int rl_startx = -1, rl_starty = -1;
89 static string SearchTerminfo (string term)
91 if (term == null || term == String.Empty)
94 // Ignore TERMINFO and TERMINFO_DIRS by now
95 //string terminfo = Environment.GetEnvironmentVariable ("TERMINFO");
96 //string terminfoDirs = Environment.GetEnvironmentVariable ("TERMINFO_DIRS");
98 foreach (string dir in locations) {
99 if (!Directory.Exists (dir))
102 string path = Path.Combine (dir, term.Substring (0, 1));
103 if (!Directory.Exists (dir))
106 path = Path.Combine (path, term);
107 if (!File.Exists (path))
116 static void WriteConsole (string str)
121 ((CStreamWriter) Console.stdout).InternalWriteString (str);
124 public TermInfoDriver ()
125 : this (Environment.GetEnvironmentVariable ("TERM"))
129 public TermInfoDriver (string term)
132 //File.Delete ("console.log");
133 logger = new StreamWriter (File.OpenWrite ("console.log"));
137 if (term == "xterm") {
138 reader = new TermInfoReader (term, KnownTerminals.xterm);
139 } else if (term == "linux") {
140 reader = new TermInfoReader (term, KnownTerminals.linux);
142 string filename = SearchTerminfo (term);
143 if (filename != null)
144 reader = new TermInfoReader (term, filename);
148 reader = new TermInfoReader (term, KnownTerminals.ansi);
151 public bool Initialized {
152 get { return inited; }
160 /* This should not happen any more, since it is checked for in Console */
161 if (!ConsoleDriver.IsConsole)
162 throw new IOException ("Not a tty.");
166 ConsoleDriver.SetEcho (false);
168 string endString = null;
169 keypadXmit = reader.Get (TermInfoStrings.KeypadXmit);
170 keypadLocal = reader.Get (TermInfoStrings.KeypadLocal);
171 if (keypadXmit != null) {
172 WriteConsole (keypadXmit); // Needed to get the arrows working
173 if (keypadLocal != null)
174 endString += keypadLocal;
177 origPair = reader.Get (TermInfoStrings.OrigPair);
178 origColors = reader.Get (TermInfoStrings.OrigColors);
179 setafcolor = MangleParameters (reader.Get (TermInfoStrings.SetAForeground));
180 setabcolor = MangleParameters (reader.Get (TermInfoStrings.SetABackground));
181 string resetColors = (origColors == null) ? origPair : origColors;
182 if (resetColors != null)
183 endString += resetColors;
185 if (!ConsoleDriver.TtySetup (endString, out verase, out vsusp, out intr))
186 throw new IOException ("Error initializing terminal.");
188 stdin = Console.OpenStandardInput (0);
189 clear = reader.Get (TermInfoStrings.ClearScreen);
190 bell = reader.Get (TermInfoStrings.Bell);
192 clear = reader.Get (TermInfoStrings.CursorHome);
193 clear += reader.Get (TermInfoStrings.ClrEos);
196 csrVisible = reader.Get (TermInfoStrings.CursorNormal);
197 if (csrVisible == null)
198 csrVisible = reader.Get (TermInfoStrings.CursorVisible);
200 csrInvisible = reader.Get (TermInfoStrings.CursorInvisible);
201 if (term == "cygwin" || term == "linux" || (term != null && term.StartsWith ("xterm")) ||
202 term == "rxvt" || term == "dtterm") {
203 titleFormat = "\x1b]0;{0}\x7"; // icon + window title
204 } else if (term == "iris-ansi") {
205 titleFormat = "\x1bP1.y{0}\x1b\\"; // not tested
206 } else if (term == "sun-cmd") {
207 titleFormat = "\x1b]l{0}\x1b\\"; // not tested
210 cursorAddress = reader.Get (TermInfoStrings.CursorAddress);
211 if (cursorAddress != null) {
212 string result = cursorAddress.Replace ("%i", String.Empty);
213 home_1_1 = (cursorAddress != result);
214 cursorAddress = MangleParameters (result);
217 GetCursorPosition ();
219 logger.WriteLine ("noGetPosition: {0} left: {1} top: {2}", noGetPosition, cursorLeft, cursorTop);
223 WriteConsole (clear);
229 static string MangleParameters (string str)
234 str = str.Replace ("{", "{{");
235 str = str.Replace ("}", "}}");
236 str = str.Replace ("%p1%d", "{0}");
237 return str.Replace ("%p2%d", "{1}");
240 static int TranslateColor (ConsoleColor desired)
243 case ConsoleColor.Black:
244 case ConsoleColor.DarkGray:
246 case ConsoleColor.DarkBlue:
247 case ConsoleColor.Blue:
249 case ConsoleColor.DarkGreen:
250 case ConsoleColor.Green:
252 case ConsoleColor.DarkCyan:
253 case ConsoleColor.Cyan:
255 case ConsoleColor.DarkRed:
256 case ConsoleColor.Red:
258 case ConsoleColor.DarkMagenta:
259 case ConsoleColor.Magenta:
261 case ConsoleColor.DarkYellow:
262 case ConsoleColor.Yellow:
264 case ConsoleColor.Gray:
265 case ConsoleColor.White:
275 if (cursorLeft >= WindowWidth) {
278 if (cursorTop >= WindowHeight) {
279 // Writing beyond the initial screen
280 if (rl_starty != -1) rl_starty--;
286 // Should never get called unless inited
287 public void WriteSpecialKey (ConsoleKeyInfo key)
290 case ConsoleKey.Backspace:
291 if (cursorLeft > 0) {
292 if (cursorLeft <= rl_startx && cursorTop == rl_starty)
295 SetCursorPosition (cursorLeft, cursorTop);
297 SetCursorPosition (cursorLeft, cursorTop);
300 logger.WriteLine ("BS left: {0} top: {1}", cursorLeft, cursorTop);
305 int n = 8 - (cursorLeft % 8);
306 for (int i = 0; i < n; i++)
309 case ConsoleKey.Clear:
311 case ConsoleKey.Enter:
317 logger.WriteLine ("left: {0} top: {1}", cursorLeft, cursorTop);
322 // Should never get called unless inited
323 public void WriteSpecialKey (char c)
325 WriteSpecialKey (CreateKeyInfoFromInt (c));
328 public bool IsSpecialKey (ConsoleKeyInfo key)
334 case ConsoleKey.Backspace:
338 case ConsoleKey.Clear:
340 case ConsoleKey.Enter:
343 if (cursorTop >= WindowHeight) {
349 // CStreamWriter will handle writing this key
355 public bool IsSpecialKey (char c)
357 return IsSpecialKey (CreateKeyInfoFromInt (c));
360 public ConsoleColor BackgroundColor {
374 WriteConsole (String.Format (setabcolor, TranslateColor (value)));
378 public ConsoleColor ForegroundColor {
392 WriteConsole (String.Format (setafcolor, TranslateColor (value)));
396 // Only used once from within Init()
397 void GetCursorPosition ()
399 int row = 0, col = 0;
401 WriteConsole ("\x1b[6n");
402 if (ConsoleDriver.InternalKeyAvailable (1000) <= 0) {
403 noGetPosition = true;
407 int b = stdin.ReadByte ();
408 while (b != '\x1b') {
410 if (ConsoleDriver.InternalKeyAvailable (100) <= 0)
412 b = stdin.ReadByte ();
415 b = stdin.ReadByte ();
417 AddToBuffer ('\x1b');
422 b = stdin.ReadByte ();
425 b = stdin.ReadByte ();
426 while ((b >= '0') && (b <= '9')) {
427 row = row * 10 + b - '0';
428 b = stdin.ReadByte ();
430 // Row/col is 0 based
434 b = stdin.ReadByte ();
437 b = stdin.ReadByte ();
438 while ((b >= '0') && (b <= '9')) {
439 col = col * 10 + b - '0';
440 b = stdin.ReadByte ();
442 // Row/col is 0 based
447 logger.WriteLine ("GetCursorPosition: {0}, {1}", col, row);
455 public int BufferHeight {
468 throw new NotSupportedException ();
472 public int BufferWidth {
485 throw new NotSupportedException ();
489 public bool CapsLock {
495 throw new NotSupportedException ();
499 public int CursorLeft {
512 SetCursorPosition (value, CursorTop);
517 public int CursorTop {
530 SetCursorPosition (CursorLeft, value);
535 public bool CursorVisible {
541 return cursorVisible;
548 cursorVisible = value;
549 WriteConsole ((value ? csrVisible : csrInvisible));
553 // we have CursorNormal vs. CursorVisible...
555 public int CursorSize {
570 public bool KeyAvailable {
576 return (writepos > readpos || ConsoleDriver.InternalKeyAvailable (0) > 0);
580 // We don't know these next 2 values, so return something reasonable
581 public int LargestWindowHeight {
582 get { return WindowHeight; }
585 public int LargestWindowWidth {
586 get { return WindowWidth; }
589 public bool NumberLock {
595 throw new NotSupportedException ();
599 public string Title {
613 WriteConsole (String.Format (titleFormat, value));
617 public bool TreatControlCAsInput {
622 return controlCAsInput;
629 if (controlCAsInput == value)
632 ConsoleDriver.SetBreak (value);
633 controlCAsInput = value;
637 void GetWindowDimensions ()
639 /* Try the ioctl first */
640 if (!ConsoleDriver.GetTtySize (MonoIO.ConsoleOutput, out windowWidth, out windowHeight)) {
641 windowWidth = reader.Get (TermInfoNumbers.Columns);
642 string env = Environment.GetEnvironmentVariable ("COLUMNS");
645 windowWidth = (int) UInt32.Parse (env);
650 windowHeight = reader.Get (TermInfoNumbers.Lines);
651 env = Environment.GetEnvironmentVariable ("LINES");
654 windowHeight = (int) UInt32.Parse (env);
660 bufferHeight = windowHeight;
661 bufferWidth = windowWidth;
662 need_window_dimensions = false;
665 public int WindowHeight {
671 if (need_window_dimensions)
672 GetWindowDimensions ();
680 throw new NotSupportedException ();
684 public int WindowLeft {
690 //GetWindowDimensions ();
698 throw new NotSupportedException ();
702 public int WindowTop {
708 //GetWindowDimensions ();
716 throw new NotSupportedException ();
720 public int WindowWidth {
726 if (need_window_dimensions)
727 GetWindowDimensions ();
735 throw new NotSupportedException ();
745 WriteConsole (clear);
748 public void Beep (int frequency, int duration)
757 public void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
758 int targetLeft, int targetTop, Char sourceChar,
759 ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
765 throw new NotImplementedException ();
768 void AddToBuffer (int b)
770 if (buffer == null) {
771 buffer = new byte [1024];
772 } else if (writepos >= buffer.Length) {
773 byte [] newbuf = new byte [buffer.Length * 2];
774 Buffer.BlockCopy (buffer, 0, newbuf, 0, buffer.Length);
778 buffer [writepos++] = (byte) b;
783 if (readpos >= writepos) {
784 readpos = writepos = 0;
788 ConsoleKeyInfo CreateKeyInfoFromInt (int n)
791 ConsoleKey key = (ConsoleKey)n;
797 key = ConsoleKey.Enter;
798 } else if (n == 8 || n == 9 || n == 12 || n == 13 || n == 19) {
799 /* Values in ConsoleKey */
800 } else if (n >= 1 && n <= 26) {
801 // For Ctrl-a to Ctrl-z.
803 key = ConsoleKey.A + n - 1;
804 } else if (n == 27) {
805 key = ConsoleKey.Escape;
806 } else if (n >= 'a' && n <= 'z') {
807 key = ConsoleKey.A - 'a' + n;
808 } else if (n >= 'A' && n <= 'Z') {
810 } else if (n >= '0' && n <= '9') {
815 return new ConsoleKeyInfo (c, key, shift, alt, ctrl);
818 object GetKeyFromBuffer (bool cooked)
820 if (readpos >= writepos)
823 int next = buffer [readpos];
824 if (!cooked || !rootmap.StartsWith (next)) {
827 return CreateKeyInfoFromInt (next);
831 TermInfoStrings str = rootmap.Match (buffer, readpos, writepos - readpos, out used);
836 if (keymap [str] != null) {
837 key = (ConsoleKeyInfo) keymap [str];
841 return CreateKeyInfoFromInt (next);
849 ConsoleKeyInfo ReadKeyInternal ()
858 o = GetKeyFromBuffer (true);
860 if (ConsoleDriver.InternalKeyAvailable (150) > 0) {
862 AddToBuffer (stdin.ReadByte ());
863 } while (ConsoleDriver.InternalKeyAvailable (0) > 0);
865 o = GetKeyFromBuffer (false);
867 AddToBuffer (stdin.ReadByte ());
872 return (ConsoleKeyInfo) o;
875 public ConsoleKeyInfo ReadKey (bool intercept)
880 ConsoleKeyInfo key = ReadKeyInternal ();
883 // echo the key back to the console
884 CStreamWriter writer = Console.stdout as CStreamWriter;
887 writer.WriteKey (key);
889 Console.stdout.Write (key.KeyChar);
895 public string ReadLine ()
900 StringBuilder builder = new StringBuilder ();
902 CStreamWriter writer = Console.stdout as CStreamWriter;
903 rl_startx = cursorLeft;
904 rl_starty = cursorTop;
906 ConsoleKeyInfo key = ReadKeyInternal ();
907 char c = key.KeyChar;
910 if (key.Key != ConsoleKey.Backspace)
912 else if (builder.Length > 0)
915 // skips over echoing the key to the console
920 // echo the key back to the console
922 writer.WriteKey (key);
924 Console.stdout.Write (c);
929 return builder.ToString ();
932 public void ResetColor ()
938 string str = (origPair != null) ? origPair : origColors;
942 public void SetBufferSize (int width, int height)
948 throw new NotImplementedException (String.Empty);
951 public void SetCursorPosition (int left, int top)
957 if (bufferWidth == 0 && need_window_dimensions)
958 GetWindowDimensions ();
960 if (left < 0 || left >= bufferWidth)
961 throw new ArgumentOutOfRangeException ("left", "Value must be positive and below the buffer width.");
963 if (top < 0 || top >= bufferHeight)
964 throw new ArgumentOutOfRangeException ("top", "Value must be positive and below the buffer height.");
966 // Either CursorAddress or nothing.
967 // We might want to play with up/down/left/right/home when ca is not available.
968 if (cursorAddress == null)
969 throw new NotSupportedException ("This terminal does not suport setting the cursor position.");
971 int one = (home_1_1 ? 1 : 0);
972 WriteConsole (String.Format (cursorAddress, top + one, left + one));
977 public void SetWindowPosition (int left, int top)
983 // No need to throw exceptions here.
984 //throw new NotSupportedException ();
987 public void SetWindowSize (int width, int height)
993 // No need to throw exceptions here.
994 //throw new NotSupportedException ();
1000 keymap = new Hashtable ();
1001 keymap [TermInfoStrings.KeyBackspace] = new ConsoleKeyInfo ('\0', ConsoleKey.Backspace, false, false, false);
1002 keymap [TermInfoStrings.KeyClear] = new ConsoleKeyInfo ('\0', ConsoleKey.Clear, false, false, false);
1003 // Delete character...
1004 keymap [TermInfoStrings.KeyDown] = new ConsoleKeyInfo ('\0', ConsoleKey.DownArrow, false, false, false);
1005 keymap [TermInfoStrings.KeyF1] = new ConsoleKeyInfo ('\0', ConsoleKey.F1, false, false, false);
1006 keymap [TermInfoStrings.KeyF10] = new ConsoleKeyInfo ('\0', ConsoleKey.F10, false, false, false);
1007 keymap [TermInfoStrings.KeyF2] = new ConsoleKeyInfo ('\0', ConsoleKey.F2, false, false, false);
1008 keymap [TermInfoStrings.KeyF3] = new ConsoleKeyInfo ('\0', ConsoleKey.F3, false, false, false);
1009 keymap [TermInfoStrings.KeyF4] = new ConsoleKeyInfo ('\0', ConsoleKey.F4, false, false, false);
1010 keymap [TermInfoStrings.KeyF5] = new ConsoleKeyInfo ('\0', ConsoleKey.F5, false, false, false);
1011 keymap [TermInfoStrings.KeyF6] = new ConsoleKeyInfo ('\0', ConsoleKey.F6, false, false, false);
1012 keymap [TermInfoStrings.KeyF7] = new ConsoleKeyInfo ('\0', ConsoleKey.F7, false, false, false);
1013 keymap [TermInfoStrings.KeyF8] = new ConsoleKeyInfo ('\0', ConsoleKey.F8, false, false, false);
1014 keymap [TermInfoStrings.KeyF9] = new ConsoleKeyInfo ('\0', ConsoleKey.F9, false, false, false);
1015 keymap [TermInfoStrings.KeyHome] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, false, false, false);
1017 keymap [TermInfoStrings.KeyLeft] = new ConsoleKeyInfo ('\0', ConsoleKey.LeftArrow, false, false, false);
1018 keymap [TermInfoStrings.KeyLl] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad1, false, false, false);
1019 keymap [TermInfoStrings.KeyNpage] = new ConsoleKeyInfo ('\0', ConsoleKey.PageDown, false, false, false);
1020 keymap [TermInfoStrings.KeyPpage] = new ConsoleKeyInfo ('\0', ConsoleKey.PageUp, false, false, false);
1021 keymap [TermInfoStrings.KeyRight] = new ConsoleKeyInfo ('\0', ConsoleKey.RightArrow, false, false, false);
1022 keymap [TermInfoStrings.KeySf] = new ConsoleKeyInfo ('\0', ConsoleKey.PageDown, false, false, false);
1023 keymap [TermInfoStrings.KeySr] = new ConsoleKeyInfo ('\0', ConsoleKey.PageUp, false, false, false);
1024 keymap [TermInfoStrings.KeyUp] = new ConsoleKeyInfo ('\0', ConsoleKey.UpArrow, false, false, false);
1025 keymap [TermInfoStrings.KeyA1] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad7, false, false, false);
1026 keymap [TermInfoStrings.KeyA3] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad9, false, false, false);
1027 keymap [TermInfoStrings.KeyB2] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad5, false, false, false);
1028 keymap [TermInfoStrings.KeyC1] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad1, false, false, false);
1029 keymap [TermInfoStrings.KeyC3] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad3, false, false, false);
1030 keymap [TermInfoStrings.KeyBtab] = new ConsoleKeyInfo ('\0', ConsoleKey.Tab, true, false, false);
1031 keymap [TermInfoStrings.KeyBeg] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, false, false, false);
1032 keymap [TermInfoStrings.KeyCopy] = new ConsoleKeyInfo ('C', ConsoleKey.C, false, true, false);
1033 keymap [TermInfoStrings.KeyEnd] = new ConsoleKeyInfo ('\0', ConsoleKey.End, false, false, false);
1034 keymap [TermInfoStrings.KeyEnter] = new ConsoleKeyInfo ('\n', ConsoleKey.Enter, false, false, false);
1035 keymap [TermInfoStrings.KeyHelp] = new ConsoleKeyInfo ('\0', ConsoleKey.Help, false, false, false);
1036 keymap [TermInfoStrings.KeyPrint] = new ConsoleKeyInfo ('\0', ConsoleKey.Print, false, false, false);
1037 keymap [TermInfoStrings.KeyUndo] = new ConsoleKeyInfo ('Z', ConsoleKey.Z , false, true, false);
1038 keymap [TermInfoStrings.KeySbeg] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, true, false, false);
1039 keymap [TermInfoStrings.KeyScopy] = new ConsoleKeyInfo ('C', ConsoleKey.C , true, true, false);
1040 keymap [TermInfoStrings.KeySdc] = new ConsoleKeyInfo ('\x9', ConsoleKey.Delete, true, false, false);
1041 keymap [TermInfoStrings.KeyShelp] = new ConsoleKeyInfo ('\0', ConsoleKey.Help, true, false, false);
1042 keymap [TermInfoStrings.KeyShome] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, true, false, false);
1043 keymap [TermInfoStrings.KeySleft] = new ConsoleKeyInfo ('\0', ConsoleKey.LeftArrow, true, false, false);
1044 keymap [TermInfoStrings.KeySprint] = new ConsoleKeyInfo ('\0', ConsoleKey.Print, true, false, false);
1045 keymap [TermInfoStrings.KeySright] = new ConsoleKeyInfo ('\0', ConsoleKey.RightArrow, true, false, false);
1046 keymap [TermInfoStrings.KeySundo] = new ConsoleKeyInfo ('Z', ConsoleKey.Z, true, false, false);
1047 keymap [TermInfoStrings.KeyF11] = new ConsoleKeyInfo ('\0', ConsoleKey.F11, false, false, false);
1048 keymap [TermInfoStrings.KeyF12] = new ConsoleKeyInfo ('\0', ConsoleKey.F12 , false, false, false);
1049 keymap [TermInfoStrings.KeyF13] = new ConsoleKeyInfo ('\0', ConsoleKey.F13, false, false, false);
1050 keymap [TermInfoStrings.KeyF14] = new ConsoleKeyInfo ('\0', ConsoleKey.F14, false, false, false);
1051 keymap [TermInfoStrings.KeyF15] = new ConsoleKeyInfo ('\0', ConsoleKey.F15, false, false, false);
1052 keymap [TermInfoStrings.KeyF16] = new ConsoleKeyInfo ('\0', ConsoleKey.F16, false, false, false);
1053 keymap [TermInfoStrings.KeyF17] = new ConsoleKeyInfo ('\0', ConsoleKey.F17, false, false, false);
1054 keymap [TermInfoStrings.KeyF18] = new ConsoleKeyInfo ('\0', ConsoleKey.F18, false, false, false);
1055 keymap [TermInfoStrings.KeyF19] = new ConsoleKeyInfo ('\0', ConsoleKey.F19, false, false, false);
1056 keymap [TermInfoStrings.KeyF20] = new ConsoleKeyInfo ('\0', ConsoleKey.F20, false, false, false);
1057 keymap [TermInfoStrings.KeyF21] = new ConsoleKeyInfo ('\0', ConsoleKey.F21, false, false, false);
1058 keymap [TermInfoStrings.KeyF22] = new ConsoleKeyInfo ('\0', ConsoleKey.F22, false, false, false);
1059 keymap [TermInfoStrings.KeyF23] = new ConsoleKeyInfo ('\0', ConsoleKey.F23, false, false, false);
1060 keymap [TermInfoStrings.KeyF24] = new ConsoleKeyInfo ('\0', ConsoleKey.F24, false, false, false);
1069 rootmap = new ByteMatcher ();
1070 AddStringMapping (TermInfoStrings.KeyBackspace);
1071 AddStringMapping (TermInfoStrings.KeyClear);
1072 AddStringMapping (TermInfoStrings.KeyDown);
1073 AddStringMapping (TermInfoStrings.KeyF1);
1074 AddStringMapping (TermInfoStrings.KeyF10);
1075 AddStringMapping (TermInfoStrings.KeyF2);
1076 AddStringMapping (TermInfoStrings.KeyF3);
1077 AddStringMapping (TermInfoStrings.KeyF4);
1078 AddStringMapping (TermInfoStrings.KeyF5);
1079 AddStringMapping (TermInfoStrings.KeyF6);
1080 AddStringMapping (TermInfoStrings.KeyF7);
1081 AddStringMapping (TermInfoStrings.KeyF8);
1082 AddStringMapping (TermInfoStrings.KeyF9);
1083 AddStringMapping (TermInfoStrings.KeyHome);
1084 AddStringMapping (TermInfoStrings.KeyLeft);
1085 AddStringMapping (TermInfoStrings.KeyLl);
1086 AddStringMapping (TermInfoStrings.KeyNpage);
1087 AddStringMapping (TermInfoStrings.KeyPpage);
1088 AddStringMapping (TermInfoStrings.KeyRight);
1089 AddStringMapping (TermInfoStrings.KeySf);
1090 AddStringMapping (TermInfoStrings.KeySr);
1091 AddStringMapping (TermInfoStrings.KeyUp);
1092 AddStringMapping (TermInfoStrings.KeyA1);
1093 AddStringMapping (TermInfoStrings.KeyA3);
1094 AddStringMapping (TermInfoStrings.KeyB2);
1095 AddStringMapping (TermInfoStrings.KeyC1);
1096 AddStringMapping (TermInfoStrings.KeyC3);
1097 AddStringMapping (TermInfoStrings.KeyBtab);
1098 AddStringMapping (TermInfoStrings.KeyBeg);
1099 AddStringMapping (TermInfoStrings.KeyCopy);
1100 AddStringMapping (TermInfoStrings.KeyEnd);
1101 AddStringMapping (TermInfoStrings.KeyEnter);
1102 AddStringMapping (TermInfoStrings.KeyHelp);
1103 AddStringMapping (TermInfoStrings.KeyPrint);
1104 AddStringMapping (TermInfoStrings.KeyUndo);
1105 AddStringMapping (TermInfoStrings.KeySbeg);
1106 AddStringMapping (TermInfoStrings.KeyScopy);
1107 AddStringMapping (TermInfoStrings.KeySdc);
1108 AddStringMapping (TermInfoStrings.KeyShelp);
1109 AddStringMapping (TermInfoStrings.KeyShome);
1110 AddStringMapping (TermInfoStrings.KeySleft);
1111 AddStringMapping (TermInfoStrings.KeySprint);
1112 AddStringMapping (TermInfoStrings.KeySright);
1113 AddStringMapping (TermInfoStrings.KeySundo);
1114 AddStringMapping (TermInfoStrings.KeyF11);
1115 AddStringMapping (TermInfoStrings.KeyF12);
1116 AddStringMapping (TermInfoStrings.KeyF13);
1117 AddStringMapping (TermInfoStrings.KeyF14);
1118 AddStringMapping (TermInfoStrings.KeyF15);
1119 AddStringMapping (TermInfoStrings.KeyF16);
1120 AddStringMapping (TermInfoStrings.KeyF17);
1121 AddStringMapping (TermInfoStrings.KeyF18);
1122 AddStringMapping (TermInfoStrings.KeyF19);
1123 AddStringMapping (TermInfoStrings.KeyF20);
1124 AddStringMapping (TermInfoStrings.KeyF21);
1125 AddStringMapping (TermInfoStrings.KeyF22);
1126 AddStringMapping (TermInfoStrings.KeyF23);
1127 AddStringMapping (TermInfoStrings.KeyF24);
1132 void AddStringMapping (TermInfoStrings s)
1134 byte [] bytes = reader.GetStringBytes (s);
1138 rootmap.AddMapping (s, bytes);
1143 Hashtable map = new Hashtable ();
1144 Hashtable starts = new Hashtable ();
1146 public void AddMapping (TermInfoStrings key, byte [] val)
1148 if (val.Length == 0)
1152 starts [(int) val [0]] = true;
1159 public bool StartsWith (int c)
1161 return (starts [c] != null);
1164 public TermInfoStrings Match (byte [] buffer, int offset, int length, out int used)
1166 foreach (byte [] bytes in map.Keys) {
1167 for (int i = 0; i < bytes.Length && i < length; i++) {
1168 if (bytes [i] != buffer [offset + i])
1171 if (bytes.Length - 1 == i) {
1172 used = bytes.Length;
1173 return (TermInfoStrings) map [bytes];
1179 return (TermInfoStrings) (-1);