root/dev/wscons/wsemul_vt100_subr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wsemul_vt100_scrollup
  2. wsemul_vt100_scrolldown
  3. wsemul_vt100_ed
  4. wsemul_vt100_el
  5. wsemul_vt100_handle_csi
  6. vt100_selectattribute
  7. wsemul_vt100_handle_dcs
  8. vt100_ansimode
  9. vt100_decmode

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

/* [<][>][^][v][top][bottom][index][help] */