2 * test_console - Test Console
4 * Copyright (c) 2011 David Herrmann <dh.herrmann@googlemail.com>
5 * Copyright (c) 2011 University of Tuebingen
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files
9 * (the "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 * This prints a console onto all available outputs. The console is not
30 * interactive, but instead all input from stdin is read and printed as
31 * printable characters onto the console.
32 * This is no terminal emulation but instead an example how to print text with
33 * the console subsystem.
35 * This prints all text from stdin to all connected outputs:
38 * This prints the text from the command "ls -la" to all outptus:
39 * $ ls -la | ./test_console
59 static volatile sig_atomic_t terminate;
62 struct ev_eloop *loop;
63 struct ev_signal *sig_term;
64 struct ev_signal *sig_int;
65 struct ev_fd *stdin_fd;
66 struct kmscon_symbol_table *st;
67 struct kmscon_font_factory *ff;
68 struct kmscon_compositor *comp;
70 struct kmscon_console *con;
77 static void stdin_cb(struct ev_fd *fd, int mask, void *data)
79 struct console *con = data;
88 ret = read(0, buf, sizeof(buf));
90 log_info("stdin read error: %d\n", errno);
92 log_info("stdin closed\n");
97 log_debug("stdin input read (len: %d)\n", len);
99 for (i = 0; i < len; ++i) {
100 if (buf[i] == '\n') {
101 kmscon_console_newline(con->con);
104 kmscon_console_write(con->con, ch);
110 static void map_outputs(struct console *con)
113 struct kmscon_output *iter;
114 struct kmscon_context *ctx;
116 if (kmscon_compositor_is_asleep(con->comp))
119 ctx = kmscon_compositor_get_context(con->comp);
121 iter = kmscon_compositor_get_outputs(con->comp);
122 for ( ; iter; iter = kmscon_output_next(iter)) {
123 if (!kmscon_output_is_active(iter))
126 ret = kmscon_output_use(iter);
130 kmscon_context_clear(ctx);
131 kmscon_console_map(con->con);
133 ret = kmscon_output_swap(iter);
139 static void draw(struct ev_idle *idle, void *data)
141 struct console *con = data;
143 ev_eloop_rm_idle(idle);
147 static void schedule_draw(struct console *con)
151 ret = ev_eloop_add_idle(con->loop, con->idle, draw, con);
152 if (ret && ret != -EALREADY)
153 log_warn("Cannot schedule draw function\n");
156 static void activate_outputs(struct console *con)
158 struct kmscon_output *iter;
159 struct kmscon_mode *mode;
165 iter = kmscon_compositor_get_outputs(con->comp);
166 for ( ; iter; iter = kmscon_output_next(iter)) {
167 if (!kmscon_output_is_active(iter)) {
168 ret = kmscon_output_activate(iter, NULL);
173 mode = kmscon_output_get_current(iter);
174 y = kmscon_mode_get_height(mode);
179 kmscon_console_resize(con->con, 0, 0, con->max_y);
183 static void sig_term(struct ev_signal *sig, int signum, void *data)
188 static bool vt_switch(struct kmscon_vt *vt, int action, void *data)
190 struct console *con = data;
193 if (action == KMSCON_VT_ENTER) {
194 ret = kmscon_compositor_wake_up(con->comp);
196 log_info("No output found\n");
197 } else if (ret > 0) {
198 activate_outputs(con);
201 kmscon_compositor_sleep(con->comp);
207 static const char help_text[] =
208 "test_console - KMS based console test\n"
209 "This application can be used to test the console subsystem. It copies stdin "
210 "to the console so you can use it to print arbitrary text like this:\n"
211 " ls -la / | sudo ./test_console\n"
212 "Please be aware that the application needs root rights to access the VT. "
213 "If no VT support is compiled in you can run it without root rights but you "
214 "should not start it from inside X!\n\n";
216 static void print_help(struct console *con)
221 len = sizeof(help_text) - 1;
222 for (i = 0; i < len; ++i) {
223 if (help_text[i] == '\n') {
224 kmscon_console_newline(con->con);
227 kmscon_console_write(con->con, ch);
232 static void destroy_eloop(struct console *con)
234 ev_eloop_rm_idle(con->idle);
235 ev_idle_unref(con->idle);
236 kmscon_console_unref(con->con);
237 kmscon_compositor_unref(con->comp);
238 kmscon_vt_unref(con->vt);
239 kmscon_font_factory_unref(con->ff);
240 kmscon_symbol_table_unref(con->st);
241 ev_eloop_rm_fd(con->stdin_fd);
242 ev_eloop_rm_signal(con->sig_int);
243 ev_eloop_rm_signal(con->sig_term);
244 ev_eloop_unref(con->loop);
247 static int setup_eloop(struct console *con)
251 ret = ev_eloop_new(&con->loop);
255 ret = ev_eloop_new_signal(con->loop, &con->sig_term, SIGTERM,
260 ret = ev_eloop_new_signal(con->loop, &con->sig_int, SIGINT,
265 ret = ev_eloop_new_fd(con->loop, &con->stdin_fd, 0,
266 EV_READABLE, stdin_cb, con);
270 ret = kmscon_symbol_table_new(&con->st);
274 ret = kmscon_compositor_new(&con->comp);
278 ret = kmscon_compositor_use(con->comp);
282 ret = kmscon_font_factory_new(&con->ff, con->st, con->comp);
286 ret = kmscon_vt_new(&con->vt, vt_switch, con);
290 ret = kmscon_vt_open(con->vt, KMSCON_VT_NEW, con->loop);
294 ret = kmscon_console_new(&con->con, con->ff, con->comp);
298 ret = ev_idle_new(&con->idle);
310 int main(int argc, char **argv)
315 setlocale(LC_ALL, "");
316 memset(&con, 0, sizeof(con));
318 ret = setup_eloop(&con);
320 log_err("Cannot setup eloop\n");
324 log_info("Starting console\n");
329 ret = ev_eloop_dispatch(con.loop, -1);
334 log_info("Stopping console\n");