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 static string [] locations = { "/etc/terminfo", "/usr/share/terminfo", "/usr/lib/terminfo" };
40 TermInfoReader reader;
43 string title = String.Empty;
44 string titleFormat = String.Empty;
45 bool cursorVisible = true;
66 string keypadXmit, keypadLocal;
74 ConsoleColor fgcolor = ConsoleColor.White;
75 ConsoleColor bgcolor = ConsoleColor.Black;
76 string setafcolor; // TODO: use setforeground/setbackground if available for better
77 string setabcolor; // color mapping.
81 bool home_1_1; // if true, we have to add 1 to x and y when using cursorAddress
82 int rl_startx = -1, rl_starty = -1;
87 static string SearchTerminfo (string term)
89 if (term == null || term == String.Empty)
92 // Ignore TERMINFO and TERMINFO_DIRS by now
93 //string terminfo = Environment.GetEnvironmentVariable ("TERMINFO");
94 //string terminfoDirs = Environment.GetEnvironmentVariable ("TERMINFO_DIRS");
96 foreach (string dir in locations) {
97 if (!Directory.Exists (dir))
100 string path = Path.Combine (dir, term.Substring (0, 1));
101 if (!Directory.Exists (dir))
104 path = Path.Combine (path, term);
105 if (!File.Exists (path))
114 static void WriteConsole (string str)
119 ((CStreamWriter) Console.stdout).InternalWriteString (str);
122 public TermInfoDriver ()
123 : this (Environment.GetEnvironmentVariable ("TERM"))
127 public TermInfoDriver (string term)
130 File.Delete ("console.log");
131 logger = new StreamWriter (File.OpenWrite ("console.log"));
135 if (term == "xterm") {
136 reader = new TermInfoReader (term, KnownTerminals.xterm);
137 } else if (term == "linux") {
138 reader = new TermInfoReader (term, KnownTerminals.linux);
140 string filename = SearchTerminfo (term);
141 if (filename != null)
142 reader = new TermInfoReader (term, filename);
146 reader = new TermInfoReader (term, KnownTerminals.ansi);
149 public bool Initialized {
150 get { return inited; }
158 /* This should not happen any more, since it is checked for in Console */
159 if (!ConsoleDriver.IsConsole)
160 throw new IOException ("Not a tty.");
163 ConsoleDriver.SetEcho (false);
164 string endString = null;
165 keypadXmit = reader.Get (TermInfoStrings.KeypadXmit);
166 keypadLocal = reader.Get (TermInfoStrings.KeypadLocal);
167 if (keypadXmit != null) {
168 WriteConsole (keypadXmit); // Needed to get the arrows working
169 if (keypadLocal != null)
170 endString += keypadLocal;
173 origPair = reader.Get (TermInfoStrings.OrigPair);
174 origColors = reader.Get (TermInfoStrings.OrigColors);
175 setafcolor = MangleParameters (reader.Get (TermInfoStrings.SetAForeground));
176 setabcolor = MangleParameters (reader.Get (TermInfoStrings.SetABackground));
177 string resetColors = (origColors == null) ? origPair : origColors;
178 if (resetColors != null)
179 endString += resetColors;
181 if (!ConsoleDriver.TtySetup (endString, out verase, out vsusp, out intr))
182 throw new IOException ("Error initializing terminal.");
184 stdin = Console.OpenStandardInput (0);
185 clear = reader.Get (TermInfoStrings.ClearScreen);
186 bell = reader.Get (TermInfoStrings.Bell);
188 clear = reader.Get (TermInfoStrings.CursorHome);
189 clear += reader.Get (TermInfoStrings.ClrEos);
192 csrVisible = reader.Get (TermInfoStrings.CursorNormal);
193 if (csrVisible == null)
194 csrVisible = reader.Get (TermInfoStrings.CursorVisible);
196 csrInvisible = reader.Get (TermInfoStrings.CursorInvisible);
197 if (term == "cygwin" || term == "linux" || (term != null && term.StartsWith ("xterm")) ||
198 term == "rxvt" || term == "dtterm") {
199 titleFormat = "\x1b]0;{0}\x7"; // icon + window title
200 } else if (term == "iris-ansi") {
201 titleFormat = "\x1bP1.y{0}\x1b\\"; // not tested
202 } else if (term == "sun-cmd") {
203 titleFormat = "\x1b]l{0}\x1b\\"; // not tested
206 cursorAddress = reader.Get (TermInfoStrings.CursorAddress);
207 if (cursorAddress != null) {
208 string result = cursorAddress.Replace ("%i", String.Empty);
209 home_1_1 = (cursorAddress != result);
210 cursorAddress = MangleParameters (result);
213 GetCursorPosition ();
215 logger.WriteLine ("noGetPosition: {0} left: {1} top: {2}", noGetPosition, cursorLeft, cursorTop);
219 WriteConsole (clear);
225 static string MangleParameters (string str)
230 str = str.Replace ("{", "{{");
231 str = str.Replace ("}", "}}");
232 str = str.Replace ("%p1%d", "{0}");
233 return str.Replace ("%p2%d", "{1}");
236 static int TranslateColor (ConsoleColor desired)
239 case ConsoleColor.Black:
240 case ConsoleColor.DarkGray:
242 case ConsoleColor.DarkBlue:
243 case ConsoleColor.Blue:
245 case ConsoleColor.DarkGreen:
246 case ConsoleColor.Green:
248 case ConsoleColor.DarkCyan:
249 case ConsoleColor.Cyan:
251 case ConsoleColor.DarkRed:
252 case ConsoleColor.Red:
254 case ConsoleColor.DarkMagenta:
255 case ConsoleColor.Magenta:
257 case ConsoleColor.DarkYellow:
258 case ConsoleColor.Yellow:
260 case ConsoleColor.Gray:
261 case ConsoleColor.White:
271 if (cursorLeft >= WindowWidth) {
274 if (cursorTop >= WindowHeight) {
275 // Writing beyond the initial screen
276 if (rl_starty != -1) rl_starty--;
282 public bool NotifyWrite (ConsoleKeyInfo key)
285 case ConsoleKey.Backspace:
286 if (cursorLeft > 0) {
287 if (cursorLeft <= rl_startx && cursorTop == rl_starty)
290 SetCursorPosition (cursorLeft, cursorTop);
292 SetCursorPosition (cursorLeft, cursorTop);
295 logger.WriteLine ("BS left: {0} top: {1}", cursorLeft, cursorTop);
300 int n = 8 - (cursorLeft % 8);
301 for (int i = 0; i < n; i++) IncrementX ();
303 case ConsoleKey.Clear:
305 case ConsoleKey.Enter:
308 if (cursorTop >= WindowHeight) {
313 logger.WriteLine ("ENTER left: {0} top: {1}", cursorLeft, cursorTop);
320 logger.WriteLine ("left: {0} top: {1}", cursorLeft, cursorTop);
326 public bool NotifyWrite (char val)
328 return NotifyWrite (CreateKeyInfoFromInt (val));
331 public ConsoleColor BackgroundColor {
332 get { return bgcolor; }
335 WriteConsole (String.Format (setabcolor, TranslateColor (value)));
339 public ConsoleColor ForegroundColor {
340 get { return fgcolor; }
343 WriteConsole (String.Format (setafcolor, TranslateColor (value)));
348 void GetCursorPosition ()
350 int row = 0, col = 0;
351 bool prevEcho = Echo;
354 WriteConsole ("\x1b[6n");
355 if (ConsoleDriver.InternalKeyAvailable (1000) <= 0) {
356 noGetPosition = true;
360 int b = stdin.ReadByte ();
361 while (b != '\x1b') {
363 if (ConsoleDriver.InternalKeyAvailable (100) <= 0)
365 b = stdin.ReadByte ();
368 b = stdin.ReadByte ();
370 AddToBuffer ('\x1b');
375 b = stdin.ReadByte ();
378 b = stdin.ReadByte ();
379 while ((b >= '0') && (b <= '9')) {
380 row = row * 10 + b - '0';
381 b = stdin.ReadByte ();
383 // Row/col is 0 based
387 b = stdin.ReadByte ();
390 b = stdin.ReadByte ();
391 while ((b >= '0') && (b <= '9')) {
392 col = col * 10 + b - '0';
393 b = stdin.ReadByte ();
395 // Row/col is 0 based
406 public int BufferHeight {
411 throw new NotSupportedException ();
415 public int BufferWidth {
420 throw new NotSupportedException ();
424 public bool CapsLock {
425 get { throw new NotSupportedException (); }
428 public int CursorLeft {
433 SetCursorPosition (value, CursorTop);
438 public int CursorTop {
443 SetCursorPosition (CursorLeft, value);
448 public bool CursorVisible {
450 return cursorVisible;
453 cursorVisible = value;
454 WriteConsole ((value ? csrVisible : csrInvisible));
458 // we have CursorNormal vs. CursorVisible...
460 public int CursorSize {
466 get { return !noEcho; }
475 public bool KeyAvailable {
477 return (writepos > readpos || ConsoleDriver.InternalKeyAvailable (0) > 0);
481 // We don't know these next 2 values, so return something reasonable
482 public int LargestWindowHeight {
483 get { return WindowHeight; }
486 public int LargestWindowWidth {
487 get { return WindowWidth; }
490 public bool NumberLock {
491 get { throw new NotSupportedException (); }
494 public string Title {
495 get { return title; }
499 WriteConsole (String.Format (titleFormat, value));
503 public bool TreatControlCAsInput {
504 get { return controlCAsInput; }
506 if (controlCAsInput == value)
509 ConsoleDriver.SetBreak (value);
510 controlCAsInput = value;
514 // TODO: use this at the beginning and on every SIGWINCH
515 void GetWindowDimensions ()
517 /* Try the ioctl first */
518 if (!ConsoleDriver.GetTtySize (MonoIO.ConsoleOutput, out windowWidth, out windowHeight)) {
519 windowWidth = reader.Get (TermInfoNumbers.Columns);
520 string env = Environment.GetEnvironmentVariable ("COLUMNS");
523 windowWidth = (int) UInt32.Parse (env);
528 windowHeight = reader.Get (TermInfoNumbers.Lines);
529 env = Environment.GetEnvironmentVariable ("LINES");
532 windowHeight = (int) UInt32.Parse (env);
538 bufferHeight = windowHeight;
539 bufferWidth = windowWidth;
542 public int WindowHeight {
544 GetWindowDimensions ();
548 throw new NotSupportedException ();
552 public int WindowLeft {
554 //GetWindowDimensions ();
558 throw new NotSupportedException ();
562 public int WindowTop {
564 //GetWindowDimensions ();
568 throw new NotSupportedException ();
572 public int WindowWidth {
574 GetWindowDimensions ();
578 throw new NotSupportedException ();
584 WriteConsole (clear);
587 public void Beep (int frequency, int duration)
592 public void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
593 int targetLeft, int targetTop, Char sourceChar,
594 ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
596 throw new NotImplementedException ();
599 void AddToBuffer (int b)
602 buffer = new byte [1024];
604 buffer [writepos++] = (byte) b;
607 ConsoleKeyInfo CreateKeyInfoFromInt (int n)
610 ConsoleKey key = (ConsoleKey)n;
616 key = ConsoleKey.Enter;
617 } else if (n == 8 || n == 9 || n == 12 || n == 13 || n == 19) {
618 /* Values in ConsoleKey */
619 } else if (n >= 1 && n <= 26) {
620 // For Ctrl-a to Ctrl-z.
622 key = ConsoleKey.A + n - 1;
623 } else if (n == 27) {
624 key = ConsoleKey.Escape;
625 } else if (n >= 'a' && n <= 'z') {
626 key = ConsoleKey.A - 'a' + n;
627 } else if (n >= 'A' && n <= 'Z') {
629 } else if (n >= '0' && n <= '9') {
634 return new ConsoleKeyInfo (c, key, shift, alt, ctrl);
637 object GetKeyFromBuffer (bool cooked)
639 if (readpos >= writepos)
642 int next = buffer [readpos];
643 if (!cooked || !rootmap.StartsWith (next)) {
645 return CreateKeyInfoFromInt (next);
649 TermInfoStrings str = rootmap.Match (buffer, readpos, writepos - readpos, out used);
654 if (keymap [str] != null) {
655 key = (ConsoleKeyInfo) keymap [str];
658 return CreateKeyInfoFromInt (next);
662 if (readpos >= writepos)
663 readpos = writepos = 0;
668 ConsoleKeyInfo ReadKeyInternal ()
673 o = GetKeyFromBuffer (true);
675 if (ConsoleDriver.InternalKeyAvailable (150) > 0) {
677 AddToBuffer (stdin.ReadByte ());
678 } while (ConsoleDriver.InternalKeyAvailable (0) > 0);
680 o = GetKeyFromBuffer (false);
682 AddToBuffer (stdin.ReadByte ());
687 return (ConsoleKeyInfo) o;
690 public ConsoleKeyInfo ReadKey (bool intercept)
692 bool prevEcho = Echo;
693 if (prevEcho == intercept)
696 ConsoleKeyInfo key = ReadKeyInternal ();
697 if (prevEcho == intercept)
703 public string ReadLine ()
705 bool prevEcho = Echo;
706 if (prevEcho == false)
708 StringBuilder builder = new StringBuilder ();
710 CStreamWriter writer = Console.stdout as CStreamWriter;
711 rl_startx = cursorLeft;
712 rl_starty = cursorLeft;
714 ConsoleKeyInfo key = ReadKeyInternal ();
715 char c = key.KeyChar;
720 writer.WriteKey (key);
722 Console.stdout.Write (c);
724 if (prevEcho == false)
728 return builder.ToString ();
731 public void ResetColor ()
733 string str = (origPair != null) ? origPair : origColors;
737 public void SetBufferSize (int width, int height)
739 throw new NotImplementedException (String.Empty);
742 public void SetCursorPosition (int left, int top)
744 if (bufferWidth == 0)
745 GetWindowDimensions ();
747 if (left < 0 || left >= bufferWidth)
748 throw new ArgumentOutOfRangeException ("left", "Value must be positive and below the buffer width.");
750 if (top < 0 || top >= bufferHeight)
751 throw new ArgumentOutOfRangeException ("top", "Value must be positive and below the buffer height.");
753 // Either CursorAddress or nothing.
754 // We might want to play with up/down/left/right/home when ca is not available.
755 if (cursorAddress == null)
756 throw new NotSupportedException ("This terminal does not suport setting the cursor position.");
758 int one = (home_1_1 ? 1 : 0);
759 WriteConsole (String.Format (cursorAddress, top + one, left + one));
764 public void SetWindowPosition (int left, int top)
766 // No need to throw exceptions here.
767 //throw new NotSupportedException ();
770 public void SetWindowSize (int width, int height)
772 // No need to throw exceptions here.
773 //throw new NotSupportedException ();
779 keymap = new Hashtable ();
780 keymap [TermInfoStrings.KeyBackspace] = new ConsoleKeyInfo ('\0', ConsoleKey.Backspace, false, false, false);
781 keymap [TermInfoStrings.KeyClear] = new ConsoleKeyInfo ('\0', ConsoleKey.Clear, false, false, false);
782 // Delete character...
783 keymap [TermInfoStrings.KeyDown] = new ConsoleKeyInfo ('\0', ConsoleKey.DownArrow, false, false, false);
784 keymap [TermInfoStrings.KeyF1] = new ConsoleKeyInfo ('\0', ConsoleKey.F1, false, false, false);
785 keymap [TermInfoStrings.KeyF10] = new ConsoleKeyInfo ('\0', ConsoleKey.F10, false, false, false);
786 keymap [TermInfoStrings.KeyF2] = new ConsoleKeyInfo ('\0', ConsoleKey.F2, false, false, false);
787 keymap [TermInfoStrings.KeyF3] = new ConsoleKeyInfo ('\0', ConsoleKey.F3, false, false, false);
788 keymap [TermInfoStrings.KeyF4] = new ConsoleKeyInfo ('\0', ConsoleKey.F4, false, false, false);
789 keymap [TermInfoStrings.KeyF5] = new ConsoleKeyInfo ('\0', ConsoleKey.F5, false, false, false);
790 keymap [TermInfoStrings.KeyF6] = new ConsoleKeyInfo ('\0', ConsoleKey.F6, false, false, false);
791 keymap [TermInfoStrings.KeyF7] = new ConsoleKeyInfo ('\0', ConsoleKey.F7, false, false, false);
792 keymap [TermInfoStrings.KeyF8] = new ConsoleKeyInfo ('\0', ConsoleKey.F8, false, false, false);
793 keymap [TermInfoStrings.KeyF9] = new ConsoleKeyInfo ('\0', ConsoleKey.F9, false, false, false);
794 keymap [TermInfoStrings.KeyHome] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, false, false, false);
796 keymap [TermInfoStrings.KeyLeft] = new ConsoleKeyInfo ('\0', ConsoleKey.LeftArrow, false, false, false);
797 keymap [TermInfoStrings.KeyLl] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad1, false, false, false);
798 keymap [TermInfoStrings.KeyNpage] = new ConsoleKeyInfo ('\0', ConsoleKey.PageDown, false, false, false);
799 keymap [TermInfoStrings.KeyPpage] = new ConsoleKeyInfo ('\0', ConsoleKey.PageUp, false, false, false);
800 keymap [TermInfoStrings.KeyRight] = new ConsoleKeyInfo ('\0', ConsoleKey.RightArrow, false, false, false);
801 keymap [TermInfoStrings.KeySf] = new ConsoleKeyInfo ('\0', ConsoleKey.PageDown, false, false, false);
802 keymap [TermInfoStrings.KeySr] = new ConsoleKeyInfo ('\0', ConsoleKey.PageUp, false, false, false);
803 keymap [TermInfoStrings.KeyUp] = new ConsoleKeyInfo ('\0', ConsoleKey.UpArrow, false, false, false);
804 keymap [TermInfoStrings.KeyA1] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad7, false, false, false);
805 keymap [TermInfoStrings.KeyA3] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad9, false, false, false);
806 keymap [TermInfoStrings.KeyB2] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad5, false, false, false);
807 keymap [TermInfoStrings.KeyC1] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad1, false, false, false);
808 keymap [TermInfoStrings.KeyC3] = new ConsoleKeyInfo ('\0', ConsoleKey.NumPad3, false, false, false);
809 keymap [TermInfoStrings.KeyBtab] = new ConsoleKeyInfo ('\0', ConsoleKey.Tab, true, false, false);
810 keymap [TermInfoStrings.KeyBeg] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, false, false, false);
811 keymap [TermInfoStrings.KeyCopy] = new ConsoleKeyInfo ('C', ConsoleKey.C, false, true, false);
812 keymap [TermInfoStrings.KeyEnd] = new ConsoleKeyInfo ('\0', ConsoleKey.End, false, false, false);
813 keymap [TermInfoStrings.KeyEnter] = new ConsoleKeyInfo ('\n', ConsoleKey.Enter, false, false, false);
814 keymap [TermInfoStrings.KeyHelp] = new ConsoleKeyInfo ('\0', ConsoleKey.Help, false, false, false);
815 keymap [TermInfoStrings.KeyPrint] = new ConsoleKeyInfo ('\0', ConsoleKey.Print, false, false, false);
816 keymap [TermInfoStrings.KeyUndo] = new ConsoleKeyInfo ('Z', ConsoleKey.Z , false, true, false);
817 keymap [TermInfoStrings.KeySbeg] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, true, false, false);
818 keymap [TermInfoStrings.KeyScopy] = new ConsoleKeyInfo ('C', ConsoleKey.C , true, true, false);
819 keymap [TermInfoStrings.KeySdc] = new ConsoleKeyInfo ('\x9', ConsoleKey.Delete, true, false, false);
820 keymap [TermInfoStrings.KeyShelp] = new ConsoleKeyInfo ('\0', ConsoleKey.Help, true, false, false);
821 keymap [TermInfoStrings.KeyShome] = new ConsoleKeyInfo ('\0', ConsoleKey.Home, true, false, false);
822 keymap [TermInfoStrings.KeySleft] = new ConsoleKeyInfo ('\0', ConsoleKey.LeftArrow, true, false, false);
823 keymap [TermInfoStrings.KeySprint] = new ConsoleKeyInfo ('\0', ConsoleKey.Print, true, false, false);
824 keymap [TermInfoStrings.KeySright] = new ConsoleKeyInfo ('\0', ConsoleKey.RightArrow, true, false, false);
825 keymap [TermInfoStrings.KeySundo] = new ConsoleKeyInfo ('Z', ConsoleKey.Z, true, false, false);
826 keymap [TermInfoStrings.KeyF11] = new ConsoleKeyInfo ('\0', ConsoleKey.F11, false, false, false);
827 keymap [TermInfoStrings.KeyF12] = new ConsoleKeyInfo ('\0', ConsoleKey.F12 , false, false, false);
828 keymap [TermInfoStrings.KeyF13] = new ConsoleKeyInfo ('\0', ConsoleKey.F13, false, false, false);
829 keymap [TermInfoStrings.KeyF14] = new ConsoleKeyInfo ('\0', ConsoleKey.F14, false, false, false);
830 keymap [TermInfoStrings.KeyF15] = new ConsoleKeyInfo ('\0', ConsoleKey.F15, false, false, false);
831 keymap [TermInfoStrings.KeyF16] = new ConsoleKeyInfo ('\0', ConsoleKey.F16, false, false, false);
832 keymap [TermInfoStrings.KeyF17] = new ConsoleKeyInfo ('\0', ConsoleKey.F17, false, false, false);
833 keymap [TermInfoStrings.KeyF18] = new ConsoleKeyInfo ('\0', ConsoleKey.F18, false, false, false);
834 keymap [TermInfoStrings.KeyF19] = new ConsoleKeyInfo ('\0', ConsoleKey.F19, false, false, false);
835 keymap [TermInfoStrings.KeyF20] = new ConsoleKeyInfo ('\0', ConsoleKey.F20, false, false, false);
836 keymap [TermInfoStrings.KeyF21] = new ConsoleKeyInfo ('\0', ConsoleKey.F21, false, false, false);
837 keymap [TermInfoStrings.KeyF22] = new ConsoleKeyInfo ('\0', ConsoleKey.F22, false, false, false);
838 keymap [TermInfoStrings.KeyF23] = new ConsoleKeyInfo ('\0', ConsoleKey.F23, false, false, false);
839 keymap [TermInfoStrings.KeyF24] = new ConsoleKeyInfo ('\0', ConsoleKey.F24, false, false, false);
848 rootmap = new ByteMatcher ();
849 AddStringMapping (TermInfoStrings.KeyBackspace);
850 AddStringMapping (TermInfoStrings.KeyClear);
851 AddStringMapping (TermInfoStrings.KeyDown);
852 AddStringMapping (TermInfoStrings.KeyF1);
853 AddStringMapping (TermInfoStrings.KeyF10);
854 AddStringMapping (TermInfoStrings.KeyF2);
855 AddStringMapping (TermInfoStrings.KeyF3);
856 AddStringMapping (TermInfoStrings.KeyF4);
857 AddStringMapping (TermInfoStrings.KeyF5);
858 AddStringMapping (TermInfoStrings.KeyF6);
859 AddStringMapping (TermInfoStrings.KeyF7);
860 AddStringMapping (TermInfoStrings.KeyF8);
861 AddStringMapping (TermInfoStrings.KeyF9);
862 AddStringMapping (TermInfoStrings.KeyHome);
863 AddStringMapping (TermInfoStrings.KeyLeft);
864 AddStringMapping (TermInfoStrings.KeyLl);
865 AddStringMapping (TermInfoStrings.KeyNpage);
866 AddStringMapping (TermInfoStrings.KeyPpage);
867 AddStringMapping (TermInfoStrings.KeyRight);
868 AddStringMapping (TermInfoStrings.KeySf);
869 AddStringMapping (TermInfoStrings.KeySr);
870 AddStringMapping (TermInfoStrings.KeyUp);
871 AddStringMapping (TermInfoStrings.KeyA1);
872 AddStringMapping (TermInfoStrings.KeyA3);
873 AddStringMapping (TermInfoStrings.KeyB2);
874 AddStringMapping (TermInfoStrings.KeyC1);
875 AddStringMapping (TermInfoStrings.KeyC3);
876 AddStringMapping (TermInfoStrings.KeyBtab);
877 AddStringMapping (TermInfoStrings.KeyBeg);
878 AddStringMapping (TermInfoStrings.KeyCopy);
879 AddStringMapping (TermInfoStrings.KeyEnd);
880 AddStringMapping (TermInfoStrings.KeyEnter);
881 AddStringMapping (TermInfoStrings.KeyHelp);
882 AddStringMapping (TermInfoStrings.KeyPrint);
883 AddStringMapping (TermInfoStrings.KeyUndo);
884 AddStringMapping (TermInfoStrings.KeySbeg);
885 AddStringMapping (TermInfoStrings.KeyScopy);
886 AddStringMapping (TermInfoStrings.KeySdc);
887 AddStringMapping (TermInfoStrings.KeyShelp);
888 AddStringMapping (TermInfoStrings.KeyShome);
889 AddStringMapping (TermInfoStrings.KeySleft);
890 AddStringMapping (TermInfoStrings.KeySprint);
891 AddStringMapping (TermInfoStrings.KeySright);
892 AddStringMapping (TermInfoStrings.KeySundo);
893 AddStringMapping (TermInfoStrings.KeyF11);
894 AddStringMapping (TermInfoStrings.KeyF12);
895 AddStringMapping (TermInfoStrings.KeyF13);
896 AddStringMapping (TermInfoStrings.KeyF14);
897 AddStringMapping (TermInfoStrings.KeyF15);
898 AddStringMapping (TermInfoStrings.KeyF16);
899 AddStringMapping (TermInfoStrings.KeyF17);
900 AddStringMapping (TermInfoStrings.KeyF18);
901 AddStringMapping (TermInfoStrings.KeyF19);
902 AddStringMapping (TermInfoStrings.KeyF20);
903 AddStringMapping (TermInfoStrings.KeyF21);
904 AddStringMapping (TermInfoStrings.KeyF22);
905 AddStringMapping (TermInfoStrings.KeyF23);
906 AddStringMapping (TermInfoStrings.KeyF24);
911 void AddStringMapping (TermInfoStrings s)
913 byte [] bytes = reader.GetStringBytes (s);
917 rootmap.AddMapping (s, bytes);
922 Hashtable map = new Hashtable ();
923 Hashtable starts = new Hashtable ();
925 public void AddMapping (TermInfoStrings key, byte [] val)
931 starts [(int) val [0]] = true;
938 public bool StartsWith (int c)
940 return (starts [c] != null);
943 public TermInfoStrings Match (byte [] buffer, int offset, int length, out int used)
945 foreach (byte [] bytes in map.Keys) {
946 for (int i = 0; i < bytes.Length && i < length; i++) {
947 if (bytes [i] != buffer [offset + i])
950 if (bytes.Length - 1 == i) {
952 return (TermInfoStrings) map [bytes];
958 return (TermInfoStrings) (-1);