5 // Dietmar Maurer (dietmar@ximian.com)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // (C) Ximian, Inc. http://www.ximian.com
9 // (C) 2004,2005 Novell, Inc. (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #if NET_2_0 || BOOTSTRAP_NET_2_0
36 using System.Runtime.CompilerServices;
37 using System.Runtime.InteropServices;
38 using System.Security.Permissions;
52 private class WindowsConsole
54 [DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
55 private static extern int GetConsoleCP ();
56 [DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
57 private static extern int GetConsoleOutputCP ();
59 [MethodImpl (MethodImplOptions.NoInlining)]
60 public static int GetInputCodePage ()
62 return GetConsoleCP ();
65 [MethodImpl (MethodImplOptions.NoInlining)]
66 public static int GetOutputCodePage ()
68 return GetConsoleOutputCP ();
72 internal static TextWriter stdout;
73 private static TextWriter stderr;
74 private static TextReader stdin;
78 #if !NET2_API || NET_2_1
79 Encoding inputEncoding;
80 Encoding outputEncoding;
83 if (Environment.IsRunningOnWindows) {
85 // On Windows, follow the Windows tradition
88 // should never happen since Moonlight does not run on windows
89 inputEncoding = outputEncoding = Encoding.GetEncoding (28591);
92 inputEncoding = Encoding.GetEncoding (WindowsConsole.GetInputCodePage ());
93 outputEncoding = Encoding.GetEncoding (WindowsConsole.GetOutputCodePage ());
94 // ArgumentException and NotSupportedException can be thrown as well
96 // FIXME: I18N assemblies are not available when compiling mcs
97 // Use Latin 1 as it is fast and UTF-8 is never used as console code page
98 inputEncoding = outputEncoding = Encoding.GetEncoding (28591);
103 // On Unix systems (128), do not output the
104 // UTF-8 ZWNBSP (zero-width non-breaking space).
107 Encoding.InternalCodePage (ref code_page);
109 if (code_page != -1 && ((code_page & 0x0fffffff) == 3 // UTF8Encoding.UTF8_CODE_PAGE
110 || ((code_page & 0x10000000) != 0)))
111 inputEncoding = outputEncoding = Encoding.UTF8Unmarked;
113 inputEncoding = outputEncoding = Encoding.Default;
116 stderr = new UnexceptionalStreamWriter (OpenStandardError (0), outputEncoding);
117 ((StreamWriter)stderr).AutoFlush = true;
118 stderr = TextWriter.Synchronized (stderr, true);
120 #if NET2_API && !NET_2_1
121 if (!Environment.IsRunningOnWindows && ConsoleDriver.IsConsole) {
122 StreamWriter w = new CStreamWriter (OpenStandardOutput (0), outputEncoding);
124 stdout = TextWriter.Synchronized (w, true);
125 stdin = new CStreamReader (OpenStandardInput (0), inputEncoding);
128 stdout = new UnexceptionalStreamWriter (OpenStandardOutput (0), outputEncoding);
129 ((StreamWriter)stdout).AutoFlush = true;
130 stdout = TextWriter.Synchronized (stdout, true);
131 stdin = new UnexceptionalStreamReader (OpenStandardInput (0), inputEncoding);
132 stdin = TextReader.Synchronized (stdin);
133 #if NET2_API && !NET_2_1
137 GC.SuppressFinalize (stdout);
138 GC.SuppressFinalize (stderr);
139 GC.SuppressFinalize (stdin);
148 public static TextWriter Error {
154 public static TextWriter Out {
160 public static TextReader In {
166 public static Stream OpenStandardError ()
168 return OpenStandardError (0);
171 // calling any FileStream constructor with a handle normally
172 // requires permissions UnmanagedCode permissions. In this
173 // case we assert this permission so the console can be used
174 // in partial trust (i.e. without having UnmanagedCode).
175 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
176 public static Stream OpenStandardError (int bufferSize)
179 return new FileStream (MonoIO.ConsoleError, FileAccess.Write, false, bufferSize, false, bufferSize == 0);
180 } catch (IOException) {
181 return new NullStream ();
185 public static Stream OpenStandardInput ()
187 return OpenStandardInput (0);
190 // calling any FileStream constructor with a handle normally
191 // requires permissions UnmanagedCode permissions. In this
192 // case we assert this permission so the console can be used
193 // in partial trust (i.e. without having UnmanagedCode).
194 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
195 public static Stream OpenStandardInput (int bufferSize)
198 return new FileStream (MonoIO.ConsoleInput, FileAccess.Read, false, bufferSize, false, bufferSize == 0);
199 } catch (IOException) {
200 return new NullStream ();
204 public static Stream OpenStandardOutput ()
206 return OpenStandardOutput (0);
209 // calling any FileStream constructor with a handle normally
210 // requires permissions UnmanagedCode permissions. In this
211 // case we assert this permission so the console can be used
212 // in partial trust (i.e. without having UnmanagedCode).
213 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
214 public static Stream OpenStandardOutput (int bufferSize)
217 return new FileStream (MonoIO.ConsoleOutput, FileAccess.Write, false, bufferSize, false, bufferSize == 0);
218 } catch (IOException) {
219 return new NullStream ();
223 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
224 public static void SetError (TextWriter newError)
226 if (newError == null)
227 throw new ArgumentNullException ("newError");
232 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
233 public static void SetIn (TextReader newIn)
236 throw new ArgumentNullException ("newIn");
241 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
242 public static void SetOut (TextWriter newOut)
245 throw new ArgumentNullException ("newOut");
250 public static void Write (bool value)
252 stdout.Write (value);
255 public static void Write (char value)
257 stdout.Write (value);
260 public static void Write (char[] buffer)
262 stdout.Write (buffer);
265 public static void Write (decimal value)
267 stdout.Write (value);
270 public static void Write (double value)
272 stdout.Write (value);
275 public static void Write (int value)
277 stdout.Write (value);
280 public static void Write (long value)
282 stdout.Write (value);
285 public static void Write (object value)
287 stdout.Write (value);
290 public static void Write (float value)
292 stdout.Write (value);
295 public static void Write (string value)
297 stdout.Write (value);
300 [CLSCompliant (false)]
301 public static void Write (uint value)
303 stdout.Write (value);
306 [CLSCompliant (false)]
307 public static void Write (ulong value)
309 stdout.Write (value);
312 public static void Write (string format, object arg0)
314 stdout.Write (format, arg0);
317 public static void Write (string format, params object[] arg)
319 stdout.Write (format, arg);
322 public static void Write (char[] buffer, int index, int count)
324 stdout.Write (buffer, index, count);
327 public static void Write (string format, object arg0, object arg1)
329 stdout.Write (format, arg0, arg1);
332 public static void Write (string format, object arg0, object arg1, object arg2 )
334 stdout.Write (format, arg0, arg1, arg2);
337 #if ! BOOTSTRAP_WITH_OLDLIB
338 [CLSCompliant (false)]
339 public static void Write (string format, object arg0, object arg1, object arg2, object arg3, __arglist)
341 ArgIterator iter = new ArgIterator (__arglist);
342 int argCount = iter.GetRemainingCount();
344 object[] args = new object [argCount + 4];
349 for (int i = 0; i < argCount; i++) {
350 TypedReference typedRef = iter.GetNextArg ();
351 args [i + 4] = TypedReference.ToObject (typedRef);
354 stdout.Write (String.Format (format, args));
358 public static void WriteLine ()
363 public static void WriteLine (bool value)
365 stdout.WriteLine (value);
368 public static void WriteLine (char value)
370 stdout.WriteLine (value);
373 public static void WriteLine (char[] buffer)
375 stdout.WriteLine (buffer);
378 public static void WriteLine (decimal value)
380 stdout.WriteLine (value);
383 public static void WriteLine (double value)
385 stdout.WriteLine (value);
388 public static void WriteLine (int value)
390 stdout.WriteLine (value);
393 public static void WriteLine (long value)
395 stdout.WriteLine (value);
398 public static void WriteLine (object value)
400 stdout.WriteLine (value);
403 public static void WriteLine (float value)
405 stdout.WriteLine (value);
408 public static void WriteLine (string value)
410 stdout.WriteLine (value);
413 [CLSCompliant (false)]
414 public static void WriteLine (uint value)
416 stdout.WriteLine (value);
419 [CLSCompliant (false)]
420 public static void WriteLine (ulong value)
422 stdout.WriteLine (value);
425 public static void WriteLine (string format, object arg0)
427 stdout.WriteLine (format, arg0);
430 public static void WriteLine (string format, params object[] arg)
432 stdout.WriteLine (format, arg);
435 public static void WriteLine (char[] buffer, int index, int count)
437 stdout.WriteLine (buffer, index, count);
440 public static void WriteLine (string format, object arg0, object arg1)
442 stdout.WriteLine (format, arg0, arg1);
445 public static void WriteLine (string format, object arg0, object arg1, object arg2)
447 stdout.WriteLine (format, arg0, arg1, arg2);
450 #if ! BOOTSTRAP_WITH_OLDLIB
451 [CLSCompliant (false)]
452 public static void WriteLine (string format, object arg0, object arg1, object arg2, object arg3, __arglist)
454 ArgIterator iter = new ArgIterator (__arglist);
455 int argCount = iter.GetRemainingCount();
457 object[] args = new object [argCount + 4];
462 for (int i = 0; i < argCount; i++) {
463 TypedReference typedRef = iter.GetNextArg ();
464 args [i + 4] = TypedReference.ToObject (typedRef);
467 stdout.WriteLine (String.Format (format, args));
471 #if NET2_API && !NET_2_1
472 public static int Read ()
474 if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
475 return ConsoleDriver.Read ();
477 return stdin.Read ();
481 public static string ReadLine ()
483 if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
484 return ConsoleDriver.ReadLine ();
486 return stdin.ReadLine ();
490 public static int Read ()
492 return stdin.Read ();
495 public static string ReadLine ()
497 return stdin.ReadLine ();
502 #if NET2_API && !NET_2_1
503 // FIXME: Console should use these encodings when changed
504 static Encoding inputEncoding;
505 static Encoding outputEncoding;
507 public static Encoding InputEncoding {
508 get { return inputEncoding; }
509 set { inputEncoding = value; }
512 public static Encoding OutputEncoding {
513 get { return outputEncoding; }
514 set { outputEncoding = value; }
517 public static ConsoleColor BackgroundColor {
518 get { return ConsoleDriver.BackgroundColor; }
519 set { ConsoleDriver.BackgroundColor = value; }
522 public static int BufferHeight {
523 get { return ConsoleDriver.BufferHeight; }
524 set { ConsoleDriver.BufferHeight = value; }
527 public static int BufferWidth {
528 get { return ConsoleDriver.BufferWidth; }
529 set { ConsoleDriver.BufferWidth = value; }
532 public static bool CapsLock {
533 get { return ConsoleDriver.CapsLock; }
536 public static int CursorLeft {
537 get { return ConsoleDriver.CursorLeft; }
538 set { ConsoleDriver.CursorLeft = value; }
541 public static int CursorTop {
542 get { return ConsoleDriver.CursorTop; }
543 set { ConsoleDriver.CursorTop = value; }
546 public static int CursorSize {
547 get { return ConsoleDriver.CursorSize; }
548 set { ConsoleDriver.CursorSize = value; }
551 public static bool CursorVisible {
552 get { return ConsoleDriver.CursorVisible; }
553 set { ConsoleDriver.CursorVisible = value; }
556 public static ConsoleColor ForegroundColor {
557 get { return ConsoleDriver.ForegroundColor; }
558 set { ConsoleDriver.ForegroundColor = value; }
561 public static bool KeyAvailable {
562 get { return ConsoleDriver.KeyAvailable; }
565 public static int LargestWindowHeight {
566 get { return ConsoleDriver.LargestWindowHeight; }
569 public static int LargestWindowWidth {
570 get { return ConsoleDriver.LargestWindowWidth; }
573 public static bool NumberLock {
574 get { return ConsoleDriver.NumberLock; }
577 public static string Title {
578 get { return ConsoleDriver.Title; }
579 set { ConsoleDriver.Title = value; }
582 public static bool TreatControlCAsInput {
583 get { return ConsoleDriver.TreatControlCAsInput; }
584 set { ConsoleDriver.TreatControlCAsInput = value; }
587 public static int WindowHeight {
588 get { return ConsoleDriver.WindowHeight; }
589 set { ConsoleDriver.WindowHeight = value; }
592 public static int WindowLeft {
593 get { return ConsoleDriver.WindowLeft; }
594 set { ConsoleDriver.WindowLeft = value; }
597 public static int WindowTop {
598 get { return ConsoleDriver.WindowTop; }
599 set { ConsoleDriver.WindowTop = value; }
602 public static int WindowWidth {
603 get { return ConsoleDriver.WindowWidth; }
604 set { ConsoleDriver.WindowWidth = value; }
607 public static void Beep ()
612 public static void Beep (int frequency, int duration)
614 if (frequency < 37 || frequency > 32767)
615 throw new ArgumentOutOfRangeException ("frequency");
618 throw new ArgumentOutOfRangeException ("duration");
620 ConsoleDriver.Beep (frequency, duration);
623 public static void Clear ()
625 ConsoleDriver.Clear ();
628 [MonoLimitation ("Implemented only on Windows")]
629 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
630 int targetLeft, int targetTop)
632 ConsoleDriver.MoveBufferArea (sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop);
635 [MonoLimitation ("Implemented only on Windows")]
636 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
637 int targetLeft, int targetTop, Char sourceChar,
638 ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
640 ConsoleDriver.MoveBufferArea (sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop,
641 sourceChar, sourceForeColor, sourceBackColor);
644 public static ConsoleKeyInfo ReadKey ()
646 return ReadKey (false);
649 public static ConsoleKeyInfo ReadKey (bool intercept)
651 return ConsoleDriver.ReadKey (intercept);
654 public static void ResetColor ()
656 ConsoleDriver.ResetColor ();
659 public static void SetBufferSize (int width, int height)
661 ConsoleDriver.SetBufferSize (width, height);
664 public static void SetCursorPosition (int left, int top)
666 ConsoleDriver.SetCursorPosition (left, top);
669 public static void SetWindowPosition (int left, int top)
671 ConsoleDriver.SetWindowPosition (left, top);
674 public static void SetWindowSize (int width, int height)
676 ConsoleDriver.SetWindowSize (width, height);
679 static ConsoleCancelEventHandler cancel_event;
680 public static event ConsoleCancelEventHandler CancelKeyPress {
682 if (ConsoleDriver.Initialized == false)
683 ConsoleDriver.Init ();
685 cancel_event += value;
688 if (ConsoleDriver.Initialized == false)
689 ConsoleDriver.Init ();
691 cancel_event -= value;
695 delegate void InternalCancelHandler ();
697 #pragma warning disable 414
699 // Used by console-io.c
701 static readonly InternalCancelHandler cancel_handler = new InternalCancelHandler (DoConsoleCancelEvent);
702 #pragma warning restore 414
704 internal static void DoConsoleCancelEvent ()
707 if (cancel_event != null) {
708 ConsoleCancelEventArgs args = new ConsoleCancelEventArgs (ConsoleSpecialKey.ControlC);
709 Delegate [] delegates = cancel_event.GetInvocationList ();
710 foreach (ConsoleCancelEventHandler d in delegates){
712 // Sender is always null here.
714 } catch {} // Ignore any exception.
720 Environment.Exit (58);