#include #include #include #include #include "font.h" #include "quinn.h" #include "convertxpm.h" #include "terminal.xpm" extern const struct bitmap_font bmapfont; int term_w; int term_h; int window_handle = -1; #define ParentRead read_pipe[0] #define ParentWrite write_pipe[1] #define ChildRead write_pipe[0] #define ChildWrite read_pipe[1] extern char **environ; int read_pipe[2]; int write_pipe[2]; char *surface; unsigned char attrib; int term_x; int term_y; int echo = 1; unsigned int char_width, char_height; char *cursor_save_buffer; int cursor_save_x; int cursor_save_y; static int state = 0; static int params[16]; static int param_count = 0; static int saved_x = 0; static int saved_y = 0; static int bold = 0; static unsigned char saved_attr = 0x07; static unsigned int console_col_map[16] = { 0xff000000, 0xff0000AA, 0xff00AA00, 0xff00AAAA, 0xffAA0000, 0xffAA00AA, 0xffAA5500, 0xffAAAAAA, 0xff555555, 0xff5555FF, 0xff55FF55, 0xff55FFFF, 0xffFF5555, 0xffFF55FF, 0xffFFFF55, 0xffFFFFFF }; void update_cursor(int restore) { int bpos, i, j; if (restore == 1 && cursor_save_x > -1 && cursor_save_y > -1) { // restore the bit of the screen where the cursor was bpos = 0; for (i=0;i<4;i++) { for (j=0;j<8;j++) { int where = ((j + (cursor_save_x*bmapfont.Width)) * 4) + (((bmapfont.Height - i - 1) + (cursor_save_y* bmapfont.Height)) * term_w * 4); surface[where] = cursor_save_buffer[bpos]; // BLUE surface[where + 1] = cursor_save_buffer[bpos + 1]; // GREEN surface[where + 2] = cursor_save_buffer[bpos + 2]; // RED surface[where + 3] = cursor_save_buffer[bpos + 3]; // ALPHA bpos += 4; } } } // save the new cursor position buffer; bpos = 0; for (i=0;i<4;i++) { for (j=0;j<8;j++) { int where = ((j + (term_x*bmapfont.Width)) * 4) + (((bmapfont.Height - i - 1) + (term_y* bmapfont.Height)) * term_w * 4); cursor_save_buffer[bpos] = surface[where]; cursor_save_buffer[bpos + 1] = surface[where + 1]; cursor_save_buffer[bpos + 2] = surface[where + 2]; cursor_save_buffer[bpos + 3] = surface[where + 3]; bpos += 4; } } cursor_save_x = term_x; cursor_save_y = term_y; // draw the cursor for (i=0;i<4;i++) { for (j=0;j<8;j++) { int where = ((j + (cursor_save_x*bmapfont.Width)) * 4) + (((bmapfont.Height - i - 1) + (cursor_save_y* bmapfont.Height)) * term_w * 4); surface[where] = 0xff; // BLUE surface[where + 1] = 0xff; // GREEN surface[where + 2] = 0xff; // RED surface[where + 3] = 0xff; bpos += 4; } } } void goto_xy(int newx, int newy) { if (newx > char_width || newy > char_height || newx < 0 || newy < 0) { return; } term_x = newx; term_y = newy; update_cursor(1); } void clear_screen(void) { int j; int k; unsigned int colour = console_col_map[(attrib & 0xf0) >> 4]; for (k=0;k> 4]; for(cy=0;cy<16;cy++){ for(cx=0;cx<8;cx++){ quinn_setpixel(window_handle, surface, x+cx, y+cy, term_w, term_h, font_char[cy] & mask[cx] ? fgcolor:bgcolor); } } } void console_backspace() { if (term_x == 0) { term_y--; term_x = char_width - 1; } else { term_x--; } draw_char(term_x * bmapfont.Width, term_y * bmapfont.Height, ' '); update_cursor(1); } void put_char(unsigned char c) { draw_char(term_x * (int)bmapfont.Width, term_y * (int)bmapfont.Height, c); term_x++; update_cursor(0); } void process_char(char c) { int j, k; if (term_x == char_width) { term_x = 0; term_y++; } if (term_y == char_height) { scroll_up(); term_y = char_height - 1; } if (state == 0) { if (c == 27) { state = 1; return; } else { if (c == '\n') { term_x = 0; term_y++; if (term_y == char_height) { scroll_up(); term_y = char_height - 1; } update_cursor(1); } else if ((unsigned char)c > 31) { put_char((unsigned char)c); } } } else if (state == 1) { if (c == '[') { state = 2; return; } } else if (state == 2) { param_count = 0; for (j=0;j<16;j++) { params[j] = 0; } state = 3; } if (state == 3) { if (c == ';') { if (param_count < 15) { param_count++; } return; } else if (c >= '0' && c <= '9') { if (!param_count) param_count = 1; params[param_count-1] = params[param_count-1] * 10 + (c - '0'); return; } else { state = 4; } } if (state == 4) { switch (c) { case 'H': case 'f': if (params[0]) params[0]--; if (params[1]) params[1]--; goto_xy(params[0], params[1]); state = 0; break; case 'A': if (param_count > 0) { goto_xy(term_x, term_y - params[0]); } else { goto_xy(term_x, term_y - 1); } state = 0; break; case 'B': if (param_count > 0) { goto_xy(term_x, term_y + params[0]); } else { goto_xy(term_x, term_y + 1); } state = 0; break; case 'C': if (param_count > 0) { goto_xy(term_x + params[0], term_y); } else { goto_xy(term_x + 1, term_y); } state = 0; break; case 'D': if (param_count > 0) { goto_xy(term_x - params[0], term_y); } else { goto_xy(term_x - 1, term_y); } state = 0; break; case 's': saved_x = term_x; saved_y = term_y; state = 0; break; case 'u': goto_xy(saved_x, saved_y); state = 0; break; case '7': saved_x = term_x; saved_y = term_y; saved_attr = attrib; state = 0; break; case '8': goto_xy(saved_x, saved_y); attrib = saved_attr; break; case 'm': for (j=0;j> 4]); } else if (params[0] == 1) { quinn_fill_rect(window_handle, surface, term_w, term_h, 0, 0, term_w, term_y * bmapfont.Height, console_col_map[attrib & 0xF0 >> 4]); } else if (params[0] == 2) { clear_screen(); term_x = 0; term_y = 0; } update_cursor(1); state = 0; break; case 'h': if (params[0] == 12) { echo = 0; } state = 0; break; case 'i': if (params[0] == 12) { echo = 1; } state = 0; break; default: state = 0; break; } } } void exit_callback(int wh) { quinn_exit(); exit(0); } void input_char(char c) { write(ParentWrite, &c, 1); if (echo) { process_char(c); } } char *sargv[] = {"shell.exe", NULL}; int main(int argc, char **argv) { struct window_req_t *req; char buffer[512]; int len; int i; int cpid; unsigned char *icon; struct widget_t *surf; attrib = 0x07; if (pipe(read_pipe) == -1) { exit(-1); } if (pipe(write_pipe) == -1) { exit(-1); } cpid = fork(); if (cpid == -1) { exit(-1); } if (cpid == 0) { close(0); dup(ChildRead); close(ChildRead); close(1); dup(ChildWrite); close(ChildWrite); close(ParentRead); close(ParentWrite); execve("disk0:/shell.exe", sargv, environ); exit(-1); } else { close(ChildRead); close(ChildWrite); term_w = 640; term_h = 400; char_height = 25;//height / font.Height; char_width = 80;//width / font.Width; quinn_init(); req = (struct window_req_t *)malloc(sizeof(struct window_req_t)); convert_xpm(terminal_xpm, &icon); req->x = 30; req->y = 30; req->width = 640; req->height = 400; req->icon = icon; req->flags = 0; strcpy(req->name, "Terminal"); window_handle = quinn_req_window(req, exit_callback); free(req); free(icon); term_x = 0; term_y = 0; surf = quinn_add_surface(window_handle, 0, 0, term_w, term_h, NULL, input_char, NULL); quinn_surface_set_cooked(surf, 1); surface = quinn_surface_get_surface(surf); quinn_fill_rect(window_handle, surface, 640, 400, 0, 0, 640,400, 0xff000000); cursor_save_buffer = (char *)malloc(8 * 4 * 4); cursor_save_x = -1; cursor_save_y = -1; while (1) { len = 0; __asm__ volatile ("int $0x30" : "=a" (len) : "0" (5), "b" (ParentRead), "c" (buffer), "d" (512)); if (len == 0) { quinn_exit(); exit(0); } if (len > 0) { for(i=0;i