2006-09-19 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / corlib / System / WindowsConsoleDriver.cs
1 //
2 // System.WindowsConsoleDriver
3 //
4 // Author:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2005 Novell, Inc. (http://www.novell.com)
8 //
9
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 #if NET_2_0
30 using System.Runtime.InteropServices;
31 using System.Text;
32 namespace System {
33         struct ConsoleCursorInfo {
34                 public int Size;
35                 public bool Visible;
36         }
37
38         struct InputRecord {
39                 public short EventType;
40                 // This is KEY_EVENT_RECORD
41                 public bool KeyDown;
42                 public short RepeatCount;
43                 public short VirtualKeyCode;
44                 public short VirtualScanCode;
45                 public char Character;
46                 public int ControlKeyState;
47                 int pad1;
48                 bool pad2;
49                 //
50         }
51
52         struct CharInfo {
53                 public char Character;
54                 public short Attributes;
55         }
56         
57         struct Coord {
58                 public short X;
59                 public short Y;
60
61                 public Coord (int x, int y)
62                 {
63                         X = (short) x;
64                         Y = (short) y;
65                 }
66         }
67
68         struct SmallRect {
69                 public short Left;
70                 public short Top;
71                 public short Right;
72                 public short Bottom;
73
74                 public SmallRect (int left, int top, int right, int bottom)
75                 {
76                         Left = (short) left;
77                         Top = (short) top;
78                         Right = (short) right;
79                         Bottom = (short) bottom;
80                 }
81         }
82
83         struct ConsoleScreenBufferInfo {
84                 public Coord Size;
85                 public Coord CursorPosition;
86                 public short Attribute;
87                 public SmallRect Window;
88                 public Coord MaxWindowSize;
89         }
90
91         enum Handles {
92                 STD_INPUT = -10,
93                 STD_OUTPUT = -11,
94                 STD_ERROR = -12
95         }
96
97         unsafe class WindowsConsoleDriver : IConsoleDriver {
98                 IntPtr inputHandle;
99                 IntPtr outputHandle;
100                 short defaultAttribute;
101                 bool inited;
102
103                 public WindowsConsoleDriver ()
104                 {
105                         outputHandle = GetStdHandle (Handles.STD_OUTPUT);
106                         inputHandle = GetStdHandle (Handles.STD_INPUT);
107                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
108                         GetConsoleScreenBufferInfo (outputHandle, out info);
109                         defaultAttribute = info.Attribute; // Not sure about this...
110                 }
111
112                 // FOREGROUND_BLUE      1
113                 // FOREGROUND_GREEN     2
114                 // FOREGROUND_RED       4
115                 // FOREGROUND_INTENSITY 8
116                 // BACKGROUND_BLUE      16
117                 // BACKGROUND_GREEN     32
118                 // BACKGROUND_RED       64
119                 // BACKGROUND_INTENSITY 128
120                 static ConsoleColor GetForeground (short attr)
121                 {
122                         attr &= 0x0F;
123                         return (ConsoleColor) attr;
124                 }
125
126                 static ConsoleColor GetBackground (short attr)
127                 {
128                         attr &= 0xF0;
129                         attr >>= 4;
130                         return (ConsoleColor) attr;
131                 }
132
133                 static short GetAttrForeground (int attr, ConsoleColor color)
134                 {
135                         attr &= ~15;
136                         return (short) (attr | (int) color);
137                 }
138
139                 static short GetAttrBackground (int attr, ConsoleColor color)
140                 {
141                         attr &= ~0xf0;
142                         int c = ((int) color) << 4;
143                         return (short) (attr | c);
144                 }
145
146                 public ConsoleColor BackgroundColor {
147                         get {
148                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
149                                 GetConsoleScreenBufferInfo (outputHandle, out info);
150                                 return GetBackground (info.Attribute);
151                         }
152                         set {
153                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
154                                 GetConsoleScreenBufferInfo (outputHandle, out info);
155                                 short attr = GetAttrBackground (info.Attribute, value);
156                                 SetConsoleTextAttribute (outputHandle, attr);
157                         }
158                 }
159
160                 public int BufferHeight {
161                         get {
162                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
163                                 GetConsoleScreenBufferInfo (outputHandle, out info);
164                                 return info.Size.Y;
165                         }
166                         set { SetBufferSize (BufferWidth, value); }
167                 }
168
169                 public int BufferWidth {
170                         get {
171                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
172                                 GetConsoleScreenBufferInfo (outputHandle, out info);
173                                 return info.Size.X;
174                         }
175                         set { SetBufferSize (value, BufferHeight); }
176                 }
177
178                 public bool CapsLock {
179                         get {
180                                 short state = GetKeyState (20); // VK_CAPITAL
181                                 return ((state & 1) == 1);
182                         }
183                 }
184
185                 public int CursorLeft {
186                         get {
187                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
188                                 GetConsoleScreenBufferInfo (outputHandle, out info);
189                                 return info.CursorPosition.X;
190                         }
191                         set { SetCursorPosition (value, CursorTop); }
192                 }
193
194                 public int CursorSize {
195                         get {
196                                 ConsoleCursorInfo info = new ConsoleCursorInfo ();
197                                 GetConsoleCursorInfo (outputHandle, out info);
198                                 return info.Size;
199                         }
200                         set {
201                                 if (value < 1 || value > 100)
202                                         throw new ArgumentOutOfRangeException ("value");
203
204                                 ConsoleCursorInfo info = new ConsoleCursorInfo ();
205                                 GetConsoleCursorInfo (outputHandle, out info);
206                                 info.Size = value;
207                                 if (!SetConsoleCursorInfo (outputHandle, ref info))
208                                         throw new Exception ("SetConsoleCursorInfo failed");
209                         }
210                 }
211
212                 public int CursorTop {
213                         get {
214                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
215                                 GetConsoleScreenBufferInfo (outputHandle, out info);
216                                 return info.CursorPosition.Y;
217                         }
218                         set { SetCursorPosition (CursorLeft, value); }
219                 }
220
221                 public bool CursorVisible {
222                         get {
223                                 ConsoleCursorInfo info = new ConsoleCursorInfo ();
224                                 GetConsoleCursorInfo (outputHandle, out info);
225                                 return info.Visible;
226                         }
227                         set {
228                                 ConsoleCursorInfo info = new ConsoleCursorInfo ();
229                                 GetConsoleCursorInfo (outputHandle, out info);
230                                 if (info.Visible == value)
231                                         return;
232
233                                 info.Visible = value;
234                                 if (!SetConsoleCursorInfo (outputHandle, ref info))
235                                         throw new Exception ("SetConsoleCursorInfo failed");
236                         }
237                 }
238
239                 public bool Echo { // not really used on windows
240                         get { return true; }
241                         set {}
242                 }
243
244                 public ConsoleColor ForegroundColor {
245                         get {
246                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
247                                 GetConsoleScreenBufferInfo (outputHandle, out info);
248                                 return GetForeground (info.Attribute);
249                         }
250                         set {
251                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
252                                 GetConsoleScreenBufferInfo (outputHandle, out info);
253                                 short attr = GetAttrForeground (info.Attribute, value);
254                                 SetConsoleTextAttribute (outputHandle, attr);
255                         }
256                 }
257
258                 public bool KeyAvailable {
259                         get {
260                                 int eventsRead;
261                                 InputRecord record = new InputRecord ();
262                                 while (true) {
263                                         // Use GetNumberOfConsoleInputEvents and remove the while?
264                                         if (!PeekConsoleInput (inputHandle, out record, 1, out eventsRead))
265                                                 throw new InvalidOperationException ("Error in PeekConsoleInput " +
266                                                                                 Marshal.GetLastWin32Error ());
267
268                                         if (eventsRead == 0)
269                                                 return false;
270
271                                         //KEY_EVENT == 1
272                                         if (record.EventType == 1 && record.KeyDown)
273                                                 return true;
274
275                                         if (!ReadConsoleInput (inputHandle, out record, 1, out eventsRead))
276                                                 throw new InvalidOperationException ("Error in ReadConsoleInput " +
277                                                                                 Marshal.GetLastWin32Error ());
278                                 }
279                         }
280                 }
281
282                 public bool Initialized { // Not useful on windows, so false.
283                         get { return false; }
284                 }
285
286                 public int LargestWindowHeight {
287                         get {
288                                 Coord coord = GetLargestConsoleWindowSize (outputHandle);
289                                 if (coord.X == 0 && coord.Y == 0)
290                                         throw new Exception ("GetLargestConsoleWindowSize" + Marshal.GetLastWin32Error ());
291
292                                 return coord.Y;
293                         }
294                 }
295
296                 public int LargestWindowWidth {
297                         get {
298                                 Coord coord = GetLargestConsoleWindowSize (outputHandle);
299                                 if (coord.X == 0 && coord.Y == 0)
300                                         throw new Exception ("GetLargestConsoleWindowSize" + Marshal.GetLastWin32Error ());
301
302                                 return coord.X;
303                         }
304                 }
305
306                 public bool NumberLock {
307                         get {
308                                 short state = GetKeyState (144); // VK_NUMLOCK
309                                 return ((state & 1) == 1);
310                         }
311                 }
312
313                 public string Title {
314                         get {
315                                 StringBuilder sb = new StringBuilder (1024); // hope this is enough
316                                 if (GetConsoleTitle (sb, 1024) == 0) {
317                                         // Try the maximum
318                                         sb = new StringBuilder (26001);
319                                         if (GetConsoleTitle (sb, 26000) == 0)
320                                                 throw new Exception ("Got " + Marshal.GetLastWin32Error ());
321                                 }
322
323                                 return sb.ToString ();
324                         }
325                         set {
326                                 if (value == null)
327                                         throw new ArgumentNullException ("value");
328
329                                 if (!SetConsoleTitle (value))
330                                         throw new Exception ("Got " + Marshal.GetLastWin32Error ());
331                         }
332                 }
333
334                 public bool TreatControlCAsInput {
335                         get {
336                                 int mode;
337                                 if (!GetConsoleMode (outputHandle, out mode))
338                                         throw new Exception ("Failed in GetConsoleMode: " + Marshal.GetLastWin32Error ());
339
340                                 // ENABLE_PROCESSED_INPUT
341                                 return ((mode & 1) == 0);
342                         }
343
344                         set {
345                                 int mode;
346                                 if (!GetConsoleMode (outputHandle, out mode))
347                                         throw new Exception ("Failed in GetConsoleMode: " + Marshal.GetLastWin32Error ());
348
349                                 bool cAsInput = ((mode & 1) == 0);
350                                 if (cAsInput == value)
351                                         return;
352
353                                 if (value)
354                                         mode &= ~1;
355                                 else
356                                         mode++;
357
358                                 if (!SetConsoleMode (outputHandle, mode))
359                                         throw new Exception ("Failed in SetConsoleMode: " + Marshal.GetLastWin32Error ());
360                         }
361                 }
362
363                 public int WindowHeight {
364                         get {
365                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
366                                 GetConsoleScreenBufferInfo (outputHandle, out info);
367                                 return info.Window.Bottom - info.Window.Top + 1;
368                         }
369                         set { SetWindowSize (WindowWidth, value); }
370                 }
371
372                 public int WindowLeft {
373                         get {
374                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
375                                 GetConsoleScreenBufferInfo (outputHandle, out info);
376                                 return info.Window.Left;
377                         }
378                         set { SetWindowPosition (value, WindowTop); }
379                 }
380
381                 public int WindowTop {
382                         get {
383                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
384                                 GetConsoleScreenBufferInfo (outputHandle, out info);
385                                 return info.Window.Top;
386                         }
387                         set { SetWindowPosition (WindowLeft, value); }
388                 }
389
390                 public int WindowWidth {
391                         get {
392                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
393                                 GetConsoleScreenBufferInfo (outputHandle, out info);
394                                 return info.Window.Right - info.Window.Left + 1;
395                         }
396                         set { SetWindowSize (value, WindowHeight); }
397                 }
398
399                 public void Beep (int frequency, int duration)
400                 {
401                         _Beep (frequency, duration);
402                 }
403
404                 public void Clear ()
405                 {
406                         Coord coord = new Coord ();
407                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
408                         GetConsoleScreenBufferInfo (outputHandle, out info);
409
410                         int size = info.Size.X * info.Size.Y;
411                         int written;
412                         FillConsoleOutputCharacter (outputHandle, ' ', size, coord, out written);
413
414                         GetConsoleScreenBufferInfo (outputHandle, out info);
415
416                         FillConsoleOutputAttribute (outputHandle, info.Attribute, size, coord, out written);
417                         SetConsoleCursorPosition (outputHandle, coord);
418                 }
419
420                 public void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
421                                         int targetLeft, int targetTop, Char sourceChar,
422                                         ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
423                 {
424                         if (sourceForeColor < 0)
425                                 throw new ArgumentException ("Cannot be less than 0.", "sourceForeColor");
426
427                         if (sourceBackColor < 0)
428                                 throw new ArgumentException ("Cannot be less than 0.", "sourceBackColor");
429
430                         if (sourceWidth == 0 || sourceHeight == 0)
431                                 return;
432
433                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
434                         GetConsoleScreenBufferInfo (outputHandle, out info);
435                         CharInfo [] buffer = new CharInfo [sourceWidth * sourceHeight];
436                         Coord bsize = new Coord (sourceWidth, sourceHeight);
437                         Coord bpos = new Coord (0, 0);
438                         SmallRect region = new SmallRect (sourceLeft, sourceTop, sourceLeft + sourceWidth - 1, sourceTop + sourceHeight - 1);
439                         fixed (void *ptr = &buffer [0]) {
440                                 if (!ReadConsoleOutput (outputHandle, ptr, bsize, bpos, ref region))
441                                         throw new ArgumentException (String.Empty, "Cannot read from the specified coordinates.");
442                         }
443
444                         int written;
445                         short attr  = GetAttrForeground (0, sourceForeColor);
446                         attr  = GetAttrBackground (attr, sourceBackColor);
447                         bpos = new Coord (sourceLeft, sourceTop);
448                         for (int i = 0; i < sourceHeight; i++, bpos.Y++) {
449                                 FillConsoleOutputCharacter (outputHandle, sourceChar, sourceWidth, bpos, out written);
450                                 FillConsoleOutputAttribute (outputHandle, attr, sourceWidth, bpos, out written);
451                         }
452
453                         bpos = new Coord (0, 0);
454                         region = new SmallRect (targetLeft, targetTop, targetLeft + sourceWidth - 1, targetTop + sourceHeight - 1);
455                         if (!WriteConsoleOutput (outputHandle, buffer, bsize, bpos, ref region))
456                                 throw new ArgumentException (String.Empty, "Cannot write to the specified coordinates.");
457                 }
458
459                 public string ReadLine ()
460                 {
461                         StringBuilder builder = new StringBuilder ();
462                         bool exit = false;
463                         do {
464                                 ConsoleKeyInfo key = ReadKey (false);
465                                 char c = key.KeyChar;
466                                 exit = (c == '\n');
467                                 if (!exit)
468                                         builder.Append (key.KeyChar);
469                         } while (!exit);
470                         return builder.ToString ();
471                 }
472
473                 public ConsoleKeyInfo ReadKey (bool intercept)
474                 {
475                         int eventsRead;
476                         InputRecord record = new InputRecord ();
477                         do {
478                                 if (!ReadConsoleInput (inputHandle, out record, 1, out eventsRead))
479                                         throw new InvalidOperationException ("Error in ReadConsoleInput " +
480                                                                         Marshal.GetLastWin32Error ());
481                         } while (record.EventType != 1 && !record.KeyDown);
482
483                         // RIGHT_ALT_PRESSED 1
484                         // LEFT_ALT_PRESSED 2
485                         // RIGHT_CTRL_PRESSED 4
486                         // LEFT_CTRL_PRESSED 8
487                         // SHIFT_PRESSED 16
488                         bool alt = ((record.ControlKeyState & 3) != 0);
489                         bool ctrl = ((record.ControlKeyState & 12) != 0);
490                         bool shift = ((record.ControlKeyState & 16) != 0);
491                         return new ConsoleKeyInfo (record.Character, (ConsoleKey) record.VirtualKeyCode, shift, alt, ctrl);
492                 }
493
494                 public void ResetColor ()
495                 {
496                         SetConsoleTextAttribute (outputHandle, defaultAttribute);
497                 }
498
499                 public void SetBufferSize (int width, int height)
500                 {
501                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
502                         GetConsoleScreenBufferInfo (outputHandle, out info);
503
504                         if (width - 1 > info.Window.Right)
505                                 throw new ArgumentOutOfRangeException ("width");
506
507                         if (height - 1 > info.Window.Bottom)
508                                 throw new ArgumentOutOfRangeException ("height");
509
510                         Coord coord = new Coord (width, height);
511                         if (!SetConsoleScreenBufferSize (outputHandle, coord))
512                                 throw new ArgumentOutOfRangeException ("height/width", "Cannot be smaller than the window size.");
513                 }
514
515                 public void SetCursorPosition (int left, int top)
516                 {
517                         Coord coord = new Coord (left, top);
518                         SetConsoleCursorPosition (outputHandle, coord);
519                 }
520
521                 public void SetWindowPosition (int left, int top)
522                 {
523                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
524                         GetConsoleScreenBufferInfo (outputHandle, out info);
525                         SmallRect rect = info.Window;
526                         rect.Left = (short) left;
527                         rect.Top = (short) top;
528                         if (!SetConsoleWindowInfo (outputHandle, true, ref rect))
529                                 throw new ArgumentOutOfRangeException ("left/top", "Windows error " + Marshal.GetLastWin32Error ());
530                 }
531
532                 public void SetWindowSize (int width, int height)
533                 {
534                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
535                         GetConsoleScreenBufferInfo (outputHandle, out info);
536                         SmallRect rect = info.Window;
537                         rect.Right = (short) (rect.Left + width - 1);
538                         rect.Bottom = (short) (rect.Top + height - 1);
539                         if (!SetConsoleWindowInfo (outputHandle, true, ref rect))
540                                 throw new ArgumentOutOfRangeException ("left/top", "Windows error " + Marshal.GetLastWin32Error ());
541                 }
542
543                 //
544                 // Imports
545                 //
546                 [DllImport ("kernel32.dll", EntryPoint="GetStdHandle", SetLastError=true, CharSet=CharSet.Unicode)]
547                 extern static IntPtr GetStdHandle (Handles handle);
548
549                 [DllImport ("kernel32.dll", EntryPoint="Beep", SetLastError=true, CharSet=CharSet.Unicode)]
550                 extern static void _Beep (int frequency, int duration);
551
552                 [DllImport ("kernel32.dll", EntryPoint="GetConsoleScreenBufferInfo", SetLastError=true, CharSet=CharSet.Unicode)]
553                 extern static bool GetConsoleScreenBufferInfo (IntPtr handle, out ConsoleScreenBufferInfo info);
554
555                 [DllImport ("kernel32.dll", EntryPoint="FillConsoleOutputCharacter", SetLastError=true, CharSet=CharSet.Unicode)]
556                 extern static bool FillConsoleOutputCharacter (IntPtr handle, char c, int size, Coord coord, out int written);
557
558                 [DllImport ("kernel32.dll", EntryPoint="FillConsoleOutputAttribute", SetLastError=true, CharSet=CharSet.Unicode)]
559                 extern static bool FillConsoleOutputAttribute (IntPtr handle, short c, int size, Coord coord, out int written);
560
561                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleCursorPosition", SetLastError=true, CharSet=CharSet.Unicode)]
562                 extern static bool SetConsoleCursorPosition (IntPtr handle, Coord coord);
563
564                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleTextAttribute", SetLastError=true, CharSet=CharSet.Unicode)]
565                 extern static bool SetConsoleTextAttribute (IntPtr handle, short attribute);
566
567                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleScreenBufferSize", SetLastError=true, CharSet=CharSet.Unicode)]
568                 extern static bool SetConsoleScreenBufferSize (IntPtr handle, Coord newSize);
569
570                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleWindowInfo", SetLastError=true, CharSet=CharSet.Unicode)]
571                 extern static bool SetConsoleWindowInfo (IntPtr handle, bool absolute, ref SmallRect rect);
572
573                 [DllImport ("kernel32.dll", EntryPoint="GetConsoleTitle", SetLastError=true, CharSet=CharSet.Unicode)]
574                 extern static int GetConsoleTitle (StringBuilder sb, int size);
575
576                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleTitle", SetLastError=true, CharSet=CharSet.Unicode)]
577                 extern static bool SetConsoleTitle (string title);
578
579                 [DllImport ("kernel32.dll", EntryPoint="GetConsoleCursorInfo", SetLastError=true, CharSet=CharSet.Unicode)]
580                 extern static bool GetConsoleCursorInfo (IntPtr handle, out ConsoleCursorInfo info);
581
582                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleCursorInfo", SetLastError=true, CharSet=CharSet.Unicode)]
583                 extern static bool SetConsoleCursorInfo (IntPtr handle, ref ConsoleCursorInfo info);
584
585                 [DllImport ("user32.dll", EntryPoint="GetKeyState", SetLastError=true, CharSet=CharSet.Unicode)]
586                 extern static short GetKeyState (int virtKey);
587
588                 [DllImport ("kernel32.dll", EntryPoint="GetConsoleMode", SetLastError=true, CharSet=CharSet.Unicode)]
589                 extern static bool GetConsoleMode (IntPtr handle, out int mode);
590
591                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleMode", SetLastError=true, CharSet=CharSet.Unicode)]
592                 extern static bool SetConsoleMode (IntPtr handle, int mode);
593
594                 [DllImport ("kernel32.dll", EntryPoint="PeekConsoleInput", SetLastError=true, CharSet=CharSet.Unicode)]
595                 extern static bool PeekConsoleInput (IntPtr handle, out InputRecord record, int length, out int eventsRead);
596
597                 [DllImport ("kernel32.dll", EntryPoint="ReadConsoleInput", SetLastError=true, CharSet=CharSet.Unicode)]
598                 extern static bool ReadConsoleInput (IntPtr handle, out InputRecord record, int length, out int nread);
599
600                 [DllImport ("kernel32.dll", EntryPoint="GetLargestConsoleWindowSize", SetLastError=true, CharSet=CharSet.Unicode)]
601                 extern static Coord GetLargestConsoleWindowSize (IntPtr handle);
602
603                 [DllImport ("kernel32.dll", EntryPoint="ReadConsoleOutput", SetLastError=true, CharSet=CharSet.Unicode)]
604                 extern static bool ReadConsoleOutput (IntPtr handle, void *buffer, Coord bsize, Coord bpos, ref SmallRect region);
605
606                 [DllImport ("kernel32.dll", EntryPoint="WriteConsoleOutput", SetLastError=true, CharSet=CharSet.Unicode)]
607                 extern static bool WriteConsoleOutput (IntPtr handle, CharInfo [] buffer, Coord bsize, Coord bpos, ref SmallRect region);
608         }
609 }
610 #endif
611