1 /* $NetBSD: ite.c,v 1.65 2022/03/29 06:56:51 riastradh Exp $ */ 2 3 /* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer 10 * Science Department. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: Utah $Hdr: ite.c 1.1 90/07/09$ 37 * 38 * @(#)ite.c 7.6 (Berkeley) 5/16/91 39 */ 40 41 /* 42 * ite - bitmaped terminal. 43 * Supports VT200, a few terminal features will be unavailable until 44 * the system actually probes the device (i.e. not after consinit()) 45 */ 46 47 #include <sys/cdefs.h> 48 __KERNEL_RCSID(0, "$NetBSD: ite.c,v 1.65 2022/03/29 06:56:51 riastradh Exp $"); 49 50 #include "ite.h" 51 #if NITE > 0 52 53 #include "bell.h" 54 #include "kbd.h" 55 56 #include "opt_ite.h" 57 58 #include <sys/param.h> 59 #include <sys/conf.h> 60 #include <sys/proc.h> 61 #include <sys/ioctl.h> 62 #include <sys/tty.h> 63 #include <sys/systm.h> 64 #include <sys/device.h> 65 #include <sys/malloc.h> 66 #include <sys/kauth.h> 67 #include <sys/device_impl.h> /* XXX autoconf abuse */ 68 69 #include <machine/cpu.h> 70 #include <machine/kbio.h> 71 #include <machine/bus.h> 72 #include <machine/autoconf.h> 73 #include <machine/grfioctl.h> 74 #include <machine/iteioctl.h> 75 76 #include <arch/x68k/dev/grfvar.h> 77 #include <arch/x68k/dev/itevar.h> 78 #include <arch/x68k/dev/kbdmap.h> 79 #include <arch/x68k/dev/mfp.h> 80 #if NBELL > 0 81 void opm_bell(void); 82 #endif 83 84 #define SUBR_INIT(ip) ip->isw->ite_init(ip) 85 #define SUBR_DEINIT(ip) ip->isw->ite_deinit(ip) 86 #define SUBR_PUTC(ip,c,dy,dx,m) ip->isw->ite_putc(ip,c,dy,dx,m) 87 #define SUBR_CURSOR(ip,flg) ip->isw->ite_cursor(ip,flg) 88 #define SUBR_CLEAR(ip,sy,sx,h,w) ip->isw->ite_clear(ip,sy,sx,h,w) 89 #define SUBR_SCROLL(ip,sy,sx,count,dir) \ 90 ip->isw->ite_scroll(ip,sy,sx,count,dir) 91 92 struct consdev; 93 94 inline static void itesendch(int); 95 inline static void alignment_display(struct ite_softc *); 96 inline static void snap_cury(struct ite_softc *); 97 inline static void ite_dnchar(struct ite_softc *, int); 98 static void ite_inchar(struct ite_softc *, int); 99 inline static void ite_clrtoeol(struct ite_softc *); 100 inline static void ite_clrtobol(struct ite_softc *); 101 inline static void ite_clrline(struct ite_softc *); 102 inline static void ite_clrtoeos(struct ite_softc *); 103 inline static void ite_clrtobos(struct ite_softc *); 104 inline static void ite_clrscreen(struct ite_softc *); 105 inline static void ite_dnline(struct ite_softc *, int); 106 inline static void ite_inline(struct ite_softc *, int); 107 inline static void ite_index(struct ite_softc *); 108 inline static void ite_lf(struct ite_softc *); 109 inline static void ite_crlf(struct ite_softc *); 110 inline static void ite_cr(struct ite_softc *); 111 inline static void ite_rlf(struct ite_softc *); 112 static void iteprecheckwrap(struct ite_softc *); 113 static void itecheckwrap(struct ite_softc *); 114 static int ite_argnum(struct ite_softc *); 115 static int ite_zargnum(struct ite_softc *); 116 static void ite_sendstr(struct ite_softc *, const char *); 117 inline static int atoi(const char *); 118 void ite_reset(struct ite_softc *); 119 struct ite_softc *getitesp(dev_t); 120 int iteon(dev_t, int); 121 void iteoff(dev_t, int); 122 123 struct itesw itesw[] = { 124 {0, tv_init, tv_deinit, 0, 125 0, 0, 0} 126 }; 127 128 /* 129 * # of chars are output in a single itestart() call. 130 * If this is too big, user processes will be blocked out for 131 * long periods of time while we are emptying the queue in itestart(). 132 * If it is too small, console output will be very ragged. 133 */ 134 #define ITEBURST 64 135 136 struct tty *ite_tty[NITE]; 137 struct ite_softc *kbd_ite = NULL; 138 struct ite_softc con_itesoftc; 139 struct device con_itedev; 140 141 struct tty *kbd_tty = NULL; 142 143 int start_repeat_timeo = 20; /* /100: initial timeout till pressed key repeats */ 144 int next_repeat_timeo = 3; /* /100: timeout when repeating for next char */ 145 146 u_char cons_tabs[MAX_TABS]; 147 148 void itestart(struct tty *); 149 150 void iteputchar(int, struct ite_softc *); 151 void ite_putstr(const u_char *, int, dev_t); 152 153 int itematch(device_t, cfdata_t, void *); 154 void iteattach(device_t, device_t, void *); 155 156 CFATTACH_DECL_NEW(ite, sizeof(struct ite_softc), 157 itematch, iteattach, NULL, NULL); 158 159 extern struct cfdriver ite_cd; 160 161 dev_type_open(iteopen); 162 dev_type_close(iteclose); 163 dev_type_read(iteread); 164 dev_type_write(itewrite); 165 dev_type_ioctl(iteioctl); 166 dev_type_tty(itetty); 167 dev_type_poll(itepoll); 168 169 const struct cdevsw ite_cdevsw = { 170 .d_open = iteopen, 171 .d_close = iteclose, 172 .d_read = iteread, 173 .d_write = itewrite, 174 .d_ioctl = iteioctl, 175 .d_stop = nostop, 176 .d_tty = itetty, 177 .d_poll = itepoll, 178 .d_mmap = nommap, 179 .d_kqfilter = ttykqfilter, 180 .d_discard = nodiscard, 181 .d_flag = D_TTY 182 }; 183 184 int 185 itematch(device_t parent, cfdata_t cf, void *aux) 186 { 187 struct grf_softc *gp; 188 189 gp = aux; 190 if (cf->cf_loc[GRFCF_GRFADDR] != gp->g_cfaddr) 191 return 0; 192 193 return 1; 194 } 195 196 /* 197 * iteinit() is the standard entry point for initialization of 198 * an ite device, it is also called from ite_cninit(). 199 */ 200 void 201 iteattach(device_t parent, device_t self, void *aux) 202 { 203 struct ite_softc *ip; 204 struct grf_softc *gp; 205 206 gp = aux; 207 ip = device_private(self); 208 ip->device = self; 209 if(con_itesoftc.grf != NULL 210 /*&& con_itesoftc.grf->g_unit == gp->g_unit*/) { 211 /* 212 * console reinit copy params over. 213 * and console always gets keyboard 214 */ 215 memcpy(&ip->grf, &con_itesoftc.grf, 216 (char *)&ip[1] - (char *)&ip->grf); 217 con_itesoftc.grf = NULL; 218 kbd_ite = ip; 219 } 220 ip->grf = gp; 221 iteinit(device_unit(self)); /* XXX */ 222 aprint_normal(": rows %d cols %d", ip->rows, ip->cols); 223 if (kbd_ite == NULL) 224 kbd_ite = ip; 225 aprint_normal("\n"); 226 } 227 228 struct ite_softc * 229 getitesp(dev_t dev) 230 { 231 232 if (x68k_realconfig && con_itesoftc.grf == NULL) 233 return device_lookup_private(&ite_cd, UNIT(dev)); 234 235 if (con_itesoftc.grf == NULL) 236 panic("no ite_softc for console"); 237 return(&con_itesoftc); 238 } 239 240 void 241 iteinit(dev_t dev) 242 { 243 struct ite_softc *ip; 244 245 ip = getitesp(dev); 246 247 if (ip->flags & ITE_INITED) 248 return; 249 memcpy(&kbdmap, &ascii_kbdmap, sizeof(struct kbdmap)); 250 251 ip->curx = 0; 252 ip->cury = 0; 253 ip->cursorx = 0; 254 ip->cursory = 0; 255 256 ip->isw = &itesw[device_unit(ip->device)]; /* XXX */ 257 SUBR_INIT(ip); 258 SUBR_CURSOR(ip, DRAW_CURSOR); 259 if (!ip->tabs) 260 ip->tabs = malloc(MAX_TABS*sizeof(u_char), M_DEVBUF, M_WAITOK); 261 ite_reset(ip); 262 ip->flags |= ITE_INITED; 263 } 264 265 void 266 ite_config_console(void) 267 { 268 struct grf_softc *gp = &congrf; 269 270 if (con_itesoftc.grf != NULL) 271 return; 272 con_itesoftc.grf = gp; 273 con_itesoftc.tabs = cons_tabs; 274 con_itesoftc.device = &con_itedev; 275 } 276 277 /* 278 * Perform functions necessary to setup device as a terminal emulator. 279 */ 280 int 281 iteon(dev_t dev, int flag) 282 { 283 int unit = UNIT(dev); 284 struct ite_softc *ip; 285 286 if (unit < 0 || unit >= ite_cd.cd_ndevs || 287 (ip = getitesp(dev)) == NULL || (ip->flags&ITE_ALIVE) == 0) 288 return(ENXIO); 289 /* force ite active, overriding graphics mode */ 290 if (flag & 1) { 291 ip->flags |= ITE_ACTIVE; 292 ip->flags &= ~(ITE_INGRF|ITE_INITED); 293 } 294 /* leave graphics mode */ 295 if (flag & 2) { 296 ip->flags &= ~ITE_INGRF; 297 if ((ip->flags & ITE_ACTIVE) == 0) 298 return(0); 299 } 300 ip->flags |= ITE_ACTIVE; 301 if (ip->flags & ITE_INGRF) 302 return(0); 303 iteinit(dev); 304 if (flag & 2) 305 ite_reset(ip); 306 #if NKBD > 0 307 mfp_send_usart(0x49); /* XXX */ 308 #endif 309 return(0); 310 } 311 312 /* 313 * "Shut down" device as terminal emulator. 314 * Note that we do not deinit the console device unless forced. 315 * Deinit'ing the console every time leads to a very active 316 * screen when processing /etc/rc. 317 */ 318 void 319 iteoff(dev_t dev, int flag) 320 { 321 int unit = UNIT(dev); 322 struct ite_softc *ip; 323 324 /* XXX check whether when call from grf.c */ 325 if (unit < 0 || unit >= ite_cd.cd_ndevs || 326 (ip = getitesp(dev)) == NULL || (ip->flags&ITE_ALIVE) == 0) 327 return; 328 if (flag & 2) 329 ip->flags |= ITE_INGRF; 330 331 if ((ip->flags & ITE_ACTIVE) == 0) 332 return; 333 if ((flag & 1) || 334 (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED) 335 SUBR_DEINIT(ip); 336 337 /* 338 * XXX When the system is rebooted with "reboot", init(8) 339 * kills the last process to have the console open. 340 * If we don't revent the ITE_ACTIVE bit from being 341 * cleared, we will never see messages printed during 342 * the process of rebooting. 343 */ 344 if ((flag & 2) == 0 && (ip->flags & ITE_ISCONS) == 0) { 345 ip->flags &= ~ITE_ACTIVE; 346 #if NKBD > 0 347 mfp_send_usart(0x48); /* XXX */ 348 #endif 349 } 350 } 351 352 /* 353 * standard entry points to the device. 354 */ 355 356 /* ARGSUSED */ 357 int 358 iteopen(dev_t dev, int mode, int devtype, struct lwp *l) 359 { 360 int unit = UNIT(dev); 361 struct tty *tp; 362 struct ite_softc *ip; 363 int error; 364 int first = 0; 365 366 if (unit >= ite_cd.cd_ndevs || (ip = getitesp(dev)) == NULL) 367 return (ENXIO); 368 if (!ite_tty[unit]) { 369 tp = ite_tty[unit] = tty_alloc(); 370 tty_attach(tp); 371 } else 372 tp = ite_tty[unit]; 373 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 374 return (EBUSY); 375 if ((ip->flags & ITE_ACTIVE) == 0) { 376 error = iteon(dev, 0); 377 if (error) 378 return (error); 379 first = 1; 380 } 381 tp->t_oproc = itestart; 382 tp->t_param = NULL; 383 tp->t_dev = dev; 384 if ((tp->t_state&TS_ISOPEN) == 0) { 385 ttychars(tp); 386 tp->t_iflag = TTYDEF_IFLAG; 387 tp->t_oflag = TTYDEF_OFLAG; 388 tp->t_cflag = TTYDEF_CFLAG; 389 tp->t_lflag = TTYDEF_LFLAG; 390 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 391 tp->t_state = TS_ISOPEN|TS_CARR_ON; 392 ttsetwater(tp); 393 } 394 error = (*tp->t_linesw->l_open)(dev, tp); 395 if (error == 0) { 396 tp->t_winsize.ws_row = ip->rows; 397 tp->t_winsize.ws_col = ip->cols; 398 } else if (first) 399 iteoff(dev, 0); 400 return (error); 401 } 402 403 /*ARGSUSED*/ 404 int 405 iteclose(dev_t dev, int flag, int mode, struct lwp *l) 406 { 407 struct tty *tp = ite_tty[UNIT(dev)]; 408 409 (*tp->t_linesw->l_close)(tp, flag); 410 ttyclose(tp); 411 iteoff(dev, 0); 412 #if 0 413 tty_free(tp); 414 ite_tty[UNIT(dev)] = (struct tty *)0; 415 #endif 416 return(0); 417 } 418 419 int 420 iteread(dev_t dev, struct uio *uio, int flag) 421 { 422 struct tty *tp = ite_tty[UNIT(dev)]; 423 424 return ((*tp->t_linesw->l_read)(tp, uio, flag)); 425 } 426 427 int 428 itewrite(dev_t dev, struct uio *uio, int flag) 429 { 430 struct tty *tp = ite_tty[UNIT(dev)]; 431 432 return ((*tp->t_linesw->l_write)(tp, uio, flag)); 433 } 434 435 int 436 itepoll(dev_t dev, int events, struct lwp *l) 437 { 438 struct tty *tp = ite_tty[UNIT(dev)]; 439 440 return ((*tp->t_linesw->l_poll)(tp, events, l)); 441 } 442 443 struct tty * 444 itetty(dev_t dev) 445 { 446 447 return (ite_tty[UNIT(dev)]); 448 } 449 450 int 451 iteioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) 452 { 453 struct iterepeat *irp; 454 struct tty *tp = ite_tty[UNIT(dev)]; 455 int error; 456 457 error = (*tp->t_linesw->l_ioctl)(tp, cmd, addr, flag, l); 458 if (error != EPASSTHROUGH) 459 return (error); 460 461 error = ttioctl(tp, cmd, addr, flag, l); 462 if (error != EPASSTHROUGH) 463 return (error); 464 465 switch (cmd) { 466 case ITEIOCSKMAP: 467 if (addr == 0) 468 return(EFAULT); 469 memcpy(&kbdmap, addr, sizeof(struct kbdmap)); 470 return(0); 471 472 case ITEIOCGKMAP: 473 if (addr == NULL) 474 return(EFAULT); 475 memcpy(addr, &kbdmap, sizeof(struct kbdmap)); 476 return(0); 477 478 case ITEIOCGREPT: 479 irp = (struct iterepeat *)addr; 480 irp->start = start_repeat_timeo; 481 irp->next = next_repeat_timeo; 482 483 case ITEIOCSREPT: 484 irp = (struct iterepeat *)addr; 485 if (irp->start < ITEMINREPEAT && irp->next < ITEMINREPEAT) 486 return(EINVAL); 487 start_repeat_timeo = irp->start; 488 next_repeat_timeo = irp->next; 489 #if x68k 490 case ITELOADFONT: 491 if (addr) { 492 memcpy(kern_font, addr, 4096 /*sizeof(kernel_font)*/); 493 ite_set_glyph(); 494 return 0; 495 } else 496 return EFAULT; 497 498 case ITETVCTRL: 499 if (addr && *(u_int8_t *)addr < 0x40) { 500 return mfp_send_usart(* (u_int8_t *)addr); 501 } else { 502 return EFAULT; 503 } 504 #endif 505 } 506 return (EPASSTHROUGH); 507 } 508 509 void 510 itestart(struct tty *tp) 511 { 512 struct clist *rbp; 513 u_char buf[ITEBURST]; 514 int s, len; 515 516 getitesp(tp->t_dev); 517 /* 518 * (Potentially) lower priority. We only need to protect ourselves 519 * from keyboard interrupts since that is all that can affect the 520 * state of our tty (kernel printf doesn't go through this routine). 521 */ 522 s = spltty(); 523 if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) 524 goto out; 525 tp->t_state |= TS_BUSY; 526 rbp = &tp->t_outq; 527 len = q_to_b(rbp, buf, ITEBURST); 528 /*splx(s);*/ 529 530 /* Here is a really good place to implement pre/jumpscroll() */ 531 ite_putstr(buf, len, tp->t_dev); 532 533 /*s = spltty();*/ 534 tp->t_state &= ~TS_BUSY; 535 /* we have characters remaining. */ 536 if (ttypull(tp)) { 537 tp->t_state |= TS_TIMEOUT; 538 callout_schedule(&tp->t_rstrt_ch, 1); 539 } 540 out: 541 splx(s); 542 } 543 544 /* XXX called after changes made in underlying grf layer. */ 545 /* I want to nuke this */ 546 void 547 ite_reinit(dev_t dev) 548 { 549 struct ite_softc *ip; 550 int unit = UNIT(dev); 551 552 /* XXX check whether when call from grf.c */ 553 if (unit < 0 || unit >= ite_cd.cd_ndevs || 554 (ip = getitesp(dev)) == NULL) 555 return; 556 557 ip->flags &= ~ITE_INITED; 558 iteinit(dev); 559 } 560 561 void 562 ite_reset(struct ite_softc *ip) 563 { 564 int i; 565 566 ip->curx = 0; 567 ip->cury = 0; 568 ip->attribute = 0; 569 ip->save_curx = 0; 570 ip->save_cury = 0; 571 ip->save_attribute = 0; 572 ip->ap = ip->argbuf; 573 ip->emul_level = EMUL_VT300_8; 574 ip->eightbit_C1 = 0; 575 ip->top_margin = 0; 576 ip->bottom_margin = ip->rows - 1; 577 ip->inside_margins = 0; /* origin mode == absolute */ 578 ip->linefeed_newline = 0; 579 ip->auto_wrap = 1; 580 ip->cursor_appmode = 0; 581 ip->keypad_appmode = 0; 582 ip->imode = 0; 583 ip->key_repeat = 1; 584 ip->G0 = CSET_ASCII; 585 ip->G1 = CSET_JIS1983; 586 ip->G2 = CSET_JISKANA; 587 ip->G3 = CSET_JIS1990; 588 ip->GL = &ip->G0; 589 ip->GR = &ip->G1; 590 ip->save_GL = 0; 591 ip->save_char = 0; 592 ip->fgcolor = 7; 593 ip->bgcolor = 0; 594 for (i = 0; i < ip->cols; i++) 595 ip->tabs[i] = ((i & 7) == 0); 596 /* XXX clear screen */ 597 SUBR_CLEAR(ip, 0, 0, ip->rows, ip->cols); 598 attrclr(ip, 0, 0, ip->rows, ip->cols); 599 } 600 601 /* Used in console at startup only */ 602 int 603 ite_cnfilter(u_char c) 604 { 605 static u_char mod = 0; 606 struct key key; 607 u_char code, up, mask; 608 int s; 609 610 up = c & 0x80 ? 1 : 0; 611 c &= 0x7f; 612 code = 0; 613 614 s = spltty(); 615 616 mask = 0; 617 if (c >= KBD_LEFT_ALT && !(c >= 0x63 && c <= 0x6c)) { /* 0x63: F1, 0x6c:F10 */ 618 switch (c) { 619 case KBD_LEFT_SHIFT: 620 mask = KBD_MOD_SHIFT; 621 break; 622 623 case KBD_LEFT_ALT: 624 mask = KBD_MOD_LALT; 625 break; 626 627 case KBD_RIGHT_ALT: 628 mask = KBD_MOD_RALT; 629 break; 630 631 case KBD_LEFT_META: 632 mask = KBD_MOD_LMETA; 633 break; 634 635 case KBD_RIGHT_META: 636 mask = KBD_MOD_RMETA; 637 break; 638 639 case KBD_CAPS_LOCK: 640 /* 641 * capslock already behaves `right', don't need to 642 * keep track of the state in here. 643 */ 644 mask = KBD_MOD_CAPS; 645 break; 646 647 case KBD_CTRL: 648 mask = KBD_MOD_CTRL; 649 break; 650 651 case KBD_RECONNECT: 652 /* ite got 0xff */ 653 if (up) 654 kbd_setLED(); 655 break; 656 } 657 if (mask & KBD_MOD_CAPS) { 658 if (!up) { 659 mod ^= KBD_MOD_CAPS; 660 kbdled ^= LED_CAPS_LOCK; 661 kbd_setLED(); 662 } 663 } else if (up) 664 mod &= ~mask; 665 else mod |= mask; 666 splx(s); 667 return -1; 668 } 669 670 if (up) { 671 splx(s); 672 return -1; 673 } 674 675 /* translate modifiers */ 676 if (mod & KBD_MOD_SHIFT) { 677 if (mod & KBD_MOD_ALT) 678 key = kbdmap.alt_shift_keys[c]; 679 else 680 key = kbdmap.shift_keys[c]; 681 } else if (mod & KBD_MOD_ALT) 682 key = kbdmap.alt_keys[c]; 683 else { 684 key = kbdmap.keys[c]; 685 /* if CAPS and key is CAPable (no pun intended) */ 686 if ((mod & KBD_MOD_CAPS) && (key.mode & KBD_MODE_CAPS)) 687 key = kbdmap.shift_keys[c]; 688 } 689 code = key.code; 690 691 /* if string return */ 692 if (key.mode & (KBD_MODE_STRING | KBD_MODE_KPAD)) { 693 splx(s); 694 return -1; 695 } 696 /* handle dead keys */ 697 if (key.mode & KBD_MODE_DEAD) { 698 splx(s); 699 return -1; 700 } 701 if (mod & KBD_MOD_CTRL) 702 code &= 0x1f; 703 if (mod & KBD_MOD_META) 704 code |= 0x80; 705 706 /* do console mapping. */ 707 code = code == '\r' ? '\n' : code; 708 709 splx(s); 710 return (code); 711 } 712 713 /* And now the old stuff. */ 714 inline static void 715 itesendch(int ch) 716 { 717 (*kbd_tty->t_linesw->l_rint)(ch, kbd_tty); 718 } 719 720 721 void 722 ite_filter(u_char c) 723 { 724 static u_short mod = 0; 725 unsigned char code, *str; 726 u_short up, mask; 727 struct key key; 728 int s, i; 729 730 if (!kbd_ite || !(kbd_tty = ite_tty[device_unit(kbd_ite->device)])) 731 return; 732 733 /* have to make sure we're at spltty in here */ 734 s = spltty(); 735 736 up = c & 0x80 ? 1 : 0; 737 c &= 0x7f; 738 code = 0; 739 740 mask = 0; 741 if (c >= KBD_LEFT_ALT && 742 !(c >= 0x63 && c <= 0x6c)) { /* 0x63: F1, 0x6c:F10 */ 743 switch (c) { 744 case KBD_LEFT_SHIFT: 745 mask = KBD_MOD_SHIFT; 746 break; 747 748 case KBD_LEFT_ALT: 749 mask = KBD_MOD_LALT; 750 break; 751 752 case KBD_RIGHT_ALT: 753 mask = KBD_MOD_RALT; 754 break; 755 756 case KBD_LEFT_META: 757 mask = KBD_MOD_LMETA; 758 break; 759 760 case KBD_RIGHT_META: 761 mask = KBD_MOD_RMETA; 762 break; 763 764 case KBD_CAPS_LOCK: 765 /* 766 * capslock already behaves `right', don't need to keep 767 * track of the state in here. 768 */ 769 mask = KBD_MOD_CAPS; 770 break; 771 772 case KBD_CTRL: 773 mask = KBD_MOD_CTRL; 774 break; 775 776 case KBD_OPT1: 777 mask = KBD_MOD_OPT1; 778 break; 779 780 case KBD_OPT2: 781 mask = KBD_MOD_OPT2; 782 break; 783 784 case KBD_RECONNECT: 785 if (up) { /* ite got 0xff */ 786 kbd_setLED(); 787 } 788 break; 789 } 790 791 if (mask & KBD_MOD_CAPS) { 792 if (!up) { 793 mod ^= KBD_MOD_CAPS; 794 kbdled ^= LED_CAPS_LOCK; 795 kbd_setLED(); 796 } 797 } else if (up) { 798 mod &= ~mask; 799 } else mod |= mask; 800 801 /* 802 * return even if it wasn't a modifier key, the other 803 * codes up here are either special (like reset warning), 804 * or not yet defined 805 */ 806 splx(s); 807 return; 808 } 809 810 if (up) { 811 splx(s); 812 return; 813 } 814 815 /* 816 * intercept LAlt-LMeta-F1 here to switch back to original ascii-keymap. 817 * this should probably be configurable.. 818 */ 819 if (mod == (KBD_MOD_LALT|KBD_MOD_LMETA) && c == 0x63) { 820 memcpy(&kbdmap, &ascii_kbdmap, sizeof(struct kbdmap)); 821 splx(s); 822 return; 823 } 824 825 /* translate modifiers */ 826 if (mod & KBD_MOD_SHIFT) { 827 if (mod & KBD_MOD_ALT) 828 key = kbdmap.alt_shift_keys[c]; 829 else 830 key = kbdmap.shift_keys[c]; 831 } else if (mod & KBD_MOD_ALT) 832 key = kbdmap.alt_keys[c]; 833 else { 834 key = kbdmap.keys[c]; 835 /* if CAPS and key is CAPable (no pun intended) */ 836 if ((mod & KBD_MOD_CAPS) && (key.mode & KBD_MODE_CAPS)) 837 key = kbdmap.shift_keys[c]; 838 else if ((mod & KBD_MOD_OPT2) && (key.mode & KBD_MODE_KPAD)) 839 key = kbdmap.shift_keys[c]; 840 } 841 code = key.code; 842 843 /* handle dead keys */ 844 if (key.mode & KBD_MODE_DEAD) { 845 splx(s); 846 return; 847 } 848 /* if not string, apply META and CTRL modifiers */ 849 if (! (key.mode & KBD_MODE_STRING) 850 && (!(key.mode & KBD_MODE_KPAD) || 851 (kbd_ite && !kbd_ite->keypad_appmode))) { 852 if ((mod & KBD_MOD_CTRL) && 853 (code == ' ' || (code >= '@' && code <= 'z'))) 854 code &= 0x1f; 855 if (mod & KBD_MOD_META) 856 code |= 0x80; 857 } else if ((key.mode & KBD_MODE_KPAD) && 858 (kbd_ite && kbd_ite->keypad_appmode)) { 859 static const char * const in = "0123456789-+.\r()/*"; 860 static const char * const out = "pqrstuvwxymlnMPQRS"; 861 char *cp = strchr(in, code); 862 863 /* 864 * keypad-appmode sends SS3 followed by the above 865 * translated character 866 */ 867 (*kbd_tty->t_linesw->l_rint)(27, kbd_tty); 868 (*kbd_tty->t_linesw->l_rint)('O', kbd_tty); 869 (*kbd_tty->t_linesw->l_rint)(out[cp - in], kbd_tty); 870 splx(s); 871 return; 872 } else { 873 /* *NO* I don't like this.... */ 874 static u_char app_cursor[] = 875 { 876 3, 27, 'O', 'A', 877 3, 27, 'O', 'B', 878 3, 27, 'O', 'C', 879 3, 27, 'O', 'D'}; 880 881 str = kbdmap.strings + code; 882 /* 883 * if this is a cursor key, AND it has the default 884 * keymap setting, AND we're in app-cursor mode, switch 885 * to the above table. This is *nasty* ! 886 */ 887 if (c >= 0x3b && c <= 0x3e && kbd_ite->cursor_appmode 888 && !memcmp(str, "\x03\x1b[", 3) && 889 strchr("ABCD", str[3])) 890 str = app_cursor + 4 * (str[3] - 'A'); 891 892 /* 893 * using a length-byte instead of 0-termination allows 894 * to embed \0 into strings, although this is not used 895 * in the default keymap 896 */ 897 for (i = *str++; i; i--) 898 (*kbd_tty->t_linesw->l_rint)(*str++, kbd_tty); 899 splx(s); 900 return; 901 } 902 (*kbd_tty->t_linesw->l_rint)(code, kbd_tty); 903 904 splx(s); 905 return; 906 } 907 908 /* helper functions, makes the code below more readable */ 909 inline static void 910 ite_sendstr(struct ite_softc *ip, const char *str) 911 { 912 while (*str) 913 itesendch(*str++); 914 } 915 916 inline static void 917 alignment_display(struct ite_softc *ip) 918 { 919 int i, j; 920 921 for (j = 0; j < ip->rows; j++) 922 for (i = 0; i < ip->cols; i++) 923 SUBR_PUTC(ip, 'E', j, i, ATTR_NOR); 924 attrclr(ip, 0, 0, ip->rows, ip->cols); 925 } 926 927 inline static void 928 snap_cury(struct ite_softc *ip) 929 { 930 if (ip->inside_margins) { 931 if (ip->cury < ip->top_margin) 932 ip->cury = ip->top_margin; 933 if (ip->cury > ip->bottom_margin) 934 ip->cury = ip->bottom_margin; 935 } 936 } 937 938 inline static void 939 ite_dnchar(struct ite_softc *ip, int n) 940 { 941 n = uimin(n, ip->cols - ip->curx); 942 if (n < ip->cols - ip->curx) { 943 SUBR_SCROLL(ip, ip->cury, ip->curx + n, n, SCROLL_LEFT); 944 attrmov(ip, ip->cury, ip->curx + n, ip->cury, ip->curx, 945 1, ip->cols - ip->curx - n); 946 attrclr(ip, ip->cury, ip->cols - n, 1, n); 947 } 948 while (n-- > 0) 949 SUBR_PUTC(ip, ' ', ip->cury, ip->cols - n - 1, ATTR_NOR); 950 } 951 952 static void 953 ite_inchar(struct ite_softc *ip, int n) 954 { 955 int c = ip->save_char; 956 ip->save_char = 0; 957 n = uimin(n, ip->cols - ip->curx); 958 if (n < ip->cols - ip->curx) { 959 SUBR_SCROLL(ip, ip->cury, ip->curx, n, SCROLL_RIGHT); 960 attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + n, 961 1, ip->cols - ip->curx - n); 962 attrclr(ip, ip->cury, ip->curx, 1, n); 963 } 964 while (n--) 965 SUBR_PUTC(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR); 966 ip->save_char = c; 967 } 968 969 inline static void 970 ite_clrtoeol(struct ite_softc *ip) 971 { 972 int y = ip->cury, x = ip->curx; 973 if (ip->cols - x > 0) { 974 SUBR_CLEAR(ip, y, x, 1, ip->cols - x); 975 attrclr(ip, y, x, 1, ip->cols - x); 976 } 977 } 978 979 inline static void 980 ite_clrtobol(struct ite_softc *ip) 981 { 982 int y = ip->cury, x = uimin(ip->curx + 1, ip->cols); 983 SUBR_CLEAR(ip, y, 0, 1, x); 984 attrclr(ip, y, 0, 1, x); 985 } 986 987 inline static void 988 ite_clrline(struct ite_softc *ip) 989 { 990 int y = ip->cury; 991 SUBR_CLEAR(ip, y, 0, 1, ip->cols); 992 attrclr(ip, y, 0, 1, ip->cols); 993 } 994 995 inline static void 996 ite_clrtoeos(struct ite_softc *ip) 997 { 998 ite_clrtoeol(ip); 999 if (ip->cury < ip->rows - 1) { 1000 SUBR_CLEAR(ip, ip->cury + 1, 0, ip->rows - 1 - ip->cury, ip->cols); 1001 attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); 1002 } 1003 } 1004 1005 inline static void 1006 ite_clrtobos(struct ite_softc *ip) 1007 { 1008 ite_clrtobol(ip); 1009 if (ip->cury > 0) { 1010 SUBR_CLEAR(ip, 0, 0, ip->cury, ip->cols); 1011 attrclr(ip, 0, 0, ip->cury, ip->cols); 1012 } 1013 } 1014 1015 inline static void 1016 ite_clrscreen(struct ite_softc *ip) 1017 { 1018 SUBR_CLEAR(ip, 0, 0, ip->rows, ip->cols); 1019 attrclr(ip, 0, 0, ip->rows, ip->cols); 1020 } 1021 1022 1023 1024 inline static void 1025 ite_dnline(struct ite_softc *ip, int n) 1026 { 1027 /* 1028 * interesting.. if the cursor is outside the scrolling 1029 * region, this command is simply ignored.. 1030 */ 1031 if (ip->cury < ip->top_margin || ip->cury > ip->bottom_margin) 1032 return; 1033 1034 n = uimin(n, ip->bottom_margin + 1 - ip->cury); 1035 if (n <= ip->bottom_margin - ip->cury) { 1036 SUBR_SCROLL(ip, ip->cury + n, 0, n, SCROLL_UP); 1037 attrmov(ip, ip->cury + n, 0, ip->cury, 0, 1038 ip->bottom_margin + 1 - ip->cury - n, ip->cols); 1039 } 1040 SUBR_CLEAR(ip, ip->bottom_margin - n + 1, 0, n, ip->cols); 1041 attrclr(ip, ip->bottom_margin - n + 1, 0, n, ip->cols); 1042 } 1043 1044 inline static void 1045 ite_inline(struct ite_softc *ip, int n) 1046 { 1047 /* 1048 * interesting.. if the cursor is outside the scrolling 1049 * region, this command is simply ignored.. 1050 */ 1051 if (ip->cury < ip->top_margin || ip->cury > ip->bottom_margin) 1052 return; 1053 1054 if (n <= 0) 1055 n = 1; 1056 else n = uimin(n, ip->bottom_margin + 1 - ip->cury); 1057 if (n <= ip->bottom_margin - ip->cury) { 1058 SUBR_SCROLL(ip, ip->cury, 0, n, SCROLL_DOWN); 1059 attrmov(ip, ip->cury, 0, ip->cury + n, 0, 1060 ip->bottom_margin + 1 - ip->cury - n, ip->cols); 1061 } 1062 SUBR_CLEAR(ip, ip->cury, 0, n, ip->cols); 1063 attrclr(ip, ip->cury, 0, n, ip->cols); 1064 ip->curx = 0; 1065 } 1066 1067 inline static void 1068 ite_index(struct ite_softc *ip) 1069 { 1070 ++ip->cury; 1071 if ((ip->cury == ip->bottom_margin+1) || (ip->cury == ip->rows)) { 1072 ip->cury--; 1073 SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP); 1074 ite_clrline(ip); 1075 } 1076 /*clr_attr(ip, ATTR_INV);*/ 1077 } 1078 1079 inline static void 1080 ite_lf(struct ite_softc *ip) 1081 { 1082 ++ip->cury; 1083 if (ip->cury > ip->bottom_margin) { 1084 ip->cury--; 1085 SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP); 1086 ite_clrline(ip); 1087 } 1088 /* SUBR_CURSOR(ip, MOVE_CURSOR);*/ 1089 /*clr_attr(ip, ATTR_INV);*/ 1090 /* reset character set ... thanks for mohta. */ 1091 ip->G0 = CSET_ASCII; 1092 ip->G1 = CSET_JIS1983; 1093 ip->G2 = CSET_JISKANA; 1094 ip->G3 = CSET_JIS1990; 1095 ip->GL = &ip->G0; 1096 ip->GR = &ip->G1; 1097 ip->save_GL = 0; 1098 ip->save_char = 0; 1099 } 1100 1101 inline static void 1102 ite_crlf(struct ite_softc *ip) 1103 { 1104 ip->curx = 0; 1105 ite_lf (ip); 1106 } 1107 1108 inline static void 1109 ite_cr(struct ite_softc *ip) 1110 { 1111 if (ip->curx) { 1112 ip->curx = 0; 1113 } 1114 } 1115 1116 inline static void 1117 ite_rlf(struct ite_softc *ip) 1118 { 1119 ip->cury--; 1120 if ((ip->cury < 0) || (ip->cury == ip->top_margin - 1)) { 1121 ip->cury++; 1122 SUBR_SCROLL(ip, ip->top_margin, 0, 1, SCROLL_DOWN); 1123 ite_clrline(ip); 1124 } 1125 clr_attr(ip, ATTR_INV); 1126 } 1127 1128 inline static int 1129 atoi(const char *cp) 1130 { 1131 int n; 1132 1133 for (n = 0; *cp && *cp >= '0' && *cp <= '9'; cp++) 1134 n = n * 10 + *cp - '0'; 1135 return n; 1136 } 1137 1138 inline static int 1139 ite_argnum(struct ite_softc *ip) 1140 { 1141 char ch; 1142 int n; 1143 1144 /* convert argument string into number */ 1145 if (ip->ap == ip->argbuf) 1146 return 1; 1147 ch = *ip->ap; 1148 *ip->ap = 0; 1149 n = atoi(ip->argbuf); 1150 *ip->ap = ch; 1151 1152 return n; 1153 } 1154 1155 inline static int 1156 ite_zargnum(struct ite_softc *ip) 1157 { 1158 char ch; 1159 int n; 1160 1161 /* convert argument string into number */ 1162 if (ip->ap == ip->argbuf) 1163 return 0; 1164 ch = *ip->ap; 1165 *ip->ap = 0; /* terminate string */ 1166 n = atoi(ip->argbuf); 1167 *ip->ap = ch; 1168 1169 return n; /* don't "n ? n : 1" here, <CSI>0m != <CSI>1m ! */ 1170 } 1171 1172 void 1173 ite_putstr(const u_char *s, int len, dev_t dev) 1174 { 1175 struct ite_softc *ip; 1176 int i; 1177 1178 ip = getitesp(dev); 1179 1180 /* XXX avoid problems */ 1181 if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) 1182 return; 1183 1184 SUBR_CURSOR(ip, START_CURSOROPT); 1185 for (i = 0; i < len; i++) 1186 if (s[i]) 1187 iteputchar(s[i], ip); 1188 SUBR_CURSOR(ip, END_CURSOROPT); 1189 } 1190 1191 void 1192 iteputchar(int c, struct ite_softc *ip) 1193 { 1194 int n, x, y; 1195 char *cp; 1196 1197 if (c >= 0x20 && ip->escape) { 1198 switch (ip->escape) { 1199 1200 case ESC: 1201 switch (c) { 1202 /* first 7bit equivalents for the 8bit control characters */ 1203 1204 case 'D': 1205 c = IND; 1206 ip->escape = 0; 1207 break; /* and fall into the next switch below (same for all `break') */ 1208 1209 case 'E': 1210 /* next line */ 1211 c = NEL; 1212 ip->escape = 0; 1213 break; 1214 1215 case 'H': 1216 /* set TAB at current col */ 1217 c = HTS; 1218 ip->escape = 0; 1219 break; 1220 1221 case 'M': 1222 /* reverse index */ 1223 c = RI; 1224 ip->escape = 0; 1225 break; 1226 1227 case 'N': 1228 /* single shift G2 */ 1229 c = SS2; 1230 ip->escape = 0; 1231 break; 1232 1233 case 'O': 1234 /* single shift G3 */ 1235 c = SS3; 1236 ip->escape = 0; 1237 break; 1238 1239 case 'P': 1240 /* DCS detected */ 1241 c = DCS; 1242 ip->escape = 0; 1243 break; 1244 1245 case '[': 1246 c = CSI; 1247 ip->escape = 0; 1248 break; 1249 1250 case '\\': 1251 /* String Terminator */ 1252 c = ST; 1253 ip->escape = 0; 1254 break; 1255 1256 case ']': 1257 c = OSC; 1258 ip->escape = 0; 1259 break; 1260 1261 case '^': 1262 c = PM; 1263 ip->escape = 0; 1264 break; 1265 1266 case '_': 1267 c = APC; 1268 ip->escape = 0; 1269 break; 1270 1271 1272 /* introduces 7/8bit control */ 1273 case ' ': 1274 /* can be followed by either F or G */ 1275 ip->escape = ' '; 1276 break; 1277 1278 1279 /* a lot of character set selections, not yet used... 1280 94-character sets: */ 1281 case '(': /* G0 */ 1282 case ')': /* G1 */ 1283 ip->escape = c; 1284 return; 1285 1286 case '*': /* G2 */ 1287 case '+': /* G3 */ 1288 case 'B': /* ASCII */ 1289 case 'A': /* ISO latin 1 */ 1290 case '<': /* user preferred suplemental */ 1291 case '0': /* dec special graphics */ 1292 1293 /* 96-character sets: */ 1294 case '-': /* G1 */ 1295 case '.': /* G2 */ 1296 case '/': /* G3 */ 1297 1298 /* national character sets: */ 1299 case '4': /* dutch */ 1300 case '5': 1301 case 'C': /* finnish */ 1302 case 'R': /* french */ 1303 case 'Q': /* french canadian */ 1304 case 'K': /* german */ 1305 case 'Y': /* italian */ 1306 case '6': /* norwegian/danish */ 1307 /* note: %5 and %6 are not supported (two chars..) */ 1308 1309 ip->escape = 0; 1310 /* just ignore for now */ 1311 return; 1312 1313 /* 94-multibyte character sets designate */ 1314 case '$': 1315 ip->escape = '$'; 1316 return; 1317 1318 /* locking shift modes */ 1319 case '`': 1320 ip->GR = &ip->G1; 1321 ip->escape = 0; 1322 return; 1323 1324 case 'n': 1325 ip->GL = &ip->G2; 1326 ip->escape = 0; 1327 return; 1328 1329 case '}': 1330 ip->GR = &ip->G2; 1331 ip->escape = 0; 1332 return; 1333 1334 case 'o': 1335 ip->GL = &ip->G3; 1336 ip->escape = 0; 1337 return; 1338 1339 case '|': 1340 ip->GR = &ip->G3; 1341 ip->escape = 0; 1342 return; 1343 1344 case '~': 1345 ip->GR = &ip->G1; 1346 ip->escape = 0; 1347 return; 1348 1349 /* font width/height control */ 1350 case '#': 1351 ip->escape = '#'; 1352 return; 1353 1354 case 'c': 1355 /* hard terminal reset .. */ 1356 ite_reset(ip); 1357 SUBR_CURSOR(ip, MOVE_CURSOR); 1358 ip->escape = 0; 1359 return; 1360 1361 1362 case '7': 1363 /* save cursor */ 1364 ip->save_curx = ip->curx; 1365 ip->save_cury = ip->cury; 1366 ip->save_attribute = ip->attribute; 1367 ip->sc_om = ip->inside_margins; 1368 ip->sc_G0 = ip->G0; 1369 ip->sc_G1 = ip->G1; 1370 ip->sc_G2 = ip->G2; 1371 ip->sc_G3 = ip->G3; 1372 ip->sc_GL = ip->GL; 1373 ip->sc_GR = ip->GR; 1374 ip->escape = 0; 1375 return; 1376 1377 case '8': 1378 /* restore cursor */ 1379 ip->curx = ip->save_curx; 1380 ip->cury = ip->save_cury; 1381 ip->attribute = ip->save_attribute; 1382 ip->inside_margins = ip->sc_om; 1383 ip->G0 = ip->sc_G0; 1384 ip->G1 = ip->sc_G1; 1385 ip->G2 = ip->sc_G2; 1386 ip->G3 = ip->sc_G3; 1387 ip->GL = ip->sc_GL; 1388 ip->GR = ip->sc_GR; 1389 SUBR_CURSOR(ip, MOVE_CURSOR); 1390 ip->escape = 0; 1391 return; 1392 1393 case '=': 1394 /* keypad application mode */ 1395 ip->keypad_appmode = 1; 1396 ip->escape = 0; 1397 return; 1398 1399 case '>': 1400 /* keypad numeric mode */ 1401 ip->keypad_appmode = 0; 1402 ip->escape = 0; 1403 return; 1404 1405 case 'Z': /* request ID */ 1406 if (ip->emul_level == EMUL_VT100) 1407 ite_sendstr(ip, "\033[61;0c"); /* XXX not clean */ 1408 else 1409 ite_sendstr(ip, "\033[63;0c"); /* XXX not clean */ 1410 ip->escape = 0; 1411 return; 1412 1413 /* default catch all for not recognized ESC sequences */ 1414 default: 1415 ip->escape = 0; 1416 return; 1417 } 1418 break; 1419 1420 1421 case '(': /* designate G0 */ 1422 switch (c) { 1423 case 'B': /* USASCII */ 1424 ip->G0 = CSET_ASCII; 1425 ip->escape = 0; 1426 return; 1427 case 'I': 1428 ip->G0 = CSET_JISKANA; 1429 ip->escape = 0; 1430 return; 1431 case 'J': 1432 ip->G0 = CSET_JISROMA; 1433 ip->escape = 0; 1434 return; 1435 case 'A': /* British or ISO-Latin-1 */ 1436 case 'H': /* Swedish */ 1437 case 'K': /* German */ 1438 case 'R': /* French */ 1439 case 'Y': /* Italian */ 1440 case 'Z': /* Spanish */ 1441 default: 1442 /* not supported */ 1443 ip->escape = 0; 1444 return; 1445 } 1446 1447 case ')': /* designate G1 */ 1448 ip->escape = 0; 1449 return; 1450 1451 case '$': /* 94-multibyte character set */ 1452 switch (c) { 1453 case '@': 1454 ip->G0 = CSET_JIS1978; 1455 ip->escape = 0; 1456 return; 1457 case 'B': 1458 ip->G0 = CSET_JIS1983; 1459 ip->escape = 0; 1460 return; 1461 case 'D': 1462 ip->G0 = CSET_JIS1990; 1463 ip->escape = 0; 1464 return; 1465 default: 1466 /* not supported */ 1467 ip->escape = 0; 1468 return; 1469 } 1470 1471 case ' ': 1472 switch (c) { 1473 case 'F': 1474 ip->eightbit_C1 = 0; 1475 ip->escape = 0; 1476 return; 1477 1478 case 'G': 1479 ip->eightbit_C1 = 1; 1480 ip->escape = 0; 1481 return; 1482 1483 default: 1484 /* not supported */ 1485 ip->escape = 0; 1486 return; 1487 } 1488 break; 1489 1490 case '#': 1491 switch (c) { 1492 case '5': 1493 /* single height, single width */ 1494 ip->escape = 0; 1495 return; 1496 1497 case '6': 1498 /* double width, single height */ 1499 ip->escape = 0; 1500 return; 1501 1502 case '3': 1503 /* top half */ 1504 ip->escape = 0; 1505 return; 1506 1507 case '4': 1508 /* bottom half */ 1509 ip->escape = 0; 1510 return; 1511 1512 case '8': 1513 /* screen alignment pattern... */ 1514 alignment_display(ip); 1515 ip->escape = 0; 1516 return; 1517 1518 default: 1519 ip->escape = 0; 1520 return; 1521 } 1522 break; 1523 1524 1525 1526 case CSI: 1527 /* the biggie... */ 1528 switch (c) { 1529 case '0': case '1': case '2': case '3': case '4': 1530 case '5': case '6': case '7': case '8': case '9': 1531 case ';': case '\"': case '$': case '>': 1532 if (ip->ap < ip->argbuf + MAX_ARGSIZE) 1533 *ip->ap++ = c; 1534 return; 1535 1536 case 'p': 1537 *ip->ap = 0; 1538 if (!strncmp(ip->argbuf, "61\"", 3)) 1539 ip->emul_level = EMUL_VT100; 1540 else if (!strncmp(ip->argbuf, "63;1\"", 5) 1541 || !strncmp(ip->argbuf, "62;1\"", 5)) 1542 ip->emul_level = EMUL_VT300_7; 1543 else 1544 ip->emul_level = EMUL_VT300_8; 1545 ip->escape = 0; 1546 return; 1547 1548 1549 case '?': 1550 *ip->ap = 0; 1551 ip->escape = '?'; 1552 ip->ap = ip->argbuf; 1553 return; 1554 1555 1556 case 'c': 1557 /* device attributes */ 1558 *ip->ap = 0; 1559 if (ip->argbuf[0] == '>') { 1560 ite_sendstr(ip, "\033[>24;0;0;0c"); 1561 } else 1562 switch (ite_zargnum(ip)) { 1563 case 0: 1564 /* primary DA request, send primary DA response */ 1565 if (ip->emul_level == EMUL_VT100) 1566 ite_sendstr(ip, "\033[?1;1c"); 1567 else 1568 ite_sendstr(ip, "\033[63;0c"); 1569 break; 1570 } 1571 ip->escape = 0; 1572 return; 1573 1574 case 'n': 1575 switch (ite_zargnum(ip)) { 1576 case 5: 1577 ite_sendstr(ip, "\033[0n"); /* no malfunction */ 1578 break; 1579 case 6: 1580 /* cursor position report */ 1581 snprintf(ip->argbuf, sizeof(ip->argbuf), 1582 "\033[%d;%dR", 1583 ip->cury + 1, ip->curx + 1); 1584 ite_sendstr(ip, ip->argbuf); 1585 break; 1586 } 1587 ip->escape = 0; 1588 return; 1589 1590 1591 case 'x': 1592 switch (ite_zargnum(ip)) { 1593 case 0: 1594 /* Fake some terminal parameters. */ 1595 ite_sendstr(ip, "\033[2;1;1;112;112;1;0x"); 1596 break; 1597 case 1: 1598 ite_sendstr(ip, "\033[3;1;1;112;112;1;0x"); 1599 break; 1600 } 1601 ip->escape = 0; 1602 return; 1603 1604 1605 case 'g': 1606 /* clear tabs */ 1607 switch (ite_zargnum(ip)) { 1608 case 0: 1609 if (ip->curx < ip->cols) 1610 ip->tabs[ip->curx] = 0; 1611 break; 1612 case 3: 1613 for (n = 0; n < ip->cols; n++) 1614 ip->tabs[n] = 0; 1615 break; 1616 1617 default: 1618 /* ignore */ 1619 break; 1620 } 1621 ip->escape = 0; 1622 return; 1623 1624 1625 case 'h': /* set mode */ 1626 case 'l': /* reset mode */ 1627 n = ite_zargnum(ip); 1628 switch (n) { 1629 case 4: 1630 ip->imode = (c == 'h'); /* insert/replace mode */ 1631 break; 1632 case 20: 1633 ip->linefeed_newline = (c == 'h'); 1634 break; 1635 } 1636 ip->escape = 0; 1637 return; 1638 1639 1640 case 'M': 1641 /* delete line */ 1642 ite_dnline(ip, ite_argnum(ip)); 1643 ip->escape = 0; 1644 return; 1645 1646 1647 case 'L': 1648 /* insert line */ 1649 ite_inline(ip, ite_argnum(ip)); 1650 ip->escape = 0; 1651 return; 1652 1653 1654 case 'P': 1655 /* delete char */ 1656 ite_dnchar(ip, ite_argnum(ip)); 1657 ip->escape = 0; 1658 return; 1659 1660 1661 case '@': 1662 /* insert char(s) */ 1663 ite_inchar(ip, ite_argnum(ip)); 1664 ip->escape = 0; 1665 return; 1666 1667 case '!': 1668 /* soft terminal reset */ 1669 ip->escape = 0; /* XXX */ 1670 return; 1671 1672 case 'G': 1673 /* this one was *not* in my vt320 manual but in 1674 a vt320 termcap entry.. who is right? 1675 It's supposed to set the horizontal cursor position. */ 1676 *ip->ap = 0; 1677 x = atoi(ip->argbuf); 1678 if (x) 1679 x--; 1680 ip->curx = uimin(x, ip->cols - 1); 1681 ip->escape = 0; 1682 SUBR_CURSOR(ip, MOVE_CURSOR); 1683 clr_attr(ip, ATTR_INV); 1684 return; 1685 1686 1687 case 'd': 1688 /* same thing here, this one's for setting the absolute 1689 vertical cursor position. Not documented... */ 1690 *ip->ap = 0; 1691 y = atoi(ip->argbuf); 1692 if (y) 1693 y--; 1694 if (ip->inside_margins) 1695 y += ip->top_margin; 1696 ip->cury = uimin(y, ip->rows - 1); 1697 ip->escape = 0; 1698 snap_cury(ip); 1699 SUBR_CURSOR(ip, MOVE_CURSOR); 1700 clr_attr(ip, ATTR_INV); 1701 return; 1702 1703 1704 case 'H': 1705 case 'f': 1706 *ip->ap = 0; 1707 y = atoi(ip->argbuf); 1708 x = 0; 1709 cp = strchr(ip->argbuf, ';'); 1710 if (cp) 1711 x = atoi(cp + 1); 1712 if (x) 1713 x--; 1714 if (y) 1715 y--; 1716 if (ip->inside_margins) 1717 y += ip->top_margin; 1718 ip->cury = uimin(y, ip->rows - 1); 1719 ip->curx = uimin(x, ip->cols - 1); 1720 ip->escape = 0; 1721 snap_cury(ip); 1722 SUBR_CURSOR(ip, MOVE_CURSOR); 1723 /*clr_attr(ip, ATTR_INV);*/ 1724 return; 1725 1726 case 'A': 1727 /* cursor up */ 1728 n = ite_argnum(ip); 1729 n = ip->cury - (n ? n : 1); 1730 if (n < 0) 1731 n = 0; 1732 if (ip->inside_margins) 1733 n = uimax(ip->top_margin, n); 1734 else if (n == ip->top_margin - 1) 1735 /* allow scrolling outside region, but don't scroll out 1736 of active region without explicit CUP */ 1737 n = ip->top_margin; 1738 ip->cury = n; 1739 ip->escape = 0; 1740 SUBR_CURSOR(ip, MOVE_CURSOR); 1741 clr_attr(ip, ATTR_INV); 1742 return; 1743 1744 case 'B': 1745 /* cursor down */ 1746 n = ite_argnum(ip); 1747 n = ip->cury + (n ? n : 1); 1748 n = uimin(ip->rows - 1, n); 1749 #if 0 1750 if (ip->inside_margins) 1751 #endif 1752 n = uimin(ip->bottom_margin, n); 1753 #if 0 1754 else if (n == ip->bottom_margin + 1) 1755 /* allow scrolling outside region, but don't scroll out 1756 of active region without explicit CUP */ 1757 n = ip->bottom_margin; 1758 #endif 1759 ip->cury = n; 1760 ip->escape = 0; 1761 SUBR_CURSOR(ip, MOVE_CURSOR); 1762 clr_attr(ip, ATTR_INV); 1763 return; 1764 1765 case 'C': 1766 /* cursor forward */ 1767 n = ite_argnum(ip); 1768 n = n ? n : 1; 1769 ip->curx = uimin(ip->curx + n, ip->cols - 1); 1770 ip->escape = 0; 1771 SUBR_CURSOR(ip, MOVE_CURSOR); 1772 clr_attr(ip, ATTR_INV); 1773 return; 1774 1775 case 'D': 1776 /* cursor backward */ 1777 n = ite_argnum(ip); 1778 n = n ? n : 1; 1779 n = ip->curx - n; 1780 ip->curx = n >= 0 ? n : 0; 1781 ip->escape = 0; 1782 SUBR_CURSOR(ip, MOVE_CURSOR); 1783 clr_attr(ip, ATTR_INV); 1784 return; 1785 1786 1787 case 'J': 1788 /* erase screen */ 1789 *ip->ap = 0; 1790 n = ite_zargnum(ip); 1791 if (n == 0) 1792 ite_clrtoeos(ip); 1793 else if (n == 1) 1794 ite_clrtobos(ip); 1795 else if (n == 2) 1796 ite_clrscreen(ip); 1797 ip->escape = 0; 1798 return; 1799 1800 1801 case 'K': 1802 /* erase line */ 1803 n = ite_zargnum(ip); 1804 if (n == 0) 1805 ite_clrtoeol(ip); 1806 else if (n == 1) 1807 ite_clrtobol(ip); 1808 else if (n == 2) 1809 ite_clrline(ip); 1810 ip->escape = 0; 1811 return; 1812 1813 case 'S': 1814 /* scroll up */ 1815 n = ite_zargnum(ip); 1816 if (n <= 0) 1817 n = 1; 1818 else if (n > ip->rows-1) 1819 n = ip->rows-1; 1820 SUBR_SCROLL(ip, ip->rows-1, 0, n, SCROLL_UP); 1821 ip->escape = 0; 1822 return; 1823 1824 case 'T': 1825 /* scroll down */ 1826 n = ite_zargnum(ip); 1827 if (n <= 0) 1828 n = 1; 1829 else if (n > ip->rows-1) 1830 n = ip->rows-1; 1831 SUBR_SCROLL(ip, 0, 0, n, SCROLL_DOWN); 1832 ip->escape = 0; 1833 return; 1834 1835 case 'X': 1836 /* erase character */ 1837 n = ite_argnum(ip) - 1; 1838 n = uimin(n, ip->cols - 1 - ip->curx); 1839 for (; n >= 0; n--) { 1840 attrclr(ip, ip->cury, ip->curx + n, 1, 1); 1841 SUBR_PUTC(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR); 1842 } 1843 ip->escape = 0; 1844 return; 1845 1846 1847 case '}': case '`': 1848 /* status line control */ 1849 ip->escape = 0; 1850 return; 1851 1852 case 'r': 1853 /* set scrolling region */ 1854 ip->escape = 0; 1855 *ip->ap = 0; 1856 x = atoi(ip->argbuf); 1857 x = x ? x : 1; 1858 y = ip->rows; 1859 cp = strchr(ip->argbuf, ';'); 1860 if (cp) { 1861 y = atoi(cp + 1); 1862 y = y ? y : ip->rows; 1863 } 1864 if (y <= x) 1865 return; 1866 x--; 1867 y--; 1868 ip->top_margin = uimin(x, ip->rows - 2); 1869 ip->bottom_margin = uimin(y, ip->rows - 1); 1870 if (ip->inside_margins) { 1871 ip->cury = ip->top_margin; 1872 } else 1873 ip->cury = 0; 1874 ip->curx = 0; 1875 return; 1876 1877 1878 case 'm': 1879 /* big attribute setter/resetter */ 1880 { 1881 char *c_p; 1882 *ip->ap = 0; 1883 /* kludge to make CSIm work (== CSI0m) */ 1884 if (ip->ap == ip->argbuf) 1885 ip->ap++; 1886 for (c_p = ip->argbuf; c_p < ip->ap; ) { 1887 switch (*c_p) { 1888 case 0: 1889 case '0': 1890 clr_attr(ip, ATTR_ALL); 1891 ip->fgcolor = 7; 1892 ip->bgcolor = 0; 1893 c_p++; 1894 break; 1895 1896 case '1': 1897 set_attr(ip, ATTR_BOLD); 1898 c_p++; 1899 break; 1900 1901 case '2': 1902 switch (c_p[1]) { 1903 case '2': 1904 clr_attr(ip, ATTR_BOLD); 1905 c_p += 2; 1906 break; 1907 1908 case '4': 1909 clr_attr(ip, ATTR_UL); 1910 c_p += 2; 1911 break; 1912 1913 case '5': 1914 clr_attr(ip, ATTR_BLINK); 1915 c_p += 2; 1916 break; 1917 1918 case '7': 1919 clr_attr(ip, ATTR_INV); 1920 c_p += 2; 1921 break; 1922 1923 default: 1924 c_p++; 1925 break; 1926 } 1927 break; 1928 1929 case '3': 1930 switch (c_p[1]) { 1931 case '0': case '1': case '2': case '3': 1932 case '4': case '5': case '6': case '7': 1933 /* foreground colors */ 1934 ip->fgcolor = c_p[1] - '0'; 1935 c_p += 2; 1936 break; 1937 default: 1938 c_p++; 1939 break; 1940 } 1941 break; 1942 1943 case '4': 1944 switch (c_p[1]) { 1945 case '0': case '1': case '2': case '3': 1946 case '4': case '5': case '6': case '7': 1947 /* background colors */ 1948 ip->bgcolor = c_p[1] - '0'; 1949 c_p += 2; 1950 break; 1951 default: 1952 set_attr(ip, ATTR_UL); 1953 c_p++; 1954 break; 1955 } 1956 break; 1957 1958 case '5': 1959 set_attr(ip, ATTR_BLINK); 1960 c_p++; 1961 break; 1962 1963 case '7': 1964 set_attr(ip, ATTR_INV); 1965 c_p++; 1966 break; 1967 1968 default: 1969 c_p++; 1970 break; 1971 } 1972 } 1973 1974 } 1975 ip->escape = 0; 1976 return; 1977 1978 1979 case 'u': 1980 /* DECRQTSR */ 1981 ite_sendstr(ip, "\033P\033\\"); 1982 ip->escape = 0; 1983 return; 1984 1985 default: 1986 ip->escape = 0; 1987 return; 1988 } 1989 break; 1990 1991 1992 1993 case '?': /* CSI ? */ 1994 switch (c) { 1995 case '0': case '1': case '2': case '3': case '4': 1996 case '5': case '6': case '7': case '8': case '9': 1997 case ';': case '\"': case '$': 1998 /* Don't fill the last character; it's needed. */ 1999 /* XXX yeah, where ?? */ 2000 if (ip->ap < ip->argbuf + MAX_ARGSIZE - 1) 2001 *ip->ap++ = c; 2002 return; 2003 2004 2005 case 'n': 2006 /* Terminal Reports */ 2007 *ip->ap = 0; 2008 if (ip->ap == &ip->argbuf[2]) { 2009 if (!strncmp(ip->argbuf, "15", 2)) 2010 /* printer status: no printer */ 2011 ite_sendstr(ip, "\033[13n"); 2012 2013 else if (!strncmp(ip->argbuf, "25", 2)) 2014 /* udk status */ 2015 ite_sendstr(ip, "\033[20n"); 2016 2017 else if (!strncmp(ip->argbuf, "26", 2)) 2018 /* keyboard dialect: US */ 2019 ite_sendstr(ip, "\033[27;1n"); 2020 } 2021 ip->escape = 0; 2022 return; 2023 2024 2025 case 'h': /* set dec private modes */ 2026 case 'l': /* reset dec private modes */ 2027 n = ite_zargnum(ip); 2028 switch (n) { 2029 case 1: 2030 /* CKM - cursor key mode */ 2031 ip->cursor_appmode = (c == 'h'); 2032 break; 2033 2034 case 3: 2035 /* 132/80 columns (132 == 'h') */ 2036 break; 2037 2038 case 4: /* smooth scroll */ 2039 break; 2040 2041 case 5: 2042 /* light background (=='h') /dark background(=='l') */ 2043 break; 2044 2045 case 6: /* origin mode */ 2046 ip->inside_margins = (c == 'h'); 2047 #if 0 2048 ip->curx = 0; 2049 ip->cury = ip->inside_margins ? ip->top_margin : 0; 2050 SUBR_CURSOR(ip, MOVE_CURSOR); 2051 #endif 2052 break; 2053 2054 case 7: /* auto wraparound */ 2055 ip->auto_wrap = (c == 'h'); 2056 break; 2057 2058 case 8: /* keyboard repeat */ 2059 ip->key_repeat = (c == 'h'); 2060 break; 2061 2062 case 20: /* newline mode */ 2063 ip->linefeed_newline = (c == 'h'); 2064 break; 2065 2066 case 25: /* cursor on/off */ 2067 SUBR_CURSOR(ip, (c == 'h') ? DRAW_CURSOR : ERASE_CURSOR); 2068 break; 2069 } 2070 ip->escape = 0; 2071 return; 2072 2073 case 'K': 2074 /* selective erase in line */ 2075 case 'J': 2076 /* selective erase in display */ 2077 2078 default: 2079 ip->escape = 0; 2080 return; 2081 } 2082 break; 2083 2084 2085 default: 2086 ip->escape = 0; 2087 return; 2088 } 2089 } 2090 2091 switch (c) { 2092 case 0x00: /* NUL */ 2093 case 0x01: /* SOH */ 2094 case 0x02: /* STX */ 2095 case 0x03: /* ETX */ 2096 case 0x04: /* EOT */ 2097 case 0x05: /* ENQ */ 2098 case 0x06: /* ACK */ 2099 break; 2100 2101 case BEL: 2102 #if NBELL > 0 2103 if (kbd_ite && ite_tty[device_unit(kbd_ite->device)]) 2104 opm_bell(); 2105 #endif 2106 break; 2107 2108 case BS: 2109 if (--ip->curx < 0) 2110 ip->curx = 0; 2111 else 2112 SUBR_CURSOR(ip, MOVE_CURSOR); 2113 break; 2114 2115 case HT: 2116 for (n = ip->curx + 1; n < ip->cols; n++) { 2117 if (ip->tabs[n]) { 2118 ip->curx = n; 2119 SUBR_CURSOR(ip, MOVE_CURSOR); 2120 break; 2121 } 2122 } 2123 break; 2124 2125 case VT: /* VT is treated like LF */ 2126 case FF: /* so is FF */ 2127 case LF: 2128 /* cr->crlf distinction is done here, on output, 2129 not on input! */ 2130 if (ip->linefeed_newline) 2131 ite_crlf(ip); 2132 else 2133 ite_lf(ip); 2134 break; 2135 2136 case CR: 2137 ite_cr(ip); 2138 break; 2139 2140 2141 case SO: 2142 ip->GL = &ip->G1; 2143 break; 2144 2145 case SI: 2146 ip->GL = &ip->G0; 2147 break; 2148 2149 case 0x10: /* DLE */ 2150 case 0x11: /* DC1/XON */ 2151 case 0x12: /* DC2 */ 2152 case 0x13: /* DC3/XOFF */ 2153 case 0x14: /* DC4 */ 2154 case 0x15: /* NAK */ 2155 case 0x16: /* SYN */ 2156 case 0x17: /* ETB */ 2157 break; 2158 2159 case CAN: 2160 ip->escape = 0; /* cancel any escape sequence in progress */ 2161 break; 2162 2163 case 0x19: /* EM */ 2164 break; 2165 2166 case SUB: 2167 ip->escape = 0; /* dito, but see below */ 2168 /* should also display a reverse question mark!! */ 2169 break; 2170 2171 case ESC: 2172 ip->escape = ESC; 2173 break; 2174 2175 case 0x1c: /* FS */ 2176 case 0x1d: /* GS */ 2177 case 0x1e: /* RS */ 2178 case 0x1f: /* US */ 2179 break; 2180 2181 /* now it gets weird.. 8bit control sequences.. */ 2182 case IND: /* index: move cursor down, scroll */ 2183 ite_index(ip); 2184 break; 2185 2186 case NEL: /* next line. next line, first pos. */ 2187 ite_crlf(ip); 2188 break; 2189 2190 case HTS: /* set horizontal tab */ 2191 if (ip->curx < ip->cols) 2192 ip->tabs[ip->curx] = 1; 2193 break; 2194 2195 case RI: /* reverse index */ 2196 ite_rlf(ip); 2197 break; 2198 2199 case SS2: /* go into G2 for one character */ 2200 ip->save_GL = ip->GR; /* GL XXX EUC */ 2201 ip->GR = &ip->G2; /* GL XXX */ 2202 break; 2203 2204 case SS3: /* go into G3 for one character */ 2205 ip->save_GL = ip->GR; /* GL XXX EUC */ 2206 ip->GR = &ip->G3; /* GL XXX */ 2207 break; 2208 2209 case DCS: /* device control string introducer */ 2210 ip->escape = DCS; 2211 ip->ap = ip->argbuf; 2212 break; 2213 2214 case CSI: /* control sequence introducer */ 2215 ip->escape = CSI; 2216 ip->ap = ip->argbuf; 2217 break; 2218 2219 case ST: /* string terminator */ 2220 /* ignore, if not used as terminator */ 2221 break; 2222 2223 case OSC: /* introduces OS command. Ignore everything upto ST */ 2224 ip->escape = OSC; 2225 break; 2226 2227 case PM: /* privacy message, ignore everything upto ST */ 2228 ip->escape = PM; 2229 break; 2230 2231 case APC: /* application program command, ignore everything upto ST */ 2232 ip->escape = APC; 2233 break; 2234 2235 case DEL: 2236 break; 2237 2238 default: 2239 if (!ip->save_char && (*((c & 0x80) ? ip->GR : ip->GL) & CSET_MULTI)) { 2240 ip->save_char = c; 2241 break; 2242 } 2243 if (ip->imode) 2244 ite_inchar(ip, ip->save_char ? 2 : 1); 2245 iteprecheckwrap(ip); 2246 #ifdef DO_WEIRD_ATTRIBUTES 2247 if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) { 2248 attrset(ip, ATTR_INV); 2249 SUBR_PUTC(ip, c, ip->cury, ip->curx, ATTR_INV); 2250 } 2251 else 2252 SUBR_PUTC(ip, c, ip->cury, ip->curx, ATTR_NOR); 2253 #else 2254 SUBR_PUTC(ip, c, ip->cury, ip->curx, ip->attribute); 2255 #endif 2256 /* SUBR_CURSOR(ip, DRAW_CURSOR);*/ 2257 itecheckwrap(ip); 2258 if (ip->save_char) { 2259 itecheckwrap(ip); 2260 ip->save_char = 0; 2261 } 2262 if (ip->save_GL) { 2263 /* 2264 * reset single shift 2265 */ 2266 ip->GR = ip->save_GL; 2267 ip->save_GL = 0; 2268 } 2269 break; 2270 } 2271 } 2272 2273 static void 2274 iteprecheckwrap(struct ite_softc *ip) 2275 { 2276 if (ip->auto_wrap && ip->curx + (ip->save_char ? 1 : 0) == ip->cols) { 2277 ip->curx = 0; 2278 clr_attr(ip, ATTR_INV); 2279 if (++ip->cury >= ip->bottom_margin + 1) { 2280 ip->cury = ip->bottom_margin; 2281 /*SUBR_CURSOR(ip, MOVE_CURSOR);*/ 2282 SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP); 2283 ite_clrtoeol(ip); 2284 } /*else 2285 SUBR_CURSOR(ip, MOVE_CURSOR);*/ 2286 } 2287 } 2288 2289 static void 2290 itecheckwrap(struct ite_softc *ip) 2291 { 2292 #if 0 2293 if (++ip->curx == ip->cols) { 2294 if (ip->auto_wrap) { 2295 ip->curx = 0; 2296 clr_attr(ip, ATTR_INV); 2297 if (++ip->cury >= ip->bottom_margin + 1) { 2298 ip->cury = ip->bottom_margin; 2299 SUBR_CURSOR(ip, MOVE_CURSOR); 2300 SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP); 2301 ite_clrtoeol(ip); 2302 return; 2303 } 2304 } else 2305 /* stay there if no autowrap.. */ 2306 ip->curx--; 2307 } 2308 #else 2309 if (ip->curx < ip->cols) { 2310 ip->curx++; 2311 /*SUBR_CURSOR(ip, MOVE_CURSOR);*/ 2312 } 2313 #endif 2314 } 2315 2316 #endif 2317 2318 #if NITE > 0 && NKBD > 0 2319 2320 /* 2321 * Console functions 2322 */ 2323 #include <dev/cons.h> 2324 extern void kbdenable(int); 2325 extern int kbdcngetc(void); 2326 2327 /* 2328 * Return a priority in consdev->cn_pri field highest wins. This function 2329 * is called before any devices have been probed. 2330 */ 2331 void 2332 itecnprobe(struct consdev *cd) 2333 { 2334 int maj; 2335 2336 /* locate the major number */ 2337 maj = cdevsw_lookup_major(&ite_cdevsw); 2338 2339 /* 2340 * return priority of the best ite (already picked from attach) 2341 * or CN_DEAD. 2342 */ 2343 if (con_itesoftc.grf == NULL) 2344 cd->cn_pri = CN_DEAD; 2345 else { 2346 con_itesoftc.flags = (ITE_ALIVE|ITE_CONSOLE); 2347 /* 2348 * hardcode the minor number. 2349 * currently we support only one ITE, it is enough for now. 2350 */ 2351 con_itesoftc.isw = &itesw[0]; 2352 cd->cn_pri = CN_INTERNAL; 2353 cd->cn_dev = makedev(maj, 0); 2354 } 2355 2356 } 2357 2358 void 2359 itecninit(struct consdev *cd) 2360 { 2361 struct ite_softc *ip; 2362 2363 ip = getitesp(cd->cn_dev); 2364 iteinit(cd->cn_dev); /* init console unit */ 2365 ip->flags |= ITE_ACTIVE | ITE_ISCONS; 2366 kbdenable(0); 2367 mfp_send_usart(0x49); 2368 } 2369 2370 /* 2371 * itecnfinish() is called in ite_init() when the device is 2372 * being probed in the normal fasion, thus we can finish setting 2373 * up this ite now that the system is more functional. 2374 */ 2375 void 2376 itecnfinish(struct ite_softc *ip) 2377 { 2378 static int done; 2379 2380 if (done) 2381 return; 2382 done = 1; 2383 } 2384 2385 /*ARGSUSED*/ 2386 int 2387 itecngetc(dev_t dev) 2388 { 2389 int c; 2390 2391 do { 2392 c = kbdcngetc(); 2393 c = ite_cnfilter(c); 2394 } while (c == -1); 2395 return (c); 2396 } 2397 2398 void 2399 itecnputc(dev_t dev, int c) 2400 { 2401 static int paniced = 0; 2402 struct ite_softc *ip = getitesp(dev); 2403 char ch = c; 2404 #ifdef ITE_KERNEL_ATTR 2405 short save_attribute; 2406 #endif 2407 2408 if (panicstr && !paniced && 2409 (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) { 2410 (void) iteon(dev, 3); 2411 paniced = 1; 2412 } 2413 #ifdef ITE_KERNEL_ATTR 2414 save_attribute = ip->attribute; 2415 ip->attribute = ITE_KERNEL_ATTR; 2416 #endif 2417 ite_putstr(&ch, 1, dev); 2418 #ifdef ITE_KERNEL_ATTR 2419 ip->attribute = save_attribute; 2420 #endif 2421 } 2422 #endif 2423