9 * This implementation of the Console interface can be used to
10 * multiplex among some input, output, and in-out consoles.
12 class Mux_console : public Console
18 SIZE = 8 ///< The maximum number of consoles to be multiplexed.
21 int write(char const *str, size_t len);
22 int getchar(bool blocking = true);
23 int char_avail() const;
35 #include "processor.h"
38 Mux_console::Mux_console()
39 : _next_getchar(-1), _items(0)
44 Mux_console::write(char const *str, size_t len)
46 for (int i = 0; i < _items; ++i)
47 if (_cons[i] && (_cons[i]->state() & OUTENABLED))
48 _cons[i]->write(str, len);
55 Mux_console::getchar(bool blocking)
57 if (_next_getchar != -1)
59 int c = _next_getchar;
67 for (int i = 0; i < _items; ++i)
68 if (_cons[i] && (_cons[i]->state() & INENABLED))
70 ret = _cons[i]->getchar(false);
78 while (blocking && ret == -1);
84 * deliver attributes of all subconsoles.
88 Mux_console::get_attributes() const
92 for (int i = 0; i < _items; i++)
94 attr |= _cons[i]->get_attributes();
101 Mux_console::getchar_chance()
103 for (int i = 0; i < _items; ++i)
104 if ( _cons[i] && (_cons[i]->state() & INENABLED)
105 && _cons[i]->char_avail() == 1)
107 int c = _cons[i]->getchar(false);
108 if (c != -1 && _next_getchar == -1)
115 Mux_console::char_avail() const
118 for (int i = 0; i < _items; ++i)
119 if (_cons[i] && (_cons[i]->state() & INENABLED))
121 int tmp = _cons[i]->char_avail();
131 * Register a console to be multiplexed.
132 * @param cons the Console to add.
133 * @param pos the position of the console, normally not needed.
137 Mux_console::register_console(Console *c, int pos = 0)
145 if (pos >= SIZE || pos < 0)
152 for (int i = _items - 1; i >= pos; --i)
153 _cons[i + 1] = _cons[i];
157 if (_cons[pos]->state() & DISABLED_INIT)
158 _cons[pos]->state(DISABLED);
160 _cons[pos]->state(INENABLED | OUTENABLED);
166 * Unregister a console from the multiplexer.
167 * @param cons the console to remove.
171 Mux_console::unregister_console(Console *c)
174 for (pos = 0; pos < _items && _cons[pos] != c; pos++)
180 for (int i = pos; i < _items; ++i)
181 _cons[i] = _cons[i + 1];
187 * Change the state of a group of consoles specified by
189 * @param any_true match if console has any of these attributes
190 * @param all_false match if console doesn't have any of these attributes
194 Mux_console::change_state(Mword any_true, Mword all_false,
195 Mword mask, Mword bits)
197 for (int i=0; i<_items; i++)
201 Mword attr = _cons[i]->get_attributes();
202 if ( // any bit of the any_true attributes must be set
203 (!any_true || (attr & any_true) != 0)
204 // all bits of the all_false attributes must be cleared
205 && (!all_false || (attr & all_false) == 0))
207 _cons[i]->state((_cons[i]->state() & mask) | bits);
214 * Find a console with a specific attribute.
215 * @param any_true match to console which has set any bit of this bitmask
219 Mux_console::find_console(Mword any_true)
221 for (int i = 0; i < _items; i++)
222 if (_cons[i] && _cons[i]->get_attributes() & any_true)
229 * Start exclusive mode for a specific console. Only the one
230 * console which matches to any_true is enabled for input and
231 * output. All other consoles are disabled.
232 * @param any_true match to console which has set any bit of this bitmask
236 Mux_console::start_exclusive(Mword any_true)
238 // enable exclusive console
239 change_state(any_true, 0, ~0UL, (OUTENABLED|INENABLED));
240 // disable all other consoles
241 change_state(0, any_true, ~(OUTENABLED|INENABLED), 0);
245 * End exclusive mode for a specific console.
246 * @param any_true match to console which has set any bit of this bitmask
250 Mux_console::end_exclusive(Mword any_true)
252 // disable exclusive console
253 change_state(any_true, 0, ~(OUTENABLED|INENABLED), 0);
254 // enable all other consoles
255 change_state(0, any_true, ~0UL, (OUTENABLED|INENABLED));
259 IMPLEMENTATION[debug]:
263 Mux_console::list_consoles()
265 for (int i = 0; i < _items; i++)
268 Mword attr = _cons[i]->get_attributes();
270 printf(" " L4_PTR_FMT " %s (%s) ",
271 attr, _cons[i]->str_mode(), _cons[i]->str_state());
272 for (unsigned bit = 2; bit < sizeof(attr) * 4; bit++)
273 if (attr & (1 << bit))
274 printf("%s ", Console::str_attr(bit));