/* * vterm.c -- FreeDOS Emulation Bridge module * * SPDX-License-Identifier: GPL-2.0-or-later * * Forks dosbox with a custom config for the * FreeDOS environment. BACK key sends SIGTERM to the child. * Monitors child exit via waitpid(WNOHANG). */ #include #include #include #include #include #include #include #include "h2_ui.h" #include "log_manager.h" int main(void) { init_h2_graphics_runtime("X86 EMULATION ENVIRONMENT"); LOG_INF("vterm module started"); lv_obj_t *scr = lv_scr_act(); lv_obj_t *title = lv_label_create(scr); lv_label_set_text(title, "EMULATION RUNTIME ENGINE"); lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 15); lv_obj_set_style_text_color(title, COLOR_PRIMARY, LV_PART_MAIN); lv_obj_t *status = lv_label_create(scr); lv_label_set_text(status, "Launching FreeDOS container...\n[BACK] to terminate"); lv_obj_align(status, LV_ALIGN_CENTER, 0, 0); lv_obj_set_style_text_align(status, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN); lv_timer_handler(); pid_t pid = fork(); if (pid == 0) { char *args[] = {"/usr/bin/dosbox", "-conf", "/data/vterm/dosbox.conf", NULL}; execv(args[0], args); _exit(1); } if (pid < 0) { lv_label_set_text(status, "FORK FAILED"); LOG_ERR("fork failed for dosbox"); } else { LOG_INF("dosbox launched (pid %d)", (int)pid); } int input_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK); struct input_event ev; int child_done = (pid < 0); while (!child_done) { lv_timer_handler(); int wstatus; pid_t ret = waitpid(pid, &wstatus, WNOHANG); if (ret == pid) { child_done = 1; lv_label_set_text(status, "DOSBOX EXITED.\n[BACK] to return"); LOG_INF("dosbox exited"); } if (input_fd >= 0 && read(input_fd, &ev, sizeof(struct input_event)) > 0) { if (ev.type == EV_KEY && ev.code == H2_KEY_BACK && ev.value == 1) { if (!child_done && pid > 0) { kill(pid, SIGTERM); usleep(200000); waitpid(pid, &wstatus, WNOHANG); LOG_INF("dosbox terminated by user"); } break; } } usleep(20000); } if (child_done && input_fd >= 0) { while (1) { lv_timer_handler(); if (read(input_fd, &ev, sizeof(struct input_event)) > 0) { if (ev.type == EV_KEY && ev.code == H2_KEY_BACK && ev.value == 1) break; } usleep(20000); } } if (input_fd >= 0) close(input_fd); LOG_INF("vterm module exited"); return 0; }