/[hurd]/hurd/console/display.c
ViewVC logotype

Diff of /hurd/console/display.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.23 by marcus, Tue Sep 17 17:13:18 2002 UTC revision 1.24 by marcus, Wed Sep 18 02:42:08 2002 UTC
# Line 85  struct cursor Line 85  struct cursor
85  };  };
86  typedef struct cursor *cursor_t;  typedef struct cursor *cursor_t;
87    
88    struct scrolling_region
89    {
90      uint32_t top;
91      uint32_t bottom;
92    };
93    
94  struct parse  struct parse
95  {  {
96    /* The parsing state of output characters, needed to handle escape    /* The parsing state of output characters, needed to handle escape
# Line 96  struct parse Line 102  struct parse
102        STATE_ESC,        STATE_ESC,
103        STATE_ESC_BRACKET_INIT,        STATE_ESC_BRACKET_INIT,
104        STATE_ESC_BRACKET,        STATE_ESC_BRACKET,
105        STATE_ESC_BRACKET_QUESTION        STATE_ESC_BRACKET_QUESTION,
106          STATE_ESC_BRACKET_RIGHT_ANGLE
107      } state;      } state;
108    
109    /* How many parameters an escape sequence may have.  */    /* How many parameters an escape sequence may have.  */
# Line 171  struct display Line 178  struct display
178       signal for this virtual console.  */       signal for this virtual console.  */
179    int owner_id;    int owner_id;
180    
181      /* The pending changes.  */
182    struct changes changes;    struct changes changes;
183    
184      /* The state of the virtual console.  */
185      /* The saved cursor position.  */
186    struct cursor cursor;    struct cursor cursor;
187      /* The output queue and parser state.  */
188    struct output output;    struct output output;
189      /* The current video attributes.  */
190    struct attr attr;    struct attr attr;
191      /* Non-zero if we are in insert mode.  */
192      int insert_mode;
193      /* Scrolling region.  */
194      struct scrolling_region csr;
195    
196    struct cons_display *user;    struct cons_display *user;
197    
198    struct user_pager_info *upi;      struct user_pager_info *upi;  
# Line 971  handle_esc_bracket_hl (display_t display Line 988  handle_esc_bracket_hl (display_t display
988  {  {
989    switch (code)    switch (code)
990      {      {
991        case 4:             /* ECMA-48 <SMIR>, <RMIR>.  */
992          /* Insert mode: <smir>, <rmir>.  */
993          display->insert_mode = flag ? 1 : 0;
994          break;
995      case 34:      case 34:
996        /* Cursor standout: <cnorm>, <cvvis>.  */        /* Cursor standout: <cnorm>, <cvvis>.  */
997        if (flag)        if (flag)
         display->user->cursor.status = CONS_CURSOR_VERY_VISIBLE;  
       else  
998          display->user->cursor.status = CONS_CURSOR_NORMAL;          display->user->cursor.status = CONS_CURSOR_NORMAL;
999          else
1000            display->user->cursor.status = CONS_CURSOR_VERY_VISIBLE;
1001        /* XXX Flag cursor status change.  */        /* XXX Flag cursor status change.  */
1002        break;        break;
1003      }      }
# Line 1028  handle_esc_bracket_m (attr_t attr, int c Line 1049  handle_esc_bracket_m (attr_t attr, int c
1049        /* Alternate character set mode on: <smacs>.  */        /* Alternate character set mode on: <smacs>.  */
1050        attr->altchar = 1;        attr->altchar = 1;
1051        break;        break;
1052        case 21:
1053          /* Normal intensity (switch off bright).  */
1054          attr->current.intensity = CONS_ATTR_INTENSITY_NORMAL;
1055          break;
1056      case 22:      case 22:
1057        /* Normal intensity.  */        /* Normal intensity (switch off dim).  */
1058        attr->current.intensity = CONS_ATTR_INTENSITY_NORMAL;        attr->current.intensity = CONS_ATTR_INTENSITY_NORMAL;
1059        break;        break;
1060      case 23:      case 23:
# Line 1095  linefeed (display_t display) Line 1120  linefeed (display_t display)
1120  {  {
1121    struct cons_display *user = display->user;    struct cons_display *user = display->user;
1122    
1123    if (user->cursor.row < user->screen.height - 1)    if (display->csr.top == 0 && display->csr.bottom >= user->screen.height - 1)
1124      {      {
1125        user->cursor.row++;        /* No scrolling region active, do the normal scrolling activity.  */
1126        /* XXX Flag cursor update.  */        if (user->cursor.row < user->screen.height - 1)
1127            {
1128              user->cursor.row++;
1129              /* XXX Flag cursor update.  */
1130            }
1131          else
1132            {
1133              user->screen.cur_line++;
1134    
1135              screen_fill (display, 0, user->screen.height - 1,
1136                           user->screen.width - 1, user->screen.height - 1,
1137                           L' ', display->attr.current);
1138              if (user->screen.scr_lines <
1139                  user->screen.lines - user->screen.height)
1140                user->screen.scr_lines++;
1141              /* XXX Flag current line change.  */
1142              /* XXX Possibly flag change of length of scroll back buffer.  */
1143            }
1144      }      }
1145    else    else
1146      {      {
1147        user->screen.cur_line++;        /* With an active scrolling region, never actually scroll.  Just
1148             shift the scrolling region if necessary.  */
1149        screen_fill (display, 0, user->screen.height - 1,        if (user->cursor.row != display->csr.bottom
1150                     user->screen.width - 1, user->screen.height - 1,            && user->cursor.row < user->screen.height - 1)
1151                     L' ', display->attr.current);          {
1152        if (user->screen.scr_lines <            user->cursor.row++;
1153            user->screen.lines - user->screen.height)            /* XXX Flag cursor update.  */
1154          user->screen.scr_lines++;          }
1155        /* XXX Flag current line change.  */        else if (user->cursor.row == display->csr.bottom)
1156        /* XXX Possibly flag change of length of scroll back buffer.  */          screen_shift_left (display, 0, display->csr.top,
1157      }                             user->screen.width - 1, display->csr.bottom,
1158                               user->screen.width,
1159                               L' ', display->attr.current);
1160        }      
1161  }  }
1162    
1163  static void  static void
# Line 1192  handle_esc_bracket (display_t display, c Line 1237  handle_esc_bracket (display_t display, c
1237        user->cursor.col -= (parse->params[0] ?: 1);        user->cursor.col -= (parse->params[0] ?: 1);
1238        limit_cursor (display);        limit_cursor (display);
1239        break;        break;
1240      case 'h':      case 'l':
1241        /* Reset mode.  */        /* Reset mode.  */
1242        for (i = 0; i < parse->nparams; i++)        for (i = 0; i < parse->nparams; i++)
1243          handle_esc_bracket_hl (display, parse->params[i], 0);          handle_esc_bracket_hl (display, parse->params[i], 0);
1244        break;        break;
1245      case 'l':      case 'h':
1246        /* Set mode.  */        /* Set mode.  */
1247        for (i = 0; i < parse->nparams; i++)        for (i = 0; i < parse->nparams; i++)
1248          handle_esc_bracket_hl (display, parse->params[i], 1);          handle_esc_bracket_hl (display, parse->params[i], 1);
# Line 1280  handle_esc_bracket (display_t display, c Line 1325  handle_esc_bracket (display_t display, c
1325                           parse->params[0] ?: 1,                           parse->params[0] ?: 1,
1326                           L' ', display->attr.current);                           L' ', display->attr.current);
1327        break;        break;
1328        case 'r':           /* VT100: Set scrolling region.  */
1329          if (!parse->params[1])
1330            {
1331              display->csr.top = 0;
1332              display->csr.bottom = user->screen.height - 1;
1333            }
1334          else
1335            {
1336              if (parse->params[1] <= user->screen.height
1337                  && parse->params[0] < parse->params[1])
1338                {
1339                  display->csr.top = parse->params[0] ? parse->params[0] - 1 : 0;
1340                  display->csr.bottom = parse->params[1] - 1;
1341                  user->cursor.col = 0;
1342                  user->cursor.row = 0;
1343                  /* XXX Flag cursor change.  */
1344                }
1345            }
1346          break;
1347      case 'S':           /* ECMA-48 <SU>.  */      case 'S':           /* ECMA-48 <SU>.  */
1348        /* Scroll up: <ind>, <indn>.  */        /* Scroll up: <ind>, <indn>.  */
1349        screen_shift_left (display, 0, 0,        screen_shift_left (display, 0, 0,
# Line 1296  handle_esc_bracket (display_t display, c Line 1360  handle_esc_bracket (display_t display, c
1360        break;        break;
1361      case 'X':           /* ECMA-48 <ECH>.  */      case 'X':           /* ECMA-48 <ECH>.  */
1362        /* Erase character(s): <ech>.  */        /* Erase character(s): <ech>.  */
1363        screen_fill (display, user->cursor.col, user->cursor.row,        {
1364                     /* XXX limit ? */user->cursor.col + (parse->params[0] ?: 1),          int col = user->cursor.col;
1365                     user->cursor.row,          if (parse->params[0] - 1 > 0)
1366                     L' ', display->attr.current);            col += parse->params[0] - 1;
1367            if (col > user->screen.width - 1)
1368              col = user->screen.width - 1;
1369    
1370            screen_fill (display, user->cursor.col, user->cursor.row,
1371                         col, user->cursor.row, L' ', display->attr.current);
1372          }
1373        break;        break;
1374      case 'I':           /* ECMA-48 <CHT>.  */      case 'I':           /* ECMA-48 <CHT>.  */
1375        /* Horizontal tab.  */        /* Horizontal tab.  */
# Line 1339  handle_esc_bracket (display_t display, c Line 1409  handle_esc_bracket (display_t display, c
1409      }      }
1410  }  }
1411    
1412    
1413  static void  static void
1414  handle_esc_bracket_question_hl (display_t display, int code, int flag)  handle_esc_bracket_question_hl (display_t display, int code, int flag)
1415  {  {
# Line 1347  handle_esc_bracket_question_hl (display_ Line 1418  handle_esc_bracket_question_hl (display_
1418      case 25:      case 25:
1419        /* Cursor invisibility: <civis>, <cnorm>.  */        /* Cursor invisibility: <civis>, <cnorm>.  */
1420        if (flag)        if (flag)
         display->user->cursor.status = CONS_CURSOR_INVISIBLE;  
       else  
1421          display->user->cursor.status = CONS_CURSOR_NORMAL;          display->user->cursor.status = CONS_CURSOR_NORMAL;
1422          else
1423            display->user->cursor.status = CONS_CURSOR_INVISIBLE;
1424        /* XXX Flag cursor status change.  */        /* XXX Flag cursor status change.  */
1425        break;        break;
1426      }      }
# Line 1364  handle_esc_bracket_question (display_t d Line 1435  handle_esc_bracket_question (display_t d
1435    int i;    int i;
1436    switch (op)    switch (op)
1437      {      {
1438      case 'h':      case 'l':
1439        /* Reset mode.  */        /* Reset mode.  */
1440        for (i = 0; i < parse->nparams; ++i)        for (i = 0; i < parse->nparams; ++i)
1441          handle_esc_bracket_question_hl (display, parse->params[i], 0);          handle_esc_bracket_question_hl (display, parse->params[i], 0);
1442        break;        break;
1443      case 'l':      case 'h':
1444        /* Set mode.  */        /* Set mode.  */
1445        for (i = 0; i < parse->nparams; ++i)        for (i = 0; i < parse->nparams; ++i)
1446          handle_esc_bracket_question_hl (display, parse->params[i], 1);          handle_esc_bracket_question_hl (display, parse->params[i], 1);
# Line 1377  handle_esc_bracket_question (display_t d Line 1448  handle_esc_bracket_question (display_t d
1448      }      }
1449  }  }
1450    
1451    
1452    static void
1453    handle_esc_bracket_right_angle_hl (display_t display, int code, int flag)
1454    {
1455      switch (code)
1456        {
1457        case 1:
1458          /* Bold: <gsbom>, <grbom>.  This is a GNU extension.  */
1459          if (flag)
1460            display->attr.current.bold = 1;
1461          else
1462            display->attr.current.bold = 0;
1463          break;
1464        }
1465    }
1466    
1467    
1468    static void
1469    handle_esc_bracket_right_angle (display_t display, char op)
1470    {
1471      parse_t parse = &display->output.parse;
1472    
1473      int i;
1474      switch (op)
1475        {
1476        case 'l':
1477          /* Reset mode.  */
1478          for (i = 0; i < parse->nparams; ++i)
1479            handle_esc_bracket_right_angle_hl (display, parse->params[i], 0);
1480          break;
1481        case 'h':
1482          /* Set mode.  */
1483          for (i = 0; i < parse->nparams; ++i)
1484            handle_esc_bracket_right_angle_hl (display, parse->params[i], 1);
1485          break;
1486        }
1487    }
1488    
1489    
1490  static wchar_t  static wchar_t
1491  altchar_to_ucs4 (wchar_t chr)  altchar_to_ucs4 (wchar_t chr)
1492  {  {
# Line 1484  display_output_one (display_t display, w Line 1594  display_output_one (display_t display, w
1594                  user->cursor.col--;                  user->cursor.col--;
1595                else                else
1596                  {                  {
1597                    /* XXX This implements the <bw> functionality.                    /* This implements the <bw> functionality.  */
                      The alternative is to cut off and set col to 0.  */  
1598                    user->cursor.col = user->screen.width - 1;                    user->cursor.col = user->screen.width - 1;
1599                    user->cursor.row--;                    user->cursor.row--;
1600                  }                  }
# Line 1512  display_output_one (display_t display, w Line 1621  display_output_one (display_t display, w
1621                % user->screen.lines;                % user->screen.lines;
1622              int idx = line * user->screen.width + user->cursor.col;              int idx = line * user->screen.width + user->cursor.col;
1623    
1624                if (display->insert_mode
1625                    && user->cursor.col != user->screen.width - 1)
1626                  {
1627                    /* If in insert mode, do the same as <ich1>.  */
1628                    screen_shift_right (display, user->cursor.col, user->cursor.row,
1629                                        user->screen.width - 1, user->cursor.row, 1,
1630                                        L' ', display->attr.current);
1631                  }
1632    
1633              user->_matrix[idx].chr = display->attr.altchar              user->_matrix[idx].chr = display->attr.altchar
1634                ? altchar_to_ucs4 (chr) : chr;                ? altchar_to_ucs4 (chr) : chr;
1635              user->_matrix[idx].attr = display->attr.current;              user->_matrix[idx].attr = display->attr.current;
# Line 1539  display_output_one (display_t display, w Line 1657  display_output_one (display_t display, w
1657            /* Reset: <rs2>.  */            /* Reset: <rs2>.  */
1658            display->attr.current = display->attr.attr_def;            display->attr.current = display->attr.attr_def;
1659            display->attr.altchar = 0;            display->attr.altchar = 0;
1660              display->insert_mode = 0;
1661              display->csr.top = 0;
1662              display->csr.bottom = user->screen.height - 1;
1663            user->cursor.status = CONS_CURSOR_NORMAL;            user->cursor.status = CONS_CURSOR_NORMAL;
1664            /* Fall through.  */            /* Fall through.  */
1665          case L'c':          case L'c':
# Line 1570  display_output_one (display_t display, w Line 1691  display_output_one (display_t display, w
1691            /* Visible bell.  */            /* Visible bell.  */
1692            user->bell.visible++;            user->bell.visible++;
1693            break;            break;
         case L'Q':              /* ECMA-48 <PU1>.  */  
           /* Bold on: <gsbom>.  This is a GNU extension.  */  
           display->attr.current.bold = 1;  
           break;  
         case L'R':              /* ECMA-48 <PU2>.  */  
           /* Bold off: <grbom>.  This is a GNU extension.  */  
           display->attr.current.bold = 0;  
           break;  
1694          default:          default:
1695            /* Unsupported escape sequence.  */            /* Unsupported escape sequence.  */
1696            break;            break;
# Line 1592  display_output_one (display_t display, w Line 1705  display_output_one (display_t display, w
1705            parse->state = STATE_ESC_BRACKET_QUESTION;            parse->state = STATE_ESC_BRACKET_QUESTION;
1706            break;        /* Consume the question mark.  */            break;        /* Consume the question mark.  */
1707          }          }
1708          else if (chr == '>')
1709            {
1710              parse->state = STATE_ESC_BRACKET_RIGHT_ANGLE;
1711              break;        /* Consume the right angle.  */
1712            }
1713        else        else
1714          parse->state = STATE_ESC_BRACKET;          parse->state = STATE_ESC_BRACKET;
1715        /* Fall through.  */        /* Fall through.  */
1716      case STATE_ESC_BRACKET:      case STATE_ESC_BRACKET:
1717      case STATE_ESC_BRACKET_QUESTION:      case STATE_ESC_BRACKET_QUESTION:
1718        case STATE_ESC_BRACKET_RIGHT_ANGLE:
1719        if (chr >= '0' && chr <= '9')        if (chr >= '0' && chr <= '9')
1720          parse->params[parse->nparams]          parse->params[parse->nparams]
1721              = parse->params[parse->nparams]*10 + chr - '0';              = parse->params[parse->nparams]*10 + chr - '0';
# Line 1610  display_output_one (display_t display, w Line 1729  display_output_one (display_t display, w
1729            parse->nparams++;            parse->nparams++;
1730            if (parse->state == STATE_ESC_BRACKET)            if (parse->state == STATE_ESC_BRACKET)
1731              handle_esc_bracket (display, chr);              handle_esc_bracket (display, chr);
1732              else if (parse->state == STATE_ESC_BRACKET_RIGHT_ANGLE)
1733                handle_esc_bracket_right_angle (display, chr);
1734            else            else
1735              handle_esc_bracket_question (display, chr);              handle_esc_bracket_question (display, chr);
1736            parse->state = STATE_NORMAL;            parse->state = STATE_NORMAL;
# Line 1738  display_create (display_t *r_display, co Line 1859  display_create (display_t *r_display, co
1859    mutex_init (&display->lock);    mutex_init (&display->lock);
1860    display->attr.attr_def = def_attr;    display->attr.attr_def = def_attr;
1861    display->attr.current = display->attr.attr_def;    display->attr.current = display->attr.attr_def;
1862      display->csr.bottom = height - 1;
1863    
1864    err = user_create (display, width, height, lines, L' ',    err = user_create (display, width, height, lines, L' ',
1865                       display->attr.current);                       display->attr.current);
1866    if (err)    if (err)
# Line 1919  display_output (display_t display, int n Line 2042  display_output (display_t display, int n
2042        errno = err;        errno = err;
2043        return err;        return err;
2044      }      }
   /* XXX What should be done with invalid characters etc?  */  
2045    if (buffer_size)    if (buffer_size)
2046      {      {
2047        /* If we used the caller's buffer DATA, the remaining bytes        /* If we used the caller's buffer DATA, the remaining bytes

Legend:
Removed from v.1.23  
changed lines
  Added in v.1.24

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26