94 lines
2.8 KiB
C
Executable File
94 lines
2.8 KiB
C
Executable File
/*
|
|
* 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 <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <sys/wait.h>
|
|
#include <signal.h>
|
|
#include <linux/input.h>
|
|
#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;
|
|
} |