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.
33 using System.Runtime.CompilerServices;
34 using System.Runtime.InteropServices;
35 using System.Security.Permissions;
48 private class WindowsConsole
50 [DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
51 private static extern int GetConsoleCP ();
52 [DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
53 private static extern int GetConsoleOutputCP ();
55 [MethodImpl (MethodImplOptions.NoInlining)]
56 public static int GetInputCodePage ()
58 return GetConsoleCP ();
61 [MethodImpl (MethodImplOptions.NoInlining)]
62 public static int GetOutputCodePage ()
64 return GetConsoleOutputCP ();
68 internal static TextWriter stdout;
69 private static TextWriter stderr;
70 private static TextReader stdin;
74 #if !NET_2_0 || NET_2_1
75 Encoding inputEncoding;
76 Encoding outputEncoding;
79 if (Environment.IsRunningOnWindows) {
81 // On Windows, follow the Windows tradition
84 inputEncoding = Encoding.GetEncoding (WindowsConsole.GetInputCodePage ());
85 outputEncoding = Encoding.GetEncoding (WindowsConsole.GetOutputCodePage ());
86 // ArgumentException and NotSupportedException can be thrown as well
88 // FIXME: I18N assemblies are not available when compiling mcs
89 // Use Latin 1 as it is fast and UTF-8 is never used as console code page
90 inputEncoding = outputEncoding = Encoding.GetEncoding (28591);
94 // On Unix systems (128), do not output the
95 // UTF-8 ZWNBSP (zero-width non-breaking space).
98 Encoding.InternalCodePage (ref code_page);
100 if (code_page != -1 && ((code_page & 0x0fffffff) == 3 // UTF8Encoding.UTF8_CODE_PAGE
101 || ((code_page & 0x10000000) != 0)))
102 inputEncoding = outputEncoding = Encoding.UTF8Unmarked;
104 inputEncoding = outputEncoding = Encoding.Default;
107 stderr = new UnexceptionalStreamWriter (OpenStandardError (0), outputEncoding);
108 ((StreamWriter)stderr).AutoFlush = true;
109 stderr = TextWriter.Synchronized (stderr, true);
111 #if NET_2_0 && !NET_2_1
112 if (!Environment.IsRunningOnWindows && ConsoleDriver.IsConsole) {
113 StreamWriter w = new CStreamWriter (OpenStandardOutput (0), outputEncoding);
116 stdin = new CStreamReader (OpenStandardInput (0), inputEncoding);
119 stdout = new UnexceptionalStreamWriter (OpenStandardOutput (0), outputEncoding);
120 ((StreamWriter)stdout).AutoFlush = true;
121 stdout = TextWriter.Synchronized (stdout, true);
122 stdin = new UnexceptionalStreamReader (OpenStandardInput (0), inputEncoding);
123 stdin = TextReader.Synchronized (stdin);
124 #if NET_2_0 && !NET_2_1
128 GC.SuppressFinalize (stdout);
129 GC.SuppressFinalize (stderr);
130 GC.SuppressFinalize (stdin);
139 public static TextWriter Error {
145 public static TextWriter Out {
151 public static TextReader In {
157 public static Stream OpenStandardError ()
159 return OpenStandardError (0);
162 // calling any FileStream constructor with a handle normally
163 // requires permissions UnmanagedCode permissions. In this
164 // case we assert this permission so the console can be used
165 // in partial trust (i.e. without having UnmanagedCode).
166 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
167 public static Stream OpenStandardError (int bufferSize)
170 return new FileStream (MonoIO.ConsoleError, FileAccess.Write, false, bufferSize, false, bufferSize == 0);
171 } catch (IOException) {
172 return new NullStream ();
176 public static Stream OpenStandardInput ()
178 return OpenStandardInput (0);
181 // calling any FileStream constructor with a handle normally
182 // requires permissions UnmanagedCode permissions. In this
183 // case we assert this permission so the console can be used
184 // in partial trust (i.e. without having UnmanagedCode).
185 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
186 public static Stream OpenStandardInput (int bufferSize)
189 return new FileStream (MonoIO.ConsoleInput, FileAccess.Read, false, bufferSize, false, bufferSize == 0);
190 } catch (IOException) {
191 return new NullStream ();
195 public static Stream OpenStandardOutput ()
197 return OpenStandardOutput (0);
200 // calling any FileStream constructor with a handle normally
201 // requires permissions UnmanagedCode permissions. In this
202 // case we assert this permission so the console can be used
203 // in partial trust (i.e. without having UnmanagedCode).
204 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
205 public static Stream OpenStandardOutput (int bufferSize)
208 return new FileStream (MonoIO.ConsoleOutput, FileAccess.Write, false, bufferSize, false, bufferSize == 0);
209 } catch (IOException) {
210 return new NullStream ();
214 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
215 public static void SetError (TextWriter newError)
217 if (newError == null)
218 throw new ArgumentNullException ("newError");
223 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
224 public static void SetIn (TextReader newIn)
227 throw new ArgumentNullException ("newIn");
232 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
233 public static void SetOut (TextWriter newOut)
236 throw new ArgumentNullException ("newOut");
241 public static void Write (bool value)
243 stdout.Write (value);
246 public static void Write (char value)
248 stdout.Write (value);
251 public static void Write (char[] value)
253 stdout.Write (value);
256 public static void Write (decimal value)
258 stdout.Write (value);
261 public static void Write (double value)
263 stdout.Write (value);
266 public static void Write (int value)
268 stdout.Write (value);
271 public static void Write (long value)
273 stdout.Write (value);
276 public static void Write (object value)
278 stdout.Write (value);
281 public static void Write (float value)
283 stdout.Write (value);
286 public static void Write (string value)
288 stdout.Write (value);
291 [CLSCompliant (false)]
292 public static void Write (uint value)
294 stdout.Write (value);
297 [CLSCompliant (false)]
298 public static void Write (ulong value)
300 stdout.Write (value);
303 public static void Write (string format, object arg0)
305 stdout.Write (format, arg0);
308 public static void Write (string format, params object[] arg)
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 #if ! BOOTSTRAP_WITH_OLDLIB
329 [CLSCompliant (false)]
330 public static void Write (string format, object arg0, object arg1, object arg2, object arg3, __arglist)
332 ArgIterator iter = new ArgIterator (__arglist);
333 int argCount = iter.GetRemainingCount();
335 object[] args = new object [argCount + 4];
340 for (int i = 0; i < argCount; i++) {
341 TypedReference typedRef = iter.GetNextArg ();
342 args [i + 4] = TypedReference.ToObject (typedRef);
345 stdout.Write (String.Format (format, args));
349 public static void WriteLine ()
354 public static void WriteLine (bool value)
356 stdout.WriteLine (value);
359 public static void WriteLine (char value)
361 stdout.WriteLine (value);
364 public static void WriteLine (char[] value)
366 stdout.WriteLine (value);
369 public static void WriteLine (decimal value)
371 stdout.WriteLine (value);
374 public static void WriteLine (double value)
376 stdout.WriteLine (value);
379 public static void WriteLine (int value)
381 stdout.WriteLine (value);
384 public static void WriteLine (long value)
386 stdout.WriteLine (value);
389 public static void WriteLine (object value)
391 stdout.WriteLine (value);
394 public static void WriteLine (float value)
396 stdout.WriteLine (value);
399 public static void WriteLine (string value)
401 stdout.WriteLine (value);
404 [CLSCompliant (false)]
405 public static void WriteLine (uint value)
407 stdout.WriteLine (value);
410 [CLSCompliant (false)]
411 public static void WriteLine (ulong value)
413 stdout.WriteLine (value);
416 public static void WriteLine (string format, object arg0)
418 stdout.WriteLine (format, arg0);
421 public static void WriteLine (string format, params object[] arg)
423 stdout.WriteLine (format, arg);
426 public static void WriteLine (char[] buffer, int index, int count)
428 stdout.WriteLine (buffer, index, count);
431 public static void WriteLine (string format, object arg0, object arg1)
433 stdout.WriteLine (format, arg0, arg1);
436 public static void WriteLine (string format, object arg0, object arg1, object arg2)
438 stdout.WriteLine (format, arg0, arg1, arg2);
441 #if ! BOOTSTRAP_WITH_OLDLIB
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 #if NET_2_0 && !NET_2_1
463 public static int Read ()
465 if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
466 return ConsoleDriver.Read ();
468 return stdin.Read ();
472 public static string ReadLine ()
474 if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
475 return ConsoleDriver.ReadLine ();
477 return stdin.ReadLine ();
481 public static int Read ()
483 return stdin.Read ();
486 public static string ReadLine ()
488 return stdin.ReadLine ();
493 #if NET_2_0 && !NET_2_1
494 // FIXME: Console should use these encodings when changed
495 static Encoding inputEncoding;
496 static Encoding outputEncoding;
498 public static Encoding InputEncoding {
499 get { return inputEncoding; }
500 set { inputEncoding = value; }
503 public static Encoding OutputEncoding {
504 get { return outputEncoding; }
505 set { outputEncoding = value; }
508 public static ConsoleColor BackgroundColor {
509 get { return ConsoleDriver.BackgroundColor; }
510 set { ConsoleDriver.BackgroundColor = value; }
513 public static int BufferHeight {
514 get { return ConsoleDriver.BufferHeight; }
515 set { ConsoleDriver.BufferHeight = value; }
518 public static int BufferWidth {
519 get { return ConsoleDriver.BufferWidth; }
520 set { ConsoleDriver.BufferWidth = value; }
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 bool CursorVisible {
534 get { return ConsoleDriver.CursorVisible; }
535 set { ConsoleDriver.CursorVisible = value; }
538 public static ConsoleColor ForegroundColor {
539 get { return ConsoleDriver.ForegroundColor; }
540 set { ConsoleDriver.ForegroundColor = value; }
543 public static bool KeyAvailable {
544 get { return ConsoleDriver.KeyAvailable; }
547 public static string Title {
548 get { return ConsoleDriver.Title; }
549 set { ConsoleDriver.Title = value; }
552 public static bool TreatControlCAsInput {
553 get { return ConsoleDriver.TreatControlCAsInput; }
554 set { ConsoleDriver.TreatControlCAsInput = value; }
557 public static int WindowHeight {
558 get { return ConsoleDriver.WindowHeight; }
559 set { ConsoleDriver.WindowHeight = value; }
562 public static int WindowLeft {
563 get { return ConsoleDriver.WindowLeft; }
564 set { ConsoleDriver.WindowLeft = value; }
567 public static int WindowTop {
568 get { return ConsoleDriver.WindowTop; }
569 set { ConsoleDriver.WindowTop = value; }
572 public static int WindowWidth {
573 get { return ConsoleDriver.WindowWidth; }
574 set { ConsoleDriver.WindowWidth = value; }
577 public static void Beep ()
582 public static void Beep (int frequency, int duration)
584 if (frequency < 37 || frequency > 32767)
585 throw new ArgumentOutOfRangeException ("frequency");
588 throw new ArgumentOutOfRangeException ("duration");
590 ConsoleDriver.Beep (frequency, duration);
593 public static void Clear ()
595 ConsoleDriver.Clear ();
598 [MonoTODO ("Not implemented")]
599 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
600 int targetLeft, int targetTop)
602 throw new NotImplementedException ();
605 [MonoTODO("Not implemented")]
606 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
607 int targetLeft, int targetTop, Char sourceChar,
608 ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
610 throw new NotImplementedException ();
613 public static ConsoleKeyInfo ReadKey ()
615 return ReadKey (false);
618 public static ConsoleKeyInfo ReadKey (bool intercept)
620 return ConsoleDriver.ReadKey (intercept);
623 public static void ResetColor ()
625 ConsoleDriver.ResetColor ();
628 public static void SetBufferSize (int width, int height)
630 ConsoleDriver.SetBufferSize (width, height);
633 public static void SetCursorPosition (int left, int top)
635 ConsoleDriver.SetCursorPosition (left, top);
638 public static void SetWindowPosition (int left, int top)
640 ConsoleDriver.SetWindowPosition (left, top);
643 public static void SetWindowSize (int width, int height)
645 ConsoleDriver.SetWindowSize (width, height);
648 static ConsoleCancelEventHandler cancel_event;
649 public static event ConsoleCancelEventHandler CancelKeyPress {
651 if (ConsoleDriver.Initialized == false)
652 ConsoleDriver.Init ();
654 cancel_event += value;
657 if (ConsoleDriver.Initialized == false)
658 ConsoleDriver.Init ();
660 cancel_event -= value;
664 delegate void InternalCancelHandler ();
665 static InternalCancelHandler cancel_handler = new InternalCancelHandler (DoConsoleCancelEvent);
667 internal static void DoConsoleCancelEvent ()
670 if (cancel_event != null) {
671 ConsoleCancelEventArgs args = new ConsoleCancelEventArgs (ConsoleSpecialKey.ControlC);
672 Delegate [] delegates = cancel_event.GetInvocationList ();
673 foreach (ConsoleCancelEventHandler d in delegates){
675 // Sender is always null here.
677 } catch {} // Ignore any exception.
683 Environment.Exit (58);