120 lines
3.2 KiB
C
120 lines
3.2 KiB
C
/* Calcite, src/user-apps/terminal/terminal.c
|
|
* Copyright 2026 Benji Dial
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <kernel-public/framebuffer.h>
|
|
#include <kernel-public/process.h>
|
|
#include <flanterm_backends/fb.h>
|
|
#include <kernel-public/ipc.h>
|
|
#include <calcite/dispatch.h>
|
|
#include <calcite/syscalls.h>
|
|
#include <calcite/format.h>
|
|
#include <calcite/memory.h>
|
|
#include <flanterm.h>
|
|
|
|
static struct flanterm_context *flanterm_context;
|
|
|
|
static ipc_dgram_receiver_handle_t input_handle;
|
|
static ipc_dgram_receiver_handle_t output_handle;
|
|
|
|
static struct dispatch_queue *queue;
|
|
|
|
struct got_output_param {
|
|
int dgram_bytes;
|
|
void *dgram;
|
|
};
|
|
|
|
static void got_output(void *x) {
|
|
struct got_output_param *param = x;
|
|
flanterm_write(flanterm_context, param->dgram, param->dgram_bytes);
|
|
heap_dealloc(param->dgram, param->dgram_bytes);
|
|
heap_dealloc(param, sizeof(struct got_output_param));
|
|
}
|
|
|
|
[[noreturn]] static void output_thread(uint64_t) {
|
|
|
|
while (1) {
|
|
|
|
int dgram_bytes = 0;
|
|
ipc_receive_dgram(output_handle, 0, &dgram_bytes);
|
|
|
|
void *dgram = heap_alloc(dgram_bytes);
|
|
ipc_receive_dgram(output_handle, dgram, &dgram_bytes);
|
|
|
|
struct got_output_param *param = heap_alloc(sizeof(struct got_output_param));
|
|
param->dgram_bytes = dgram_bytes;
|
|
param->dgram = dgram;
|
|
|
|
dispatch(queue, &got_output, param);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[[noreturn]] static void input_thread(uint64_t) {
|
|
|
|
//TODO
|
|
while (1)
|
|
sleep_ms(1000000000);
|
|
|
|
}
|
|
|
|
void main() {
|
|
|
|
uint64_t output_pipe = ipc_create_private_dgram_pipe();
|
|
uint64_t input_pipe = ipc_create_private_dgram_pipe();
|
|
|
|
ipc_create_private_dgram_receiver(output_pipe, &output_handle);
|
|
ipc_create_private_dgram_sender(input_pipe, &input_handle);
|
|
|
|
struct framebuffer_info fb;
|
|
map_framebuffer(&fb);
|
|
|
|
flanterm_context =
|
|
flanterm_fb_init(
|
|
&heap_alloc, &heap_dealloc, (void *)fb.fb_base, fb.fb_width,
|
|
fb.fb_height, fb.fb_pitch, 8, 16, 8,
|
|
8, 8, 0, 0, 0,
|
|
0, 0, 0, 0, 0,
|
|
0, 0, 0, 1, 0, 0, 0);
|
|
|
|
queue = create_dispatch_queue();
|
|
|
|
create_thread(&output_thread, 0);
|
|
create_thread(&input_thread, 0);
|
|
|
|
char input_pipe_hex[17];
|
|
to_hex(input_pipe, 16, input_pipe_hex);
|
|
input_pipe_hex[16] = 0;
|
|
|
|
char output_pipe_hex[17];
|
|
to_hex(output_pipe, 16, output_pipe_hex);
|
|
output_pipe_hex[16] = 0;
|
|
|
|
const char *envvars[4] = {
|
|
"TERMINAL_INPUT_PIPE_ID", input_pipe_hex,
|
|
"TERMINAL_OUTPUT_PIPE_ID", output_pipe_hex };
|
|
|
|
struct process_start_info psi;
|
|
psi.forwared_envvar_count = 0;
|
|
psi.set_envvar_count = 2;
|
|
psi.set_envvars = envvars;
|
|
|
|
start_elf("root://calcite/apps/shell/shell.elf", &psi);
|
|
|
|
dispatch_loop(queue);
|
|
|
|
}
|