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.
31 using System.Collections;
34 using System.Runtime.InteropServices;
36 class TermInfoDriver : IConsoleDriver {
37 static string [] locations = { "/etc/terminfo", "/usr/share/terminfo", "/usr/lib/terminfo" };
39 TermInfoReader reader;
42 string title = String.Empty;
43 string titleFormat = String.Empty;
44 bool cursorVisible = true;
65 string keypadXmit, keypadLocal;
73 ConsoleColor fgcolor = ConsoleColor.White;
74 ConsoleColor bgcolor = ConsoleColor.Black;
75 string setafcolor; // TODO: use setforeground/setbackground if available for better
76 string setabcolor; // color mapping.
80 bool home_1_1; // if true, we have to add 1 to x and y when using cursorAddress
82 static string SearchTerminfo (string term)
84 if (term == null || term == String.Empty)
87 // Ignore TERMINFO and TERMINFO_DIRS by now
88 //string terminfo = Environment.GetEnvironmentVariable ("TERMINFO");
89 //string terminfoDirs = Environment.GetEnvironmentVariable ("TERMINFO_DIRS");
91 foreach (string dir in locations) {
92 if (!Directory.Exists (dir))
95 string path = Path.Combine (dir, term.Substring (0, 1));
96 if (!Directory.Exists (dir))
99 path = Path.Combine (path, term);
100 if (!File.Exists (path))
109 static void WriteConsole (string str)
114 ((CStreamWriter) Console.stdout).InternalWriteString (str);
117 public TermInfoDriver ()
118 : this (Environment.GetEnvironmentVariable ("TERM"))
122 public TermInfoDriver (string term)
126 if (term == "xterm") {
127 reader = new TermInfoReader (term, KnownTerminals.xterm);
128 } else if (term == "linux") {
129 reader = new TermInfoReader (term, KnownTerminals.linux);
131 string filename = SearchTerminfo (term);
132 if (filename != null)
133 reader = new TermInfoReader (term, filename);
137 reader = new TermInfoReader (term, KnownTerminals.ansi);
140 public bool Initialized {
141 get { return inited; }
149 /* This should not happen any more, since it is checked for in Console */
150 if (!ConsoleDriver.IsConsole)
151 throw new IOException ("Not a tty.");
154 ConsoleDriver.SetEcho (false);
155 string endString = null;
156 keypadXmit = reader.Get (TermInfoStrings.KeypadXmit);
157 keypadLocal = reader.Get (TermInfoStrings.KeypadLocal);
158 if (keypadXmit != null) {
159 WriteConsole (keypadXmit); // Needed to get the arrows working
160 if (keypadLocal != null)
161 endString += keypadLocal;
164 origPair = reader.Get (TermInfoStrings.OrigPair);
165 origColors = reader.Get (TermInfoStrings.OrigColors);
166 setafcolor = MangleParameters (reader.Get (TermInfoStrings.SetAForeground));
167 setabcolor = MangleParameters (reader.Get (TermInfoStrings.SetABackground));
168 string resetColors = (origColors == null) ? origPair : origColors;
169 if (resetColors != null)
170 endString += resetColors;
172 if (!ConsoleDriver.TtySetup (endString, out verase, out vsusp, out intr))
173 throw new IOException ("Error initializing terminal.");
175 stdin = Console.OpenStandardInput (0);
176 clear = reader.Get (TermInfoStrings.ClearScreen);
177 bell = reader.Get (TermInfoStrings.Bell);
179 clear = reader.Get (TermInfoStrings.CursorHome);
180 clear += reader.Get (TermInfoStrings.ClrEos);
183 csrVisible = reader.Get (TermInfoStrings.CursorNormal);
184 if (csrVisible == null)
185 csrVisible = reader.Get (TermInfoStrings.CursorVisible);
187 csrInvisible = reader.Get (TermInfoStrings.CursorInvisible);
188 if (term == "cygwin" || term == "linux" || term.StartsWith ("xterm") ||
189 term == "rxvt" || term == "dtterm") {
190 titleFormat = "\x1b]0;{0}\x7"; // icon + window title
191 } else if (term == "iris-ansi") {
192 titleFormat = "\x1bP1.y{0}\x1b\\"; // not tested
193 } else if (term == "sun-cmd") {
194 titleFormat = "\x1b]l{0}\x1b\\"; // not tested
197 cursorAddress = reader.Get (TermInfoStrings.CursorAddress);
198 if (cursorAddress != null) {
199 string result = cursorAddress.Replace ("%i", String.Empty);
200 home_1_1 = (cursorAddress != result);
201 cursorAddress = MangleParameters (result);
204 GetCursorPosition ();
206 WriteConsole (clear);
212 static string MangleParameters (string str)
217 str = str.Replace ("{", "{{");
218 str = str.Replace ("}", "}}");
219 str = str.Replace ("%p1%d", "{0}");
220 return str.Replace ("%p2%d", "{1}");
223 static int TranslateColor (ConsoleColor desired)
226 case ConsoleColor.Black:
227 case ConsoleColor.DarkGray:
229 case ConsoleColor.DarkBlue:
230 case ConsoleColor.Blue:
232 case ConsoleColor.DarkGreen:
233 case ConsoleColor.Green:
235 case ConsoleColor.DarkCyan:
236 case ConsoleColor.Cyan:
238 case ConsoleColor.DarkRed:
239 case ConsoleColor.Red:
241 case ConsoleColor.DarkMagenta:
242 case ConsoleColor.Magenta:
244 case ConsoleColor.DarkYellow:
245 case ConsoleColor.Yellow:
247 case ConsoleColor.Gray:
248 case ConsoleColor.White:
255 public bool NotifyWrite (ConsoleKeyInfo key)
257 if (key.Key >= ConsoleKey.A && key.Key <= ConsoleKey.Z) {
259 if (cursorLeft >= WindowWidth) {
262 if (cursorTop >= WindowHeight) {
269 case ConsoleKey.Backspace:
270 if (cursorLeft > 0) {
272 SetCursorPosition (cursorLeft, cursorTop);
274 SetCursorPosition (cursorLeft, cursorTop);
279 case ConsoleKey.Clear:
281 case ConsoleKey.Enter:
283 case ConsoleKey.Pause:
285 case ConsoleKey.Escape:
287 case ConsoleKey.Spacebar:
289 case ConsoleKey.PageUp:
291 case ConsoleKey.PageDown:
295 case ConsoleKey.Home:
297 case ConsoleKey.LeftArrow:
299 case ConsoleKey.UpArrow:
301 case ConsoleKey.RightArrow:
303 case ConsoleKey.DownArrow:
305 case ConsoleKey.Select:
307 case ConsoleKey.Print:
309 case ConsoleKey.Execute:
311 case ConsoleKey.PrintScreen:
313 case ConsoleKey.Insert:
315 case ConsoleKey.Delete:
317 case ConsoleKey.Help:
339 case ConsoleKey.LeftWindows:
341 case ConsoleKey.RightWindows:
343 case ConsoleKey.Applications:
345 case ConsoleKey.Sleep:
347 case ConsoleKey.NumPad0:
349 case ConsoleKey.NumPad1:
351 case ConsoleKey.NumPad2:
353 case ConsoleKey.NumPad3:
355 case ConsoleKey.NumPad4:
357 case ConsoleKey.NumPad5:
359 case ConsoleKey.NumPad6:
361 case ConsoleKey.NumPad7:
363 case ConsoleKey.NumPad8:
365 case ConsoleKey.NumPad9:
367 case ConsoleKey.Multiply:
371 case ConsoleKey.Separator:
373 case ConsoleKey.Subtract:
375 case ConsoleKey.Decimal:
377 case ConsoleKey.Divide:
427 case ConsoleKey.BrowserBack:
429 case ConsoleKey.BrowserForward:
431 case ConsoleKey.BrowserRefresh:
433 case ConsoleKey.BrowserStop:
435 case ConsoleKey.BrowserSearch:
437 case ConsoleKey.BrowserFavorites:
439 case ConsoleKey.BrowserHome:
441 case ConsoleKey.VolumeMute:
443 case ConsoleKey.VolumeDown:
445 case ConsoleKey.VolumeUp:
447 case ConsoleKey.MediaNext:
449 case ConsoleKey.MediaPrevious:
451 case ConsoleKey.MediaStop:
453 case ConsoleKey.MediaPlay:
455 case ConsoleKey.LaunchMail:
457 case ConsoleKey.LaunchMediaSelect:
459 case ConsoleKey.LaunchApp1:
461 case ConsoleKey.LaunchApp2:
463 case ConsoleKey.Oem1:
465 case ConsoleKey.OemPlus:
467 case ConsoleKey.OemComma:
469 case ConsoleKey.OemMinus:
471 case ConsoleKey.OemPeriod:
473 case ConsoleKey.Oem2:
475 case ConsoleKey.Oem3:
477 case ConsoleKey.Oem4:
479 case ConsoleKey.Oem5:
481 case ConsoleKey.Oem6:
483 case ConsoleKey.Oem7:
485 case ConsoleKey.Oem8:
487 case ConsoleKey.Oem102:
489 case ConsoleKey.Process:
491 case ConsoleKey.Packet:
493 case ConsoleKey.Attention:
495 case ConsoleKey.CrSel:
497 case ConsoleKey.ExSel:
499 case ConsoleKey.EraseEndOfFile:
501 case ConsoleKey.Play:
503 case ConsoleKey.Zoom:
505 case ConsoleKey.NoName:
509 case ConsoleKey.OemClear:
517 public bool NotifyWrite (char val)
520 string str = reader.Get (TermInfoStrings.EraseChars);
522 Console.Error.WriteLine ("{0}", TermInfoReader.Escape (str));
524 Console.Error.WriteLine ("FUCK");
528 //TODO: compute cursor position
533 public ConsoleColor BackgroundColor {
534 get { return bgcolor; }
537 WriteConsole (String.Format (setabcolor, TranslateColor (value)));
541 public ConsoleColor ForegroundColor {
542 get { return fgcolor; }
545 WriteConsole (String.Format (setafcolor, TranslateColor (value)));
550 void GetCursorPosition ()
552 int row = 0, col = 0;
553 bool prevEcho = Echo;
556 WriteConsole ("\x1b[6n");
557 if (ConsoleDriver.InternalKeyAvailable (1000) <= 0) {
558 noGetPosition = true;
562 int b = stdin.ReadByte ();
563 while (b != '\x1b') {
565 if (ConsoleDriver.InternalKeyAvailable (100) <= 0)
567 b = stdin.ReadByte ();
570 b = stdin.ReadByte ();
572 AddToBuffer ('\x1b');
577 b = stdin.ReadByte ();
580 b = stdin.ReadByte ();
581 while ((b >= '0') && (b <= '9')) {
582 row = row * 10 + b - '0';
583 b = stdin.ReadByte ();
585 // Row/col is 0 based
589 b = stdin.ReadByte ();
592 b = stdin.ReadByte ();
593 while ((b >= '0') && (b <= '9')) {
594 col = col * 10 + b - '0';
595 b = stdin.ReadByte ();
597 // Row/col is 0 based
608 public int BufferHeight {
613 throw new NotSupportedException ();
617 public int BufferWidth {
622 throw new NotSupportedException ();
626 public bool CapsLock {
627 get { throw new NotSupportedException (); }
630 public int CursorLeft {
635 SetCursorPosition (value, CursorTop);
640 public int CursorTop {
645 SetCursorPosition (CursorLeft, value);
650 public bool CursorVisible {
652 return cursorVisible;
655 cursorVisible = value;
656 WriteConsole ((value ? csrVisible : csrInvisible));
660 // we have CursorNormal vs. CursorVisible...
662 public int CursorSize {
668 get { return !noEcho; }
677 public bool KeyAvailable {
679 return (writepos > readpos || ConsoleDriver.InternalKeyAvailable (0) > 0);
683 // We don't know these next 2 values, so return something reasonable
684 public int LargestWindowHeight {
685 get { return WindowHeight; }
688 public int LargestWindowWidth {
689 get { return WindowWidth; }
692 public bool NumberLock {
693 get { throw new NotSupportedException (); }
696 public string Title {
697 get { return title; }
701 WriteConsole (String.Format (titleFormat, value));
705 public bool TreatControlCAsInput {
706 get { return controlCAsInput; }
708 if (controlCAsInput == value)
711 ConsoleDriver.SetBreak (value);
712 controlCAsInput = value;
716 // TODO: use this at the beginning and on every SIGWINCH
717 void GetWindowDimensions ()
719 /* Try the ioctl first */
720 if (!ConsoleDriver.GetTtySize (MonoIO.ConsoleOutput, out windowWidth, out windowHeight)) {
721 windowWidth = reader.Get (TermInfoNumbers.Columns);
722 string env = Environment.GetEnvironmentVariable ("COLUMNS");
725 windowWidth = (int) UInt32.Parse (env);
730 windowHeight = reader.Get (TermInfoNumbers.Lines);
731 env = Environment.GetEnvironmentVariable ("LINES");
734 windowHeight = (int) UInt32.Parse (env);
740 bufferHeight = windowHeight;
741 bufferWidth = windowWidth;
744 public int WindowHeight {
746 GetWindowDimensions ();
750 throw new NotSupportedException ();
754 public int WindowLeft {
756 //GetWindowDimensions ();
760 throw new NotSupportedException ();
764 public int WindowTop {
766 //GetWindowDimensions ();
770 throw new NotSupportedException ();
774 public int WindowWidth {
776 GetWindowDimensions ();
780 throw new NotSupportedException ();
786 WriteConsole (clear);
789 public void Beep (int frequency, int duration)
794 public void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
795 int targetLeft, int targetTop, Char sourceChar,
796 ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
798 throw new NotImplementedException ();
801 void AddToBuffer (int b)
804 buffer = new byte [1024];
806 buffer [writepos++] = (byte) b;
809 ConsoleKeyInfo CreateKeyInfoFromInt (int n)
812 ConsoleKey key = (ConsoleKey)n;
818 key = ConsoleKey.Enter;
819 } else if (n == 8 || n == 9 || n == 12 || n == 13 || n == 19) {
820 /* Values in ConsoleKey */
821 } else if (n >= 1 && n <= 26) {
822 // For Ctrl-a to Ctrl-z.
824 key = ConsoleKey.A + n - 1;
825 } else if (n == 27) {
826 key = ConsoleKey.Escape;
827 } else if (n >= 'a' && n <= 'z') {
828 key = ConsoleKey.A - 'a' + n;
829 } else if (n >= 'A' && n <= 'Z') {
831 } else if (n >= '0' && n <= '9') {
836 return new ConsoleKeyInfo (c, key, shift, alt, ctrl);
839 object GetKeyFromBuffer (bool cooked)
841 if (readpos >= writepos)
844 int next = buffer [readpos];
845 if (!cooked || !rootmap.StartsWith (next)) {
847 return CreateKeyInfoFromInt (next);
851 TermInfoStrings str = rootmap.Match (buffer, readpos, writepos - readpos, out used);
856 if (keymap [str] != null) {
857 key = (ConsoleKeyInfo) keymap [str];
860 return CreateKeyInfoFromInt (next);
864 if (readpos >= writepos)
865 readpos = writepos = 0;
870 ConsoleKeyInfo ReadKeyInternal ()
875 o = GetKeyFromBuffer (true);
877 if (ConsoleDriver.InternalKeyAvailable (150) > 0) {
879 AddToBuffer (stdin.ReadByte ());
880 } while (ConsoleDriver.InternalKeyAvailable (0) > 0);
882 o = GetKeyFromBuffer (false);
884 AddToBuffer (stdin.ReadByte ());
889 return (ConsoleKeyInfo) o;
892 public ConsoleKeyInfo ReadKey (bool intercept)
894 bool prevEcho = Echo;
895 if (prevEcho == intercept)
898 ConsoleKeyInfo key = ReadKeyInternal ();
899 if (prevEcho == intercept)
905 public string ReadLine ()
907 bool prevEcho = Echo;
908 if (prevEcho == false)
910 StringBuilder builder = new StringBuilder ();
912 CStreamWriter writer = (CStreamWriter) Console.stdout;
914 ConsoleKeyInfo key = ReadKeyInternal ();
915 char c = key.KeyChar;
919 writer.WriteKey (key);
921 if (prevEcho == false)
923 return builder.ToString ();
926 public void ResetColor ()
928 string str = (origPair != null) ? origPair : origColors;
932 public void SetBufferSize (int width, int height)
934 throw new NotImplementedException (String.Empty);
937 public void SetCursorPosition (int left, int top)
939 if (bufferWidth == 0)
940 GetWindowDimensions ();
942 if (left < 0 || left >= bufferWidth)
943 throw new ArgumentOutOfRangeException ("left", "Value must be positive and below the buffer width.");
945 if (top < 0 || top >= bufferHeight)
946 throw new ArgumentOutOfRangeException ("top", "Value must be positive and below the buffer height.");
948 // Either CursorAddress or nothing.
949 // We might want to play with up/down/left/right/home when ca is not available.
950 if (cursorAddress == null)
951 throw new NotSupportedException ("This terminal does not suport setting the cursor position.");
953 int one = (home_1_1 ? 1 : 0);
954 WriteConsole (String.Format (cursorAddress, top + one, left + one));
959 public void SetWindowPosition (int left, int top)
961 // No need to throw exceptions here.
962 //throw new NotSupportedException ();
965 public void SetWindowSize (int width, int height)
967 // No need to throw exceptions here.
968 //throw new NotSupportedException ();
974 keymap = new Hashtable ();
975 keymap [TermInfoStrings.KeyBackspace] = new ConsoleKeyInfo ('\0', ConsoleKey.Backspace, false, false, false);
976 keymap [TermInfoStrings.KeyClear] = new ConsoleKeyInfo ('\0', ConsoleKey.Clear, false, false, false);
977 // Delete character...
978 keymap [TermInfoStrings.KeyDown] = new ConsoleKeyInfo ('\0', ConsoleKey.DownArrow, false, false, false);
979 keymap [TermInfoStrings.KeyF1] = new ConsoleKeyInfo ('\0', ConsoleKey.F1, false, false, false);
980 keymap [TermInfoStrings.KeyF10] = new ConsoleKeyInfo ('\0', ConsoleKey.F10, false, false, false);
981 keymap [TermInfoStrings.KeyF2] = new ConsoleKeyInfo ('\0', ConsoleKey.F2, false, false, false);
982 keymap [TermInfoStrings.KeyF3] = new ConsoleKeyInfo ('\0', ConsoleKey.F3, false, false, false);
983 keymap [TermInfoStrings.KeyF4] = new ConsoleKeyInfo ('\0', ConsoleKey.F4, false, false, false);
984 keymap [TermInfoStrings.KeyF5] = new ConsoleKeyInfo ('\0', ConsoleKey.F5, false, false, false);
985 keymap [TermInfoStrings.KeyF6] = new ConsoleKeyInfo ('\0', ConsoleKey.F6, false, false, false);
986 keymap [TermInfoStrings.KeyF7] = new ConsoleKeyInfo ('\0', ConsoleKey.F7, false, false, false);
987 keymap [TermInfoStrings.KeyF8] = new ConsoleKeyInfo ('\0', ConsoleKey.F8, false, false, false);
988 keymap [TermInfoStrings.KeyF9] = new ConsoleKeyInfo ('\0', ConsoleKey.F9, false, false, false);
989 keymap [TermInfoStrings.KeyHome] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, false, false, false);
991 keymap [TermInfoStrings.KeyLeft] = new ConsoleKeyInfo ('\0', ConsoleKey.LeftArrow, false, false, false);
992 keymap [TermInfoStrings.KeyLl] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad1, false, false, false);
993 keymap [TermInfoStrings.KeyNpage] = new ConsoleKeyInfo ('\0', ConsoleKey.PageDown, false, false, false);
994 keymap [TermInfoStrings.KeyPpage] = new ConsoleKeyInfo ('\0', ConsoleKey.PageUp, false, false, false);
995 keymap [TermInfoStrings.KeyRight] = new ConsoleKeyInfo ('\0', ConsoleKey.RightArrow, false, false, false);
996 keymap [TermInfoStrings.KeySf] = new ConsoleKeyInfo ('\0', ConsoleKey.PageDown, false, false, false);
997 keymap [TermInfoStrings.KeySr] = new ConsoleKeyInfo ('\0', ConsoleKey.PageUp, false, false, false);
998 keymap [TermInfoStrings.KeyUp] = new ConsoleKeyInfo ('\0', ConsoleKey.UpArrow, false, false, false);
999 keymap [TermInfoStrings.KeyA1] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad7, false, false, false);
1000 keymap [TermInfoStrings.KeyA3] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad9, false, false, false);
1001 keymap [TermInfoStrings.KeyB2] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad5, false, false, false);
1002 keymap [TermInfoStrings.KeyC1] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad1, false, false, false);
1003 keymap [TermInfoStrings.KeyC3] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad3, false, false, false);
1004 keymap [TermInfoStrings.KeyBtab] = new ConsoleKeyInfo ('\0', ConsoleKey.Tab, true, false, false);
1005 keymap [TermInfoStrings.KeyBeg] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, false, false, false);
1006 keymap [TermInfoStrings.KeyCopy] = new ConsoleKeyInfo ('C', ConsoleKey.C, false, true, false);
1007 keymap [TermInfoStrings.KeyEnd] = new ConsoleKeyInfo ('\0', ConsoleKey.End, false, false, false);
1008 keymap [TermInfoStrings.KeyEnter] = new ConsoleKeyInfo ('\n', ConsoleKey.Enter, false, false, false);
1009 keymap [TermInfoStrings.KeyHelp] = new ConsoleKeyInfo ('\0', ConsoleKey.Help, false, false, false);
1010 keymap [TermInfoStrings.KeyPrint] = new ConsoleKeyInfo ('\0', ConsoleKey.Print, false, false, false);
1011 keymap [TermInfoStrings.KeyUndo] = new ConsoleKeyInfo ('Z', ConsoleKey.Z , false, true, false);
1012 keymap [TermInfoStrings.KeySbeg] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, true, false, false);
1013 keymap [TermInfoStrings.KeyScopy] = new ConsoleKeyInfo ('C', ConsoleKey.C , true, true, false);
1014 keymap [TermInfoStrings.KeySdc] = new ConsoleKeyInfo ('\x9', ConsoleKey.Delete, true, false, false);
1015 keymap [TermInfoStrings.KeyShelp] = new ConsoleKeyInfo ('\0', ConsoleKey.Help, true, false, false);
1016 keymap [TermInfoStrings.KeyShome] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, true, false, false);
1017 keymap [TermInfoStrings.KeySleft] = new ConsoleKeyInfo ('\0', ConsoleKey.LeftArrow, true, false, false);
1018 keymap [TermInfoStrings.KeySprint] = new ConsoleKeyInfo ('\0', ConsoleKey.Print, true, false, false);
1019 keymap [TermInfoStrings.KeySright] = new ConsoleKeyInfo ('\0', ConsoleKey.RightArrow, true, false, false);
1020 keymap [TermInfoStrings.KeySundo] = new ConsoleKeyInfo ('Z', ConsoleKey.Z, true, false, false);
1021 keymap [TermInfoStrings.KeyF11] = new ConsoleKeyInfo ('\0', ConsoleKey.F11, false, false, false);
1022 keymap [TermInfoStrings.KeyF12] = new ConsoleKeyInfo ('\0', ConsoleKey.F12 , false, false, false);
1023 keymap [TermInfoStrings.KeyF13] = new ConsoleKeyInfo ('\0', ConsoleKey.F13, false, false, false);
1024 keymap [TermInfoStrings.KeyF14] = new ConsoleKeyInfo ('\0', ConsoleKey.F14, false, false, false);
1025 keymap [TermInfoStrings.KeyF15] = new ConsoleKeyInfo ('\0', ConsoleKey.F15, false, false, false);
1026 keymap [TermInfoStrings.KeyF16] = new ConsoleKeyInfo ('\0', ConsoleKey.F16, false, false, false);
1027 keymap [TermInfoStrings.KeyF17] = new ConsoleKeyInfo ('\0', ConsoleKey.F17, false, false, false);
1028 keymap [TermInfoStrings.KeyF18] = new ConsoleKeyInfo ('\0', ConsoleKey.F18, false, false, false);
1029 keymap [TermInfoStrings.KeyF19] = new ConsoleKeyInfo ('\0', ConsoleKey.F19, false, false, false);
1030 keymap [TermInfoStrings.KeyF20] = new ConsoleKeyInfo ('\0', ConsoleKey.F20, false, false, false);
1031 keymap [TermInfoStrings.KeyF21] = new ConsoleKeyInfo ('\0', ConsoleKey.F21, false, false, false);
1032 keymap [TermInfoStrings.KeyF22] = new ConsoleKeyInfo ('\0', ConsoleKey.F22, false, false, false);
1033 keymap [TermInfoStrings.KeyF23] = new ConsoleKeyInfo ('\0', ConsoleKey.F23, false, false, false);
1034 keymap [TermInfoStrings.KeyF24] = new ConsoleKeyInfo ('\0', ConsoleKey.F24, false, false, false);
1043 rootmap = new ByteMatcher ();
1044 AddStringMapping (TermInfoStrings.KeyBackspace);
1045 AddStringMapping (TermInfoStrings.KeyClear);
1046 AddStringMapping (TermInfoStrings.KeyDown);
1047 AddStringMapping (TermInfoStrings.KeyF1);
1048 AddStringMapping (TermInfoStrings.KeyF10);
1049 AddStringMapping (TermInfoStrings.KeyF2);
1050 AddStringMapping (TermInfoStrings.KeyF3);
1051 AddStringMapping (TermInfoStrings.KeyF4);
1052 AddStringMapping (TermInfoStrings.KeyF5);
1053 AddStringMapping (TermInfoStrings.KeyF6);
1054 AddStringMapping (TermInfoStrings.KeyF7);
1055 AddStringMapping (TermInfoStrings.KeyF8);
1056 AddStringMapping (TermInfoStrings.KeyF9);
1057 AddStringMapping (TermInfoStrings.KeyHome);
1058 AddStringMapping (TermInfoStrings.KeyLeft);
1059 AddStringMapping (TermInfoStrings.KeyLl);
1060 AddStringMapping (TermInfoStrings.KeyNpage);
1061 AddStringMapping (TermInfoStrings.KeyPpage);
1062 AddStringMapping (TermInfoStrings.KeyRight);
1063 AddStringMapping (TermInfoStrings.KeySf);
1064 AddStringMapping (TermInfoStrings.KeySr);
1065 AddStringMapping (TermInfoStrings.KeyUp);
1066 AddStringMapping (TermInfoStrings.KeyA1);
1067 AddStringMapping (TermInfoStrings.KeyA3);
1068 AddStringMapping (TermInfoStrings.KeyB2);
1069 AddStringMapping (TermInfoStrings.KeyC1);
1070 AddStringMapping (TermInfoStrings.KeyC3);
1071 AddStringMapping (TermInfoStrings.KeyBtab);
1072 AddStringMapping (TermInfoStrings.KeyBeg);
1073 AddStringMapping (TermInfoStrings.KeyCopy);
1074 AddStringMapping (TermInfoStrings.KeyEnd);
1075 AddStringMapping (TermInfoStrings.KeyEnter);
1076 AddStringMapping (TermInfoStrings.KeyHelp);
1077 AddStringMapping (TermInfoStrings.KeyPrint);
1078 AddStringMapping (TermInfoStrings.KeyUndo);
1079 AddStringMapping (TermInfoStrings.KeySbeg);
1080 AddStringMapping (TermInfoStrings.KeyScopy);
1081 AddStringMapping (TermInfoStrings.KeySdc);
1082 AddStringMapping (TermInfoStrings.KeyShelp);
1083 AddStringMapping (TermInfoStrings.KeyShome);
1084 AddStringMapping (TermInfoStrings.KeySleft);
1085 AddStringMapping (TermInfoStrings.KeySprint);
1086 AddStringMapping (TermInfoStrings.KeySright);
1087 AddStringMapping (TermInfoStrings.KeySundo);
1088 AddStringMapping (TermInfoStrings.KeyF11);
1089 AddStringMapping (TermInfoStrings.KeyF12);
1090 AddStringMapping (TermInfoStrings.KeyF13);
1091 AddStringMapping (TermInfoStrings.KeyF14);
1092 AddStringMapping (TermInfoStrings.KeyF15);
1093 AddStringMapping (TermInfoStrings.KeyF16);
1094 AddStringMapping (TermInfoStrings.KeyF17);
1095 AddStringMapping (TermInfoStrings.KeyF18);
1096 AddStringMapping (TermInfoStrings.KeyF19);
1097 AddStringMapping (TermInfoStrings.KeyF20);
1098 AddStringMapping (TermInfoStrings.KeyF21);
1099 AddStringMapping (TermInfoStrings.KeyF22);
1100 AddStringMapping (TermInfoStrings.KeyF23);
1101 AddStringMapping (TermInfoStrings.KeyF24);
1106 void AddStringMapping (TermInfoStrings s)
1108 byte [] bytes = reader.GetStringBytes (s);
1112 rootmap.AddMapping (s, bytes);
1117 Hashtable map = new Hashtable ();
1118 Hashtable starts = new Hashtable ();
1120 public void AddMapping (TermInfoStrings key, byte [] val)
1122 if (val.Length == 0)
1126 starts [(int) val [0]] = true;
1133 public bool StartsWith (int c)
1135 return (starts [c] != null);
1138 public TermInfoStrings Match (byte [] buffer, int offset, int length, out int used)
1140 foreach (byte [] bytes in map.Keys) {
1141 for (int i = 0; i < bytes.Length && i < length; i++) {
1142 if (bytes [i] != buffer [offset + i])
1145 if (bytes.Length - 1 == i) {
1146 used = bytes.Length;
1147 return (TermInfoStrings) map [bytes];
1153 return (TermInfoStrings) (-1);