/* * --------------------------------------------------------------------------- * Name : terminal_write * Purpose: Write a string to the buffer. * Args : const char* data, * size_t size * Returns: void * --------------------------------------------------------------------------- */ void terminal_write(const char* data, size_t size) { for ( size_t i = 0; i < size; i++ ) if(data[i] == '\n') { terminal_column = 0; if(++terminal_row == VGA_HEIGHT) { terminal_scroll(); } } else if(data[i] == '\t') { size_t i = 0; while(i++ < 4 - (terminal_column % 4)) terminal_putchar(' '); } else if(data[i] == '\r') { while(terminal_column-- >= 0) terminal_putentryat(' ', make_color(COLOR_LIGHT_GREY, COLOR_BLACK), terminal_column, terminal_row); } else if(data[i] == '\x1b') { i += terminal_escape_sequence(data + i); } else { terminal_putchar(data[i]); } }
static int _write_helper(const char *buf, size_t len, void *arg) { if (!screen.buf) { const char *end = buf + len; for (const char *ptr = buf; ptr < end; ++ptr) { if (*ptr == '\n') terminal_putchar('\r'); terminal_putchar(*ptr); } } else { terminal_write_cached((const uchar_t *) buf, len); } return 0; }
void terminal_writehexdigits(uint8_t digit) { uint8_t low = digit & 0x0F; uint8_t high = (digit & 0xF0) >> 4; if (high > 9) { terminal_putchar('A' + high - 10); } else { terminal_putchar('0' + high); } if (low > 9) { terminal_putchar('A' + low - 10); } else { terminal_putchar('0' + low ); } }
void terminal_puts(const char *str){ size_t len = strlen(str); for(size_t i = 0 ; i < len ; i++ ){ terminal_putchar(str[i]); } update_cursor(terminal_row,terminal_column); }
/* * printk * * Print a format string to the terminal with special character sequences * replaced by arguments. * * Currently supported format char sequences: %c, %s, %d, %x. * * TODO: Implement complete printk functionality. */ void printk(const char *fmt, ...) { va_list ap; uint8_t fmtln = strlen(fmt); char numstr[32] = {0}; memset(numstr, 0, 32); va_start(ap, fmt); for (uint8_t i = 0; i < fmtln; i++) { if (fmt[i] != '%') { terminal_putchar(fmt[i]); } else { switch (fmt[++i]) { case 'c': terminal_putchar((char) va_arg(ap, int)); break; case 's': terminal_writestring(va_arg(ap, char *)); break; case 'd': terminal_writestring(itoa(va_arg(ap, int), numstr, 10)); memset(numstr, 0, 32); break; case 'x': terminal_writestring(itoa(va_arg(ap, int), numstr, 16)); memset(numstr, 0, 32); break; default: //TODO: Panic break; } } } va_end(ap); }
/** * 生成并发送ANSI光标移动指令 * @param col 要移动到的列 * @param line 要移动到的行 */ static void move_terminal_cursor_to(int col, int line) { char buf[16]; snprintf(buf, sizeof(buf), "\033[%d;%dH", line + 1, col + 1); for (char *p = buf; *p; ++p) terminal_putchar(*p); }
void printf(const char *str, ...) { va_list arglist; va_start(arglist, str); int p = 0; while (str[p] != NULL) { if (str[p] == '%') { const char nextone = str[p + 1]; if (nextone == '%') { terminal_putchar('%'); } else if (nextone == 's') { terminal_putstring(va_arg(arglist, const char*)); } else if (nextone == 'd') { // As of right now, we have no method of dynamic allocation, and thus must unfortunately have an array of considerable size and hope it's enough. //But I think 128 digits is plenty for now, considering that a number that is 64 bits long can only go as far as 20 digits! char theletters[128]; if (itoa(va_arg(arglist, int), 10, theletters)) { terminal_putstring(theletters); }; } else if (nextone == 'b') { char theletters[128]; if (itoa(va_arg(arglist, int), 2, theletters)) { terminal_putstring(theletters); }; }
void terminal_writestring(const char* string) { size_t stringlen = strlen(string); for(size_t i = 0; i < stringlen; i++) terminal_putchar(string[i]); }
void terminal_writestring(const char* data) { size_t datalen = strlen(data); for ( size_t i = 0; i < datalen; i++ ) { terminal_putchar(data[i]); } }
static void kaypro_erase_end_of_line(void) { int x, attr; attr = ' '; for (x = cur_x; x < KAYPRO_SCREEN_W; x++) terminal_putchar(kaypro_terminal, x, cur_y, attr); }
static void keyboard_handler(intctx_t *ctx) { UNUSED(ctx); unsigned char scancode = inb(0x60); if (scancode & 0x80) { } else { terminal_putchar(kbdus[scancode]); } }
// terminal_writestring - print a string to screen // this function prints a line of text to screen, wrapping and scrolling if necessary. void terminal_writestring(char* data) { __vga_write_lock.lock(); size_t datalen = strlen(data); for ( size_t i = 0; i < datalen; i++ ) { terminal_putchar(data[i]); } __vga_write_lock.unlock(); }
void terminal_writerainbow(const char *data) { size_t datalen = strlen(data); for (size_t i = 0; i < datalen; i++) { uint8_t fg = terminal_color; uint8_t bg = terminal_color >> 4; terminal_setcolor(make_color(++fg % NUMCOLORS, ++bg % NUMCOLORS)); terminal_putchar(data[i]); } }
void screen_flush(void) { if (!screen.buf) { terminal_flush(); return; } if (!terminal_input_buffer_empty()) return; if (screen.redraw || (abs(screen.scrollcnt) >= (screen.lines - 3))) { screen_redraw(); return; } if (screen.scrollcnt < 0) { move_terminal_cursor(0, 0); while (screen.scrollcnt < 0) { ansi_cmd(ANSI_CMD_SR); screen.scrollcnt++; } } if (screen.scrollcnt > 0) { move_terminal_cursor(0, screen.lines - 1); while (screen.scrollcnt > 0) { terminal_putchar('\n'); screen.scrollcnt--; } } for (int i = 0; i < screen.lines; i++) { screen_line_t *sl = get_screen_line(i); sl->data[sl->len] = '\0'; int width = screen_display_width((char *) sl->data, true); if (sl->modified) { sl->modified = false; move_terminal_cursor(0, i); screen_write_cached(sl->data, sl->len); screen.tc_col = width; if (screen.tc_col >= screen.columns) { screen.tc_col -= screen.columns; screen.tc_line++; if (screen.tc_line >= screen.lines) screen.tc_line = screen.lines - 1; } } if (sl->old_width > width) { move_terminal_cursor(width, i); ansi_cmd(ANSI_CMD_CE); } sl->old_width = width; } move_terminal_cursor(screen.cur_col, screen.cur_ln); terminal_flush(); }
void draw_logo(void) { char c, *data; terminal_clear(); data = logo; while ((c = *data++) != '\0' ) { switch (c) { case '_': terminal_setcolor(0x08); // Dark Grey terminal_putchar('_'); break; case '/': terminal_setcolor(0x0A); // Green terminal_putchar('/'); break; case 'X': terminal_setcolor(0x0A); // Green terminal_putchar('\\'); break; case ' ': terminal_putchar(' '); break; case 'n': terminal_putchar('\n'); break; } } terminal_setcolor(0x07); // Light Grey printf("===============================================================================\n"); terminal_setcolor(0x0F); printf(" ## BYOK: Forth machine, version: %s ##\n", VERSION); terminal_setcolor(0x07); printf(" This program (c) 2015 Richard Hull, published under the MIT License\n"); printf(" To read the licence, type LICENSE <enter>. For help, type HELP <enter>\n"); printf("===============================================================================\n"); }
/** * Output a character. * @param c The character. * @return 1, 0 on ansi control codes. * @deprecated */ int outc(int c) { if (!screen.buf) { if (!isprint2(c)) { if (c == '\n') { terminal_putchar('\r'); } else { if (c != KEY_ESC || !showansi) c = '*'; } } terminal_putchar(c); return 1; } screen_line_t *slp = get_screen_line(screen.cur_ln); if (!isprint2(c)) { if (c == '\n' || c == '\r') { if (screen.cur_col> slp->len) { memset(slp->data + slp->len, ' ', screen.cur_col - slp->len + 1); } slp->len = screen.cur_col; screen.cur_col = 0; if (screen.cur_ln < screen.lines) screen.cur_ln++; return 1; } else { if (c != KEY_ESC || !showansi) c = '*'; } } screen_put_gbk(c); if (screen.cur_col >= screen.columns) { screen.cur_col = 0; if (screen.cur_ln < screen.lines) screen.cur_ln++; } return 1; }
void print_requirement(const char *text, bool have) { terminal_setcolor(make_color(FGCOLOR, BGCOLOR)); terminal_printf(" - %s ", text); size_t textlen = strlen(text); for (size_t pneed = textlen; pneed < 32; pneed++) { terminal_putchar('.'); } terminal_putchar('['); if (have) { terminal_setcolor(make_color(COLOR_GREEN, BGCOLOR)); terminal_writestring("OK"); } else { terminal_setcolor(make_color(COLOR_RED, BGCOLOR)); terminal_writestring("FAIL"); } terminal_setcolor(make_color(FGCOLOR, BGCOLOR)); terminal_writestring("]\n"); }
/** * 移动终端光标到指定位置 * @param col 要移动到的列 * @param line 要移动到的行 */ static void move_terminal_cursor(int col, int line) { if (line >= screen.lines || col >= screen.columns) return; if (!col && line == screen.tc_line + 1) { terminal_putchar('\n'); if (screen.tc_col) terminal_putchar('\r'); } else if (!col && line == screen.tc_line) { if (screen.tc_col) terminal_putchar('\r'); } else if (col == screen.tc_col - 1 && line == screen.tc_line) { terminal_putchar(Ctrl('H')); } else if (col != screen.tc_col || line != screen.tc_line) { move_terminal_cursor_to(col, line); } screen.tc_col = col; screen.tc_line = line; }
/****************************************************************************** * kaypro_scroll * scroll the screen buffer from line top to line scroll_lines-1 * either up or down. scroll up if lines > 0, down if lines < 0 * repeat lines times and mark changes in dirtybuffer ******************************************************************************/ static void kaypro_scroll(int top, int lines) { int x, y; short attr; while (lines) { if (lines > 0) { for( y = top; y < scroll_lines - 1; y++ ) { for( x = 0; x < KAYPRO_SCREEN_W; x++ ) { terminal_putchar(kaypro_terminal, x, y, terminal_getchar(kaypro_terminal, x, y+1)); } } attr = ' '; for (x = 0; x < KAYPRO_SCREEN_W; x++) { terminal_putchar(kaypro_terminal, x, scroll_lines - 1, attr); } lines--; } else { for (y = scroll_lines - 1; y > top; y--) { for (x = 0; x < KAYPRO_SCREEN_W; x++) { terminal_putchar(kaypro_terminal, x, y, terminal_getchar(kaypro_terminal, x, y-1)); } } attr = ' '; for (x = 0; x < KAYPRO_SCREEN_W; x++) { terminal_putchar(kaypro_terminal, x, top, attr); } lines++; } } }
/** * Clear to end of current line. */ void clrtoeol(void) { if (!screen.buf) { if (screen.cur_col == 0) terminal_putchar('\r'); ansi_cmd(ANSI_CMD_CE); } else { screen_line_t *sl = get_screen_line(screen.cur_ln); if (screen.cur_col > sl->len) memset(sl->data + sl->len, ' ', screen.cur_col - sl->len + 1); sl->len = screen.cur_col; } }
static void kaypro_erase_end_of_screen(void) { int x, y, attr; attr = ' '; kaypro_erase_end_of_line(); for (y = cur_y + 1; y < scroll_lines; y++) { for (x = 0; x < KAYPRO_SCREEN_W; x++) terminal_putchar(kaypro_terminal, x, y, attr); } }
static int lua_writeout_proxy(lua_State *st) { int n_args = lua_gettop(st); unsigned int ret = 0; for(int i=1;i<=n_args;i++) { if( lua_isstring(st, i) ) { const char *out = lua_tostring(st, i); terminal_writestring(const_cast<char*>(out)); ret += strlen(const_cast<char*>(out)); } } terminal_putchar('\n'); lua_pushnumber(st, ret); return 1; }
void keyboard_handler() { unsigned char scancode; //Read from port 60 when handler is called. //0x60 is the keyboard key port scancode = inportb(0x60); //if top bit is set, then key has just been released //useful for shifts and control/alt if ((scancode & 0x80) != 0 ) { if (scancode == 0xAA || scancode == 0xB6) { isShift = 0; return; } } else { if (kbdus[scancode] == 91 || kbdus[scancode] == 90) { isShift = 1; return; } if (isShift != 0) { terminal_putchar(upperKbdus[scancode]); } else terminal_putchar(kbdus[scancode]); if (kbdus[scancode] == '\n') { runShell(); } //key just pressed down } }
void terminal_putchar(const char c) { if (c == '\n') { terminal_row++; if (terminal_row == VGA_HEIGHT) { ScrollDown(1); terminal_row = 23; }; terminal_column = 0; return; }; if (terminal_column++ == VGA_WIDTH) { terminal_putchar('\n'); }; terminal_putentryat(c, terminal_color, terminal_column, terminal_row); };
static void kaypro_pixel(int x, int y, int set) { static int attr_bits[4][2] = { { 0x002, 0x001}, { 0x008, 0x004}, { 0x020, 0x010}, {AT_REVERSE, 0x040} }; int cx, cy, offs, bits; short attr; /* The Kaypro 2x font has a 2x4 pattern block graphics */ cx = x / 2; cy = y / 4; offs = cy * KAYPRO_SCREEN_W + cx; attr = terminal_getchar(kaypro_terminal, cx, cy); /* if it is a space, we change it to a graphic space */ if ((attr & 0xff) == ' ') attr = (attr & 0xff00) | 0x80; /* if it is non graphics, we do nothing */ if (! (attr & 0x80)) return; /* reverse video (lower-left pixel) inverts all the other pixels */ if (attr & AT_REVERSE) attr ^= 0x7f; /* get the bit mask for the pixel */ bits = attr_bits[y % 4][x % 2]; /* set it ? */ if (set) attr |= bits; else attr &= ~ bits; /* reverse video (lower-left pixel) inverts all the other pixels */ if (attr & AT_REVERSE) attr ^= 0x7f; terminal_putchar(kaypro_terminal, cx, cy, attr); }
void terminal_put_char(const char character) { int i ; if(character >= 0x20 && character <= 127) //character is printable { if(cursor_position_x == 50) { cursor_position_y++; cursor_position_x = 1; } if(cursor_position_y!=0) screen_buffer[(cursor_position_y-1)*64 + cursor_position_x] = character; terminal_putchar(character, cursor_position_x, cursor_position_y); cursor_position_x++; } else if(character == '\r') { cursor_position_x = 1; } else if(character == '\n') { cursor_position_y++; } if(cursor_position_y >= 37) //Scroll screen { copy(0, screen_buffer, 64*64); cursor_position_y = 36; for(i = 0; i< 63*64; i++) { screen_buffer[i] = screen_buffer[i+64]; } } }
void terminal_printf(const char* string, ...) { va_list a_list; va_start(a_list, string); for (size_t i = 0; i < strlen(string); i++) { if (string[i] == '%') { i++; char buffer[33]; if (string[i] == '%') { terminal_putchar('%'); } else if (string[i] == 's') { terminal_writestring(va_arg(a_list, const char*)); } else if (string[i] == 'c') { terminal_putchar((char)va_arg(a_list, int)); } else if (string[i] == 'd')
int putchar(int c) { terminal_putchar(c); return c; }
void terminal_write(const char* data, size_t size) { for ( size_t i = 0; i < size; i++ ) terminal_putchar(data[i]); }
void terminal_putstring(const char* str) { size_t strlength = strlen(str); for (size_t i = 0; i < strlength; i++) { terminal_putchar(str[i]); }; };