8 #include <msp/core/systemerror.h>
10 #include "handle_private.h"
17 DWORD stream_to_sys(Console::Stream stream)
21 case INPUT: return STD_INPUT_HANDLE;
22 case OUTPUT: return STD_OUTPUT_HANDLE;
23 case ERROR: return STD_ERROR_HANDLE;
24 default: throw invalid_argument("stream_to_sys");
37 Console::Console(Stream s):
40 mode = (stream==INPUT ? 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");
102 // XXX ICANON does more than just set line buffering, may need a bit more thought
104 if(tcgetattr(*handle, &t)==-1)
105 throw system_error("tcgetattr");
106 t.c_lflag = (t.c_lflag&~ICANON) | (l?ICANON:0);
107 if(tcsetattr(*handle, TCSADRAIN, &t)==-1)
108 throw system_error("tcsetattr");
112 void Console::get_size(unsigned &rows, unsigned &cols)
114 check_access(M_WRITE);
117 // XXX Figure out how to do this
122 if(ioctl(*handle, TIOCGWINSZ, &wsz)==-1)
123 throw system_error("ioctl TIOCGWINSZ");
129 void Console::redirect(Base &other)
131 Handle other_handle = other.get_handle(mode&M_RDWR);
133 SetStdHandle(stream_to_sys(stream), *other_handle);
135 dup2(*other_handle, *handle);
139 unsigned Console::do_write(const char *buf, unsigned len)
141 check_access(M_WRITE);
143 return sys_write(handle, buf, len);
146 unsigned Console::do_read(char *buf, unsigned len)
148 check_access(M_READ);
150 unsigned ret = sys_read(handle, buf, len);
157 Console &Console::instance(Stream s)
159 static Console in(INPUT);
160 static Console out(OUTPUT);
161 static Console err(ERROR);
165 case INPUT: return in;
166 case OUTPUT: return out;
167 case ERROR: return err;
170 throw invalid_argument("Console::instance");
173 Console &cin = Console::instance(Console::INPUT);
174 Console &cout = Console::instance(Console::OUTPUT);
175 Console &cerr = Console::instance(Console::ERROR);