8 #include <msp/core/systemerror.h>
10 #include "handle_private.h"
17 DWORD stream_to_sys(Msp::IO::Console::Stream stream)
21 case Msp::IO::Console::CIN: return STD_INPUT_HANDLE;
22 case Msp::IO::Console::COUT: return STD_OUTPUT_HANDLE;
23 case Msp::IO::Console::CERR: return STD_ERROR_HANDLE;
24 default: throw invalid_argument("stream_to_sys");
37 Console::Console(Stream s):
40 mode = (stream==CIN ? M_READ : M_WRITE);
43 *handle = GetStdHandle(stream_to_sys(stream));
48 tcgetattr(*handle, &orig_attr);
59 tcsetattr(*handle, TCSADRAIN, &orig_attr);
63 void Console::set_block(bool b)
66 // XXX Dunno how to do this in win32
69 int flags = fcntl(*handle, F_GETFL);
70 flags = (flags&~O_NONBLOCK) | (b?0:O_NONBLOCK);
71 fcntl(*handle, F_SETFL, flags);
75 void Console::set_local_echo(bool e)
81 GetConsoleMode(*handle, &m);
82 SetConsoleMode(*handle, (m&~ENABLE_ECHO_INPUT) | (e?ENABLE_ECHO_INPUT:0));
85 tcgetattr(*handle, &t);
86 t.c_lflag = (t.c_lflag&~ECHO) | (e?ECHO:0);
87 tcsetattr(*handle, TCSADRAIN, &t);
91 void Console::set_line_buffer(bool l)
97 if(!GetConsoleMode(*handle, &m))
98 throw system_error("GetConsoleMode");
99 if(!SetConsoleMode(*handle, (m&~ENABLE_LINE_INPUT) | (l?ENABLE_LINE_INPUT:0)))
100 throw system_error("SetConsoleMode");
103 if(tcgetattr(*handle, &t)==-1)
104 throw system_error("tcgetattr");
105 t.c_lflag = (t.c_lflag&~ICANON) | (l?ICANON:0);
106 // man termios warns that VMIN and VTIME may share indices with VEOF and VEOL
109 t.c_cc[VEOF] = orig_attr.c_cc[VEOF];
110 t.c_cc[VEOL] = orig_attr.c_cc[VEOL];
117 if(tcsetattr(*handle, TCSADRAIN, &t)==-1)
118 throw system_error("tcsetattr");
122 void Console::get_size(unsigned &rows, unsigned &cols)
124 check_access(M_WRITE);
127 CONSOLE_SCREEN_BUFFER_INFO sbi;
128 if(!GetConsoleScreenBufferInfo(*handle, &sbi))
129 throw system_error("GetConsoleScreenBufferInfo");
130 // Right/bottom coords are inclusive
131 rows = sbi.srWindow.Bottom+1-sbi.srWindow.Top;
132 cols = sbi.srWindow.Right+1-sbi.srWindow.Left;
135 if(ioctl(*handle, TIOCGWINSZ, &wsz)==-1)
136 throw system_error("ioctl TIOCGWINSZ");
142 void Console::redirect(Base &other)
144 Handle other_handle = other.get_handle(mode&M_RDWR);
146 SetStdHandle(stream_to_sys(stream), *other_handle);
148 dup2(*other_handle, *handle);
152 unsigned Console::do_write(const char *buf, unsigned len)
154 check_access(M_WRITE);
156 return sys_write(handle, buf, len);
159 unsigned Console::do_read(char *buf, unsigned len)
161 check_access(M_READ);
163 unsigned ret = sys_read(handle, buf, len);
170 Console &Console::instance(Stream s)
172 static Console in(CIN);
173 static Console out(COUT);
174 static Console err(CERR);
179 case COUT: return out;
180 case CERR: return err;
183 throw invalid_argument("Console::instance");
186 Console &cin = Console::instance(Console::CIN);
187 Console &cout = Console::instance(Console::COUT);
188 Console &cerr = Console::instance(Console::CERR);