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


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

FreeBSD/Linux Kernel Cross Reference
sys/dev/wscons/wsemul_vt100_subr.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 /* $NetBSD: wsemul_vt100_subr.c,v 1.15 2004/03/24 17:26:53 drochner Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1998
    5  *      Matthias Drochner.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  *
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __KERNEL_RCSID(0, "$NetBSD: wsemul_vt100_subr.c,v 1.15 2004/03/24 17:26:53 drochner Exp $");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 
   35 #include <dev/wscons/wsksymvar.h>
   36 #include <dev/wscons/wsdisplayvar.h>
   37 #include <dev/wscons/wsemulvar.h>
   38 #include <dev/wscons/wsemul_vt100var.h>
   39 
   40 #include "opt_wsemul.h"
   41 
   42 static int vt100_selectattribute(struct wsemul_vt100_emuldata *,
   43                                       int, int, int, long *, long *);
   44 static int vt100_ansimode(struct wsemul_vt100_emuldata *, int, int);
   45 static int vt100_decmode(struct wsemul_vt100_emuldata *, int, int);
   46 #define VTMODE_SET 33
   47 #define VTMODE_RESET 44
   48 #define VTMODE_REPORT 55
   49 
   50 /*
   51  * scroll up within scrolling region
   52  */
   53 void
   54 wsemul_vt100_scrollup(struct wsemul_vt100_emuldata *edp, int n)
   55 {
   56         int help;
   57 
   58         if (n > edp->scrreg_nrows)
   59                 n = edp->scrreg_nrows;
   60 
   61         help = edp->scrreg_nrows - n;
   62         if (help > 0) {
   63                 (*edp->emulops->copyrows)(edp->emulcookie,
   64                                           edp->scrreg_startrow + n,
   65                                           edp->scrreg_startrow,
   66                                           help);
   67                 if (edp->dblwid)
   68                         memmove(&edp->dblwid[edp->scrreg_startrow],
   69                                 &edp->dblwid[edp->scrreg_startrow + n],
   70                                 help);
   71         }
   72         (*edp->emulops->eraserows)(edp->emulcookie,
   73                                    edp->scrreg_startrow + help, n,
   74                                    edp->bkgdattr);
   75         if (edp->dblwid)
   76                 memset(&edp->dblwid[edp->scrreg_startrow + help], 0, n);
   77         CHECK_DW;
   78 }
   79 
   80 /*
   81  * scroll down within scrolling region
   82  */
   83 void
   84 wsemul_vt100_scrolldown(struct wsemul_vt100_emuldata *edp, int n)
   85 {
   86         int help;
   87 
   88         if (n > edp->scrreg_nrows)
   89                 n = edp->scrreg_nrows;
   90 
   91         help = edp->scrreg_nrows - n;
   92         if (help > 0) {
   93                 (*edp->emulops->copyrows)(edp->emulcookie,
   94                                           edp->scrreg_startrow,
   95                                           edp->scrreg_startrow + n,
   96                                           help);
   97                 if (edp->dblwid)
   98                         memmove(&edp->dblwid[edp->scrreg_startrow + n],
   99                                 &edp->dblwid[edp->scrreg_startrow],
  100                                 help);
  101         }
  102         (*edp->emulops->eraserows)(edp->emulcookie,
  103                                    edp->scrreg_startrow, n,
  104                                    edp->bkgdattr);
  105         if (edp->dblwid)
  106                 memset(&edp->dblwid[edp->scrreg_startrow], 0, n);
  107         CHECK_DW;
  108 }
  109 
  110 /*
  111  * erase in display
  112  */
  113 void
  114 wsemul_vt100_ed(struct wsemul_vt100_emuldata *edp, int arg)
  115 {
  116         int n;
  117 
  118         switch (arg) {
  119             case 0: /* cursor to end */
  120                 ERASECOLS(edp->ccol, COLS_LEFT + 1, edp->bkgdattr);
  121                 n = edp->nrows - edp->crow - 1;
  122                 if (n > 0) {
  123                         (*edp->emulops->eraserows)(edp->emulcookie,
  124                                                    edp->crow + 1, n,
  125                                                    edp->bkgdattr);
  126                         if (edp->dblwid)
  127                                 memset(&edp->dblwid[edp->crow + 1], 0, n);
  128                 }
  129                 break;
  130             case 1: /* beginning to cursor */
  131                 if (edp->crow > 0) {
  132                         (*edp->emulops->eraserows)(edp->emulcookie,
  133                                                    0, edp->crow,
  134                                                    edp->bkgdattr);
  135                         if (edp->dblwid)
  136                                 memset(&edp->dblwid[0], 0, edp->crow);
  137                 }
  138                 ERASECOLS(0, edp->ccol + 1, edp->bkgdattr);
  139                 break;
  140             case 2: /* complete display */
  141                 (*edp->emulops->eraserows)(edp->emulcookie,
  142                                            0, edp->nrows,
  143                                            edp->bkgdattr);
  144                 if (edp->dblwid)
  145                         memset(&edp->dblwid[0], 0, edp->nrows);
  146                 break;
  147             default:
  148 #ifdef VT100_PRINTUNKNOWN
  149                 printf("ed(%d) unknown\n", arg);
  150 #endif
  151                 break;
  152         }
  153         CHECK_DW;
  154 }
  155 
  156 /*
  157  * erase in line
  158  */
  159 void
  160 wsemul_vt100_el(struct wsemul_vt100_emuldata *edp, int arg)
  161 {
  162         switch (arg) {
  163             case 0: /* cursor to end */
  164                 ERASECOLS(edp->ccol, COLS_LEFT + 1, edp->bkgdattr);
  165                 break;
  166             case 1: /* beginning to cursor */
  167                 ERASECOLS(0, edp->ccol + 1, edp->bkgdattr);
  168                 break;
  169             case 2: /* complete line */
  170                 (*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
  171                                            0, edp->ncols,
  172                                            edp->bkgdattr);
  173                 break;
  174             default:
  175 #ifdef VT100_PRINTUNKNOWN
  176                 printf("el(%d) unknown\n", arg);
  177 #endif
  178                 break;
  179         }
  180 }
  181 
  182 /*
  183  * handle commands after CSI (ESC[)
  184  */
  185 void
  186 wsemul_vt100_handle_csi(struct wsemul_vt100_emuldata *edp, u_char c)
  187 {
  188         int n, help, flags, fgcol, bgcol;
  189         long attr, bkgdattr;
  190 
  191 #define A3(a, b, c) (((a) << 16) | ((b) << 8) | (c))
  192         switch (A3(edp->modif1, edp->modif2, c)) {
  193             case A3('>', '\0', 'c'): /* DA secondary */
  194                 wsdisplay_emulinput(edp->cbcookie, WSEMUL_VT_ID2,
  195                                     sizeof(WSEMUL_VT_ID2));
  196                 break;
  197 
  198             case A3('\0', '\0', 'J'): /* ED selective erase in display */
  199             case A3('?', '\0', 'J'): /* DECSED selective erase in display */
  200                 wsemul_vt100_ed(edp, ARG(0));
  201                 break;
  202             case A3('\0', '\0', 'K'): /* EL selective erase in line */
  203             case A3('?', '\0', 'K'): /* DECSEL selective erase in line */
  204                 wsemul_vt100_el(edp, ARG(0));
  205                 break;
  206             case A3('\0', '\0', 'h'): /* SM */
  207                 for (n = 0; n < edp->nargs; n++)
  208                         vt100_ansimode(edp, ARG(n), VTMODE_SET);
  209                 break;
  210             case A3('?', '\0', 'h'): /* DECSM */
  211                 for (n = 0; n < edp->nargs; n++)
  212                         vt100_decmode(edp, ARG(n), VTMODE_SET);
  213                 break;
  214             case A3('\0', '\0', 'l'): /* RM */
  215                 for (n = 0; n < edp->nargs; n++)
  216                         vt100_ansimode(edp, ARG(n), VTMODE_RESET);
  217                 break;
  218             case A3('?', '\0', 'l'): /* DECRM */
  219                 for (n = 0; n < edp->nargs; n++)
  220                         vt100_decmode(edp, ARG(n), VTMODE_RESET);
  221                 break;
  222             case A3('\0', '$', 'p'): /* DECRQM request mode ANSI */
  223                 vt100_ansimode(edp, ARG(0), VTMODE_REPORT);
  224                 break;
  225             case A3('?', '$', 'p'): /* DECRQM request mode DEC */
  226                 vt100_decmode(edp, ARG(0), VTMODE_REPORT);
  227                 break;
  228             case A3('\0', '\0', 'i'): /* MC printer controller mode */
  229             case A3('?', '\0', 'i'): /* MC printer controller mode */
  230                 switch (ARG(0)) {
  231                     case 0: /* print screen */
  232                     case 1: /* print cursor line */
  233                     case 4: /* off */
  234                     case 5: /* on */
  235 #ifdef VT100_PRINTNOTIMPL
  236                         printf("CSI%di ignored\n", ARG(0));
  237 #endif
  238                         break;
  239                     default:
  240 #ifdef VT100_PRINTUNKNOWN
  241                         printf("CSI%di unknown\n", ARG(0));
  242 #endif
  243                         break;
  244                 }
  245                 break;
  246 
  247 #define A2(a, b) (((a) << 8) | (b))
  248             case A2('!', 'p'): /* DECSTR soft reset VT300 only */
  249                 wsemul_vt100_reset(edp);
  250                 break;
  251 
  252             case A2('"', 'p'): /* DECSCL */
  253                 switch (ARG(0)) {
  254                     case 61: /* VT100 mode (no further arguments!) */
  255                         break;
  256                     case 62:
  257                     case 63: /* VT300 mode */
  258                         break;
  259                     default:
  260 #ifdef VT100_PRINTUNKNOWN
  261                         printf("CSI%d\"p unknown\n", ARG(0));
  262 #endif
  263                         break;
  264                 }
  265                 switch (ARG(1)) {
  266                     case 0:
  267                     case 2: /* 8-bit controls */
  268 #ifdef VT100_PRINTNOTIMPL
  269                         printf("CSI%d;%d\"p ignored\n", ARG(0), ARG(1));
  270 #endif
  271                         break;
  272                     case 1: /* 7-bit controls */
  273                         break;
  274                     default:
  275 #ifdef VT100_PRINTUNKNOWN
  276                         printf("CSI%d;%d\"p unknown\n", ARG(0), ARG(1));
  277 #endif
  278                         break;
  279                 }
  280                 break;
  281             case A2('"', 'q'): /* DECSCA select character attribute VT300 */
  282                 switch (ARG(0)) {
  283                     case 0:
  284                     case 1: /* erasable */
  285                         break;
  286                     case 2: /* not erasable */
  287 #ifdef VT100_PRINTNOTIMPL
  288                         printf("CSI2\"q ignored\n");
  289 #endif
  290                         break;
  291                     default:
  292 #ifdef VT100_PRINTUNKNOWN
  293                         printf("CSI%d\"q unknown\n", ARG(0));
  294 #endif
  295                         break;
  296                 }
  297                 break;
  298 
  299             case A2('$', 'u'): /* DECRQTSR request terminal status report */
  300                 switch (ARG(0)) {
  301                     case 0: /* ignored */
  302                         break;
  303                     case 1: /* terminal state report */
  304 #ifdef VT100_PRINTNOTIMPL
  305                         printf("CSI1$u ignored\n");
  306 #endif
  307                         break;
  308                     default:
  309 #ifdef VT100_PRINTUNKNOWN
  310                         printf("CSI%d$u unknown\n", ARG(0));
  311 #endif
  312                         break;
  313                 }
  314                 break;
  315             case A2('$', 'w'): /* DECRQPSR request presentation status report
  316                                 (VT300 only) */
  317                 switch (ARG(0)) {
  318                     case 0: /* error */
  319                         break;
  320                     case 1: /* cursor information report */
  321 #ifdef VT100_PRINTNOTIMPL
  322                         printf("CSI1$w ignored\n");
  323 #endif
  324                         break;
  325                     case 2: /* tab stop report */
  326                         {
  327                         int i, n, ps = 0;
  328                         char buf[20];
  329                         KASSERT(edp->tabs != 0);
  330                         wsdisplay_emulinput(edp->cbcookie, "\033P2$u", 5);
  331                         for (i = 0; i < edp->ncols; i++)
  332                                 if (edp->tabs[i]) {
  333                                         n = sprintf(buf, "%s%d",
  334                                                     (ps ? "/" : ""), i + 1);
  335                                         wsdisplay_emulinput(edp->cbcookie,
  336                                                             buf, n);
  337                                         ps = 1;
  338                                 }
  339                         }
  340                         wsdisplay_emulinput(edp->cbcookie, "\033\\", 2);
  341                         break;
  342                     default:
  343 #ifdef VT100_PRINTUNKNOWN
  344                         printf("CSI%d$w unknown\n", ARG(0));
  345 #endif
  346                         break;
  347                 }
  348                 break;
  349             case A2('$', '}'): /* DECSASD select active status display */
  350                 switch (ARG(0)) {
  351                     case 0: /* main display */
  352                     case 1: /* status line */
  353 #ifdef VT100_PRINTNOTIMPL
  354                         printf("CSI%d$} ignored\n", ARG(0));
  355 #endif
  356                         break;
  357                     default:
  358 #ifdef VT100_PRINTUNKNOWN
  359                         printf("CSI%d$} unknown\n", ARG(0));
  360 #endif
  361                         break;
  362                 }
  363                 break;
  364             case A2('$', '~'): /* DECSSDD select status line type */
  365                 switch (ARG(0)) {
  366                     case 0: /* none */
  367                     case 1: /* indicator */
  368                     case 2: /* host-writable */
  369 #ifdef VT100_PRINTNOTIMPL
  370                         printf("CSI%d$~ ignored\n", ARG(0));
  371 #endif
  372                         break;
  373                     default:
  374 #ifdef VT100_PRINTUNKNOWN
  375                         printf("CSI%d$~ unknown\n", ARG(0));
  376 #endif
  377                         break;
  378                 }
  379                 break;
  380 
  381             case A2('&', 'u'): /* DECRQUPSS request user preferred
  382                                   supplemental set */
  383                 wsdisplay_emulinput(edp->cbcookie, "\033P0!u%5\033\\", 9);
  384                 break;
  385 
  386             case '@': /* ICH insert character VT300 only */
  387                 n = min(DEF1_ARG(0), COLS_LEFT + 1);
  388                 help = NCOLS - (edp->ccol + n);
  389                 if (help > 0)
  390                         COPYCOLS(edp->ccol, edp->ccol + n, help);
  391                 ERASECOLS(edp->ccol, n, edp->bkgdattr);
  392                 break;
  393             case 'A': /* CUU */
  394                 edp->crow -= min(DEF1_ARG(0), ROWS_ABOVE);
  395                 CHECK_DW;
  396                 break;
  397             case 'B': /* CUD */
  398                 edp->crow += min(DEF1_ARG(0), ROWS_BELOW);
  399                 CHECK_DW;
  400                 break;
  401             case 'C': /* CUF */
  402                 edp->ccol += min(DEF1_ARG(0), COLS_LEFT);
  403                 break;
  404             case 'D': /* CUB */
  405                 edp->ccol -= min(DEF1_ARG(0), edp->ccol);
  406                 edp->flags &= ~VTFL_LASTCHAR;
  407                 break;
  408             case 'H': /* CUP */
  409             case 'f': /* HVP */
  410                 if (edp->flags & VTFL_DECOM)
  411                         edp->crow = edp->scrreg_startrow +
  412                             min(DEF1_ARG(0), edp->scrreg_nrows) - 1;
  413                 else
  414                         edp->crow = min(DEF1_ARG(0), edp->nrows) - 1;
  415                 CHECK_DW;
  416                 edp->ccol = min(DEF1_ARG(1), NCOLS) - 1;
  417                 edp->flags &= ~VTFL_LASTCHAR;
  418                 break;
  419             case 'L': /* IL insert line */
  420             case 'M': /* DL delete line */
  421                 n = min(DEF1_ARG(0), ROWS_BELOW + 1);
  422                 {
  423                 int savscrstartrow, savscrnrows;
  424                 savscrstartrow = edp->scrreg_startrow;
  425                 savscrnrows = edp->scrreg_nrows;
  426                 edp->scrreg_nrows -= ROWS_ABOVE;
  427                 edp->scrreg_startrow = edp->crow;
  428                 if (c == 'L')
  429                         wsemul_vt100_scrolldown(edp, n);
  430                 else
  431                         wsemul_vt100_scrollup(edp, n);
  432                 edp->scrreg_startrow = savscrstartrow;
  433                 edp->scrreg_nrows = savscrnrows;
  434                 }
  435                 break;
  436             case 'P': /* DCH delete character */
  437                 n = min(DEF1_ARG(0), COLS_LEFT + 1);
  438                 help = NCOLS - (edp->ccol + n);
  439                 if (help > 0)
  440                         COPYCOLS(edp->ccol + n, edp->ccol, help);
  441                 ERASECOLS(NCOLS - n, n, edp->bkgdattr);
  442                 break;
  443             case 'X': /* ECH erase character */
  444                 n = min(DEF1_ARG(0), COLS_LEFT + 1);
  445                 ERASECOLS(edp->ccol, n, edp->bkgdattr);
  446                 break;
  447             case 'c': /* DA primary */
  448                 if (ARG(0) == 0)
  449                         wsdisplay_emulinput(edp->cbcookie, WSEMUL_VT_ID1,
  450                                             sizeof(WSEMUL_VT_ID1));
  451                 break;
  452             case 'g': /* TBC */
  453                 KASSERT(edp->tabs != 0);
  454                 switch (ARG(0)) {
  455                     case 0:
  456                         edp->tabs[edp->ccol] = 0;
  457                         break;
  458                     case 3:
  459                         memset(edp->tabs, 0, edp->ncols);
  460                         break;
  461                     default:
  462 #ifdef VT100_PRINTUNKNOWN
  463                         printf("CSI%dg unknown\n", ARG(0));
  464 #endif
  465                         break;
  466                 }
  467                 break;
  468             case 'm': /* SGR select graphic rendition */
  469                 flags = edp->attrflags;
  470                 fgcol = edp->fgcol;
  471                 bgcol = edp->bgcol;
  472                 for (n = 0; n < edp->nargs; n++) {
  473                         switch (ARG(n)) {
  474                             case 0: /* reset */
  475                                 if (n == edp->nargs - 1) {
  476                                         edp->bkgdattr = edp->curattr = edp->defattr;
  477                                         edp->attrflags = 0;
  478                                         edp->fgcol = WSCOL_WHITE;
  479                                         edp->bgcol = WSCOL_BLACK;
  480                                         return;
  481                                 }
  482                                 flags = 0;
  483                                 fgcol = WSCOL_WHITE;
  484                                 bgcol = WSCOL_BLACK;
  485                                 break;
  486                             case 1: /* bold */
  487                                 flags |= WSATTR_HILIT;
  488                                 break;
  489                             case 4: /* underline */
  490                                 flags |= WSATTR_UNDERLINE;
  491                                 break;
  492                             case 5: /* blink */
  493                                 flags |= WSATTR_BLINK;
  494                                 break;
  495                             case 7: /* reverse */
  496                                 flags |= WSATTR_REVERSE;
  497                                 break;
  498                             case 22: /* ~bold VT300 only */
  499                                 flags &= ~WSATTR_HILIT;
  500                                 break;
  501                             case 24: /* ~underline VT300 only */
  502                                 flags &= ~WSATTR_UNDERLINE;
  503                                 break;
  504                             case 25: /* ~blink VT300 only */
  505                                 flags &= ~WSATTR_BLINK;
  506                                 break;
  507                             case 27: /* ~reverse VT300 only */
  508                                 flags &= ~WSATTR_REVERSE;
  509                                 break;
  510                             case 30: case 31: case 32: case 33:
  511                             case 34: case 35: case 36: case 37:
  512                                 /* fg color */
  513                                 flags |= WSATTR_WSCOLORS;
  514                                 fgcol = ARG(n) - 30;
  515                                 break;
  516                             case 40: case 41: case 42: case 43:
  517                             case 44: case 45: case 46: case 47:
  518                                 /* bg color */
  519                                 flags |= WSATTR_WSCOLORS;
  520                                 bgcol = ARG(n) - 40;
  521                                 break;
  522                             default:
  523 #ifdef VT100_PRINTUNKNOWN
  524                                 printf("CSI%dm unknown\n", ARG(n));
  525 #endif
  526                                 break;
  527                         }
  528                 }
  529                 if (vt100_selectattribute(edp, flags, fgcol, bgcol, &attr,
  530                     &bkgdattr)) {
  531 #ifdef VT100_DEBUG
  532                         printf("error allocating attr %d/%d/%x\n",
  533                                fgcol, bgcol, flags);
  534 #endif
  535                 } else {
  536                         edp->curattr = attr;
  537                         edp->bkgdattr = bkgdattr;
  538                         edp->attrflags = flags;
  539                         edp->fgcol = fgcol;
  540                         edp->bgcol = bgcol;
  541                 }
  542                 break;
  543             case 'n': /* reports */
  544                 switch (ARG(0)) {
  545                     case 5: /* DSR operating status */
  546                         /* 0 = OK, 3 = malfunction */
  547                         wsdisplay_emulinput(edp->cbcookie, "\033[0n", 4);
  548                         break;
  549                     case 6: { /* DSR cursor position report */
  550                         char buf[20];
  551                         int row;
  552                         if (edp->flags & VTFL_DECOM)
  553                                 row = ROWS_ABOVE;
  554                         else
  555                                 row = edp->crow;
  556                         n = sprintf(buf, "\033[%d;%dR",
  557                                     row + 1, edp->ccol + 1);
  558                         wsdisplay_emulinput(edp->cbcookie, buf, n);
  559                         }
  560                         break;
  561                     case 15: /* DSR printer status */
  562                         /* 13 = no printer, 10 = ready, 11 = not ready */
  563                         wsdisplay_emulinput(edp->cbcookie, "\033[?13n", 6);
  564                         break;
  565                     case 25: /* UDK status - VT300 only */
  566                         /* 20 = locked, 21 = unlocked */
  567                         wsdisplay_emulinput(edp->cbcookie, "\033[?21n", 6);
  568                         break;
  569                     case 26: /* keyboard dialect */
  570                         /* 1 = north american , 7 = german */
  571                         wsdisplay_emulinput(edp->cbcookie, "\033[?27;1n", 8);
  572                         break;
  573                     default:
  574 #ifdef VT100_PRINTUNKNOWN
  575                         printf("CSI%dn unknown\n", ARG(0));
  576 #endif
  577                         break;
  578                 }
  579                 break;
  580             case 'r': /* DECSTBM set top/bottom margins */
  581                 help = min(DEF1_ARG(0), edp->nrows) - 1;
  582                 n = min(DEFx_ARG(1, edp->nrows), edp->nrows) - help;
  583                 if (n < 2) {
  584                         /* minimal scrolling region has 2 lines */
  585                         return;
  586                 } else {
  587                         edp->scrreg_startrow = help;
  588                         edp->scrreg_nrows = n;
  589                 }
  590                 edp->crow = ((edp->flags & VTFL_DECOM) ?
  591                              edp->scrreg_startrow : 0);
  592                 edp->ccol = 0;
  593                 break;
  594             case 'y':
  595                 switch (ARG(0)) {
  596                     case 4: /* DECTST invoke confidence test */
  597                         /* ignore */
  598                         break;
  599                     default:
  600 #ifdef VT100_PRINTUNKNOWN
  601                         printf("CSI%dy unknown\n", ARG(0));
  602 #endif
  603                         break;
  604                 }
  605                 break;
  606             default:
  607 #ifdef VT100_PRINTUNKNOWN
  608                 printf("CSI%c (%d, %d) unknown\n", c, ARG(0), ARG(1));
  609 #endif
  610                 break;
  611         }
  612 }
  613 
  614 /*
  615  * get an attribute from the graphics driver,
  616  * try to find replacements if the desired appearance
  617  * is not supported
  618  */
  619 static int
  620 vt100_selectattribute(struct wsemul_vt100_emuldata *edp,
  621         int flags, int fgcol, int bgcol, long *attr, long *bkgdattr)
  622 {
  623         int error;
  624 
  625         if ((flags & WSATTR_WSCOLORS) &&
  626             !(edp->scrcapabilities & WSSCREEN_WSCOLORS)) {
  627                 flags &= ~WSATTR_WSCOLORS;
  628 #ifdef VT100_DEBUG
  629                 printf("colors ignored (impossible)\n");
  630 #endif
  631         }
  632         error = (*edp->emulops->allocattr)(edp->emulcookie, fgcol, bgcol,
  633                                            flags & WSATTR_WSCOLORS, bkgdattr);
  634         if (error)
  635                 return (error);
  636 
  637         if ((flags & WSATTR_HILIT) &&
  638             !(edp->scrcapabilities & WSSCREEN_HILIT)) {
  639                 flags &= ~WSATTR_HILIT;
  640                 if (edp->scrcapabilities & WSSCREEN_WSCOLORS) {
  641 #if defined(WSEMUL_VT100_HILIT_FG) && WSEMUL_VT100_HILIT_FG != -1
  642                         fgcol = WSEMUL_VT100_HILIT_FG;
  643 #elif !defined(WSEMUL_VT100_HILIT_FG)
  644                         fgcol = WSCOL_RED;
  645 #endif
  646 #if defined(WSEMUL_VT100_HILIT_BG) && WSEMUL_VT100_HILIT_BG != -1
  647                         bgcol = WSEMUL_VT100_HILIT_BG;
  648 #endif
  649                         flags |= WSATTR_WSCOLORS;
  650                 } else {
  651 #ifdef VT100_DEBUG
  652                         printf("bold ignored (impossible)\n");
  653 #endif
  654                 }
  655         }
  656         if ((flags & WSATTR_UNDERLINE) &&
  657             !(edp->scrcapabilities & WSSCREEN_UNDERLINE)) {
  658                 flags &= ~WSATTR_UNDERLINE;
  659                 if (edp->scrcapabilities & WSSCREEN_WSCOLORS) {
  660 #if defined(WSEMUL_VT100_UNDERLINE_FG) && WSEMUL_VT100_UNDERLINE_FG != -1
  661                         fgcol = WSEMUL_VT100_UNDERLINE_FG;
  662 #endif
  663 #if defined(WSEMUL_VT100_UNDERLINE_BG) && WSEMUL_VT100_UNDERLINE_BG != -1
  664                         bgcol = WSEMUL_VT100_UNDERLINE_BG;
  665 #elif !defined(WSEMUL_VT100_UNDERLINE_BG)
  666                         bgcol = WSCOL_BROWN;
  667 #endif
  668                         flags |= WSATTR_WSCOLORS;
  669                 } else {
  670 #ifdef VT100_DEBUG
  671                         printf("underline ignored (impossible)\n");
  672 #endif
  673                 }
  674         }
  675         if ((flags & WSATTR_BLINK) &&
  676             !(edp->scrcapabilities & WSSCREEN_BLINK)) {
  677                 flags &= ~WSATTR_BLINK;
  678 #ifdef VT100_DEBUG
  679                 printf("blink ignored (impossible)\n");
  680 #endif
  681         }
  682         if ((flags & WSATTR_REVERSE) &&
  683             !(edp->scrcapabilities & WSSCREEN_REVERSE)) {
  684                 flags &= ~WSATTR_REVERSE;
  685                 if (edp->scrcapabilities & WSSCREEN_WSCOLORS) {
  686                         int help;
  687                         help = bgcol;
  688                         bgcol = fgcol;
  689                         fgcol = help;
  690                         flags |= WSATTR_WSCOLORS;
  691                 } else {
  692 #ifdef VT100_DEBUG
  693                         printf("reverse ignored (impossible)\n");
  694 #endif
  695                 }
  696         }
  697         error = (*edp->emulops->allocattr)(edp->emulcookie, fgcol, bgcol,
  698                                            flags, attr);
  699         if (error)
  700                 return (error);
  701 
  702         return (0);
  703 }
  704 
  705 /*
  706  * handle device control sequences if the main state machine
  707  * told so by setting edp->dcstype to a nonzero value
  708  */
  709 void
  710 wsemul_vt100_handle_dcs(struct wsemul_vt100_emuldata *edp)
  711 {
  712         int i, pos;
  713 
  714         switch (edp->dcstype) {
  715             case 0: /* not handled */
  716                 return;
  717             case DCSTYPE_TABRESTORE:
  718                 KASSERT(edp->tabs != 0);
  719                 memset(edp->tabs, 0, edp->ncols);
  720                 pos = 0;
  721                 for (i = 0; i < edp->dcspos; i++) {
  722                         char c = edp->dcsarg[i];
  723                         switch (c) {
  724                             case '': case '1': case '2': case '3': case '4':
  725                             case '5': case '6': case '7': case '8': case '9':
  726                                 pos = pos * 10 + (edp->dcsarg[i] - '');
  727                                 break;
  728                             case '/':
  729                                 if (pos > 0)
  730                                         edp->tabs[pos - 1] = 1;
  731                                 pos = 0;
  732                                 break;
  733                             default:
  734 #ifdef VT100_PRINTUNKNOWN
  735                                 printf("unknown char %c in DCS\n", c);
  736 #endif
  737                                 break;
  738                         }
  739                 }
  740                 if (pos > 0)
  741                         edp->tabs[pos - 1] = 1;
  742                 break;
  743             default:
  744                 panic("wsemul_vt100_handle_dcs: bad type %d", edp->dcstype);
  745         }
  746         edp->dcstype = 0;
  747 }
  748 
  749 static int
  750 vt100_ansimode(struct wsemul_vt100_emuldata *edp, int nr, int op)
  751 {
  752         int res = 0; /* default: unknown */
  753 
  754         switch (nr) {
  755             case 2: /* KAM keyboard locked/unlocked */
  756                 break;
  757             case 3: /* CRM control representation */
  758                 break;
  759             case 4: /* IRM insert/replace characters */
  760                 if (op == VTMODE_SET)
  761                         edp->flags |= VTFL_INSERTMODE;
  762                 else if (op == VTMODE_RESET)
  763                         edp->flags &= ~VTFL_INSERTMODE;
  764                 res = ((edp->flags & VTFL_INSERTMODE) ? 1 : 2);
  765                 break;
  766             case 10: /* HEM horizontal editing (permanently reset) */
  767                 res = 4;
  768                 break;
  769             case 12: /* SRM local echo off/on */
  770                 res = 4; /* permanently reset ??? */
  771                 break;
  772             case 20: /* LNM newline = newline/linefeed */
  773                 break;
  774             default:
  775 #ifdef VT100_PRINTUNKNOWN
  776                 printf("ANSI mode %d unknown\n", nr);
  777 #endif
  778                 break;
  779         }
  780         return (res);
  781 }
  782 
  783 static int
  784 vt100_decmode(struct wsemul_vt100_emuldata *edp, int nr, int op)
  785 {
  786         int res = 0; /* default: unknown */
  787         int flags;
  788 
  789         flags = edp->flags;
  790         switch (nr) {
  791             case 1: /* DECCKM application/nomal cursor keys */
  792                 if (op == VTMODE_SET)
  793                         flags |= VTFL_APPLCURSOR;
  794                 else if (op == VTMODE_RESET)
  795                         flags &= ~VTFL_APPLCURSOR;
  796                 res = ((flags & VTFL_APPLCURSOR) ? 1 : 2);
  797                 break;
  798             case 2: /* DECANM ANSI vt100/vt52 */
  799                 res = 3; /* permanently set ??? */
  800                 break;
  801             case 3: /* DECCOLM 132/80 cols */
  802             case 4: /* DECSCLM smooth/jump scroll */
  803             case 5: /* DECSCNM light/dark background */
  804                 res = 4; /* all permanently reset ??? */
  805                 break;
  806             case 6: /* DECOM move within/outside margins */
  807                 if (op == VTMODE_SET)
  808                         flags |= VTFL_DECOM;
  809                 else if (op == VTMODE_RESET)
  810                         flags &= ~VTFL_DECOM;
  811                 res = ((flags & VTFL_DECOM) ? 1 : 2);
  812                 break;
  813             case 7: /* DECAWM autowrap */
  814                 if (op == VTMODE_SET)
  815                         flags |= VTFL_DECAWM;
  816                 else if (op == VTMODE_RESET)
  817                         flags &= ~VTFL_DECAWM;
  818                 res = ((flags & VTFL_DECAWM) ? 1 : 2);
  819                 break;
  820             case 8: /* DECARM keyboard autorepeat */
  821                 break;
  822             case 18: /* DECPFF print form feed */
  823                 break;
  824             case 19: /* DECPEX printer extent: screen/scrolling region */
  825                 break;
  826             case 25: /* DECTCEM text cursor on/off */
  827                 if (op == VTMODE_SET)
  828                         flags |= VTFL_CURSORON;
  829                 else if (op == VTMODE_RESET)
  830                         flags &= ~VTFL_CURSORON;
  831                 if (flags != edp->flags)
  832                         (*edp->emulops->cursor)(edp->emulcookie,
  833                                                 flags & VTFL_CURSORON,
  834                                                 edp->crow, edp->ccol);
  835                 res = ((flags & VTFL_CURSORON) ? 1 : 2);
  836                 break;
  837             case 42: /* DECNRCM use 7-bit NRC /
  838                       7/8 bit from DEC multilingual or ISO-latin-1*/
  839                 if (op == VTMODE_SET)
  840                         flags |= VTFL_NATCHARSET;
  841                 else if (op == VTMODE_RESET)
  842                         flags &= ~VTFL_NATCHARSET;
  843                 res = ((flags & VTFL_NATCHARSET) ? 1 : 2);
  844                 break;
  845             case 66: /* DECNKM numeric keypad */
  846                 break;
  847             case 68: /* DECKBUM keyboard usage data processing/typewriter */
  848                 break;
  849             default:
  850 #ifdef VT100_PRINTUNKNOWN
  851                 printf("DEC mode %d unknown\n", nr);
  852 #endif
  853                 break;
  854         }
  855         edp->flags = flags;
  856 
  857         return (res);
  858 }

Cache object: 972cc3f80762f2d9b1b84431be148f6e


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