Diff for /qemu/console.c between versions 1.1.1.4 and 1.1.1.5

version 1.1.1.4, 2018/04/24 16:44:52 version 1.1.1.5, 2018/04/24 16:47:16
Line 1 Line 1
 /*  /*
  * QEMU graphical console   * QEMU graphical console
  *    *
  * Copyright (c) 2004 Fabrice Bellard   * Copyright (c) 2004 Fabrice Bellard
  *    *
  * Permission is hereby granted, free of charge, to any person obtaining a copy   * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal   * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights   * in the Software without restriction, including without limitation the rights
Line 21 Line 21
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.   * THE SOFTWARE.
  */   */
 #include "vl.h"  #include "qemu-common.h"
   #include "console.h"
   #include "qemu-timer.h"
   
 //#define DEBUG_CONSOLE  //#define DEBUG_CONSOLE
 #define DEFAULT_BACKSCROLL 512  #define DEFAULT_BACKSCROLL 512
Line 59  typedef struct QEMUFIFO { Line 61  typedef struct QEMUFIFO {
     int count, wptr, rptr;      int count, wptr, rptr;
 } QEMUFIFO;  } QEMUFIFO;
   
 int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)  static int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)
 {  {
     int l, len;      int l, len;
   
Line 82  int qemu_fifo_write(QEMUFIFO *f, const u Line 84  int qemu_fifo_write(QEMUFIFO *f, const u
     return len1;      return len1;
 }  }
   
 int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)  static int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)
 {  {
     int l, len;      int l, len;
   
Line 104  int qemu_fifo_read(QEMUFIFO *f, uint8_t  Line 106  int qemu_fifo_read(QEMUFIFO *f, uint8_t 
     return len1;      return len1;
 }  }
   
   typedef enum {
       GRAPHIC_CONSOLE,
       TEXT_CONSOLE,
       TEXT_CONSOLE_FIXED_SIZE
   } console_type_t;
   
 /* ??? This is mis-named.  /* ??? This is mis-named.
    It is used for both text and graphical consoles.  */     It is used for both text and graphical consoles.  */
 struct TextConsole {  struct TextConsole {
     int text_console; /* true if text console */      console_type_t console_type;
     DisplayState *ds;      DisplayState *ds;
     /* Graphic console state.  */      /* Graphic console state.  */
     vga_hw_update_ptr hw_update;      vga_hw_update_ptr hw_update;
Line 174  static unsigned int vga_get_color(Displa Line 182  static unsigned int vga_get_color(Displa
         r = (rgba >> 16) & 0xff;          r = (rgba >> 16) & 0xff;
         g = (rgba >> 8) & 0xff;          g = (rgba >> 8) & 0xff;
         b = (rgba) & 0xff;          b = (rgba) & 0xff;
         color = (rgb_to_index[r] * 6 * 6) +           color = (rgb_to_index[r] * 6 * 6) +
             (rgb_to_index[g] * 6) +               (rgb_to_index[g] * 6) +
             (rgb_to_index[b]);              (rgb_to_index[b]);
         break;          break;
 #endif  #endif
Line 199  static unsigned int vga_get_color(Displa Line 207  static unsigned int vga_get_color(Displa
     return color;      return color;
 }  }
   
 static void vga_fill_rect (DisplayState *ds,   static void vga_fill_rect (DisplayState *ds,
                            int posx, int posy, int width, int height, uint32_t color)                             int posx, int posy, int width, int height, uint32_t color)
 {  {
     uint8_t *d, *d1;      uint8_t *d, *d1;
     int x, y, bpp;      int x, y, bpp;
       
     bpp = (ds->depth + 7) >> 3;      bpp = (ds->depth + 7) >> 3;
     d1 = ds->data +       d1 = ds->data +
         ds->linesize * posy + bpp * posx;          ds->linesize * posy + bpp * posx;
     for (y = 0; y < height; y++) {      for (y = 0; y < height; y++) {
         d = d1;          d = d1;
Line 244  static void vga_bitblt(DisplayState *ds, Line 252  static void vga_bitblt(DisplayState *ds,
     bpp = (ds->depth + 7) >> 3;      bpp = (ds->depth + 7) >> 3;
     wb = w * bpp;      wb = w * bpp;
     if (yd <= ys) {      if (yd <= ys) {
         s = ds->data +           s = ds->data +
             ds->linesize * ys + bpp * xs;              ds->linesize * ys + bpp * xs;
         d = ds->data +           d = ds->data +
             ds->linesize * yd + bpp * xd;              ds->linesize * yd + bpp * xd;
         for (y = 0; y < h; y++) {          for (y = 0; y < h; y++) {
             memmove(d, s, wb);              memmove(d, s, wb);
Line 254  static void vga_bitblt(DisplayState *ds, Line 262  static void vga_bitblt(DisplayState *ds,
             s += ds->linesize;              s += ds->linesize;
         }          }
     } else {      } else {
         s = ds->data +           s = ds->data +
             ds->linesize * (ys + h - 1) + bpp * xs;              ds->linesize * (ys + h - 1) + bpp * xs;
         d = ds->data +           d = ds->data +
             ds->linesize * (yd + h - 1) + bpp * xd;              ds->linesize * (yd + h - 1) + bpp * xd;
        for (y = 0; y < h; y++) {         for (y = 0; y < h; y++) {
             memmove(d, s, wb);              memmove(d, s, wb);
Line 399  static void console_print_text_attribute Line 407  static void console_print_text_attribute
 }  }
 #endif  #endif
   
 static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,   static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
                           TextAttributes *t_attrib)                            TextAttributes *t_attrib)
 {  {
     uint8_t *d;      uint8_t *d;
Line 422  static void vga_putcharxy(DisplayState * Line 430  static void vga_putcharxy(DisplayState *
     }      }
   
     bpp = (ds->depth + 7) >> 3;      bpp = (ds->depth + 7) >> 3;
     d = ds->data +       d = ds->data +
         ds->linesize * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;          ds->linesize * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
     linesize = ds->linesize;      linesize = ds->linesize;
     font_ptr = vgafont16 + FONT_HEIGHT * ch;      font_ptr = vgafont16 + FONT_HEIGHT * ch;
Line 503  static void text_console_resize(TextCons Line 511  static void text_console_resize(TextCons
             c++;              c++;
         }          }
     }      }
     free(s->cells);      qemu_free(s->cells);
     s->cells = cells;      s->cells = cells;
 }  }
   
Line 519  static void update_xy(TextConsole *s, in Line 527  static void update_xy(TextConsole *s, in
             y2 += s->total_height;              y2 += s->total_height;
         if (y2 < s->height) {          if (y2 < s->height) {
             c = &s->cells[y1 * s->width + x];              c = &s->cells[y1 * s->width + x];
             vga_putcharxy(s->ds, x, y2, c->ch,               vga_putcharxy(s->ds, x, y2, c->ch,
                           &(c->t_attrib));                            &(c->t_attrib));
             dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT,               dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT,
                        FONT_WIDTH, FONT_HEIGHT);                         FONT_WIDTH, FONT_HEIGHT);
         }          }
     }      }
Line 533  static void console_show_cursor(TextCons Line 541  static void console_show_cursor(TextCons
     int y, y1;      int y, y1;
   
     if (s == active_console) {      if (s == active_console) {
           int x = s->x;
           if (x >= s->width) {
               x = s->width - 1;
           }
         y1 = (s->y_base + s->y) % s->total_height;          y1 = (s->y_base + s->y) % s->total_height;
         y = y1 - s->y_displayed;          y = y1 - s->y_displayed;
         if (y < 0)          if (y < 0)
             y += s->total_height;              y += s->total_height;
         if (y < s->height) {          if (y < s->height) {
             c = &s->cells[y1 * s->width + s->x];              c = &s->cells[y1 * s->width + x];
             if (show) {              if (show) {
                 TextAttributes t_attrib = s->t_attrib_default;                  TextAttributes t_attrib = s->t_attrib_default;
                 t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */                  t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
                 vga_putcharxy(s->ds, s->x, y, c->ch, &t_attrib);                  vga_putcharxy(s->ds, x, y, c->ch, &t_attrib);
             } else {              } else {
                 vga_putcharxy(s->ds, s->x, y, c->ch,                   vga_putcharxy(s->ds, x, y, c->ch, &(c->t_attrib));
                               &(c->t_attrib));  
             }              }
             dpy_update(s->ds, s->x * FONT_WIDTH, y * FONT_HEIGHT,               dpy_update(s->ds, x * FONT_WIDTH, y * FONT_HEIGHT,
                        FONT_WIDTH, FONT_HEIGHT);                         FONT_WIDTH, FONT_HEIGHT);
         }          }
     }      }
Line 558  static void console_refresh(TextConsole  Line 569  static void console_refresh(TextConsole 
     TextCell *c;      TextCell *c;
     int x, y, y1;      int x, y, y1;
   
     if (s != active_console)       if (s != active_console)
         return;          return;
   
     vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,      vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,
Line 567  static void console_refresh(TextConsole  Line 578  static void console_refresh(TextConsole 
     for(y = 0; y < s->height; y++) {      for(y = 0; y < s->height; y++) {
         c = s->cells + y1 * s->width;          c = s->cells + y1 * s->width;
         for(x = 0; x < s->width; x++) {          for(x = 0; x < s->width; x++) {
             vga_putcharxy(s->ds, x, y, c->ch,               vga_putcharxy(s->ds, x, y, c->ch,
                           &(c->t_attrib));                            &(c->t_attrib));
             c++;              c++;
         }          }
Line 582  static void console_scroll(int ydelta) Line 593  static void console_scroll(int ydelta)
 {  {
     TextConsole *s;      TextConsole *s;
     int i, y1;      int i, y1;
       
     s = active_console;      s = active_console;
     if (!s || !s->text_console)      if (!s || (s->console_type == GRAPHIC_CONSOLE))
         return;          return;
   
     if (ydelta > 0) {      if (ydelta > 0) {
Line 637  static void console_put_lf(TextConsole * Line 648  static void console_put_lf(TextConsole *
             c++;              c++;
         }          }
         if (s == active_console && s->y_displayed == s->y_base) {          if (s == active_console && s->y_displayed == s->y_base) {
             vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0,               vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0,
                        s->width * FONT_WIDTH,                          s->width * FONT_WIDTH,
                        (s->height - 1) * FONT_HEIGHT);                         (s->height - 1) * FONT_HEIGHT);
             vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,              vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,
                           s->width * FONT_WIDTH, FONT_HEIGHT,                             s->width * FONT_WIDTH, FONT_HEIGHT,
                           color_table[0][s->t_attrib_default.bgcol]);                            color_table[0][s->t_attrib_default.bgcol]);
             dpy_update(s->ds, 0, 0,               dpy_update(s->ds, 0, 0,
                        s->width * FONT_WIDTH, s->height * FONT_HEIGHT);                         s->width * FONT_WIDTH, s->height * FONT_HEIGHT);
         }          }
     }      }
Line 772  static void console_putchar(TextConsole  Line 783  static void console_putchar(TextConsole 
             console_put_lf(s);              console_put_lf(s);
             break;              break;
         case '\b':  /* backspace */          case '\b':  /* backspace */
             if (s->x > 0)               if (s->x > 0)
                 s->x--;                  s->x--;
             break;              break;
         case '\t':  /* tabspace */          case '\t':  /* tabspace */
Line 796  static void console_putchar(TextConsole  Line 807  static void console_putchar(TextConsole 
             s->state = TTY_STATE_ESC;              s->state = TTY_STATE_ESC;
             break;              break;
         default:          default:
             if (s->x >= s->width - 1) {              if (s->x >= s->width) {
                 break;                  /* line wrap */
                   s->x = 0;
                   console_put_lf(s);
             }              }
             y1 = (s->y_base + s->y) % s->total_height;              y1 = (s->y_base + s->y) % s->total_height;
             c = &s->cells[y1 * s->width + s->x];              c = &s->cells[y1 * s->width + s->x];
Line 805  static void console_putchar(TextConsole  Line 818  static void console_putchar(TextConsole 
             c->t_attrib = s->t_attrib;              c->t_attrib = s->t_attrib;
             update_xy(s, s->x, s->y);              update_xy(s, s->x, s->y);
             s->x++;              s->x++;
 #if 0 /* line wrap disabled */  
             if (s->x >= s->width) {  
                 s->x = 0;  
                 console_put_lf(s);  
             }  
 #endif  
             break;              break;
         }          }
         break;          break;
Line 827  static void console_putchar(TextConsole  Line 834  static void console_putchar(TextConsole 
     case TTY_STATE_CSI: /* handle escape sequence parameters */      case TTY_STATE_CSI: /* handle escape sequence parameters */
         if (ch >= '0' && ch <= '9') {          if (ch >= '0' && ch <= '9') {
             if (s->nb_esc_params < MAX_ESC_PARAMS) {              if (s->nb_esc_params < MAX_ESC_PARAMS) {
                 s->esc_params[s->nb_esc_params] =                   s->esc_params[s->nb_esc_params] =
                     s->esc_params[s->nb_esc_params] * 10 + ch - '0';                      s->esc_params[s->nb_esc_params] * 10 + ch - '0';
             }              }
         } else {          } else {
Line 991  void console_select(unsigned int index) Line 998  void console_select(unsigned int index)
     s = consoles[index];      s = consoles[index];
     if (s) {      if (s) {
         active_console = s;          active_console = s;
         if (s->text_console) {          if (s->console_type != GRAPHIC_CONSOLE) {
             if (s->g_width != s->ds->width ||              if (s->g_width != s->ds->width ||
                 s->g_height != s->ds->height) {                  s->g_height != s->ds->height) {
                   if (s->console_type == TEXT_CONSOLE_FIXED_SIZE) {
                       dpy_resize(s->ds, s->g_width, s->g_height);
                   } else {
                 s->g_width = s->ds->width;                  s->g_width = s->ds->width;
                 s->g_height = s->ds->height;                  s->g_height = s->ds->height;
                 text_console_resize(s);                  text_console_resize(s);
             }              }
               }
             console_refresh(s);              console_refresh(s);
         } else {          } else {
             vga_hw_invalidate();              vga_hw_invalidate();
Line 1038  static void kbd_send_chars(void *opaque) Line 1049  static void kbd_send_chars(void *opaque)
     TextConsole *s = opaque;      TextConsole *s = opaque;
     int len;      int len;
     uint8_t buf[16];      uint8_t buf[16];
       
     len = qemu_chr_can_read(s->chr);      len = qemu_chr_can_read(s->chr);
     if (len > s->out_fifo.count)      if (len > s->out_fifo.count)
         len = s->out_fifo.count;          len = s->out_fifo.count;
Line 1063  void kbd_put_keysym(int keysym) Line 1074  void kbd_put_keysym(int keysym)
     int c;      int c;
   
     s = active_console;      s = active_console;
     if (!s || !s->text_console)      if (!s || (s->console_type == GRAPHIC_CONSOLE))
         return;          return;
   
     switch(keysym) {      switch(keysym) {
Line 1105  void kbd_put_keysym(int keysym) Line 1116  void kbd_put_keysym(int keysym)
     }      }
 }  }
   
 static TextConsole *new_console(DisplayState *ds, int text)  static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
 {  {
     TextConsole *s;      TextConsole *s;
     int i;      int i;
Line 1116  static TextConsole *new_console(DisplayS Line 1127  static TextConsole *new_console(DisplayS
     if (!s) {      if (!s) {
         return NULL;          return NULL;
     }      }
     if (!active_console || (active_console->text_console && !text))      if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
           (console_type == GRAPHIC_CONSOLE))) {
         active_console = s;          active_console = s;
       }
     s->ds = ds;      s->ds = ds;
     s->text_console = text;      s->console_type = console_type;
     if (text) {      if (console_type != GRAPHIC_CONSOLE) {
         consoles[nb_consoles++] = s;          consoles[nb_consoles++] = s;
     } else {      } else {
         /* HACK: Put graphical consoles before text consoles.  */          /* HACK: Put graphical consoles before text consoles.  */
         for (i = nb_consoles; i > 0; i--) {          for (i = nb_consoles; i > 0; i--) {
             if (!consoles[i - 1]->text_console)              if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE)
                 break;                  break;
             consoles[i] = consoles[i - 1];              consoles[i] = consoles[i - 1];
         }          }
Line 1141  TextConsole *graphic_console_init(Displa Line 1154  TextConsole *graphic_console_init(Displa
 {  {
     TextConsole *s;      TextConsole *s;
   
     s = new_console(ds, 0);      s = new_console(ds, GRAPHIC_CONSOLE);
     if (!s)      if (!s)
       return NULL;        return NULL;
     s->hw_update = update;      s->hw_update = update;
Line 1153  TextConsole *graphic_console_init(Displa Line 1166  TextConsole *graphic_console_init(Displa
   
 int is_graphic_console(void)  int is_graphic_console(void)
 {  {
     return !active_console->text_console;      return active_console->console_type == GRAPHIC_CONSOLE;
 }  }
   
 CharDriverState *text_console_init(DisplayState *ds)  void console_color_init(DisplayState *ds)
   {
       int i, j;
       for (j = 0; j < 2; j++) {
           for (i = 0; i < 8; i++) {
               color_table[j][i] = col_expand(ds, 
                      vga_get_color(ds, color_table_rgb[j][i]));
           }
       }
   }
   
   CharDriverState *text_console_init(DisplayState *ds, const char *p)
 {  {
     CharDriverState *chr;      CharDriverState *chr;
     TextConsole *s;      TextConsole *s;
     int i,j;      unsigned width;
       unsigned height;
     static int color_inited;      static int color_inited;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = qemu_mallocz(sizeof(CharDriverState));
     if (!chr)      if (!chr)
         return NULL;          return NULL;
     s = new_console(ds, 1);      s = new_console(ds, (p == 0) ? TEXT_CONSOLE : TEXT_CONSOLE_FIXED_SIZE);
     if (!s) {      if (!s) {
         free(chr);          free(chr);
         return NULL;          return NULL;
Line 1179  CharDriverState *text_console_init(Displ Line 1204  CharDriverState *text_console_init(Displ
     s->out_fifo.buf = s->out_fifo_buf;      s->out_fifo.buf = s->out_fifo_buf;
     s->out_fifo.buf_size = sizeof(s->out_fifo_buf);      s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
     s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);      s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
       
     if (!color_inited) {      if (!color_inited) {
         color_inited = 1;          color_inited = 1;
         for(j = 0; j < 2; j++) {          console_color_init(s->ds);
             for(i = 0; i < 8; i++) {  
                 color_table[j][i] = col_expand(s->ds,   
                         vga_get_color(s->ds, color_table_rgb[j][i]));  
             }  
         }  
     }      }
     s->y_displayed = 0;      s->y_displayed = 0;
     s->y_base = 0;      s->y_base = 0;
     s->total_height = DEFAULT_BACKSCROLL;      s->total_height = DEFAULT_BACKSCROLL;
     s->x = 0;      s->x = 0;
     s->y = 0;      s->y = 0;
     s->g_width = s->ds->width;      width = s->ds->width;
     s->g_height = s->ds->height;      height = s->ds->height;
       if (p != 0) {
           width = strtoul(p, (char **)&p, 10);
           if (*p == 'C') {
               p++;
               width *= FONT_WIDTH;
           }
           if (*p == 'x') {
               p++;
               height = strtoul(p, (char **)&p, 10);
               if (*p == 'C') {
                   p++;
                   height *= FONT_HEIGHT;
               }
           }
       }
       s->g_width = width;
       s->g_height = height;
   
     /* Set text attribute defaults */      /* Set text attribute defaults */
     s->t_attrib_default.bold = 0;      s->t_attrib_default.bold = 0;

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5


unix.superglobalmegacorp.com