From 7c6cd9c5313ad6b7428f0e4ab9b3909d52500fdd Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Sun, 4 Mar 2018 22:50:53 +0900 Subject: [PATCH] Add VGA terminal --- Makefile | 5 +- apps/init.c | 22 +- apps/terminal-vga.c | 939 ++++++++++++++++++++++++++++++++++++++ apps/vga-palette.h | 259 +++++++++++ cdrom/boot/grub/menus.cfg | 12 +- lib/yutani.c | 1 - 6 files changed, 1231 insertions(+), 7 deletions(-) create mode 100644 apps/terminal-vga.c create mode 100644 apps/vga-palette.h diff --git a/Makefile b/Makefile index 34d0c0d3..febff851 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -APPS=init hello sh ls terminal uname compositor drawlines background session kdebug cat yutani-test sysinfo hostname yutani-query env mount date echo nyancat kill ps pstree bim +APPS=init hello sh ls terminal uname compositor drawlines background session kdebug cat yutani-test sysinfo hostname yutani-query env mount date echo nyancat kill ps pstree bim terminal-vga CC=i686-pc-toaru-gcc AR=i686-pc-toaru-ar @@ -89,6 +89,9 @@ base/bin/sysinfo: apps/sysinfo.c base/lib/libnihc.so base/lib/libtoaru_graphics. base/bin/terminal: apps/terminal.c base/lib/libnihc.so base/lib/libtoaru_graphics.so base/lib/libtoaru_yutani.so base/lib/libtoaru_decorations.so base/lib/libtoaru_dlfcn.so base/lib/libtoaru_list.so base/lib/libtoaru_kbd.so base/lib/libtoaru_termemu.so base/lib/libtoaru_pex.so base/lib/libtoaru_hashmap.so $(CC) $(CFLAGS) -o $@ $< -ltoaru_termemu -ltoaru_decorations -ltoaru_yutani -ltoaru_graphics -ltoaru_pex -ltoaru_hashmap -ltoaru_dlfcn -ltoaru_kbd -ltoaru_list $(LIBS) +base/bin/terminal-vga: apps/terminal-vga.c base/lib/libnihc.so base/lib/libtoaru_graphics.so base/lib/libtoaru_kbd.so base/lib/libtoaru_termemu.so + $(CC) $(CFLAGS) -o $@ $< -ltoaru_termemu -ltoaru_graphics -ltoaru_kbd $(LIBS) + base/bin/background: apps/background.c base/lib/libnihc.so base/lib/libtoaru_graphics.so base/lib/libtoaru_yutani.so base/lib/libtoaru_pthread.so base/lib/libtoaru_drawstring.so $(CC) $(CFLAGS) -o $@ $< -ltoaru_drawstring -ltoaru_yutani -ltoaru_graphics -ltoaru_pex -ltoaru_pthread -ltoaru_hashmap -ltoaru_list $(LIBS) diff --git a/apps/init.c b/apps/init.c index d10fc041..a8999ccf 100644 --- a/apps/init.c +++ b/apps/init.c @@ -1,7 +1,7 @@ #include #include -#include <_xlog.h> #include +#include void set_console() { int _stdin = syscall_open("/dev/null", 0, 0); @@ -37,7 +37,6 @@ int start_options(char * args[]) { } int main(int argc, char * argv[]) { - _XLOG("Init starting..."); set_console(); char * _argv[] = { @@ -46,5 +45,22 @@ int main(int argc, char * argv[]) { }; syscall_sethostname("base"); - return start_options(_argv); + + if (argc > 1) { + char * args = NULL; + if (argc > 2) { + args = argv[2]; + } + if (!strcmp(argv[1], "--vga")) { + return start_options((char *[]){"/bin/terminal-vga","-l",NULL}); +#if 0 + } else if (!strcmp(argv[1], "--migrate")) { + return start_options((char *[]){"/usr/bin/python","/bin/migrate.py",NULL}); +#endif + } else { + /* Pass it to the compositor... */ + return start_options((char *[]){"/bin/compositor","--",argv[1],NULL}); + } + } + return start_options((char *[]){"/bin/compositor",NULL}); } diff --git a/apps/terminal-vga.c b/apps/terminal-vga.c new file mode 100644 index 00000000..d3567c12 --- /dev/null +++ b/apps/terminal-vga.c @@ -0,0 +1,939 @@ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * This file is part of ToaruOS and is released under the terms + * of the NCSA / University of Illinois License - see LICENSE.md + * Copyright (C) 2014 Kevin Lange + * + * Terminal Emulator - VGA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "lib/utf8decode.h" +#include "lib/kbd.h" +#include "lib/graphics.h" +#include "lib/termemu.h" + +#include "vga-palette.h" + +#define USE_BELL 0 + +/* master and slave pty descriptors */ +static int fd_master, fd_slave; +static FILE * terminal; + +uint16_t term_width = 80; /* Width of the terminal (in cells) */ +uint16_t term_height = 25; /* Height of the terminal (in cells) */ +uint16_t csr_x = 0; /* Cursor X */ +uint16_t csr_y = 0; /* Cursor Y */ +term_cell_t * term_buffer = NULL; /* The terminal cell buffer */ +uint32_t current_fg = 7; /* Current foreground color */ +uint32_t current_bg = 0; /* Current background color */ +uint8_t cursor_on = 1; /* Whether or not the cursor should be rendered */ + +uint8_t _login_shell = 0; /* Whether we're going to display a login shell or not */ +uint8_t _hold_out = 0; /* state indicator on last cell ignore \n */ + +uint64_t mouse_ticks = 0; + +#define char_width 1 +#define char_height 1 + +term_state_t * ansi_state = NULL; + +void reinit(); /* Defined way further down */ +void term_redraw_cursor(); + +/* Cursor bink timer */ +static unsigned int timer_tick = 0; + +void term_clear(); + +void dump_buffer(); + +static uint64_t get_ticks(void) { + struct timeval now; + gettimeofday(&now, NULL); + + return (uint64_t)now.tv_sec * 1000000LL + (uint64_t)now.tv_usec; +} + +static int color_distance(uint32_t a, uint32_t b) { + int a_r = (a & 0xFF0000) >> 16; + int a_g = (a & 0xFF00) >> 8; + int a_b = (a & 0xFF); + + int b_r = (b & 0xFF0000) >> 16; + int b_g = (b & 0xFF00) >> 8; + int b_b = (b & 0xFF); + + int distance = 0; + distance += abs(a_r - b_r) * 3; + distance += abs(a_g - b_g) * 6; + distance += abs(a_b - b_b) * 10; + + return distance; +} + +static uint32_t vga_base_colors[] = { + 0x000000, + 0xAA0000, + 0x00AA00, + 0xAA5500, + 0x0000AA, + 0xAA00AA, + 0x00AAAA, + 0xAAAAAA, + 0x555555, + 0xFF5555, + 0x55AA55, + 0xFFFF55, + 0x5555FF, + 0xFF55FF, + 0x55FFFF, + 0xFFFFFF, +}; + +static int is_gray(uint32_t a) { + int a_r = (a & 0xFF0000) >> 16; + int a_g = (a & 0xFF00) >> 8; + int a_b = (a & 0xFF); + + return (a_r == a_g && a_g == a_b); +} + +static int best_match(uint32_t a) { + int best_distance = INT32_MAX; + int best_index = 0; + for (int j = 0; j < 16; ++j) { + if (is_gray(a) && !is_gray(vga_base_colors[j])); + int distance = color_distance(a, vga_base_colors[j]); + if (distance < best_distance) { + best_index = j; + best_distance = distance; + } + } + return best_index; +} + + +volatile int exit_application = 0; + +static void set_term_font_size(float s) { + /* do nothing */ +} + +/* Returns the lower of two shorts */ +uint16_t min(uint16_t a, uint16_t b) { + return (a < b) ? a : b; +} + +/* Returns the higher of two shorts */ +uint16_t max(uint16_t a, uint16_t b) { + return (a > b) ? a : b; +} + +void set_title(char * c) { + /* Do nothing */ +} + +void input_buffer_stuff(char * str) { + size_t s = strlen(str) + 1; + write(fd_master, str, s); +} + +unsigned short * textmemptr = (unsigned short *)0xB8000; +void placech(unsigned char c, int x, int y, int attr) { + unsigned short *where; + unsigned att = attr << 8; + where = textmemptr + (y * 80 + x); + *where = c | att; +} + +/* ANSI-to-VGA */ +char vga_to_ansi[] = { + 0, 4, 2, 6, 1, 5, 3, 7, + 8,12,10,14, 9,13,11,15 +}; + +uint32_t ununicode(uint32_t c) { + switch (c) { + case L'☺': return 1; + case L'☻': return 2; + case L'♥': return 3; + case L'♦': return 4; + case L'♣': return 5; + case L'♠': return 6; + case L'•': return 7; + case L'◘': return 8; + case L'○': return 9; + case L'◙': return 10; + case L'♂': return 11; + case L'♀': return 12; + case L'♪': return 13; + case L'♫': return 14; + case L'☼': return 15; + case L'►': return 16; + case L'◄': return 17; + case L'↕': return 18; + case L'‼': return 19; + case L'¶': return 20; + case L'§': return 21; + case L'▬': return 22; + case L'↨': return 23; + case L'↑': return 24; + case L'↓': return 25; + case L'→': return 26; + case L'←': return 27; + case L'∟': return 28; + case L'↔': return 29; + case L'▲': return 30; + case L'▼': return 31; + /* ASCII text */ + case L'⌂': return 127; + case L'Ç': return 128; + case L'ü': return 129; + case L'é': return 130; + case L'â': return 131; + case L'ä': return 132; + case L'à': return 133; + case L'å': return 134; + case L'ç': return 135; + case L'ê': return 136; + case L'ë': return 137; + case L'è': return 138; + case L'ï': return 139; + case L'î': return 140; + case L'ì': return 141; + case L'Ä': return 142; + case L'Å': return 143; + case L'É': return 144; + case L'æ': return 145; + case L'Æ': return 146; + case L'ô': return 147; + case L'ö': return 148; + case L'ò': return 149; + case L'û': return 150; + case L'ù': return 151; + case L'ÿ': return 152; + case L'Ö': return 153; + case L'Ü': return 154; + case L'¢': return 155; + case L'£': return 156; + case L'¥': return 157; + case L'₧': return 158; + case L'ƒ': return 159; + case L'á': return 160; + case L'í': return 161; + case L'ó': return 162; + case L'ú': return 163; + case L'ñ': return 164; + case L'Ñ': return 165; + case L'ª': return 166; + case L'º': return 167; + case L'¿': return 168; + case L'⌐': return 169; + case L'¬': return 170; + case L'½': return 171; + case L'¼': return 172; + case L'¡': return 173; + case L'«': return 174; + case L'»': return 175; + case L'░': return 176; + case L'▒': return 177; + case L'▓': return 178; + case L'│': return 179; + case L'┤': return 180; + case L'╡': return 181; + case L'╢': return 182; + case L'╖': return 183; + case L'╕': return 184; + case L'╣': return 185; + case L'║': return 186; + case L'╗': return 187; + case L'╝': return 188; + case L'╜': return 189; + case L'╛': return 190; + case L'┐': return 191; + case L'└': return 192; + case L'┴': return 193; + case L'┬': return 194; + case L'├': return 195; + case L'─': return 196; + case L'┼': return 197; + case L'╞': return 198; + case L'╟': return 199; + case L'╚': return 200; + case L'╔': return 201; + case L'╩': return 202; + case L'╦': return 203; + case L'╠': return 204; + case L'═': return 205; + case L'╬': return 206; + case L'╧': return 207; + case L'╨': return 208; + case L'╤': return 209; + case L'╥': return 210; + case L'╙': return 211; + case L'╘': return 212; + case L'╒': return 213; + case L'╓': return 214; + case L'╫': return 215; + case L'╪': return 216; + case L'┘': return 217; + case L'┌': return 218; + case L'█': return 219; + case L'▄': return 220; + case L'▌': return 221; + case L'▐': return 222; + case L'▀': return 223; + case L'α': return 224; + case L'ß': return 225; + case L'Γ': return 226; + case L'π': return 227; + case L'Σ': return 228; + case L'σ': return 229; + case L'µ': return 230; + case L'τ': return 231; + case L'Φ': return 232; + case L'Θ': return 233; + case L'Ω': return 234; + case L'δ': return 235; + case L'∞': return 236; + case L'φ': return 237; + case L'ε': return 238; + case L'∩': return 239; + case L'≡': return 240; + case L'±': return 241; + case L'≥': return 242; + case L'≤': return 243; + case L'⌠': return 244; + case L'⌡': return 245; + case L'÷': return 246; + case L'≈': return 247; + case L'°': return 248; + case L'∙': return 249; + case L'·': return 250; + case L'√': return 251; + case L'ⁿ': return 252; + case L'²': return 253; + case L'■': return 254; + } + return 4; +} + +void +term_write_char( + uint32_t val, + uint16_t x, + uint16_t y, + uint32_t fg, + uint32_t bg, + uint8_t flags + ) { + if (val > 128) val = ununicode(val); + if (fg > 256) { + fg = best_match(fg); + } + if (bg > 256) { + bg = best_match(bg); + } + if (fg > 16) { + fg = vga_colors[fg]; + } + if (bg > 16) { + bg = vga_colors[bg]; + } + if (fg == 16) fg = 0; + if (bg == 16) bg = 0; + placech(val, x, y, (vga_to_ansi[fg] & 0xF) | (vga_to_ansi[bg] << 4)); +} + +static void cell_set(uint16_t x, uint16_t y, uint32_t c, uint32_t fg, uint32_t bg, uint8_t flags) { + if (x >= term_width || y >= term_height) return; + term_cell_t * cell = (term_cell_t *)((uintptr_t)term_buffer + (y * term_width + x) * sizeof(term_cell_t)); + cell->c = c; + cell->fg = fg; + cell->bg = bg; + cell->flags = flags; +} + +static void cell_redraw(uint16_t x, uint16_t y) { + if (x >= term_width || y >= term_height) return; + term_cell_t * cell = (term_cell_t *)((uintptr_t)term_buffer + (y * term_width + x) * sizeof(term_cell_t)); + if (((uint32_t *)cell)[0] == 0x00000000) { + term_write_char(' ', x * char_width, y * char_height, TERM_DEFAULT_FG, TERM_DEFAULT_BG, TERM_DEFAULT_FLAGS); + } else { + term_write_char(cell->c, x * char_width, y * char_height, cell->fg, cell->bg, cell->flags); + } +} + +static void cell_redraw_inverted(uint16_t x, uint16_t y) { + if (x >= term_width || y >= term_height) return; + term_cell_t * cell = (term_cell_t *)((uintptr_t)term_buffer + (y * term_width + x) * sizeof(term_cell_t)); + if (((uint32_t *)cell)[0] == 0x00000000) { + term_write_char(' ', x * char_width, y * char_height, TERM_DEFAULT_BG, TERM_DEFAULT_FG, TERM_DEFAULT_FLAGS | ANSI_SPECBG); + } else { + term_write_char(cell->c, x * char_width, y * char_height, cell->bg, cell->fg, cell->flags | ANSI_SPECBG); + } +} + +static void cell_redraw_box(uint16_t x, uint16_t y) { + if (x >= term_width || y >= term_height) return; + term_cell_t * cell = (term_cell_t *)((uintptr_t)term_buffer + (y * term_width + x) * sizeof(term_cell_t)); + if (((uint32_t *)cell)[0] == 0x00000000) { + term_write_char(' ', x * char_width, y * char_height, TERM_DEFAULT_FG, TERM_DEFAULT_BG, TERM_DEFAULT_FLAGS | ANSI_BORDER); + } else { + term_write_char(cell->c, x * char_width, y * char_height, cell->fg, cell->bg, cell->flags | ANSI_BORDER); + } +} + +void render_cursor() { + cell_redraw_inverted(csr_x, csr_y); +} + +void draw_cursor() { + if (!cursor_on) return; + mouse_ticks = get_ticks(); + render_cursor(); +} + +void term_redraw_all() { + for (uint16_t y = 0; y < term_height; ++y) { + for (uint16_t x = 0; x < term_width; ++x) { + cell_redraw(x,y); + } + } +} + +void term_scroll(int how_much) { + if (how_much >= term_height || -how_much >= term_height) { + term_clear(); + return; + } + if (how_much == 0) { + return; + } + if (how_much > 0) { + /* Shift terminal cells one row up */ + memmove(term_buffer, (void *)((uintptr_t)term_buffer + sizeof(term_cell_t) * term_width), sizeof(term_cell_t) * term_width * (term_height - how_much)); + /* Reset the "new" row to clean cells */ + memset((void *)((uintptr_t)term_buffer + sizeof(term_cell_t) * term_width * (term_height - how_much)), 0x0, sizeof(term_cell_t) * term_width * how_much); + for (int i = 0; i < how_much; ++i) { + for (uint16_t x = 0; x < term_width; ++x) { + cell_set(x,term_height - how_much,' ', current_fg, current_bg, ansi_state->flags); + } + } + term_redraw_all(); + } else { + how_much = -how_much; + /* Shift terminal cells one row up */ + memmove((void *)((uintptr_t)term_buffer + sizeof(term_cell_t) * term_width), term_buffer, sizeof(term_cell_t) * term_width * (term_height - how_much)); + /* Reset the "new" row to clean cells */ + memset(term_buffer, 0x0, sizeof(term_cell_t) * term_width * how_much); + term_redraw_all(); + } +} + +int is_wide(uint32_t codepoint) { + if (codepoint < 256) return 0; + return wcwidth(codepoint) == 2; +} + +void term_write(char c) { + static uint32_t codepoint = 0; + static uint32_t unicode_state = 0; + + cell_redraw(csr_x, csr_y); + if (!decode(&unicode_state, &codepoint, (uint8_t)c)) { + if (c == '\r') { + csr_x = 0; + return; + } + if (csr_x == term_width) { + csr_x = 0; + ++csr_y; + } + if (csr_y == term_height) { + term_scroll(1); + csr_y = term_height - 1; + } + if (c == '\n') { + if (csr_x == 0 && _hold_out) { + _hold_out = 0; + return; + } + ++csr_y; + if (csr_y == term_height) { + term_scroll(1); + csr_y = term_height - 1; + } + draw_cursor(); + } else if (c == '\007') { + /* bell */ +#if USE_BELL + for (int i = 0; i < term_height; ++i) { + for (int j = 0; j < term_width; ++j) { + cell_redraw_inverted(j, i); + } + } + syscall_nanosleep(0,10); + term_redraw_all(); +#endif + } else if (c == '\b') { + if (csr_x > 0) { + --csr_x; + } + cell_redraw(csr_x, csr_y); + draw_cursor(); + } else if (c == '\t') { + csr_x += (8 - csr_x % 8); + draw_cursor(); + } else { + int wide = is_wide(codepoint); + uint8_t flags = ansi_state->flags; + if (wide && csr_x == term_width - 1) { + csr_x = 0; + ++csr_y; + } + if (wide) { + flags = flags | ANSI_WIDE; + } + cell_set(csr_x,csr_y, codepoint, current_fg, current_bg, flags); + cell_redraw(csr_x,csr_y); + csr_x++; + if (wide && csr_x != term_width) { + cell_set(csr_x, csr_y, 0xFFFF, current_fg, current_bg, ansi_state->flags); + cell_redraw(csr_x,csr_y); + cell_redraw(csr_x-1,csr_y); + csr_x++; + } + } + } else if (unicode_state == UTF8_REJECT) { + unicode_state = 0; + } + draw_cursor(); +} + +void term_set_csr(int x, int y) { + cell_redraw(csr_x,csr_y); + csr_x = x; + csr_y = y; + draw_cursor(); +} + +int term_get_csr_x() { + return csr_x; +} + +int term_get_csr_y() { + return csr_y; +} + +void term_set_csr_show(int on) { + cursor_on = on; +} + +void term_set_colors(uint32_t fg, uint32_t bg) { + current_fg = fg; + current_bg = bg; +} + +void term_redraw_cursor() { + if (term_buffer) { + draw_cursor(); + } +} + +void flip_cursor() { + static uint8_t cursor_flipped = 0; + if (cursor_flipped) { + cell_redraw(csr_x, csr_y); + } else { + render_cursor(); + } + cursor_flipped = 1 - cursor_flipped; +} + +void term_set_cell(int x, int y, uint32_t c) { + cell_set(x, y, c, current_fg, current_bg, ansi_state->flags); + cell_redraw(x, y); +} + +void term_redraw_cell(int x, int y) { + if (x < 0 || y < 0 || x >= term_width || y >= term_height) return; + cell_redraw(x,y); +} + +void term_clear(int i) { + if (i == 2) { + /* Oh dear */ + csr_x = 0; + csr_y = 0; + memset((void *)term_buffer, 0x00, term_width * term_height * sizeof(term_cell_t)); + term_redraw_all(); + } else if (i == 0) { + for (int x = csr_x; x < term_width; ++x) { + term_set_cell(x, csr_y, ' '); + } + for (int y = csr_y + 1; y < term_height; ++y) { + for (int x = 0; x < term_width; ++x) { + term_set_cell(x, y, ' '); + } + } + } else if (i == 1) { + for (int y = 0; y < csr_y; ++y) { + for (int x = 0; x < term_width; ++x) { + term_set_cell(x, y, ' '); + } + } + for (int x = 0; x < csr_x; ++x) { + term_set_cell(x, csr_y, ' '); + } + } +} + +#define INPUT_SIZE 1024 +char input_buffer[INPUT_SIZE]; +int input_collected = 0; + +void clear_input() { + memset(input_buffer, 0x0, INPUT_SIZE); + input_collected = 0; +} + +uint32_t child_pid = 0; + +void handle_input(char c) { + write(fd_master, &c, 1); +} + +void handle_input_s(char * c) { + write(fd_master, c, strlen(c)); +} + +void key_event(int ret, key_event_t * event) { + if (ret) { + if (event->modifiers & KEY_MOD_LEFT_ALT || event->modifiers & KEY_MOD_RIGHT_ALT) { + handle_input('\033'); + } + if ((event->modifiers & KEY_MOD_LEFT_SHIFT || event->modifiers & KEY_MOD_RIGHT_SHIFT) && + event->key == '\t') { + handle_input_s("\033[Z"); + return; + } + handle_input(event->key); + } else { + if (event->action == KEY_ACTION_UP) return; + switch (event->keycode) { + case KEY_F1: + handle_input_s("\033OP"); + break; + case KEY_F2: + handle_input_s("\033OQ"); + break; + case KEY_F3: + handle_input_s("\033OR"); + break; + case KEY_F4: + handle_input_s("\033OS"); + break; + case KEY_F5: + handle_input_s("\033[15~"); + break; + case KEY_F6: + handle_input_s("\033[17~"); + break; + case KEY_F7: + handle_input_s("\033[18~"); + break; + case KEY_F8: + handle_input_s("\033[19~"); + break; + case KEY_F9: + handle_input_s("\033[20~"); + break; + case KEY_F10: + handle_input_s("\033[21~"); + break; + case KEY_F11: + handle_input_s("\033[23~"); + break; + case KEY_F12: + /* XXX This is for testing only */ + handle_input_s("テスト"); + //handle_input_s("\033[24~"); + break; + case KEY_ARROW_UP: + handle_input_s("\033[A"); + break; + case KEY_ARROW_DOWN: + handle_input_s("\033[B"); + break; + case KEY_ARROW_RIGHT: + handle_input_s("\033[C"); + break; + case KEY_ARROW_LEFT: + handle_input_s("\033[D"); + break; + case KEY_PAGE_UP: + handle_input_s("\033[5~"); + break; + case KEY_PAGE_DOWN: + handle_input_s("\033[6~"); + break; + case KEY_HOME: + handle_input_s("\033OH"); + break; + case KEY_END: + handle_input_s("\033OF"); + break; + case KEY_DEL: + handle_input_s("\033[3~"); + break; + } + } +} + +void usage(char * argv[]) { + printf( + "VGA Terminal Emulator\n" + "\n" + "usage: %s [-b] [-F] [-h]\n" + "\n" + " -h --help \033[3mShow this help message.\033[0m\n" + "\n", + argv[0]); +} + +int unsupported_int(void) { return 0; } +void unsupported(int x, int y, char * data) { } + +term_callbacks_t term_callbacks = { + term_write, + term_set_colors, + term_set_csr, + term_get_csr_x, + term_get_csr_y, + term_set_cell, + term_clear, + term_scroll, + term_redraw_cursor, + input_buffer_stuff, + set_term_font_size, + set_title, + unsupported, + unsupported_int, + unsupported_int, + term_set_csr_show, +}; + +void reinit(int send_sig) { + if (term_buffer) { + /* Do nothing */ + } else { + term_buffer = malloc(sizeof(term_cell_t) * term_width * term_height); + memset(term_buffer, 0x0, sizeof(term_cell_t) * term_width * term_height); + } + + ansi_state = ansi_init(ansi_state, term_width, term_height, &term_callbacks); + term_redraw_all(); +} + + +void maybe_flip_cursor(void) { + uint64_t ticks = get_ticks(); + if (ticks > mouse_ticks + 600000LL) { + mouse_ticks = ticks; + flip_cursor(); + } +} + + +void check_for_exit(void) { + if (exit_application) return; + + int pid = waitpid(-1, NULL, WNOHANG); + + if (pid != child_pid) return; + + /* Clean up */ + exit_application = 1; + /* Exit */ + char exit_message[] = "[Process terminated]\n"; + write(fd_slave, exit_message, sizeof(exit_message)); +} + + +int main(int argc, char ** argv) { + + _login_shell = 0; + +#if 0 + static struct option long_opts[] = { + {"login", no_argument, 0, 'l'}, + {"help", no_argument, 0, 'h'}, + {0,0,0,0} + }; + + /* Read some arguments */ + int index, c; + while ((c = getopt_long(argc, argv, "hl", long_opts, &index)) != -1) { + if (!c) { + if (long_opts[index].flag == 0) { + c = long_opts[index].val; + } + } + switch (c) { + case 'l': + _login_shell = 1; + break; + case 'h': + usage(argv); + return 0; + break; + case '?': + break; + default: + break; + } + } + + putenv("TERM=toaru"); +#endif + +#if 1 + char * _env = malloc(strlen("TERM=toaru")); + sprintf(_env, "TERM=toaru"); + size_t env_c = 0; + for (char ** env = environ; *env; env++, env_c++); + char ** env_new = malloc(sizeof(char *) * (env_c + 2)); + int set_env = 0; + for (size_t i = 0; i < env_c; ++i) { + if (strstr(environ[i], "TERM=") == environ[i]) { + env_new[i] = _env; + set_env = 1; + } else { + env_new[i] = environ[i]; + } + } + if (!set_env) { + env_new[env_c] = _env; + env_c++; + } + env_new[env_c] = NULL; + environ = env_new; +#endif + + syscall_openpty(&fd_master, &fd_slave, NULL, NULL, NULL); + + terminal = fdopen(fd_slave, "w"); + + struct winsize w; + w.ws_row = term_height; + w.ws_col = term_width; + w.ws_xpixel = 0; + w.ws_ypixel = 0; + ioctl(fd_master, TIOCSWINSZ, &w); + + reinit(0); + + fflush(stdin); + + system("cursor-off"); /* Might GPF */ + + int pid = getpid(); + uint32_t f = fork(); + + if (getpid() != pid) { + dup2(fd_slave, 0); + dup2(fd_slave, 1); + dup2(fd_slave, 2); + +#if 0 + if (argv[optind] != NULL) { + char * tokens[] = {argv[optind], NULL}; + int i = execvp(tokens[0], tokens); + fprintf(stderr, "Failed to launch requested startup application.\n"); + } else { +#endif + if (_login_shell) { + char * tokens[] = {"/bin/login",NULL}; + int i = execvp(tokens[0], tokens); + } else { + char * shell = getenv("SHELL"); + if (!shell) shell = "/bin/sh"; /* fallback */ + char * tokens[] = {shell,NULL}; + int i = execvp(tokens[0], tokens); + } +#if 0 + } +#endif + + exit_application = 1; + + return 1; + } else { + + child_pid = f; + + int kfd = open("/dev/kbd", O_RDONLY); + key_event_t event; + char c; + + key_event_state_t kbd_state = {0}; + + /* Prune any keyboard input we got before the terminal started. */ + struct stat s; + fstat(kfd, &s); + for (int i = 0; i < s.st_size; i++) { + char tmp[1]; + read(kfd, tmp, 1); + } + + int fds[2] = {fd_master, kfd}; + + unsigned char buf[1024]; + while (!exit_application) { + + int index = syscall_fswait2(2,fds,200); + + check_for_exit(); + + if (index == 0) { + maybe_flip_cursor(); + int r = read(fd_master, buf, 1024); + for (uint32_t i = 0; i < r; ++i) { + ansi_put(ansi_state, buf[i]); + } + } else if (index == 1) { + maybe_flip_cursor(); + int r = read(kfd, &c, 1); + if (r > 0) { + int ret = kbd_scancode(&kbd_state, c, &event); + key_event(ret, &event); + } + } else if (index == 2) { + maybe_flip_cursor(); + } + } + + } + + return 0; +} diff --git a/apps/vga-palette.h b/apps/vga-palette.h new file mode 100644 index 00000000..ed4775f4 --- /dev/null +++ b/apps/vga-palette.h @@ -0,0 +1,259 @@ +#define PALETTE_COLORS 256 +uint32_t vga_colors[PALETTE_COLORS] = { + 0x0, + 0x1, + 0x2, + 0x3, + 0x4, + 0x5, + 0x6, + 0x7, + 0x8, + 0x9, + 0xa, + 0xb, + 0xc, + 0xd, + 0xe, + 0xf, + 0x0, /* #000000 -> #000000 */ + 0x4, /* #00005f -> #0000aa */ + 0x4, /* #000087 -> #0000aa */ + 0x4, /* #0000af -> #0000aa */ + 0x4, /* #0000d7 -> #0000aa */ + 0xc, /* #0000ff -> #5555ff */ + 0x2, /* #005f00 -> #00aa00 */ + 0x8, /* #005f5f -> #555555 */ + 0x6, /* #005f87 -> #00aaaa */ + 0x6, /* #005faf -> #00aaaa */ + 0xc, /* #005fd7 -> #5555ff */ + 0xc, /* #005fff -> #5555ff */ + 0x2, /* #008700 -> #00aa00 */ + 0xa, /* #00875f -> #55aa55 */ + 0x6, /* #008787 -> #00aaaa */ + 0x6, /* #0087af -> #00aaaa */ + 0x6, /* #0087d7 -> #00aaaa */ + 0xc, /* #0087ff -> #5555ff */ + 0x2, /* #00af00 -> #00aa00 */ + 0xa, /* #00af5f -> #55aa55 */ + 0x6, /* #00af87 -> #00aaaa */ + 0x6, /* #00afaf -> #00aaaa */ + 0x6, /* #00afd7 -> #00aaaa */ + 0xe, /* #00afff -> #55ffff */ + 0x2, /* #00d700 -> #00aa00 */ + 0xa, /* #00d75f -> #55aa55 */ + 0x6, /* #00d787 -> #00aaaa */ + 0x6, /* #00d7af -> #00aaaa */ + 0x6, /* #00d7d7 -> #00aaaa */ + 0xe, /* #00d7ff -> #55ffff */ + 0x2, /* #00ff00 -> #00aa00 */ + 0xa, /* #00ff5f -> #55aa55 */ + 0x6, /* #00ff87 -> #00aaaa */ + 0x6, /* #00ffaf -> #00aaaa */ + 0xe, /* #00ffd7 -> #55ffff */ + 0xe, /* #00ffff -> #55ffff */ + 0x1, /* #5f0000 -> #aa0000 */ + 0x8, /* #5f005f -> #555555 */ + 0x5, /* #5f0087 -> #aa00aa */ + 0x5, /* #5f00af -> #aa00aa */ + 0x5, /* #5f00d7 -> #aa00aa */ + 0xc, /* #5f00ff -> #5555ff */ + 0x3, /* #5f5f00 -> #aa5500 */ + 0x8, /* #5f5f5f -> #555555 */ + 0x8, /* #5f5f87 -> #555555 */ + 0x7, /* #5f5faf -> #aaaaaa */ + 0xc, /* #5f5fd7 -> #5555ff */ + 0xc, /* #5f5fff -> #5555ff */ + 0x2, /* #5f8700 -> #00aa00 */ + 0xa, /* #5f875f -> #55aa55 */ + 0xa, /* #5f8787 -> #55aa55 */ + 0x7, /* #5f87af -> #aaaaaa */ + 0xc, /* #5f87d7 -> #5555ff */ + 0xc, /* #5f87ff -> #5555ff */ + 0x2, /* #5faf00 -> #00aa00 */ + 0xa, /* #5faf5f -> #55aa55 */ + 0xa, /* #5faf87 -> #55aa55 */ + 0x7, /* #5fafaf -> #aaaaaa */ + 0x7, /* #5fafd7 -> #aaaaaa */ + 0xe, /* #5fafff -> #55ffff */ + 0x2, /* #5fd700 -> #00aa00 */ + 0xa, /* #5fd75f -> #55aa55 */ + 0xa, /* #5fd787 -> #55aa55 */ + 0x7, /* #5fd7af -> #aaaaaa */ + 0xe, /* #5fd7d7 -> #55ffff */ + 0xe, /* #5fd7ff -> #55ffff */ + 0x2, /* #5fff00 -> #00aa00 */ + 0xb, /* #5fff5f -> #ffff55 */ + 0xb, /* #5fff87 -> #ffff55 */ + 0x7, /* #5fffaf -> #aaaaaa */ + 0xe, /* #5fffd7 -> #55ffff */ + 0xe, /* #5fffff -> #55ffff */ + 0x1, /* #870000 -> #aa0000 */ + 0x8, /* #87005f -> #555555 */ + 0x5, /* #870087 -> #aa00aa */ + 0x5, /* #8700af -> #aa00aa */ + 0x5, /* #8700d7 -> #aa00aa */ + 0xc, /* #8700ff -> #5555ff */ + 0x3, /* #875f00 -> #aa5500 */ + 0x8, /* #875f5f -> #555555 */ + 0x8, /* #875f87 -> #555555 */ + 0x7, /* #875faf -> #aaaaaa */ + 0xc, /* #875fd7 -> #5555ff */ + 0xc, /* #875fff -> #5555ff */ + 0x3, /* #878700 -> #aa5500 */ + 0xa, /* #87875f -> #55aa55 */ + 0x7, /* #878787 -> #aaaaaa */ + 0x7, /* #8787af -> #aaaaaa */ + 0x7, /* #8787d7 -> #aaaaaa */ + 0xc, /* #8787ff -> #5555ff */ + 0x2, /* #87af00 -> #00aa00 */ + 0xa, /* #87af5f -> #55aa55 */ + 0x7, /* #87af87 -> #aaaaaa */ + 0x7, /* #87afaf -> #aaaaaa */ + 0x7, /* #87afd7 -> #aaaaaa */ + 0xe, /* #87afff -> #55ffff */ + 0x2, /* #87d700 -> #00aa00 */ + 0xa, /* #87d75f -> #55aa55 */ + 0x7, /* #87d787 -> #aaaaaa */ + 0x7, /* #87d7af -> #aaaaaa */ + 0xe, /* #87d7d7 -> #55ffff */ + 0xe, /* #87d7ff -> #55ffff */ + 0x2, /* #87ff00 -> #00aa00 */ + 0xb, /* #87ff5f -> #ffff55 */ + 0xb, /* #87ff87 -> #ffff55 */ + 0x7, /* #87ffaf -> #aaaaaa */ + 0xe, /* #87ffd7 -> #55ffff */ + 0xe, /* #87ffff -> #55ffff */ + 0x1, /* #af0000 -> #aa0000 */ + 0x5, /* #af005f -> #aa00aa */ + 0x5, /* #af0087 -> #aa00aa */ + 0x5, /* #af00af -> #aa00aa */ + 0x5, /* #af00d7 -> #aa00aa */ + 0xd, /* #af00ff -> #ff55ff */ + 0x3, /* #af5f00 -> #aa5500 */ + 0x9, /* #af5f5f -> #ff5555 */ + 0x9, /* #af5f87 -> #ff5555 */ + 0x7, /* #af5faf -> #aaaaaa */ + 0xd, /* #af5fd7 -> #ff55ff */ + 0xd, /* #af5fff -> #ff55ff */ + 0x3, /* #af8700 -> #aa5500 */ + 0xa, /* #af875f -> #55aa55 */ + 0x7, /* #af8787 -> #aaaaaa */ + 0x7, /* #af87af -> #aaaaaa */ + 0x7, /* #af87d7 -> #aaaaaa */ + 0xd, /* #af87ff -> #ff55ff */ + 0x2, /* #afaf00 -> #00aa00 */ + 0xa, /* #afaf5f -> #55aa55 */ + 0x7, /* #afaf87 -> #aaaaaa */ + 0x7, /* #afafaf -> #aaaaaa */ + 0x7, /* #afafd7 -> #aaaaaa */ + 0xf, /* #afafff -> #ffffff */ + 0x2, /* #afd700 -> #00aa00 */ + 0xb, /* #afd75f -> #ffff55 */ + 0x7, /* #afd787 -> #aaaaaa */ + 0x7, /* #afd7af -> #aaaaaa */ + 0x7, /* #afd7d7 -> #aaaaaa */ + 0xf, /* #afd7ff -> #ffffff */ + 0x2, /* #afff00 -> #00aa00 */ + 0xb, /* #afff5f -> #ffff55 */ + 0xb, /* #afff87 -> #ffff55 */ + 0x7, /* #afffaf -> #aaaaaa */ + 0xf, /* #afffd7 -> #ffffff */ + 0xf, /* #afffff -> #ffffff */ + 0x1, /* #d70000 -> #aa0000 */ + 0x9, /* #d7005f -> #ff5555 */ + 0x5, /* #d70087 -> #aa00aa */ + 0x5, /* #d700af -> #aa00aa */ + 0x5, /* #d700d7 -> #aa00aa */ + 0xd, /* #d700ff -> #ff55ff */ + 0x3, /* #d75f00 -> #aa5500 */ + 0x9, /* #d75f5f -> #ff5555 */ + 0x9, /* #d75f87 -> #ff5555 */ + 0x7, /* #d75faf -> #aaaaaa */ + 0xd, /* #d75fd7 -> #ff55ff */ + 0xd, /* #d75fff -> #ff55ff */ + 0x3, /* #d78700 -> #aa5500 */ + 0x9, /* #d7875f -> #ff5555 */ + 0x7, /* #d78787 -> #aaaaaa */ + 0x7, /* #d787af -> #aaaaaa */ + 0x7, /* #d787d7 -> #aaaaaa */ + 0xd, /* #d787ff -> #ff55ff */ + 0x2, /* #d7af00 -> #00aa00 */ + 0xa, /* #d7af5f -> #55aa55 */ + 0x7, /* #d7af87 -> #aaaaaa */ + 0x7, /* #d7afaf -> #aaaaaa */ + 0x7, /* #d7afd7 -> #aaaaaa */ + 0xf, /* #d7afff -> #ffffff */ + 0x2, /* #d7d700 -> #00aa00 */ + 0xb, /* #d7d75f -> #ffff55 */ + 0x7, /* #d7d787 -> #aaaaaa */ + 0x7, /* #d7d7af -> #aaaaaa */ + 0xf, /* #d7d7d7 -> #ffffff */ + 0xf, /* #d7d7ff -> #ffffff */ + 0xb, /* #d7ff00 -> #ffff55 */ + 0xb, /* #d7ff5f -> #ffff55 */ + 0xb, /* #d7ff87 -> #ffff55 */ + 0x7, /* #d7ffaf -> #aaaaaa */ + 0xf, /* #d7ffd7 -> #ffffff */ + 0xf, /* #d7ffff -> #ffffff */ + 0x1, /* #ff0000 -> #aa0000 */ + 0x9, /* #ff005f -> #ff5555 */ + 0x5, /* #ff0087 -> #aa00aa */ + 0x5, /* #ff00af -> #aa00aa */ + 0x5, /* #ff00d7 -> #aa00aa */ + 0xd, /* #ff00ff -> #ff55ff */ + 0x3, /* #ff5f00 -> #aa5500 */ + 0x9, /* #ff5f5f -> #ff5555 */ + 0x9, /* #ff5f87 -> #ff5555 */ + 0x7, /* #ff5faf -> #aaaaaa */ + 0xd, /* #ff5fd7 -> #ff55ff */ + 0xd, /* #ff5fff -> #ff55ff */ + 0x3, /* #ff8700 -> #aa5500 */ + 0x9, /* #ff875f -> #ff5555 */ + 0x9, /* #ff8787 -> #ff5555 */ + 0x7, /* #ff87af -> #aaaaaa */ + 0xd, /* #ff87d7 -> #ff55ff */ + 0xd, /* #ff87ff -> #ff55ff */ + 0x2, /* #ffaf00 -> #00aa00 */ + 0xb, /* #ffaf5f -> #ffff55 */ + 0x7, /* #ffaf87 -> #aaaaaa */ + 0x7, /* #ffafaf -> #aaaaaa */ + 0x7, /* #ffafd7 -> #aaaaaa */ + 0xf, /* #ffafff -> #ffffff */ + 0x2, /* #ffd700 -> #00aa00 */ + 0xb, /* #ffd75f -> #ffff55 */ + 0xb, /* #ffd787 -> #ffff55 */ + 0x7, /* #ffd7af -> #aaaaaa */ + 0xf, /* #ffd7d7 -> #ffffff */ + 0xf, /* #ffd7ff -> #ffffff */ + 0xb, /* #ffff00 -> #ffff55 */ + 0xb, /* #ffff5f -> #ffff55 */ + 0xb, /* #ffff87 -> #ffff55 */ + 0xf, /* #ffffaf -> #ffffff */ + 0xf, /* #ffffd7 -> #ffffff */ + 0xf, /* #ffffff -> #ffffff */ + 0x0, /* #080808 -> #000000 */ + 0x0, /* #121212 -> #000000 */ + 0x0, /* #1c1c1c -> #000000 */ + 0x0, /* #262626 -> #000000 */ + 0x8, /* #303030 -> #555555 */ + 0x8, /* #3a3a3a -> #555555 */ + 0x8, /* #444444 -> #555555 */ + 0x8, /* #4e4e4e -> #555555 */ + 0x8, /* #585858 -> #555555 */ + 0x8, /* #626262 -> #555555 */ + 0x8, /* #6c6c6c -> #555555 */ + 0x8, /* #767676 -> #555555 */ + 0x7, /* #808080 -> #aaaaaa */ + 0x7, /* #8a8a8a -> #aaaaaa */ + 0x7, /* #949494 -> #aaaaaa */ + 0x7, /* #9e9e9e -> #aaaaaa */ + 0x7, /* #a8a8a8 -> #aaaaaa */ + 0x7, /* #b2b2b2 -> #aaaaaa */ + 0x7, /* #bcbcbc -> #aaaaaa */ + 0x7, /* #c6c6c6 -> #aaaaaa */ + 0x7, /* #d0d0d0 -> #aaaaaa */ + 0xf, /* #dadada -> #ffffff */ + 0xf, /* #e4e4e4 -> #ffffff */ + 0xf, /* #eeeeee -> #ffffff */ +}; diff --git a/cdrom/boot/grub/menus.cfg b/cdrom/boot/grub/menus.cfg index d1930f44..d2322d52 100644 --- a/cdrom/boot/grub/menus.cfg +++ b/cdrom/boot/grub/menus.cfg @@ -6,14 +6,22 @@ if [ ! "${seen_menu}" = "yes" ]; then export seen_menu fi -submenu 'RUN' { - multiboot /kernel vid=${t_driver},${t_resolution} ${t_root} start=hello +submenu 'Normal Graphical Boot' { + multiboot /kernel vid=${t_driver},${t_resolution} ${t_root} start=session load_modules load_ramdisk set_vidmode boot } +submenu 'VGA Text-Mode Terminal (Debug)' { + multiboot /kernel ${t_root} start=--vga + load_modules + load_ramdisk + set gfxpayload=text + boot +} + submenu '> Advanced graphics configuration options...' { set_theme menuentry '800x600' { diff --git a/lib/yutani.c b/lib/yutani.c index 0555b2cc..c3c86ac6 100644 --- a/lib/yutani.c +++ b/lib/yutani.c @@ -567,7 +567,6 @@ yutani_t * yutani_init(void) { FILE * c = pex_connect(server_name); if (!c) { - fprintf(stderr, "Pex connection failed?\n"); return NULL; /* Connection failed. */ }