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