LCOV - code coverage report
Current view: top level - dev/wscons - wsemul_vt100_subr.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 349 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13