test_console: Use new eloop and VT subsystem
The test_console application now supports VT-switching and monitor-hotplug. New monitors are detected when switching VTs. Full hotplug-support will be added later. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
e195d911e1
commit
20beb30357
@ -46,6 +46,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <locale.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -53,143 +54,218 @@
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user