#include "vt.h" #include 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(int v) { if (v == 0) { put('0'); return; } if (v < 0) { put ('-'); v = -v; } 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*)kmalloc(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) kfree(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); }