Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel' of newskysaw.cs.northwestern.edu:/home/palacios/palacios into...
[palacios.git] / linux_usr / v3_cons_sc.c
1 /* 
2  * V3 Console utility
3  * Taken from Palacios console display in MINIX ( by Erik Van der Kouwe )
4  * (c) Jack lange, 2010
5  */
6
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <sys/ioctl.h> 
11 #include <errno.h>
12 #include <assert.h>
13 #include <string.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 #include <curses.h>
17 #include <termios.h>
18 #include <linux/kd.h>
19 #include <linux/keyboard.h>
20
21 #include "v3_ctrl.h"
22
23 static int use_curses = 0;
24 static int debug_enable = 1;
25
26
27 typedef enum { CONSOLE_CURS_SET = 1,
28                CONSOLE_CHAR_SET = 2,
29                CONSOLE_SCROLL = 3,
30                CONSOLE_UPDATE = 4,
31                CONSOLE_RESOLUTION = 5 } console_op_t;
32
33
34
35 static struct {
36     WINDOW * win;
37     int x;
38     int y;
39     int rows;
40     int cols;
41     struct termios termios_old;
42     unsigned char old_kbd_mode;
43 } console;
44
45
46 struct cursor_msg {
47     int x;
48     int y;
49 } __attribute__((packed));
50
51 struct character_msg {
52     int x;
53     int y;
54     char c;
55     unsigned char style;
56 } __attribute__((packed));
57
58 struct scroll_msg {
59     int lines;
60 } __attribute__((packed));
61
62 struct resolution_msg {
63     int cols;
64     int rows;
65 } __attribute__((packed));
66
67
68 struct cons_msg {
69     unsigned char op;
70     union {
71         struct cursor_msg cursor;
72         struct character_msg  character;
73         struct scroll_msg scroll;
74         struct resolution_msg resolution;
75     };
76 } __attribute__((packed)); 
77
78
79
80
81 static int handle_char_set(struct character_msg * msg) {
82     char c = msg->c;
83
84     if (debug_enable) {
85         fprintf(stderr, "setting char (%c), at (x=%d, y=%d)\n", c, msg->x, msg->y);
86     }
87
88     if (c == 0) {
89         c = ' ';
90     }
91
92
93     if ((c < ' ') || (c >= 127)) {
94         fprintf(stderr, "unexpected control character %d\n", c);
95         c = '?';
96     }
97
98     if (use_curses) {
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)) {
103
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);
106             return -1;
107         }
108
109         if ((msg->x == console.win->_maxx) &&
110             (msg->y == console.win->_maxy)) {
111             return -1;
112         }
113
114         mvwaddch(console.win, msg->y, msg->x, c);
115
116     } else {
117         //stdout text display
118         while (console.y < msg->y) {
119             printf("\n");
120             console.x = 0;
121             console.y++;
122         }
123
124         while (console.x < msg->x) {
125             printf(" ");
126             console.x++;
127         }
128
129         printf("%c", c);
130         console.x++;
131
132         assert(console.x <= console.cols); 
133
134         if (console.x == console.cols) {
135             printf("\n");
136             console.x = 0;
137             console.y++;
138         }
139     }
140
141     return 0;
142 }
143
144 int handle_curs_set(struct cursor_msg * msg) {
145     if (debug_enable) {
146         fprintf(stderr, "cursor set: (x=%d, y=%d)\n", msg->x, msg->y);
147     }
148
149     if (use_curses) {
150         /* nothing to do now, cursor is set before update to make sure it isn't 
151          * affected by character_set
152          */
153
154         console.x = msg->x;
155         console.y = msg->y;
156     }
157     
158     return 0;
159 }
160
161
162 int handle_scroll(struct scroll_msg * msg) {
163     int lines = msg->lines;
164
165     if (debug_enable) {
166         fprintf(stderr, "scroll: %d lines\n", lines);
167     }
168
169
170     assert(lines >= 0);
171
172     if (use_curses) {
173         while (lines > 0) {
174             scroll(console.win);
175             lines--;
176         }
177     } else {
178         console.y -= lines;     
179     }
180 }
181
182 int handle_text_resolution(struct resolution_msg * msg) {
183     if (debug_enable) {
184         fprintf(stderr, "text resolution: rows=%d, cols=%d\n", msg->rows, msg->cols);
185     }
186
187
188     console.rows = msg->rows;
189     console.cols = msg->cols;
190
191     return 0;
192 }
193
194 int handle_update( void ) {
195     if (debug_enable) {
196         fprintf(stderr, "update\n");
197     }    
198
199     if (use_curses) {
200
201         if ( (console.x >= 0) && (console.y >= 0) &&
202              (console.x <= console.win->_maxx) &&
203              (console.y <= console.win->_maxy) ) {
204
205             wmove(console.win, console.y, console.x);
206
207         }
208
209         wrefresh(console.win);
210     } else {
211         fflush(stdout);
212     }
213 }
214
215
216 int handle_console_msg(int cons_fd) {
217     int ret = 0;
218     struct cons_msg msg;
219
220     ret = read(cons_fd, &msg, sizeof(struct cons_msg));
221
222     switch (msg.op) {
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));
226             break;
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);*/
231             break;
232         case CONSOLE_SCROLL:
233             //  printf("Console scroll (lines=%d)\n", msg.scroll.lines);
234             handle_scroll(&(msg.scroll));
235             break;
236         case CONSOLE_UPDATE:
237             // printf("Console update\n");
238             handle_update();
239             break;
240         case CONSOLE_RESOLUTION:
241             handle_text_resolution(&(msg.resolution));
242             break;
243         default:
244             printf("Invalid console message operation (%d)\n", msg.op);
245             break;
246     }
247
248     return 0;
249 }
250
251
252 int send_key(int cons_fd, char scan_code) {
253
254     return 0;
255 }
256
257
258
259 void handle_exit(void) {
260     fprintf(stderr, "Exiting from console terminal\n");
261
262     if (use_curses) {
263         endwin();
264     }
265
266     //    tcsetattr(STDIN_FILENO, TCSANOW, &console.termios_old);
267
268     // ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE);
269 }
270
271
272 #define NO_KEY { 0, 0 }
273
274 struct key_code {
275     unsigned char scan_code;
276     unsigned char capital;
277 };
278
279 static const struct key_code ascii_to_key_code[] = {             // ASCII Value Serves as Index
280     NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x00 - 0x03
281     NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x04 - 0x07
282     { 0x0E, 0 },    { 0x0F, 0 },    { 0x1C, 0 },    NO_KEY,      // 0x08 - 0x0B
283     NO_KEY,         { 0x1C, 0 },    NO_KEY,         NO_KEY,      // 0x0C - 0x0F
284     NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x10 - 0x13
285     NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x14 - 0x17
286     NO_KEY,         NO_KEY,         NO_KEY,         { 0x01, 0 }, // 0x18 - 0x1B
287     NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x1C - 0x1F
288     { 0x39, 0 },    { 0x02, 1 },    { 0x28, 1 },    { 0x04, 1 }, // 0x20 - 0x23
289     { 0x05, 1 },    { 0x06, 1 },    { 0x08, 1 },    { 0x28, 0 }, // 0x24 - 0x27
290     { 0x0A, 1 },    { 0x0B, 1 },    { 0x09, 1 },    { 0x0D, 1 }, // 0x28 - 0x2B
291     { 0x33, 0 },    { 0x0C, 0 },    { 0x34, 0 },    { 0x35, 0 }, // 0x2C - 0x2F
292     { 0x0B, 0 },    { 0x02, 0 },    { 0x03, 0 },    { 0x04, 0 }, // 0x30 - 0x33
293     { 0x05, 0 },    { 0x06, 0 },    { 0x07, 0 },    { 0x08, 0 }, // 0x34 - 0x37
294     { 0x09, 0 },    { 0x0A, 0 },    { 0x27, 1 },    { 0x27, 0 }, // 0x38 - 0x3B
295     { 0x33, 1 },    { 0x0D, 0 },    { 0x34, 1 },    { 0x35, 1 }, // 0x3C - 0x3F
296     { 0x03, 1 },    { 0x1E, 1 },    { 0x30, 1 },    { 0x2E, 1 }, // 0x40 - 0x43
297     { 0x20, 1 },    { 0x12, 1 },    { 0x21, 1 },    { 0x22, 1 }, // 0x44 - 0x47
298     { 0x23, 1 },    { 0x17, 1 },    { 0x24, 1 },    { 0x25, 1 }, // 0x48 - 0x4B
299     { 0x26, 1 },    { 0x32, 1 },    { 0x31, 1 },    { 0x18, 1 }, // 0x4C - 0x4F
300     { 0x19, 1 },    { 0x10, 1 },    { 0x13, 1 },    { 0x1F, 1 }, // 0x50 - 0x53
301     { 0x14, 1 },    { 0x16, 1 },    { 0x2F, 1 },    { 0x11, 1 }, // 0x54 - 0x57
302     { 0x2D, 1 },    { 0x15, 1 },    { 0x2C, 1 },    { 0x1A, 0 }, // 0x58 - 0x5B
303     { 0x2B, 0 },    { 0x1B, 0 },    { 0x07, 1 },    { 0x0C, 1 }, // 0x5C - 0x5F
304     { 0x29, 0 },    { 0x1E, 0 },    { 0x30, 0 },    { 0x2E, 0 }, // 0x60 - 0x63
305     { 0x20, 0 },    { 0x12, 0 },    { 0x21, 0 },    { 0x22, 0 }, // 0x64 - 0x67
306     { 0x23, 0 },    { 0x17, 0 },    { 0x24, 0 },    { 0x25, 0 }, // 0x68 - 0x6B
307     { 0x26, 0 },    { 0x32, 0 },    { 0x31, 0 },    { 0x18, 0 }, // 0x6C - 0x6F
308     { 0x19, 0 },    { 0x10, 0 },    { 0x13, 0 },    { 0x1F, 0 }, // 0x70 - 0x73
309     { 0x14, 0 },    { 0x16, 0 },    { 0x2F, 0 },    { 0x11, 0 }, // 0x74 - 0x77
310     { 0x2D, 0 },    { 0x15, 0 },    { 0x2C, 0 },    { 0x1A, 1 }, // 0x78 - 0x7B
311     { 0x2B, 1 },    { 0x1B, 1 },    { 0x29, 1 },    { 0x0E, 0 }  // 0x7C - 0x7F
312 };
313
314
315
316 #define writeit(fd,c)  do { fprintf(stderr,"scancode 0x%x\n",(c)); if (write((fd),&(c),1)!=1) { return -1; } } while (0)
317
318 int send_char_to_palacios_as_scancodes(int fd, unsigned char c)
319 {
320     unsigned char sc;
321
322     fprintf(stderr,"key '%c'\n",c);
323
324     if (c<0x80) { 
325         struct key_code k = ascii_to_key_code[c];
326         
327         if (k.scan_code==0 && k.capital==0) { 
328             fprintf(stderr,"Cannot send key '%c' to palacios as it maps to no scancode\n",c);
329         } else {
330             if (k.capital) { 
331                 //shift down
332                 sc = 0x2a ; // left shift down
333                 writeit(fd,sc);
334             }
335             
336             
337             sc = k.scan_code;
338             
339             writeit(fd,sc);  // key down
340             
341             sc |= 0x80;      // key up
342             
343             writeit(fd,sc);
344             
345             if (k.capital) { 
346                 sc = 0x2a | 0x80;
347                 writeit(fd,sc);
348             }
349         }
350             
351     } else {
352
353
354         fprintf(stderr,"Cannot send key '%c' to palacios because it is >=0x80\n",c);
355
356 /*      switch (key) {  */
357 /*          case 0xffe1:  //left shift */
358 /*              scancode = 0x2a; */
359 /*              break; */
360
361 /*          case 0xffe2:  //right shift */
362 /*              scancode = 0x36; */
363 /*              break; */
364
365 /*          case 0xffe3:  //left ctrl */
366 /*          case 0xffe4:  //right ctrl */
367 /*              scancode = 0x1d;   // translated as left ctrl */
368 /*              break; */
369
370 /*          case 0xffe7:  //left meta */
371 /*          case 0xffe8:  //right meta */
372 /*          case 0xffe9:  //left alt */
373 /*          case 0xffea:  //right alt */
374 /*              scancode = 0x38;  // translated as a left alt */
375 /*              break;  */
376
377 /*          case 0xff08: // backspace */
378 /*              scancode = 0x0e; */
379 /*              break;  */
380
381 /*          case 0xff09: // tab */
382 /*              scancode = 0x0f;   */
383 /*              break;  */
384
385 /*          case 0xff0d: // return */
386 /*              scancode = 0x1c; */
387 /*              break;  */
388
389 /*          case 0xff1b: // escape */
390 /*              scancode = 0x01; */
391 /*              break;  */
392
393 /*          case 0xff63: // insert */
394 /*              scancode = 0x52; */
395 /*              break;  */
396
397 /*          case 0xffff: // delete */
398 /*              scancode = 0x53; */
399 /*              break;  */
400
401 /*          case 0xff50: // home */
402 /*              scancode = 0x47; */
403 /*              break;  */
404
405 /*          case 0xff57: // end */
406 /*              scancode = 0x4f; */
407 /*              break;  */
408                 
409 /*          case 0xff55: // pageup */
410 /*              scancode = 0x49; */
411 /*              break;  */
412
413 /*          case 0xff56: // pagedown */
414 /*              scancode = 0x51; */
415 /*              break;  */
416
417 /*          case 0xff51: // left */
418 /*              scancode = 0x4b; */
419 /*              break;  */
420
421 /*          case 0xff52: // up */
422 /*              scancode = 0x48; */
423 /*              break;  */
424
425 /*          case 0xff53: // right */
426 /*              scancode = 0x4d; */
427 /*              break;  */
428
429 /*          case 0xff54: // down */
430 /*              scancode = 0x50; */
431 /*              break;  */
432
433 /*          case 0xffbe: // f1 */
434 /*              scancode = 0x3b; */
435 /*              break;  */
436 /*          case 0xffbf: // f2 */
437 /*              scancode = 0x3c; */
438 /*              break;  */
439 /*          case 0xffc0: // f3 */
440 /*              scancode = 0x3d; */
441 /*              break;  */
442 /*          case 0xffc1: // f4 */
443 /*              scancode = 0x3e; */
444 /*              break;  */
445 /*          case 0xffc2: // f5 */
446 /*              scancode = 0x3f; */
447 /*              break;  */
448 /*          case 0xffc3: // f6 */
449 /*              scancode = 0x40; */
450 /*              break;  */
451 /*          case 0xffc4: // f7 */
452 /*              scancode = 0x41; */
453 /*              break;  */
454 /*          case 0xffc5: // f8 */
455 /*              scancode = 0x42; */
456 /*              break;  */
457 /*          case 0xffc6: // f9 */
458 /*              scancode = 0x43; */
459 /*              break; */
460 /*          case 0xffc7: // f10 */
461 /*              scancode = 0x44; */
462 /*              break;  */
463 /*          case 0xffc8: // f11 */
464 /*              scancode = 0x57; */
465 /*              break;  */
466 /*          case 0xffc9: // f12 */
467 /*              scancode = 0x58; */
468 /*              break;  */
469
470
471 /*          default: */
472 /*              scancode = 0; */
473 /*              fprintf(stderr,"Ignoring key 0x%x (down=%d)\n", key, down); */
474 /*      } */
475 /*     } */
476     
477 /*     if (scancode==0) {  */
478 /*      return 0; */
479 /*     } */
480         
481         
482 /*     return scancode; */
483         
484     }
485     return 0;
486 }
487     
488 int main(int argc, char* argv[]) {
489     int vm_fd;
490     int cons_fd;
491     char * vm_dev = NULL;
492     struct termios termios;
493
494     use_curses = 1;
495
496     if (argc < 2) {
497         printf("Usage: ./v3_cons <vm_device>\n");
498         return -1;
499     }
500
501     vm_dev = argv[1];
502
503
504
505     vm_fd = open(vm_dev, O_RDONLY);
506
507     if (vm_fd == -1) {
508         printf("Error opening VM device: %s\n", vm_dev);
509         return -1;
510     }
511
512     cons_fd = ioctl(vm_fd, V3_VM_CONSOLE_CONNECT, NULL); 
513
514     /* Close the file descriptor.  */ 
515     close(vm_fd); 
516
517     if (cons_fd < 0) {
518         printf("Error opening stream Console\n");
519         return -1;
520     }
521
522     tcgetattr(STDIN_FILENO, &console.termios_old);
523     atexit(handle_exit);
524
525     console.x = 0;
526     console.y = 0;
527
528
529     if (use_curses) {
530         gettmode();
531         console.win = initscr();
532         
533         if (console.win == NULL) {
534             fprintf(stderr, "Error initialization curses screen\n");
535             exit(-1);
536         }
537
538         scrollok(console.win, 1);
539     }
540
541     /*
542     termios = console.termios_old;
543     termios.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | IGNPAR);
544     termios.c_iflag &= ~(INLCR | INPCK | ISTRIP | IXOFF | IXON | PARMRK); 
545     //termios.c_iflag &= ~(ICRNL | INLCR );    
546
547     //  termios.c_iflag |= SCANCODES; 
548     //    termios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); 
549     //termios.c_lflag &= ~(ICANON | IEXTEN | ISIG | NOFLSH);
550     termios.c_lflag &= ~(ICANON | ECHO);
551
552     termios.c_cc[VMIN] = 1;
553     termios.c_cc[VTIME] = 0;
554
555     tcflush(STDIN_FILENO, TCIFLUSH);
556     tcsetattr(STDIN_FILENO, TCSANOW, &termios);
557     */    
558
559     raw();
560     cbreak();
561     noecho();
562     keypad(console.win, TRUE);
563
564     //ioctl(STDIN_FILENO, KDSKBMODE, K_RAW);
565
566     while (1) {
567         int ret; 
568         int bytes_read = 0;
569         fd_set rset;
570
571         FD_ZERO(&rset);
572         FD_SET(cons_fd, &rset);
573         FD_SET(STDIN_FILENO, &rset);
574
575         ret = select(cons_fd + 1, &rset, NULL, NULL, NULL);
576         
577         //      printf("Returned from select...\n");
578
579         if (ret == 0) {
580             continue;
581         } else if (ret == -1) {
582             perror("Select returned error...\n");
583             return -1;
584         }
585
586         if (FD_ISSET(cons_fd, &rset)) {
587             if (handle_console_msg(cons_fd) == -1) {
588                 printf("Console Error\n");
589                 return -1;
590             }
591         }
592
593         if (FD_ISSET(STDIN_FILENO, &rset)) {
594             unsigned char key = getch();
595
596             if (key == '\\') { // ESC
597                 break;
598             } else if (key == '`') {
599                 unsigned char sc = 0x44; // F10
600                 writeit(cons_fd,sc);
601                 sc |= 0x80;
602                 writeit(cons_fd,sc);
603             }else {
604                 if (send_char_to_palacios_as_scancodes(cons_fd,key)) {
605                     fprintf(stderr, "Error sendign key to console\n");
606                     return -1;
607                 }
608             }
609             
610         }
611     } 
612
613     close(cons_fd);
614
615     return 0; 
616 }
617
618