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

Cache object: a6da146b95e33f8e4b564e82098facf2


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