1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * from: Utah Hdr: ite.c 1.1 90/07/09 39 * from: @(#)ite.c 7.6 (Berkeley) 5/16/91 40 <<<<<<< ite.c 41 * $Id: ite.c,v 1.3 1993/09/02 18:08:02 mw Exp $ 42 ||||||| 1.1.1.2 43 * $Id: ite.c,v 1.3 1993/09/02 18:08:02 mw Exp $ 44 ======= 45 * $Id: ite.c,v 1.3 1993/09/02 18:08:02 mw Exp $ 46 * 47 * Original author: unknown 48 * Amiga author:: Markus Wild 49 * Other contributors: Bryan Ford (improved vt100 compability) 50 >>>>>>> /tmp/T4009622 51 */ 52 53 /* 54 * Bit-mapped display terminal emulator machine independent code. 55 * This is a very rudimentary. Much more can be abstracted out of 56 * the hardware dependent routines. 57 */ 58 #include "ite.h" 59 #if NITE > 0 60 61 #include "grf.h" 62 63 #undef NITE 64 #define NITE NGRF 65 66 #include "param.h" 67 #include "conf.h" 68 #include "proc.h" 69 #include "ioctl.h" 70 #include "tty.h" 71 #include "systm.h" 72 #include "malloc.h" 73 74 #include "itevar.h" 75 #include "iteioctl.h" 76 #include "kbdmap.h" 77 78 #include "machine/cpu.h" 79 #include "../amiga/cons.h" 80 81 #ifdef __STDC__ 82 /* automatically generated, as you might guess:-) */ 83 84 struct consdev; 85 struct itesw; 86 87 extern int iteon (dev_t dev, int flag); 88 extern int iteinit (dev_t dev); 89 extern int iteoff (dev_t dev, int flag); 90 extern int iteopen (dev_t dev, int mode, int devtype, struct proc *p); 91 extern int iteclose (dev_t dev, int flag, int mode, struct proc *p); 92 extern int iteread (dev_t dev, struct uio *uio, int flag); 93 extern int itewrite (dev_t dev, struct uio *uio, int flag); 94 extern int iteioctl (dev_t dev, int cmd, caddr_t addr, int flag); 95 extern int itestart (register struct tty *tp); 96 extern int itefilter (register u_char c, enum caller caller); 97 extern void iteputchar (register int c, dev_t dev); 98 extern int iteprecheckwrap (register struct ite_softc *ip, register struct itesw *sp); 99 extern int itecheckwrap (register struct ite_softc *ip, register struct itesw *sp); 100 extern int itecnprobe (struct consdev *cp); 101 extern int itecninit (struct consdev *cp); 102 extern int itecngetc (dev_t dev); 103 extern int itecnputc (dev_t dev, int c); 104 static void repeat_handler (int a0, int a1); 105 static void inline ite_reset(struct ite_softc *ip); 106 static void ite_dnchar (struct ite_softc *ip, struct itesw *sp, int n); 107 static void ite_inchar (struct ite_softc *ip, struct itesw *sp, int n); 108 static void ite_clrtoeol (struct ite_softc *ip, struct itesw *sp); 109 static void ite_clrtobol (struct ite_softc *ip, struct itesw *sp); 110 static void ite_clrline (struct ite_softc *ip, struct itesw *sp); 111 static void ite_clrtoeos (struct ite_softc *ip, struct itesw *sp); 112 static void ite_clrtobos (struct ite_softc *ip, struct itesw *sp); 113 static void ite_clrscreen (struct ite_softc *ip, struct itesw *sp); 114 static void ite_dnline (struct ite_softc *ip, struct itesw *sp, int n); 115 static void ite_inline (struct ite_softc *ip, struct itesw *sp, int n); 116 static void ite_lf (struct ite_softc *ip, struct itesw *sp); 117 static void ite_crlf (struct ite_softc *ip, struct itesw *sp); 118 static void ite_cr (struct ite_softc *ip, struct itesw *sp); 119 static void ite_rlf (struct ite_softc *ip, struct itesw *sp); 120 static int atoi (const char *cp); 121 static char *index (const char *cp, char ch); 122 static int ite_argnum (struct ite_softc *ip); 123 static int ite_zargnum (struct ite_softc *ip); 124 static void ite_sendstr (struct ite_softc *ip, char *str); 125 static int strncmp (const char *a, const char *b, int l); 126 #endif 127 128 129 #define set_attr(ip, attr) ((ip)->attribute |= (attr)) 130 #define clr_attr(ip, attr) ((ip)->attribute &= ~(attr)) 131 132 extern int nodev(); 133 134 int customc_scroll(), customc_init(), customc_deinit(); 135 int customc_clear(), customc_putc(), customc_cursor(); 136 137 int tiga_scroll(), tiga_init(), tiga_deinit(); 138 int tiga_clear(), tiga_putc(), tiga_cursor(); 139 140 int retina_scroll(), retina_init(), retina_deinit(); 141 int retina_clear(), retina_putc(), retina_cursor(); 142 143 struct itesw itesw[] = 144 { 145 customc_init, customc_deinit, 0, 146 0, 0, 0, 147 148 tiga_init, tiga_deinit, tiga_clear, 149 tiga_putc, tiga_cursor, tiga_scroll, 150 151 retina_init, retina_deinit, retina_clear, 152 retina_putc, retina_cursor, retina_scroll, 153 }; 154 155 /* 156 * # of chars are output in a single itestart() call. 157 * If this is too big, user processes will be blocked out for 158 * long periods of time while we are emptying the queue in itestart(). 159 * If it is too small, console output will be very ragged. 160 */ 161 int iteburst = 64; 162 163 int nite = NITE; 164 165 struct tty *kbd_tty = NULL; 166 struct ite_softc *kbd_ip = NULL; 167 168 struct tty ite_cons1, ite_cons2; 169 #if 0 170 struct tty *ite_tty[NITE] = { &ite_cons1, &ite_cons2 }; 171 #else 172 struct tty *ite_tty[NITE]; 173 /* ugh.. */ 174 static int delayed_con_tty = -1; /* if >= 0 set cn_tp later to that tty.. */ 175 #endif 176 struct ite_softc ite_softc[NITE]; 177 178 int itestart(); 179 extern int ttrstrt(); 180 extern struct tty *constty; 181 182 /* These are (later..) settable via an ioctl */ 183 int start_repeat_timo = 20; /* /100: initial timeout till pressed key repeats */ 184 int next_repeat_timo = 3; /* /100: timeout when repeating for next char */ 185 186 #ifdef DO_WEIRD_ATTRIBUTES 187 /* 188 * Primary attribute buffer to be used by the first bitmapped console 189 * found. Secondary displays alloc the attribute buffer as needed. 190 * Size is based on a 68x128 display, which is currently our largest. 191 */ 192 u_char console_attributes[0x2200]; 193 #endif 194 u_char console_tabs[256 * NITE]; 195 196 /* 197 * Perform functions necessary to setup device as a terminal emulator. 198 */ 199 iteon(dev, flag) 200 dev_t dev; 201 { 202 int unit = UNIT(dev); 203 struct tty *tp = ite_tty[unit]; 204 struct ite_softc *ip = &ite_softc[unit]; 205 206 if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0) 207 return(ENXIO); 208 /* force ite active, overriding graphics mode */ 209 if (flag & 1) { 210 ip->flags |= ITE_ACTIVE; 211 ip->flags &= ~(ITE_INGRF|ITE_INITED); 212 } 213 /* leave graphics mode */ 214 if (flag & 2) { 215 ip->flags &= ~ITE_INGRF; 216 if ((ip->flags & ITE_ACTIVE) == 0) 217 return(0); 218 } 219 ip->flags |= ITE_ACTIVE; 220 if (ip->flags & ITE_INGRF) 221 return(0); 222 if (tp && (kbd_tty == NULL || kbd_tty == tp)) { 223 kbd_tty = tp; 224 kbd_ip = ip; 225 kbdenable(); 226 } 227 iteinit(dev); 228 return(0); 229 } 230 231 /* used by the grf layer to reinitialize ite after changing fb parameters */ 232 itereinit(dev) 233 dev_t dev; 234 { 235 int unit = UNIT(dev); 236 struct ite_softc *ip = &ite_softc[unit]; 237 238 ip->flags &= ~ITE_INITED; 239 iteinit (dev); 240 } 241 242 iteinit(dev) 243 dev_t dev; 244 { 245 int unit = UNIT(dev); 246 struct ite_softc *ip = &ite_softc[unit]; 247 248 if (ip->flags & ITE_INITED) 249 return; 250 251 bcopy (&ascii_kbdmap, &kbdmap, sizeof (struct kbdmap)); 252 253 ip->cursorx = 0; 254 ip->cursory = 0; 255 (*itesw[ip->type].ite_init)(ip); 256 <<<<<<< ite.c 257 (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR); 258 ||||||| 1.1.1.2 259 (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR); 260 261 /* ip->rows initialized by ite_init above */ 262 ip->top_margin = 0; ip->bottom_margin = ip->rows - 1; 263 ======= 264 >>>>>>> /tmp/T4009622 265 266 <<<<<<< ite.c 267 /* ip->rows initialized by ite_init above */ 268 ip->top_margin = 0; ip->bottom_margin = ip->rows - 1; 269 270 ip->attribute = 0; 271 ||||||| 1.1.1.2 272 ip->attribute = 0; 273 ======= 274 #ifdef DO_WEIRD_ATTRIBUTES 275 >>>>>>> /tmp/T4009622 276 if (ip->attrbuf == NULL) 277 ip->attrbuf = (u_char *) 278 malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK); 279 bzero(ip->attrbuf, (ip->rows * ip->cols)); 280 #endif 281 if (! ip->tabs) 282 { 283 /* can't use malloc, as this buffer might be used before 284 the allocators are initialized (console!) */ 285 ip->tabs = &console_tabs[unit * 256]; 286 } 287 288 ite_reset (ip); 289 290 (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR); 291 ip->flags |= ITE_INITED; 292 } 293 294 /* 295 * "Shut down" device as terminal emulator. 296 * Note that we do not deinit the console device unless forced. 297 * Deinit'ing the console every time leads to a very active 298 * screen when processing /etc/rc. 299 */ 300 iteoff(dev, flag) 301 dev_t dev; 302 { 303 register struct ite_softc *ip = &ite_softc[UNIT(dev)]; 304 305 if (flag & 2) 306 ip->flags |= ITE_INGRF; 307 if ((ip->flags & ITE_ACTIVE) == 0) 308 return; 309 if ((flag & 1) || 310 (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED) 311 (*itesw[ip->type].ite_deinit)(ip); 312 if ((flag & 2) == 0) 313 ip->flags &= ~ITE_ACTIVE; 314 } 315 316 /* ARGSUSED */ 317 #ifdef __STDC__ 318 iteopen(dev_t dev, int mode, int devtype, struct proc *p) 319 #else 320 iteopen(dev, mode, devtype, p) 321 dev_t dev; 322 int mode, devtype; 323 struct proc *p; 324 #endif 325 { 326 int unit = UNIT(dev); 327 register struct tty *tp; 328 register struct ite_softc *ip = &ite_softc[unit]; 329 register int error; 330 int first = 0; 331 332 if (unit >= NITE) 333 return ENXIO; 334 335 if(!ite_tty[unit]) { 336 #if 0 337 MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK); 338 bzero(tp, sizeof(struct tty)); 339 ite_tty[unit] = tp; 340 #else 341 tp = ite_tty[unit] = ttymalloc(); 342 /* HA! caught it finally... */ 343 if (unit == delayed_con_tty) 344 { 345 extern struct consdev *cn_tab; 346 extern struct tty *cn_tty; 347 348 kbd_tty = tp; 349 kbd_ip = ip; 350 kbdenable (); 351 cn_tty = cn_tab->cn_tp = tp; 352 delayed_con_tty = -1; 353 } 354 #endif 355 } else 356 tp = ite_tty[unit]; 357 358 if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE) 359 && p->p_ucred->cr_uid != 0) 360 return (EBUSY); 361 if ((ip->flags & ITE_ACTIVE) == 0) { 362 error = iteon(dev, 0); 363 if (error) 364 return (error); 365 first = 1; 366 } 367 tp->t_oproc = itestart; 368 tp->t_param = NULL; 369 tp->t_dev = dev; 370 if ((tp->t_state&TS_ISOPEN) == 0) { 371 ttychars(tp); 372 tp->t_iflag = TTYDEF_IFLAG; 373 tp->t_oflag = TTYDEF_OFLAG; 374 tp->t_cflag = CS8|CREAD; 375 tp->t_lflag = TTYDEF_LFLAG; 376 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 377 /* don't set TS_ISOPEN here, or the tty queues won't 378 be initialized in ttyopen()! */ 379 tp->t_state = TS_CARR_ON; 380 ttsetwater(tp); 381 } 382 error = (*linesw[tp->t_line].l_open)(dev, tp); 383 if (error == 0) { 384 tp->t_winsize.ws_row = ip->rows; 385 tp->t_winsize.ws_col = ip->cols; 386 ip->open_cnt++; 387 } else if (first) 388 iteoff(dev, 0); 389 return (error); 390 } 391 392 /*ARGSUSED*/ 393 iteclose(dev, flag, mode, p) 394 dev_t dev; 395 int flag, mode; 396 struct proc *p; 397 { 398 int unit = UNIT(dev); 399 register struct tty *tp = ite_tty[unit]; 400 register struct ite_softc *ip = &ite_softc[unit]; 401 402 #if 0 403 /* aliasing with /dev/console can lead to such weird problems... */ 404 if (ip->open_cnt-- > 0) 405 return 0; 406 #endif 407 408 if (tp) 409 { 410 (*linesw[tp->t_line].l_close)(tp, flag); 411 ttyclose(tp); 412 } 413 iteoff(dev, 0); 414 #if 0 415 if (tp != &ite_cons) 416 { 417 #if 0 418 FREE(tp, M_TTYS); 419 #else 420 ttyfree (tp); 421 #endif 422 ite_tty[UNIT(dev)] = (struct tty *)NULL; 423 } 424 #endif 425 return(0); 426 } 427 428 iteread(dev, uio, flag) 429 dev_t dev; 430 struct uio *uio; 431 { 432 register struct tty *tp = ite_tty[UNIT(dev)]; 433 int rc; 434 435 if (! tp) 436 return ENXIO; 437 438 rc = ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 439 return rc; 440 } 441 442 itewrite(dev, uio, flag) 443 dev_t dev; 444 struct uio *uio; 445 { 446 int unit = UNIT(dev); 447 register struct tty *tp = ite_tty[unit]; 448 449 if (! tp) 450 return ENXIO; 451 452 if ((ite_softc[unit].flags & ITE_ISCONS) && constty && 453 (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) 454 tp = constty; 455 return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 456 } 457 458 iteioctl(dev, cmd, addr, flag) 459 dev_t dev; 460 caddr_t addr; 461 { 462 register struct tty *tp = ite_tty[UNIT(dev)]; 463 int error; 464 465 if (! tp) 466 return ENXIO; 467 468 469 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag); 470 if (error >= 0) 471 return (error); 472 error = ttioctl(tp, cmd, addr, flag); 473 if (error >= 0) 474 return (error); 475 476 switch (cmd) 477 { 478 case ITELOADKMAP: 479 if (addr) 480 { 481 bcopy (addr, &kbdmap, sizeof (struct kbdmap)); 482 return 0; 483 } 484 else 485 return EFAULT; 486 487 case ITEGETKMAP: 488 if (addr) 489 { 490 bcopy (&kbdmap, addr, sizeof (struct kbdmap)); 491 return 0; 492 } 493 else 494 return EFAULT; 495 } 496 497 498 return (ENOTTY); 499 } 500 501 itestart(tp) 502 register struct tty *tp; 503 { 504 register int cc, s; 505 int unit = UNIT(tp->t_dev); 506 register struct ite_softc *ip = &ite_softc[unit]; 507 int hiwat = 0; 508 509 s = spltty(); 510 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { 511 splx(s); 512 return; 513 } 514 tp->t_state |= TS_BUSY; 515 cc = tp->t_outq.c_cc; 516 if (cc <= tp->t_lowat) { 517 if (tp->t_state & TS_ASLEEP) { 518 tp->t_state &= ~TS_ASLEEP; 519 wakeup((caddr_t) &tp->t_outq); 520 } 521 selwakeup(&tp->t_wsel); 522 } 523 /* 524 * Limit the amount of output we do in one burst 525 * to prevent hogging the CPU. 526 */ 527 if (cc > iteburst) { 528 hiwat++; 529 cc = iteburst; 530 } 531 (*itesw[ip->type].ite_cursor)(ip, START_CURSOROPT); 532 while (--cc >= 0) { 533 register int c; 534 535 c = getc(&tp->t_outq); 536 /* 537 * iteputchar() may take a long time and we don't want to 538 * block all interrupts for long periods of time. Since 539 * there is no need to stay at high priority while outputing 540 * the character (since we don't have to worry about 541 * interrupts), we don't. We just need to make sure that 542 * we don't reenter iteputchar, which is guarenteed by the 543 * earlier setting of TS_BUSY. 544 */ 545 splx(s); 546 iteputchar(c, tp->t_dev); 547 spltty(); 548 } 549 (*itesw[ip->type].ite_cursor)(ip, END_CURSOROPT); 550 if (hiwat) { 551 tp->t_state |= TS_TIMEOUT; 552 timeout((timeout_t) ttrstrt, (caddr_t) tp, 1); 553 } 554 tp->t_state &= ~TS_BUSY; 555 splx(s); 556 } 557 558 /* these are used to implement repeating keys.. */ 559 static u_char last_char = 0; 560 static u_char tout_pending = 0; 561 562 static void 563 repeat_handler (a0, a1) 564 int a0, a1; 565 { 566 tout_pending = 0; 567 /* leave it up to itefilter() to possibly install a new callout entry 568 to reinvoke repeat_handler() */ 569 if (last_char) 570 { 571 /* don't call itefilter directly, we're at spl6 here, and have 572 blocked out way too much stuff. Besides, the keyboard wouldn't 573 even have a chance to tell us about key-up events if we 574 did.. */ 575 add_sicallback (itefilter, last_char, ITEFILT_REPEATER); 576 577 /* itefilter (last_char, ITEFILT_REPEATER); */ 578 } 579 } 580 581 static void inline 582 itesendch (int ch) 583 { 584 (*linesw[kbd_tty->t_line].l_rint)(ch, kbd_tty); 585 } 586 587 588 int 589 itefilter(c, caller) 590 register u_char c; 591 enum caller caller; 592 { 593 static u_char mod = 0; 594 static u_char last_dead = 0; 595 register unsigned char code, *str; 596 u_char up, mask, i; 597 struct key key; 598 int s; 599 600 if (caller != ITEFILT_CONSOLE && kbd_tty == NULL) 601 return; 602 603 /* have to make sure we're at spltty in here */ 604 s = spltty (); 605 606 /* keyboard interrupts come at priority 2, while softint- 607 generated keyboard-repeat interrupts come at level 1. 608 So, to not allow a key-up event to get thru before 609 a repeat for the key-down, we remove any outstanding 610 callout requests.. */ 611 rem_sicallback (itefilter); 612 613 up = c & 0x80 ? 1 : 0; 614 c &= 0x7f; 615 code = 0; 616 617 mask = 0; 618 if (c >= KBD_LEFT_SHIFT) 619 { 620 switch (c) 621 { 622 case KBD_LEFT_SHIFT: 623 mask = KBD_MOD_LSHIFT; 624 break; 625 626 case KBD_RIGHT_SHIFT: 627 mask = KBD_MOD_RSHIFT; 628 break; 629 630 case KBD_LEFT_ALT: 631 mask = KBD_MOD_LALT; 632 break; 633 634 case KBD_RIGHT_ALT: 635 mask = KBD_MOD_RALT; 636 break; 637 638 case KBD_LEFT_META: 639 mask = KBD_MOD_LMETA; 640 break; 641 642 case KBD_RIGHT_META: 643 mask = KBD_MOD_RMETA; 644 break; 645 646 case KBD_CAPS_LOCK: 647 /* capslock already behaves `right', don't need to keep track of the 648 state in here. */ 649 mask = KBD_MOD_CAPS; 650 break; 651 652 case KBD_CTRL: 653 mask = KBD_MOD_CTRL; 654 break; 655 } 656 657 if (mask) 658 { 659 if (up) 660 mod &= ~mask; 661 else 662 mod |= mask; 663 } 664 665 /* these keys should not repeat, so it's the Right Thing dealing with 666 repeaters only after this block. */ 667 668 /* return even if it wasn't a modifier key, the other codes up here 669 are either special (like reset warning), or not yet defined */ 670 splx (s); 671 return -1; 672 } 673 674 /* no matter which character we're repeating, stop it if we get a key-up 675 event. I think this is the same thing amigados does. */ 676 if (up) 677 { 678 if (tout_pending) 679 { 680 untimeout ((timeout_t) repeat_handler, 0); 681 tout_pending = 0; 682 last_char = 0; 683 } 684 splx (s); 685 return -1; 686 } 687 688 689 /* intercept Ctrl-LAlt-F1 here to switch back to original ascii-keymap. 690 this should probably be configurable.. */ 691 if (mod == (KBD_MOD_LALT|KBD_MOD_SHIFT) && code == 0x50) 692 { 693 bcopy (&ascii_kbdmap, &kbdmap, sizeof (struct kbdmap)); 694 splx (s); 695 return -1; 696 } 697 698 699 switch (mod & (KBD_MOD_ALT | KBD_MOD_SHIFT)) 700 { 701 case 0: 702 key = kbdmap.keys[c]; 703 if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS)) 704 break; 705 /* FALL INTO */ 706 707 case KBD_MOD_LSHIFT: 708 case KBD_MOD_RSHIFT: 709 case KBD_MOD_SHIFT: 710 key = kbdmap.shift_keys[c]; 711 break; 712 713 case KBD_MOD_LALT: 714 case KBD_MOD_RALT: 715 case KBD_MOD_ALT: 716 key = kbdmap.alt_keys[c]; 717 if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS)) 718 break; 719 /* FALL INTO */ 720 721 case KBD_MOD_LALT|KBD_MOD_LSHIFT: 722 case KBD_MOD_LALT|KBD_MOD_RSHIFT: 723 case KBD_MOD_LALT|KBD_MOD_SHIFT: 724 case KBD_MOD_RALT|KBD_MOD_RSHIFT: 725 case KBD_MOD_RALT|KBD_MOD_SHIFT: 726 case KBD_MOD_ALT|KBD_MOD_RSHIFT: 727 key = kbdmap.alt_shift_keys[c]; 728 break; 729 } 730 731 code = key.code; 732 733 /* arrange to repeat the keystroke. By doing this at the level of scan-codes, 734 we can have function keys, and keys that send strings, repeat too. This 735 also entitles an additional overhead, since we have to do the conversion 736 each time, but I guess that's ok. */ 737 if (!tout_pending && caller == ITEFILT_TTY && kbd_ip->key_repeat) 738 { 739 tout_pending = 1; 740 last_char = c; 741 timeout ((timeout_t) repeat_handler, 0, start_repeat_timo); 742 } 743 else if (!tout_pending && caller == ITEFILT_REPEATER && kbd_ip->key_repeat) 744 { 745 tout_pending = 1; 746 last_char = c; 747 timeout ((timeout_t) repeat_handler, 0, next_repeat_timo); 748 } 749 750 /* handle dead keys */ 751 if (key.mode & KBD_MODE_DEAD) 752 { 753 /* if entered twice, send accent itself */ 754 if (last_dead == key.mode & KBD_MODE_ACCMASK) 755 last_dead = 0; 756 else 757 { 758 last_dead = key.mode & KBD_MODE_ACCMASK; 759 splx (s); 760 return -1; 761 } 762 } 763 if (last_dead) 764 { 765 /* can't apply dead flag to string-keys */ 766 if (! (key.mode & KBD_MODE_STRING) && code >= '@' && code < 0x7f) 767 code = acctable[KBD_MODE_ACCENT (last_dead)][code - '@']; 768 769 last_dead = 0; 770 } 771 772 /* if not string, apply META and CTRL modifiers */ 773 if (! (key.mode & KBD_MODE_STRING)) 774 { 775 if (mod & KBD_MOD_CTRL) 776 code &= 0x1f; 777 778 if (mod & KBD_MOD_META) 779 code |= 0x80; 780 } 781 else 782 { 783 /* strings are only supported in normal tty mode, not in console mode */ 784 if (caller != ITEFILT_CONSOLE) 785 { 786 str = kbdmap.strings + code; 787 /* using a length-byte instead of 0-termination allows to embed \0 into 788 strings, although this is not used in the default keymap */ 789 for (i = *str++; i; i--) 790 itesendch(*str++); 791 } 792 splx (s); 793 return -1; 794 } 795 796 if (caller == ITEFILT_CONSOLE) 797 { 798 /* do the conversion here because raw console input doesn't go thru 799 tty conversions */ 800 code = code == '\r' ? '\n' : code; 801 splx (s); 802 return code; 803 } 804 else 805 /* NOTE: *don't* do any cr->crlf conversion here, this is input 806 processing, the mentioned conversion should only be 807 done for output processing (for input, it is not 808 terminal-specific but depends on tty-settings!) */ 809 (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty); 810 811 splx (s); 812 return -1; 813 } 814 815 816 /* helper functions, makes the code below more readable */ 817 static void inline 818 ite_sendstr (ip, str) 819 struct ite_softc *ip; 820 char *str; 821 { 822 while (*str) 823 itesendch (*str++); 824 } 825 826 static void 827 alignment_display(struct ite_softc *ip, struct itesw *sp) 828 { 829 int i, j; 830 831 for (j = 0; j < ip->rows; j++) 832 for (i = 0; i < ip->cols; i++) 833 (*sp->ite_putc)(ip, 'E', j, i, ATTR_NOR); 834 attrclr(ip, 0, 0, ip->rows, ip->cols); 835 (*sp->ite_cursor)(ip, DRAW_CURSOR); 836 } 837 838 static void inline 839 snap_cury(struct ite_softc *ip, struct itesw *sp) 840 { 841 if (ip->inside_margins) 842 { 843 if (ip->cury < ip->top_margin) 844 ip->cury = ip->top_margin; 845 if (ip->cury > ip->bottom_margin) 846 ip->cury = ip->bottom_margin; 847 } 848 } 849 850 static void inline 851 ite_dnchar(ip, sp, n) 852 struct ite_softc *ip; 853 struct itesw *sp; 854 int n; 855 { 856 n = MIN(n, ip->cols - ip->curx); 857 if (n < ip->cols - ip->curx) 858 { 859 (*sp->ite_scroll)(ip, ip->cury, ip->curx + n, n, SCROLL_LEFT); 860 attrmov(ip, ip->cury, ip->curx + n, ip->cury, ip->curx, 861 1, ip->cols - ip->curx - n); 862 attrclr(ip, ip->cury, ip->cols - n, 1, n); 863 } 864 while (n-- > 0) 865 (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - n - 1, ATTR_NOR); 866 (*sp->ite_cursor)(ip, DRAW_CURSOR); 867 } 868 869 static void inline 870 ite_inchar(ip, sp, n) 871 struct ite_softc *ip; 872 struct itesw *sp; 873 int n; 874 { 875 n = MIN(n, ip->cols - ip->curx); 876 if (n < ip->cols - ip->curx) 877 { 878 (*sp->ite_scroll)(ip, ip->cury, ip->curx, n, SCROLL_RIGHT); 879 attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + n, 880 1, ip->cols - ip->curx - n); 881 attrclr(ip, ip->cury, ip->curx, 1, n); 882 } 883 while (n--) 884 (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR); 885 (*sp->ite_cursor)(ip, DRAW_CURSOR); 886 } 887 888 static void inline 889 ite_clrtoeol(ip, sp) 890 struct ite_softc *ip; 891 struct itesw *sp; 892 { 893 int y = ip->cury, x = ip->curx; 894 if (ip->cols - x > 0) 895 { 896 (*sp->ite_clear)(ip, y, x, 1, ip->cols - x); 897 attrclr(ip, y, x, 1, ip->cols - x); 898 (*sp->ite_cursor)(ip, DRAW_CURSOR); 899 } 900 } 901 902 static void inline 903 ite_clrtobol(ip, sp) 904 struct ite_softc *ip; 905 struct itesw *sp; 906 { 907 int y = ip->cury, x = MIN(ip->curx + 1, ip->cols); 908 (*sp->ite_clear)(ip, y, 0, 1, x); 909 attrclr(ip, y, 0, 1, x); 910 (*sp->ite_cursor)(ip, DRAW_CURSOR); 911 } 912 913 static void inline 914 ite_clrline(ip, sp) 915 struct ite_softc *ip; 916 struct itesw *sp; 917 { 918 int y = ip->cury; 919 (*sp->ite_clear)(ip, y, 0, 1, ip->cols); 920 attrclr(ip, y, 0, 1, ip->cols); 921 (*sp->ite_cursor)(ip, DRAW_CURSOR); 922 } 923 924 925 926 static void inline 927 ite_clrtoeos(ip, sp) 928 struct ite_softc *ip; 929 struct itesw *sp; 930 { 931 ite_clrtoeol(ip, sp); 932 if (ip->cury < ip->rows - 1) 933 { 934 (*sp->ite_clear)(ip, ip->cury + 1, 0, ip->rows - 1 - ip->cury, ip->cols); 935 attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); 936 (*sp->ite_cursor)(ip, DRAW_CURSOR); 937 } 938 } 939 940 static void inline 941 ite_clrtobos(ip, sp) 942 struct ite_softc *ip; 943 struct itesw *sp; 944 { 945 ite_clrtobol(ip, sp); 946 if (ip->cury > 0) 947 { 948 (*sp->ite_clear)(ip, 0, 0, ip->cury, ip->cols); 949 attrclr(ip, 0, 0, ip->cury, ip->cols); 950 (*sp->ite_cursor)(ip, DRAW_CURSOR); 951 } 952 } 953 954 static void inline 955 ite_clrscreen(ip, sp) 956 struct ite_softc *ip; 957 struct itesw *sp; 958 { 959 (*sp->ite_clear)(ip, 0, 0, ip->rows, ip->cols); 960 attrclr(ip, 0, 0, ip->rows, ip->cols); 961 (*sp->ite_cursor)(ip, DRAW_CURSOR); 962 } 963 964 965 966 static void inline 967 ite_dnline(ip, sp, n) 968 struct ite_softc *ip; 969 struct itesw *sp; 970 int n; 971 { 972 n = MIN(n, ip->bottom_margin + 1 - ip->cury); 973 if (n <= ip->bottom_margin - ip->cury) 974 { 975 (*sp->ite_scroll)(ip, ip->cury + n, 0, n, SCROLL_UP); 976 attrmov(ip, ip->cury + n, 0, ip->cury, 0, 977 ip->bottom_margin + 1 - ip->cury - n, ip->cols); 978 } 979 (*sp->ite_clear)(ip, ip->bottom_margin - n + 1, 0, n, ip->cols); 980 attrclr(ip, ip->bottom_margin - n + 1, 0, n, ip->cols); 981 (*sp->ite_cursor)(ip, DRAW_CURSOR); 982 } 983 984 static void inline 985 ite_inline(ip, sp, n) 986 struct ite_softc *ip; 987 struct itesw *sp; 988 int n; 989 { 990 if ((ip->cury >= ip->top_margin) && (ip->cury <= ip->bottom_margin)) 991 { 992 n = MIN(n, ip->bottom_margin + 1 - ip->cury); 993 if (n <= ip->bottom_margin - ip->cury) 994 { 995 (*sp->ite_scroll)(ip, ip->cury, 0, n, SCROLL_DOWN); 996 attrmov(ip, ip->cury, 0, ip->cury + n, 0, 997 ip->bottom_margin + 1 - ip->cury - n, ip->cols); 998 } 999 (*sp->ite_clear)(ip, ip->cury, 0, n, ip->cols); 1000 attrclr(ip, ip->cury, 0, n, ip->cols); 1001 (*sp->ite_cursor)(ip, DRAW_CURSOR); 1002 } 1003 } 1004 1005 static void inline 1006 ite_lf (ip, sp) 1007 struct ite_softc *ip; 1008 struct itesw *sp; 1009 { 1010 if (ip->inside_margins) 1011 { 1012 ++ip->cury; 1013 if ((ip->cury == ip->bottom_margin+1) || (ip->cury == ip->rows)) 1014 { 1015 ip->cury--; 1016 (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP); 1017 ite_clrline(ip, sp); 1018 } 1019 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1020 } 1021 else 1022 { 1023 if (++ip->cury >= ip->rows) 1024 { 1025 ip->cury = ip->rows - 1; 1026 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 1027 ite_clrline(ip, sp); 1028 } 1029 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1030 } 1031 clr_attr(ip, ATTR_INV); 1032 } 1033 1034 static void inline 1035 ite_crlf (ip, sp) 1036 struct ite_softc *ip; 1037 struct itesw *sp; 1038 { 1039 ip->curx = 0; 1040 ite_lf (ip, sp); 1041 } 1042 1043 static void inline 1044 ite_cr (ip, sp) 1045 struct ite_softc *ip; 1046 struct itesw *sp; 1047 { 1048 if (ip->curx) 1049 { 1050 ip->curx = 0; 1051 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1052 } 1053 } 1054 1055 static void inline 1056 ite_rlf (ip, sp) 1057 struct ite_softc *ip; 1058 struct itesw *sp; 1059 { 1060 int top = ip->inside_margins ? ip->top_margin : 0; 1061 1062 ip->cury--; 1063 if ((ip->cury < 0) || (ip->cury == top-1)) 1064 { 1065 ip->cury++; 1066 (*sp->ite_scroll)(ip, top, 0, 1, SCROLL_DOWN); 1067 ite_clrline(ip, sp); 1068 } 1069 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1070 clr_attr(ip, ATTR_INV); 1071 } 1072 1073 static int inline 1074 atoi (cp) 1075 const char *cp; 1076 { 1077 int n; 1078 1079 for (n = 0; *cp && *cp >= '0' && *cp <= '9'; cp++) 1080 n = n * 10 + *cp - '0'; 1081 1082 return n; 1083 } 1084 1085 static char * 1086 index (cp, ch) 1087 const char *cp; 1088 char ch; 1089 { 1090 while (*cp && *cp != ch) cp++; 1091 return *cp ? (char *) cp : 0; 1092 } 1093 1094 1095 1096 static int inline 1097 ite_argnum (ip) 1098 struct ite_softc *ip; 1099 { 1100 char ch; 1101 int n; 1102 1103 /* convert argument string into number */ 1104 if (ip->ap == ip->argbuf) 1105 return 1; 1106 ch = *ip->ap; 1107 *ip->ap = 0; 1108 n = atoi (ip->argbuf); 1109 *ip->ap = ch; 1110 1111 return n; 1112 } 1113 1114 static int inline 1115 ite_zargnum (ip) 1116 struct ite_softc *ip; 1117 { 1118 char ch, *cp; 1119 int n; 1120 1121 /* convert argument string into number */ 1122 if (ip->ap == ip->argbuf) 1123 return 0; 1124 ch = *ip->ap; 1125 *ip->ap = 0; 1126 n = atoi (ip->argbuf); 1127 *ip->ap = ch; 1128 1129 return n; /* don't "n ? n : 1" here, <CSI>0m != <CSI>1m ! */ 1130 } 1131 1132 static int inline 1133 strncmp (a, b, l) 1134 const char *a, *b; 1135 int l; 1136 { 1137 for (;l--; a++, b++) 1138 if (*a != *b) 1139 return *a - *b; 1140 return 0; 1141 } 1142 1143 static void inline 1144 ite_reset(ip) 1145 struct ite_softc *ip; 1146 { 1147 int i; 1148 1149 ip->curx = 0; 1150 ip->cury = 0; 1151 ip->attribute = 0; 1152 ip->save_curx = 0; 1153 ip->save_cury = 0; 1154 ip->save_attribute = 0; 1155 ip->ap = ip->argbuf; 1156 ip->emul_level = EMUL_VT300_7; 1157 ip->eightbit_C1 = 0; 1158 ip->top_margin = 0; ip->bottom_margin = ip->rows - 1; 1159 ip->inside_margins = 1; 1160 ip->linefeed_newline = 0; 1161 ip->auto_wrap = 0; 1162 ip->cursor_appmode = 0; 1163 ip->keypad_appmode = 0; 1164 ip->imode = 0; 1165 ip->key_repeat = 1; 1166 1167 #ifdef DO_WEIRD_ATTRIBUTES 1168 bzero(ip->attrbuf, (ip->rows * ip->cols)); 1169 #endif 1170 bzero (ip->tabs, ip->cols); 1171 for (i = 0; i < ip->cols; i++) 1172 ip->tabs[i] = (i & 7) == 0; 1173 } 1174 1175 1176 void 1177 iteputchar(c, dev) 1178 register int c; 1179 dev_t dev; 1180 { 1181 int unit = UNIT(dev); 1182 register struct ite_softc *ip = &ite_softc[unit]; 1183 register struct itesw *sp = &itesw[ip->type]; 1184 register int n; 1185 int x, y; 1186 char *cp; 1187 1188 if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) 1189 return; 1190 1191 #if 0 1192 if (ite_tty[unit]) 1193 if ((ite_tty[unit]->t_cflag & CSIZE) == CS7 1194 || (ite_tty[unit]->t_cflag & PARENB)) 1195 c &= 0x7f; 1196 #endif 1197 1198 if (ip->escape) 1199 { 1200 doesc: 1201 switch (ip->escape) 1202 { 1203 case ESC: 1204 switch (c) 1205 { 1206 /* first 7bit equivalents for the 8bit control characters */ 1207 1208 case 'D': 1209 c = IND; 1210 ip->escape = 0; 1211 break; /* and fall into the next switch below (same for all `break') */ 1212 1213 case 'E': 1214 c = NEL; 1215 ip->escape = 0; 1216 break; 1217 1218 case 'H': 1219 c = HTS; 1220 ip->escape = 0; 1221 break; 1222 1223 case 'M': 1224 c = RI; 1225 ip->escape = 0; 1226 break; 1227 1228 case 'N': 1229 c = SS2; 1230 ip->escape = 0; 1231 break; 1232 1233 case 'O': 1234 c = SS3; 1235 ip->escape = 0; 1236 break; 1237 1238 case 'P': 1239 c = DCS; 1240 ip->escape = 0; 1241 break; 1242 1243 case '[': 1244 c = CSI; 1245 ip->escape = 0; 1246 break; 1247 1248 case '\\': 1249 c = ST; 1250 ip->escape = 0; 1251 break; 1252 1253 case ']': 1254 c = OSC; 1255 ip->escape = 0; 1256 break; 1257 1258 case '^': 1259 c = PM; 1260 ip->escape = 0; 1261 break; 1262 1263 case '_': 1264 c = APC; 1265 ip->escape = 0; 1266 break; 1267 1268 1269 /* introduces 7/8bit control */ 1270 case ' ': 1271 /* can be followed by either F or G */ 1272 ip->escape = ' '; 1273 break; 1274 1275 1276 /* a lot of character set selections, not yet used... 1277 94-character sets: */ 1278 case '(': /* G0 */ 1279 case ')': /* G1 */ 1280 ip->escape = c; 1281 return; 1282 1283 case '*': /* G2 */ 1284 case '+': /* G3 */ 1285 case 'B': /* ASCII */ 1286 case 'A': /* ISO latin 1 */ 1287 case '<': /* user preferred suplemental */ 1288 case '0': /* dec special graphics */ 1289 1290 /* 96-character sets: */ 1291 case '-': /* G1 */ 1292 case '.': /* G2 */ 1293 case '/': /* G3 */ 1294 1295 /* national character sets: */ 1296 case '4': /* dutch */ 1297 case '5': 1298 case 'C': /* finnish */ 1299 case 'R': /* french */ 1300 case 'Q': /* french canadian */ 1301 case 'K': /* german */ 1302 case 'Y': /* italian */ 1303 case '6': /* norwegian/danish */ 1304 /* note: %5 and %6 are not supported (two chars..) */ 1305 1306 ip->escape = 0; 1307 /* just ignore for now */ 1308 return; 1309 1310 1311 /* locking shift modes (as you might guess, not yet supported..) */ 1312 case '`': 1313 ip->GR = ip->G1; 1314 ip->escape = 0; 1315 return; 1316 1317 case 'n': 1318 ip->GL = ip->G2; 1319 ip->escape = 0; 1320 return; 1321 1322 case '}': 1323 ip->GR = ip->G2; 1324 ip->escape = 0; 1325 return; 1326 1327 case 'o': 1328 ip->GL = ip->G3; 1329 ip->escape = 0; 1330 return; 1331 1332 case '|': 1333 ip->GR = ip->G3; 1334 ip->escape = 0; 1335 return; 1336 1337 1338 /* font width/height control */ 1339 case '#': 1340 ip->escape = '#'; 1341 return; 1342 1343 1344 /* hard terminal reset .. */ 1345 case 'c': 1346 ite_reset (ip); 1347 (*itesw[ip->type].ite_cursor)(ip, MOVE_CURSOR); 1348 ip->escape = 0; 1349 return; 1350 1351 1352 case '7': 1353 ip->save_curx = ip->curx; 1354 ip->save_cury = ip->cury; 1355 ip->save_attribute = ip->attribute; 1356 ip->escape = 0; 1357 return; 1358 1359 case '8': 1360 ip->curx = ip->save_curx; 1361 ip->cury = ip->save_cury; 1362 ip->attribute = ip->save_attribute; 1363 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1364 ip->escape = 0; 1365 return; 1366 1367 case '=': 1368 ip->keypad_appmode = 1; 1369 ip->escape = 0; 1370 return; 1371 1372 case '>': 1373 ip->keypad_appmode = 0; 1374 ip->escape = 0; 1375 return; 1376 1377 case 'Z': /* request ID */ 1378 if (ip->emul_level == EMUL_VT100) 1379 ite_sendstr (ip, "\033[61;0c"); 1380 else 1381 ite_sendstr (ip, "\033[63;0c"); 1382 ip->escape = 0; 1383 return; 1384 1385 /* default catch all for not recognized ESC sequences */ 1386 default: 1387 ip->escape = 0; 1388 return; 1389 } 1390 break; 1391 1392 1393 case '(': 1394 case ')': 1395 ip->escape = 0; 1396 return; 1397 1398 1399 case ' ': 1400 switch (c) 1401 { 1402 case 'F': 1403 ip->eightbit_C1 = 0; 1404 ip->escape = 0; 1405 return; 1406 1407 case 'G': 1408 ip->eightbit_C1 = 1; 1409 ip->escape = 0; 1410 return; 1411 1412 default: 1413 /* not supported */ 1414 ip->escape = 0; 1415 return; 1416 } 1417 break; 1418 1419 1420 case '#': 1421 switch (c) 1422 { 1423 case '5': 1424 /* single height, single width */ 1425 ip->escape = 0; 1426 return; 1427 1428 case '6': 1429 /* double width, single height */ 1430 ip->escape = 0; 1431 return; 1432 1433 case '3': 1434 /* top half */ 1435 ip->escape = 0; 1436 return; 1437 1438 case '4': 1439 /* bottom half */ 1440 ip->escape = 0; 1441 return; 1442 1443 case '8': 1444 /* screen alignment pattern... */ 1445 ip->escape = 0; 1446 return; 1447 1448 default: 1449 ip->escape = 0; 1450 return; 1451 } 1452 break; 1453 1454 1455 1456 case CSI: 1457 /* the biggie... */ 1458 switch (c) 1459 { 1460 case '0': case '1': case '2': case '3': case '4': 1461 case '5': case '6': case '7': case '8': case '9': 1462 case ';': case '\"': case '$': case '>': 1463 if (ip->ap < ip->argbuf + ARGBUF_SIZE) 1464 *ip->ap++ = c; 1465 return; 1466 1467 case 'p': 1468 *ip->ap = 0; 1469 if (! strncmp (ip->argbuf, "61\"", 3)) 1470 ip->emul_level = EMUL_VT100; 1471 else if (! strncmp (ip->argbuf, "63;1\"", 5) 1472 || ! strncmp (ip->argbuf, "62;1\"", 5)) 1473 ip->emul_level = EMUL_VT300_7; 1474 else 1475 ip->emul_level = EMUL_VT300_8; 1476 ip->escape = 0; 1477 return; 1478 1479 1480 case '?': 1481 *ip->ap = 0; 1482 ip->escape = '?'; 1483 ip->ap = ip->argbuf; 1484 return; 1485 1486 1487 case 'c': 1488 *ip->ap = 0; 1489 if (ip->argbuf[0] == '>') 1490 { 1491 ite_sendstr (ip, "\033[>24;0;0;0c"); 1492 } 1493 else switch (ite_zargnum(ip)) 1494 { 1495 case 0: 1496 /* primary DA request, send primary DA response */ 1497 if (ip->emul_level == EMUL_VT100) 1498 ite_sendstr (ip, "\033[?1;1c"); 1499 else 1500 ite_sendstr (ip, "\033[63;0c"); 1501 break; 1502 } 1503 ip->escape = 0; 1504 <<<<<<< ite.c 1505 return -1; 1506 ||||||| 1.1.1.2 1507 return -1; 1508 1509 ======= 1510 return; 1511 >>>>>>> /tmp/T4009622 1512 1513 1514 case 'n': 1515 switch (ite_zargnum(ip)) 1516 { 1517 case 5: 1518 ite_sendstr (ip, "\033[0n"); /* no malfunction */ 1519 break; 1520 case 6: 1521 /* cursor position report */ 1522 sprintf (ip->argbuf, "\033[%d;%dR", 1523 ip->cury + 1, ip->curx + 1); 1524 ite_sendstr (ip, ip->argbuf); 1525 break; 1526 } 1527 ip->escape = 0; 1528 <<<<<<< ite.c 1529 return -1; 1530 1531 ||||||| 1.1.1.2 1532 return -1; 1533 ======= 1534 return; 1535 >>>>>>> /tmp/T4009622 1536 1537 <<<<<<< ite.c 1538 case 'h': case 'l': 1539 *ip->ap = 0; 1540 if (ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '4') 1541 ip->imode = (c == 'h'); /* insert/replace mode */ 1542 ||||||| 1.1.1.2 1543 1544 case 'h': case 'l': 1545 *ip->ap = 0; 1546 if (ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '4') 1547 ip->imode = (c == 'h'); /* insert/replace mode */ 1548 ======= 1549 1550 case 'x': 1551 switch (ite_zargnum(ip)) 1552 { 1553 case 0: 1554 /* Fake some terminal parameters. */ 1555 ite_sendstr (ip, "\033[2;1;1;112;112;1;0x"); 1556 break; 1557 case 1: 1558 ite_sendstr (ip, "\033[3;1;1;112;112;1;0x"); 1559 break; 1560 } 1561 ip->escape = 0; 1562 return; 1563 >>>>>>> /tmp/T4009622 1564 1565 1566 case 'g': 1567 switch (ite_zargnum(ip)) 1568 { 1569 case 0: 1570 if (ip->curx < ip->cols) 1571 ip->tabs[ip->curx] = 0; 1572 break; 1573 case 3: 1574 for (n = 0; n < ip->cols; n++) 1575 ip->tabs[n] = 0; 1576 break; 1577 } 1578 ip->escape = 0; 1579 return; 1580 1581 1582 case 'h': case 'l': 1583 n = ite_zargnum (ip); 1584 switch (n) 1585 { 1586 case 4: 1587 ip->imode = (c == 'h'); /* insert/replace mode */ 1588 break; 1589 case 20: 1590 ip->linefeed_newline = (c == 'h'); 1591 break; 1592 } 1593 ip->escape = 0; 1594 return; 1595 1596 1597 case 'M': 1598 ite_dnline (ip, sp, ite_argnum (ip)); 1599 ip->escape = 0; 1600 return; 1601 1602 1603 case 'L': 1604 ite_inline (ip, sp, ite_argnum (ip)); 1605 ip->escape = 0; 1606 return; 1607 1608 1609 case 'P': 1610 ite_dnchar (ip, sp, ite_argnum (ip)); 1611 ip->escape = 0; 1612 return; 1613 1614 1615 case '@': 1616 ite_inchar (ip, sp, ite_argnum (ip)); 1617 ip->escape = 0; 1618 return; 1619 1620 1621 case 'H': 1622 case 'f': 1623 *ip->ap = 0; 1624 y = atoi (ip->argbuf); 1625 x = 0; 1626 cp = index (ip->argbuf, ';'); 1627 if (cp) 1628 x = atoi (cp + 1); 1629 if (x) x--; 1630 if (y) y--; 1631 ip->cury = MIN(y, ip->rows - 1); 1632 ip->curx = MIN(x, ip->cols - 1); 1633 ip->escape = 0; 1634 snap_cury(ip, sp); 1635 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1636 clr_attr (ip, ATTR_INV); 1637 return; 1638 1639 case 'A': 1640 n = ip->cury - ite_argnum (ip); 1641 if (n < 0) n = 0; 1642 ip->cury = MAX(n, ip->inside_margins ? ip->top_margin : 0); 1643 ip->escape = 0; 1644 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1645 clr_attr (ip, ATTR_INV); 1646 return; 1647 1648 case 'B': 1649 n = ite_argnum (ip) + ip->cury; 1650 ip->cury = MIN(n, ip->inside_margins ? ip->bottom_margin : ip->rows - 1); 1651 ip->escape = 0; 1652 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1653 clr_attr (ip, ATTR_INV); 1654 return; 1655 1656 case 'C': 1657 n = ite_argnum (ip); 1658 ip->curx = MIN(ip->curx + n, ip->cols - 1); 1659 ip->escape = 0; 1660 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1661 clr_attr (ip, ATTR_INV); 1662 return; 1663 1664 case 'D': 1665 n = ite_argnum (ip); 1666 n = ip->curx - n; 1667 ip->curx = n >= 0 ? n : 0; 1668 ip->escape = 0; 1669 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1670 clr_attr (ip, ATTR_INV); 1671 return; 1672 1673 1674 1675 1676 case 'J': 1677 *ip->ap = 0; 1678 n = ite_zargnum (ip); 1679 if (n == 0) 1680 ite_clrtoeos(ip, sp); 1681 else if (n == 1) 1682 ite_clrtobos(ip, sp); 1683 else if (n == 2) 1684 ite_clrscreen(ip, sp); 1685 ip->escape = 0; 1686 return; 1687 1688 1689 case 'K': 1690 n = ite_zargnum (ip); 1691 if (n == 0) 1692 ite_clrtoeol(ip, sp); 1693 else if (n == 1) 1694 ite_clrtobol(ip, sp); 1695 else if (n == 2) 1696 ite_clrline(ip, sp); 1697 ip->escape = 0; 1698 return; 1699 1700 1701 case 'X': 1702 n = ite_argnum(ip) - 1; 1703 n = MIN(n, ip->cols - 1 - ip->curx); 1704 for (; n >= 0; n--) 1705 { 1706 attrclr(ip, ip->cury, ip->curx + n, 1, 1); 1707 (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR); 1708 } 1709 ip->escape = 0; 1710 return; 1711 1712 1713 case '}': case '`': 1714 /* status line control */ 1715 ip->escape = 0; 1716 return; 1717 1718 1719 case 'r': 1720 *ip->ap = 0; 1721 x = atoi (ip->argbuf); 1722 y = 0; 1723 cp = index (ip->argbuf, ';'); 1724 if (cp) 1725 y = atoi (cp + 1); 1726 if ((x > 0) || (y > 1)) 1727 { 1728 if (x) x--; 1729 if (y) y--; 1730 ip->top_margin = MIN(x, ip->rows - 1); 1731 ip->bottom_margin = MIN(y, ip->rows - 1); 1732 if (ip->bottom_margin < ip->top_margin) 1733 ip->bottom_margin = ip->top_margin; 1734 } 1735 else 1736 { 1737 ip->top_margin = 0; 1738 ip->bottom_margin = ip->rows - 1; 1739 } 1740 ip->cury = ip->top_margin; 1741 ip->curx = 0; 1742 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1743 ip->escape = 0; 1744 return; 1745 1746 1747 case 'm': 1748 /* big attribute setter/resetter */ 1749 { 1750 char *cp; 1751 *ip->ap = 0; 1752 /* kludge to make CSIm work (== CSI0m) */ 1753 if (ip->ap == ip->argbuf) 1754 ip->ap++; 1755 for (cp = ip->argbuf; cp < ip->ap; ) 1756 { 1757 switch (*cp) 1758 { 1759 case 0: 1760 case '0': 1761 clr_attr (ip, ATTR_ALL); 1762 cp++; 1763 break; 1764 1765 case '1': 1766 set_attr (ip, ATTR_BOLD); 1767 cp++; 1768 break; 1769 1770 case '2': 1771 switch (cp[1]) 1772 { 1773 case '2': 1774 clr_attr (ip, ATTR_BOLD); 1775 cp += 2; 1776 break; 1777 1778 case '4': 1779 clr_attr (ip, ATTR_UL); 1780 cp += 2; 1781 break; 1782 1783 case '5': 1784 clr_attr (ip, ATTR_BLINK); 1785 cp += 2; 1786 break; 1787 1788 case '7': 1789 clr_attr (ip, ATTR_INV); 1790 cp += 2; 1791 break; 1792 1793 default: 1794 cp++; 1795 break; 1796 } 1797 break; 1798 1799 case '4': 1800 set_attr (ip, ATTR_UL); 1801 cp++; 1802 break; 1803 1804 case '5': 1805 set_attr (ip, ATTR_BLINK); 1806 cp++; 1807 break; 1808 1809 case '7': 1810 set_attr (ip, ATTR_INV); 1811 cp++; 1812 break; 1813 1814 default: 1815 cp++; 1816 break; 1817 } 1818 } 1819 1820 } 1821 ip->escape = 0; 1822 return; 1823 1824 1825 case 'u': 1826 /* DECRQTSR */ 1827 ite_sendstr (ip, "\033P\033\\"); 1828 ip->escape = 0; 1829 return; 1830 1831 1832 1833 default: 1834 ip->escape = 0; 1835 return; 1836 } 1837 break; 1838 1839 1840 1841 case '?': /* CSI ? */ 1842 switch (c) 1843 { 1844 case '0': case '1': case '2': case '3': case '4': 1845 case '5': case '6': case '7': case '8': case '9': 1846 case ';': case '\"': case '$': 1847 /* Don't fill the last character; it's needed. */ 1848 /* XXX yeah, where ?? */ 1849 if (ip->ap < ip->argbuf + ARGBUF_SIZE - 1) 1850 *ip->ap++ = c; 1851 return; 1852 1853 1854 case 'n': 1855 *ip->ap = 0; 1856 if (ip->ap == &ip->argbuf[2]) 1857 { 1858 if (! strncmp (ip->argbuf, "15", 2)) 1859 /* printer status: no printer */ 1860 ite_sendstr (ip, "\033[13n"); 1861 1862 else if (! strncmp (ip->argbuf, "25", 2)) 1863 /* udk status */ 1864 ite_sendstr (ip, "\033[20n"); 1865 1866 else if (! strncmp (ip->argbuf, "26", 2)) 1867 /* keyboard dialect: US */ 1868 ite_sendstr (ip, "\033[27;1n"); 1869 } 1870 ip->escape = 0; 1871 return; 1872 1873 1874 case 'h': case 'l': 1875 n = ite_zargnum (ip); 1876 switch (n) 1877 { 1878 case 1: 1879 ip->cursor_appmode = (c == 'h'); 1880 break; 1881 1882 case 3: 1883 /* 132/80 columns (132 == 'h') */ 1884 break; 1885 1886 case 4: /* smooth scroll */ 1887 break; 1888 1889 case 5: 1890 /* light background (=='h') /dark background(=='l') */ 1891 break; 1892 1893 case 6: /* origin mode */ 1894 ip->inside_margins = (c == 'h'); 1895 break; 1896 1897 case 7: /* auto wraparound */ 1898 ip->auto_wrap = (c == 'h'); 1899 break; 1900 1901 case 8: /* keyboard repeat */ 1902 ip->key_repeat = (c == 'h'); 1903 break; 1904 1905 case 20: /* newline mode */ 1906 ip->linefeed_newline = (c == 'h'); 1907 break; 1908 1909 case 25: /* cursor on/off */ 1910 (*itesw[ip->type].ite_cursor)(ip, (c == 'h') ? DRAW_CURSOR : ERASE_CURSOR); 1911 break; 1912 } 1913 ip->escape = 0; 1914 return; 1915 1916 default: 1917 ip->escape = 0; 1918 return; 1919 } 1920 break; 1921 1922 1923 default: 1924 ip->escape = 0; 1925 return; 1926 } 1927 } 1928 1929 1930 switch (c) { 1931 1932 case VT: /* VT is treated like LF */ 1933 case FF: /* so is FF */ 1934 case LF: 1935 /* cr->crlf distinction is done here, on output, 1936 not on input! */ 1937 if (ip->linefeed_newline) 1938 ite_crlf (ip, sp); 1939 else 1940 ite_lf (ip, sp); 1941 break; 1942 1943 case CR: 1944 ite_cr (ip, sp); 1945 break; 1946 1947 case BS: 1948 if (--ip->curx < 0) 1949 ip->curx = 0; 1950 else 1951 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1952 break; 1953 1954 case HT: 1955 for (n = ip->curx + 1; n < ip->cols; n++) { 1956 if (ip->tabs[n]) { 1957 ip->curx = n; 1958 (*sp->ite_cursor)(ip, MOVE_CURSOR); 1959 break; 1960 } 1961 } 1962 break; 1963 1964 case BEL: 1965 if (kbd_tty && ite_tty[unit] == kbd_tty) 1966 kbdbell(); 1967 break; 1968 1969 case SO: 1970 ip->GL = ip->G1; 1971 break; 1972 1973 case SI: 1974 ip->GL = ip->G0; 1975 break; 1976 1977 case ENQ: 1978 /* send answer-back message !! */ 1979 break; 1980 1981 case CAN: 1982 ip->escape = 0; /* cancel any escape sequence in progress */ 1983 break; 1984 1985 case SUB: 1986 ip->escape = 0; /* dito, but see below */ 1987 /* should also display a reverse question mark!! */ 1988 break; 1989 1990 case ESC: 1991 ip->escape = ESC; 1992 break; 1993 1994 1995 /* now it gets weird.. 8bit control sequences.. */ 1996 case IND: /* index: move cursor down, scroll */ 1997 ite_lf (ip, sp); 1998 break; 1999 2000 case NEL: /* next line. next line, first pos. */ 2001 ite_crlf (ip, sp); 2002 break; 2003 2004 case HTS: /* set horizontal tab */ 2005 if (ip->curx < ip->cols) 2006 ip->tabs[ip->curx] = 1; 2007 break; 2008 2009 case RI: /* reverse index */ 2010 ite_rlf (ip, sp); 2011 break; 2012 2013 case SS2: /* go into G2 for one character */ 2014 /* not yet supported */ 2015 break; 2016 2017 case SS3: /* go into G3 for one character */ 2018 break; 2019 2020 case DCS: /* device control string introducer */ 2021 ip->escape = DCS; 2022 ip->ap = ip->argbuf; 2023 break; 2024 2025 case CSI: /* control sequence introducer */ 2026 ip->escape = CSI; 2027 ip->ap = ip->argbuf; 2028 break; 2029 2030 case ST: /* string terminator */ 2031 /* ignore, if not used as terminator */ 2032 break; 2033 2034 case OSC: /* introduces OS command. Ignore everything upto ST */ 2035 ip->escape = OSC; 2036 break; 2037 2038 case PM: /* privacy message, ignore everything upto ST */ 2039 ip->escape = PM; 2040 break; 2041 2042 case APC: /* application program command, ignore everything upto ST */ 2043 ip->escape = APC; 2044 break; 2045 2046 default: 2047 if (c < ' ' || c == DEL) 2048 break; 2049 if (ip->imode) 2050 ite_inchar(ip, sp, 1); 2051 iteprecheckwrap(ip, sp); 2052 #ifdef DO_WEIRD_ATTRIBUTES 2053 if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) { 2054 attrset(ip, ATTR_INV); 2055 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV); 2056 } 2057 else 2058 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR); 2059 #else 2060 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ip->attribute); 2061 #endif 2062 (*sp->ite_cursor)(ip, DRAW_CURSOR); 2063 itecheckwrap(ip, sp); 2064 break; 2065 } 2066 } 2067 2068 iteprecheckwrap(ip, sp) 2069 register struct ite_softc *ip; 2070 register struct itesw *sp; 2071 { 2072 if (ip->auto_wrap && ip->curx == ip->cols) { 2073 ip->curx = 0; 2074 clr_attr(ip, ATTR_INV); 2075 if (++ip->cury >= ip->bottom_margin + 1) { 2076 ip->cury = ip->bottom_margin; 2077 (*sp->ite_cursor)(ip, MOVE_CURSOR); 2078 (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP); 2079 ite_clrtoeol(ip, sp); 2080 } else 2081 (*sp->ite_cursor)(ip, MOVE_CURSOR); 2082 } 2083 } 2084 2085 itecheckwrap(ip, sp) 2086 register struct ite_softc *ip; 2087 register struct itesw *sp; 2088 { 2089 #if 0 2090 if (++ip->curx == ip->cols) { 2091 if (ip->auto_wrap) { 2092 ip->curx = 0; 2093 clr_attr(ip, ATTR_INV); 2094 if (++ip->cury >= ip->bottom_margin + 1) { 2095 ip->cury = ip->bottom_margin; 2096 (*sp->ite_cursor)(ip, MOVE_CURSOR); 2097 (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP); 2098 ite_clrtoeol(ip, sp); 2099 return; 2100 } 2101 } else 2102 /* stay there if no autowrap.. */ 2103 ip->curx--; 2104 } 2105 #else 2106 if (ip->curx < ip->cols) { 2107 ip->curx++; 2108 (*sp->ite_cursor)(ip, MOVE_CURSOR); 2109 } 2110 #endif 2111 } 2112 2113 /* 2114 * Console functions 2115 */ 2116 #include "grfioctl.h" 2117 #include "grfvar.h" 2118 2119 #ifdef DEBUG 2120 /* 2121 * Minimum ITE number at which to start looking for a console. 2122 * Setting to 0 will do normal search, 1 will skip first ITE device, 2123 * NITE will skip ITEs and use serial port. 2124 */ 2125 int whichconsole = 0; 2126 #endif 2127 2128 itecnprobe(cp) 2129 struct consdev *cp; 2130 { 2131 register struct ite_softc *ip; 2132 int i, maj, unit, pri; 2133 2134 /* locate the major number */ 2135 for (maj = 0; maj < nchrdev; maj++) 2136 if (cdevsw[maj].d_open == iteopen) 2137 break; 2138 2139 /* urk! */ 2140 grfconfig(); 2141 2142 /* check all the individual displays and find the best */ 2143 unit = -1; 2144 pri = CN_DEAD; 2145 for (i = 0; i < NITE; i++) { 2146 struct grf_softc *gp = &grf_softc[i]; 2147 2148 ip = &ite_softc[i]; 2149 if ((gp->g_flags & GF_ALIVE) == 0) 2150 continue; 2151 ip->flags = (ITE_ALIVE|ITE_CONSOLE); 2152 2153 /* XXX - we need to do something about mapping these */ 2154 switch (gp->g_type) { 2155 case GT_CUSTOMCHIPS: 2156 ip->type = ITE_CUSTOMCHIPS; 2157 break; 2158 2159 case GT_TIGA_A2410: 2160 ip->type = ITE_TIGA_A2410; 2161 break; 2162 2163 case GT_RETINA: 2164 ip->type = ITE_RETINA; 2165 break; 2166 } 2167 #ifdef DEBUG 2168 if (i < whichconsole) 2169 continue; 2170 #endif 2171 if ((int)gp->g_type == GT_CUSTOMCHIPS) { 2172 pri = CN_INTERNAL; 2173 unit = i; 2174 } else /* if (unit < 0) */ { 2175 pri = CN_NORMAL; 2176 unit = i; 2177 } 2178 2179 } 2180 2181 /* initialize required fields */ 2182 cp->cn_dev = makedev(maj, unit); 2183 #if 0 2184 cp->cn_tp = ite_tty[unit]; 2185 #else 2186 delayed_con_tty = unit; 2187 #endif 2188 cp->cn_pri = pri; 2189 } 2190 2191 itecninit(cp) 2192 struct consdev *cp; 2193 { 2194 int unit; 2195 struct ite_softc *ip; 2196 2197 iteinit(cp->cn_dev); 2198 unit = UNIT(cp->cn_dev); 2199 ip = &ite_softc[unit]; 2200 2201 #ifdef DO_WEIRD_ATTRIBUTES 2202 ip->attrbuf = console_attributes; 2203 #endif 2204 ip->flags |= (ITE_ACTIVE|ITE_ISCONS); 2205 /* if this is the console, NEVER close the device! */ 2206 ip->open_cnt++; 2207 #if 0 2208 /* have to delay this too.. sigh.. */ 2209 kbd_tty = ite_tty[unit]; 2210 kbd_ip = ip; 2211 kbdenable(); 2212 #endif 2213 } 2214 2215 /*ARGSUSED*/ 2216 itecngetc(dev) 2217 dev_t dev; 2218 { 2219 register int c; 2220 2221 do 2222 { 2223 c = kbdgetcn (); 2224 c = itefilter (c, ITEFILT_CONSOLE); 2225 } 2226 while (c == -1); 2227 2228 return(c); 2229 } 2230 2231 itecnputc(dev, c) 2232 dev_t dev; 2233 int c; 2234 { 2235 static int paniced = 0; 2236 struct ite_softc *ip = &ite_softc[UNIT(dev)]; 2237 2238 if (panicstr && !paniced && 2239 (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) { 2240 (void) iteon(dev, 3); 2241 paniced = 1; 2242 } 2243 iteputchar(c, dev); 2244 } 2245 #endif 2246