1 /* 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 7 * 8 * %sccs.include.redist.c% 9 * 10 * from: $Hdr: vt100.c,v 4.300 91/06/09 06:14:56 root Rel41 $ SONY 11 * 12 * @(#)vt100.c 7.1 (Berkeley) 06/04/92 13 */ 14 15 #include "../include/fix_machine_type.h" 16 17 #include "types.h" 18 #include "param.h" 19 #include "../iop/framebuf.h" 20 #include "../iop/kbreg.h" 21 #include "../iop/keyboard.h" 22 #include "../fb/fbdefs.h" 23 #include "../bm/vt100.h" 24 #include "../bm/bitmapif.h" 25 26 #ifdef IPC_MRX 27 #include "config.h" 28 #define kbd_ioctl(chan, cmd, argp) { \ 29 if (kb_ioctl) \ 30 (*kb_ioctl)(chan, cmd, argp); \ 31 } 32 #endif 33 34 #ifdef IPC_MRX 35 #include "mrx.h" 36 #include "process.h" 37 #include "object.h" 38 #include "console.h" 39 #endif 40 41 #ifdef CPU_SINGLE 42 #include "../sio/scc.h" 43 #endif 44 45 extern Key_string key_str; 46 extern int tmode; 47 static unsigned int first_code; 48 49 #ifdef IPC_MRX 50 #define SCC_KEYBOARD 0 51 #endif 52 53 SCREEN screen; 54 struct cursor inner_buf_csr; 55 int inner_buf_tstat; 56 char c_pos_mess[C_MESS_SIZ]; 57 extern struct csr_buf local_csr_buf; 58 59 #ifdef IPC_MRX 60 int bitmap_use; 61 #ifdef IPC_3CPU 62 #include "../../ubdev/msgio.h" 63 extern int ipc_ready; 64 #endif /* IPC_3CPU */ 65 extern struct cons_devsw vt100_cons; 66 #endif /* IPC_MRX */ 67 68 #ifdef CPU_DOUBLE 69 int auto_dimmer(); 70 #endif 71 72 #if CPU_SINGLE 73 extern int hz; 74 extern kbd_profun_init(); 75 #endif 76 77 lRectangle char_r1; 78 lRectangle font_r1; 79 lRectangle char_r2; 80 lRectangle font_r2; 81 82 int font_len1; 83 int font_len2; 84 85 int fcolor; 86 int bcolor; 87 88 int font_w; 89 int font_h; 90 int char_w; 91 int char_h; 92 int scr_w; 93 int scr_h; 94 int ch_pos; 95 int ul_pos; 96 int x_ofst; 97 int y_ofst; 98 int rit_m; 99 int btm_m; 100 int bell_len; 101 int dim_cnt; 102 int a_dim_on; 103 104 unsigned short fbuf[256]; 105 int fp; 106 int fpn; 107 lPoint fpp; 108 int fpa; 109 110 vt100init() 111 { 112 register int i; 113 register SCREEN *sp = &screen; 114 115 sp->s_term_mode = 0; 116 sp->s_term_mode |= (SRM|DECSCLM|DECAWM|DECARM|DECCSR_ACTV); 117 sp->s_current_stat = 0; 118 sp->s_csr.csr_x = 1; 119 sp->s_csr.csr_y = 1; 120 sp->s_csr.csr_p.x = x_ofst; 121 sp->s_csr.csr_p.y = y_ofst; 122 sp->s_csr.csr_attributes = NORMALM; 123 sp->s_region.top_margin = TOP_M; 124 sp->s_region.btm_margin = btm_m; 125 sp->s_plane = consfb->planemask; 126 sp->s_bgcol = 0; 127 fcolor = sp->s_plane; 128 bcolor = sp->s_bgcol; 129 for (i = 0; i < RIT_M_MAX; i++) 130 sp->s_tab_pos[i] = 0; 131 for (i = 9; i < RIT_M_MAX; i +=8) 132 sp->s_tab_pos[i] = 1; 133 134 esc_store_csr(sp); 135 inner_buf_tstat = sp->s_term_mode & (DECOM|DECAWM); 136 local_csr_buf.csr_number = 1; 137 138 cursor_on(&sp->s_csr.csr_p); 139 } 140 141 ncp_str(p, q, n) 142 register char *p, *q; 143 register int n; 144 { 145 while (n-- > 0) 146 *q++ = *p++; 147 } 148 149 /* 150 * default parameter set 151 */ 152 set_default_param() 153 { 154 register struct fbdev *cfb = consfb; 155 156 font_w = cfb->font_w; 157 font_h = cfb->font_h; 158 char_w = cfb->char_w; 159 char_h = cfb->char_h; 160 scr_w = cfb->scr_w; 161 scr_h = cfb->scr_h; 162 ch_pos = cfb->ch_pos; 163 ul_pos = cfb->ul_pos; 164 x_ofst = cfb->x_offset; 165 y_ofst = cfb->y_offset; 166 rit_m = cfb->rit_m; 167 btm_m = cfb->btm_m; 168 a_dim_on = 1; 169 170 font_r1.extent.x = font_w; 171 font_r1.extent.y = font_h; 172 font_r2.extent.x = font_w * 2; 173 font_r2.extent.y = font_h; 174 font_len1 = (font_w + 0x0f) >> 4; 175 font_len2 = (font_w*2 + 0x0f) >> 4; 176 char_r1.extent.x = char_w; 177 char_r1.extent.y = char_h; 178 char_r2.extent.x = char_w * 2; 179 char_r2.extent.y = char_h; 180 181 dim_cnt = DIM_CNT_DFLT; 182 bell_len = BELL_LEN_DFLT; 183 } 184 185 vt100_open() 186 { 187 static int only_one = 0; 188 extern char **ext_fnt_addr; 189 190 set_default_param(); 191 vt100init(); 192 bitmapinit(); 193 if (only_one == 0) { 194 #ifdef IPC_MRX 195 #ifdef IPC_3CPU 196 while (ipc_ready == 0) 197 proc_sleep_self(100); 198 #endif 199 while ((bitmap_use = object_query(BITMAP)) <= 0) 200 proc_sleep_self(100); 201 202 proc_create("auto_dimmer", auto_dimmer, 401, 512, 0); 203 #endif /* IPC_MRX */ 204 only_one = 1; 205 } 206 #define INIT_STRING "\033[42;1H" 207 vt100_write(0, INIT_STRING, sizeof(INIT_STRING) - 1); 208 #ifdef CPU_SINGLE 209 kbd_open(SCC_KEYBOARD); 210 #endif 211 } 212 213 #ifdef IPC_MRX 214 vt100_cons_setup() 215 { 216 int vt100_open(), vt100_read(), vt100_write(), vt100_ioctl(); 217 218 vt100_cons.open = vt100_open; 219 vt100_cons.read = vt100_read; 220 vt100_cons.write = vt100_write; 221 vt100_cons.ioctl = vt100_ioctl; 222 } 223 224 #define DIMMER_RESET 0 225 #define DIMMER_ON 1 226 #define DIMMER_OFF 2 227 #define DIMMER_INTERVAL 60 /* sec */ 228 229 static int dimmer_stdport; 230 231 auto_dimmer() 232 { 233 register int select, i; 234 register int dimm_counter = DIM_CNT_DFLT; 235 register int dimm_level = 0; 236 int ports[2], *mode; 237 238 spl0(); 239 ports[0] = dimmer_stdport = STDPORT; 240 ports[1] = port_create("auto_dimmer_sub"); 241 register_interval(ports[1], DIMMER_INTERVAL); 242 for(;;) { 243 select = msg_select(2, ports); 244 if (select == 0) { 245 msg_recv(ports[0], NULL, &mode, NULL, 0); 246 switch (*mode) { 247 case DIMMER_RESET: 248 if (!a_dim_on) 249 break; 250 dimm_counter = dim_cnt; 251 if (dimm_level > 0) { 252 dimm_level =0; 253 for (i = 0; i < nfbdev; i++) 254 fbbm_set_dimmer(&fbdev[i], 0); 255 } 256 break; 257 case DIMMER_ON: 258 dimm_counter = dim_cnt; 259 dimm_level =0; 260 for (i = 0; i < nfbdev; i++) 261 fbbm_set_dimmer(&fbdev[i], dimm_level); 262 a_dim_on = 1; 263 break; 264 case DIMMER_OFF: 265 dimm_counter = dim_cnt; 266 dimm_level =0; 267 for (i = 0; i < nfbdev; i++) 268 fbbm_set_dimmer(&fbdev[i], dimm_level); 269 a_dim_on = 0; 270 break; 271 } 272 } else { 273 msg_recv(ports[1], NULL, NULL, NULL, 0); 274 if (a_dim_on && (dimm_counter-- <= 0)) { 275 if (dimm_level < 3) { 276 dimm_level++; 277 } 278 for (i = 0; i < nfbdev; i++) 279 fbbm_set_dimmer(&fbdev[i], dimm_level); 280 dimm_counter = dim_cnt; 281 } 282 } 283 } 284 } 285 286 rst_dimmer_cnt() 287 { 288 register int diff; 289 static unsigned last_time; 290 extern unsigned sys_time; 291 int mode = DIMMER_RESET; 292 293 diff = sys_time - last_time; 294 if (diff > DIMMER_INTERVAL*HZ || diff < 0) { 295 dimmer(DIMMER_RESET); 296 last_time = sys_time; 297 } 298 } 299 300 auto_dimmer_on() 301 { 302 dimmer(DIMMER_ON); 303 } 304 305 auto_dimmer_off() 306 { 307 dimmer(DIMMER_OFF); 308 } 309 310 dimmer(mode) 311 int mode; 312 { 313 if (dimmer_stdport) 314 msg_send(dimmer_stdport, 0, &mode, sizeof(mode), 0); 315 } 316 #else /* IPC_MRX */ 317 318 static int dimmer_counter = DIM_CNT_DFLT; 319 static int dim_level = 0; 320 321 #ifdef CPU_SINGLE 322 auto_dimmer() 323 { 324 register int s, i; 325 326 s = spl4(); 327 if (a_dim_on && (dimmer_counter-- <= 0)) { 328 if (dim_level < 3) 329 dim_level++; 330 for (i = 0; i < nfbdev; i++) 331 fbbm_set_dimmer(&fbdev[i], dim_level); 332 dimmer_counter = dim_cnt; 333 } 334 splx(s); 335 timeout(auto_dimmer, (caddr_t) 0, 60 * hz); 336 } 337 #endif 338 339 rst_dimmer_cnt() 340 { 341 register int s, i; 342 343 if (!a_dim_on) 344 return; 345 #ifdef CPU_SINGLE 346 s = spl4(); 347 #endif 348 dimmer_counter = dim_cnt; 349 350 if (dim_level > 0) { 351 dim_level =0; 352 for (i = 0; i < nfbdev; i++) 353 fbbm_set_dimmer(&fbdev[i], 0); 354 } 355 splx(s); 356 } 357 358 auto_dimmer_on() 359 { 360 register int s, i; 361 362 #ifdef CPU_SINGLE 363 s = spl4(); 364 #endif 365 dimmer_counter = dim_cnt; 366 dim_level =0; 367 for (i = 0; i < nfbdev; i++) 368 fbbm_set_dimmer(&fbdev[i], dim_level); 369 a_dim_on = 1; 370 splx(s); 371 } 372 373 auto_dimmer_off() 374 { 375 register int s, i; 376 377 #ifdef CPU_SINGLE 378 s = spl4(); 379 #endif 380 dimmer_counter = dim_cnt; 381 dim_level =0; 382 for (i = 0; i < nfbdev; i++) 383 fbbm_set_dimmer(&fbdev[i], dim_level); 384 a_dim_on = 0; 385 splx(s); 386 } 387 #endif /* IPC_MRX */ 388 /* 389 * The routine `_putc(sp, c)' only prints a character c with the cursor 390 * attributes by using `copy_char(x, y, c, attributes)'. 391 * And when IRM (terminal insertion-replacement mode) is set, the characters 392 * righthand side of the cursor are shifted right and lost when they passed 393 * beyond the right margin. 394 * The position is specified by the sp pointer of the structure SCREEN. 395 * 396 */ 397 static 398 _putc(sp, c, kanji) 399 register SCREEN *sp; 400 unsigned int c; 401 { 402 if (sp->s_term_mode & IRM) { 403 vt_flush(&(sp->s_csr)); 404 move_chars(sp->s_csr.csr_x, sp->s_csr.csr_y, 405 rit_m - sp->s_csr.csr_x - ((kanji)? 1: 0), 406 sp->s_csr.csr_x + ((kanji) ? 2: 1)); 407 copy_char(sp, c, kanji); 408 } 409 if (fp) { 410 fbuf[fp++] = c; 411 fpn += kanji + 1; 412 } else { 413 fbuf[fp++] = c; 414 fpp = sp->s_csr.csr_p; 415 fpa = sp->s_csr.csr_attributes; 416 fpn = kanji + 1; 417 } 418 } 419 420 /* 421 * Scroll up and down in the scroll region. 422 * New oriented line must be cleared with terminal mode, that is whether 423 * the screen is reverse mode or not. 424 */ 425 scroll_up(top, bottom, revsw, fcol, bcol) 426 int top; 427 int bottom; 428 int revsw; 429 int fcol; 430 int bcol; 431 { 432 move_lines(top + 1, bottom - top, top); 433 clear_lines(bottom, 1, revsw, fcol, bcol); 434 } 435 436 scroll_down(top, bottom, revsw, fcol, bcol) 437 int top; 438 int bottom; 439 int revsw; 440 int fcol; 441 int bcol; 442 { 443 move_lines(top, bottom - top, top + 1); 444 clear_lines(top, 1, revsw, fcol, bcol); 445 } 446 447 /* 448 * Back space 449 * back_space(sp) moves cursor next to left at current cursor position. 450 * The cursor can not move beyond left or right margin. 451 */ 452 back_space(sp) 453 register SCREEN *sp; 454 { 455 register struct cursor *spc = &sp->s_csr; 456 457 cursor_off(); 458 if (spc->csr_x > LFT_M) { 459 spc->csr_x -= 1; 460 spc->csr_p.x -= char_w; 461 } 462 cursor_on(&spc->csr_p); 463 } 464 465 /* 466 * Tab stop 467 * next_tab_stop(sp) moves cursor to next tab stop. 468 */ 469 next_tab_stop(sp) 470 register SCREEN *sp; 471 { 472 register int i; 473 474 cursor_off(); 475 for (i = sp->s_csr.csr_x + 1; i < rit_m; i++) 476 if (sp->s_tab_pos[i] == 1) 477 break; 478 sp->s_csr.csr_x = MIN(i, rit_m); 479 sp->s_csr.csr_p.x = (sp->s_csr.csr_x - 1) * char_w + x_ofst; 480 cursor_on(&sp->s_csr.csr_p); 481 } 482 483 /* 484 * Carriage return 485 * carriage_ret(sp) moves cursor at beginning of the current line. 486 */ 487 carriage_ret(sp) 488 register SCREEN *sp; 489 { 490 cursor_off(); 491 sp->s_csr.csr_x = LFT_M; 492 sp->s_csr.csr_p.x = x_ofst; 493 cursor_on(&sp->s_csr.csr_p); 494 } 495 496 /* 497 * Bell 498 */ 499 static 500 bell() 501 { 502 #ifdef news1800 503 static int port; 504 505 if (port == 0) 506 port = port_create("port_cons_bell"); 507 kbd_ioctl(port, KIOCBELL, &bell_len); 508 #else 509 kbd_ioctl(SCC_KEYBOARD, KIOCBELL, &bell_len); 510 #endif 511 return (0); 512 } 513 514 int 515 Putchar(c, eob) 516 unsigned int c; 517 { 518 register SCREEN *sp = &screen; 519 unsigned int sftjis_to_jis(); 520 521 c &= 0xff; 522 523 if (eob) { 524 vt_flush(&(sp->s_csr)); 525 return(0); 526 } 527 528 if (c == 0x1b) { /* c == esc */ 529 vt_flush(&(sp->s_csr)); 530 recover(sp); 531 sp->s_current_stat |= ESCAPE; 532 return; 533 } else if (sp->s_current_stat & ESCAPE) { 534 (*sp->s_esc_handler)(sp, c); 535 return; 536 } else if (sp->s_current_stat & SKANJI) { 537 c = sftjis_to_jis(first_code, c); 538 if (sp->s_current_stat & JKANJI) { 539 addch(sp, c); 540 } else { 541 sp->s_current_stat |= JKANJI; 542 addch(sp, c); 543 sp->s_current_stat &= ~JKANJI; 544 } 545 sp->s_current_stat &= ~SKANJI; 546 goto set_csr; 547 } else if (sp->s_current_stat & EKANJI) { 548 c = (c & 0x7f) | (first_code << 8); 549 if (sp->s_current_stat & JKANJI) { 550 addch(sp, c); 551 } else { 552 sp->s_current_stat |= JKANJI; 553 addch(sp, c); 554 sp->s_current_stat &= ~JKANJI; 555 } 556 sp->s_current_stat &= ~EKANJI; 557 goto set_csr; 558 } else if (sp->s_current_stat & JKANJI) { 559 jiskanji(sp, c); 560 goto set_csr; 561 } else if (sp->s_current_stat & EKANA) { 562 sp->s_current_stat &= ~EKANA; 563 addch(sp, c); 564 goto set_csr; 565 } 566 if (c < 0x20) { /* control code */ 567 vt_flush(&(sp->s_csr)); 568 switch (c) { 569 case 0x00: /* ignore */ 570 break; 571 case 0x07: /* bell */ 572 bell(); 573 break; 574 case 0x08: /* back space */ 575 back_space(sp); 576 break; 577 case 0x09: /* tabulation */ 578 next_tab_stop(sp); 579 break; 580 case 0x0a: /* line feed */ 581 case 0x0b: /* vertical feed */ 582 case 0x0c: /* form feed */ 583 esc_index(sp); 584 break; 585 case 0x0d: /* carriage return */ 586 carriage_ret(sp); 587 break; 588 case 0x0e: /* shift out */ 589 break; 590 case 0x0f: /* shift in */ 591 break; 592 case 0x11: /* xon */ 593 break; 594 case 0x13: /* xoff */ 595 break; 596 case 0x18: /* cancel */ 597 sp->s_current_stat &= ~ESCAPE; 598 break; 599 case 0x1b: /* escape */ 600 /* NOT REACHED */ 601 recover(sp); 602 sp->s_current_stat |= ESCAPE; 603 break; 604 case 0x7f: /* delete */ 605 break; 606 607 default: 608 break; 609 } 610 } else { 611 switch (tmode) { 612 #ifdef KM_SJIS 613 case KM_SJIS: 614 if ((c >= JVR1S && c <= JVR1E) || 615 (c >= JVR2S && c <= JVR2E)) { 616 sp->s_current_stat |= SKANJI; 617 first_code = c; 618 } 619 else 620 addch(sp, c); 621 break; 622 #endif 623 #ifdef KM_EUC 624 case KM_EUC: 625 if (c >= CS1S && c <= CS1E) { 626 sp->s_current_stat |= EKANJI; 627 first_code = c & 0x7f; 628 } 629 else if (c == SS2) 630 sp->s_current_stat |= EKANA; 631 else 632 addch(sp, c); 633 break; 634 #endif 635 #ifdef KM_JIS 636 case KM_JIS: 637 #endif 638 #ifdef KM_ASCII 639 case KM_ASCII: 640 #endif 641 default: 642 addch(sp, c); 643 } 644 } 645 646 set_csr: 647 cursor_on(&sp->s_csr.csr_p); 648 /* altered */ 649 return ; 650 } 651 652 /* 653 * A printable character is printed in this routine by using 654 * the routine `_putc()'. 655 * Anyway, a character is printed in replacement mode or insertion 656 * mode and if the terminal is autowrap then it takes place wrapping 657 * and if cursor is bottom margin of the scroll region then it takes 658 * place scroll up. 659 * The escape sequence handling is another routine. 660 * 661 */ 662 addch(sp, c) 663 register SCREEN *sp; 664 unsigned int c; 665 { 666 register struct cursor *spc = &(sp->s_csr); 667 register struct region *spr = &(sp->s_region); 668 669 if (spc->csr_x >= rit_m || 670 ((sp->s_current_stat & JKANJI) && (spc->csr_x >= rit_m - 1))) { 671 vt_flush(spc); 672 if (sp->s_term_mode & DECAWM) { 673 if ((sp->s_current_stat & WRAP) || (spc->csr_x == rit_m 674 && sp->s_current_stat & JKANJI)) { 675 if (spc->csr_y == spr->btm_margin) { 676 cursor_off(); 677 scroll_up(spr->top_margin, 678 spr->btm_margin, 679 sp->s_term_mode & DECSCNM, 680 sp->s_plane, sp->s_bgcol); 681 cursor_on(&(spc->csr_p)); 682 } else if (spc->csr_y < btm_m) { 683 spc->csr_y += 1; 684 spc->csr_p.y += char_h; 685 } 686 spc->csr_x = LFT_M; 687 spc->csr_p.x = x_ofst; 688 addch(sp, c); 689 return; 690 } 691 sp->s_current_stat |= WRAP; 692 } 693 if (sp->s_current_stat & JKANJI) { 694 if (spc->csr_x != rit_m) { 695 _putc(sp, c, 1); 696 } 697 } else { 698 _putc(sp, c, 0); 699 } 700 if (spc->csr_x < rit_m) { 701 spc->csr_x += 1; 702 spc->csr_p.x += char_w; 703 } 704 705 return ; 706 } 707 if (sp->s_current_stat & JKANJI) { 708 _putc(sp, c, 1); 709 spc->csr_x++; 710 spc->csr_p.x += char_w; 711 } else { 712 _putc(sp, c, 0); 713 } 714 715 spc->csr_x++; /* altered */ 716 spc->csr_p.x += char_w; 717 718 sp->s_current_stat &= ~WRAP; 719 return ; 720 } 721