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 (out bool fresh)
855 if ((o = GetKeyFromBuffer (true)) == null) {
857 if (ConsoleDriver.InternalKeyAvailable (150) > 0) {
859 AddToBuffer (stdin.ReadByte ());
860 } while (ConsoleDriver.InternalKeyAvailable (0) > 0);
862 if ((o = GetKeyFromBuffer (false)) != null)
865 AddToBuffer (stdin.ReadByte ());
868 o = GetKeyFromBuffer (true);
871 // freshly read character
874 // this char was pre-buffered (e.g. not fresh)
878 return (ConsoleKeyInfo) o;
881 public int Read ([In, Out] char [] dest, int index, int count)
883 CStreamWriter writer = Console.stdout as CStreamWriter;
886 int BoL = 0; // Beginning-of-Line marker (can't backspace beyond this)
891 sbuf = new StringBuilder ();
893 // consume buffered keys first (do not echo, these have already been echo'd)
895 if ((o = GetKeyFromBuffer (true)) == null)
898 key = (ConsoleKeyInfo) o;
901 if (key.Key != ConsoleKey.Backspace) {
902 if (key.Key == ConsoleKey.Enter)
906 } else if (sbuf.Length > BoL) {
911 // continue reading until Enter is hit
912 rl_startx = cursorLeft;
913 rl_starty = cursorTop;
916 key = ReadKeyInternal (out fresh);
919 if (key.Key != ConsoleKey.Backspace) {
920 if (key.Key == ConsoleKey.Enter)
924 } else if (sbuf.Length > BoL) {
931 // echo fresh keys back to the console
933 writer.WriteKey (key);
935 Console.stdout.Write (c);
937 } while (key.Key != ConsoleKey.Enter);
942 // copy up to count chars into dest
944 while (count > 0 && nread < sbuf.Length) {
945 dest[index + nread] = sbuf[nread];
950 // put the rest back into our key buffer
951 for (int i = nread; i < sbuf.Length; i++)
952 AddToBuffer (sbuf[i]);
957 public ConsoleKeyInfo ReadKey (bool intercept)
961 ConsoleKeyInfo key = ReadKeyInternal (out fresh);
963 if (!intercept && fresh) {
964 // echo the fresh key back to the console
965 CStreamWriter writer = Console.stdout as CStreamWriter;
968 writer.WriteKey (key);
970 Console.stdout.Write (key.KeyChar);
976 public string ReadLine ()
981 // Hack to make Iron Python work (since it goes behind our backs
982 // when writing to the console thus preventing us from keeping
983 // cursor state normally).
984 GetCursorPosition ();
986 CStreamWriter writer = Console.stdout as CStreamWriter;
987 StringBuilder builder = new StringBuilder ();
992 rl_startx = cursorLeft;
993 rl_starty = cursorTop;
996 key = ReadKeyInternal (out fresh);
998 if (key.Key != ConsoleKey.Enter) {
999 if (key.Key != ConsoleKey.Backspace)
1001 else if (builder.Length > 0)
1004 // skips over echoing the key to the console
1010 // echo fresh keys back to the console
1012 writer.WriteKey (key);
1014 Console.stdout.Write (c);
1016 } while (key.Key != ConsoleKey.Enter);
1021 return builder.ToString ();
1024 public void ResetColor ()
1030 string str = (origPair != null) ? origPair : origColors;
1034 public void SetBufferSize (int width, int height)
1040 throw new NotImplementedException (String.Empty);
1043 public void SetCursorPosition (int left, int top)
1049 if (bufferWidth == 0 && need_window_dimensions)
1050 GetWindowDimensions ();
1052 if (left < 0 || left >= bufferWidth)
1053 throw new ArgumentOutOfRangeException ("left", "Value must be positive and below the buffer width.");
1055 if (top < 0 || top >= bufferHeight)
1056 throw new ArgumentOutOfRangeException ("top", "Value must be positive and below the buffer height.");
1058 // Either CursorAddress or nothing.
1059 // We might want to play with up/down/left/right/home when ca is not available.
1060 if (cursorAddress == null)
1061 throw new NotSupportedException ("This terminal does not suport setting the cursor position.");
1063 int one = (home_1_1 ? 1 : 0);
1064 WriteConsole (String.Format (cursorAddress, top + one, left + one));
1069 public void SetWindowPosition (int left, int top)
1075 // No need to throw exceptions here.
1076 //throw new NotSupportedException ();
1079 public void SetWindowSize (int width, int height)
1085 // No need to throw exceptions here.
1086 //throw new NotSupportedException ();
1090 void CreateKeyMap ()
1092 keymap = new Hashtable ();
1093 keymap [TermInfoStrings.KeyBackspace] = new ConsoleKeyInfo ('\0', ConsoleKey.Backspace, false, false, false);
1094 keymap [TermInfoStrings.KeyClear] = new ConsoleKeyInfo ('\0', ConsoleKey.Clear, false, false, false);
1095 // Delete character...
1096 keymap [TermInfoStrings.KeyDown] = new ConsoleKeyInfo ('\0', ConsoleKey.DownArrow, false, false, false);
1097 keymap [TermInfoStrings.KeyF1] = new ConsoleKeyInfo ('\0', ConsoleKey.F1, false, false, false);
1098 keymap [TermInfoStrings.KeyF10] = new ConsoleKeyInfo ('\0', ConsoleKey.F10, false, false, false);
1099 keymap [TermInfoStrings.KeyF2] = new ConsoleKeyInfo ('\0', ConsoleKey.F2, false, false, false);
1100 keymap [TermInfoStrings.KeyF3] = new ConsoleKeyInfo ('\0', ConsoleKey.F3, false, false, false);
1101 keymap [TermInfoStrings.KeyF4] = new ConsoleKeyInfo ('\0', ConsoleKey.F4, false, false, false);
1102 keymap [TermInfoStrings.KeyF5] = new ConsoleKeyInfo ('\0', ConsoleKey.F5, false, false, false);
1103 keymap [TermInfoStrings.KeyF6] = new ConsoleKeyInfo ('\0', ConsoleKey.F6, false, false, false);
1104 keymap [TermInfoStrings.KeyF7] = new ConsoleKeyInfo ('\0', ConsoleKey.F7, false, false, false);
1105 keymap [TermInfoStrings.KeyF8] = new ConsoleKeyInfo ('\0', ConsoleKey.F8, false, false, false);
1106 keymap [TermInfoStrings.KeyF9] = new ConsoleKeyInfo ('\0', ConsoleKey.F9, false, false, false);
1107 keymap [TermInfoStrings.KeyHome] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, false, false, false);
1109 keymap [TermInfoStrings.KeyLeft] = new ConsoleKeyInfo ('\0', ConsoleKey.LeftArrow, false, false, false);
1110 keymap [TermInfoStrings.KeyLl] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad1, false, false, false);
1111 keymap [TermInfoStrings.KeyNpage] = new ConsoleKeyInfo ('\0', ConsoleKey.PageDown, false, false, false);
1112 keymap [TermInfoStrings.KeyPpage] = new ConsoleKeyInfo ('\0', ConsoleKey.PageUp, false, false, false);
1113 keymap [TermInfoStrings.KeyRight] = new ConsoleKeyInfo ('\0', ConsoleKey.RightArrow, false, false, false);
1114 keymap [TermInfoStrings.KeySf] = new ConsoleKeyInfo ('\0', ConsoleKey.PageDown, false, false, false);
1115 keymap [TermInfoStrings.KeySr] = new ConsoleKeyInfo ('\0', ConsoleKey.PageUp, false, false, false);
1116 keymap [TermInfoStrings.KeyUp] = new ConsoleKeyInfo ('\0', ConsoleKey.UpArrow, false, false, false);
1117 keymap [TermInfoStrings.KeyA1] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad7, false, false, false);
1118 keymap [TermInfoStrings.KeyA3] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad9, false, false, false);
1119 keymap [TermInfoStrings.KeyB2] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad5, false, false, false);
1120 keymap [TermInfoStrings.KeyC1] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad1, false, false, false);
1121 keymap [TermInfoStrings.KeyC3] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad3, false, false, false);
1122 keymap [TermInfoStrings.KeyBtab] = new ConsoleKeyInfo ('\0', ConsoleKey.Tab, true, false, false);
1123 keymap [TermInfoStrings.KeyBeg] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, false, false, false);
1124 keymap [TermInfoStrings.KeyCopy] = new ConsoleKeyInfo ('C', ConsoleKey.C, false, true, false);
1125 keymap [TermInfoStrings.KeyEnd] = new ConsoleKeyInfo ('\0', ConsoleKey.End, false, false, false);
1126 keymap [TermInfoStrings.KeyEnter] = new ConsoleKeyInfo ('\n', ConsoleKey.Enter, false, false, false);
1127 keymap [TermInfoStrings.KeyHelp] = new ConsoleKeyInfo ('\0', ConsoleKey.Help, false, false, false);
1128 keymap [TermInfoStrings.KeyPrint] = new ConsoleKeyInfo ('\0', ConsoleKey.Print, false, false, false);
1129 keymap [TermInfoStrings.KeyUndo] = new ConsoleKeyInfo ('Z', ConsoleKey.Z , false, true, false);
1130 keymap [TermInfoStrings.KeySbeg] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, true, false, false);
1131 keymap [TermInfoStrings.KeyScopy] = new ConsoleKeyInfo ('C', ConsoleKey.C , true, true, false);
1132 keymap [TermInfoStrings.KeySdc] = new ConsoleKeyInfo ('\x9', ConsoleKey.Delete, true, false, false);
1133 keymap [TermInfoStrings.KeyShelp] = new ConsoleKeyInfo ('\0', ConsoleKey.Help, true, false, false);
1134 keymap [TermInfoStrings.KeyShome] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, true, false, false);
1135 keymap [TermInfoStrings.KeySleft] = new ConsoleKeyInfo ('\0', ConsoleKey.LeftArrow, true, false, false);
1136 keymap [TermInfoStrings.KeySprint] = new ConsoleKeyInfo ('\0', ConsoleKey.Print, true, false, false);
1137 keymap [TermInfoStrings.KeySright] = new ConsoleKeyInfo ('\0', ConsoleKey.RightArrow, true, false, false);
1138 keymap [TermInfoStrings.KeySundo] = new ConsoleKeyInfo ('Z', ConsoleKey.Z, true, false, false);
1139 keymap [TermInfoStrings.KeyF11] = new ConsoleKeyInfo ('\0', ConsoleKey.F11, false, false, false);
1140 keymap [TermInfoStrings.KeyF12] = new ConsoleKeyInfo ('\0', ConsoleKey.F12 , false, false, false);
1141 keymap [TermInfoStrings.KeyF13] = new ConsoleKeyInfo ('\0', ConsoleKey.F13, false, false, false);
1142 keymap [TermInfoStrings.KeyF14] = new ConsoleKeyInfo ('\0', ConsoleKey.F14, false, false, false);
1143 keymap [TermInfoStrings.KeyF15] = new ConsoleKeyInfo ('\0', ConsoleKey.F15, false, false, false);
1144 keymap [TermInfoStrings.KeyF16] = new ConsoleKeyInfo ('\0', ConsoleKey.F16, false, false, false);
1145 keymap [TermInfoStrings.KeyF17] = new ConsoleKeyInfo ('\0', ConsoleKey.F17, false, false, false);
1146 keymap [TermInfoStrings.KeyF18] = new ConsoleKeyInfo ('\0', ConsoleKey.F18, false, false, false);
1147 keymap [TermInfoStrings.KeyF19] = new ConsoleKeyInfo ('\0', ConsoleKey.F19, false, false, false);
1148 keymap [TermInfoStrings.KeyF20] = new ConsoleKeyInfo ('\0', ConsoleKey.F20, false, false, false);
1149 keymap [TermInfoStrings.KeyF21] = new ConsoleKeyInfo ('\0', ConsoleKey.F21, false, false, false);
1150 keymap [TermInfoStrings.KeyF22] = new ConsoleKeyInfo ('\0', ConsoleKey.F22, false, false, false);
1151 keymap [TermInfoStrings.KeyF23] = new ConsoleKeyInfo ('\0', ConsoleKey.F23, false, false, false);
1152 keymap [TermInfoStrings.KeyF24] = new ConsoleKeyInfo ('\0', ConsoleKey.F24, false, false, false);
1161 rootmap = new ByteMatcher ();
1162 AddStringMapping (TermInfoStrings.KeyBackspace);
1163 AddStringMapping (TermInfoStrings.KeyClear);
1164 AddStringMapping (TermInfoStrings.KeyDown);
1165 AddStringMapping (TermInfoStrings.KeyF1);
1166 AddStringMapping (TermInfoStrings.KeyF10);
1167 AddStringMapping (TermInfoStrings.KeyF2);
1168 AddStringMapping (TermInfoStrings.KeyF3);
1169 AddStringMapping (TermInfoStrings.KeyF4);
1170 AddStringMapping (TermInfoStrings.KeyF5);
1171 AddStringMapping (TermInfoStrings.KeyF6);
1172 AddStringMapping (TermInfoStrings.KeyF7);
1173 AddStringMapping (TermInfoStrings.KeyF8);
1174 AddStringMapping (TermInfoStrings.KeyF9);
1175 AddStringMapping (TermInfoStrings.KeyHome);
1176 AddStringMapping (TermInfoStrings.KeyLeft);
1177 AddStringMapping (TermInfoStrings.KeyLl);
1178 AddStringMapping (TermInfoStrings.KeyNpage);
1179 AddStringMapping (TermInfoStrings.KeyPpage);
1180 AddStringMapping (TermInfoStrings.KeyRight);
1181 AddStringMapping (TermInfoStrings.KeySf);
1182 AddStringMapping (TermInfoStrings.KeySr);
1183 AddStringMapping (TermInfoStrings.KeyUp);
1184 AddStringMapping (TermInfoStrings.KeyA1);
1185 AddStringMapping (TermInfoStrings.KeyA3);
1186 AddStringMapping (TermInfoStrings.KeyB2);
1187 AddStringMapping (TermInfoStrings.KeyC1);
1188 AddStringMapping (TermInfoStrings.KeyC3);
1189 AddStringMapping (TermInfoStrings.KeyBtab);
1190 AddStringMapping (TermInfoStrings.KeyBeg);
1191 AddStringMapping (TermInfoStrings.KeyCopy);
1192 AddStringMapping (TermInfoStrings.KeyEnd);
1193 AddStringMapping (TermInfoStrings.KeyEnter);
1194 AddStringMapping (TermInfoStrings.KeyHelp);
1195 AddStringMapping (TermInfoStrings.KeyPrint);
1196 AddStringMapping (TermInfoStrings.KeyUndo);
1197 AddStringMapping (TermInfoStrings.KeySbeg);
1198 AddStringMapping (TermInfoStrings.KeyScopy);
1199 AddStringMapping (TermInfoStrings.KeySdc);
1200 AddStringMapping (TermInfoStrings.KeyShelp);
1201 AddStringMapping (TermInfoStrings.KeyShome);
1202 AddStringMapping (TermInfoStrings.KeySleft);
1203 AddStringMapping (TermInfoStrings.KeySprint);
1204 AddStringMapping (TermInfoStrings.KeySright);
1205 AddStringMapping (TermInfoStrings.KeySundo);
1206 AddStringMapping (TermInfoStrings.KeyF11);
1207 AddStringMapping (TermInfoStrings.KeyF12);
1208 AddStringMapping (TermInfoStrings.KeyF13);
1209 AddStringMapping (TermInfoStrings.KeyF14);
1210 AddStringMapping (TermInfoStrings.KeyF15);
1211 AddStringMapping (TermInfoStrings.KeyF16);
1212 AddStringMapping (TermInfoStrings.KeyF17);
1213 AddStringMapping (TermInfoStrings.KeyF18);
1214 AddStringMapping (TermInfoStrings.KeyF19);
1215 AddStringMapping (TermInfoStrings.KeyF20);
1216 AddStringMapping (TermInfoStrings.KeyF21);
1217 AddStringMapping (TermInfoStrings.KeyF22);
1218 AddStringMapping (TermInfoStrings.KeyF23);
1219 AddStringMapping (TermInfoStrings.KeyF24);
1224 void AddStringMapping (TermInfoStrings s)
1226 byte [] bytes = reader.GetStringBytes (s);
1230 rootmap.AddMapping (s, bytes);
1235 Hashtable map = new Hashtable ();
1236 Hashtable starts = new Hashtable ();
1238 public void AddMapping (TermInfoStrings key, byte [] val)
1240 if (val.Length == 0)
1244 starts [(int) val [0]] = true;
1251 public bool StartsWith (int c)
1253 return (starts [c] != null);
1256 public TermInfoStrings Match (byte [] buffer, int offset, int length, out int used)
1258 foreach (byte [] bytes in map.Keys) {
1259 for (int i = 0; i < bytes.Length && i < length; i++) {
1260 if (bytes [i] != buffer [offset + i])
1263 if (bytes.Length - 1 == i) {
1264 used = bytes.Length;
1265 return (TermInfoStrings) map [bytes];
1271 return (TermInfoStrings) (-1);