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;
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);
112 if (!Environment.IsRunningOnWindows && ConsoleDriver.IsConsole) {
113 StreamWriter w = new CStreamWriter (OpenStandardOutput (0), outputEncoding);
116 stdin = new CStreamReader (OpenStandardInput (0), inputEncoding);
117 ConsoleDriver.Init ();
120 stdout = new UnexceptionalStreamWriter (OpenStandardOutput (0), outputEncoding);
121 ((StreamWriter)stdout).AutoFlush = true;
122 stdout = TextWriter.Synchronized (stdout, true);
123 stdin = new UnexceptionalStreamReader (OpenStandardInput (0), inputEncoding);
124 stdin = TextReader.Synchronized (stdin);
129 GC.SuppressFinalize (stdout);
130 GC.SuppressFinalize (stderr);
131 GC.SuppressFinalize (stdin);
140 public static TextWriter Error {
146 public static TextWriter Out {
152 public static TextReader In {
158 public static Stream OpenStandardError ()
160 return OpenStandardError (0);
163 // calling any FileStream constructor with a handle normally
164 // requires permissions UnmanagedCode permissions. In this
165 // case we assert this permission so the console can be used
166 // in partial trust (i.e. without having UnmanagedCode).
167 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
168 public static Stream OpenStandardError (int bufferSize)
171 return new FileStream (MonoIO.ConsoleError, FileAccess.Write, false, bufferSize, false, bufferSize == 0);
172 } catch (IOException) {
173 return new NullStream ();
177 public static Stream OpenStandardInput ()
179 return OpenStandardInput (0);
182 // calling any FileStream constructor with a handle normally
183 // requires permissions UnmanagedCode permissions. In this
184 // case we assert this permission so the console can be used
185 // in partial trust (i.e. without having UnmanagedCode).
186 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
187 public static Stream OpenStandardInput (int bufferSize)
190 return new FileStream (MonoIO.ConsoleInput, FileAccess.Read, false, bufferSize, false, bufferSize == 0);
191 } catch (IOException) {
192 return new NullStream ();
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)
209 return new FileStream (MonoIO.ConsoleOutput, FileAccess.Write, false, bufferSize, false, bufferSize == 0);
210 } catch (IOException) {
211 return new NullStream ();
215 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
216 public static void SetError (TextWriter newError)
218 if (newError == null)
219 throw new ArgumentNullException ("newError");
224 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
225 public static void SetIn (TextReader newIn)
228 throw new ArgumentNullException ("newIn");
233 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
234 public static void SetOut (TextWriter newOut)
237 throw new ArgumentNullException ("newOut");
242 public static void Write (bool value)
244 stdout.Write (value);
247 public static void Write (char value)
249 stdout.Write (value);
252 public static void Write (char[] value)
254 stdout.Write (value);
257 public static void Write (decimal value)
259 stdout.Write (value);
262 public static void Write (double value)
264 stdout.Write (value);
267 public static void Write (int value)
269 stdout.Write (value);
272 public static void Write (long value)
274 stdout.Write (value);
277 public static void Write (object value)
279 stdout.Write (value);
282 public static void Write (float value)
284 stdout.Write (value);
287 public static void Write (string value)
289 stdout.Write (value);
292 [CLSCompliant (false)]
293 public static void Write (uint value)
295 stdout.Write (value);
298 [CLSCompliant (false)]
299 public static void Write (ulong value)
301 stdout.Write (value);
304 public static void Write (string format, object arg0)
306 stdout.Write (format, arg0);
309 public static void Write (string format, params object[] arg)
311 stdout.Write (format, arg);
314 public static void Write (char[] buffer, int index, int count)
316 stdout.Write (buffer, index, count);
319 public static void Write (string format, object arg0, object arg1)
321 stdout.Write (format, arg0, arg1);
324 public static void Write (string format, object arg0, object arg1, object arg2 )
326 stdout.Write (format, arg0, arg1, arg2);
329 #if ! BOOTSTRAP_WITH_OLDLIB
330 [CLSCompliant (false)]
331 public static void Write (string format, object arg0, object arg1, object arg2, object arg3, __arglist)
333 ArgIterator iter = new ArgIterator (__arglist);
334 int argCount = iter.GetRemainingCount();
336 object[] args = new object [argCount + 4];
341 for (int i = 0; i < argCount; i++) {
342 TypedReference typedRef = iter.GetNextArg ();
343 args [i + 4] = TypedReference.ToObject (typedRef);
346 stdout.Write (String.Format (format, args));
350 public static void WriteLine ()
355 public static void WriteLine (bool value)
357 stdout.WriteLine (value);
360 public static void WriteLine (char value)
362 stdout.WriteLine (value);
365 public static void WriteLine (char[] value)
367 stdout.WriteLine (value);
370 public static void WriteLine (decimal value)
372 stdout.WriteLine (value);
375 public static void WriteLine (double value)
377 stdout.WriteLine (value);
380 public static void WriteLine (int value)
382 stdout.WriteLine (value);
385 public static void WriteLine (long value)
387 stdout.WriteLine (value);
390 public static void WriteLine (object value)
392 stdout.WriteLine (value);
395 public static void WriteLine (float value)
397 stdout.WriteLine (value);
400 public static void WriteLine (string value)
402 stdout.WriteLine (value);
405 [CLSCompliant (false)]
406 public static void WriteLine (uint value)
408 stdout.WriteLine (value);
411 [CLSCompliant (false)]
412 public static void WriteLine (ulong value)
414 stdout.WriteLine (value);
417 public static void WriteLine (string format, object arg0)
419 stdout.WriteLine (format, arg0);
422 public static void WriteLine (string format, params object[] arg)
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 #if ! BOOTSTRAP_WITH_OLDLIB
443 [CLSCompliant (false)]
444 public static void WriteLine (string format, object arg0, object arg1, object arg2, object arg3, __arglist)
446 ArgIterator iter = new ArgIterator (__arglist);
447 int argCount = iter.GetRemainingCount();
449 object[] args = new object [argCount + 4];
454 for (int i = 0; i < argCount; i++) {
455 TypedReference typedRef = iter.GetNextArg ();
456 args [i + 4] = TypedReference.ToObject (typedRef);
459 stdout.WriteLine (String.Format (format, args));
464 public static int Read ()
466 if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
467 return ConsoleDriver.Read ();
469 return stdin.Read ();
473 public static string ReadLine ()
475 if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
476 return ConsoleDriver.ReadLine ();
478 return stdin.ReadLine ();
482 public static int Read ()
484 return stdin.Read ();
487 public static string ReadLine ()
489 return stdin.ReadLine ();
495 // FIXME: Console should use these encodings when changed
496 static Encoding inputEncoding;
497 static Encoding outputEncoding;
499 public static Encoding InputEncoding {
500 get { return inputEncoding; }
501 set { inputEncoding = value; }
504 public static Encoding OutputEncoding {
505 get { return outputEncoding; }
506 set { outputEncoding = value; }
509 public static ConsoleColor BackgroundColor {
510 get { return ConsoleDriver.BackgroundColor; }
511 set { ConsoleDriver.BackgroundColor = value; }
514 public static int BufferHeight {
515 get { return ConsoleDriver.BufferHeight; }
516 set { ConsoleDriver.BufferHeight = value; }
519 public static int BufferWidth {
520 get { return ConsoleDriver.BufferWidth; }
521 set { ConsoleDriver.BufferWidth = value; }
524 public static int CursorLeft {
525 get { return ConsoleDriver.CursorLeft; }
526 set { ConsoleDriver.CursorLeft = value; }
529 public static int CursorTop {
530 get { return ConsoleDriver.CursorTop; }
531 set { ConsoleDriver.CursorTop = value; }
534 public static bool CursorVisible {
535 get { return ConsoleDriver.CursorVisible; }
536 set { ConsoleDriver.CursorVisible = value; }
539 public static ConsoleColor ForegroundColor {
540 get { return ConsoleDriver.ForegroundColor; }
541 set { ConsoleDriver.ForegroundColor = value; }
544 public static bool KeyAvailable {
545 get { return ConsoleDriver.KeyAvailable; }
548 public static string Title {
549 get { return ConsoleDriver.Title; }
550 set { ConsoleDriver.Title = value; }
553 public static bool TreatControlCAsInput {
554 get { return ConsoleDriver.TreatControlCAsInput; }
555 set { ConsoleDriver.TreatControlCAsInput = value; }
558 public static int WindowHeight {
559 get { return ConsoleDriver.WindowHeight; }
560 set { ConsoleDriver.WindowHeight = value; }
563 public static int WindowLeft {
564 get { return ConsoleDriver.WindowLeft; }
565 set { ConsoleDriver.WindowLeft = value; }
568 public static int WindowTop {
569 get { return ConsoleDriver.WindowTop; }
570 set { ConsoleDriver.WindowTop = value; }
573 public static int WindowWidth {
574 get { return ConsoleDriver.WindowWidth; }
575 set { ConsoleDriver.WindowWidth = value; }
578 public static void Beep ()
583 public static void Beep (int frequency, int duration)
585 if (frequency < 37 || frequency > 32767)
586 throw new ArgumentOutOfRangeException ("frequency");
589 throw new ArgumentOutOfRangeException ("duration");
591 ConsoleDriver.Beep (frequency, duration);
594 public static void Clear ()
596 ConsoleDriver.Clear ();
600 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
601 int targetLeft, int targetTop)
603 throw new NotImplementedException ();
607 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
608 int targetLeft, int targetTop, Char sourceChar,
609 ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
611 throw new NotImplementedException ();
614 public static ConsoleKeyInfo ReadKey ()
616 return ReadKey (false);
619 public static ConsoleKeyInfo ReadKey (bool intercept)
621 return ConsoleDriver.ReadKey (intercept);
624 public static void ResetColor ()
626 ConsoleDriver.ResetColor ();
629 public static void SetBufferSize (int width, int height)
631 ConsoleDriver.SetBufferSize (width, height);
634 public static void SetCursorPosition (int left, int top)
636 ConsoleDriver.SetCursorPosition (left, top);
639 public static void SetWindowPosition (int left, int top)
641 ConsoleDriver.SetWindowPosition (left, top);
644 public static void SetWindowSize (int width, int height)
646 ConsoleDriver.SetWindowSize (width, height);
649 public static event ConsoleCancelEventHandler CancelKeyPress;
651 delegate void InternalCancelHandler ();
652 static InternalCancelHandler cancel_handler = new InternalCancelHandler (DoConsoleCancelEvent);
654 internal static void DoConsoleCancelEvent ()
657 if (CancelKeyPress != null) {
658 ConsoleCancelEventArgs args = new ConsoleCancelEventArgs (ConsoleSpecialKey.ControlC);
659 Delegate [] delegates = CancelKeyPress.GetInvocationList ();
660 foreach (ConsoleCancelEventHandler d in delegates){
662 // Sender is always null here.
664 } catch {} // Ignore any exception.
670 Environment.Exit (58);