Merge pull request #4248 from Unity-Technologies/boehm-gc-alloc-fixed
[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 MONO_FEATURE_CONSOLE
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 #pragma warning disable 169
39         struct InputRecord {
40                 public short EventType;
41                 // This is KEY_EVENT_RECORD
42                 public bool KeyDown;
43                 public short RepeatCount;
44                 public short VirtualKeyCode;
45                 public short VirtualScanCode;
46                 public char Character;
47                 public int ControlKeyState;
48                 int pad1;
49                 bool pad2;
50                 //
51         }
52 #pragma warning restore 169
53
54         struct CharInfo {
55                 public char Character;
56                 public short Attributes;
57         }
58         
59         struct Coord {
60                 public short X;
61                 public short Y;
62
63                 public Coord (int x, int y)
64                 {
65                         X = (short) x;
66                         Y = (short) y;
67                 }
68         }
69
70         struct SmallRect {
71                 public short Left;
72                 public short Top;
73                 public short Right;
74                 public short Bottom;
75
76                 public SmallRect (int left, int top, int right, int bottom)
77                 {
78                         Left = (short) left;
79                         Top = (short) top;
80                         Right = (short) right;
81                         Bottom = (short) bottom;
82                 }
83         }
84
85         struct ConsoleScreenBufferInfo {
86                 public Coord Size;
87                 public Coord CursorPosition;
88                 public short Attribute;
89                 public SmallRect Window;
90                 public Coord MaxWindowSize;
91         }
92
93         enum Handles {
94                 STD_INPUT = -10,
95                 STD_OUTPUT = -11,
96                 STD_ERROR = -12
97         }
98
99         unsafe class WindowsConsoleDriver : IConsoleDriver {
100                 IntPtr inputHandle;
101                 IntPtr outputHandle;
102                 short defaultAttribute;
103
104                 public WindowsConsoleDriver ()
105                 {
106                         outputHandle = GetStdHandle (Handles.STD_OUTPUT);
107                         inputHandle = GetStdHandle (Handles.STD_INPUT);
108                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
109                         GetConsoleScreenBufferInfo (outputHandle, out info);
110                         defaultAttribute = info.Attribute; // Not sure about this...
111                 }
112
113                 // FOREGROUND_BLUE      1
114                 // FOREGROUND_GREEN     2
115                 // FOREGROUND_RED       4
116                 // FOREGROUND_INTENSITY 8
117                 // BACKGROUND_BLUE      16
118                 // BACKGROUND_GREEN     32
119                 // BACKGROUND_RED       64
120                 // BACKGROUND_INTENSITY 128
121                 static ConsoleColor GetForeground (short attr)
122                 {
123                         attr &= 0x0F;
124                         return (ConsoleColor) attr;
125                 }
126
127                 static ConsoleColor GetBackground (short attr)
128                 {
129                         attr &= 0xF0;
130                         attr >>= 4;
131                         return (ConsoleColor) attr;
132                 }
133
134                 static short GetAttrForeground (int attr, ConsoleColor color)
135                 {
136                         attr &= ~15;
137                         return (short) (attr | (int) color);
138                 }
139
140                 static short GetAttrBackground (int attr, ConsoleColor color)
141                 {
142                         attr &= ~0xf0;
143                         int c = ((int) color) << 4;
144                         return (short) (attr | c);
145                 }
146
147                 public ConsoleColor BackgroundColor {
148                         get {
149                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
150                                 GetConsoleScreenBufferInfo (outputHandle, out info);
151                                 return GetBackground (info.Attribute);
152                         }
153                         set {
154                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
155                                 GetConsoleScreenBufferInfo (outputHandle, out info);
156                                 short attr = GetAttrBackground (info.Attribute, value);
157                                 SetConsoleTextAttribute (outputHandle, attr);
158                         }
159                 }
160
161                 public int BufferHeight {
162                         get {
163                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
164                                 GetConsoleScreenBufferInfo (outputHandle, out info);
165                                 return info.Size.Y;
166                         }
167                         set { SetBufferSize (BufferWidth, value); }
168                 }
169
170                 public int BufferWidth {
171                         get {
172                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
173                                 GetConsoleScreenBufferInfo (outputHandle, out info);
174                                 return info.Size.X;
175                         }
176                         set { SetBufferSize (value, BufferHeight); }
177                 }
178
179                 public bool CapsLock {
180                         get {
181                                 short state = GetKeyState (20); // VK_CAPITAL
182                                 return ((state & 1) == 1);
183                         }
184                 }
185
186                 public int CursorLeft {
187                         get {
188                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
189                                 GetConsoleScreenBufferInfo (outputHandle, out info);
190                                 return info.CursorPosition.X;
191                         }
192                         set { SetCursorPosition (value, CursorTop); }
193                 }
194
195                 public int CursorSize {
196                         get {
197                                 ConsoleCursorInfo info = new ConsoleCursorInfo ();
198                                 GetConsoleCursorInfo (outputHandle, out info);
199                                 return info.Size;
200                         }
201                         set {
202                                 if (value < 1 || value > 100)
203                                         throw new ArgumentOutOfRangeException ("value");
204
205                                 ConsoleCursorInfo info = new ConsoleCursorInfo ();
206                                 GetConsoleCursorInfo (outputHandle, out info);
207                                 info.Size = value;
208                                 if (!SetConsoleCursorInfo (outputHandle, ref info))
209                                         throw new Exception ("SetConsoleCursorInfo failed");
210                         }
211                 }
212
213                 public int CursorTop {
214                         get {
215                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
216                                 GetConsoleScreenBufferInfo (outputHandle, out info);
217                                 return info.CursorPosition.Y;
218                         }
219                         set { SetCursorPosition (CursorLeft, value); }
220                 }
221
222                 public bool CursorVisible {
223                         get {
224                                 ConsoleCursorInfo info = new ConsoleCursorInfo ();
225                                 GetConsoleCursorInfo (outputHandle, out info);
226                                 return info.Visible;
227                         }
228                         set {
229                                 ConsoleCursorInfo info = new ConsoleCursorInfo ();
230                                 GetConsoleCursorInfo (outputHandle, out info);
231                                 if (info.Visible == value)
232                                         return;
233
234                                 info.Visible = value;
235                                 if (!SetConsoleCursorInfo (outputHandle, ref info))
236                                         throw new Exception ("SetConsoleCursorInfo failed");
237                         }
238                 }
239
240                 public ConsoleColor ForegroundColor {
241                         get {
242                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
243                                 GetConsoleScreenBufferInfo (outputHandle, out info);
244                                 return GetForeground (info.Attribute);
245                         }
246                         set {
247                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
248                                 GetConsoleScreenBufferInfo (outputHandle, out info);
249                                 short attr = GetAttrForeground (info.Attribute, value);
250                                 SetConsoleTextAttribute (outputHandle, attr);
251                         }
252                 }
253
254                 public bool KeyAvailable {
255                         get {
256                                 int eventsRead;
257                                 InputRecord record = new InputRecord ();
258                                 while (true) {
259                                         // Use GetNumberOfConsoleInputEvents and remove the while?
260                                         if (!PeekConsoleInput (inputHandle, out record, 1, out eventsRead))
261                                                 throw new InvalidOperationException ("Error in PeekConsoleInput " +
262                                                                                 Marshal.GetLastWin32Error ());
263
264                                         if (eventsRead == 0)
265                                                 return false;
266
267                                         //KEY_EVENT == 1
268                                         if (record.EventType == 1 && record.KeyDown && !IsModifierKey (record.VirtualKeyCode))
269                                                 return true;
270
271                                         if (!ReadConsoleInput (inputHandle, out record, 1, out eventsRead))
272                                                 throw new InvalidOperationException ("Error in ReadConsoleInput " +
273                                                                                 Marshal.GetLastWin32Error ());
274                                 }
275                         }
276                 }
277
278                 public bool Initialized { // Not useful on windows, so false.
279                         get { return false; }
280                 }
281
282                 public int LargestWindowHeight {
283                         get {
284                                 Coord coord = GetLargestConsoleWindowSize (outputHandle);
285                                 if (coord.X == 0 && coord.Y == 0)
286                                         throw new Exception ("GetLargestConsoleWindowSize" + Marshal.GetLastWin32Error ());
287
288                                 return coord.Y;
289                         }
290                 }
291
292                 public int LargestWindowWidth {
293                         get {
294                                 Coord coord = GetLargestConsoleWindowSize (outputHandle);
295                                 if (coord.X == 0 && coord.Y == 0)
296                                         throw new Exception ("GetLargestConsoleWindowSize" + Marshal.GetLastWin32Error ());
297
298                                 return coord.X;
299                         }
300                 }
301
302                 public bool NumberLock {
303                         get {
304                                 short state = GetKeyState (144); // VK_NUMLOCK
305                                 return ((state & 1) == 1);
306                         }
307                 }
308
309                 public string Title {
310                         get {
311                                 StringBuilder sb = new StringBuilder (1024); // hope this is enough
312                                 if (GetConsoleTitle (sb, 1024) == 0) {
313                                         // Try the maximum
314                                         sb = new StringBuilder (26001);
315                                         if (GetConsoleTitle (sb, 26000) == 0)
316                                                 throw new Exception ("Got " + Marshal.GetLastWin32Error ());
317                                 }
318
319                                 return sb.ToString ();
320                         }
321                         set {
322                                 if (value == null)
323                                         throw new ArgumentNullException ("value");
324
325                                 if (!SetConsoleTitle (value))
326                                         throw new Exception ("Got " + Marshal.GetLastWin32Error ());
327                         }
328                 }
329
330                 public bool TreatControlCAsInput {
331                         get {
332                                 int mode;
333                                 if (!GetConsoleMode (inputHandle, out mode))
334                                         throw new Exception ("Failed in GetConsoleMode: " + Marshal.GetLastWin32Error ());
335
336                                 // ENABLE_PROCESSED_INPUT
337                                 return ((mode & 1) == 0);
338                         }
339
340                         set {
341                                 int mode;
342                                 if (!GetConsoleMode (inputHandle, out mode))
343                                         throw new Exception ("Failed in GetConsoleMode: " + Marshal.GetLastWin32Error ());
344
345                                 bool cAsInput = ((mode & 1) == 0);
346                                 if (cAsInput == value)
347                                         return;
348
349                                 if (value)
350                                         mode &= ~1;
351                                 else
352                                         mode |= 1;
353
354                                 if (!SetConsoleMode (inputHandle, mode))
355                                         throw new Exception ("Failed in SetConsoleMode: " + Marshal.GetLastWin32Error ());
356                         }
357                 }
358
359                 public int WindowHeight {
360                         get {
361                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
362                                 GetConsoleScreenBufferInfo (outputHandle, out info);
363                                 return info.Window.Bottom - info.Window.Top + 1;
364                         }
365                         set { SetWindowSize (WindowWidth, value); }
366                 }
367
368                 public int WindowLeft {
369                         get {
370                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
371                                 GetConsoleScreenBufferInfo (outputHandle, out info);
372                                 return info.Window.Left;
373                         }
374                         set { SetWindowPosition (value, WindowTop); }
375                 }
376
377                 public int WindowTop {
378                         get {
379                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
380                                 GetConsoleScreenBufferInfo (outputHandle, out info);
381                                 return info.Window.Top;
382                         }
383                         set { SetWindowPosition (WindowLeft, value); }
384                 }
385
386                 public int WindowWidth {
387                         get {
388                                 ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
389                                 GetConsoleScreenBufferInfo (outputHandle, out info);
390                                 return info.Window.Right - info.Window.Left + 1;
391                         }
392                         set { SetWindowSize (value, WindowHeight); }
393                 }
394
395                 public void Beep (int frequency, int duration)
396                 {
397                         _Beep (frequency, duration);
398                 }
399
400                 public void Clear ()
401                 {
402                         Coord coord = new Coord ();
403                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
404                         GetConsoleScreenBufferInfo (outputHandle, out info);
405
406                         int size = info.Size.X * info.Size.Y;
407                         int written;
408                         FillConsoleOutputCharacter (outputHandle, ' ', size, coord, out written);
409
410                         GetConsoleScreenBufferInfo (outputHandle, out info);
411
412                         FillConsoleOutputAttribute (outputHandle, info.Attribute, size, coord, out written);
413                         SetConsoleCursorPosition (outputHandle, coord);
414                 }
415
416                 public void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
417                                         int targetLeft, int targetTop, Char sourceChar,
418                                         ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
419                 {
420                         if (sourceForeColor < 0)
421                                 throw new ArgumentException ("Cannot be less than 0.", "sourceForeColor");
422
423                         if (sourceBackColor < 0)
424                                 throw new ArgumentException ("Cannot be less than 0.", "sourceBackColor");
425
426                         if (sourceWidth == 0 || sourceHeight == 0)
427                                 return;
428
429                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
430                         GetConsoleScreenBufferInfo (outputHandle, out info);
431                         CharInfo [] buffer = new CharInfo [sourceWidth * sourceHeight];
432                         Coord bsize = new Coord (sourceWidth, sourceHeight);
433                         Coord bpos = new Coord (0, 0);
434                         SmallRect region = new SmallRect (sourceLeft, sourceTop, sourceLeft + sourceWidth - 1, sourceTop + sourceHeight - 1);
435                         fixed (void *ptr = &buffer [0]) {
436                                 if (!ReadConsoleOutput (outputHandle, ptr, bsize, bpos, ref region))
437                                         throw new ArgumentException (String.Empty, "Cannot read from the specified coordinates.");
438                         }
439
440                         int written;
441                         short attr  = GetAttrForeground (0, sourceForeColor);
442                         attr  = GetAttrBackground (attr, sourceBackColor);
443                         bpos = new Coord (sourceLeft, sourceTop);
444                         for (int i = 0; i < sourceHeight; i++, bpos.Y++) {
445                                 FillConsoleOutputCharacter (outputHandle, sourceChar, sourceWidth, bpos, out written);
446                                 FillConsoleOutputAttribute (outputHandle, attr, sourceWidth, bpos, out written);
447                         }
448
449                         bpos = new Coord (0, 0);
450                         region = new SmallRect (targetLeft, targetTop, targetLeft + sourceWidth - 1, targetTop + sourceHeight - 1);
451                         if (!WriteConsoleOutput (outputHandle, buffer, bsize, bpos, ref region))
452                                 throw new ArgumentException (String.Empty, "Cannot write to the specified coordinates.");
453                 }
454
455                 public void Init ()
456                 {
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                         for (;;) {
478                                 if (!ReadConsoleInput (inputHandle, out record, 1, out eventsRead))
479                                         throw new InvalidOperationException ("Error in ReadConsoleInput " +
480                                                                         Marshal.GetLastWin32Error ());
481                                 if (record.KeyDown && record.EventType == 1 && !IsModifierKey (record.VirtualKeyCode))
482                                         break;
483                         }
484
485                         // RIGHT_ALT_PRESSED 1
486                         // LEFT_ALT_PRESSED 2
487                         // RIGHT_CTRL_PRESSED 4
488                         // LEFT_CTRL_PRESSED 8
489                         // SHIFT_PRESSED 16
490                         bool alt = ((record.ControlKeyState & 3) != 0);
491                         bool ctrl = ((record.ControlKeyState & 12) != 0);
492                         bool shift = ((record.ControlKeyState & 16) != 0);
493                         return new ConsoleKeyInfo (record.Character, (ConsoleKey) record.VirtualKeyCode, shift, alt, ctrl);
494                 }
495
496                 public void ResetColor ()
497                 {
498                         SetConsoleTextAttribute (outputHandle, defaultAttribute);
499                 }
500
501                 public void SetBufferSize (int width, int height)
502                 {
503                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
504                         GetConsoleScreenBufferInfo (outputHandle, out info);
505
506                         if (width - 1 > info.Window.Right)
507                                 throw new ArgumentOutOfRangeException ("width");
508
509                         if (height - 1 > info.Window.Bottom)
510                                 throw new ArgumentOutOfRangeException ("height");
511
512                         Coord coord = new Coord (width, height);
513                         if (!SetConsoleScreenBufferSize (outputHandle, coord))
514                                 throw new ArgumentOutOfRangeException ("height/width", "Cannot be smaller than the window size.");
515                 }
516
517                 public void SetCursorPosition (int left, int top)
518                 {
519                         Coord coord = new Coord (left, top);
520                         SetConsoleCursorPosition (outputHandle, coord);
521                 }
522
523                 public void SetWindowPosition (int left, int top)
524                 {
525                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
526                         GetConsoleScreenBufferInfo (outputHandle, out info);
527                         SmallRect rect = info.Window;
528                         rect.Left = (short) left;
529                         rect.Top = (short) top;
530                         if (!SetConsoleWindowInfo (outputHandle, true, ref rect))
531                                 throw new ArgumentOutOfRangeException ("left/top", "Windows error " + Marshal.GetLastWin32Error ());
532                 }
533
534                 public void SetWindowSize (int width, int height)
535                 {
536                         ConsoleScreenBufferInfo info = new ConsoleScreenBufferInfo ();
537                         GetConsoleScreenBufferInfo (outputHandle, out info);
538                         SmallRect rect = info.Window;
539                         rect.Right = (short) (rect.Left + width - 1);
540                         rect.Bottom = (short) (rect.Top + height - 1);
541                         if (!SetConsoleWindowInfo (outputHandle, true, ref rect))
542                                 throw new ArgumentOutOfRangeException ("left/top", "Windows error " + Marshal.GetLastWin32Error ());
543                 }
544
545                 static bool IsModifierKey (short virtualKeyCode)
546                 {
547                         // 0x10 through 0x14 is shift/control/alt/pause/capslock
548                         // 0x2C is print screen, 0x90 is numlock, 0x91 is scroll lock
549                         switch (virtualKeyCode) {
550                         case 0x10:
551                         case 0x11:
552                         case 0x12:
553                         case 0x14:
554                         case 0x90:
555                         case 0x91:
556                                 return true;
557                         default:
558                                 return false;
559                         }
560                 }
561
562                 //
563                 // Imports
564                 //
565                 [DllImport ("kernel32.dll", EntryPoint="GetStdHandle", SetLastError=true, CharSet=CharSet.Unicode)]
566                 extern static IntPtr GetStdHandle (Handles handle);
567
568                 [DllImport ("kernel32.dll", EntryPoint="Beep", SetLastError=true, CharSet=CharSet.Unicode)]
569                 extern static void _Beep (int frequency, int duration);
570
571                 [DllImport ("kernel32.dll", EntryPoint="GetConsoleScreenBufferInfo", SetLastError=true, CharSet=CharSet.Unicode)]
572                 extern static bool GetConsoleScreenBufferInfo (IntPtr handle, out ConsoleScreenBufferInfo info);
573
574                 [DllImport ("kernel32.dll", EntryPoint="FillConsoleOutputCharacter", SetLastError=true, CharSet=CharSet.Unicode)]
575                 extern static bool FillConsoleOutputCharacter (IntPtr handle, char c, int size, Coord coord, out int written);
576
577                 [DllImport ("kernel32.dll", EntryPoint="FillConsoleOutputAttribute", SetLastError=true, CharSet=CharSet.Unicode)]
578                 extern static bool FillConsoleOutputAttribute (IntPtr handle, short c, int size, Coord coord, out int written);
579
580                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleCursorPosition", SetLastError=true, CharSet=CharSet.Unicode)]
581                 extern static bool SetConsoleCursorPosition (IntPtr handle, Coord coord);
582
583                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleTextAttribute", SetLastError=true, CharSet=CharSet.Unicode)]
584                 extern static bool SetConsoleTextAttribute (IntPtr handle, short attribute);
585
586                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleScreenBufferSize", SetLastError=true, CharSet=CharSet.Unicode)]
587                 extern static bool SetConsoleScreenBufferSize (IntPtr handle, Coord newSize);
588
589                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleWindowInfo", SetLastError=true, CharSet=CharSet.Unicode)]
590                 extern static bool SetConsoleWindowInfo (IntPtr handle, bool absolute, ref SmallRect rect);
591
592                 [DllImport ("kernel32.dll", EntryPoint="GetConsoleTitle", SetLastError=true, CharSet=CharSet.Unicode)]
593                 extern static int GetConsoleTitle (StringBuilder sb, int size);
594
595                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleTitle", SetLastError=true, CharSet=CharSet.Unicode)]
596                 extern static bool SetConsoleTitle (string title);
597
598                 [DllImport ("kernel32.dll", EntryPoint="GetConsoleCursorInfo", SetLastError=true, CharSet=CharSet.Unicode)]
599                 extern static bool GetConsoleCursorInfo (IntPtr handle, out ConsoleCursorInfo info);
600
601                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleCursorInfo", SetLastError=true, CharSet=CharSet.Unicode)]
602                 extern static bool SetConsoleCursorInfo (IntPtr handle, ref ConsoleCursorInfo info);
603
604                 [DllImport ("user32.dll", EntryPoint="GetKeyState", SetLastError=true, CharSet=CharSet.Unicode)]
605                 extern static short GetKeyState (int virtKey);
606
607                 [DllImport ("kernel32.dll", EntryPoint="GetConsoleMode", SetLastError=true, CharSet=CharSet.Unicode)]
608                 extern static bool GetConsoleMode (IntPtr handle, out int mode);
609
610                 [DllImport ("kernel32.dll", EntryPoint="SetConsoleMode", SetLastError=true, CharSet=CharSet.Unicode)]
611                 extern static bool SetConsoleMode (IntPtr handle, int mode);
612
613                 [DllImport ("kernel32.dll", EntryPoint="PeekConsoleInput", SetLastError=true, CharSet=CharSet.Unicode)]
614                 extern static bool PeekConsoleInput (IntPtr handle, out InputRecord record, int length, out int eventsRead);
615
616                 [DllImport ("kernel32.dll", EntryPoint="ReadConsoleInput", SetLastError=true, CharSet=CharSet.Unicode)]
617                 extern static bool ReadConsoleInput (IntPtr handle, out InputRecord record, int length, out int nread);
618
619                 [DllImport ("kernel32.dll", EntryPoint="GetLargestConsoleWindowSize", SetLastError=true, CharSet=CharSet.Unicode)]
620                 extern static Coord GetLargestConsoleWindowSize (IntPtr handle);
621
622                 [DllImport ("kernel32.dll", EntryPoint="ReadConsoleOutput", SetLastError=true, CharSet=CharSet.Unicode)]
623                 extern static bool ReadConsoleOutput (IntPtr handle, void *buffer, Coord bsize, Coord bpos, ref SmallRect region);
624
625                 [DllImport ("kernel32.dll", EntryPoint="WriteConsoleOutput", SetLastError=true, CharSet=CharSet.Unicode)]
626                 extern static bool WriteConsoleOutput (IntPtr handle, CharInfo [] buffer, Coord bsize, Coord bpos, ref SmallRect region);
627         }
628 }
629 #endif
630