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/pc98/cbus/scterm-sck.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 FreeBSD(98) Porting Team.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer as
   10  *    the first lines of this file unmodified.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include "opt_syscons.h"
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/kernel.h>
   35 #include <sys/module.h>
   36 #include <sys/consio.h>
   37 
   38 #include <machine/pc/display.h>
   39 
   40 #include <dev/syscons/syscons.h>
   41 #include <pc98/cbus/sctermvar.h>
   42 
   43 #define MAX_ESC_PAR     5
   44 
   45 #ifdef KANJI
   46 #define IS_KTYPE_ASCII_or_HANKAKU(A)    (!((A) & 0xee))
   47 #define IS_KTYPE_KANA(A)                ((A) & 0x11)
   48 #define KTYPE_MASK_CTRL(A)              ((A) &= 0xF0)
   49 #endif /* KANJI */
   50 
   51 /* attribute flags */
   52 typedef struct {
   53         u_short         fg;                     /* foreground color */
   54         u_short         bg;                     /* background color */
   55 } color_t;
   56 
   57 typedef struct {
   58         int             flags;
   59 #define SCTERM_BUSY     (1 << 0)
   60         int             esc;
   61         int             num_param;
   62         int             last_param;
   63         int             param[MAX_ESC_PAR];
   64         int             saved_xpos;
   65         int             saved_ypos;
   66 
   67 #ifdef KANJI
   68         u_char          kanji_1st_char;
   69         u_char          kanji_type;
   70 #define KTYPE_ASCII     0                       /* ASCII */
   71 #define KTYPE_KANA      1                       /* HANKAKU */
   72 #define KTYPE_JKANA     0x10                    /* JIS HANKAKU */
   73 #define KTYPE_7JIS      0x20                    /* JIS */
   74 #define KTYPE_SJIS      2                       /* Shift JIS */
   75 #define KTYPE_UJIS      4                       /* UJIS */
   76 #define KTYPE_SUKANA    3                       /* Shift JIS or UJIS HANKAKU */
   77 #define KTYPE_SUJIS     6                       /* SHift JIS or UJIS */
   78 #define KTYPE_KANIN     0x80                    /* Kanji Invoke sequence */
   79 #define KTYPE_ASCIN     0x40                    /* ASCII Invoke sequence */
   80 #endif /* KANJI */
   81 
   82         int             attr_mask;              /* current logical attr mask */
   83 #define NORMAL_ATTR     0x00
   84 #define BLINK_ATTR      0x01
   85 #define BOLD_ATTR       0x02
   86 #define UNDERLINE_ATTR  0x04
   87 #define REVERSE_ATTR    0x08
   88 #define FG_CHANGED      0x10
   89 #define BG_CHANGED      0x20
   90         int             cur_attr;               /* current hardware attr word */
   91         color_t         cur_color;              /* current hardware color */
   92         color_t         std_color;              /* normal hardware color */
   93         color_t         rev_color;              /* reverse hardware color */
   94         color_t         dflt_std_color;         /* default normal color */
   95         color_t         dflt_rev_color;         /* default reverse color */
   96 } term_stat;
   97 
   98 static sc_term_init_t           scterm_init;
   99 static sc_term_term_t           scterm_term;
  100 static sc_term_puts_t           scterm_puts;
  101 static sc_term_ioctl_t          scterm_ioctl;
  102 static sc_term_reset_t          scterm_reset;
  103 static sc_term_default_attr_t   scterm_default_attr;
  104 static sc_term_clear_t          scterm_clear;
  105 static sc_term_notify_t         scterm_notify;
  106 static sc_term_input_t          scterm_input;
  107 static sc_term_fkeystr_t        scterm_fkeystr;
  108 
  109 static sc_term_sw_t sc_term_sc = {
  110         { NULL, NULL },
  111         "sck",                                  /* emulator name */
  112         "syscons kanji terminal",               /* description */
  113         "*",                                    /* matching renderer, any :-) */
  114         sizeof(term_stat),                      /* softc size */
  115         0,
  116         scterm_init,
  117         scterm_term,
  118         scterm_puts,
  119         scterm_ioctl,
  120         scterm_reset,
  121         scterm_default_attr,
  122         scterm_clear,
  123         scterm_notify,
  124         scterm_input,
  125         scterm_fkeystr,
  126 };
  127 
  128 SCTERM_MODULE(sc, sc_term_sc);
  129 
  130 static term_stat        reserved_term_stat;
  131 static int              default_kanji = UJIS;
  132 static void             scterm_scan_esc(scr_stat *scp, term_stat *tcp,
  133                                         u_char c);
  134 static int              mask2attr(term_stat *tcp);
  135 
  136 #ifdef KANJI
  137 static inline u_char
  138 iskanji1(u_char mode, u_char c)
  139 {
  140         if (c > 0x80) {
  141                 if ((c >= 0xa1) && (c <= 0xdf)) {
  142                         if (default_kanji == UJIS) {
  143                                 /* UJIS */
  144                                 return KTYPE_UJIS;
  145                         }
  146                         if (default_kanji == SJIS) {
  147                                 /* SJIS HANKAKU */
  148                                 return KTYPE_KANA;
  149                         }
  150                 }
  151 
  152                 if (c <= 0x9f) {
  153                         if (c == 0x8e) {
  154                                 /* SJIS or UJIS HANKAKU */
  155                                 return KTYPE_SUKANA;
  156                         }
  157 
  158                         /* SJIS */
  159                         default_kanji = SJIS;
  160                         return KTYPE_SJIS;
  161                 }
  162 
  163                 if ((c >= 0xe0) && (c <= 0xef)) {
  164                         /* SJIS or UJIS */
  165                         return KTYPE_SUJIS;
  166                 }
  167 
  168                 if ((c >= 0xf0) && (c <= 0xfe)) {
  169                         /* UJIS */
  170                         default_kanji = UJIS;
  171                         return KTYPE_UJIS;
  172                 }
  173         } else {
  174                 if ((mode == KTYPE_7JIS) && (c >= 0x21) && (c <= 0x7e)) {
  175                         /* JIS */
  176                         default_kanji = UJIS;
  177                         return KTYPE_7JIS;
  178                 }
  179 
  180                 if ((mode == KTYPE_JKANA) && (c >= 0x21) && (c <= 0x5f)) {
  181                         /* JIS HANKAKU */
  182                         default_kanji = UJIS;
  183                         return KTYPE_JKANA;
  184                 }
  185         }
  186 
  187         return KTYPE_ASCII;
  188 }
  189 
  190 static inline u_char
  191 iskanji2(u_char mode, u_char c)
  192 {
  193         switch (mode) {
  194         case KTYPE_7JIS:
  195                 if ((c >= 0x21) && (c <= 0x7e)) {
  196                         /* JIS */
  197                         return KTYPE_7JIS;
  198                 }
  199                 break;
  200         case KTYPE_SJIS:
  201                 if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) {
  202                         /* SJIS */
  203                         return KTYPE_SJIS;
  204                 }
  205                 break;
  206         case KTYPE_UJIS:
  207                 if ((c >= 0xa1) && (c <= 0xfe)) {
  208                         /* UJIS */
  209                         return KTYPE_UJIS;
  210                 }
  211                 break;
  212         case KTYPE_SUKANA:
  213                 if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) {
  214                         /* UJIS HANKAKU */
  215                         return KTYPE_KANA;
  216                 }
  217                 if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) {
  218                         /* SJIS */
  219                         default_kanji = SJIS;
  220                         return KTYPE_SJIS;
  221                 }
  222                 break;
  223         case KTYPE_SUJIS:
  224                 if ((c >= 0x40) && (c <= 0xa0) && (c != 0x7f)) {
  225                         /* SJIS */
  226                         default_kanji = SJIS;
  227                         return KTYPE_SJIS;
  228                 }
  229                 if ((c == 0xfd) || (c == 0xfe)) {
  230                         /* UJIS */
  231                         default_kanji = UJIS;
  232                         return KTYPE_UJIS;
  233                 }
  234                 if ((c >= 0xa1) && (c <= 0xfc)) {
  235                         if (default_kanji == SJIS)
  236                                 return KTYPE_SJIS;
  237                         if (default_kanji == UJIS)
  238                                 return KTYPE_UJIS;
  239                 }
  240                 break;
  241         }
  242 
  243         return KTYPE_ASCII;
  244 }
  245 
  246 /*
  247  * JIS X0208-83 keisen conversion table
  248  */
  249 static u_short keiConv[32] = {
  250         0x240c, 0x260c, 0x300c, 0x340c, 0x3c0c, 0x380c, 0x400c, 0x500c,
  251         0x480c, 0x580c, 0x600c, 0x250c, 0x270c, 0x330c, 0x370c, 0x3f0c,
  252         0x3b0c, 0x470c, 0x570c, 0x4f0c, 0x5f0c, 0x6f0c, 0x440c, 0x530c,
  253         0x4c0c, 0x5b0c, 0x630c, 0x410c, 0x540c, 0x490c, 0x5c0c, 0x660c
  254 };
  255 
  256 static u_short
  257 kanji_convert(u_char mode, u_char h, u_char l)
  258 {
  259         u_short tmp, high, low, c;
  260 
  261         high = (u_short) h;
  262         low  = (u_short) l;
  263 
  264         switch (mode) {
  265         case KTYPE_SJIS: /* SHIFT JIS */
  266                 if (low >= 0xe0) {
  267                         low -= 0x40;
  268                 }
  269                 low = (low - 0x81) * 2 + 0x21;
  270                 if (high > 0x7f) {
  271                         high--;
  272                 }
  273                 if (high > 0x9d) {
  274                         low++;
  275                         high -= 0x9e - 0x21;
  276                 } else {
  277                         high -= 0x40 - 0x21;
  278                 }
  279                 high &= 0x7F;
  280                 low  &= 0x7F;
  281                 tmp = ((high << 8) | low) - 0x20;
  282                 break;
  283         case KTYPE_7JIS: /* JIS */
  284         case KTYPE_UJIS: /* UJIS */
  285                 high &= 0x7F;
  286                 low &= 0x7F;
  287                 tmp = ((high << 8) | low) - 0x20;
  288                 break;
  289         default:
  290                 tmp = 0;
  291                 break;
  292         }
  293 
  294         /* keisen */
  295         c = ((tmp & 0xff) << 8) | (tmp >> 8);
  296         /* 0x2821 .. 0x2840 */
  297         if (0x0821 <= c && c <= 0x0840)
  298                 tmp = keiConv[c - 0x0821];
  299 
  300         return (tmp);
  301 }
  302 #endif /* KANJI */
  303 
  304 static int
  305 scterm_init(scr_stat *scp, void **softc, int code)
  306 {
  307         term_stat *tcp;
  308 
  309         if (*softc == NULL) {
  310                 if (reserved_term_stat.flags & SCTERM_BUSY)
  311                         return EINVAL;
  312                 *softc = &reserved_term_stat;
  313         }
  314         tcp = *softc;
  315 
  316         switch (code) {
  317         case SC_TE_COLD_INIT:
  318                 bzero(tcp, sizeof(*tcp));
  319                 tcp->flags = SCTERM_BUSY;
  320                 tcp->esc = 0;
  321                 tcp->saved_xpos = -1;
  322                 tcp->saved_ypos = -1;
  323 #ifdef KANJI
  324                 tcp->kanji_1st_char = 0;
  325                 tcp->kanji_type = KTYPE_ASCII;
  326 #endif
  327                 tcp->attr_mask = NORMAL_ATTR;
  328                 /* XXX */
  329                 tcp->dflt_std_color.fg = SC_NORM_ATTR & 0x0f;
  330                 tcp->dflt_std_color.bg = (SC_NORM_ATTR >> 4) & 0x0f;
  331                 tcp->dflt_rev_color.fg = SC_NORM_REV_ATTR & 0x0f;
  332                 tcp->dflt_rev_color.bg = (SC_NORM_REV_ATTR >> 4) & 0x0f;
  333                 tcp->std_color = tcp->dflt_std_color;
  334                 tcp->rev_color = tcp->dflt_rev_color;
  335                 tcp->cur_color = tcp->std_color;
  336                 tcp->cur_attr = mask2attr(tcp);
  337                 ++sc_term_sc.te_refcount;
  338                 break;
  339 
  340         case SC_TE_WARM_INIT:
  341                 tcp->esc = 0;
  342                 tcp->saved_xpos = -1;
  343                 tcp->saved_ypos = -1;
  344 #if 0
  345                 tcp->std_color = tcp->dflt_std_color;
  346                 tcp->rev_color = tcp->dflt_rev_color;
  347 #endif
  348                 tcp->cur_color = tcp->std_color;
  349                 tcp->cur_attr = mask2attr(tcp);
  350                 break;
  351         }
  352 
  353         return 0;
  354 }
  355 
  356 static int
  357 scterm_term(scr_stat *scp, void **softc)
  358 {
  359         if (*softc == &reserved_term_stat) {
  360                 *softc = NULL;
  361                 bzero(&reserved_term_stat, sizeof(reserved_term_stat));
  362         }
  363         --sc_term_sc.te_refcount;
  364         return 0;
  365 }
  366 
  367 static void
  368 scterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c)
  369 {
  370         static u_char ansi_col[16] = {
  371                 FG_BLACK,     FG_RED,          FG_GREEN,      FG_BROWN,
  372                 FG_BLUE,      FG_MAGENTA,      FG_CYAN,       FG_LIGHTGREY,
  373                 FG_DARKGREY,  FG_LIGHTRED,     FG_LIGHTGREEN, FG_YELLOW,
  374                 FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN,  FG_WHITE
  375         };
  376         static int cattrs[] = {
  377                 0,                                      /* block */
  378                 CONS_BLINK_CURSOR,                      /* blinking block */
  379                 CONS_CHAR_CURSOR,                       /* underline */
  380                 CONS_CHAR_CURSOR | CONS_BLINK_CURSOR,   /* blinking underline */
  381                 CONS_RESET_CURSOR,                      /* reset to default */
  382                 CONS_HIDDEN_CURSOR,                     /* hide cursor */
  383         };
  384         static int tcattrs[] = {
  385                 CONS_RESET_CURSOR | CONS_LOCAL_CURSOR,  /* normal */
  386                 CONS_HIDDEN_CURSOR | CONS_LOCAL_CURSOR, /* invisible */
  387                 CONS_BLINK_CURSOR | CONS_LOCAL_CURSOR,  /* very visible */
  388         };
  389         sc_softc_t *sc;
  390         int v0, v1, v2;
  391         int i, n;
  392 
  393         i = n = 0;
  394         sc = scp->sc; 
  395         if (tcp->esc == 1) {    /* seen ESC */
  396 #ifdef KANJI
  397                 switch (tcp->kanji_type) {
  398                 case KTYPE_KANIN:       /* Kanji Invoke sequence */
  399                         switch (c) {
  400                         case 'B':
  401                         case '@':
  402                                 tcp->kanji_type = KTYPE_7JIS;
  403                                 tcp->esc = 0;
  404                                 tcp->kanji_1st_char = 0;
  405                                 return;
  406                         default:
  407                                 tcp->kanji_type = KTYPE_ASCII;
  408                                 tcp->esc = 0;
  409                                 break;
  410                         }
  411                         break;
  412                 case KTYPE_ASCIN:       /* Ascii Invoke sequence */
  413                         switch (c) {
  414                         case 'J':
  415                         case 'B':
  416                         case 'H':
  417                                 tcp->kanji_type = KTYPE_ASCII;
  418                                 tcp->esc = 0;
  419                                 tcp->kanji_1st_char = 0;
  420                                 return;
  421                         case 'I':
  422                                 tcp->kanji_type = KTYPE_JKANA;
  423                                 tcp->esc = 0;
  424                                 tcp->kanji_1st_char = 0;
  425                                 return;
  426                         default:
  427                                 tcp->kanji_type = KTYPE_ASCII;
  428                                 tcp->esc = 0;
  429                                 break;
  430                         }
  431                         break;
  432                 default:
  433                         break;
  434                 }
  435 #endif
  436                 switch (c) {
  437 
  438                 case '7':       /* Save cursor position */
  439                         tcp->saved_xpos = scp->xpos;
  440                         tcp->saved_ypos = scp->ypos;
  441                         break;
  442 
  443                 case '8':       /* Restore saved cursor position */
  444                         if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
  445                                 sc_move_cursor(scp, tcp->saved_xpos,
  446                                                tcp->saved_ypos);
  447                         break;
  448 
  449                 case '[':       /* Start ESC [ sequence */
  450                         tcp->esc = 2;
  451                         tcp->last_param = -1;
  452                         for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
  453                                 tcp->param[i] = 1;
  454                         tcp->num_param = 0;
  455                         return;
  456 
  457 #ifdef KANJI
  458                 case '$':       /* Kanji Invoke sequence */
  459                         tcp->kanji_type = KTYPE_KANIN;
  460                         return;
  461 #endif
  462 
  463                 case 'M':       /* Move cursor up 1 line, scroll if at top */
  464                         sc_term_up_scroll(scp, 1, sc->scr_map[0x20],
  465                                           tcp->cur_attr, 0, 0);
  466                         break;
  467 #ifdef notyet
  468                 case 'Q':
  469                         tcp->esc = 4;
  470                         return;
  471 #endif
  472                 case 'c':       /* reset */
  473                         tcp->attr_mask = NORMAL_ATTR;
  474                         tcp->cur_color = tcp->std_color
  475                                        = tcp->dflt_std_color;
  476                         tcp->rev_color = tcp->dflt_rev_color;
  477                         tcp->cur_attr = mask2attr(tcp);
  478                         sc_change_cursor_shape(scp,
  479                             CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, -1, -1);
  480                         sc_clear_screen(scp);
  481                         break;
  482 
  483                 case '(':       /* iso-2022: designate 94 character set to G0 */
  484 #ifdef KANJI
  485                         tcp->kanji_type = KTYPE_ASCIN;
  486 #else
  487                         tcp->esc = 5;
  488 #endif
  489                         return;
  490                 }
  491         } else if (tcp->esc == 2) {     /* seen ESC [ */
  492                 if (c >= '' && c <= '9') {
  493                         if (tcp->num_param < MAX_ESC_PAR) {
  494                                 if (tcp->last_param != tcp->num_param) {
  495                                         tcp->last_param = tcp->num_param;
  496                                         tcp->param[tcp->num_param] = 0;
  497                                 } else {
  498                                         tcp->param[tcp->num_param] *= 10;
  499                                 }
  500                                 tcp->param[tcp->num_param] += c - '';
  501                                 return;
  502                         }
  503                 }
  504                 tcp->num_param = tcp->last_param + 1;
  505                 switch (c) {
  506 
  507                 case ';':
  508                         if (tcp->num_param < MAX_ESC_PAR)
  509                                 return;
  510                         break;
  511 
  512                 case '=':
  513                         tcp->esc = 3;
  514                         tcp->last_param = -1;
  515                         for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
  516                                 tcp->param[i] = 1;
  517                         tcp->num_param = 0;
  518                         return;
  519 
  520                 case 'A':       /* up n rows */
  521                         sc_term_up(scp, tcp->param[0], 0);
  522                         break;
  523 
  524                 case 'B':       /* down n rows */
  525                         sc_term_down(scp, tcp->param[0], 0);
  526                         break;
  527 
  528                 case 'C':       /* right n columns */
  529                         sc_term_right(scp, tcp->param[0]);
  530                         break;
  531 
  532                 case 'D':       /* left n columns */
  533                         sc_term_left(scp, tcp->param[0]);
  534                         break;
  535 
  536                 case 'E':       /* cursor to start of line n lines down */
  537                         n = tcp->param[0];
  538                         if (n < 1)
  539                                 n = 1;
  540                         sc_move_cursor(scp, 0, scp->ypos + n);
  541                         break;
  542 
  543                 case 'F':       /* cursor to start of line n lines up */
  544                         n = tcp->param[0];
  545                         if (n < 1)
  546                                 n = 1;
  547                         sc_move_cursor(scp, 0, scp->ypos - n);
  548                         break;
  549 
  550                 case 'f':       /* Cursor move */
  551                 case 'H':
  552                         if (tcp->num_param == 0)
  553                                 sc_move_cursor(scp, 0, 0);
  554                         else if (tcp->num_param == 2)
  555                                 sc_move_cursor(scp, tcp->param[1] - 1,
  556                                                tcp->param[0] - 1);
  557                         break;
  558 
  559                 case 'J':       /* Clear all or part of display */
  560                         if (tcp->num_param == 0)
  561                                 n = 0;
  562                         else
  563                                 n = tcp->param[0];
  564                         sc_term_clr_eos(scp, n, sc->scr_map[0x20],
  565                                         tcp->cur_attr);
  566                         break;
  567 
  568                 case 'K':       /* Clear all or part of line */
  569                         if (tcp->num_param == 0)
  570                                 n = 0;
  571                         else
  572                                 n = tcp->param[0];
  573                         sc_term_clr_eol(scp, n, sc->scr_map[0x20],
  574                                         tcp->cur_attr);
  575                         break;
  576 
  577                 case 'L':       /* Insert n lines */
  578                         sc_term_ins_line(scp, scp->ypos, tcp->param[0],
  579                                          sc->scr_map[0x20], tcp->cur_attr, 0);
  580                         break;
  581 
  582                 case 'M':       /* Delete n lines */
  583                         sc_term_del_line(scp, scp->ypos, tcp->param[0],
  584                                          sc->scr_map[0x20], tcp->cur_attr, 0);
  585                         break;
  586 
  587                 case 'P':       /* Delete n chars */
  588                         sc_term_del_char(scp, tcp->param[0],
  589                                          sc->scr_map[0x20], tcp->cur_attr);
  590                         break;
  591 
  592                 case '@':       /* Insert n chars */
  593                         sc_term_ins_char(scp, tcp->param[0],
  594                                          sc->scr_map[0x20], tcp->cur_attr);
  595                         break;
  596 
  597                 case 'S':       /* scroll up n lines */
  598                         sc_term_del_line(scp, 0, tcp->param[0],
  599                                          sc->scr_map[0x20], tcp->cur_attr, 0);
  600                         break;
  601 
  602                 case 'T':       /* scroll down n lines */
  603                         sc_term_ins_line(scp, 0, tcp->param[0],
  604                                          sc->scr_map[0x20], tcp->cur_attr, 0);
  605                         break;
  606 
  607                 case 'X':       /* erase n characters in line */
  608                         n = tcp->param[0];
  609                         if (n < 1)
  610                                 n = 1;
  611                         if (n > scp->xsize - scp->xpos)
  612                                 n = scp->xsize - scp->xpos;
  613                         sc_vtb_erase(&scp->vtb, scp->cursor_pos, n,
  614                                      sc->scr_map[0x20], tcp->cur_attr);
  615                         mark_for_update(scp, scp->cursor_pos);
  616                         mark_for_update(scp, scp->cursor_pos + n - 1);
  617                         break;
  618 
  619                 case 'Z':       /* move n tabs backwards */
  620                         sc_term_backtab(scp, tcp->param[0]);
  621                         break;
  622 
  623                 case '`':       /* move cursor to column n */
  624                         sc_term_col(scp, tcp->param[0]);
  625                         break;
  626 
  627                 case 'a':       /* move cursor n columns to the right */
  628                         sc_term_right(scp, tcp->param[0]);
  629                         break;
  630 
  631                 case 'd':       /* move cursor to row n */
  632                         sc_term_row(scp, tcp->param[0]);
  633                         break;
  634 
  635                 case 'e':       /* move cursor n rows down */
  636                         sc_term_down(scp, tcp->param[0], 0);
  637                         break;
  638 
  639                 case 'm':       /* change attribute */
  640                         if (tcp->num_param == 0) {
  641                                 tcp->attr_mask = NORMAL_ATTR;
  642                                 tcp->cur_color = tcp->std_color;
  643                                 tcp->cur_attr = mask2attr(tcp);
  644                                 break;
  645                         }
  646                         for (i = 0; i < tcp->num_param; i++) {
  647                                 switch (n = tcp->param[i]) {
  648                                 case 0: /* back to normal */
  649                                         tcp->attr_mask = NORMAL_ATTR;
  650                                         tcp->cur_color = tcp->std_color;
  651                                         tcp->cur_attr = mask2attr(tcp);
  652                                         break;
  653                                 case 1: /* bold */
  654                                         tcp->attr_mask |= BOLD_ATTR;
  655                                         tcp->cur_attr = mask2attr(tcp);
  656                                         break;
  657                                 case 4: /* underline */
  658                                         tcp->attr_mask |= UNDERLINE_ATTR;
  659                                         tcp->cur_attr = mask2attr(tcp);
  660                                         break;
  661                                 case 5: /* blink */
  662                                         tcp->attr_mask |= BLINK_ATTR;
  663                                         tcp->cur_attr = mask2attr(tcp);
  664                                         break;
  665                                 case 7: /* reverse */
  666                                         tcp->attr_mask |= REVERSE_ATTR;
  667                                         tcp->cur_attr = mask2attr(tcp);
  668                                         break;
  669                                 case 22: /* remove bold (or dim) */
  670                                         tcp->attr_mask &= ~BOLD_ATTR;
  671                                         tcp->cur_attr = mask2attr(tcp);
  672                                         break;
  673                                 case 24: /* remove underline */
  674                                         tcp->attr_mask &= ~UNDERLINE_ATTR;
  675                                         tcp->cur_attr = mask2attr(tcp);
  676                                         break;
  677                                 case 25: /* remove blink */
  678                                         tcp->attr_mask &= ~BLINK_ATTR;
  679                                         tcp->cur_attr = mask2attr(tcp);
  680                                         break;
  681                                 case 27: /* remove reverse */
  682                                         tcp->attr_mask &= ~REVERSE_ATTR;
  683                                         tcp->cur_attr = mask2attr(tcp);
  684                                         break;
  685                                 case 30: case 31: /* set ansi fg color */
  686                                 case 32: case 33: case 34:
  687                                 case 35: case 36: case 37:
  688                                         tcp->attr_mask |= FG_CHANGED;
  689                                         tcp->cur_color.fg = ansi_col[n - 30];
  690                                         tcp->cur_attr = mask2attr(tcp);
  691                                         break;
  692                                 case 39: /* restore fg color back to normal */
  693                                         tcp->attr_mask &= ~(FG_CHANGED|BOLD_ATTR);
  694                                         tcp->cur_color.fg = tcp->std_color.fg;
  695                                         tcp->cur_attr = mask2attr(tcp);
  696                                         break;
  697                                 case 40: case 41: /* set ansi bg color */
  698                                 case 42: case 43: case 44:
  699                                 case 45: case 46: case 47:
  700                                         tcp->attr_mask |= BG_CHANGED;
  701                                         tcp->cur_color.bg = ansi_col[n - 40];
  702                                         tcp->cur_attr = mask2attr(tcp);
  703                                         break;
  704                                 case 49: /* restore bg color back to normal */
  705                                         tcp->attr_mask &= ~BG_CHANGED;
  706                                         tcp->cur_color.bg = tcp->std_color.bg;
  707                                         tcp->cur_attr = mask2attr(tcp);
  708                                         break;
  709                                 }
  710                         }
  711                         break;
  712 
  713                 case 's':       /* Save cursor position */
  714                         tcp->saved_xpos = scp->xpos;
  715                         tcp->saved_ypos = scp->ypos;
  716                         break;
  717 
  718                 case 'u':       /* Restore saved cursor position */
  719                         if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
  720                                 sc_move_cursor(scp, tcp->saved_xpos,
  721                                                tcp->saved_ypos);
  722                         break;
  723 
  724                 case 'x':
  725                         if (tcp->num_param == 0)
  726                                 n = 0;
  727                         else
  728                                 n = tcp->param[0];
  729                         switch (n) {
  730                         case 0: /* reset colors and attributes back to normal */
  731                                 tcp->attr_mask = NORMAL_ATTR;
  732                                 tcp->cur_color = tcp->std_color
  733                                                = tcp->dflt_std_color;
  734                                 tcp->rev_color = tcp->dflt_rev_color;
  735                                 tcp->cur_attr = mask2attr(tcp);
  736                                 break;
  737                         case 1: /* set ansi background */
  738                                 tcp->attr_mask &= ~BG_CHANGED;
  739                                 tcp->cur_color.bg = tcp->std_color.bg
  740                                                   = ansi_col[tcp->param[1] & 0x0f];
  741                                 tcp->cur_attr = mask2attr(tcp);
  742                                 break;
  743                         case 2: /* set ansi foreground */
  744                                 tcp->attr_mask &= ~FG_CHANGED;
  745                                 tcp->cur_color.fg = tcp->std_color.fg
  746                                                   = ansi_col[tcp->param[1] & 0x0f];
  747                                 tcp->cur_attr = mask2attr(tcp);
  748                                 break;
  749                         case 3: /* set adapter attribute directly */
  750                                 tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED);
  751                                 tcp->cur_color.fg = tcp->std_color.fg
  752                                                   = tcp->param[1] & 0x0f;
  753                                 tcp->cur_color.bg = tcp->std_color.bg
  754                                                   = (tcp->param[1] >> 4) & 0x0f;
  755                                 tcp->cur_attr = mask2attr(tcp);
  756                                 break;
  757                         case 5: /* set ansi reverse background */
  758                                 tcp->rev_color.bg = ansi_col[tcp->param[1] & 0x0f];
  759                                 tcp->cur_attr = mask2attr(tcp);
  760                                 break;
  761                         case 6: /* set ansi reverse foreground */
  762                                 tcp->rev_color.fg = ansi_col[tcp->param[1] & 0x0f];
  763                                 tcp->cur_attr = mask2attr(tcp);
  764                                 break;
  765                         case 7: /* set adapter reverse attribute directly */
  766                                 tcp->rev_color.fg = tcp->param[1] & 0x0f;
  767                                 tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f;
  768                                 tcp->cur_attr = mask2attr(tcp);
  769                                 break;
  770                         }
  771                         break;
  772 
  773                 case 'z':       /* switch to (virtual) console n */
  774                         if (tcp->num_param == 1)
  775                                 sc_switch_scr(sc, tcp->param[0]);
  776                         break;
  777                 }
  778         } else if (tcp->esc == 3) {     /* seen ESC [0-9]+ = */
  779                 if (c >= '' && c <= '9') {
  780                         if (tcp->num_param < MAX_ESC_PAR) {
  781                                 if (tcp->last_param != tcp->num_param) {
  782                                         tcp->last_param = tcp->num_param;
  783                                         tcp->param[tcp->num_param] = 0;
  784                                 } else {
  785                                         tcp->param[tcp->num_param] *= 10;
  786                                 }
  787                                 tcp->param[tcp->num_param] += c - '';
  788                                 return;
  789                         }
  790                 }
  791                 tcp->num_param = tcp->last_param + 1;
  792                 switch (c) {
  793 
  794                 case ';':
  795                         if (tcp->num_param < MAX_ESC_PAR)
  796                                 return;
  797                         break;
  798 
  799                 case 'A':   /* set display border color */
  800                         if (tcp->num_param == 1) {
  801                                 scp->border=tcp->param[0] & 0xff;
  802                                 if (scp == sc->cur_scp)
  803                                         sc_set_border(scp, scp->border);
  804                         }
  805                         break;
  806 
  807                 case 'B':   /* set bell pitch and duration */
  808                         if (tcp->num_param == 2) {
  809                                 scp->bell_pitch = tcp->param[0];
  810                                 scp->bell_duration = 
  811                                     (tcp->param[1] * hz + 99) / 100;
  812                         }
  813                         break;
  814 
  815                 case 'C':   /* set global/parmanent cursor type & shape */
  816                         i = spltty();
  817                         n = tcp->num_param;
  818                         v0 = tcp->param[0];
  819                         v1 = tcp->param[1];
  820                         v2 = tcp->param[2];
  821                         switch (n) {
  822                         case 1: /* flags only */
  823                                 if (v0 < nitems(cattrs))
  824                                         v0 = cattrs[v0];
  825                                 else    /* backward compatibility */
  826                                         v0 = cattrs[v0 & 0x3];
  827                                 sc_change_cursor_shape(scp, v0, -1, -1);
  828                                 break;
  829                         case 2:
  830                                 v2 = 0;
  831                                 v0 &= 0x1f;     /* backward compatibility */
  832                                 v1 &= 0x1f;
  833                                 /* FALL THROUGH */
  834                         case 3: /* base and height */
  835                                 if (v2 == 0)    /* count from top */
  836                                         sc_change_cursor_shape(scp, -1,
  837                                             scp->font_size - v1 - 1,
  838                                             v1 - v0 + 1);
  839                                 else if (v2 == 1) /* count from bottom */
  840                                         sc_change_cursor_shape(scp, -1,
  841                                             v0, v1 - v0 + 1);
  842                                 break;
  843                         }
  844                         splx(i);
  845                         break;
  846 
  847                 case 'F':   /* set adapter foreground */
  848                         if (tcp->num_param == 1) {
  849                                 tcp->attr_mask &= ~FG_CHANGED;
  850                                 tcp->cur_color.fg = tcp->std_color.fg
  851                                                   = tcp->param[0] & 0x0f;
  852                                 tcp->cur_attr = mask2attr(tcp);
  853                         }
  854                         break;
  855 
  856                 case 'G':   /* set adapter background */
  857                         if (tcp->num_param == 1) {
  858                                 tcp->attr_mask &= ~BG_CHANGED;
  859                                 tcp->cur_color.bg = tcp->std_color.bg
  860                                                   = tcp->param[0] & 0x0f;
  861                                 tcp->cur_attr = mask2attr(tcp);
  862                         }
  863                         break;
  864 
  865                 case 'H':   /* set adapter reverse foreground */
  866                         if (tcp->num_param == 1) {
  867                                 tcp->rev_color.fg = tcp->param[0] & 0x0f;
  868                                 tcp->cur_attr = mask2attr(tcp);
  869                         }
  870                         break;
  871 
  872                 case 'I':   /* set adapter reverse background */
  873                         if (tcp->num_param == 1) {
  874                                 tcp->rev_color.bg = tcp->param[0] & 0x0f;
  875                                 tcp->cur_attr = mask2attr(tcp);
  876                         }
  877                         break;
  878 
  879                 case 'S':   /* set local/temporary cursor type & shape */
  880                         i = spltty();
  881                         n = tcp->num_param;
  882                         v0 = tcp->param[0];
  883                         switch (n) {
  884                         case 0:
  885                                 v0 = 0;
  886                                 /* FALL THROUGH */
  887                         case 1:
  888                                 if (v0 < nitems(tcattrs))
  889                                         sc_change_cursor_shape(scp,
  890                                             tcattrs[v0], -1, -1);
  891                                 break;
  892                         }
  893                         splx(i);
  894                         break;
  895                 }
  896 #ifdef notyet
  897         } else if (tcp->esc == 4) {     /* seen ESC Q */
  898                 /* to be filled */
  899 #endif
  900         } else if (tcp->esc == 5) {     /* seen ESC ( */
  901                 switch (c) {
  902                 case 'B':   /* iso-2022: desginate ASCII into G0 */
  903                         break;
  904                 /* other items to be filled */
  905                 default:
  906                         break;
  907                 }
  908         }
  909         tcp->esc = 0;
  910 }
  911 
  912 static void
  913 scterm_puts(scr_stat *scp, u_char *buf, int len)
  914 {
  915         term_stat *tcp;
  916         u_char *ptr;
  917 #ifdef KANJI
  918         u_short kanji_code;
  919 #endif
  920 
  921         tcp = scp->ts;
  922         ptr = buf;
  923 outloop:
  924         scp->sc->write_in_progress++;
  925 
  926         if (tcp->esc) {
  927                 scterm_scan_esc(scp, tcp, *ptr++);
  928                 len--;
  929         } else if (PRINTABLE(*ptr)) {     /* Print only printables */
  930                 vm_offset_t p;
  931                 u_char *map;
  932                 int attr;
  933                 int i;
  934                 int cnt;
  935 #ifdef KANJI
  936                 u_char c;
  937 #endif
  938 
  939                 p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos);
  940                 map = scp->sc->scr_map;
  941                 attr = tcp->cur_attr;
  942 
  943 #ifdef KANJI
  944                 c = *ptr;
  945                 if (tcp->kanji_1st_char == 0) {
  946                     tcp->kanji_type = iskanji1(tcp->kanji_type, c);
  947                     if (!IS_KTYPE_ASCII_or_HANKAKU(tcp->kanji_type)) {
  948                         /* not Ascii & not HANKAKU */
  949                         tcp->kanji_1st_char = c;
  950                         goto kanji_end;
  951                     } else if (tcp->kanji_type == KTYPE_ASCII) {
  952                         cnt = imin(len, scp->xsize - scp->xpos);
  953                         i = cnt;
  954                         do {
  955                             p = sc_vtb_putchar(&scp->vtb, p, map[c], attr);
  956                             c = *++ptr;
  957                             --i;
  958                         } while (i > 0 && PRINTABLE(c) &&
  959                                  iskanji1(tcp->kanji_type, c) == KTYPE_ASCII);
  960 
  961                         len -= cnt - i;
  962                         mark_for_update(scp, scp->cursor_pos);
  963                         scp->cursor_pos += cnt - i;
  964                         mark_for_update(scp, scp->cursor_pos - 1);
  965                         scp->xpos += cnt - i;
  966                         KTYPE_MASK_CTRL(tcp->kanji_type);
  967                         goto ascii_end;
  968                     }
  969                 } else {
  970                     if ((tcp->kanji_type =
  971                          iskanji2(tcp->kanji_type, c)) & 0xee) {
  972                         /* print kanji on TEXT VRAM */
  973                         kanji_code = kanji_convert(tcp->kanji_type, c,
  974                                                    tcp->kanji_1st_char);
  975                         mark_for_update(scp, scp->cursor_pos);
  976                         for (i = 0; i < 2; i++) {
  977                             /* *cursor_pos = (kanji_code | (i*0x80)); */
  978                             p = sc_vtb_putchar(&scp->vtb, p,
  979                                kanji_code | ((i == 0) ? 0x00 : 0x80), attr);
  980                             ++scp->cursor_pos;
  981                             if (++scp->xpos >= scp->xsize) {
  982                                 scp->xpos = 0;
  983                                 scp->ypos++;
  984                             }
  985                         }
  986                         mark_for_update(scp, scp->cursor_pos - 1);
  987                         KTYPE_MASK_CTRL(tcp->kanji_type);
  988                         tcp->kanji_1st_char = 0;
  989                         goto kanji_end;
  990                     } else {
  991                         tcp->kanji_1st_char = 0;
  992                     }
  993                 }                               
  994                 if (IS_KTYPE_KANA(tcp->kanji_type))
  995                     c |= 0x80;
  996                 KTYPE_MASK_CTRL(tcp->kanji_type);
  997                 sc_vtb_putchar(&scp->vtb, p, map[c], attr);
  998                 mark_for_update(scp, scp->cursor_pos);
  999                 mark_for_update(scp, scp->cursor_pos);
 1000                 ++scp->cursor_pos;
 1001                 ++scp->xpos;
 1002 kanji_end:
 1003                 ++ptr;
 1004                 --len;
 1005 ascii_end:
 1006 #else /* !KANJI */
 1007                 cnt = imin(len, scp->xsize - scp->xpos);
 1008                 i = cnt;
 1009                 do {
 1010                     /*
 1011                      * gcc-2.6.3 generates poor (un)sign extension code.
 1012                      * Casting the pointers in the following to volatile should
 1013                      * have no effect, but in fact speeds up this inner loop
 1014                      * from 26 to 18 cycles (+ cache misses) on i486's.
 1015                      */
 1016 #define UCVP(ucp)       ((u_char volatile *)(ucp))
 1017                     p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)],
 1018                                        attr);
 1019                     ++ptr;
 1020                     --i;
 1021                 } while (i > 0 && PRINTABLE(*ptr));
 1022 
 1023                 len -= cnt - i;
 1024                 mark_for_update(scp, scp->cursor_pos);
 1025                 scp->cursor_pos += cnt - i;
 1026                 mark_for_update(scp, scp->cursor_pos - 1);
 1027                 scp->xpos += cnt - i;
 1028 #endif /* !KANJI */
 1029 
 1030                 if (scp->xpos >= scp->xsize) {
 1031                         scp->xpos = 0;
 1032                         scp->ypos++;
 1033                 }
 1034         } else {
 1035                 switch (*ptr) {
 1036                 case 0x07:
 1037                         sc_bell(scp, scp->bell_pitch, scp->bell_duration);
 1038                         break;
 1039 
 1040                 case 0x08:      /* non-destructive backspace */
 1041                         if (scp->cursor_pos > 0) {
 1042                                 mark_for_update(scp, scp->cursor_pos);
 1043                                 scp->cursor_pos--;
 1044                                 mark_for_update(scp, scp->cursor_pos);
 1045                                 if (scp->xpos > 0)
 1046                                         scp->xpos--;
 1047                                 else {
 1048                                         scp->xpos += scp->xsize - 1;
 1049                                         scp->ypos--;
 1050                                 }
 1051                         }
 1052                         break;
 1053 
 1054                 case 0x09:      /* non-destructive tab */
 1055                         mark_for_update(scp, scp->cursor_pos);
 1056                         scp->cursor_pos += (8 - scp->xpos % 8u);
 1057                         scp->xpos += (8 - scp->xpos % 8u);
 1058                         if (scp->xpos >= scp->xsize) {
 1059                                 scp->xpos = 0;
 1060                                 scp->ypos++;
 1061                                 scp->cursor_pos = scp->xsize * scp->ypos;
 1062                         }
 1063                         mark_for_update(scp, scp->cursor_pos);
 1064                         break;
 1065 
 1066                 case 0x0a:      /* newline, same pos */
 1067                         mark_for_update(scp, scp->cursor_pos);
 1068                         scp->cursor_pos += scp->xsize;
 1069                         mark_for_update(scp, scp->cursor_pos);
 1070                         scp->ypos++;
 1071                         break;
 1072 
 1073                 case 0x0c:      /* form feed, clears screen */
 1074                         sc_clear_screen(scp);
 1075                         break;
 1076 
 1077                 case 0x0d:      /* return, return to pos 0 */
 1078                         mark_for_update(scp, scp->cursor_pos);
 1079                         scp->cursor_pos -= scp->xpos;
 1080                         mark_for_update(scp, scp->cursor_pos);
 1081                         scp->xpos = 0;
 1082                         break;
 1083 
 1084                 case 0x0e:      /* ^N */
 1085                         tcp->kanji_type = KTYPE_JKANA;
 1086                         tcp->esc = 0;
 1087                         tcp->kanji_1st_char = 0;
 1088                         break;
 1089 
 1090                 case 0x0f:      /* ^O */
 1091                         tcp->kanji_type = KTYPE_ASCII;
 1092                         tcp->esc = 0;
 1093                         tcp->kanji_1st_char = 0;
 1094                         break;
 1095 
 1096                 case 0x1b:      /* start escape sequence */
 1097                         tcp->esc = 1;
 1098                         tcp->num_param = 0;
 1099                         break;
 1100                 }
 1101                 ptr++;
 1102                 len--;
 1103         }
 1104 
 1105         sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr);
 1106 
 1107         scp->sc->write_in_progress--;
 1108         if (len)
 1109                 goto outloop;
 1110 }
 1111 
 1112 static int
 1113 scterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
 1114              struct thread *td)
 1115 {
 1116         term_stat *tcp = scp->ts;
 1117         vid_info_t *vi;
 1118 
 1119         switch (cmd) {
 1120         case GIO_ATTR:          /* get current attributes */
 1121                 /* FIXME: */
 1122                 *(int*)data = (tcp->cur_attr >> 8) & 0xff;
 1123                 return 0;
 1124         case CONS_GETINFO:      /* get current (virtual) console info */
 1125                 vi = (vid_info_t *)data;
 1126                 if (vi->size != sizeof(struct vid_info))
 1127                         return EINVAL;
 1128                 vi->mv_norm.fore = tcp->std_color.fg;
 1129                 vi->mv_norm.back = tcp->std_color.bg;
 1130                 vi->mv_rev.fore = tcp->rev_color.fg;
 1131                 vi->mv_rev.back = tcp->rev_color.bg;
 1132                 /*
 1133                  * The other fields are filled by the upper routine. XXX
 1134                  */
 1135                 return ENOIOCTL;
 1136         }
 1137         return ENOIOCTL;
 1138 }
 1139 
 1140 static int
 1141 scterm_reset(scr_stat *scp, int code)
 1142 {
 1143         /* FIXME */
 1144         return 0;
 1145 }
 1146 
 1147 static void
 1148 scterm_default_attr(scr_stat *scp, int color, int rev_color)
 1149 {
 1150         term_stat *tcp = scp->ts;
 1151 
 1152         tcp->dflt_std_color.fg = color & 0x0f;
 1153         tcp->dflt_std_color.bg = (color >> 4) & 0x0f;
 1154         tcp->dflt_rev_color.fg = rev_color & 0x0f;
 1155         tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f;
 1156         tcp->std_color = tcp->dflt_std_color;
 1157         tcp->rev_color = tcp->dflt_rev_color;
 1158         tcp->cur_color = tcp->std_color;
 1159         tcp->cur_attr = mask2attr(tcp);
 1160 }
 1161 
 1162 static void
 1163 scterm_clear(scr_stat *scp)
 1164 {
 1165         term_stat *tcp = scp->ts;
 1166 
 1167         sc_move_cursor(scp, 0, 0);
 1168         sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr);
 1169         mark_all(scp);
 1170 }
 1171 
 1172 static void
 1173 scterm_notify(scr_stat *scp, int event)
 1174 {
 1175         switch (event) {
 1176         case SC_TE_NOTIFY_VTSWITCH_IN:
 1177                 break;
 1178         case SC_TE_NOTIFY_VTSWITCH_OUT:
 1179                 break;
 1180         }
 1181 }
 1182 
 1183 static int
 1184 scterm_input(scr_stat *scp, int c, struct tty *tp)
 1185 {
 1186         return FALSE;
 1187 }
 1188 
 1189 static const char *
 1190 scterm_fkeystr(scr_stat *scp, int c)
 1191 {
 1192 
 1193         return (NULL);
 1194 }
 1195 
 1196 /*
 1197  * Calculate hardware attributes word using logical attributes mask and
 1198  * hardware colors
 1199  */
 1200 
 1201 /* FIXME */
 1202 static int
 1203 mask2attr(term_stat *tcp)
 1204 {
 1205         int attr, mask = tcp->attr_mask;
 1206 
 1207         if (mask & REVERSE_ATTR) {
 1208                 attr = ((mask & FG_CHANGED) ?
 1209                         tcp->cur_color.bg : tcp->rev_color.fg) |
 1210                         (((mask & BG_CHANGED) ?
 1211                         tcp->cur_color.fg : tcp->rev_color.bg) << 4);
 1212         } else
 1213                 attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4);
 1214 
 1215         /* XXX: underline mapping for Hercules adapter can be better */
 1216         if (mask & (BOLD_ATTR | UNDERLINE_ATTR))
 1217                 attr ^= 0x08;
 1218         if (mask & BLINK_ATTR)
 1219                 attr ^= 0x80;
 1220 
 1221         return (attr << 8);
 1222 }

Cache object: cb3cb6ae6bd4b426c0f03cc0aa4b2dc4


[ 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.