3 * Taken from Palacios console display in MINIX ( by Erik Van der Kouwe )
10 #include <sys/ioctl.h>
19 #include <linux/keyboard.h>
23 static int use_curses = 0;
24 static int debug_enable = 0;
27 typedef enum { CONSOLE_CURS_SET = 1,
31 CONSOLE_RESOLUTION = 5 } console_op_t;
41 struct termios termios_old;
42 unsigned char old_kbd_mode;
49 } __attribute__((packed));
51 struct character_msg {
56 } __attribute__((packed));
60 } __attribute__((packed));
62 struct resolution_msg {
65 } __attribute__((packed));
71 struct cursor_msg cursor;
72 struct character_msg character;
73 struct scroll_msg scroll;
74 struct resolution_msg resolution;
76 } __attribute__((packed));
81 static int handle_char_set(struct character_msg * msg) {
85 fprintf(stderr, "setting char (%c), at (x=%d, y=%d)\n", c, msg->x, msg->y);
93 if ((c < ' ') || (c >= 127)) {
94 fprintf(stderr, "unexpected control character %d\n", c);
99 /* clip whatever falls outside the visible area to avoid errors */
100 if ((msg->x < 0) || (msg->y < 0) ||
101 (msg->x > console.win->_maxx) ||
102 (msg->y > console.win->_maxy)) {
104 fprintf(stderr, "Char out of range (x=%d,y=%d) MAX:(x=%d,y=%d)\n",
105 msg->x, msg->y, console.win->_maxx, console.win->_maxy);
109 if ((msg->x == console.win->_maxx) &&
110 (msg->y == console.win->_maxy)) {
114 mvwaddch(console.win, msg->y, msg->x, c);
117 //stdout text display
118 while (console.y < msg->y) {
124 while (console.x < msg->x) {
132 assert(console.x <= console.cols);
134 if (console.x == console.cols) {
144 int handle_curs_set(struct cursor_msg * msg) {
146 fprintf(stderr, "cursor set: (x=%d, y=%d)\n", msg->x, msg->y);
150 /* nothing to do now, cursor is set before update to make sure it isn't
151 * affected by character_set
162 int handle_scroll(struct scroll_msg * msg) {
163 int lines = msg->lines;
166 fprintf(stderr, "scroll: %d lines\n", lines);
182 int handle_text_resolution(struct resolution_msg * msg) {
184 fprintf(stderr, "text resolution: rows=%d, cols=%d\n", msg->rows, msg->cols);
188 console.rows = msg->rows;
189 console.cols = msg->cols;
194 int handle_update( void ) {
196 fprintf(stderr, "update\n");
201 if ( (console.x >= 0) && (console.y >= 0) &&
202 (console.x <= console.win->_maxx) &&
203 (console.y <= console.win->_maxy) ) {
205 wmove(console.win, console.y, console.x);
209 wrefresh(console.win);
216 int handle_console_msg(int cons_fd) {
220 ret = read(cons_fd, &msg, sizeof(struct cons_msg));
223 case CONSOLE_CURS_SET:
224 // printf("Console cursor set (x=%d, y=%d)\n", msg.cursor.x, msg.cursor.y);
225 handle_curs_set(&(msg.cursor));
227 case CONSOLE_CHAR_SET:
228 handle_char_set(&(msg.character));
229 /* printf("Console character set (x=%d, y=%d, c=%c, style=%c)\n",
230 msg.character.x, msg.character.y, msg.character.c, msg.character.style);*/
233 // printf("Console scroll (lines=%d)\n", msg.scroll.lines);
234 handle_scroll(&(msg.scroll));
237 // printf("Console update\n");
240 case CONSOLE_RESOLUTION:
241 handle_text_resolution(&(msg.resolution));
244 printf("Invalid console message operation (%d)\n", msg.op);
252 int send_key(int cons_fd, char scan_code) {
259 void handle_exit(void) {
260 fprintf(stderr, "Exiting from console terminal\n");
266 tcsetattr(STDIN_FILENO, TCSANOW, &console.termios_old);
268 ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE);
271 int main(int argc, char* argv[]) {
274 char * vm_dev = NULL;
275 struct termios termios;
280 printf("usage: v3_cons <vm_device>\nThis will only work when run from a real PC console!\n");
288 vm_fd = open(vm_dev, O_RDONLY);
291 printf("Error opening VM device: %s\n", vm_dev);
295 cons_fd = ioctl(vm_fd, V3_VM_CONSOLE_CONNECT, NULL);
297 /* Close the file descriptor. */
301 printf("Error opening stream Console\n");
305 tcgetattr(STDIN_FILENO, &console.termios_old);
314 console.win = initscr();
316 if (console.win == NULL) {
317 fprintf(stderr, "Error initialization curses screen\n");
321 scrollok(console.win, 1);
325 termios = console.termios_old;
326 termios.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | IGNPAR);
327 termios.c_iflag &= ~(INLCR | INPCK | ISTRIP | IXOFF | IXON | PARMRK);
328 //termios.c_iflag &= ~(ICRNL | INLCR );
330 // termios.c_iflag |= SCANCODES;
331 // termios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
332 //termios.c_lflag &= ~(ICANON | IEXTEN | ISIG | NOFLSH);
333 termios.c_lflag &= ~(ICANON | ECHO);
335 termios.c_cc[VMIN] = 1;
336 termios.c_cc[VTIME] = 0;
338 tcflush(STDIN_FILENO, TCIFLUSH);
339 tcsetattr(STDIN_FILENO, TCSANOW, &termios);
345 keypad(console.win, TRUE);
347 ioctl(STDIN_FILENO, KDSKBMODE, K_RAW);
355 FD_SET(cons_fd, &rset);
356 FD_SET(STDIN_FILENO, &rset);
358 ret = select(cons_fd + 1, &rset, NULL, NULL, NULL);
360 // printf("Returned from select...\n");
364 } else if (ret == -1) {
365 perror("Select returned error...\n");
369 if (FD_ISSET(cons_fd, &rset)) {
370 if (handle_console_msg(cons_fd) == -1) {
371 printf("Console Error\n");
376 if (FD_ISSET(STDIN_FILENO, &rset)) {
377 unsigned char key = getch();
379 if (key == 0x01) { // ESC
383 if (write(cons_fd, &key, 1) != 1) {
384 fprintf(stderr, "ERrror sendign key to console\n");