mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
feat(gui): Make the desktop terminal run real commands
The GUI terminal recognised four hardcoded strings and answered everything else
with "Executed: '<cmd>'". It now dispatches to the same LazyBox applet table and
shell builtins the kernel TTY uses, so ls, free, uname, lspci, ktest, neofetch,
sort, cd and the rest all work, with cwd tracked across commands.
LazyBox reports through printk, so before running a command the terminal
installs a printk sink and streams the output into its own scrollback:
- ANSI SGR codes become per-line colours instead of being stripped.
- CP437 box-drawing and block characters fall back to ASCII, so the colour
swatch in neofetch renders as '#' rather than a row of '?'.
- 256 lines of scrollback, command history on Up/Down, PgUp/PgDn/Home/End.
- Applets that read the keyboard directly (nano, snake, sh, top) are refused
with a pointer to the TTY, since they would block the compositor.
The window's paint and event handlers moved out of gui_apps.c into
gui/gui_terminal.c, and gui_gfx.c now draws from the shared lib/font8x8.c table
rather than its own copy.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP
This commit is contained in:
1 parent
56a378b142
commit
eacba4f4d3
8 files changed
+543
-196
No files matched your search
@@ -89,98 +89,6 @@ void gui_app_sysmon_launch(int x, int y, int w, int h) {
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// 2. GUI Terminal Emulator App (High-Res 440x280)
|
||||
// =================================================================
|
||||
typedef struct {
|
||||
char lines[12][50];
|
||||
int line_count;
|
||||
char input[48];
|
||||
int input_len;
|
||||
} term_data_t;
|
||||
|
||||
static void terminal_paint(gui_window_t* win) {
|
||||
term_data_t* td = (term_data_t*)win->user_data;
|
||||
if (!td) return;
|
||||
|
||||
int cx = win->x + 10;
|
||||
int cy = win->y + GUI_TITLEBAR_HEIGHT + 8;
|
||||
|
||||
gui_gfx_fill_rect(win->x + 1, win->y + GUI_TITLEBAR_HEIGHT + 1, win->width - 2, win->height - GUI_TITLEBAR_HEIGHT - 2, 0xFF0B0F19);
|
||||
|
||||
// Render lines with sharp 8x16 font
|
||||
for (int i = 0; i < td->line_count && i < 11; i++) {
|
||||
uint32_t fg = (td->lines[i][0] == '$') ? GUI_THEME_SUCCESS : GUI_THEME_TEXT_MAIN;
|
||||
gui_gfx_draw_string_16(cx, cy + i * 18, td->lines[i], fg);
|
||||
}
|
||||
|
||||
// Render active prompt line
|
||||
int prompt_y = cy + td->line_count * 18;
|
||||
if (prompt_y < win->y + win->height - 20) {
|
||||
gui_gfx_draw_string_16(cx, prompt_y, "sub-os:/> ", GUI_THEME_PRIMARY);
|
||||
gui_gfx_draw_string_16(cx + 80, prompt_y, td->input, GUI_THEME_TEXT_MAIN);
|
||||
// Blinking Cursor block
|
||||
gui_gfx_fill_rect(cx + 80 + td->input_len * 8, prompt_y + 2, 8, 14, GUI_THEME_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
static void terminal_event(gui_window_t* win, const gui_event_t* ev) {
|
||||
term_data_t* td = (term_data_t*)win->user_data;
|
||||
if (!td) return;
|
||||
|
||||
if (ev->type == GUI_EVENT_KEY_DOWN) {
|
||||
char c = (char)(ev->key & 0xFF);
|
||||
if (c == '\n' || c == '\r') {
|
||||
if (td->line_count < 10) {
|
||||
snprintf(td->lines[td->line_count], 50, "$ %s", td->input);
|
||||
td->line_count++;
|
||||
if (strcmp(td->input, "clear") == 0) {
|
||||
td->line_count = 0;
|
||||
} else if (strcmp(td->input, "uname") == 0) {
|
||||
snprintf(td->lines[td->line_count++], 50, "SUB-OS 0.2.0-lts (x86_64)");
|
||||
} else if (strcmp(td->input, "help") == 0) {
|
||||
snprintf(td->lines[td->line_count++], 50, "Commands: uname, clear, date, tree, help");
|
||||
} else if (strcmp(td->input, "tree") == 0) {
|
||||
snprintf(td->lines[td->line_count++], 50, "/ [bin etc dev proc sys home mnt]");
|
||||
} else if (td->input_len > 0) {
|
||||
snprintf(td->lines[td->line_count++], 50, "Executed: '%s'", td->input);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 9; i++) strcpy(td->lines[i], td->lines[i + 1]);
|
||||
snprintf(td->lines[9], 50, "$ %s", td->input);
|
||||
}
|
||||
td->input[0] = '\0';
|
||||
td->input_len = 0;
|
||||
} else if (c == '\b' || (uint8_t)c == 0x7F) {
|
||||
if (td->input_len > 0) {
|
||||
td->input_len--;
|
||||
td->input[td->input_len] = '\0';
|
||||
}
|
||||
} else if (c >= 32 && c <= 126 && td->input_len < 36) {
|
||||
td->input[td->input_len++] = c;
|
||||
td->input[td->input_len] = '\0';
|
||||
}
|
||||
} else if (ev->type == GUI_EVENT_CLOSE) {
|
||||
if (win->user_data) {
|
||||
kfree(win->user_data);
|
||||
win->user_data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gui_app_terminal_launch(int x, int y, int w, int h) {
|
||||
gui_window_t* win = gui_wm_create_window("Terminal Console", x, y, (w > 0) ? w : 440, (h > 0) ? h : 270);
|
||||
if (win) {
|
||||
term_data_t* td = (term_data_t*)kzalloc(sizeof(term_data_t));
|
||||
strcpy(td->lines[0], "SUB-OS High-Resolution Terminal Emulator");
|
||||
strcpy(td->lines[1], "Type 'uname', 'tree', or 'help'");
|
||||
td->line_count = 2;
|
||||
win->user_data = td;
|
||||
win->paint = terminal_paint;
|
||||
win->handle_event = terminal_event;
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// 3. File Manager Explorer App (High-Res 380x240)
|
||||
// =================================================================
|
||||
|
||||
Reference in new issue
Block a user