diff options
Diffstat (limited to 'src/kernel/ui')
-rw-r--r-- | src/kernel/ui/vt.cpp | 159 | ||||
-rw-r--r-- | src/kernel/ui/vt.h | 49 |
2 files changed, 208 insertions, 0 deletions
diff --git a/src/kernel/ui/vt.cpp b/src/kernel/ui/vt.cpp new file mode 100644 index 0000000..4675cdc --- /dev/null +++ b/src/kernel/ui/vt.cpp @@ -0,0 +1,159 @@ +#include "vt.h" +#include <dev/display.h> + +vt *ke_vt = 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; + + text = 0; + if (w != 0 && h != 0) { + text = (vt_char*)kmalloc(w * h * sizeof(vt_char)); + clear(); + } +} + +void vt::put_at(int l, int c, int ch) { + text[l * w + c].fgcolor = fgcolor; + text[l * w + c].bgcolor = bgcolor; + text[l * w + c].ch = ch; + if (output != 0) output->text_put(l, c, ch, fgcolor, bgcolor); +} + +void vt::put(int c) { + if (text == 0) return; + + if (c == '\b' && csr_c != 0) { + csr_c--; + put_at(csr_l, csr_c, ' '); + } else if (c == '\t') { + int csr_nc = (csr_c + 8) & ~(8 - 1); + for (int i = csr_c; i < csr_nc && i < w; i++) put_at(csr_l, i, ' '); + csr_c = csr_nc; + } else if (c == '\r') { + csr_c = 0; + } else if (c == '\n') { + csr_c = 0; + csr_l++; + } else if (c >= ' ') { + put_at(csr_l, csr_c, c); + csr_c++; + } + if (csr_c >= w) { + csr_c = 0; + 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--; + } + if (output != 0 && output->connected_vt == this) output->text_setcsr(csr_l, csr_c, cursor_visible); +} + +void vt::clear() { + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + put_at(j, i, ' '); + } + } + csr_c = csr_l = 0; +} + +void vt::writeStr(char *s) { + while (*s) { + put(*(s++)); + } +} + +void vt::writeHex(uint32_t v) { + int i; + + put('0'); put('x'); + char hexdigits[] = "0123456789abcdef"; + + for (i = 0; i < 8; i++) { + put(hexdigits[v >> 28]); + v = v << 4; + } +} + +void vt::writeDec(uint32_t v) { + if (v == 0) { + put('0'); + return; + } + + char numbers[] = "0123456789"; + while (v > 0) { + int order = 1, no = 1; + while (v / order > 0) order *= 10; + order /= 10; + put(numbers[v / order]); + v = v - (v / order * order); + while (v / no > 0) no *= 10; + while (no < order) { + put('0'); + no *= 10; + } + } +} + +// ******* + +int vt::outputTo(display *display) { + output = display; + if (output == 0) return 0; + output->connected_vt = this; + + if (output->text_w() != w || output->text_h() != h) { + int ow = w, oh = h; + vt_char *old_text = text; + + w = output->text_w(); + h = output->text_h(); + text = (vt_char*)malloc(w * h * sizeof(vt_char)); + for (int c = 0; c < w; c++) { + for (int l = 0; l < h; l++) { + if (c < ow && l < oh) { + put_at(l, c, old_text[l * ow + c].ch); + } else { + put_at(l, c, ' '); + } + } + } + if (old_text != 0) free(old_text); + if (csr_c >= w) csr_c = w; + if (csr_l >= h) csr_l = h; + } else { + for (int c = 0; c < w; c++) { + for (int l = 0; l < h; l++) { + output->text_put(l, c, text[l*w+c].ch, text[l*w+c].fgcolor, text[l*w+c].bgcolor); + } + } + } + return 0; +} + +int vt::write(size_t offset, size_t len, char* buffer) { + // ignore offset + for (unsigned i = 0; i < len; i++) put(buffer[i]); + return len; +} + +size_t vt::get_size() { + return ((w << 16) + h); +} diff --git a/src/kernel/ui/vt.h b/src/kernel/ui/vt.h new file mode 100644 index 0000000..b4f3672 --- /dev/null +++ b/src/kernel/ui/vt.h @@ -0,0 +1,49 @@ +#ifndef DEF_UI_VT_H +#define DEF_UI_VT_H + +#include <vfs/node.h> +#include <dev/display.h> + +struct vt_char { + int ch; + uint8_t fgcolor, bgcolor; +}; + +class vt : public node { + private: + display *output; + int w, h, csr_l, csr_c; + vt_char *text; + + void put_at(int l, int c, int ch); + bool cursor_visible; + + public: + uint8_t fgcolor, bgcolor; + + vt(node* parent, int w, int h); + + // internal use + void put(int c); + void clear(); + void writeStr(char* str); + void writeHex(uint32_t v); + void writeDec(uint32_t v); + + int outputTo(display *display); + + virtual int write(size_t offset, size_t len, char* buffer); + virtual size_t get_size(); +}; + +extern vt *ke_vt; +#define NL ke_vt->writeStr("\n"); +#define TAB ke_vt->writeStr("\t"); +#define WHERE { ke_vt->writeStr("(ke:"); \ + ke_vt->writeStr(__FILE__); \ + ke_vt->writeStr(":"); \ + ke_vt->writeDec(__LINE__); \ + ke_vt->writeStr(") "); } + +#endif + |