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
)
307 stdout
.Write (format
, arg
);
310 public static void Write (char[] buffer
, int index
, int count
)
312 stdout
.Write (buffer
, index
, count
);
315 public static void Write (string format
, object arg0
, object arg1
)
317 stdout
.Write (format
, arg0
, arg1
);
320 public static void Write (string format
, object arg0
, object arg1
, object arg2
)
322 stdout
.Write (format
, arg0
, arg1
, arg2
);
325 [CLSCompliant (false)]
326 public static void Write (string format
, object arg0
, object arg1
, object arg2
, object arg3
, __arglist
)
328 ArgIterator iter
= new ArgIterator (__arglist
);
329 int argCount
= iter
.GetRemainingCount();
331 object[] args
= new object [argCount
+ 4];
336 for (int i
= 0; i
< argCount
; i
++) {
337 TypedReference typedRef
= iter
.GetNextArg ();
338 args
[i
+ 4] = TypedReference
.ToObject (typedRef
);
341 stdout
.Write (String
.Format (format
, args
));
344 public static void WriteLine ()
349 public static void WriteLine (bool value)
351 stdout
.WriteLine (value);
354 public static void WriteLine (char value)
356 stdout
.WriteLine (value);
359 public static void WriteLine (char[] buffer
)
361 stdout
.WriteLine (buffer
);
364 public static void WriteLine (decimal value)
366 stdout
.WriteLine (value);
369 public static void WriteLine (double value)
371 stdout
.WriteLine (value);
374 public static void WriteLine (int value)
376 stdout
.WriteLine (value);
379 public static void WriteLine (long value)
381 stdout
.WriteLine (value);
384 public static void WriteLine (object value)
386 stdout
.WriteLine (value);
389 public static void WriteLine (float value)
391 stdout
.WriteLine (value);
394 public static void WriteLine (string value)
396 stdout
.WriteLine (value);
399 [CLSCompliant (false)]
400 public static void WriteLine (uint value)
402 stdout
.WriteLine (value);
405 [CLSCompliant (false)]
406 public static void WriteLine (ulong value)
408 stdout
.WriteLine (value);
411 public static void WriteLine (string format
, object arg0
)
413 stdout
.WriteLine (format
, arg0
);
416 public static void WriteLine (string format
, params object[] arg
)
418 stdout
.WriteLine (format
, arg
);
421 public static void WriteLine (char[] buffer
, int index
, int count
)
423 stdout
.WriteLine (buffer
, index
, count
);
426 public static void WriteLine (string format
, object arg0
, object arg1
)
428 stdout
.WriteLine (format
, arg0
, arg1
);
431 public static void WriteLine (string format
, object arg0
, object arg1
, object arg2
)
433 stdout
.WriteLine (format
, arg0
, arg1
, arg2
);
436 [CLSCompliant (false)]
437 public static void WriteLine (string format
, object arg0
, object arg1
, object arg2
, object arg3
, __arglist
)
439 ArgIterator iter
= new ArgIterator (__arglist
);
440 int argCount
= iter
.GetRemainingCount();
442 object[] args
= new object [argCount
+ 4];
447 for (int i
= 0; i
< argCount
; i
++) {
448 TypedReference typedRef
= iter
.GetNextArg ();
449 args
[i
+ 4] = TypedReference
.ToObject (typedRef
);
452 stdout
.WriteLine (String
.Format (format
, args
));
456 public static int Read ()
458 if ((stdin
is CStreamReader
) && ConsoleDriver
.IsConsole
) {
459 return ConsoleDriver
.Read ();
461 return stdin
.Read ();
465 public static string ReadLine ()
467 if ((stdin
is CStreamReader
) && ConsoleDriver
.IsConsole
) {
468 return ConsoleDriver
.ReadLine ();
470 return stdin
.ReadLine ();
474 public static int Read ()
476 return stdin
.Read ();
479 public static string ReadLine ()
481 return stdin
.ReadLine ();
487 // FIXME: Console should use these encodings when changed
488 static Encoding inputEncoding
;
489 static Encoding outputEncoding
;
491 public static Encoding InputEncoding
{
492 get { return inputEncoding; }
493 set { inputEncoding = value; }
496 public static Encoding OutputEncoding
{
497 get { return outputEncoding; }
498 set { outputEncoding = value; }
501 public static ConsoleColor BackgroundColor
{
502 get { return ConsoleDriver.BackgroundColor; }
503 set { ConsoleDriver.BackgroundColor = value; }
506 public static int BufferHeight
{
507 get { return ConsoleDriver.BufferHeight; }
508 [MonoLimitation ("Implemented only on Windows")]
509 set { ConsoleDriver.BufferHeight = value; }
512 public static int BufferWidth
{
513 get { return ConsoleDriver.BufferWidth; }
514 [MonoLimitation ("Implemented only on Windows")]
515 set { ConsoleDriver.BufferWidth = value; }
518 [MonoLimitation ("Implemented only on Windows")]
519 public static bool CapsLock
{
520 get { return ConsoleDriver.CapsLock; }
523 public static int CursorLeft
{
524 get { return ConsoleDriver.CursorLeft; }
525 set { ConsoleDriver.CursorLeft = value; }
528 public static int CursorTop
{
529 get { return ConsoleDriver.CursorTop; }
530 set { ConsoleDriver.CursorTop = value; }
533 public static int CursorSize
{
534 get { return ConsoleDriver.CursorSize; }
535 set { ConsoleDriver.CursorSize = value; }
538 public static bool CursorVisible
{
539 get { return ConsoleDriver.CursorVisible; }
540 set { ConsoleDriver.CursorVisible = value; }
543 public static ConsoleColor ForegroundColor
{
544 get { return ConsoleDriver.ForegroundColor; }
545 set { ConsoleDriver.ForegroundColor = value; }
548 public static bool KeyAvailable
{
549 get { return ConsoleDriver.KeyAvailable; }
552 public static int LargestWindowHeight
{
553 get { return ConsoleDriver.LargestWindowHeight; }
556 public static int LargestWindowWidth
{
557 get { return ConsoleDriver.LargestWindowWidth; }
560 [MonoLimitation ("Only works on windows")]
561 public static bool NumberLock
{
562 get { return ConsoleDriver.NumberLock; }
565 public static string Title
{
566 get { return ConsoleDriver.Title; }
567 set { ConsoleDriver.Title = value; }
570 public static bool TreatControlCAsInput
{
571 get { return ConsoleDriver.TreatControlCAsInput; }
572 set { ConsoleDriver.TreatControlCAsInput = value; }
575 [MonoLimitation ("Only works on windows")]
576 public static int WindowHeight
{
577 get { return ConsoleDriver.WindowHeight; }
578 set { ConsoleDriver.WindowHeight = value; }
581 [MonoLimitation ("Only works on windows")]
582 public static int WindowLeft
{
583 get { return ConsoleDriver.WindowLeft; }
584 set { ConsoleDriver.WindowLeft = value; }
587 [MonoLimitation ("Only works on windows")]
588 public static int WindowTop
{
589 get { return ConsoleDriver.WindowTop; }
590 set { ConsoleDriver.WindowTop = value; }
593 [MonoLimitation ("Only works on windows")]
594 public static int WindowWidth
{
595 get { return ConsoleDriver.WindowWidth; }
596 set { ConsoleDriver.WindowWidth = value; }
599 public static void Beep ()
604 public static void Beep (int frequency
, int duration
)
606 if (frequency
< 37 || frequency
> 32767)
607 throw new ArgumentOutOfRangeException ("frequency");
610 throw new ArgumentOutOfRangeException ("duration");
612 ConsoleDriver
.Beep (frequency
, duration
);
615 public static void Clear ()
617 ConsoleDriver
.Clear ();
620 [MonoLimitation ("Implemented only on Windows")]
621 public static void MoveBufferArea (int sourceLeft
, int sourceTop
, int sourceWidth
, int sourceHeight
,
622 int targetLeft
, int targetTop
)
624 ConsoleDriver
.MoveBufferArea (sourceLeft
, sourceTop
, sourceWidth
, sourceHeight
, targetLeft
, targetTop
);
627 [MonoLimitation ("Implemented only on Windows")]
628 public static void MoveBufferArea (int sourceLeft
, int sourceTop
, int sourceWidth
, int sourceHeight
,
629 int targetLeft
, int targetTop
, Char sourceChar
,
630 ConsoleColor sourceForeColor
, ConsoleColor sourceBackColor
)
632 ConsoleDriver
.MoveBufferArea (sourceLeft
, sourceTop
, sourceWidth
, sourceHeight
, targetLeft
, targetTop
,
633 sourceChar
, sourceForeColor
, sourceBackColor
);
636 public static ConsoleKeyInfo
ReadKey ()
638 return ReadKey (false);
641 public static ConsoleKeyInfo
ReadKey (bool intercept
)
643 return ConsoleDriver
.ReadKey (intercept
);
646 public static void ResetColor ()
648 ConsoleDriver
.ResetColor ();
651 [MonoLimitation ("Only works on windows")]
652 public static void SetBufferSize (int width
, int height
)
654 ConsoleDriver
.SetBufferSize (width
, height
);
657 public static void SetCursorPosition (int left
, int top
)
659 ConsoleDriver
.SetCursorPosition (left
, top
);
662 public static void SetWindowPosition (int left
, int top
)
664 ConsoleDriver
.SetWindowPosition (left
, top
);
667 public static void SetWindowSize (int width
, int height
)
669 ConsoleDriver
.SetWindowSize (width
, height
);
672 static ConsoleCancelEventHandler cancel_event
;
673 public static event ConsoleCancelEventHandler CancelKeyPress
{
675 if (ConsoleDriver
.Initialized
== false)
676 ConsoleDriver
.Init ();
678 cancel_event
+= value;
681 if (ConsoleDriver
.Initialized
== false)
682 ConsoleDriver
.Init ();
684 cancel_event
-= value;
688 delegate void InternalCancelHandler ();
690 #pragma warning disable 414
692 // Used by console-io.c
694 static readonly InternalCancelHandler cancel_handler
= new InternalCancelHandler (DoConsoleCancelEvent
);
695 #pragma warning restore 414
697 internal static void DoConsoleCancelEvent ()
700 if (cancel_event
!= null) {
701 ConsoleCancelEventArgs args
= new ConsoleCancelEventArgs (ConsoleSpecialKey
.ControlC
);
702 Delegate
[] delegates
= cancel_event
.GetInvocationList ();
703 foreach (ConsoleCancelEventHandler d
in delegates
){
705 // Sender is always null here.
707 } catch {} // Ignore any exception.
713 Environment
.Exit (58);