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.


Further text-mode console client enhancements
Peter Dinda [Thu, 14 Jul 2016 00:09:43 +0000 (19:09 -0500)]
- cleanup of color handling in both curses clients
- v3_cons_tc cleanup for function key, etc, handling
- v3_console selects the better of _tc and _sc depending
  on which have been built in the instalation

linux_usr/v3_cons_sc.c
linux_usr/v3_cons_tc.c
linux_usr/v3_console

index 9419804..6272357 100644 (file)
 
 #include "v3_ctrl.h"
 
+static int in_color = 0;
+static int color8 = 0;
+#define TRANS_STYLE(x) ( !color8 ? (x) : ((x)&0x7)|(((x)&0x70)>>1))
+
 static int use_curses = 0;
 static int debug_enable = 0;
 
@@ -117,9 +121,9 @@ static int handle_char_set(struct character_msg * msg) {
            return -1;
        }
 
-        wattron(console.win, COLOR_PAIR(msg->style));
+       if (in_color) {wattron(console.win,  COLOR_PAIR(TRANS_STYLE(msg->style)));}
        mvwaddch(console.win, msg->y, msg->x, c);
-        wattroff(console.win, COLOR_PAIR(msg->style));
+       if (in_color) {wattroff(console.win, COLOR_PAIR(TRANS_STYLE(msg->style)));}
 
     } else {
        //stdout text display
@@ -403,10 +407,59 @@ int check_terminal_size (void)
 static void
 init_colors (void)
 {
+    unsigned short i;
+
+    if (!has_colors()) {
+      fprintf(stderr,"No color support\n");
+      in_color=0;
+      color8=0;
+      return;
+    }
+    
     start_color();
-    int i;
-    for (i = 0; i < 0x100; i++) {
-        init_pair(i, i & 0xf, (i >> 4) & 0xf);
+
+    if (can_change_color() && COLORS>=16 && COLOR_PAIRS>=256) {
+      fprintf(stderr, "Modifyable color support with enough colors available\n");
+      // initialize first 16 colors to be the PC colors
+      // then create all the pairings
+      for (i=0;i<16;i++) {
+       unsigned short red, green, blue, intens;
+       // i = IRGB (4 bits)
+       intens = i>>3 & 0x1;
+       red = i>>2 & 0x1;
+       green = i>>1 & 0x1;
+       blue = i>>0 & 0x1;
+       init_color(i, 500*(red+intens), 500*(blue+intens), 500*(green+intens));
+      }
+      for (i=0;i<256;i++) {
+       init_pair(i, i & 0xf, (i >> 4) & 0xf);
+      }
+      in_color = 1;
+      color8 = 0;
+      return;
+    } else {
+      if (COLORS!=8 || COLOR_PAIRS<64) {
+       fprintf(stderr,"Insufficient number of fixed colors (%d) or color pairs (%d)\n",COLORS,COLOR_PAIRS);
+       in_color = 0;
+       color8 = 0;
+       return;
+      } 
+      // We have only the low-intensity colors available, so
+      // map just to these
+      fprintf(stderr,"Only 8 color standard palette available\n");
+      for (i=0;i<64;i++) {
+       // VGA color order:     black, blue, green, cyan, red, magenta, brown, gray
+       // curses color order:  black, red, green, yellow, blue, magenta, cyan, white
+       short map[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+       unsigned short fg, bg;
+       // discard intensity bit
+       bg = (i>>3 & 0x7);
+       fg = i & 0x7; 
+       init_pair(i, map[fg], map[bg]);
+      }
+      in_color = 1;
+      color8 = 1;
+      return;
     }
 }
 
@@ -468,7 +521,8 @@ int main(int argc, char* argv[]) {
        scrollok(console.win, 1);
 
        erase();
-    init_colors();
+       init_colors();
+       //abort();
     }
 
     /*
index 5171a6a..0d85a97 100644 (file)
 #include "v3_ctrl.h"
 #include "termkey.h"
 
+static int in_color = 0;
+static int color8 = 0;
+#define TRANS_STYLE(x) ( !color8 ? (x) : ((x)&0x7)|(((x)&0x70)>>1))
+
 static int use_curses = 0;
 static int debug_enable = 0;
 
+static int ctrlc_count = 0;
 
 #define VCONS_EXIT  2
 #define VCONS_CTRLC 3
@@ -123,9 +128,9 @@ static int handle_char_set(struct character_msg * msg) {
            return -1;
        }
 
-    wattron(console.win, COLOR_PAIR(msg->style));
+       if (in_color) {wattron(console.win,  COLOR_PAIR(TRANS_STYLE(msg->style)));}
        mvwaddch(console.win, msg->y, msg->x, c);
-    wattroff(console.win, COLOR_PAIR(msg->style));
+       if (in_color) {wattroff(console.win, COLOR_PAIR(TRANS_STYLE(msg->style)));}
 
     } else {
        //stdout text display
@@ -263,12 +268,6 @@ int handle_console_msg(int cons_fd) {
 }
 
 
-int send_key(int cons_fd, char can_code) {
-
-    return 0;
-}
-
-
 
 void handle_exit(void) {
     if ( debug_enable ) {
@@ -332,7 +331,59 @@ static const struct key_code ascii_to_key_code[] = {             // ASCII Value
 
 #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)
+
+int send_scancode_group_to_palacios(int fd, TermKeyKey * kc, struct key_code *k)
+{
+  unsigned char sc;
+
+  if (kc->modifiers & TERMKEY_KEYMOD_CTRL) {
+    // left ctrl down
+    sc = 0x1d;
+    writeit(fd, sc);
+  }
+
+  if (kc->modifiers & TERMKEY_KEYMOD_ALT) {
+    // left alt down
+    sc = 0x38;
+    writeit(fd, sc);
+  }
+
+  if (k->capital) { 
+    // left shift down
+    sc = 0x2a ; 
+    writeit(fd,sc);
+  }
+
+  sc = k->scan_code;
+  
+  writeit(fd,sc);  // key down
+
+  sc |= 0x80;      // key up
+
+  writeit(fd,sc);
+
+  if (k->capital) { 
+    // left shift up
+    sc = 0x2a | 0x80;
+    writeit(fd,sc);
+  }
+  
+  if (kc->modifiers & TERMKEY_KEYMOD_CTRL) {
+    // left ctrl up
+    sc = 0x1d | 0x80;   
+    writeit(fd,sc);
+  }
+  
+  if (kc->modifiers & TERMKEY_KEYMOD_ALT) {
+    // left alt up
+    sc = 0x38 | 0x80; 
+    writeit(fd, sc);
+  }
+
+  return 0;
+}
+
+int handle_key(int fd, TermKeyKey * kc)
 {
     unsigned char sc;
 
@@ -340,15 +391,6 @@ int send_char_to_palacios_as_scancodes(int fd, TermKeyKey * kc)
         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];
@@ -357,58 +399,16 @@ int send_char_to_palacios_as_scancodes(int fd, TermKeyKey * kc)
             if (debug_enable) { 
                 fprintf(stderr,"Cannot send key '%c' to palacios as it maps to no scancode\n",kc->code.number);
             }
+           return 0;
         } 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);
-            }
-        }
-
+         return send_scancode_group_to_palacios(fd,kc,&k);
+       }
     } else {
-
-
         if (debug_enable) { 
             fprintf(stderr,"Cannot send key '%c' to palacios because it is >=0x80\n",kc->code.number);
         }
-
-
+       return 0;
     }
-    return 0;
 }
 
 
@@ -448,17 +448,9 @@ static int handle_fnkey (int fd, TermKeyKey * kc) {
             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:
@@ -466,13 +458,10 @@ static int handle_fnkey (int fd, TermKeyKey * kc) {
             break;
     }
 
-    writeit(fd, sc);
-
-    sc |= 0x80;
+    struct key_code k = { sc,  kc->modifiers & TERMKEY_KEYMOD_SHIFT };
 
-    writeit(fd, sc);
+    return send_scancode_group_to_palacios(fd,kc,&k);
 
-    return 0;
 }
 
 static int handle_symkey (int fd, TermKeyKey * kc) {
@@ -571,16 +560,14 @@ static int handle_symkey (int fd, TermKeyKey * kc) {
             break;
         default:
             fprintf(stderr, "Unknown sym key\n");
-            return;
+            return -1;
     }
+    
 
-    writeit(fd, sc);
-
-    sc |= 0x80;
+    struct key_code k = { sc,  kc->modifiers & TERMKEY_KEYMOD_SHIFT };
 
-    writeit(fd, sc);
+    return send_scancode_group_to_palacios(fd,kc,&k);
 
-    return 0;
 
 }
 
@@ -613,15 +600,63 @@ int check_terminal_size (void)
 static void
 init_colors (void)
 {
+    unsigned short i;
+
+    if (!has_colors()) {
+      fprintf(stderr,"No color support\n");
+      in_color=0;
+      color8=0;
+      return;
+    }
+    
     start_color();
-    int i;
-    for (i = 0; i < 0x100; i++) {
-        init_pair(i, i & 0xf, (i >> 4) & 0xf);
+
+    if (can_change_color() && COLORS>=16 && COLOR_PAIRS>=256) {
+      fprintf(stderr, "Modifyable color support with enough colors available\n");
+      // initialize first 16 colors to be the PC colors
+      // then create all the pairings
+      for (i=0;i<16;i++) {
+       unsigned short red, green, blue, intens;
+       // i = IRGB (4 bits)
+       intens = i>>3 & 0x1;
+       red = i>>2 & 0x1;
+       green = i>>1 & 0x1;
+       blue = i>>0 & 0x1;
+       init_color(i, 500*(red+intens), 500*(blue+intens), 500*(green+intens));
+      }
+      for (i=0;i<256;i++) {
+       init_pair(i, i & 0xf, (i >> 4) & 0xf);
+      }
+      in_color = 1;
+      color8 = 0;
+      return;
+    } else {
+      if (COLORS!=8 || COLOR_PAIRS<64) {
+       fprintf(stderr,"Insufficient number of fixed colors (%d) or color pairs (%d)\n",COLORS,COLOR_PAIRS);
+       in_color = 0;
+       color8 = 0;
+       return;
+      } 
+      // We have only the low-intensity colors available, so
+      // map just to these
+      fprintf(stderr,"Only 8 color standard palette available\n");
+      for (i=0;i<64;i++) {
+       // VGA color order:     black, blue, green, cyan, red, magenta, brown, gray
+       // curses color order:  black, red, green, yellow, blue, magenta, cyan, white
+       short map[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+       unsigned short fg, bg;
+       // discard intensity bit
+       bg = (i>>3 & 0x7);
+       fg = i & 0x7; 
+       init_pair(i, map[fg], map[bg]);
+      }
+      in_color = 1;
+      color8 = 1;
+      return;
     }
 }
 
 
-
 int main(int argc, char* argv[]) {
     int vm_fd;
     int cons_fd;
@@ -661,9 +696,8 @@ int main(int argc, char* argv[]) {
     use_curses = 1;
 
     if (argc < 2) {
-        printf("usage: v3_cons_sc <vm_device>\n\n"
-               "NOTE: to use CTRL-C within the terminal, use Alt-C\n"
-               "      to exit the terminal, use CTRL-ALT-x\n\n");
+        printf("usage: v3_cons_tc <vm_device>\n\n"
+               "NOTE: to exit the terminal, use CTRL-ALT-\\\n\n");
         goto exit_err;
     }
 
@@ -716,10 +750,10 @@ int main(int argc, char* argv[]) {
 
 
     raw();
-    cbreak();
     noecho();
     keypad(console.win, TRUE);
 
+
     while (1) {
 
         int ret; 
@@ -757,28 +791,19 @@ int main(int argc, char* argv[]) {
                 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);
-                           }
-
+                     // should we quit ?
+                     if (key.code.number == '\\' && 
+                         key.modifiers & TERMKEY_KEYMOD_CTRL && 
+                         key.modifiers & TERMKEY_KEYMOD_ALT) {
+                       exit(1);
+                     } else {
+                       int ret = handle_key(cons_fd, &key);
+                       
+                       if (ret < 0) {
+                         printf("Error sending key to console\n");
+                         return -1;
+                       } 
+                     }
                            break;
                                                }
                     case TERMKEY_TYPE_FUNCTION:
index 3662d1d..98cf495 100755 (executable)
@@ -1,11 +1,13 @@
 #!/usr/bin/perl -w
 
+use IPC::Cmd qw/can_run/;
+
 if ($#ARGV!=0) { 
   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 '\\' or 'CTRL-ALT-\\' to escape\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";
@@ -22,5 +24,11 @@ if ($#ARGV!=0) {
 
 $vm=shift;
 
-system "v3_cons_sc $vm 2>/dev/null";
+if (can_run('v3_cons_tc')) {
+    system "v3_cons_tc $vm 2>/dev/null";
+} elsif (can_run('v3_cons_sc')) {
+    system "v3_cons_sc $vm 2>/dev/null";
+} else {
+    print "You have no console program on your path\n";
+}