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

version 1.1.1.3, 2018/04/24 16:42:39 version 1.1.1.4, 2018/04/24 16:44:52
Line 121  struct TextConsole { Line 121  struct TextConsole {
     int total_height;      int total_height;
     int backscroll_height;      int backscroll_height;
     int x, y;      int x, y;
       int x_saved, y_saved;
     int y_displayed;      int y_displayed;
     int y_base;      int y_base;
     TextAttributes t_attrib_default; /* default text attributes */      TextAttributes t_attrib_default; /* default text attributes */
Line 131  struct TextConsole { Line 132  struct TextConsole {
     int esc_params[MAX_ESC_PARAMS];      int esc_params[MAX_ESC_PARAMS];
     int nb_esc_params;      int nb_esc_params;
   
     /* kbd read handler */      CharDriverState *chr;
     IOCanRWHandler *fd_can_read;   
     IOReadHandler *fd_read;  
     void *fd_opaque;  
     /* fifo for key pressed */      /* fifo for key pressed */
     QEMUFIFO out_fifo;      QEMUFIFO out_fifo;
     uint8_t out_fifo_buf[16];      uint8_t out_fifo_buf[16];
Line 147  static int nb_consoles = 0; Line 145  static int nb_consoles = 0;
   
 void vga_hw_update(void)  void vga_hw_update(void)
 {  {
     if (active_console->hw_update)      if (active_console && active_console->hw_update)
         active_console->hw_update(active_console->hw);          active_console->hw_update(active_console->hw);
 }  }
   
Line 659  static void console_handle_escape(TextCo Line 657  static void console_handle_escape(TextCo
 {  {
     int i;      int i;
   
     if (s->nb_esc_params == 0) { /* ESC[m sets all attributes to default */  
         s->t_attrib = s->t_attrib_default;  
         return;  
     }  
     for (i=0; i<s->nb_esc_params; i++) {      for (i=0; i<s->nb_esc_params; i++) {
         switch (s->esc_params[i]) {          switch (s->esc_params[i]) {
             case 0: /* reset all console attributes to default */              case 0: /* reset all console attributes to default */
Line 752  static void console_handle_escape(TextCo Line 746  static void console_handle_escape(TextCo
     }      }
 }  }
   
   static void console_clear_xy(TextConsole *s, int x, int y)
   {
       int y1 = (s->y_base + y) % s->total_height;
       TextCell *c = &s->cells[y1 * s->width + x];
       c->ch = ' ';
       c->t_attrib = s->t_attrib_default;
       c++;
       update_xy(s, x, y);
   }
   
 static void console_putchar(TextConsole *s, int ch)  static void console_putchar(TextConsole *s, int ch)
 {  {
     TextCell *c;      TextCell *c;
     int y1, i, x;      int y1, i;
       int x, y;
   
     switch(s->state) {      switch(s->state) {
     case TTY_STATE_NORM:      case TTY_STATE_NORM:
Line 781  static void console_putchar(TextConsole  Line 786  static void console_putchar(TextConsole 
         case '\a':  /* alert aka. bell */          case '\a':  /* alert aka. bell */
             /* TODO: has to be implemented */              /* TODO: has to be implemented */
             break;              break;
           case 14:
               /* SI (shift in), character set 0 (ignored) */
               break;
           case 15:
               /* SO (shift out), character set 1 (ignored) */
               break;
         case 27:    /* esc (introducing an escape sequence) */          case 27:    /* esc (introducing an escape sequence) */
             s->state = TTY_STATE_ESC;              s->state = TTY_STATE_ESC;
             break;              break;
         default:          default:
               if (s->x >= s->width - 1) {
                   break;
               }
             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];
             c->ch = ch;              c->ch = ch;
             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) {              if (s->x >= s->width) {
                 s->x = 0;                  s->x = 0;
                 console_put_lf(s);                  console_put_lf(s);
             }              }
   #endif
             break;              break;
         }          }
         break;          break;
Line 818  static void console_putchar(TextConsole  Line 834  static void console_putchar(TextConsole 
             s->nb_esc_params++;              s->nb_esc_params++;
             if (ch == ';')              if (ch == ';')
                 break;                  break;
   #ifdef DEBUG_CONSOLE
               fprintf(stderr, "escape sequence CSI%d;%d%c, %d parameters\n",
                       s->esc_params[0], s->esc_params[1], ch, s->nb_esc_params);
   #endif
             s->state = TTY_STATE_NORM;              s->state = TTY_STATE_NORM;
             switch(ch) {              switch(ch) {
             case 'D':              case 'A':
                 if (s->x > 0)                  /* move cursor up */
                     s->x--;                  if (s->esc_params[0] == 0) {
                       s->esc_params[0] = 1;
                   }
                   s->y -= s->esc_params[0];
                   if (s->y < 0) {
                       s->y = 0;
                   }
                   break;
               case 'B':
                   /* move cursor down */
                   if (s->esc_params[0] == 0) {
                       s->esc_params[0] = 1;
                   }
                   s->y += s->esc_params[0];
                   if (s->y >= s->height) {
                       s->y = s->height - 1;
                   }
                 break;                  break;
             case 'C':              case 'C':
                 if (s->x < (s->width - 1))                  /* move cursor right */
                     s->x++;                  if (s->esc_params[0] == 0) {
                       s->esc_params[0] = 1;
                   }
                   s->x += s->esc_params[0];
                   if (s->x >= s->width) {
                       s->x = s->width - 1;
                   }
                 break;                  break;
               case 'D':
                   /* move cursor left */
                   if (s->esc_params[0] == 0) {
                       s->esc_params[0] = 1;
                   }
                   s->x -= s->esc_params[0];
                   if (s->x < 0) {
                       s->x = 0;
                   }
                   break;
               case 'G':
                   /* move cursor to column */
                   s->x = s->esc_params[0] - 1;
                   if (s->x < 0) {
                       s->x = 0;
                   }
                   break;
               case 'f':
               case 'H':
                   /* move cursor to row, column */
                   s->x = s->esc_params[1] - 1;
                   if (s->x < 0) {
                       s->x = 0;
                   }
                   s->y = s->esc_params[0] - 1;
                   if (s->y < 0) {
                       s->y = 0;
                   }
                   break;
               case 'J':
                   switch (s->esc_params[0]) {
                   case 0:
                       /* clear to end of screen */
                       for (y = s->y; y < s->height; y++) {
                           for (x = 0; x < s->width; x++) {
                               if (y == s->y && x < s->x) {
                                   continue;
                               }
                               console_clear_xy(s, x, y);
                           }
                       }
                       break;
                   case 1:
                       /* clear from beginning of screen */
                       for (y = 0; y <= s->y; y++) {
                           for (x = 0; x < s->width; x++) {
                               if (y == s->y && x > s->x) {
                                   break;
                               }
                               console_clear_xy(s, x, y);
                           }
                       }
                       break;
                   case 2:
                       /* clear entire screen */
                       for (y = 0; y <= s->height; y++) {
                           for (x = 0; x < s->width; x++) {
                               console_clear_xy(s, x, y);
                           }
                       }
                   break;
                   }
             case 'K':              case 'K':
                   switch (s->esc_params[0]) {
                   case 0:
                 /* clear to eol */                  /* clear to eol */
                 y1 = (s->y_base + s->y) % s->total_height;  
                 for(x = s->x; x < s->width; x++) {                  for(x = s->x; x < s->width; x++) {
                     c = &s->cells[y1 * s->width + x];                          console_clear_xy(s, x, s->y);
                     c->ch = ' ';  
                     c->t_attrib = s->t_attrib_default;  
                     c++;  
                     update_xy(s, x, s->y);  
                 }                  }
                 break;                  break;
             default:                  case 1:
                       /* clear from beginning of line */
                       for (x = 0; x <= s->x; x++) {
                           console_clear_xy(s, x, s->y);
                       }
                       break;
                   case 2:
                       /* clear entire line */
                       for(x = 0; x < s->width; x++) {
                           console_clear_xy(s, x, s->y);
                       }
                 break;                  break;
             }              }
                   break;
               case 'm':
             console_handle_escape(s);              console_handle_escape(s);
             break;              break;
               case 'n':
                   /* report cursor position */
                   /* TODO: send ESC[row;colR */
                   break;
               case 's':
                   /* save cursor position */
                   s->x_saved = s->x;
                   s->y_saved = s->y;
                   break;
               case 'u':
                   /* restore cursor position */
                   s->x = s->x_saved;
                   s->y = s->y_saved;
                   break;
               default:
   #ifdef DEBUG_CONSOLE
                   fprintf(stderr, "unhandled escape character '%c'\n", ch);
   #endif
                   break;
               }
               break;
         }          }
     }      }
 }  }
Line 884  static int console_puts(CharDriverState  Line 1018  static int console_puts(CharDriverState 
     return len;      return len;
 }  }
   
 static void console_chr_add_read_handler(CharDriverState *chr,   
                                          IOCanRWHandler *fd_can_read,   
                                          IOReadHandler *fd_read, void *opaque)  
 {  
     TextConsole *s = chr->opaque;  
     s->fd_can_read = fd_can_read;  
     s->fd_read = fd_read;  
     s->fd_opaque = opaque;  
 }  
   
 static void console_send_event(CharDriverState *chr, int event)  static void console_send_event(CharDriverState *chr, int event)
 {  {
     TextConsole *s = chr->opaque;      TextConsole *s = chr->opaque;
Line 915  static void kbd_send_chars(void *opaque) Line 1039  static void kbd_send_chars(void *opaque)
     int len;      int len;
     uint8_t buf[16];      uint8_t buf[16];
           
     len = s->fd_can_read(s->fd_opaque);      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;
     if (len > 0) {      if (len > 0) {
         if (len > sizeof(buf))          if (len > sizeof(buf))
             len = sizeof(buf);              len = sizeof(buf);
         qemu_fifo_read(&s->out_fifo, buf, len);          qemu_fifo_read(&s->out_fifo, buf, len);
         s->fd_read(s->fd_opaque, buf, len);          qemu_chr_read(s->chr, buf, len);
     }      }
     /* characters are pending: we send them a bit later (XXX:      /* characters are pending: we send them a bit later (XXX:
        horrible, should change char device API) */         horrible, should change char device API) */
Line 973  void kbd_put_keysym(int keysym) Line 1097  void kbd_put_keysym(int keysym)
         } else {          } else {
                 *q++ = keysym;                  *q++ = keysym;
         }          }
         if (s->fd_read) {          if (s->chr->chr_read) {
             qemu_fifo_write(&s->out_fifo, buf, q - buf);              qemu_fifo_write(&s->out_fifo, buf, q - buf);
             kbd_send_chars(s);              kbd_send_chars(s);
         }          }
Line 1049  CharDriverState *text_console_init(Displ Line 1173  CharDriverState *text_console_init(Displ
     }      }
     chr->opaque = s;      chr->opaque = s;
     chr->chr_write = console_puts;      chr->chr_write = console_puts;
     chr->chr_add_read_handler = console_chr_add_read_handler;  
     chr->chr_send_event = console_send_event;      chr->chr_send_event = console_send_event;
   
       s->chr = chr;
     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);
Line 1086  CharDriverState *text_console_init(Displ Line 1210  CharDriverState *text_console_init(Displ
     s->t_attrib = s->t_attrib_default;      s->t_attrib = s->t_attrib_default;
     text_console_resize(s);      text_console_resize(s);
   
       qemu_chr_reset(chr);
   
     return chr;      return chr;
 }  }

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


unix.superglobalmegacorp.com