3 This file is part of libmspio
4 Copyright © 2008 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
12 #include <sys/ioctl.h>
14 #include <msp/core/except.h>
28 Console::Console(unsigned n)
31 throw InvalidParameterValue("Invalid parameter for Console::Console");
33 mode = (n==0 ? M_READ : M_WRITE);
38 case 0: handle = GetStdHandle(STD_INPUT_HANDLE); break;
39 case 1: handle = GetStdHandle(STD_OUTPUT_HANDLE); break;
40 case 2: handle = GetStdHandle(STD_ERROR_HANDLE); break;
46 tcgetattr(handle, &orig_attr);
57 tcsetattr(handle, TCSADRAIN, &orig_attr);
61 void Console::set_block(bool b)
64 // XXX Dunno how to do this in win32
67 int flags = fcntl(0, F_GETFL);
68 flags = (flags&~O_NONBLOCK) | (b?0:O_NONBLOCK);
69 fcntl(0, F_SETFL, flags);
73 void Console::set_local_echo(bool e)
76 throw InvalidState("Local echo can only be set on input console");
80 GetConsoleMode(handle, &m);
81 SetConsoleMode(handle, (m&~ENABLE_ECHO_INPUT) | (e?ENABLE_ECHO_INPUT:0));
85 t.c_lflag = (t.c_lflag&~ECHO) | (e?ECHO:0);
86 tcsetattr(0, TCSADRAIN, &t);
90 void Console::set_line_buffer(bool l)
93 throw InvalidState("Line buffering can only be set on input console");
97 GetConsoleMode(handle, &m);
98 SetConsoleMode(handle, (m&~ENABLE_LINE_INPUT) | (l?ENABLE_LINE_INPUT:0));
100 // XXX ICANON does more than just set line buffering, may need a bit more thought
103 t.c_lflag = (t.c_lflag&~ICANON) | (l?ICANON:0);
104 tcsetattr(0, TCSADRAIN, &t);
108 void Console::get_size(unsigned &rows, unsigned &cols)
111 throw InvalidState("Size can only be queried from an output console");
114 // XXX Figure out how to do this
119 ioctl(handle, TIOCGWINSZ, &wsz);
125 Handle Console::get_event_handle()
130 unsigned Console::do_write(const char *buf, unsigned len)
133 throw InvalidState("Console is not writable");
137 if(!WriteFile(handle, buf, len, &ret, 0))
138 throw SystemError("Writing to console failed", GetLastError());
140 int ret = ::write(handle, buf, len);
142 throw SystemError("Writing to console failed", errno);
148 unsigned Console::do_read(char *buf, unsigned len)
151 throw InvalidState("Console is not readable");
155 if(!ReadFile(handle, buf, len, &ret, 0))
156 throw SystemError("Reading from console failed", GetLastError());
158 int ret = ::read(handle, buf, len);
164 throw SystemError("Reading from console failed", errno);
173 Console &Console::instance(unsigned n)
175 static Console in(0);
176 static Console out(1);
177 static Console err(2);
186 throw InvalidParameterValue("Unknown Console instance requested");
189 Console &cin = Console::instance(0);
190 Console &cout = Console::instance(1);
191 Console &cerr = Console::instance(2);