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.
32 using System.Diagnostics;
34 using System.Runtime.CompilerServices;
35 using System.Runtime.InteropServices;
36 using System.Security;
37 using System.Security.Permissions;
42 public static class Console
45 private class WindowsConsole
47 [DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
48 private static extern int GetConsoleCP ();
49 [DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
50 private static extern int GetConsoleOutputCP ();
52 [MethodImpl (MethodImplOptions.NoInlining)]
53 public static int GetInputCodePage ()
55 return GetConsoleCP ();
58 [MethodImpl (MethodImplOptions.NoInlining)]
59 public static int GetOutputCodePage ()
61 return GetConsoleOutputCP ();
65 internal static TextWriter stdout;
66 private static TextWriter stderr;
67 private static TextReader stdin;
72 Encoding inputEncoding;
73 Encoding outputEncoding;
76 if (Environment.IsRunningOnWindows) {
78 // On Windows, follow the Windows tradition
81 // should never happen since Moonlight does not run on windows
82 inputEncoding = outputEncoding = Encoding.Default;
85 inputEncoding = Encoding.GetEncoding (WindowsConsole.GetInputCodePage ());
86 outputEncoding = Encoding.GetEncoding (WindowsConsole.GetOutputCodePage ());
87 // ArgumentException and NotSupportedException can be thrown as well
89 // FIXME: I18N assemblies are not available when compiling mcs
90 // Use Latin 1 as it is fast and UTF-8 is never used as console code page
91 inputEncoding = outputEncoding = Encoding.Default;
96 // On Unix systems (128), do not output the
97 // UTF-8 ZWNBSP (zero-width non-breaking space).
100 Encoding.InternalCodePage (ref code_page);
102 if (code_page != -1 && ((code_page & 0x0fffffff) == 3 // UTF8Encoding.UTF8_CODE_PAGE
103 || ((code_page & 0x10000000) != 0)))
104 inputEncoding = outputEncoding = Encoding.UTF8Unmarked;
106 inputEncoding = outputEncoding = Encoding.Default;
109 stderr = new UnexceptionalStreamWriter (OpenStandardError (0), outputEncoding);
110 ((StreamWriter)stderr).AutoFlush = true;
111 stderr = TextWriter.Synchronized (stderr, true);
114 if (!Environment.IsRunningOnWindows && ConsoleDriver.IsConsole) {
115 StreamWriter w = new CStreamWriter (OpenStandardOutput (0), outputEncoding);
117 stdout = TextWriter.Synchronized (w, true);
118 stdin = new CStreamReader (OpenStandardInput (0), inputEncoding);
121 stdout = new UnexceptionalStreamWriter (OpenStandardOutput (0), outputEncoding);
122 ((StreamWriter)stdout).AutoFlush = true;
123 stdout = TextWriter.Synchronized (stdout, true);
124 stdin = new UnexceptionalStreamReader (OpenStandardInput (0), inputEncoding);
125 stdin = TextReader.Synchronized (stdin);
130 GC.SuppressFinalize (stdout);
131 GC.SuppressFinalize (stderr);
132 GC.SuppressFinalize (stdin);
135 public static TextWriter Error {
141 public static TextWriter Out {
147 public static TextReader In {
153 private static Stream Open (IntPtr handle, FileAccess access, int bufferSize)
156 if (SecurityManager.SecurityEnabled && !Debugger.IsAttached && Environment.GetEnvironmentVariable ("MOONLIGHT_ENABLE_CONSOLE") == null)
157 return new NullStream ();
160 return new FileStream (handle, access, false, bufferSize, false, bufferSize == 0);
161 } catch (IOException) {
162 return new NullStream ();
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)
178 return Open (MonoIO.ConsoleError, FileAccess.Write, bufferSize);
181 public static Stream OpenStandardInput ()
183 return OpenStandardInput (0);
186 // calling any FileStream constructor with a handle normally
187 // requires permissions UnmanagedCode permissions. In this
188 // case we assert this permission so the console can be used
189 // in partial trust (i.e. without having UnmanagedCode).
190 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
191 public static Stream OpenStandardInput (int bufferSize)
193 return Open (MonoIO.ConsoleInput, FileAccess.Read, bufferSize);
196 public static Stream OpenStandardOutput ()
198 return OpenStandardOutput (0);
201 // calling any FileStream constructor with a handle normally
202 // requires permissions UnmanagedCode permissions. In this
203 // case we assert this permission so the console can be used
204 // in partial trust (i.e. without having UnmanagedCode).
205 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
206 public static Stream OpenStandardOutput (int bufferSize)
208 return Open (MonoIO.ConsoleOutput, FileAccess.Write, bufferSize);
211 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
212 public static void SetError (TextWriter newError)
214 if (newError == null)
215 throw new ArgumentNullException ("newError");
220 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
221 public static void SetIn (TextReader newIn)
224 throw new ArgumentNullException ("newIn");
229 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
230 public static void SetOut (TextWriter newOut)
233 throw new ArgumentNullException ("newOut");
238 public static void Write (bool value)
240 stdout.Write (value);
243 public static void Write (char value)
245 stdout.Write (value);
248 public static void Write (char[] buffer)
250 stdout.Write (buffer);
253 public static void Write (decimal value)
255 stdout.Write (value);
258 public static void Write (double value)
260 stdout.Write (value);
263 public static void Write (int value)
265 stdout.Write (value);
268 public static void Write (long value)
270 stdout.Write (value);
273 public static void Write (object value)
275 stdout.Write (value);
278 public static void Write (float value)
280 stdout.Write (value);
283 public static void Write (string value)
285 stdout.Write (value);
288 [CLSCompliant (false)]
289 public static void Write (uint value)
291 stdout.Write (value);
294 [CLSCompliant (false)]
295 public static void Write (ulong value)
297 stdout.Write (value);
300 public static void Write (string format, object arg0)
302 stdout.Write (format, arg0);
305 public static void Write (string format, params object[] arg)
308 stdout.Write (format);
310 stdout.Write (format, arg);
313 public static void Write (char[] buffer, int index, int count)
315 stdout.Write (buffer, index, count);
318 public static void Write (string format, object arg0, object arg1)
320 stdout.Write (format, arg0, arg1);
323 public static void Write (string format, object arg0, object arg1, object arg2 )
325 stdout.Write (format, arg0, arg1, arg2);
328 [CLSCompliant (false)]
329 public static void Write (string format, object arg0, object arg1, object arg2, object arg3, __arglist)
331 ArgIterator iter = new ArgIterator (__arglist);
332 int argCount = iter.GetRemainingCount();
334 object[] args = new object [argCount + 4];
339 for (int i = 0; i < argCount; i++) {
340 TypedReference typedRef = iter.GetNextArg ();
341 args [i + 4] = TypedReference.ToObject (typedRef);
344 stdout.Write (String.Format (format, args));
347 public static void WriteLine ()
352 public static void WriteLine (bool value)
354 stdout.WriteLine (value);
357 public static void WriteLine (char value)
359 stdout.WriteLine (value);
362 public static void WriteLine (char[] buffer)
364 stdout.WriteLine (buffer);
367 public static void WriteLine (decimal value)
369 stdout.WriteLine (value);
372 public static void WriteLine (double value)
374 stdout.WriteLine (value);
377 public static void WriteLine (int value)
379 stdout.WriteLine (value);
382 public static void WriteLine (long value)
384 stdout.WriteLine (value);
387 public static void WriteLine (object value)
389 stdout.WriteLine (value);
392 public static void WriteLine (float value)
394 stdout.WriteLine (value);
397 public static void WriteLine (string value)
399 stdout.WriteLine (value);
402 [CLSCompliant (false)]
403 public static void WriteLine (uint value)
405 stdout.WriteLine (value);
408 [CLSCompliant (false)]
409 public static void WriteLine (ulong value)
411 stdout.WriteLine (value);
414 public static void WriteLine (string format, object arg0)
416 stdout.WriteLine (format, arg0);
419 public static void WriteLine (string format, params object[] arg)
422 stdout.WriteLine (format);
424 stdout.WriteLine (format, arg);
427 public static void WriteLine (char[] buffer, int index, int count)
429 stdout.WriteLine (buffer, index, count);
432 public static void WriteLine (string format, object arg0, object arg1)
434 stdout.WriteLine (format, arg0, arg1);
437 public static void WriteLine (string format, object arg0, object arg1, object arg2)
439 stdout.WriteLine (format, arg0, arg1, arg2);
442 [CLSCompliant (false)]
443 public static void WriteLine (string format, object arg0, object arg1, object arg2, object arg3, __arglist)
445 ArgIterator iter = new ArgIterator (__arglist);
446 int argCount = iter.GetRemainingCount();
448 object[] args = new object [argCount + 4];
453 for (int i = 0; i < argCount; i++) {
454 TypedReference typedRef = iter.GetNextArg ();
455 args [i + 4] = TypedReference.ToObject (typedRef);
458 stdout.WriteLine (String.Format (format, args));
462 public static int Read ()
464 if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
465 return ConsoleDriver.Read ();
467 return stdin.Read ();
471 public static string ReadLine ()
473 if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
474 return ConsoleDriver.ReadLine ();
476 return stdin.ReadLine ();
480 public static int Read ()
482 return stdin.Read ();
485 public static string ReadLine ()
487 return stdin.ReadLine ();
493 // FIXME: Console should use these encodings when changed
494 static Encoding inputEncoding;
495 static Encoding outputEncoding;
497 public static Encoding InputEncoding {
498 get { return inputEncoding; }
499 set { inputEncoding = value; }
502 public static Encoding OutputEncoding {
503 get { return outputEncoding; }
504 set { outputEncoding = value; }
507 public static ConsoleColor BackgroundColor {
508 get { return ConsoleDriver.BackgroundColor; }
509 set { ConsoleDriver.BackgroundColor = value; }
512 public static int BufferHeight {
513 get { return ConsoleDriver.BufferHeight; }
514 [MonoLimitation ("Implemented only on Windows")]
515 set { ConsoleDriver.BufferHeight = value; }
518 public static int BufferWidth {
519 get { return ConsoleDriver.BufferWidth; }
520 [MonoLimitation ("Implemented only on Windows")]
521 set { ConsoleDriver.BufferWidth = value; }
524 [MonoLimitation ("Implemented only on Windows")]
525 public static bool CapsLock {
526 get { return ConsoleDriver.CapsLock; }
529 public static int CursorLeft {
530 get { return ConsoleDriver.CursorLeft; }
531 set { ConsoleDriver.CursorLeft = value; }
534 public static int CursorTop {
535 get { return ConsoleDriver.CursorTop; }
536 set { ConsoleDriver.CursorTop = value; }
539 public static int CursorSize {
540 get { return ConsoleDriver.CursorSize; }
541 set { ConsoleDriver.CursorSize = value; }
544 public static bool CursorVisible {
545 get { return ConsoleDriver.CursorVisible; }
546 set { ConsoleDriver.CursorVisible = value; }
549 public static ConsoleColor ForegroundColor {
550 get { return ConsoleDriver.ForegroundColor; }
551 set { ConsoleDriver.ForegroundColor = value; }
554 public static bool KeyAvailable {
555 get { return ConsoleDriver.KeyAvailable; }
558 public static int LargestWindowHeight {
559 get { return ConsoleDriver.LargestWindowHeight; }
562 public static int LargestWindowWidth {
563 get { return ConsoleDriver.LargestWindowWidth; }
566 [MonoLimitation ("Only works on windows")]
567 public static bool NumberLock {
568 get { return ConsoleDriver.NumberLock; }
571 public static string Title {
572 get { return ConsoleDriver.Title; }
573 set { ConsoleDriver.Title = value; }
576 public static bool TreatControlCAsInput {
577 get { return ConsoleDriver.TreatControlCAsInput; }
578 set { ConsoleDriver.TreatControlCAsInput = value; }
581 [MonoLimitation ("Only works on windows")]
582 public static int WindowHeight {
583 get { return ConsoleDriver.WindowHeight; }
584 set { ConsoleDriver.WindowHeight = value; }
587 [MonoLimitation ("Only works on windows")]
588 public static int WindowLeft {
589 get { return ConsoleDriver.WindowLeft; }
590 set { ConsoleDriver.WindowLeft = value; }
593 [MonoLimitation ("Only works on windows")]
594 public static int WindowTop {
595 get { return ConsoleDriver.WindowTop; }
596 set { ConsoleDriver.WindowTop = value; }
599 [MonoLimitation ("Only works on windows")]
600 public static int WindowWidth {
601 get { return ConsoleDriver.WindowWidth; }
602 set { ConsoleDriver.WindowWidth = value; }
605 public static void Beep ()
610 public static void Beep (int frequency, int duration)
612 if (frequency < 37 || frequency > 32767)
613 throw new ArgumentOutOfRangeException ("frequency");
616 throw new ArgumentOutOfRangeException ("duration");
618 ConsoleDriver.Beep (frequency, duration);
621 public static void Clear ()
623 ConsoleDriver.Clear ();
626 [MonoLimitation ("Implemented only on Windows")]
627 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
628 int targetLeft, int targetTop)
630 ConsoleDriver.MoveBufferArea (sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop);
633 [MonoLimitation ("Implemented only on Windows")]
634 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
635 int targetLeft, int targetTop, Char sourceChar,
636 ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
638 ConsoleDriver.MoveBufferArea (sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop,
639 sourceChar, sourceForeColor, sourceBackColor);
642 public static ConsoleKeyInfo ReadKey ()
644 return ReadKey (false);
647 public static ConsoleKeyInfo ReadKey (bool intercept)
649 return ConsoleDriver.ReadKey (intercept);
652 public static void ResetColor ()
654 ConsoleDriver.ResetColor ();
657 [MonoLimitation ("Only works on windows")]
658 public static void SetBufferSize (int width, int height)
660 ConsoleDriver.SetBufferSize (width, height);
663 public static void SetCursorPosition (int left, int top)
665 ConsoleDriver.SetCursorPosition (left, top);
668 public static void SetWindowPosition (int left, int top)
670 ConsoleDriver.SetWindowPosition (left, top);
673 public static void SetWindowSize (int width, int height)
675 ConsoleDriver.SetWindowSize (width, height);
678 static ConsoleCancelEventHandler cancel_event;
679 public static event ConsoleCancelEventHandler CancelKeyPress {
681 if (ConsoleDriver.Initialized == false)
682 ConsoleDriver.Init ();
684 cancel_event += value;
687 if (ConsoleDriver.Initialized == false)
688 ConsoleDriver.Init ();
690 cancel_event -= value;
694 delegate void InternalCancelHandler ();
696 #pragma warning disable 414
698 // Used by console-io.c
700 static readonly InternalCancelHandler cancel_handler = new InternalCancelHandler (DoConsoleCancelEvent);
701 #pragma warning restore 414
703 internal static void DoConsoleCancelEvent ()
706 if (cancel_event != null) {
707 ConsoleCancelEventArgs args = new ConsoleCancelEventArgs (ConsoleSpecialKey.ControlC);
708 Delegate [] delegates = cancel_event.GetInvocationList ();
709 foreach (ConsoleCancelEventHandler d in delegates){
711 // Sender is always null here.
713 } catch {} // Ignore any exception.
719 Environment.Exit (58);