diff options
author | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-19 09:23:48 +0200 |
---|---|---|
committer | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-19 09:23:48 +0200 |
commit | 7b466345af0d3a7dc5622617ce443a90c64e34a4 (patch) | |
tree | f276b6bf391ccfe8ec3a2cb62a7f70964249621f /src/kernel | |
parent | ac10c1a29c44b0cb29960cd0f792c7361bc430ce (diff) | |
download | TCE-7b466345af0d3a7dc5622617ce443a90c64e34a4.tar.gz TCE-7b466345af0d3a7dc5622617ce443a90c64e34a4.zip |
Added ANSI support, minimal readline-like library.
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/config.h | 4 | ||||
-rw-r--r-- | src/kernel/core/kmain.cpp | 5 | ||||
-rw-r--r-- | src/kernel/dev/display.h | 2 | ||||
-rw-r--r-- | src/kernel/dev/vgatxt.cpp | 22 | ||||
-rw-r--r-- | src/kernel/task/syscall.cpp | 4 | ||||
-rw-r--r-- | src/kernel/task/task.cpp | 15 | ||||
-rw-r--r-- | src/kernel/task/task.h | 5 | ||||
-rw-r--r-- | src/kernel/ui/vt.cpp | 211 | ||||
-rw-r--r-- | src/kernel/ui/vt.h | 5 | ||||
-rw-r--r-- | src/kernel/vfs/node.cpp | 1 |
10 files changed, 228 insertions, 46 deletions
diff --git a/src/kernel/config.h b/src/kernel/config.h index 21035ba..5a6c629 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -2,7 +2,7 @@ #define DEF_CONFIG_H #define K_OS_NAME "T/CE" -#define K_OS_VER "0.1.1" -#define K_OS_CODENAME "executify" +#define K_OS_VER "0.1.2" +#define K_OS_CODENAME "Make Your Terminal ANSI" #endif diff --git a/src/kernel/core/kmain.cpp b/src/kernel/core/kmain.cpp index 0aa047a..05d7966 100644 --- a/src/kernel/core/kmain.cpp +++ b/src/kernel/core/kmain.cpp @@ -61,6 +61,10 @@ extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) { ke_vt->outputTo(text_display); home_vt = new vt(dot_ui, 80, 25); dot_ui->add_child("home", home_vt); + dot_ui->add_child("vt1", new vt(dot_ui, 80, 25)); + dot_ui->add_child("vt2", new vt(dot_ui, 80, 25)); + dot_ui->add_child("vt3", new vt(dot_ui, 80, 25)); + dot_ui->add_child("vt4", new vt(dot_ui, 80, 25)); // Say hello ke_vt->fgcolor = TC_LIGHTGRAY; @@ -105,6 +109,7 @@ extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) { if (pr == 0) { *ke_vt << "Error loading\n"; } else { + pr->fd.set(0, ke_vt); *ke_vt << "OK, pid=" << (int)pr->pid << "\n"; } } else if (initrd_check((uint8_t*)mods[i].mod_start) == 0) { diff --git a/src/kernel/dev/display.h b/src/kernel/dev/display.h index 6960b7d..ec67e7e 100644 --- a/src/kernel/dev/display.h +++ b/src/kernel/dev/display.h @@ -11,6 +11,8 @@ #define TC_PURPLE 5 #define TC_BROWN 6 #define TC_LIGHTGRAY 7 +#define TC_MAKE_LIGHT 8 +#define TC_MAKE_DARK (~8) #define TC_WHITE 15 class vt; diff --git a/src/kernel/dev/vgatxt.cpp b/src/kernel/dev/vgatxt.cpp index 75071fb..eb57eb9 100644 --- a/src/kernel/dev/vgatxt.cpp +++ b/src/kernel/dev/vgatxt.cpp @@ -35,16 +35,20 @@ void vgatxt::text_put(int l, int c, int ch, uint8_t fgcolor, uint8_t bgcolor) { void vgatxt::text_scroll(int n, uint8_t fgcolor, uint8_t bgcolor) { //TODO: optimize - for (int i = 0; i < n; i++) { + if (n > 0) { + for (int i = 0; i < n; i++) { + + uint16_t blank = (((bgcolor << 4) | fgcolor) << 8) | 0x20; + int j; + for (j = 0; j < 80*24; j++) { + video_memory[j] = video_memory[j+80]; + } + for (j = 80*24; j < 80*25; j++) { + video_memory[j] = blank; + } - uint16_t blank = (((bgcolor << 4) | fgcolor) << 8) | 0x20; - int j; - for (j = 0; j < 80*24; j++) { - video_memory[j] = video_memory[j+80]; } - for (j = 80*24; j < 80*25; j++) { - video_memory[j] = blank; - } - + } else if (n < 0) { + // TODO } } diff --git a/src/kernel/task/syscall.cpp b/src/kernel/task/syscall.cpp index 4eddb61..9e7c089 100644 --- a/src/kernel/task/syscall.cpp +++ b/src/kernel/task/syscall.cpp @@ -28,7 +28,7 @@ CALL1V(idt_waitIrq, irq_wait_sc); CALL0(proc_priv, proc_priv_sc); CALL1(process_sbrk, proc_sbrk_sc); CALL1V(process_brk, proc_brk_sc); -CALL1(process_waitpid, waitpid_sc); +CALL2(process_waitpid, waitpid_sc); CALL1V(close, close_sc); @@ -43,7 +43,7 @@ static void thread_new_sc(registers* r) { } static void run_sc(registers *r) { - r->eax = process_run((char*)r->ebx, (char**)r->ecx); + r->eax = process_run((char*)r->ebx, (char**)r->ecx, (int)r->edx); } static void open_sc(registers *r) { diff --git a/src/kernel/task/task.cpp b/src/kernel/task/task.cpp index 98204d6..7eb2b36 100644 --- a/src/kernel/task/task.cpp +++ b/src/kernel/task/task.cpp @@ -295,8 +295,6 @@ process::process(process* _parent, uint32_t _uid, uint32_t _privilege) : fd(12, data = 0; dataseg = 0; - fd.add((node*)-1); // descriptor #0 must not be used - stack = 0; if (privilege >= PL_USER) { //We are running in user mode size_t stacksBottom = K_HIGHHALF_ADDR - 0x01000000; @@ -431,7 +429,7 @@ void process_brk(size_t ptr) { current_process->sbrk(ptr - current_process->data); } -int process_run(char* file, char** args) { +int process_run(char* file, char** args, FILE zero_fd) { node* bin = vfs_find(root, file); if (bin == 0) return E_NOT_FOUND; if ((bin->type & FT_FILE) == 0) return E_INVALID; @@ -467,14 +465,21 @@ int process_run(char* file, char** args) { kfree(v); for (int i = 0; arg_data[i] != 0; i++) kfree(arg_data[i]); kfree(arg_data); - return (p == 0 ? E_INVALID : p->pid); + if (p == 0) { + return E_INVALID; + } else { + p->fd.set(0, current_process->fd.at((zero_fd < 0 ? 0 : zero_fd))); + return p->pid; + } } -int process_waitpid(int pid) { +int process_waitpid(int pid, int block) { if (pid <= 0) return E_INVALID_RANGE; process *p = proc_by_pid->at(pid); if (p != 0) { + if (block == 0) return E_NOT_FINISHED; + current_thread->queue_next = p->threads_waiting; p->threads_waiting = current_thread; thread_goInactive(); diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h index 2ebb66e..8a0e94a 100644 --- a/src/kernel/task/task.h +++ b/src/kernel/task/task.h @@ -6,6 +6,7 @@ #include "idt.h" #include <lib/earray.h> +#include <tce/vfs.h> #define TS_RUNNING 0 #define TS_WAKEWAIT 2 //Waiting to be waked up by something precise (thread currently blocked) @@ -82,7 +83,7 @@ void thread_exit(); void process_exit(size_t retval); size_t process_sbrk(size_t size); void process_brk(size_t ptr); -int process_run(char* file, char** args); -int process_waitpid(int pid); +int process_run(char* file, char** args, FILE zero_fd); +int process_waitpid(int pid, int block); #endif diff --git a/src/kernel/ui/vt.cpp b/src/kernel/ui/vt.cpp index 34dfbe9..9b0bdf0 100644 --- a/src/kernel/ui/vt.cpp +++ b/src/kernel/ui/vt.cpp @@ -3,12 +3,22 @@ vt *ke_vt = 0, *home_vt = 0; +static char *kb_cmd_esc[] = { + /* 00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 20 */ 0, 0, 0, 0, 0, 0, 0, 0, "\x1b[B", 0, + /* 30 */ "\x1b[D", 0, "\x1b[C", 0, "\x1b[A", 0, 0, 0, 0, 0, + /* 40 */ 0, 0, 0, 0, 0, 0, "\x1b[B", "\x1b[A", "\x1b[D", "\x1b[C", + /* 50 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 60 */ 0, 0, 0, 0 }; + vt::vt(node* parent, int ww, int hh) : node(parent, FT_TERMINAL) { w = ww; h = hh; fgcolor = TC_LIGHTGRAY; bgcolor = TC_BLACK; output = 0; cursor_visible = true; + keyboard_echo = false; csr_l = csr_c = 0; kbd_buffer_filled = 0; @@ -34,6 +44,25 @@ void vt::put_at(int l, int c, int ch) { } } +void vt::scroll(int n) { + if (output != 0 && output->connected_vt == this) { + output->text_scroll(n, fgcolor, bgcolor); + } + if (n > 0) { + for (int j = 0; j < w * (h-n); j++) { + text[j] = text[j + w]; + } + for (int j = w * (h-n); j < w * h; j++) { + text[j].fgcolor = fgcolor; + text[j].bgcolor = bgcolor; + text[j].ch = ' '; + } + } else if (n < 0) { + //TODO + } + csr_l -= n; +} + void vt::put(int c) { if (text == 0) return; @@ -60,18 +89,7 @@ void vt::put(int c) { csr_l++; } if (csr_l == h) { - if (output != 0 && output->connected_vt == this) { - output->text_scroll(1, fgcolor, bgcolor); - } - for (int j = 0; j < w * (h-1); j++) { - text[j] = text[j + w]; - } - for (int j = w * (h-1); j < w * h; j++) { - text[j].fgcolor = fgcolor; - text[j].bgcolor = bgcolor; - text[j].ch = ' '; - } - csr_l--; + scroll(1); } if (output != 0 && output->connected_vt == this) output->text_setcsr(csr_l, csr_c, cursor_visible); } @@ -179,6 +197,11 @@ void vt::keyboardInput(keypress kp, keyboard* from) { } else if (kp.command == KB_CMD_ALT && kp.character >= 64 && kp.character <= 126 && kp.pressed) { b[n++] = 27; b[n++] = kp.character; + } else if (kb_cmd_esc[kp.command & 0x3F] != 0 && kp.pressed) { + int i; + for (i = 0; kb_cmd_esc[kp.command & 0x3F][i] != 0; i++) { + b[n++] = kb_cmd_esc[kp.command & 0x3F][i]; + } } if (n == 0) return; if (kbd_buffer_filled + n > KBD_BUFFER_SIZE) goto wake_up; @@ -200,7 +223,136 @@ int vt::write(size_t offset, size_t len, char* buffer) { // ignore offset // TODO: ANSI escape sequences // todo some day : unicode - for (unsigned i = 0; i < len; i++) put(buffer[i]); + for (unsigned i = 0; i < len; i++) { + if (buffer[i] == 27) { + i++; + if (buffer[i++] == '[') { + int n = -1, m = -1; + while (buffer[i] >= '0' && buffer[i] <= '9') { + if (n == -1) n = 0; + n *= 10; + n += buffer[i] - '0'; + i++; + } + if (buffer[i] == ';') { + i++; + while (buffer[i] >= '0' && buffer[i] <= '9') { + if (m == -1) m = 0; + m *= 10; + m += buffer[i] - '0'; + i++; + } + } + if (buffer[i] == 'A') { // move cursor up + if (n == -1) n = 1; + csr_l -= n; + } else if (buffer[i] == 'B') { // move cursor down + if (n == -1) n = 1; + csr_l += n; + } else if (buffer[i] == 'C') { // move cursor forward + if (n == -1) n = 1; + csr_c += n; + } else if (buffer[i] == 'D') { // move cursor back + if (n == -1) n = 1; + csr_c -= n; + } else if (buffer[i] == 'E') { // move cursor n lines down, to beginning of line + if (n == -1) n = 1; + csr_l += n; + csr_c = 0; + } else if (buffer[i] == 'F') { // move cursor to beginning of line, n lines up + if (n == -1) n = 1; + csr_l -= n; + csr_c = 0; + } else if (buffer[i] == 'H' || buffer[i] == 'f') { // set cursor position + if (n == -1) n = 1; + if (m == -1) m = 1; + csr_l = n - 1; + csr_c = m - 1; + } else if (buffer[i] == 'J' || buffer[i] == 'K') { // erase data / erase line + if (n == -1) n = 0; + int start = 0, end = 0; + if (n == 0) { + start = csr_c; end = w; + } else if (n == 1) { + start = 0; end = csr_c; + } else if (n == 2) { + start = 0; end = w; + } + for (int p = start; p < end; p++) put_at(csr_l, p, ' '); + if (buffer[i] == 'J') { // erase data + if (n == 0) { + start = csr_l + 1; end = h; + } else if (n == 1) { + start = 0; end = csr_l; + } else if (n == 2) { + start = 0; end = h; + } + for (int l = start; l < end; l++) { + for (int c = 0; c < w; c++) put_at(l, c, ' '); + } + } + } else if (buffer[i] == 'S') { // scroll up + if (n == -1) n = 1; + scroll(n); + } else if (buffer[i] == 'T') { // scroll down + if (n == -1) n = 1; + scroll(-n); + } else if (buffer[i] == 'm') { // select graphic rendition + if (n == -1) n = 0; + if (n == 0) { + fgcolor = 7; + bgcolor = 0; + } else if (n == 1) { + fgcolor |= TC_MAKE_LIGHT; + } else if (n == 22) { + fgcolor &= TC_MAKE_DARK; + } else if (n >= 30 && n <= 37) { + fgcolor = (fgcolor & TC_MAKE_LIGHT) | (n - 30); + } else if (n >= 40 && n <= 47) { + bgcolor = (n - 40); + } else { + // others to do. + } + } else if (buffer[i] == 'n') { // device status report + kbd_buffer[kbd_buffer_filled++] = 27; + kbd_buffer[kbd_buffer_filled++] = '['; + if (csr_l >= 100) kbd_buffer[kbd_buffer_filled++] = ((csr_l / 100) % 10) + '0'; + if (csr_l >= 10) kbd_buffer[kbd_buffer_filled++] = ((csr_l / 10) % 10) + '0'; + kbd_buffer[kbd_buffer_filled++] = (csr_l % 10) + '0'; + kbd_buffer[kbd_buffer_filled++] = ';'; + if (csr_c >= 100) kbd_buffer[kbd_buffer_filled++] = ((csr_c / 100) % 10) + '0'; + if (csr_c >= 10) kbd_buffer[kbd_buffer_filled++] = ((csr_c / 10) % 10) + '0'; + kbd_buffer[kbd_buffer_filled++] = (csr_c % 10) + '0'; + kbd_buffer[kbd_buffer_filled++] = 'R'; + } else if (buffer[i] == 's') { // save cursor position + save_csr_l = csr_l; + save_csr_c = csr_c; + } else if (buffer[i] == 'p') { // restore cursor position + csr_l = save_csr_l; + csr_c = save_csr_c; + } else if (buffer[i] == 'e') { // CUSTOM : enable keyboard echo + keyboard_echo = true; + } else if (buffer[i] == 'h') { // CUSTOM : disable keyboard echo + keyboard_echo = false; + } else if (buffer[i] == '?') { + if (buffer[++i] == '2' && buffer[++i] == '5') { + if (buffer[++i] == 'l') cursor_visible = false; + else cursor_visible = true; + } + } else { + } + if (csr_l < 0) csr_l = 0; + if (csr_c < 0) csr_c = 0; + if (csr_l >= h) csr_l = h - 1; + if (csr_c >= w) csr_c = w - 1; + if (output != 0 && output->connected_vt == this) output->text_setcsr(csr_l, csr_c, cursor_visible); + } else { + // ignore it. + } + } else { + put(buffer[i]); + } + } return len; } @@ -212,19 +364,30 @@ int vt::read(size_t offset, size_t len, char* buffer) { bool end = false; if (kbd_buffer_filled > 0) { int r = 0; - for (; r < kbd_buffer_filled; r++) { - if (kbd_buffer[r] == '\b') { - if (c > 0) { - c--; - put('\b'); + if (keyboard_echo) { + for (; r < kbd_buffer_filled; r++) { + if (kbd_buffer[r] == '\b') { + if (c > 0) { + c--; + put('\b'); + } + } else if (kbd_buffer[r] == '\n') { + buffer[c++] = '\n'; + c++; + put('\n'); + end = true; + break; + } else if (kbd_buffer[r] >= ' ') { + buffer[c++] = kbd_buffer[r]; + put(buffer[c]); } - } else { - buffer[c] = kbd_buffer[r]; - put(buffer[c]); - if (buffer[c] == '\n' || buffer[c] == 27) end = true; - c++; + if (c == len) break; + } + } else { + for (; r < kbd_buffer_filled && c < len; r++) { + buffer[c++] = kbd_buffer[r]; } - if (c == len) break; + end = true; } memcpy(kbd_buffer + r, kbd_buffer, (kbd_buffer_filled - r)); kbd_buffer_filled -= r; diff --git a/src/kernel/ui/vt.h b/src/kernel/ui/vt.h index a80452b..a29716f 100644 --- a/src/kernel/ui/vt.h +++ b/src/kernel/ui/vt.h @@ -15,11 +15,11 @@ struct vt_char { class vt : public node { private: display *output; - int w, h, csr_l, csr_c; + int w, h, csr_l, csr_c, save_csr_l, save_csr_c; vt_char *text; void put_at(int l, int c, int ch); - bool cursor_visible; + bool cursor_visible, keyboard_echo; int kbd_buffer_filled; char kbd_buffer[KBD_BUFFER_SIZE]; @@ -35,6 +35,7 @@ class vt : public node { // internal use void put(int c); void clear(); + void scroll(int l); void writeStr(char* str) { write(0, strlen(str), str); } void writeHex(uint32_t v); void writeDec(int v); diff --git a/src/kernel/vfs/node.cpp b/src/kernel/vfs/node.cpp index c517aae..0b753af 100644 --- a/src/kernel/vfs/node.cpp +++ b/src/kernel/vfs/node.cpp @@ -54,6 +54,7 @@ node* vfs_find(node* root, char* fn) { } node* vfs_read_fd(FILE d) { + if (d < 0) return 0; return current_process->fd.at(d); } |