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