From: Kyle Hale Date: Wed, 13 Jul 2016 18:08:01 +0000 (-0500) Subject: Enhancements to text mode console clients X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=ea68fe042705986beaec92f33db0395b816c2e38 Enhancements to text mode console clients - v3_cons_sc now does color and arrow keys - new v3_cons_tc does this and more - v3_cons_tc is non-default, needs installation of libtermkey --- diff --git a/linux_usr/Makefile b/linux_usr/Makefile index c0d5034..238458f 100644 --- a/linux_usr/Makefile +++ b/linux_usr/Makefile @@ -55,7 +55,9 @@ EXPERIMENTAL_EXECS = v3_simulate \ v3_env_inject \ v3_syscall \ v3_register_gm \ - v3_devfile_shadow + v3_devfile_shadow \ + +NONDEFAULT_EXECS = v3_cons_tc # needs to have termkey installed @@ -133,6 +135,10 @@ v3_cons: v3_cons.c v3_cons_sc: v3_cons_sc.c $(CC) $(CFLAGS) $(CURSES_CFLAGS) $< $(CURSES_LIBS) -o $@ +v3_cons_tc: v3_cons_tc.c + $(CC) $(CFLAGS) $(CURSES_CFLAGS) $< $(CURSES_LIBS) -L. -ltermkey -lcurses -o $@ + + v3_create: v3_create.c ezxml.c libv3_ctrl.a $(CC) $(CFLAGS) $^ -lv3_ctrl -L. -o $@ diff --git a/linux_usr/v3_cons_sc.c b/linux_usr/v3_cons_sc.c index 6d7e522..9419804 100644 --- a/linux_usr/v3_cons_sc.c +++ b/linux_usr/v3_cons_sc.c @@ -117,7 +117,9 @@ static int handle_char_set(struct character_msg * msg) { return -1; } + wattron(console.win, COLOR_PAIR(msg->style)); mvwaddch(console.win, msg->y, msg->x, c); + wattroff(console.win, COLOR_PAIR(msg->style)); } else { //stdout text display @@ -285,8 +287,8 @@ struct key_code { }; static const struct key_code ascii_to_key_code[] = { // ASCII Value Serves as Index - NO_KEY, NO_KEY, NO_KEY, NO_KEY, // 0x00 - 0x03 - NO_KEY, NO_KEY, NO_KEY, { 0x0E, 0 }, // 0x04 - 0x07 + NO_KEY, NO_KEY, {0x50, 0}, {0x48, 0}, // 0x00 - 0x03 + {0x4B, 0}, {0x4D, 0}, NO_KEY, { 0x0E, 0 }, // 0x04 - 0x07 { 0x0E, 0 }, { 0x0F, 0 }, { 0x1C, 0 }, NO_KEY, // 0x08 - 0x0B NO_KEY, { 0x1C, 0 }, NO_KEY, NO_KEY, // 0x0C - 0x0F NO_KEY, NO_KEY, NO_KEY, NO_KEY, // 0x10 - 0x13 @@ -397,6 +399,18 @@ int check_terminal_size (void) } + +static void +init_colors (void) +{ + start_color(); + int i; + for (i = 0; i < 0x100; i++) { + init_pair(i, i & 0xf, (i >> 4) & 0xf); + } +} + + int main(int argc, char* argv[]) { int vm_fd; int cons_fd; @@ -454,6 +468,7 @@ int main(int argc, char* argv[]) { scrollok(console.win, 1); erase(); + init_colors(); } /* @@ -508,32 +523,32 @@ int main(int argc, char* argv[]) { } } - if (FD_ISSET(STDIN_FILENO, &rset)) { - unsigned char key = getch(); - - if (key == '\\') { // ESC - break; - } else if (key == '`') { - unsigned char sc = 0x44; // F10 - writeit(cons_fd,sc); - sc |= 0x80; - writeit(cons_fd,sc); - } else if (key == '~') { // CTRL-C - unsigned char sc; - sc = 0x1d; // left ctrl down - writeit(cons_fd,sc); - sc = 0x2e; // c down - writeit(cons_fd,sc); - sc = 0x2e | 0x80; // c up - writeit(cons_fd,sc); - sc = 0x1d | 0x80; // left ctrl up - writeit(cons_fd,sc); - } else { - if (send_char_to_palacios_as_scancodes(cons_fd,key)) { - printf("Error sending key to console\n"); - return -1; - } - } + if (FD_ISSET(STDIN_FILENO, &rset)) { + unsigned char key = getch(); + + if (key == '\\') { // ESC + break; + } else if (key == '`') { + unsigned char sc = 0x44; // F10 + writeit(cons_fd,sc); + sc |= 0x80; + writeit(cons_fd,sc); + } else if (key == '~') { // CTRL-C + unsigned char sc; + sc = 0x1d; // left ctrl down + writeit(cons_fd,sc); + sc = 0x2e; // c down + writeit(cons_fd,sc); + sc = 0x2e | 0x80; // c up + writeit(cons_fd,sc); + sc = 0x1d | 0x80; // left ctrl up + writeit(cons_fd,sc); + } else { + if (send_char_to_palacios_as_scancodes(cons_fd,key)) { + printf("Error sending key to console\n"); + return -1; + } + } } } diff --git a/linux_usr/v3_cons_tc.c b/linux_usr/v3_cons_tc.c new file mode 100644 index 0000000..5171a6a --- /dev/null +++ b/linux_usr/v3_cons_tc.c @@ -0,0 +1,811 @@ +/* + * V3 Console utility + * Taken from Palacios console display in MINIX ( by Erik Van der Kouwe ) + * (c) Jack lange, 2010 + * (c) Peter Dinda, 2011 (Scan code encoding) + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "v3_ctrl.h" +#include "termkey.h" + +static int use_curses = 0; +static int debug_enable = 0; + + +#define VCONS_EXIT 2 +#define VCONS_CTRLC 3 + +typedef enum { CONSOLE_CURS_SET = 1, + CONSOLE_CHAR_SET = 2, + CONSOLE_SCROLL = 3, + CONSOLE_UPDATE = 4, + CONSOLE_RESOLUTION = 5 } console_op_t; + + + +static struct { + WINDOW * win; + int x; + int y; + int rows; + int cols; + struct termios termios_old; + unsigned char old_kbd_mode; +} console; + +static TermKey * tk; + + +struct cursor_msg { + int x; + int y; +} __attribute__((packed)); + +struct character_msg { + int x; + int y; + char c; + unsigned char style; +} __attribute__((packed)); + +struct scroll_msg { + int lines; +} __attribute__((packed)); + +struct resolution_msg { + int cols; + int rows; +} __attribute__((packed)); + + +struct cons_msg { + unsigned char op; + union { + struct cursor_msg cursor; + struct character_msg character; + struct scroll_msg scroll; + struct resolution_msg resolution; + }; +} __attribute__((packed)); + + + + +static int handle_char_set(struct character_msg * msg) { + char c = msg->c; + + if (debug_enable) { + fprintf(stderr, "setting char (%c), at (x=%d, y=%d)\n", c, msg->x, msg->y); + } + + if (c == 0) { + c = ' '; + } + + + if ((c < ' ') || (c >= 127)) { + if (debug_enable) { + fprintf(stderr, "unexpected control character %d\n", c); + } + c = '?'; + } + + if (use_curses) { + /* clip whatever falls outside the visible area to avoid errors */ + if ((msg->x < 0) || (msg->y < 0) || + (msg->x > console.win->_maxx) || + (msg->y > console.win->_maxy)) { + + if (debug_enable) { + fprintf(stderr, "Char out of range (x=%d,y=%d) MAX:(x=%d,y=%d)\n", + msg->x, msg->y, console.win->_maxx, console.win->_maxy); + } + + return -1; + } + + if ((msg->x == console.win->_maxx) && + (msg->y == console.win->_maxy)) { + return -1; + } + + wattron(console.win, COLOR_PAIR(msg->style)); + mvwaddch(console.win, msg->y, msg->x, c); + wattroff(console.win, COLOR_PAIR(msg->style)); + + } else { + //stdout text display + while (console.y < msg->y) { + printf("\n"); + console.x = 0; + console.y++; + } + + while (console.x < msg->x) { + printf(" "); + console.x++; + } + + printf("%c", c); + console.x++; + + assert(console.x <= console.cols); + + if (console.x == console.cols) { + printf("\n"); + console.x = 0; + console.y++; + } + } + + return 0; +} + +int handle_curs_set(struct cursor_msg * msg) { + if (debug_enable) { + fprintf(stderr, "cursor set: (x=%d, y=%d)\n", msg->x, msg->y); + } + + if (use_curses) { + /* nothing to do now, cursor is set before update to make sure it isn't + * affected by character_set + */ + + console.x = msg->x; + console.y = msg->y; + } + + return 0; +} + + +int handle_scroll(struct scroll_msg * msg) { + int lines = msg->lines; + + if (debug_enable) { + fprintf(stderr, "scroll: %d lines\n", lines); + } + + + assert(lines >= 0); + + if (use_curses) { + while (lines > 0) { + scroll(console.win); + lines--; + } + } else { + console.y -= lines; + } +} + +int handle_text_resolution(struct resolution_msg * msg) { + if (debug_enable) { + fprintf(stderr, "text resolution: rows=%d, cols=%d\n", msg->rows, msg->cols); + } + + + console.rows = msg->rows; + console.cols = msg->cols; + + return 0; +} + +int handle_update( void ) { + if (debug_enable) { + fprintf(stderr, "update\n"); + } + + if (use_curses) { + + if ( (console.x >= 0) && (console.y >= 0) && + (console.x <= console.win->_maxx) && + (console.y <= console.win->_maxy) ) { + + wmove(console.win, console.y, console.x); + + } + + wrefresh(console.win); + } else { + fflush(stdout); + } +} + + +int handle_console_msg(int cons_fd) { + int ret = 0; + struct cons_msg msg; + + ret = read(cons_fd, &msg, sizeof(struct cons_msg)); + + switch (msg.op) { + case CONSOLE_CURS_SET: + // printf("Console cursor set (x=%d, y=%d)\n", msg.cursor.x, msg.cursor.y); + handle_curs_set(&(msg.cursor)); + break; + case CONSOLE_CHAR_SET: + handle_char_set(&(msg.character)); + /* printf("Console character set (x=%d, y=%d, c=%c, style=%c)\n", + msg.character.x, msg.character.y, msg.character.c, msg.character.style);*/ + break; + case CONSOLE_SCROLL: + // printf("Console scroll (lines=%d)\n", msg.scroll.lines); + handle_scroll(&(msg.scroll)); + break; + case CONSOLE_UPDATE: + // printf("Console update\n"); + handle_update(); + break; + case CONSOLE_RESOLUTION: + handle_text_resolution(&(msg.resolution)); + break; + default: + printf("Invalid console message operation (%d)\n", msg.op); + break; + } + + return 0; +} + + +int send_key(int cons_fd, char can_code) { + + return 0; +} + + + +void handle_exit(void) { + if ( debug_enable ) { + fprintf(stderr, "Exiting from console terminal\n"); + } + + if (use_curses) { + endwin(); + } + + termkey_destroy(tk); + // tcsetattr(STDIN_FILENO, TCSANOW, &console.termios_old); + + // ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE); +} + + +#define NO_KEY { 0, 0 } + +struct key_code { + unsigned char scan_code; + unsigned char capital; +}; + +static const struct key_code ascii_to_key_code[] = { // ASCII Value Serves as Index + NO_KEY, NO_KEY, {0x50, 0}, {0x48, 0}, // 0x00 - 0x03 + {0x4B, 0}, {0x4D, 0}, NO_KEY, { 0x0E, 0 }, // 0x04 - 0x07 + { 0x0E, 0 }, { 0x0F, 0 }, { 0x1C, 0 }, NO_KEY, // 0x08 - 0x0B + NO_KEY, { 0x1C, 0 }, NO_KEY, NO_KEY, // 0x0C - 0x0F + NO_KEY, NO_KEY, NO_KEY, NO_KEY, // 0x10 - 0x13 + NO_KEY, NO_KEY, NO_KEY, NO_KEY, // 0x14 - 0x17 + NO_KEY, NO_KEY, NO_KEY, { 0x01, 0 }, // 0x18 - 0x1B + NO_KEY, NO_KEY, NO_KEY, NO_KEY, // 0x1C - 0x1F + { 0x39, 0 }, { 0x02, 1 }, { 0x28, 1 }, { 0x04, 1 }, // 0x20 - 0x23 + { 0x05, 1 }, { 0x06, 1 }, { 0x08, 1 }, { 0x28, 0 }, // 0x24 - 0x27 + { 0x0A, 1 }, { 0x0B, 1 }, { 0x09, 1 }, { 0x0D, 1 }, // 0x28 - 0x2B + { 0x33, 0 }, { 0x0C, 0 }, { 0x34, 0 }, { 0x35, 0 }, // 0x2C - 0x2F + { 0x0B, 0 }, { 0x02, 0 }, { 0x03, 0 }, { 0x04, 0 }, // 0x30 - 0x33 + { 0x05, 0 }, { 0x06, 0 }, { 0x07, 0 }, { 0x08, 0 }, // 0x34 - 0x37 + { 0x09, 0 }, { 0x0A, 0 }, { 0x27, 1 }, { 0x27, 0 }, // 0x38 - 0x3B + { 0x33, 1 }, { 0x0D, 0 }, { 0x34, 1 }, { 0x35, 1 }, // 0x3C - 0x3F + { 0x03, 1 }, { 0x1E, 1 }, { 0x30, 1 }, { 0x2E, 1 }, // 0x40 - 0x43 + { 0x20, 1 }, { 0x12, 1 }, { 0x21, 1 }, { 0x22, 1 }, // 0x44 - 0x47 + { 0x23, 1 }, { 0x17, 1 }, { 0x24, 1 }, { 0x25, 1 }, // 0x48 - 0x4B + { 0x26, 1 }, { 0x32, 1 }, { 0x31, 1 }, { 0x18, 1 }, // 0x4C - 0x4F + { 0x19, 1 }, { 0x10, 1 }, { 0x13, 1 }, { 0x1F, 1 }, // 0x50 - 0x53 + { 0x14, 1 }, { 0x16, 1 }, { 0x2F, 1 }, { 0x11, 1 }, // 0x54 - 0x57 + { 0x2D, 1 }, { 0x15, 1 }, { 0x2C, 1 }, { 0x1A, 0 }, // 0x58 - 0x5B + { 0x2B, 0 }, { 0x1B, 0 }, { 0x07, 1 }, { 0x0C, 1 }, // 0x5C - 0x5F + { 0x29, 0 }, { 0x1E, 0 }, { 0x30, 0 }, { 0x2E, 0 }, // 0x60 - 0x63 + { 0x20, 0 }, { 0x12, 0 }, { 0x21, 0 }, { 0x22, 0 }, // 0x64 - 0x67 + { 0x23, 0 }, { 0x17, 0 }, { 0x24, 0 }, { 0x25, 0 }, // 0x68 - 0x6B + { 0x26, 0 }, { 0x32, 0 }, { 0x31, 0 }, { 0x18, 0 }, // 0x6C - 0x6F + { 0x19, 0 }, { 0x10, 0 }, { 0x13, 0 }, { 0x1F, 0 }, // 0x70 - 0x73 + { 0x14, 0 }, { 0x16, 0 }, { 0x2F, 0 }, { 0x11, 0 }, // 0x74 - 0x77 + { 0x2D, 0 }, { 0x15, 0 }, { 0x2C, 0 }, { 0x1A, 1 }, // 0x78 - 0x7B + { 0x2B, 1 }, { 0x1B, 1 }, { 0x29, 1 }, { 0x0E, 0 } // 0x7C - 0x7F +}; + + + +#define writeit(fd,c) do { if (debug_enable) { fprintf(stderr,"scancode 0x%x\n",(c));} if (write((fd),&(c),1)!=1) { return -1; } } while (0) + +int send_char_to_palacios_as_scancodes(int fd, TermKeyKey * kc) +{ + unsigned char sc; + + if (debug_enable) { + fprintf(stderr,"key '%c'\n",kc->code.number); + } + + if (kc->code.number == 'x' && + kc->modifiers & TERMKEY_KEYMOD_CTRL && + kc->modifiers & TERMKEY_KEYMOD_ALT) { + return VCONS_EXIT; + } else if (kc->code.number == 'c' && + //kc->modifiers & TERMKEY_KEYMOD_CTRL && + kc->modifiers & TERMKEY_KEYMOD_ALT) { + return VCONS_CTRLC; + } + + if (kc->code.number<0x80) { + struct key_code k = ascii_to_key_code[kc->code.number]; + + if (k.scan_code==0 && k.capital==0) { + if (debug_enable) { + fprintf(stderr,"Cannot send key '%c' to palacios as it maps to no scancode\n",kc->code.number); + } + } else { + + if (kc->modifiers & TERMKEY_KEYMOD_CTRL) { + sc = 0x1d; + writeit(fd, sc); + } + + if (kc->modifiers & TERMKEY_KEYMOD_ALT) { + sc = 0x38; + writeit(fd, sc); + } + + if (k.capital) { + //shift down + sc = 0x2a ; // left shift down + writeit(fd,sc); + } + + sc = k.scan_code; + + writeit(fd,sc); // key down + + sc |= 0x80; // key up + + writeit(fd,sc); + + if (k.capital) { + sc = 0x2a | 0x80; + writeit(fd,sc); + } + + if (kc->modifiers & TERMKEY_KEYMOD_CTRL) { + sc = 0x1d | 0x80; // left ctrl up + writeit(fd,sc); + } + + if (kc->modifiers & TERMKEY_KEYMOD_ALT) { + sc = 0x38 | 0x80; // left alt up + writeit(fd, sc); + } + } + + } else { + + + if (debug_enable) { + fprintf(stderr,"Cannot send key '%c' to palacios because it is >=0x80\n",kc->code.number); + } + + + } + return 0; +} + + +static int handle_fnkey (int fd, TermKeyKey * kc) { + + unsigned char sc; + + switch (kc->code.number) { + case 0x1: + sc = 0x3b; + break; + case 0x2: + sc = 0x3c; + break; + case 0x3: + sc = 0x3d; + break; + case 0x4: + sc = 0x3e; + break; + case 0x5: + sc = 0x3f; + break; + case 0x6: + sc = 0x40; + break; + case 0x7: + sc = 0x41; + break; + case 0x8: + sc = 0x42; + break; + case 0x9: + sc = 0x43; + break; + case 0xa: + sc = 0x44; + break; + case 0xb: + // this is a ctrl+c sequence + if (kc->modifiers & TERMKEY_KEYMOD_CTRL) { + return VCONS_CTRLC; + } + sc = 0x57; + break; + case 0xc: + // this is an exit sequence + if (kc->modifiers & TERMKEY_KEYMOD_CTRL) { + return VCONS_EXIT; + } + sc = 0x58; + break; + default: + fprintf(stderr, "Unknown function key <%x>\n", kc->code.number); + break; + } + + writeit(fd, sc); + + sc |= 0x80; + + writeit(fd, sc); + + return 0; +} + +static int handle_symkey (int fd, TermKeyKey * kc) { + unsigned char sc; + + switch (kc->code.sym) { + case TERMKEY_SYM_BACKSPACE: + sc = 0xe; + break; + case TERMKEY_SYM_TAB: + sc = 0xf; + break; + case TERMKEY_SYM_ENTER: + sc = 0x1c; + break; + case TERMKEY_SYM_ESCAPE: + sc = 0x1; + break; + case TERMKEY_SYM_SPACE: + sc = 0x39; + break; + case TERMKEY_SYM_INSERT: + sc = 0x52; + break; + case TERMKEY_SYM_DEL: + sc = 0x53; + break; + case TERMKEY_SYM_UP: + sc = 0x48; + break; + case TERMKEY_SYM_DOWN: + sc = 0x50; + break; + case TERMKEY_SYM_LEFT: + sc = 0x4b; + break; + case TERMKEY_SYM_RIGHT: + sc = 0x4d; + break; + case TERMKEY_SYM_PAGEUP: + sc = 0x49; + break; + case TERMKEY_SYM_PAGEDOWN: + sc = 0x51; + break; + case TERMKEY_SYM_HOME: + sc = 0x47; + break; + case TERMKEY_SYM_END: + sc = 0x4f; + break; + case TERMKEY_SYM_KP0: + sc = 0x70; + break; + case TERMKEY_SYM_KP1: + sc = 0x69; + break; + case TERMKEY_SYM_KP2: + sc = 0x72; + break; + case TERMKEY_SYM_KP3: + sc = 0x7a; + break; + case TERMKEY_SYM_KP4: + sc = 0x6b; + break; + case TERMKEY_SYM_KP5: + sc = 0x73; + break; + case TERMKEY_SYM_KP6: + sc = 0x74; + break; + case TERMKEY_SYM_KP7: + sc = 0x6c; + break; + case TERMKEY_SYM_KP8: + sc = 0x75; + break; + case TERMKEY_SYM_KP9: + sc = 0x7d; + break; + case TERMKEY_SYM_KPENTER: + sc = 0x5a; + break; + case TERMKEY_SYM_KPPLUS: + sc = 0x79; + break; + case TERMKEY_SYM_KPMINUS: + sc = 0x7b; + break; + case TERMKEY_SYM_KPMULT: + sc = 0x7c; + break; + case TERMKEY_SYM_KPDIV: + sc = 0x4a; + break; + default: + fprintf(stderr, "Unknown sym key\n"); + return; + } + + writeit(fd, sc); + + sc |= 0x80; + + writeit(fd, sc); + + return 0; + +} + + +#define MIN_TTY_COLS 80 +#define MIN_TTY_ROWS 25 +int check_terminal_size (void) +{ + unsigned short n_cols = 0; + unsigned short n_rows = 0; + struct winsize winsz; + + ioctl (fileno(stdin), TIOCGWINSZ, &winsz); + n_cols = winsz.ws_col; + n_rows = winsz.ws_row; + + if (n_cols < MIN_TTY_COLS || n_rows < MIN_TTY_ROWS) { + printf ("Your window is not large enough.\n"); + printf ("It must be at least %dx%d, but yours is %dx%d\n", + MIN_TTY_COLS, MIN_TTY_ROWS, n_cols, n_rows); + return (-1); + } + + /* SUCCESS */ + return (0); +} + + + +static void +init_colors (void) +{ + start_color(); + int i; + for (i = 0; i < 0x100; i++) { + init_pair(i, i & 0xf, (i >> 4) & 0xf); + } +} + + + +int main(int argc, char* argv[]) { + int vm_fd; + int cons_fd; + int mouse = 0; + int mouse_proto = 0; + char buffer[50]; + char * vm_dev = NULL; + struct termios termios; + TERMKEY_CHECK_VERSION; + TermKeyFormat format = TERMKEY_FORMAT_VIM; + tk = termkey_new(0, TERMKEY_FLAG_SPACESYMBOL|TERMKEY_FLAG_CTRLC); + + if (!tk) { + fprintf(stderr, "Could not allocate termkey instance\n"); + exit(EXIT_FAILURE); + } + + if (termkey_get_flags(tk) & TERMKEY_FLAG_UTF8) { + if (debug_enable) { + printf("Termkey in UTF-8 mode\n"); + } + } else if (termkey_get_flags(tk) & TERMKEY_FLAG_RAW) { + if (debug_enable) { + printf("Termkey in RAW mode\n"); + } + } + + TermKeyResult ret; + TermKeyKey key; + + if(mouse) { + printf("\033[?%dhMouse mode active\n", mouse); + if(mouse_proto) + printf("\033[?%dh", mouse_proto); + } + + use_curses = 1; + + if (argc < 2) { + printf("usage: v3_cons_sc \n\n" + "NOTE: to use CTRL-C within the terminal, use Alt-C\n" + " to exit the terminal, use CTRL-ALT-x\n\n"); + goto exit_err; + } + + /* Check for minimum Terminal size at start */ + if (0 != check_terminal_size()) { + printf ("Error: terminal too small!\n"); + goto exit_err; + } + + vm_dev = argv[1]; + + vm_fd = open(vm_dev, O_RDONLY); + + if (vm_fd == -1) { + printf("Error opening VM device: %s\n", vm_dev); + goto exit_err; + } + + cons_fd = ioctl(vm_fd, V3_VM_CONSOLE_CONNECT, NULL); + + /* Close the file descriptor. */ + close(vm_fd); + + if (cons_fd < 0) { + printf("Error opening stream Console\n"); + goto exit_err; + } + + atexit(handle_exit); + + console.x = 0; + console.y = 0; + + + if (use_curses) { + + gettmode(); + console.win = initscr(); + + if (console.win == NULL) { + fprintf(stderr, "Error initialization curses screen\n"); + exit(-1); + } + + scrollok(console.win, 1); + + erase(); + init_colors(); + } + + + raw(); + cbreak(); + noecho(); + keypad(console.win, TRUE); + + while (1) { + + int ret; + int bytes_read = 0; + fd_set rset; + + FD_ZERO(&rset); + FD_SET(cons_fd, &rset); + FD_SET(STDIN_FILENO, &rset); + + ret = select(cons_fd + 1, &rset, NULL, NULL, NULL); + + if (ret == 0) { + continue; + } else if (ret == -1) { + perror("Select returned error...\n"); + return -1; + } + + if (FD_ISSET(cons_fd, &rset)) { + if (handle_console_msg(cons_fd) == -1) { + printf("Console Error\n"); + return -1; + } + } + + if (FD_ISSET(STDIN_FILENO, &rset)) { + + ret = termkey_waitkey(tk, &key); + + if(ret == TERMKEY_RES_KEY) { + + termkey_strfkey(tk, buffer, sizeof buffer, &key, format); + + switch (key.type) { + + case TERMKEY_TYPE_UNICODE: { + + int ret = send_char_to_palacios_as_scancodes(cons_fd, &key); + + if (ret < 0) { + printf("Error sending key to console\n"); + return -1; + } else if (ret == VCONS_CTRLC) { + + unsigned char sc; + sc = 0x1d; // left ctrl down + writeit(cons_fd,sc); + sc = 0x2e; // c down + writeit(cons_fd,sc); + sc = 0x2e | 0x80; // c up + writeit(cons_fd,sc); + sc = 0x1d | 0x80; // left ctrl up + writeit(cons_fd,sc); + + } else if (ret == VCONS_EXIT) { + exit(1); + } + + break; + } + case TERMKEY_TYPE_FUNCTION: + handle_fnkey(cons_fd, &key); + break; + case TERMKEY_TYPE_KEYSYM: + handle_symkey(cons_fd, &key); + break; + default: + fprintf(stderr, "Unknown key type\n"); + } + } + + } + } + + erase(); + + printf("Console terminated\n"); + + close(cons_fd); + + return 0; + +exit_err: + termkey_destroy(tk); + return -1; +} + + diff --git a/linux_usr/v3_console b/linux_usr/v3_console index d14979b..3662d1d 100755 --- a/linux_usr/v3_console +++ b/linux_usr/v3_console @@ -1,11 +1,22 @@ #!/usr/bin/perl -w if ($#ARGV!=0) { - print "v3_console /dev/v3-vmXXX\n"; - print "Use '\\' to escape terminal\n\n"; - print "Use v3_cons if you are on a raw PC console\n"; - print "Use v3_vncclient if you are trying to connect to a v3_vncserver\n"; - exit; + print "v3_console /dev/v3-vmXXX\n"; + print "Use '\\' to escape terminal\n\n"; + print "Use v3_console if you are on a terminal and\n"; + print " want to connect to the VM's screen+keybaord\n"; + print " in text mode.\n"; + print "Use v3_cons if you are on a raw PC console and\n"; + print " want to connnect to the VM's screen+keyboard\n"; + print " in text mode.\n"; + print "Use v3_vncclient if you want to connect to the\n"; + print " VM's screen+keyboard in graphical mode.\n"; + print " This requires a v3_vncserver and an correctly\n"; + print " configured VM.\n"; + print "Use v3_stream if you are on a terminal and\n"; + print " want to connect to a stream on the VM, \n"; + print " for example a serial port.\n"; + exit; }