diff --git a/tests/test_console.c b/tests/test_console.c index 6eab19a..c29ecd8 100644 --- a/tests/test_console.c +++ b/tests/test_console.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -53,143 +54,218 @@ #include #include #include "console.h" +#include "eloop.h" #include "log.h" #include "output.h" +#include "vt.h" static volatile sig_atomic_t terminate; -static void sig_term(int sig) -{ - terminate = 1; -} +struct console { + struct kmscon_eloop *loop; + struct kmscon_signal *sig_term; + struct kmscon_signal *sig_int; + struct kmscon_compositor *comp; + struct kmscon_vt *vt; + struct kmscon_console *con; + struct kmscon_idle *idle; -static int map_outputs(struct kmscon_compositor *comp, - struct kmscon_console *con) + uint32_t max_x; + uint32_t max_y; +}; + +static void map_outputs(struct console *con) { int ret; struct kmscon_output *iter; - iter = kmscon_compositor_get_outputs(comp); + if (kmscon_compositor_is_asleep(con->comp)) + return; + + kmscon_console_draw(con->con); + + iter = kmscon_compositor_get_outputs(con->comp); for ( ; iter; iter = kmscon_output_next(iter)) { if (!kmscon_output_is_active(iter)) continue; ret = kmscon_output_use(iter); - if (ret) { - log_warning("Cannot use output %p: %d\n", iter, ret); + if (ret) continue; - } glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); - kmscon_console_map(con); + kmscon_console_map(con->con); ret = kmscon_output_swap(iter); - if (ret) { - log_warning("Cannot swap buffers of output %p: %d\n", - iter, ret); + if (ret) continue; - } } - - return 0; } -static int run_console(struct kmscon_compositor *comp) +static void draw(struct kmscon_idle *idle, void *data) +{ + struct console *con = data; + + kmscon_eloop_rm_idle(idle); + map_outputs(con); +} + +static void schedule_draw(struct console *con) +{ + int ret; + + ret = kmscon_eloop_add_idle(con->loop, con->idle, draw, con); + if (ret && ret != -EALREADY) + log_warning("Cannot schedule draw function\n"); +} + +static void activate_outputs(struct console *con) { struct kmscon_output *iter; struct kmscon_mode *mode; - struct kmscon_console *con; int ret; - uint32_t max_x, max_y, x, y; + uint32_t x, y; - max_x = 0; - max_y = 0; + con->max_x = 0; + con->max_y = 0; - iter = kmscon_compositor_get_outputs(comp); + iter = kmscon_compositor_get_outputs(con->comp); for ( ; iter; iter = kmscon_output_next(iter)) { - log_info("Activating output %p...\n", iter); - ret = kmscon_output_activate(iter, NULL); - if (ret) { - log_err("Cannot activate output: %d\n", ret); - continue; + if (!kmscon_output_is_active(iter)) { + ret = kmscon_output_activate(iter, NULL); + if (ret) + continue; } mode = kmscon_output_get_current(iter); x = kmscon_mode_get_width(mode); y = kmscon_mode_get_height(mode); - if (x > max_x) - max_x = x; - if (y > max_y) - max_y = y; + if (x > con->max_x) + con->max_x = x; + if (y > con->max_y) + con->max_y = y; } - if (max_x == 0 || max_y == 0) { - log_err("Cannot retrieve output resolution\n"); - return -EINVAL; + if (con->max_x == 0) + con->max_x = 800; + if (con->max_y == 0) + con->max_y = 600; + + kmscon_console_set_res(con->con, con->max_x, con->max_y); + schedule_draw(con); +} + +static void sig_term(struct kmscon_signal *sig, int signum, void *data) +{ + terminate = 1; +} + +static bool vt_switch(struct kmscon_vt *vt, int action, void *data) +{ + struct console *con = data; + int ret; + + if (action == KMSCON_VT_ENTER) { + ret = kmscon_compositor_wake_up(con->comp); + if (ret == 0) { + log_info("No output found\n"); + } else if (ret > 0) { + ret = kmscon_compositor_use(con->comp); + if (!ret) + activate_outputs(con); + } + } else { + kmscon_compositor_sleep(con->comp); } - ret = kmscon_console_new(&con); - if (ret) { - log_err("Cannot create console: %d\n", ret); + return true; +} + +static void destroy_eloop(struct console *con) +{ + kmscon_eloop_rm_idle(con->idle); + kmscon_idle_unref(con->idle); + kmscon_compositor_unref(con->comp); + kmscon_console_unref(con->con); + kmscon_vt_unref(con->vt); + kmscon_eloop_rm_signal(con->sig_int); + kmscon_eloop_rm_signal(con->sig_term); + kmscon_eloop_unref(con->loop); +} + +static int setup_eloop(struct console *con) +{ + int ret; + + ret = kmscon_eloop_new(&con->loop); + if (ret) return ret; - } - ret = kmscon_console_set_res(con, max_x, max_y); - if (ret) { - log_err("Cannot set console resolution: %d\n", ret); - goto err_unref; - } + ret = kmscon_eloop_new_signal(con->loop, &con->sig_term, SIGTERM, + sig_term, NULL); + if (ret) + goto err_loop; - while (!terminate) { - kmscon_console_draw(con); - map_outputs(comp, con); - usleep(10000); - } + ret = kmscon_eloop_new_signal(con->loop, &con->sig_int, SIGINT, + sig_term, NULL); + if (ret) + goto err_loop; - log_info("Terminating due to user request\n"); + ret = kmscon_vt_new(&con->vt, vt_switch, con); + if (ret) + goto err_loop; -err_unref: - kmscon_console_unref(con); + ret = kmscon_vt_open(con->vt, KMSCON_VT_NEW); + if (ret) + goto err_loop; + + ret = kmscon_vt_connect_eloop(con->vt, con->loop); + if (ret) + goto err_loop; + + ret = kmscon_console_new(&con->con); + if (ret) + goto err_loop; + + ret = kmscon_compositor_new(&con->comp); + if (ret) + goto err_loop; + + ret = kmscon_idle_new(&con->idle); + if (ret) + goto err_loop; + + return 0; + +err_loop: + destroy_eloop(con); return ret; } int main(int argc, char **argv) { - struct kmscon_compositor *comp; + struct console con; int ret; - struct sigaction sig; setlocale(LC_ALL, ""); + memset(&con, 0, sizeof(con)); - memset(&sig, 0, sizeof(sig)); - sig.sa_handler = sig_term; - sigaction(SIGTERM, &sig, NULL); - sigaction(SIGINT, &sig, NULL); - - ret = kmscon_compositor_new(&comp); + ret = setup_eloop(&con); if (ret) { - log_err("Cannot create compositor: %d\n", ret); + log_err("Cannot setup eloop\n"); return abs(ret); } - ret = kmscon_compositor_wake_up(comp); - if (ret < 0) { - log_err("Cannot wake up compositor: %d\n", ret); - goto err_unref; + schedule_draw(&con); + + while (!terminate) { + ret = kmscon_eloop_dispatch(con.loop, -1); + if (ret) + break; } - if (ret == 0) { - log_err("No output available\n"); - ret = -EINVAL; - goto err_unref; - } - - kmscon_compositor_use(comp); - ret = run_console(comp); - -err_unref: - kmscon_compositor_unref(comp); + destroy_eloop(&con); return abs(ret); }