The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/syscons/scterm-sc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
    3  * Copyright (c) 1992-1998 Søren Schmidt
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer as
   11  *    the first lines of this file unmodified.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD$");
   30 
   31 #include "opt_syscons.h"
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/kernel.h>
   36 #include <sys/module.h>
   37 #include <sys/consio.h>
   38 
   39 #if defined(__arm__) || defined(__mips__) || defined(__powerpc__)
   40 #include <machine/sc_machdep.h>
   41 #else
   42 #include <machine/pc/display.h>
   43 #endif
   44 
   45 #include <dev/syscons/syscons.h>
   46 #include <dev/syscons/sctermvar.h>
   47 
   48 #define MAX_ESC_PAR     5
   49 
   50 /* attribute flags */
   51 typedef struct {
   52         u_short         fg;                     /* foreground color */
   53         u_short         bg;                     /* background color */
   54 } color_t;
   55 
   56 typedef struct {
   57         int             flags;
   58 #define SCTERM_BUSY     (1 << 0)
   59         int             esc;
   60         int             num_param;
   61         int             last_param;
   62         int             param[MAX_ESC_PAR];
   63         int             saved_xpos;
   64         int             saved_ypos;
   65         int             attr_mask;              /* current logical attr mask */
   66 #define NORMAL_ATTR     0x00
   67 #define BLINK_ATTR      0x01
   68 #define BOLD_ATTR       0x02
   69 #define UNDERLINE_ATTR  0x04
   70 #define REVERSE_ATTR    0x08
   71 #define FG_CHANGED      0x10
   72 #define BG_CHANGED      0x20
   73         int             cur_attr;               /* current hardware attr word */
   74         color_t         cur_color;              /* current hardware color */
   75         color_t         std_color;              /* normal hardware color */
   76         color_t         rev_color;              /* reverse hardware color */
   77         color_t         dflt_std_color;         /* default normal color */
   78         color_t         dflt_rev_color;         /* default reverse color */
   79 } term_stat;
   80 
   81 static sc_term_init_t   scterm_init;
   82 static sc_term_term_t   scterm_term;
   83 static sc_term_puts_t   scterm_puts;
   84 static sc_term_ioctl_t  scterm_ioctl;
   85 static sc_term_reset_t  scterm_reset;
   86 static sc_term_default_attr_t   scterm_default_attr;
   87 static sc_term_clear_t  scterm_clear;
   88 static sc_term_notify_t scterm_notify;
   89 static sc_term_input_t  scterm_input;
   90 static sc_term_fkeystr_t        scterm_fkeystr;
   91 static sc_term_sync_t   scterm_sync;
   92 
   93 static sc_term_sw_t sc_term_sc = {
   94         { NULL, NULL },
   95         "sc",                                   /* emulator name */
   96         "syscons terminal",                     /* description */
   97         "*",                                    /* matching renderer, any :-) */
   98         sizeof(term_stat),                      /* softc size */
   99         0,
  100         scterm_init,
  101         scterm_term,
  102         scterm_puts,
  103         scterm_ioctl,
  104         scterm_reset,
  105         scterm_default_attr,
  106         scterm_clear,
  107         scterm_notify,
  108         scterm_input,
  109         scterm_fkeystr,
  110         scterm_sync,
  111 };
  112 
  113 SCTERM_MODULE(sc, sc_term_sc);
  114 
  115 static term_stat        reserved_term_stat;
  116 static void             scterm_scan_esc(scr_stat *scp, term_stat *tcp,
  117                                         u_char c);
  118 static int              mask2attr(term_stat *tcp);
  119 
  120 static int
  121 scterm_init(scr_stat *scp, void **softc, int code)
  122 {
  123         term_stat *tcp;
  124 
  125         if (*softc == NULL) {
  126                 if (reserved_term_stat.flags & SCTERM_BUSY)
  127                         return EINVAL;
  128                 *softc = &reserved_term_stat;
  129         }
  130         tcp = *softc;
  131 
  132         switch (code) {
  133         case SC_TE_COLD_INIT:
  134                 bzero(tcp, sizeof(*tcp));
  135                 tcp->flags = SCTERM_BUSY;
  136                 tcp->esc = 0;
  137                 tcp->saved_xpos = -1;
  138                 tcp->saved_ypos = -1;
  139                 tcp->attr_mask = NORMAL_ATTR;
  140                 /* XXX */
  141                 tcp->dflt_std_color.fg = SC_NORM_ATTR & 0x0f;
  142                 tcp->dflt_std_color.bg = (SC_NORM_ATTR >> 4) & 0x0f;
  143                 tcp->dflt_rev_color.fg = SC_NORM_REV_ATTR & 0x0f;
  144                 tcp->dflt_rev_color.bg = (SC_NORM_REV_ATTR >> 4) & 0x0f;
  145                 tcp->std_color = tcp->dflt_std_color;
  146                 tcp->rev_color = tcp->dflt_rev_color;
  147                 tcp->cur_color = tcp->std_color;
  148                 tcp->cur_attr = mask2attr(tcp);
  149                 ++sc_term_sc.te_refcount;
  150                 break;
  151 
  152         case SC_TE_WARM_INIT:
  153                 tcp->esc = 0;
  154                 tcp->saved_xpos = -1;
  155                 tcp->saved_ypos = -1;
  156 #if 0
  157                 tcp->std_color = tcp->dflt_std_color;
  158                 tcp->rev_color = tcp->dflt_rev_color;
  159 #endif
  160                 tcp->cur_color = tcp->std_color;
  161                 tcp->cur_attr = mask2attr(tcp);
  162                 break;
  163         }
  164 
  165         return 0;
  166 }
  167 
  168 static int
  169 scterm_term(scr_stat *scp, void **softc)
  170 {
  171         if (*softc == &reserved_term_stat) {
  172                 *softc = NULL;
  173                 bzero(&reserved_term_stat, sizeof(reserved_term_stat));
  174         }
  175         --sc_term_sc.te_refcount;
  176         return 0;
  177 }
  178 
  179 static void
  180 scterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c)
  181 {
  182         static u_char ansi_col[16] = {
  183                 FG_BLACK,     FG_RED,          FG_GREEN,      FG_BROWN,
  184                 FG_BLUE,      FG_MAGENTA,      FG_CYAN,       FG_LIGHTGREY,
  185                 FG_DARKGREY,  FG_LIGHTRED,     FG_LIGHTGREEN, FG_YELLOW,
  186                 FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN,  FG_WHITE
  187         };
  188         static int cattrs[] = {
  189                 0,                                      /* block */
  190                 CONS_BLINK_CURSOR,                      /* blinking block */
  191                 CONS_CHAR_CURSOR,                       /* underline */
  192                 CONS_CHAR_CURSOR | CONS_BLINK_CURSOR,   /* blinking underline */
  193                 CONS_RESET_CURSOR,                      /* reset to default */
  194                 CONS_HIDDEN_CURSOR,                     /* hide cursor */
  195         };
  196         static int tcattrs[] = {
  197                 CONS_RESET_CURSOR | CONS_LOCAL_CURSOR,  /* normal */
  198                 CONS_HIDDEN_CURSOR | CONS_LOCAL_CURSOR, /* invisible */
  199                 CONS_BLINK_CURSOR | CONS_LOCAL_CURSOR,  /* very visible */
  200         };
  201         sc_softc_t *sc;
  202         int v0, v1, v2;
  203         int i, n;
  204 
  205         i = n = 0;
  206         sc = scp->sc; 
  207         if (tcp->esc == 1) {    /* seen ESC */
  208                 switch (c) {
  209                 case '7':       /* Save cursor position */
  210                         tcp->saved_xpos = scp->xpos;
  211                         tcp->saved_ypos = scp->ypos;
  212                         break;
  213 
  214                 case '8':       /* Restore saved cursor position */
  215                         if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
  216                                 sc_move_cursor(scp, tcp->saved_xpos,
  217                                                tcp->saved_ypos);
  218                         break;
  219 
  220                 case '[':       /* Start ESC [ sequence */
  221                         tcp->esc = 2;
  222                         tcp->last_param = -1;
  223                         for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
  224                                 tcp->param[i] = 1;
  225                         tcp->num_param = 0;
  226                         return;
  227 
  228                 case 'M':       /* Move cursor up 1 line, scroll if at top */
  229                         sc_term_up_scroll(scp, 1, sc->scr_map[0x20],
  230                                           tcp->cur_attr, 0, 0);
  231                         break;
  232 #ifdef notyet
  233                 case 'Q':
  234                         tcp->esc = 4;
  235                         return;
  236 #endif
  237                 case 'c':       /* reset */
  238                         tcp->attr_mask = NORMAL_ATTR;
  239                         tcp->cur_color = tcp->std_color
  240                                        = tcp->dflt_std_color;
  241                         tcp->rev_color = tcp->dflt_rev_color;
  242                         tcp->cur_attr = mask2attr(tcp);
  243                         sc_change_cursor_shape(scp,
  244                             CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, -1, -1);
  245                         sc_clear_screen(scp);
  246                         break;
  247 
  248                 case '(':       /* iso-2022: designate 94 character set to G0 */
  249                         tcp->esc = 5;
  250                         return;
  251                 }
  252         } else if (tcp->esc == 2) {     /* seen ESC [ */
  253                 if (c >= '' && c <= '9') {
  254                         if (tcp->num_param < MAX_ESC_PAR) {
  255                                 if (tcp->last_param != tcp->num_param) {
  256                                         tcp->last_param = tcp->num_param;
  257                                         tcp->param[tcp->num_param] = 0;
  258                                 } else {
  259                                         tcp->param[tcp->num_param] *= 10;
  260                                 }
  261                                 tcp->param[tcp->num_param] += c - '';
  262                                 return;
  263                         }
  264                 }
  265                 tcp->num_param = tcp->last_param + 1;
  266                 switch (c) {
  267                 case ';':
  268                         if (tcp->num_param < MAX_ESC_PAR)
  269                                 return;
  270                         break;
  271 
  272                 case '=':
  273                         tcp->esc = 3;
  274                         tcp->last_param = -1;
  275                         for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
  276                                 tcp->param[i] = 1;
  277                         tcp->num_param = 0;
  278                         return;
  279 
  280                 case 'A':       /* up n rows */
  281                         sc_term_up(scp, tcp->param[0], 0);
  282                         break;
  283 
  284                 case 'B':       /* down n rows */
  285                         sc_term_down(scp, tcp->param[0], 0);
  286                         break;
  287 
  288                 case 'C':       /* right n columns */
  289                         sc_term_right(scp, tcp->param[0]);
  290                         break;
  291 
  292                 case 'D':       /* left n columns */
  293                         sc_term_left(scp, tcp->param[0]);
  294                         break;
  295 
  296                 case 'E':       /* cursor to start of line n lines down */
  297                         n = tcp->param[0];
  298                         if (n < 1)
  299                                 n = 1;
  300                         sc_move_cursor(scp, 0, scp->ypos + n);
  301                         break;
  302 
  303                 case 'F':       /* cursor to start of line n lines up */
  304                         n = tcp->param[0];
  305                         if (n < 1)
  306                                 n = 1;
  307                         sc_move_cursor(scp, 0, scp->ypos - n);
  308                         break;
  309 
  310                 case 'f':       /* Cursor move */
  311                 case 'H':
  312                         if (tcp->num_param == 0)
  313                                 sc_move_cursor(scp, 0, 0);
  314                         else if (tcp->num_param == 2)
  315                                 sc_move_cursor(scp, tcp->param[1] - 1,
  316                                                tcp->param[0] - 1);
  317                         break;
  318 
  319                 case 'J':       /* Clear all or part of display */
  320                         if (tcp->num_param == 0)
  321                                 n = 0;
  322                         else
  323                                 n = tcp->param[0];
  324                         sc_term_clr_eos(scp, n, sc->scr_map[0x20],
  325                                         tcp->cur_attr);
  326                         break;
  327 
  328                 case 'K':       /* Clear all or part of line */
  329                         if (tcp->num_param == 0)
  330                                 n = 0;
  331                         else
  332                                 n = tcp->param[0];
  333                         sc_term_clr_eol(scp, n, sc->scr_map[0x20],
  334                                         tcp->cur_attr);
  335                         break;
  336 
  337                 case 'L':       /* Insert n lines */
  338                         sc_term_ins_line(scp, scp->ypos, tcp->param[0],
  339                                          sc->scr_map[0x20], tcp->cur_attr, 0);
  340                         break;
  341 
  342                 case 'M':       /* Delete n lines */
  343                         sc_term_del_line(scp, scp->ypos, tcp->param[0],
  344                                          sc->scr_map[0x20], tcp->cur_attr, 0);
  345                         break;
  346 
  347                 case 'P':       /* Delete n chars */
  348                         sc_term_del_char(scp, tcp->param[0],
  349                                          sc->scr_map[0x20], tcp->cur_attr);
  350                         break;
  351 
  352                 case '@':       /* Insert n chars */
  353                         sc_term_ins_char(scp, tcp->param[0],
  354                                          sc->scr_map[0x20], tcp->cur_attr);
  355                         break;
  356 
  357                 case 'S':       /* scroll up n lines */
  358                         sc_term_del_line(scp, 0, tcp->param[0],
  359                                          sc->scr_map[0x20], tcp->cur_attr, 0);
  360                         break;
  361 
  362                 case 'T':       /* scroll down n lines */
  363                         sc_term_ins_line(scp, 0, tcp->param[0],
  364                                          sc->scr_map[0x20], tcp->cur_attr, 0);
  365                         break;
  366 
  367                 case 'X':       /* erase n characters in line */
  368                         n = tcp->param[0];
  369                         if (n < 1)
  370                                 n = 1;
  371                         if (n > scp->xsize - scp->xpos)
  372                                 n = scp->xsize - scp->xpos;
  373                         sc_vtb_erase(&scp->vtb, scp->cursor_pos, n,
  374                                      sc->scr_map[0x20], tcp->cur_attr);
  375                         mark_for_update(scp, scp->cursor_pos);
  376                         mark_for_update(scp, scp->cursor_pos + n - 1);
  377                         break;
  378 
  379                 case 'Z':       /* move n tabs backwards */
  380                         sc_term_backtab(scp, tcp->param[0]);
  381                         break;
  382 
  383                 case '`':       /* move cursor to column n */
  384                         sc_term_col(scp, tcp->param[0]);
  385                         break;
  386 
  387                 case 'a':       /* move cursor n columns to the right */
  388                         sc_term_right(scp, tcp->param[0]);
  389                         break;
  390 
  391                 case 'd':       /* move cursor to row n */
  392                         sc_term_row(scp, tcp->param[0]);
  393                         break;
  394 
  395                 case 'e':       /* move cursor n rows down */
  396                         sc_term_down(scp, tcp->param[0], 0);
  397                         break;
  398 
  399                 case 'm':       /* change attribute */
  400                         if (tcp->num_param == 0) {
  401                                 tcp->attr_mask = NORMAL_ATTR;
  402                                 tcp->cur_color = tcp->std_color;
  403                                 tcp->cur_attr = mask2attr(tcp);
  404                                 break;
  405                         }
  406                         for (i = 0; i < tcp->num_param; i++) {
  407                                 switch (n = tcp->param[i]) {
  408                                 case 0: /* back to normal */
  409                                         tcp->attr_mask = NORMAL_ATTR;
  410                                         tcp->cur_color = tcp->std_color;
  411                                         tcp->cur_attr = mask2attr(tcp);
  412                                         break;
  413                                 case 1: /* bold */
  414                                         tcp->attr_mask |= BOLD_ATTR;
  415                                         tcp->cur_attr = mask2attr(tcp);
  416                                         break;
  417                                 case 4: /* underline */
  418                                         tcp->attr_mask |= UNDERLINE_ATTR;
  419                                         tcp->cur_attr = mask2attr(tcp);
  420                                         break;
  421                                 case 5: /* blink */
  422                                         tcp->attr_mask |= BLINK_ATTR;
  423                                         tcp->cur_attr = mask2attr(tcp);
  424                                         break;
  425                                 case 7: /* reverse */
  426                                         tcp->attr_mask |= REVERSE_ATTR;
  427                                         tcp->cur_attr = mask2attr(tcp);
  428                                         break;
  429                                 case 22: /* remove bold (or dim) */
  430                                         tcp->attr_mask &= ~BOLD_ATTR;
  431                                         tcp->cur_attr = mask2attr(tcp);
  432                                         break;
  433                                 case 24: /* remove underline */
  434                                         tcp->attr_mask &= ~UNDERLINE_ATTR;
  435                                         tcp->cur_attr = mask2attr(tcp);
  436                                         break;
  437                                 case 25: /* remove blink */
  438                                         tcp->attr_mask &= ~BLINK_ATTR;
  439                                         tcp->cur_attr = mask2attr(tcp);
  440                                         break;
  441                                 case 27: /* remove reverse */
  442                                         tcp->attr_mask &= ~REVERSE_ATTR;
  443                                         tcp->cur_attr = mask2attr(tcp);
  444                                         break;
  445                                 case 30: case 31: /* set ansi fg color */
  446                                 case 32: case 33: case 34:
  447                                 case 35: case 36: case 37:
  448                                         tcp->attr_mask |= FG_CHANGED;
  449                                         tcp->cur_color.fg = ansi_col[n - 30];
  450                                         tcp->cur_attr = mask2attr(tcp);
  451                                         break;
  452                                 case 39: /* restore fg color back to normal */
  453                                         tcp->attr_mask &= ~(FG_CHANGED|BOLD_ATTR);
  454                                         tcp->cur_color.fg = tcp->std_color.fg;
  455                                         tcp->cur_attr = mask2attr(tcp);
  456                                         break;
  457                                 case 40: case 41: /* set ansi bg color */
  458                                 case 42: case 43: case 44:
  459                                 case 45: case 46: case 47:
  460                                         tcp->attr_mask |= BG_CHANGED;
  461                                         tcp->cur_color.bg = ansi_col[n - 40];
  462                                         tcp->cur_attr = mask2attr(tcp);
  463                                         break;
  464                                 case 49: /* restore bg color back to normal */
  465                                         tcp->attr_mask &= ~BG_CHANGED;
  466                                         tcp->cur_color.bg = tcp->std_color.bg;
  467                                         tcp->cur_attr = mask2attr(tcp);
  468                                         break;
  469                                 }
  470                         }
  471                         break;
  472 
  473                 case 's':       /* Save cursor position */
  474                         tcp->saved_xpos = scp->xpos;
  475                         tcp->saved_ypos = scp->ypos;
  476                         break;
  477 
  478                 case 'u':       /* Restore saved cursor position */
  479                         if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
  480                                 sc_move_cursor(scp, tcp->saved_xpos,
  481                                                tcp->saved_ypos);
  482                         break;
  483 
  484                 case 'x':
  485                         if (tcp->num_param == 0)
  486                                 n = 0;
  487                         else
  488                                 n = tcp->param[0];
  489                         switch (n) {
  490                         case 0: /* reset colors and attributes back to normal */
  491                                 tcp->attr_mask = NORMAL_ATTR;
  492                                 tcp->cur_color = tcp->std_color
  493                                                = tcp->dflt_std_color;
  494                                 tcp->rev_color = tcp->dflt_rev_color;
  495                                 tcp->cur_attr = mask2attr(tcp);
  496                                 break;
  497                         case 1: /* set ansi background */
  498                                 tcp->attr_mask &= ~BG_CHANGED;
  499                                 tcp->cur_color.bg = tcp->std_color.bg
  500                                                   = ansi_col[tcp->param[1] & 0x0f];
  501                                 tcp->cur_attr = mask2attr(tcp);
  502                                 break;
  503                         case 2: /* set ansi foreground */
  504                                 tcp->attr_mask &= ~FG_CHANGED;
  505                                 tcp->cur_color.fg = tcp->std_color.fg
  506                                                   = ansi_col[tcp->param[1] & 0x0f];
  507                                 tcp->cur_attr = mask2attr(tcp);
  508                                 break;
  509                         case 3: /* set adapter attribute directly */
  510                                 tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED);
  511                                 tcp->cur_color.fg = tcp->std_color.fg
  512                                                   = tcp->param[1] & 0x0f;
  513                                 tcp->cur_color.bg = tcp->std_color.bg
  514                                                   = (tcp->param[1] >> 4) & 0x0f;
  515                                 tcp->cur_attr = mask2attr(tcp);
  516                                 break;
  517                         case 5: /* set ansi reverse background */
  518                                 tcp->rev_color.bg = ansi_col[tcp->param[1] & 0x0f];
  519                                 tcp->cur_attr = mask2attr(tcp);
  520                                 break;
  521                         case 6: /* set ansi reverse foreground */
  522                                 tcp->rev_color.fg = ansi_col[tcp->param[1] & 0x0f];
  523                                 tcp->cur_attr = mask2attr(tcp);
  524                                 break;
  525                         case 7: /* set adapter reverse attribute directly */
  526                                 tcp->rev_color.fg = tcp->param[1] & 0x0f;
  527                                 tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f;
  528                                 tcp->cur_attr = mask2attr(tcp);
  529                                 break;
  530                         }
  531                         break;
  532 
  533                 case 'z':       /* switch to (virtual) console n */
  534                         if (tcp->num_param == 1)
  535                                 sc_switch_scr(sc, tcp->param[0]);
  536                         break;
  537                 }
  538         } else if (tcp->esc == 3) {     /* seen ESC [0-9]+ = */
  539                 if (c >= '' && c <= '9') {
  540                         if (tcp->num_param < MAX_ESC_PAR) {
  541                                 if (tcp->last_param != tcp->num_param) {
  542                                         tcp->last_param = tcp->num_param;
  543                                         tcp->param[tcp->num_param] = 0;
  544                                 } else {
  545                                         tcp->param[tcp->num_param] *= 10;
  546                                 }
  547                                 tcp->param[tcp->num_param] += c - '';
  548                                 return;
  549                         }
  550                 }
  551                 tcp->num_param = tcp->last_param + 1;
  552                 switch (c) {
  553                 case ';':
  554                         if (tcp->num_param < MAX_ESC_PAR)
  555                                 return;
  556                         break;
  557 
  558                 case 'A':   /* set display border color */
  559                         if (tcp->num_param == 1) {
  560                                 scp->border=tcp->param[0] & 0xff;
  561                                 if (scp == sc->cur_scp)
  562                                         sc_set_border(scp, scp->border);
  563                         }
  564                         break;
  565 
  566                 case 'B':   /* set bell pitch and duration */
  567                         if (tcp->num_param == 2) {
  568                                 scp->bell_pitch = tcp->param[0];
  569                                 scp->bell_duration = 
  570                                     (tcp->param[1] * hz + 99) / 100;
  571                         }
  572                         break;
  573 
  574                 case 'C':   /* set global/parmanent cursor type & shape */
  575                         i = spltty();
  576                         n = tcp->num_param;
  577                         v0 = tcp->param[0];
  578                         v1 = tcp->param[1];
  579                         v2 = tcp->param[2];
  580                         switch (n) {
  581                         case 1: /* flags only */
  582                                 if (v0 < sizeof(cattrs)/sizeof(cattrs[0]))
  583                                         v0 = cattrs[v0];
  584                                 else    /* backward compatibility */
  585                                         v0 = cattrs[v0 & 0x3];
  586                                 sc_change_cursor_shape(scp, v0, -1, -1);
  587                                 break;
  588                         case 2:
  589                                 v2 = 0;
  590                                 v0 &= 0x1f;     /* backward compatibility */
  591                                 v1 &= 0x1f;
  592                                 /* FALL THROUGH */
  593                         case 3: /* base and height */
  594                                 if (v2 == 0)    /* count from top */
  595                                         sc_change_cursor_shape(scp, -1,
  596                                             scp->font_size - v1 - 1,
  597                                             v1 - v0 + 1);
  598                                 else if (v2 == 1) /* count from bottom */
  599                                         sc_change_cursor_shape(scp, -1,
  600                                             v0, v1 - v0 + 1);
  601                                 break;
  602                         }
  603                         splx(i);
  604                         break;
  605 
  606                 case 'F':   /* set adapter foreground */
  607                         if (tcp->num_param == 1) {
  608                                 tcp->attr_mask &= ~FG_CHANGED;
  609                                 tcp->cur_color.fg = tcp->std_color.fg
  610                                                   = tcp->param[0] & 0x0f;
  611                                 tcp->cur_attr = mask2attr(tcp);
  612                         }
  613                         break;
  614 
  615                 case 'G':   /* set adapter background */
  616                         if (tcp->num_param == 1) {
  617                                 tcp->attr_mask &= ~BG_CHANGED;
  618                                 tcp->cur_color.bg = tcp->std_color.bg
  619                                                   = tcp->param[0] & 0x0f;
  620                                 tcp->cur_attr = mask2attr(tcp);
  621                         }
  622                         break;
  623 
  624                 case 'H':   /* set adapter reverse foreground */
  625                         if (tcp->num_param == 1) {
  626                                 tcp->rev_color.fg = tcp->param[0] & 0x0f;
  627                                 tcp->cur_attr = mask2attr(tcp);
  628                         }
  629                         break;
  630 
  631                 case 'I':   /* set adapter reverse background */
  632                         if (tcp->num_param == 1) {
  633                                 tcp->rev_color.bg = tcp->param[0] & 0x0f;
  634                                 tcp->cur_attr = mask2attr(tcp);
  635                         }
  636                         break;
  637 
  638                 case 'S':   /* set local/temporary cursor type & shape */
  639                         i = spltty();
  640                         n = tcp->num_param;
  641                         v0 = tcp->param[0];
  642                         switch (n) {
  643                         case 0:
  644                                 v0 = 0;
  645                                 /* FALL THROUGH */
  646                         case 1:
  647                                 if (v0 < sizeof(tcattrs)/sizeof(tcattrs[0]))
  648                                         sc_change_cursor_shape(scp,
  649                                             tcattrs[v0], -1, -1);
  650                                 break;
  651                         }
  652                         splx(i);
  653                         break;
  654                 }
  655 #ifdef notyet
  656         } else if (tcp->esc == 4) {     /* seen ESC Q */
  657                 /* to be filled */
  658 #endif
  659         } else if (tcp->esc == 5) {     /* seen ESC ( */
  660                 switch (c) {
  661                 case 'B':   /* iso-2022: desginate ASCII into G0 */
  662                         break;
  663                 /* other items to be filled */
  664                 default:
  665                         break;
  666                 }
  667         }
  668         tcp->esc = 0;
  669 }
  670 
  671 static void
  672 scterm_puts(scr_stat *scp, u_char *buf, int len)
  673 {
  674         term_stat *tcp;
  675 
  676         tcp = scp->ts;
  677 outloop:
  678         scp->sc->write_in_progress++;
  679 
  680         if (tcp->esc) {
  681                 scterm_scan_esc(scp, tcp, *buf);
  682                 buf++;
  683                 len--;
  684         } else {
  685                 switch (*buf) {
  686                 case 0x1b:
  687                         tcp->esc = 1;
  688                         tcp->num_param = 0;
  689                         buf++;
  690                         len--;
  691                         break;
  692                 default:
  693                         sc_term_gen_print(scp, &buf, &len, tcp->cur_attr);
  694                         break;
  695                 }
  696         }
  697 
  698         sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr);
  699 
  700         scp->sc->write_in_progress--;
  701         if (len)
  702                 goto outloop;
  703 }
  704 
  705 static int
  706 scterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
  707              struct thread *td)
  708 {
  709         term_stat *tcp = scp->ts;
  710         vid_info_t *vi;
  711 
  712         switch (cmd) {
  713         case GIO_ATTR:          /* get current attributes */
  714                 /* FIXME: */
  715                 *(int*)data = (tcp->cur_attr >> 8) & 0xff;
  716                 return 0;
  717         case CONS_GETINFO:      /* get current (virtual) console info */
  718                 vi = (vid_info_t *)data;
  719                 if (vi->size != sizeof(struct vid_info))
  720                         return EINVAL;
  721                 vi->mv_norm.fore = tcp->std_color.fg;
  722                 vi->mv_norm.back = tcp->std_color.bg;
  723                 vi->mv_rev.fore = tcp->rev_color.fg;
  724                 vi->mv_rev.back = tcp->rev_color.bg;
  725                 /*
  726                  * The other fields are filled by the upper routine. XXX
  727                  */
  728                 return ENOIOCTL;
  729         }
  730         return ENOIOCTL;
  731 }
  732 
  733 static int
  734 scterm_reset(scr_stat *scp, int code)
  735 {
  736         /* FIXME */
  737         return 0;
  738 }
  739 
  740 static void
  741 scterm_default_attr(scr_stat *scp, int color, int rev_color)
  742 {
  743         term_stat *tcp = scp->ts;
  744 
  745         tcp->dflt_std_color.fg = color & 0x0f;
  746         tcp->dflt_std_color.bg = (color >> 4) & 0x0f;
  747         tcp->dflt_rev_color.fg = rev_color & 0x0f;
  748         tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f;
  749         tcp->std_color = tcp->dflt_std_color;
  750         tcp->rev_color = tcp->dflt_rev_color;
  751         tcp->cur_color = tcp->std_color;
  752         tcp->cur_attr = mask2attr(tcp);
  753 }
  754 
  755 static void
  756 scterm_clear(scr_stat *scp)
  757 {
  758         term_stat *tcp = scp->ts;
  759 
  760         sc_move_cursor(scp, 0, 0);
  761         sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr);
  762         mark_all(scp);
  763 }
  764 
  765 static void
  766 scterm_notify(scr_stat *scp, int event)
  767 {
  768         switch (event) {
  769         case SC_TE_NOTIFY_VTSWITCH_IN:
  770                 break;
  771         case SC_TE_NOTIFY_VTSWITCH_OUT:
  772                 break;
  773         }
  774 }
  775 
  776 static int
  777 scterm_input(scr_stat *scp, int c, struct tty *tp)
  778 {
  779         return FALSE;
  780 }
  781 
  782 static const char *
  783 scterm_fkeystr(scr_stat *scp, int c)
  784 {
  785         return (NULL);
  786 }
  787 
  788 static void
  789 scterm_sync(scr_stat *scp)
  790 {
  791 }
  792 
  793 /*
  794  * Calculate hardware attributes word using logical attributes mask and
  795  * hardware colors
  796  */
  797 
  798 /* FIXME */
  799 static int
  800 mask2attr(term_stat *tcp)
  801 {
  802         int attr, mask = tcp->attr_mask;
  803 
  804         if (mask & REVERSE_ATTR) {
  805                 attr = ((mask & FG_CHANGED) ?
  806                         tcp->cur_color.bg : tcp->rev_color.fg) |
  807                         (((mask & BG_CHANGED) ?
  808                         tcp->cur_color.fg : tcp->rev_color.bg) << 4);
  809         } else
  810                 attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4);
  811 
  812         /* XXX: underline mapping for Hercules adapter can be better */
  813         if (mask & (BOLD_ATTR | UNDERLINE_ATTR))
  814                 attr ^= 0x08;
  815         if (mask & BLINK_ATTR)
  816                 attr ^= 0x80;
  817 
  818         return (attr << 8);
  819 }

Cache object: 8c5f0e3487597c2eade6f71806322867


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.