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 void GetCursorPosition ()
398 int row = 0, col = 0;
400 WriteConsole ("\x1b[6n");
401 if (ConsoleDriver.InternalKeyAvailable (1000) <= 0) {
402 noGetPosition = true;
406 int b = stdin.ReadByte ();
407 while (b != '\x1b') {
409 if (ConsoleDriver.InternalKeyAvailable (100) <= 0)
411 b = stdin.ReadByte ();
414 b = stdin.ReadByte ();
416 AddToBuffer ('\x1b');
421 b = stdin.ReadByte ();
424 b = stdin.ReadByte ();
425 while ((b >= '0') && (b <= '9')) {
426 row = row * 10 + b - '0';
427 b = stdin.ReadByte ();
429 // Row/col is 0 based
433 b = stdin.ReadByte ();
436 b = stdin.ReadByte ();
437 while ((b >= '0') && (b <= '9')) {
438 col = col * 10 + b - '0';
439 b = stdin.ReadByte ();
441 // Row/col is 0 based
446 logger.WriteLine ("GetCursorPosition: {0}, {1}", col, row);
454 public int BufferHeight {
467 throw new NotSupportedException ();
471 public int BufferWidth {
484 throw new NotSupportedException ();
488 public bool CapsLock {
494 throw new NotSupportedException ();
498 public int CursorLeft {
511 SetCursorPosition (value, CursorTop);
515 public int CursorTop {
528 SetCursorPosition (CursorLeft, value);
532 public bool CursorVisible {
538 return cursorVisible;
545 cursorVisible = value;
546 WriteConsole ((value ? csrVisible : csrInvisible));
550 // we have CursorNormal vs. CursorVisible...
552 public int CursorSize {
567 public bool KeyAvailable {
573 return (writepos > readpos || ConsoleDriver.InternalKeyAvailable (0) > 0);
577 // We don't know these next 2 values, so return something reasonable
578 public int LargestWindowHeight {
579 get { return WindowHeight; }
582 public int LargestWindowWidth {
583 get { return WindowWidth; }
586 public bool NumberLock {
592 throw new NotSupportedException ();
596 public string Title {
610 WriteConsole (String.Format (titleFormat, value));
614 public bool TreatControlCAsInput {
619 return controlCAsInput;
626 if (controlCAsInput == value)
629 ConsoleDriver.SetBreak (value);
630 controlCAsInput = value;
634 void GetWindowDimensions ()
636 /* Try the ioctl first */
637 if (!ConsoleDriver.GetTtySize (MonoIO.ConsoleOutput, out windowWidth, out windowHeight)) {
638 windowWidth = reader.Get (TermInfoNumbers.Columns);
639 string env = Environment.GetEnvironmentVariable ("COLUMNS");
642 windowWidth = (int) UInt32.Parse (env);
647 windowHeight = reader.Get (TermInfoNumbers.Lines);
648 env = Environment.GetEnvironmentVariable ("LINES");
651 windowHeight = (int) UInt32.Parse (env);
657 bufferHeight = windowHeight;
658 bufferWidth = windowWidth;
659 need_window_dimensions = false;
662 public int WindowHeight {
668 if (need_window_dimensions)
669 GetWindowDimensions ();
677 throw new NotSupportedException ();
681 public int WindowLeft {
687 //GetWindowDimensions ();
695 throw new NotSupportedException ();
699 public int WindowTop {
705 //GetWindowDimensions ();
713 throw new NotSupportedException ();
717 public int WindowWidth {
723 if (need_window_dimensions)
724 GetWindowDimensions ();
732 throw new NotSupportedException ();
742 WriteConsole (clear);
745 public void Beep (int frequency, int duration)
754 public void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
755 int targetLeft, int targetTop, Char sourceChar,
756 ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
762 throw new NotImplementedException ();
765 void AddToBuffer (int b)
767 if (buffer == null) {
768 buffer = new byte [1024];
769 } else if (writepos >= buffer.Length) {
770 byte [] newbuf = new byte [buffer.Length * 2];
771 Buffer.BlockCopy (buffer, 0, newbuf, 0, buffer.Length);
775 buffer [writepos++] = (byte) b;
780 if (readpos >= writepos) {
781 readpos = writepos = 0;
785 ConsoleKeyInfo CreateKeyInfoFromInt (int n)
788 ConsoleKey key = (ConsoleKey)n;
794 key = ConsoleKey.Enter;
795 } else if (n == 8 || n == 9 || n == 12 || n == 13 || n == 19) {
796 /* Values in ConsoleKey */
797 } else if (n >= 1 && n <= 26) {
798 // For Ctrl-a to Ctrl-z.
800 key = ConsoleKey.A + n - 1;
801 } else if (n == 27) {
802 key = ConsoleKey.Escape;
803 } else if (n >= 'a' && n <= 'z') {
804 key = ConsoleKey.A - 'a' + n;
805 } else if (n >= 'A' && n <= 'Z') {
807 } else if (n >= '0' && n <= '9') {
812 return new ConsoleKeyInfo (c, key, shift, alt, ctrl);
815 object GetKeyFromBuffer (bool cooked)
817 if (readpos >= writepos)
820 int next = buffer [readpos];
821 if (!cooked || !rootmap.StartsWith (next)) {
824 return CreateKeyInfoFromInt (next);
828 TermInfoStrings str = rootmap.Match (buffer, readpos, writepos - readpos, out used);
833 if (keymap [str] != null) {
834 key = (ConsoleKeyInfo) keymap [str];
838 return CreateKeyInfoFromInt (next);
846 ConsoleKeyInfo ReadKeyInternal ()
855 o = GetKeyFromBuffer (true);
857 if (ConsoleDriver.InternalKeyAvailable (150) > 0) {
859 AddToBuffer (stdin.ReadByte ());
860 } while (ConsoleDriver.InternalKeyAvailable (0) > 0);
862 o = GetKeyFromBuffer (false);
864 AddToBuffer (stdin.ReadByte ());
869 return (ConsoleKeyInfo) o;
872 public ConsoleKeyInfo ReadKey (bool intercept)
877 ConsoleKeyInfo key = ReadKeyInternal ();
880 // echo the key back to the console
881 CStreamWriter writer = Console.stdout as CStreamWriter;
884 writer.WriteKey (key);
886 Console.stdout.Write (key.KeyChar);
892 public string ReadLine ()
897 // Hack to make Iron Python work (since it goes behind our backs
898 // when writing to the console thus preventing us from keeping
899 // cursor state normally).
900 GetCursorPosition ();
902 StringBuilder builder = new StringBuilder ();
904 CStreamWriter writer = Console.stdout as CStreamWriter;
905 rl_startx = cursorLeft;
906 rl_starty = cursorTop;
908 ConsoleKeyInfo key = ReadKeyInternal ();
909 char c = key.KeyChar;
912 if (key.Key != ConsoleKey.Backspace)
914 else if (builder.Length > 0)
917 // skips over echoing the key to the console
922 // echo the key back to the console
924 writer.WriteKey (key);
926 Console.stdout.Write (c);
931 return builder.ToString ();
934 public void ResetColor ()
940 string str = (origPair != null) ? origPair : origColors;
944 public void SetBufferSize (int width, int height)
950 throw new NotImplementedException (String.Empty);
953 public void SetCursorPosition (int left, int top)
959 if (bufferWidth == 0 && need_window_dimensions)
960 GetWindowDimensions ();
962 if (left < 0 || left >= bufferWidth)
963 throw new ArgumentOutOfRangeException ("left", "Value must be positive and below the buffer width.");
965 if (top < 0 || top >= bufferHeight)
966 throw new ArgumentOutOfRangeException ("top", "Value must be positive and below the buffer height.");
968 // Either CursorAddress or nothing.
969 // We might want to play with up/down/left/right/home when ca is not available.
970 if (cursorAddress == null)
971 throw new NotSupportedException ("This terminal does not suport setting the cursor position.");
973 int one = (home_1_1 ? 1 : 0);
974 WriteConsole (String.Format (cursorAddress, top + one, left + one));
979 public void SetWindowPosition (int left, int top)
985 // No need to throw exceptions here.
986 //throw new NotSupportedException ();
989 public void SetWindowSize (int width, int height)
995 // No need to throw exceptions here.
996 //throw new NotSupportedException ();
1000 void CreateKeyMap ()
1002 keymap = new Hashtable ();
1003 keymap [TermInfoStrings.KeyBackspace] = new ConsoleKeyInfo ('\0', ConsoleKey.Backspace, false, false, false);
1004 keymap [TermInfoStrings.KeyClear] = new ConsoleKeyInfo ('\0', ConsoleKey.Clear, false, false, false);
1005 // Delete character...
1006 keymap [TermInfoStrings.KeyDown] = new ConsoleKeyInfo ('\0', ConsoleKey.DownArrow, false, false, false);
1007 keymap [TermInfoStrings.KeyF1] = new ConsoleKeyInfo ('\0', ConsoleKey.F1, false, false, false);
1008 keymap [TermInfoStrings.KeyF10] = new ConsoleKeyInfo ('\0', ConsoleKey.F10, false, false, false);
1009 keymap [TermInfoStrings.KeyF2] = new ConsoleKeyInfo ('\0', ConsoleKey.F2, false, false, false);
1010 keymap [TermInfoStrings.KeyF3] = new ConsoleKeyInfo ('\0', ConsoleKey.F3, false, false, false);
1011 keymap [TermInfoStrings.KeyF4] = new ConsoleKeyInfo ('\0', ConsoleKey.F4, false, false, false);
1012 keymap [TermInfoStrings.KeyF5] = new ConsoleKeyInfo ('\0', ConsoleKey.F5, false, false, false);
1013 keymap [TermInfoStrings.KeyF6] = new ConsoleKeyInfo ('\0', ConsoleKey.F6, false, false, false);
1014 keymap [TermInfoStrings.KeyF7] = new ConsoleKeyInfo ('\0', ConsoleKey.F7, false, false, false);
1015 keymap [TermInfoStrings.KeyF8] = new ConsoleKeyInfo ('\0', ConsoleKey.F8, false, false, false);
1016 keymap [TermInfoStrings.KeyF9] = new ConsoleKeyInfo ('\0', ConsoleKey.F9, false, false, false);
1017 keymap [TermInfoStrings.KeyHome] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, false, false, false);
1019 keymap [TermInfoStrings.KeyLeft] = new ConsoleKeyInfo ('\0', ConsoleKey.LeftArrow, false, false, false);
1020 keymap [TermInfoStrings.KeyLl] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad1, false, false, false);
1021 keymap [TermInfoStrings.KeyNpage] = new ConsoleKeyInfo ('\0', ConsoleKey.PageDown, false, false, false);
1022 keymap [TermInfoStrings.KeyPpage] = new ConsoleKeyInfo ('\0', ConsoleKey.PageUp, false, false, false);
1023 keymap [TermInfoStrings.KeyRight] = new ConsoleKeyInfo ('\0', ConsoleKey.RightArrow, false, false, false);
1024 keymap [TermInfoStrings.KeySf] = new ConsoleKeyInfo ('\0', ConsoleKey.PageDown, false, false, false);
1025 keymap [TermInfoStrings.KeySr] = new ConsoleKeyInfo ('\0', ConsoleKey.PageUp, false, false, false);
1026 keymap [TermInfoStrings.KeyUp] = new ConsoleKeyInfo ('\0', ConsoleKey.UpArrow, false, false, false);
1027 keymap [TermInfoStrings.KeyA1] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad7, false, false, false);
1028 keymap [TermInfoStrings.KeyA3] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad9, false, false, false);
1029 keymap [TermInfoStrings.KeyB2] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad5, false, false, false);
1030 keymap [TermInfoStrings.KeyC1] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad1, false, false, false);
1031 keymap [TermInfoStrings.KeyC3] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad3, false, false, false);
1032 keymap [TermInfoStrings.KeyBtab] = new ConsoleKeyInfo ('\0', ConsoleKey.Tab, true, false, false);
1033 keymap [TermInfoStrings.KeyBeg] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, false, false, false);
1034 keymap [TermInfoStrings.KeyCopy] = new ConsoleKeyInfo ('C', ConsoleKey.C, false, true, false);
1035 keymap [TermInfoStrings.KeyEnd] = new ConsoleKeyInfo ('\0', ConsoleKey.End, false, false, false);
1036 keymap [TermInfoStrings.KeyEnter] = new ConsoleKeyInfo ('\n', ConsoleKey.Enter, false, false, false);
1037 keymap [TermInfoStrings.KeyHelp] = new ConsoleKeyInfo ('\0', ConsoleKey.Help, false, false, false);
1038 keymap [TermInfoStrings.KeyPrint] = new ConsoleKeyInfo ('\0', ConsoleKey.Print, false, false, false);
1039 keymap [TermInfoStrings.KeyUndo] = new ConsoleKeyInfo ('Z', ConsoleKey.Z , false, true, false);
1040 keymap [TermInfoStrings.KeySbeg] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, true, false, false);
1041 keymap [TermInfoStrings.KeyScopy] = new ConsoleKeyInfo ('C', ConsoleKey.C , true, true, false);
1042 keymap [TermInfoStrings.KeySdc] = new ConsoleKeyInfo ('\x9', ConsoleKey.Delete, true, false, false);
1043 keymap [TermInfoStrings.KeyShelp] = new ConsoleKeyInfo ('\0', ConsoleKey.Help, true, false, false);
1044 keymap [TermInfoStrings.KeyShome] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, true, false, false);
1045 keymap [TermInfoStrings.KeySleft] = new ConsoleKeyInfo ('\0', ConsoleKey.LeftArrow, true, false, false);
1046 keymap [TermInfoStrings.KeySprint] = new ConsoleKeyInfo ('\0', ConsoleKey.Print, true, false, false);
1047 keymap [TermInfoStrings.KeySright] = new ConsoleKeyInfo ('\0', ConsoleKey.RightArrow, true, false, false);
1048 keymap [TermInfoStrings.KeySundo] = new ConsoleKeyInfo ('Z', ConsoleKey.Z, true, false, false);
1049 keymap [TermInfoStrings.KeyF11] = new ConsoleKeyInfo ('\0', ConsoleKey.F11, false, false, false);
1050 keymap [TermInfoStrings.KeyF12] = new ConsoleKeyInfo ('\0', ConsoleKey.F12 , false, false, false);
1051 keymap [TermInfoStrings.KeyF13] = new ConsoleKeyInfo ('\0', ConsoleKey.F13, false, false, false);
1052 keymap [TermInfoStrings.KeyF14] = new ConsoleKeyInfo ('\0', ConsoleKey.F14, false, false, false);
1053 keymap [TermInfoStrings.KeyF15] = new ConsoleKeyInfo ('\0', ConsoleKey.F15, false, false, false);
1054 keymap [TermInfoStrings.KeyF16] = new ConsoleKeyInfo ('\0', ConsoleKey.F16, false, false, false);
1055 keymap [TermInfoStrings.KeyF17] = new ConsoleKeyInfo ('\0', ConsoleKey.F17, false, false, false);
1056 keymap [TermInfoStrings.KeyF18] = new ConsoleKeyInfo ('\0', ConsoleKey.F18, false, false, false);
1057 keymap [TermInfoStrings.KeyF19] = new ConsoleKeyInfo ('\0', ConsoleKey.F19, false, false, false);
1058 keymap [TermInfoStrings.KeyF20] = new ConsoleKeyInfo ('\0', ConsoleKey.F20, false, false, false);
1059 keymap [TermInfoStrings.KeyF21] = new ConsoleKeyInfo ('\0', ConsoleKey.F21, false, false, false);
1060 keymap [TermInfoStrings.KeyF22] = new ConsoleKeyInfo ('\0', ConsoleKey.F22, false, false, false);
1061 keymap [TermInfoStrings.KeyF23] = new ConsoleKeyInfo ('\0', ConsoleKey.F23, false, false, false);
1062 keymap [TermInfoStrings.KeyF24] = new ConsoleKeyInfo ('\0', ConsoleKey.F24, false, false, false);
1071 rootmap = new ByteMatcher ();
1072 AddStringMapping (TermInfoStrings.KeyBackspace);
1073 AddStringMapping (TermInfoStrings.KeyClear);
1074 AddStringMapping (TermInfoStrings.KeyDown);
1075 AddStringMapping (TermInfoStrings.KeyF1);
1076 AddStringMapping (TermInfoStrings.KeyF10);
1077 AddStringMapping (TermInfoStrings.KeyF2);
1078 AddStringMapping (TermInfoStrings.KeyF3);
1079 AddStringMapping (TermInfoStrings.KeyF4);
1080 AddStringMapping (TermInfoStrings.KeyF5);
1081 AddStringMapping (TermInfoStrings.KeyF6);
1082 AddStringMapping (TermInfoStrings.KeyF7);
1083 AddStringMapping (TermInfoStrings.KeyF8);
1084 AddStringMapping (TermInfoStrings.KeyF9);
1085 AddStringMapping (TermInfoStrings.KeyHome);
1086 AddStringMapping (TermInfoStrings.KeyLeft);
1087 AddStringMapping (TermInfoStrings.KeyLl);
1088 AddStringMapping (TermInfoStrings.KeyNpage);
1089 AddStringMapping (TermInfoStrings.KeyPpage);
1090 AddStringMapping (TermInfoStrings.KeyRight);
1091 AddStringMapping (TermInfoStrings.KeySf);
1092 AddStringMapping (TermInfoStrings.KeySr);
1093 AddStringMapping (TermInfoStrings.KeyUp);
1094 AddStringMapping (TermInfoStrings.KeyA1);
1095 AddStringMapping (TermInfoStrings.KeyA3);
1096 AddStringMapping (TermInfoStrings.KeyB2);
1097 AddStringMapping (TermInfoStrings.KeyC1);
1098 AddStringMapping (TermInfoStrings.KeyC3);
1099 AddStringMapping (TermInfoStrings.KeyBtab);
1100 AddStringMapping (TermInfoStrings.KeyBeg);
1101 AddStringMapping (TermInfoStrings.KeyCopy);
1102 AddStringMapping (TermInfoStrings.KeyEnd);
1103 AddStringMapping (TermInfoStrings.KeyEnter);
1104 AddStringMapping (TermInfoStrings.KeyHelp);
1105 AddStringMapping (TermInfoStrings.KeyPrint);
1106 AddStringMapping (TermInfoStrings.KeyUndo);
1107 AddStringMapping (TermInfoStrings.KeySbeg);
1108 AddStringMapping (TermInfoStrings.KeyScopy);
1109 AddStringMapping (TermInfoStrings.KeySdc);
1110 AddStringMapping (TermInfoStrings.KeyShelp);
1111 AddStringMapping (TermInfoStrings.KeyShome);
1112 AddStringMapping (TermInfoStrings.KeySleft);
1113 AddStringMapping (TermInfoStrings.KeySprint);
1114 AddStringMapping (TermInfoStrings.KeySright);
1115 AddStringMapping (TermInfoStrings.KeySundo);
1116 AddStringMapping (TermInfoStrings.KeyF11);
1117 AddStringMapping (TermInfoStrings.KeyF12);
1118 AddStringMapping (TermInfoStrings.KeyF13);
1119 AddStringMapping (TermInfoStrings.KeyF14);
1120 AddStringMapping (TermInfoStrings.KeyF15);
1121 AddStringMapping (TermInfoStrings.KeyF16);
1122 AddStringMapping (TermInfoStrings.KeyF17);
1123 AddStringMapping (TermInfoStrings.KeyF18);
1124 AddStringMapping (TermInfoStrings.KeyF19);
1125 AddStringMapping (TermInfoStrings.KeyF20);
1126 AddStringMapping (TermInfoStrings.KeyF21);
1127 AddStringMapping (TermInfoStrings.KeyF22);
1128 AddStringMapping (TermInfoStrings.KeyF23);
1129 AddStringMapping (TermInfoStrings.KeyF24);
1134 void AddStringMapping (TermInfoStrings s)
1136 byte [] bytes = reader.GetStringBytes (s);
1140 rootmap.AddMapping (s, bytes);
1145 Hashtable map = new Hashtable ();
1146 Hashtable starts = new Hashtable ();
1148 public void AddMapping (TermInfoStrings key, byte [] val)
1150 if (val.Length == 0)
1154 starts [(int) val [0]] = true;
1161 public bool StartsWith (int c)
1163 return (starts [c] != null);
1166 public TermInfoStrings Match (byte [] buffer, int offset, int length, out int used)
1168 foreach (byte [] bytes in map.Keys) {
1169 for (int i = 0; i < bytes.Length && i < length; i++) {
1170 if (bytes [i] != buffer [offset + i])
1173 if (bytes.Length - 1 == i) {
1174 used = bytes.Length;
1175 return (TermInfoStrings) map [bytes];
1181 return (TermInfoStrings) (-1);