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: vt100esc.c,v 4.300 91/06/09 06:14:59 root Rel41 $ SONY 11 * 12 * @(#)vt100esc.c 7.6 (Berkeley) 05/30/93 13 */ 14 15 /* 16 * vt100 escape sequence handler 17 */ 18 19 #ifdef IPC_MRX 20 #include "../../h/param.h" 21 #include "../../h/systm.h" 22 #include "../../iop/framebuf.h" 23 #else 24 #include <sys/param.h> 25 #include <sys/systm.h> 26 #include <news3400/iop/framebuf.h> 27 #endif 28 29 #include <news3400/bm/vt100.h> 30 #include <news3400/bm/bitmapif.h> 31 32 #include <news3400/fb/fbdefs.h> 33 34 #ifdef IPC_MRX 35 #include "../../iop/kbreg.h" 36 #include "../../iop/keyboard.h" 37 #else 38 #include <news3400/iop/kbreg.h> 39 #include <news3400/iop/keyboard.h> 40 #endif 41 42 #if CPU_SINGLE 43 #include <news3400/sio/scc.h> 44 #endif 45 46 #ifdef IPC_MRX 47 #include "config.h" 48 #define kbd_ioctl(chan, cmd, argp) { \ 49 if (kb_ioctl) \ 50 (*kb_ioctl)(chan, cmd, argp); \ 51 } 52 #endif 53 54 /* 55 * escape sequece functions 56 */ 57 int esc_csi(); 58 int esc_csi_ansi(); 59 int esc_csi_dec(); 60 int esc_store_csr(); 61 int esc_restore_csr(); 62 int esc_index(); 63 int esc_next_line(); 64 int esc_tab_set(); 65 int esc_rev_index(); 66 int esc_numeric_kpad(); 67 int esc_application_kpad(); 68 int esc_line_size(); 69 int esc_char_setr(); 70 int esc_char_setl(); 71 int esc_kanji_set(); 72 int esc_parm_set(); 73 int esc_pf_define(); 74 int esc_ignore(); 75 76 struct esc_sequence esc_seq_table[] = { 77 {'[', "ABCDfgHhJKLlMmnPr", esc_csi}, 78 {'7', "", esc_store_csr}, 79 {'8', "", esc_restore_csr}, 80 {'D', "", esc_index}, 81 {'E', "", esc_next_line}, 82 {'H', "", esc_tab_set}, 83 {'M', "", esc_rev_index}, 84 {'=', "", esc_application_kpad}, 85 {'>', "", esc_numeric_kpad}, 86 {'#', "34568", esc_line_size}, 87 {'(', "0ABJH", esc_char_setr}, 88 {')', "0AB", esc_char_setl}, 89 {'$', "B@", esc_kanji_set}, 90 {'~', "fcpsomdbDiGCBTtE", esc_parm_set}, 91 {'P', "pPZiI", esc_pf_define}, 92 {'\0', "", esc_ignore}, 93 }; 94 95 struct key_pad key_pad[] = { 96 { '0', 'p' }, /* 0 */ 97 { '1', 'q' }, /* 1 */ 98 { '2', 'r' }, /* 2 */ 99 { '3', 's' }, /* 3 */ 100 { '4', 't' }, /* 4 */ 101 { '5', 'u' }, /* 5 */ 102 { '6', 'v' }, /* 6 */ 103 { '7', 'w' }, /* 7 */ 104 { '8', 'x' }, /* 8 */ 105 { '9', 'y' }, /* 9 */ 106 { '.', 'n' }, /* period */ 107 { '-', 'm' }, /* minus */ 108 { '+', 'k' }, /* plus */ 109 { ',', 'l' }, /* comma */ 110 { '\n', 'M' }, /* enter */ 111 { 'A', 'A' }, /* cursor up */ 112 { 'B', 'B' }, /* cursor down */ 113 { 'C', 'C' }, /* cursor right */ 114 { 'D', 'D' }, /* cursor left */ 115 { '\0', '\0' } /* */ 116 }; 117 118 static char esc_buf[ESC_BUF_SIZ]; 119 static char *esc_bp = esc_buf; 120 extern char c_pos_mess[]; 121 122 static change_csr_key_pad(), change_aux_key_pad(), itoa(); 123 124 Key_string key_str; 125 Pfk_string pfk_str; 126 127 unsigned int first_jcode; 128 129 /* 130 * put out jis-code kanji 131 */ 132 jiskanji(sp, c) 133 register SCREEN *sp; 134 register unsigned int c; 135 { 136 if (first_jcode) { 137 addch(sp, c | (first_jcode << 8)); 138 first_jcode = 0; 139 } else { 140 first_jcode = c; 141 } 142 } 143 144 /* 145 * This routine is the command analiser using second character. 146 * If a command has found then switch to particular escape handling 147 * routine, and directly called by mother routine. 148 * The arguments are passed through the routine. 149 */ 150 esc_top_level(sp, c) 151 register SCREEN *sp; 152 char c; 153 { 154 register struct esc_sequence *estp; 155 156 for (estp = esc_seq_table; estp->command ; estp++) { 157 if (estp->command == c) { 158 /* command found */ 159 sp->s_estp = estp; 160 if (*estp->terminators == '\0') { 161 (*estp->esc_func)(sp); 162 sp->s_current_stat &= ~ESCAPE; 163 } else { 164 sp->s_esc_handler = estp->esc_func; 165 } 166 return; 167 } 168 } 169 sp->s_current_stat &= ~ESCAPE; 170 } 171 172 /* 173 * Undo the ESCAPE flag, escape buffer 174 * and the esc_handler routine 175 * This routine has to be called when escape sequence has started. 176 */ 177 recover(sp) 178 register SCREEN *sp; 179 { 180 register int *ip = (int *) esc_buf; 181 register int *sup = (int *) (esc_buf + ESC_BUF_SIZ); 182 183 sp->s_current_stat &= ~ESCAPE; 184 sp->s_esc_handler = esc_top_level; 185 while (ip < sup) 186 *ip++ = 0; 187 esc_bp = esc_buf; 188 } 189 190 /* 191 * This routine in_str(c, string) returns 192 * if string contains c then TRUE (1) else FALSE (0) 193 */ 194 in_str(c, string) 195 char c; 196 register char *string; 197 { 198 while(*string) 199 if (c == *string++) 200 return(TRUE); 201 return(FALSE); 202 } 203 204 /* 205 * Control sequence introducer (CSI) 206 * Which begins `^[[' and terminates one of `ABCDfgHhJKLlMmPr' 207 */ 208 esc_csi(sp, c) 209 register SCREEN *sp; 210 unsigned int c; 211 { 212 static int bufc = 0; 213 214 if (in_str(c, sp->s_estp->terminators)) { 215 esc_csi_ansi(sp, esc_bp, c); 216 sp->s_current_stat &= ~ESCAPE; 217 bufc = 0; 218 return; 219 } 220 /* buffering arguments */ 221 if (bufc < ESC_BUF_SIZ) { 222 if (c >= '0' && c <= '9') { 223 *esc_bp = *esc_bp *10 + (c - '0'); 224 } else if (c == ';') { 225 esc_bp++; 226 bufc++; 227 } else if (c == '?') { 228 if (esc_bp == esc_buf) { 229 sp->s_esc_handler = esc_csi_dec; 230 } else { 231 esc_buf[0] = INVALID; 232 } 233 } else { 234 sp->s_current_stat &= ~ESCAPE; 235 bufc = 0; 236 } 237 } 238 } 239 240 #ifdef IPC_MRX 241 #define SCC_KEYBOARD 0 242 #endif 243 244 /* 245 * Ansi standard csi handler 246 */ 247 esc_csi_ansi(sp, esc_bp, terminator) 248 register SCREEN *sp; 249 char *esc_bp; 250 char terminator; 251 { 252 register char *cp = esc_buf; 253 register struct cursor *spc = &sp->s_csr; 254 register char *p; 255 register int i; 256 257 if (*cp == INVALID) 258 return; 259 260 cursor_off(); 261 switch (terminator) { 262 case 'A': /* CUU */ 263 if (spc->csr_y < sp->s_region.top_margin) { 264 spc->csr_y = max(spc->csr_y - max(*cp, 1) 265 ,TOP_M); 266 } else { 267 spc->csr_y = max(spc->csr_y - max(*cp, 1) 268 ,sp->s_region.top_margin); 269 } 270 spc->csr_p.y = (spc->csr_y - 1) * char_h + y_ofst; 271 sp->s_current_stat &= ~WRAP; 272 break; 273 case 'B': /* CUD */ 274 if (spc->csr_y > sp->s_region.btm_margin) { 275 spc->csr_y = min(spc->csr_y + max(*cp, 1) 276 ,btm_m); 277 } else { 278 spc->csr_y = min(spc->csr_y + max(*cp, 1) 279 ,sp->s_region.btm_margin); 280 } 281 spc->csr_p.y = (spc->csr_y - 1) * char_h + y_ofst; 282 sp->s_current_stat &= ~WRAP; 283 break; 284 case 'C': /* CUF */ 285 spc->csr_x = min(spc->csr_x + max(*cp, 1), rit_m); 286 spc->csr_p.x = (spc->csr_x - 1) * char_w + x_ofst; 287 sp->s_current_stat &= ~WRAP; 288 break; 289 case 'D': /* CUB */ 290 spc->csr_x = max(spc->csr_x - max(*cp, 1), LFT_M); 291 spc->csr_p.x = (spc->csr_x - 1) * char_w + x_ofst; 292 sp->s_current_stat &= ~WRAP; 293 break; 294 case 'g': /* TBC */ 295 switch (*cp) { 296 case 0: 297 sp->s_tab_pos[spc->csr_x] = 0; 298 break; 299 case 3: 300 for (i = 0; i <= rit_m; i++) 301 sp->s_tab_pos[i] = 0; 302 break; 303 default: 304 break; 305 } 306 break; 307 case 'f': /* HVP */ 308 case 'H': /* CUP same as HVP */ 309 csr_pos(sp, cp[1], cp[0]); 310 sp->s_current_stat &= ~WRAP; 311 break; 312 case 'J': /* ED */ 313 erase_disp(sp, cp[0]); 314 sp->s_current_stat &= ~WRAP; 315 break; 316 case 'K': /* EL */ 317 erase_line(sp, cp[0]); 318 sp->s_current_stat &= ~WRAP; 319 break; 320 case 'L': /* IL */ 321 insert_line(sp, cp[0]); 322 break; 323 case 'M': /* DL */ 324 delete_line(sp, cp[0]); 325 break; 326 case 'P': /* DCH */ 327 delete_char(sp, cp[0]); 328 sp->s_current_stat &= ~WRAP; 329 break; 330 case 'r': /* DECSTBM */ 331 cp[2] = max(cp[0] == 0 ? TOP_M: cp[0], TOP_M); 332 cp[3] = min(cp[1] == 0 ? btm_m: cp[1], btm_m); 333 if (cp[2] >= cp[3]) 334 break; 335 336 sp->s_region.top_margin = cp[2]; 337 sp->s_region.btm_margin = cp[3]; 338 339 spc->csr_x = LFT_M; 340 spc->csr_p.x = x_ofst; 341 if (sp->s_term_mode & DECOM) { 342 spc->csr_y = sp->s_region.top_margin; 343 spc->csr_p.y = (spc->csr_y - 1) * char_h + y_ofst; 344 } else { 345 spc->csr_y = TOP_M; 346 spc->csr_p.y = y_ofst; 347 } 348 break; 349 case 'm': /* CRA */ 350 while (cp <= esc_bp) { 351 switch (*cp++) { 352 case 0: 353 spc->csr_attributes &= NORMALM; 354 if (sp->s_term_mode & DECSCNM) { 355 fcolor = sp->s_bgcol; 356 bcolor = sp->s_plane; 357 } 358 else { 359 fcolor = sp->s_plane; 360 bcolor = sp->s_bgcol; 361 } 362 break; 363 case 1: /* bold */ 364 spc->csr_attributes |= BOLD; 365 break; 366 case 4: /* under score */ 367 spc->csr_attributes |= USCORE; 368 break; 369 case 5: /* blinking */ 370 spc->csr_attributes |= BLINK; 371 break; 372 case 7: /* reverse */ 373 spc->csr_attributes |= REVERSE; 374 if (sp->s_term_mode & DECSCNM) { 375 fcolor = sp->s_plane; 376 bcolor = sp->s_bgcol; 377 } 378 else { 379 fcolor = sp->s_bgcol; 380 bcolor = sp->s_plane; 381 } 382 break; 383 case 22: /* unbold */ 384 spc->csr_attributes &= ~BOLD; 385 break; 386 case 24: /* no under score */ 387 spc->csr_attributes &= ~USCORE; 388 break; 389 case 25: /* no blinking */ 390 spc->csr_attributes &= ~BLINK; 391 break; 392 case 27: /* re-reverse */ 393 spc->csr_attributes &= ~REVERSE; 394 if (sp->s_term_mode & DECSCNM) { 395 fcolor = sp->s_bgcol; 396 bcolor = sp->s_plane; 397 } 398 else { 399 fcolor = sp->s_plane; 400 bcolor = sp->s_bgcol; 401 } 402 break; 403 default: 404 break; 405 } 406 } 407 break; 408 case 'n': 409 while (cp <= esc_bp) { /* DSR(status request) */ 410 switch (*cp++) { 411 case 6: /* inquiry cursor position */ 412 key_str.key_string = c_pos_mess; 413 key_str.key_length = spr(c_pos_mess, 414 "\033[%d;%dR", (sp->s_term_mode & DECOM) ? 415 spc->csr_y - sp->s_region.top_margin + 1: 416 spc->csr_y, spc->csr_x); 417 kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str); 418 break; 419 default: 420 break; 421 } 422 } 423 break; 424 case 'h': /* SM */ 425 while (cp <= esc_bp) { 426 switch (*cp++) { 427 case 2: /* Keyboard Action */ 428 sp->s_term_mode |= KAM; 429 break; 430 case 4: /* Insert Replace */ 431 sp->s_term_mode |= IRM; 432 break; 433 case 12: /* Local echo disable */ 434 sp->s_term_mode |= SRM; 435 break; 436 case 20: /* Linefeed newline */ 437 sp->s_term_mode |= LNM; 438 break; 439 default: 440 break; 441 } 442 } 443 break; 444 case 'l': /* RM */ 445 while (cp <= esc_bp) { 446 switch (*cp++) { 447 case 2: /* Keyboard Action */ 448 sp->s_term_mode &= ~KAM; 449 break; 450 case 4: /* Insert Replace */ 451 sp->s_term_mode &= ~IRM; 452 break; 453 case 12: /* Local echo disable */ 454 sp->s_term_mode &= ~SRM; 455 break; 456 case 20: /* Linefeed newline */ 457 sp->s_term_mode &= ~LNM; 458 break; 459 default: 460 break; 461 } 462 } 463 break; 464 default: 465 break; 466 } 467 cursor_on(&spc->csr_p); 468 sp->s_current_stat &= ~ESCAPE; 469 } 470 471 472 /* 473 * Cursor position. 474 * csr_pos(sp, x, y) moves the cursor to (x, y). 475 */ 476 csr_pos(sp, x, y) 477 register SCREEN *sp; 478 register int x, y; 479 { 480 if (sp->s_term_mode & DECOM) { 481 sp->s_csr.csr_y = min(sp->s_region.top_margin + 482 max(y, 1) - 1, sp->s_region.btm_margin); 483 } else { 484 sp->s_csr.csr_y = min(TOP_M + max(y, 1) - 1, btm_m); 485 } 486 sp->s_csr.csr_x = max(min(x, rit_m), LFT_M); 487 sp->s_csr.csr_p.x = (sp->s_csr.csr_x -1) * char_w + x_ofst; 488 sp->s_csr.csr_p.y = (sp->s_csr.csr_y -1) * char_h + y_ofst; 489 } 490 491 492 /* 493 * Erase in display. 494 * erase_disp(sp, pn) erases display from the cursor to the end, from 495 * the beginning to the cursor or completely according to pn = 0, 1 or 2 496 * respectively. 497 */ 498 erase_disp(sp, pn) 499 register SCREEN *sp; 500 register int pn; 501 { 502 register struct cursor *spc = &sp->s_csr; 503 504 switch (pn) { 505 case 0: /* cursor to end */ 506 erase_line(sp, 0); 507 clear_lines(min(spc->csr_y + 1, btm_m), 508 btm_m - spc->csr_y, sp->s_term_mode & DECSCNM, 509 sp->s_plane, sp->s_bgcol); 510 break; 511 case 1: /* beginning to cursor */ 512 erase_line(sp, 1); 513 clear_lines(TOP_M, spc->csr_y - TOP_M, sp->s_term_mode & DECSCNM, 514 sp->s_plane, sp->s_bgcol); 515 break; 516 case 2: /* whole */ 517 clear_lines(TOP_M, btm_m - TOP_M + 1, 518 sp->s_term_mode & DECSCNM, 519 sp->s_plane, sp->s_bgcol); 520 break; 521 default: 522 break; 523 } 524 } 525 526 527 528 /* 529 * Erase in line. 530 * erase_line(sp, pn) erases line from the cursor to the end, from the 531 * beginning to the cursor or completely according to pn = 0, 1 or 2 532 * respectively. 533 */ 534 erase_line(sp, pn) 535 register SCREEN *sp; 536 register int pn; 537 { 538 register struct cursor *spc = &sp->s_csr; 539 540 switch(pn) { 541 case 0: 542 clear_chars(spc->csr_x, spc->csr_y, 543 rit_m - spc->csr_x + 1, sp->s_term_mode & DECSCNM, 544 sp->s_plane, sp->s_bgcol); 545 break; 546 case 1: 547 clear_chars(LFT_M, spc->csr_y, 548 spc->csr_x - LFT_M + 1, sp->s_term_mode & DECSCNM, 549 sp->s_plane, sp->s_bgcol); 550 break; 551 case 2: 552 clear_lines(spc->csr_y, 1, sp->s_term_mode & DECSCNM, 553 sp->s_plane, sp->s_bgcol); 554 break; 555 default: 556 break; 557 } 558 } 559 560 /* 561 * Insert line. 562 * insert_line(sp, pn) inserts pn lines in scroll region 563 */ 564 insert_line(sp, pn) 565 register SCREEN *sp; 566 register int pn; 567 { 568 register struct cursor *spc = &sp->s_csr; 569 register struct region *spr = &sp->s_region; 570 571 pn = max(pn, 1); 572 if (spc->csr_y < spr->top_margin || spc->csr_y > spr->btm_margin) 573 return; 574 if (pn <= spr->btm_margin - spc->csr_y) { 575 move_lines(spc->csr_y, spr->btm_margin - pn - spc->csr_y + 1, 576 spc->csr_y + pn); 577 } 578 clear_lines(spc->csr_y, 579 min(spc->csr_y + pn - 1, spr->btm_margin) - spc->csr_y + 1, 580 sp->s_term_mode & DECSCNM, sp->s_plane, sp->s_bgcol); 581 spc->csr_x = LFT_M; 582 spc->csr_p.x = x_ofst; 583 } 584 585 /* 586 * Delete line. 587 * delete_line(sp, pn) deletes pn lines in scroll region 588 */ 589 delete_line(sp, pn) 590 register SCREEN *sp; 591 register int pn; 592 { 593 register struct cursor *spc = &sp->s_csr; 594 register struct region *spr = &sp->s_region; 595 register int aux; 596 597 pn = max(pn, 1); 598 if (spc->csr_y < spr->top_margin || spc->csr_y > spr->btm_margin) 599 return; 600 if (pn <= spr->btm_margin - spc->csr_y) { 601 aux = spc->csr_y + pn; 602 move_lines(aux, spr->btm_margin - aux + 1, spc->csr_y); 603 } 604 aux = max(spr->btm_margin - pn + 1, spc->csr_y); 605 clear_lines(aux, spr->btm_margin - aux + 1, sp->s_term_mode & DECSCNM, 606 sp->s_plane, sp->s_bgcol); 607 spc->csr_x = LFT_M; 608 spc->csr_p.x = x_ofst; 609 } 610 611 /* 612 * Delete character. 613 * delete_char(sp, pn) deletes pn characters right side of the cursor. 614 */ 615 delete_char(sp, pn) 616 register SCREEN *sp; 617 register int pn; 618 { 619 register struct cursor *spc = &sp->s_csr; 620 register int aux; 621 622 pn = max(pn, 1); 623 if (pn < rit_m - spc->csr_x + 1) { 624 move_chars(spc->csr_x + pn, spc->csr_y, 625 rit_m - spc->csr_x - pn + 1 ,spc->csr_x); 626 } 627 aux = max(rit_m - pn + 1, spc->csr_x); 628 clear_chars(aux, spc->csr_y, rit_m - aux + 1, 629 sp->s_term_mode & DECSCNM, sp->s_plane, sp->s_bgcol); 630 } 631 632 /* 633 * This escape control sequence begins `^[[?' and ends `h' or `l' 634 */ 635 esc_csi_dec(sp, c) 636 register SCREEN *sp; 637 char c; 638 { 639 register char *cp; 640 641 if (in_str(c, sp->s_estp->terminators)) { 642 if (esc_buf[0] != INVALID) { 643 cursor_off(); 644 switch (c) { 645 case 'h': /* set mode */ 646 for (cp = esc_buf; cp <= esc_bp; cp++) { 647 switch (*cp) { 648 case 1: /* cursor key application */ 649 sp->s_term_mode |= DECCKM; 650 change_csr_key_pad(APPLIC); 651 break; 652 case 3: /* 132 column mode */ 653 sp->s_term_mode |= DECCOLM; 654 break; 655 case 4: /* jump scroll */ 656 sp->s_term_mode |= DECSCLM; 657 break; 658 case 5: /* reverse */ 659 if ((sp->s_term_mode & DECSCNM) == 0) 660 reverse_rec(sp->s_bgcol, 661 sp->s_plane); 662 sp->s_term_mode |= DECSCNM; 663 if (sp->s_csr.csr_attributes & REVERSE) 664 { 665 fcolor = sp->s_plane; 666 bcolor = sp->s_bgcol; 667 } else { 668 fcolor = sp->s_bgcol; 669 bcolor = sp->s_plane; 670 } 671 break; 672 case 6: /* origin */ 673 sp->s_term_mode |= DECOM; 674 sp->s_csr.csr_x = LFT_M; 675 sp->s_csr.csr_y = 676 sp->s_region.top_margin; 677 sp->s_csr.csr_p.x = x_ofst; 678 sp->s_csr.csr_p.y = 679 (sp->s_csr.csr_y - 1) * char_h + 680 y_ofst; 681 break; 682 case 7: /* auto wrap */ 683 sp->s_term_mode |= DECAWM; 684 break; 685 case 8: /* auto repeat */ 686 if ((sp->s_term_mode & DECARM) == 0) { 687 kbd_ioctl(SCC_KEYBOARD, KIOCREPT, 688 (int *)0); 689 } 690 sp->s_term_mode |= DECARM; 691 break; 692 case 25: /* cursor active */ 693 sp->s_term_mode |= DECCSR_ACTV; 694 break; 695 default: 696 break; 697 } 698 } 699 break; 700 case 'l': /* reset mode */ 701 for (cp = esc_buf; cp <= esc_bp; cp++) { 702 switch (*cp) { 703 case 1: /* cursor key application */ 704 sp->s_term_mode &= ~DECCKM; 705 change_csr_key_pad(NUMERIC); 706 break; 707 case 3: /* 132 column mode */ 708 sp->s_term_mode &= ~DECCOLM; 709 break; 710 case 4: /* jump scroll */ 711 sp->s_term_mode &= ~DECSCLM; 712 break; 713 case 5: /* reverse */ 714 if (sp->s_term_mode & DECSCNM) 715 reverse_rec(sp->s_plane, 716 sp->s_bgcol); 717 sp->s_term_mode &= ~DECSCNM; 718 if (sp->s_csr.csr_attributes & REVERSE) 719 { 720 fcolor = sp->s_bgcol; 721 bcolor = sp->s_plane; 722 } else { 723 fcolor = sp->s_plane; 724 bcolor = sp->s_bgcol; 725 } 726 break; 727 case 6: /* origin */ 728 sp->s_term_mode &= ~DECOM; 729 sp->s_csr.csr_x = LFT_M; 730 sp->s_csr.csr_y = TOP_M; 731 sp->s_csr.csr_p.x = x_ofst; 732 sp->s_csr.csr_p.y = y_ofst; 733 break; 734 case 7: /* auto wrap */ 735 sp->s_term_mode &= ~DECAWM; 736 break; 737 case 8: /* auto repeat */ 738 if (sp->s_term_mode & DECARM) { 739 kbd_ioctl(SCC_KEYBOARD, KIOCNRPT, 740 (int *) 0); 741 } 742 sp->s_term_mode &= ~DECARM; 743 break; 744 case 25: /* cursor non-active */ 745 sp->s_term_mode &= ~DECCSR_ACTV; 746 break; 747 default: 748 break; 749 } 750 } 751 break; 752 default: 753 break; 754 } 755 cursor_on(&sp->s_csr.csr_p); 756 } 757 sp->s_current_stat &= ~ESCAPE; 758 } else { /* buffering arguments */ 759 if (c >= '0' && c <= '9') { 760 *esc_bp = *esc_bp * 10 + (c - '0'); 761 } else if (c == ';') { 762 esc_bp++; 763 } else if (c == '?') { 764 esc_buf[0] = INVALID; 765 } else { 766 sp->s_current_stat &= ~ESCAPE; 767 } 768 } 769 } 770 771 /* 772 * changes cursor key pad to ansi_ctl 773 */ 774 static 775 change_csr_key_pad(applic) 776 register int applic; 777 { 778 char pad[4]; 779 register Pfk_string *pfk = &pfk_str; 780 register Key_string *kys = &pfk_str.pfk_string; 781 register struct key_pad *kpd; 782 register int i; 783 784 kpd = &key_pad[UP-N0]; 785 pad[0] = '\033'; 786 pad[1] = (applic) ? 'O': '['; 787 for (i = UP; i <= LEFT; i++) { 788 pfk->pfk_num = i; 789 kys->key_length = (applic) ? 3: 3; 790 pad[2] = (applic) ? kpd->kpd_applic: kpd->kpd_numeric; 791 kys->key_string = pad; 792 kpd++; 793 pfk->pfk_shift = PF_NORMAL; 794 kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk); 795 pfk->pfk_shift = PF_SHIFT; 796 kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk); 797 } 798 } 799 800 extern struct cursor inner_buf_csr; 801 extern int inner_buf_tstat; 802 /* 803 * Store cursor position and attributes. 804 * The SCREEN structure is stored inner structure. 805 */ 806 esc_store_csr(sp) 807 register SCREEN *sp; 808 { 809 inner_buf_csr = sp->s_csr; 810 inner_buf_tstat = (DECOM|DECAWM) & sp->s_term_mode; 811 } 812 813 /* 814 * Restore cursor position and attributes. 815 * The SCREEN structure is restored from inner structure. 816 * Prevail error from unexpected use of this command, inner structure 817 * must be initialized. 818 */ 819 esc_restore_csr(sp) 820 register SCREEN *sp; 821 { 822 cursor_off(); 823 sp->s_csr = inner_buf_csr; 824 sp->s_term_mode = (sp->s_term_mode & ~(DECOM|DECAWM)) | inner_buf_tstat; 825 cursor_on(&sp->s_csr.csr_p); 826 } 827 828 /* 829 * index() 830 * esc_index(sp) moves the cursor down if the cursor is not at 831 * bottom margin. If the cursor is at the bottom margin then 832 * scroll up. 833 */ 834 esc_index(sp) 835 register SCREEN *sp; 836 { 837 cursor_off(); 838 if (sp->s_csr.csr_y == sp->s_region.btm_margin) 839 scroll_up(sp->s_region.top_margin, 840 sp->s_region.btm_margin, sp->s_term_mode & DECSCNM, 841 sp->s_plane, sp->s_bgcol); 842 else { 843 if (sp->s_csr.csr_y < btm_m) { 844 sp->s_csr.csr_y += 1; 845 sp->s_csr.csr_p.y += char_h; 846 } 847 } 848 sp->s_current_stat &= ~WRAP; 849 cursor_on(&sp->s_csr.csr_p); 850 } 851 852 /* 853 * next line 854 * esc_next_line(sp) moves the cursor down like index but the cursor 855 * position is the beginning of the next line. 856 */ 857 esc_next_line(sp) 858 register SCREEN *sp; 859 { 860 sp->s_csr.csr_x = LFT_M; 861 sp->s_csr.csr_p.x = x_ofst; 862 esc_index(sp); 863 } 864 865 /* 866 * tabulation set 867 * esc_tab_set(sp) sets tabulation stop at the current cursor point. 868 */ 869 esc_tab_set(sp) 870 register SCREEN *sp; 871 { 872 sp->s_tab_pos[sp->s_csr.csr_x] = 1; 873 } 874 875 /* 876 * reverse index 877 * esc_rev_index(sp) moves the cursor up if the cursor is not at the top 878 * margin. If the cursor is at the top margin then the screen takes place 879 * scroll down. 880 */ 881 esc_rev_index(sp) 882 register SCREEN *sp; 883 { 884 cursor_off(); 885 if (sp->s_csr.csr_y == sp->s_region.top_margin) 886 scroll_down(sp->s_region.top_margin, 887 sp->s_region.btm_margin, sp->s_term_mode & DECSCNM, 888 sp->s_plane, sp->s_bgcol); 889 else { 890 if (sp->s_csr.csr_y > TOP_M) { 891 sp->s_csr.csr_y -= 1; 892 sp->s_csr.csr_p.y -= char_h; 893 } 894 } 895 sp->s_current_stat &= ~WRAP; 896 cursor_on(&sp->s_csr.csr_p); 897 } 898 899 /* 900 * numeric key pad 901 * esc_numeric_kpad(sp) changes key pad of cursor to numeric one. 902 * This sequence is used in vi. 903 * currently not supported 904 */ 905 esc_numeric_kpad(sp) 906 register SCREEN *sp; 907 { 908 change_aux_key_pad(NUMERIC); 909 sp->s_current_stat &= ~ESCAPE; 910 } 911 912 /* 913 * application key pad 914 * esc_application_kpad(sp) changes key pad of cursor to application one. 915 * This sequence is also used in vi. 916 * currently not supported. 917 */ 918 esc_application_kpad(sp) 919 register SCREEN *sp; 920 { 921 change_aux_key_pad(APPLIC); 922 sp->s_current_stat &= ~ESCAPE; 923 } 924 925 /* 926 * change auxiliary keypad 927 */ 928 static 929 change_aux_key_pad(applic) 930 register int applic; 931 { 932 char pad[4]; 933 register Pfk_string *pfk = &pfk_str; 934 register Key_string *kys = &pfk_str.pfk_string; 935 register struct key_pad *kpd; 936 register int i; 937 938 kpd = &key_pad[0]; 939 if (applic) { 940 pad[0] = '\033'; 941 pad[1] = 'O'; 942 } 943 for (i = N0; i <= NENTER; i++) { 944 945 pfk->pfk_num = i; 946 kys->key_length = (applic) ? 3: 1; 947 if (applic) { 948 pad[2] = kpd->kpd_applic; 949 } else { 950 pad[0] = kpd->kpd_numeric; 951 } 952 kys->key_string = pad; 953 kpd++; 954 pfk->pfk_shift = PF_NORMAL; 955 kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk); 956 pfk->pfk_shift = PF_SHIFT; 957 kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk); 958 } 959 if (!applic) { 960 pfk->pfk_shift = PF_SHIFT; 961 kys->key_length = 1; 962 963 pfk->pfk_num = MINUS; 964 kys->key_string = "/"; 965 kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk); 966 967 pfk->pfk_num = PLUS; 968 kys->key_string = "*"; 969 kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk); 970 971 pfk->pfk_num = COMMA; 972 kys->key_string = "="; 973 kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk); 974 } 975 } 976 977 extern struct csr_buf local_csr_buf; 978 /* 979 * change line size 980 * esc_line_size(sp, pn) changes line size. 981 * c = `3' double side double height(top half) 982 * c = `4' double side double height(bottom half) 983 * c = `5' sigle width line 984 * c = `6' double width line 985 * currently not supported 986 */ 987 esc_line_size(sp, c) 988 register SCREEN *sp; 989 char c; 990 { 991 register int i; 992 register int j; 993 int save_f, save_b; 994 995 cursor_off(); 996 switch (c) { 997 case '5': 998 local_csr_buf.csr_number = 1; 999 break; 1000 case '6': 1001 local_csr_buf.csr_number = 2; 1002 break; 1003 case '8': 1004 sp->s_region.top_margin = TOP_M; 1005 sp->s_region.btm_margin = btm_m; 1006 save_f = fcolor; 1007 save_b = bcolor; 1008 fcolor = sp->s_bgcol; 1009 bcolor = sp->s_plane; 1010 sp->s_csr.csr_p.y = y_ofst; 1011 for (i = TOP_M; i <= btm_m; i++) { 1012 sp->s_csr.csr_p.x = x_ofst; 1013 sp->s_csr.csr_y = i; 1014 for (j = LFT_M; j <= rit_m; j++) { 1015 sp->s_csr.csr_x = j; 1016 copy_char(sp, 'E', 0); 1017 sp->s_csr.csr_p.x += char_w; 1018 } 1019 sp->s_csr.csr_p.y += char_h; 1020 } 1021 sp->s_csr.csr_x = LFT_M; 1022 sp->s_csr.csr_y = TOP_M; 1023 sp->s_csr.csr_p.x = x_ofst; 1024 sp->s_csr.csr_p.y = y_ofst; 1025 fcolor = save_f; 1026 bcolor = save_b; 1027 break; 1028 default: 1029 break; 1030 } 1031 cursor_on(&sp->s_csr.csr_p); 1032 sp->s_current_stat &= ~ESCAPE; 1033 } 1034 1035 /* 1036 * character set 1037 * esc_char_setr sets which character set you use in right graphic set. 1038 * currently not supported 1039 */ 1040 esc_char_setr(sp, c) 1041 register SCREEN *sp; 1042 int c; 1043 { 1044 #if defined(IPC_MRX) || defined(CPU_SINGLE) 1045 switch (c) { 1046 case 'J': 1047 case 'H': 1048 font_jisroman(); 1049 #ifdef CPU_SINGLE 1050 font_jisroman24(); 1051 #endif 1052 sp->s_current_stat &= ~JKANJI; 1053 break; 1054 case 'B': 1055 font_ascii(); 1056 #ifdef CPU_SINGLE 1057 font_ascii24(); 1058 #endif 1059 sp->s_current_stat &= ~JKANJI; 1060 break; 1061 } 1062 #else /* IPC_MRX || CPU_SINGLE */ 1063 if (c == 'B' || c == 'J' || c == 'H') { 1064 sp->s_current_stat &= ~JKANJI; 1065 } 1066 #endif /* IPC_MRX || CPU_SINGLE */ 1067 sp->s_current_stat &= ~ESCAPE; 1068 } 1069 1070 /* 1071 * character set to left graphic set 1072 * esc_char_setl sets which character set you use in left graphic set. 1073 * currently not supported 1074 */ 1075 esc_char_setl(sp, c) 1076 register SCREEN *sp; 1077 int c; 1078 { 1079 sp->s_current_stat &= ~ESCAPE; 1080 } 1081 1082 extern tmode; 1083 extern unsigned int first_jcode; 1084 /* 1085 * character set to kanji 1086 * esc_kanji_set sets kanji 1087 */ 1088 esc_kanji_set(sp, c) 1089 register SCREEN *sp; 1090 int c; 1091 { 1092 1093 #ifdef KM_JIS 1094 if (tmode == KM_JIS && (c == 'B' || c == '@')) { 1095 sp->s_current_stat |= JKANJI; 1096 first_jcode = 0; 1097 } 1098 #endif 1099 sp->s_current_stat &= ~ESCAPE; 1100 } 1101 1102 static short parm_buf[PARM_BUF_SIZ]; 1103 static short *parm_bp = parm_buf; 1104 static int sensitive = 0; 1105 static int pval = 0; 1106 /* 1107 * terminal parameter set command 1108 * esc_parm_set(sp, c) sets terminal parameters such as font-width, 1109 * font-height, character-width, character-height, character-position, 1110 * underlind-position, screen-width, screen-height, x-offset, y-offset, 1111 * right-mergin, bottom-mergin, dimmer-count, bell-length. 1112 */ 1113 esc_parm_set(sp, c) 1114 register SCREEN *sp; 1115 register unsigned int c; 1116 { 1117 static int bufc = 0; 1118 1119 if (in_str(c, sp->s_estp->terminators)) { 1120 if (sensitive) { 1121 *parm_bp++ = pval; 1122 } else { 1123 *parm_bp++ = -1; 1124 } 1125 *parm_bp++ = -1; 1126 parm_set(sp, parm_buf, c); 1127 sp->s_current_stat &= ~ESCAPE; 1128 sensitive = pval = 0; 1129 parm_bp = parm_buf; 1130 bufc = 0; 1131 return; 1132 } 1133 /* buffering arguments */ 1134 if (bufc < PARM_BUF_SIZ) { 1135 if (c >= '0' && c <= '9') { 1136 pval = pval *10 + (c - '0'); 1137 sensitive = 1; 1138 } else if (c == ';') { 1139 if (sensitive) { 1140 *parm_bp++ = pval; 1141 } else { 1142 *parm_bp++ = -1; 1143 } 1144 sensitive = pval = 0; 1145 bufc++; 1146 } else { 1147 sp->s_current_stat &= ~ESCAPE; 1148 sensitive = pval = 0; 1149 parm_bp = parm_buf; 1150 bufc = 0; 1151 } 1152 } 1153 } 1154 1155 static char an_buf[AN_BUF_SIZ]; 1156 1157 parm_set(sp, parm, terminator) 1158 SCREEN *sp; 1159 short *parm; 1160 unsigned int terminator; 1161 { 1162 register char *bp = an_buf; 1163 register char *p; 1164 1165 switch (terminator) { 1166 case 'f': 1167 if (parm[0] >= FONT_W_MIN && parm[0] <= consfb->font_w && 1168 parm[0] < char_w) 1169 font_w = parm[0]; 1170 1171 if (parm[1] >= FONT_H_MIN && parm[1] <= consfb->font_h && 1172 parm[1] <= (char_h - ch_pos)) 1173 font_h = parm[1]; 1174 break; 1175 case 'c': 1176 if (parm[0] >= CHAR_W_MIN && parm[0] > font_w && 1177 parm[0] <= CHAR_W_MAX) 1178 char_w = parm[0]; 1179 1180 if (parm[1] >= CHAR_H_MIN && parm[1] >= (font_h + ch_pos) && 1181 parm[1] > ul_pos && parm[1] <= CHAR_H_MAX) 1182 char_h = parm[1]; 1183 1184 break; 1185 case 'p': 1186 if (parm[0] >= UL_POS_MIN && parm[0] <= UL_POS_MAX && 1187 parm[0] < char_h) { 1188 ul_pos = parm[0]; 1189 } 1190 if (parm[1] >= CH_POS_MIN && parm[1] <= CH_POS_MAX && 1191 parm[1] < (char_h - font_h)) { 1192 ch_pos = parm[1]; 1193 } 1194 break; 1195 case 's': 1196 if (parm[0] > SCR_W_MIN && parm[0] <= consfb->scr_w) 1197 scr_w = (parm[0] < char_w) ? char_w: parm[0]; 1198 if (parm[1] > SCR_H_MIN && parm[1] <= consfb->scr_h) 1199 scr_h = (parm[1] < char_h) ? char_h: parm[1]; 1200 break; 1201 case 'o': 1202 if (parm[0] >= X_OFST_MIN && parm[0] <= X_OFST_MAX) 1203 x_ofst = (parm[0] > scr_w - char_w) ? 1204 (scr_w - char_w): parm[0]; 1205 if (parm[1] >= Y_OFST_MIN && parm[1] <= Y_OFST_MAX) 1206 y_ofst = (parm[1] > scr_h - char_h) ? 1207 (scr_h - char_h): parm[1]; 1208 break; 1209 case 'm': 1210 if (parm[0] >= RIT_M_MIN) { 1211 if (parm[0] > RIT_M_MAX /* consfb->rit_m */) { 1212 parm[0] = consfb->rit_m; 1213 } 1214 rit_m = (parm[0] > (scr_w - x_ofst)/char_w) ? 1215 (scr_w - x_ofst)/char_w: parm[0]; 1216 } 1217 if (parm[1] >= BTM_M_MIN) { 1218 if (parm[1] > BTM_M_MAX /* consfb->btm_m */) { 1219 parm[1] = consfb->btm_m; 1220 } 1221 btm_m = (parm[1] > (scr_h - y_ofst)/char_h) ? 1222 (scr_h - y_ofst)/char_h: parm[1]; 1223 } 1224 break; 1225 case 'd': 1226 if (parm[0] >= DIM_CNT_MIN /* && parm[0] <= DIM_CNT_MAX */) 1227 dim_cnt = a_dim_on = parm[0]; 1228 else 1229 a_dim_on = 0; 1230 break; 1231 case 'b': 1232 if (parm[0] >= BELL_LEN_MIN && parm[0] <= BELL_LEN_MAX) 1233 bell_len = parm[0]; 1234 break; 1235 case 'D': 1236 set_default_param(); 1237 vt100init(); 1238 bitmapinit(); 1239 break; 1240 case 'i': 1241 cursor_off(); 1242 csr_pos(sp, LFT_M, TOP_M); 1243 key_str.key_string = c_pos_mess; 1244 key_str.key_length = spr(c_pos_mess, "f=(%d,%d), ", 1245 font_w, font_h); 1246 kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str); 1247 1248 key_str.key_length = spr(c_pos_mess, "c=(%d,%d), ", 1249 char_w, char_h); 1250 kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str); 1251 1252 csr_pos(sp, LFT_M, (TOP_M - 1)); 1253 key_str.key_string = c_pos_mess; 1254 key_str.key_length = spr(c_pos_mess, "p=(%d,%d), ", 1255 ul_pos, ch_pos); 1256 kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str); 1257 key_str.key_length = spr(c_pos_mess, "s=(%d,%d), ", 1258 scr_w, scr_h); 1259 kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str); 1260 1261 csr_pos(sp, LFT_M, (TOP_M - 2)); 1262 key_str.key_string = c_pos_mess; 1263 key_str.key_length = spr(c_pos_mess, "o=(%d,%d), ", 1264 x_ofst, y_ofst); 1265 kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str); 1266 key_str.key_length = spr(c_pos_mess, "m=(%d,%d)", 1267 rit_m, btm_m); 1268 kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str); 1269 1270 cursor_on(&sp->s_csr.csr_p); 1271 return; 1272 case 'G': 1273 line(parm); 1274 return; 1275 case 'C': 1276 if (parm[0] >= 0) { 1277 sp->s_plane = fbbm_get_pixel(consfb, parm[0]); 1278 } 1279 if (parm[1] >= 0) { 1280 sp->s_bgcol = fbbm_get_pixel(consfb, parm[1]); 1281 } 1282 cursor_off(); 1283 if ((sp->s_csr.csr_attributes & REVERSE) ^ 1284 (sp->s_term_mode & DECSCNM)) { 1285 fcolor = sp->s_bgcol; 1286 bcolor = sp->s_plane; 1287 } 1288 else { 1289 fcolor = sp->s_plane; 1290 bcolor = sp->s_bgcol; 1291 } 1292 cursor_on(&sp->s_csr.csr_p); 1293 return; 1294 case 'T': 1295 if (parm[0] < 0 || consfb->Mono) 1296 return; 1297 /* 1298 * what value is defined on pallet N? 1299 * put string in an_buf 1300 */ 1301 *bp++ = '\033'; 1302 *bp++ = '~'; 1303 bp += itoa(bm_pallet_read(parm[0]), 10, bp); 1304 *bp++ = 'a'; 1305 key_str.key_length = bp - an_buf; 1306 key_str.key_string = an_buf; 1307 kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str); 1308 return; 1309 case 't': 1310 if (parm[0] >= 0 && !consfb->Mono) { 1311 bm_pallet_write(parm[0], 1312 (unsigned) parm[1] << 16 1313 | (unsigned) parm[2] << 8 1314 | (unsigned) parm[3] 1315 ); 1316 } 1317 return; 1318 default: 1319 return; 1320 } 1321 if (char_w < font_w) char_w = font_w; 1322 if (char_h < font_h) char_h = font_h; 1323 if (ch_pos > char_h - font_h) { 1324 ch_pos = char_h - font_h; 1325 ul_pos = char_h - 1; 1326 } 1327 if (rit_m > (scr_w - x_ofst)/char_w) 1328 rit_m = (scr_w - x_ofst)/char_w; 1329 if (btm_m > (scr_h - y_ofst)/char_h) 1330 btm_m = (scr_h - y_ofst)/char_h; 1331 sp->s_region.top_margin = TOP_M; 1332 sp->s_region.btm_margin = btm_m; 1333 font_r1.extent.x = font_w; 1334 font_r1.extent.y = font_h; 1335 font_r2.extent.x = font_w * 2; 1336 font_r2.extent.y = font_h; 1337 font_len1 = (font_w + 0x0f)>>4; 1338 font_len2 = (font_w*2 + 0x0f)>>4; 1339 cursor_off(); 1340 char_r1.extent.x = char_w; 1341 char_r1.extent.y = char_h; 1342 char_r2.extent.x = char_w * 2; 1343 char_r2.extent.y = char_h; 1344 csr_pos(sp, sp->s_csr.csr_x, sp->s_csr.csr_y); 1345 sp->s_csr.csr_p.x = (sp->s_csr.csr_x - 1) * char_w + x_ofst; 1346 sp->s_csr.csr_p.y = (sp->s_csr.csr_y - 1) * char_h + y_ofst; 1347 cursor_on(&sp->s_csr.csr_p); 1348 } 1349 1350 /* VARARGS */ 1351 spr(s, fmt, ad, dummy) 1352 register char *s, *fmt; 1353 u_int ad; 1354 { 1355 register int b, c; 1356 register u_int *adx = &ad; 1357 char *base = s; 1358 1359 for (;;) { 1360 while ((c = *fmt++) != '%') { 1361 *s++ = c; 1362 if (c == '\0') 1363 return (s - base - 1); 1364 } 1365 1366 c = *fmt++; 1367 switch (c) { 1368 1369 case 'x': case 'X': 1370 b = 16; 1371 goto number; 1372 case 'd': case 'D': 1373 b = 10; 1374 goto number; 1375 case 'o': case 'O': 1376 b = 8; 1377 number: 1378 s += itoa(*adx, b, s); 1379 break; 1380 1381 case 'c': 1382 *s++ = *adx; 1383 break; 1384 1385 case '%': 1386 *s++ = c; 1387 break; 1388 } 1389 adx++; 1390 } 1391 } 1392 1393 static int pfn = -1; 1394 static int active_buf = 0; 1395 /* 1396 * define the programable function keys and answer back message. 1397 * the vt100 facilities do not contain this command! 1398 * command sequence is as follows: 1399 * "^[Pn|n1;n2;...;nmp" (normal mode) 1400 * or 1401 * "^[Pn|n1;n2;...;nmP" (shift mode) 1402 * or 1403 * "^[Pn|n1;n2;...;nmZ" (answer backe message) 1404 * where, `n' denotes the decimal number asigned to function key, 1405 * from `n1' to `nm' denote hexa number, finally, 1406 * `p' , `E' or `Z' tells that the sequence has terminated. 1407 * remark: 1408 * when the terminator is `Z', the function number `n' can be omitted, 1409 * and even though the number is specified, there is no affection to 1410 * the result. 1411 * 1412 * 1413 * ADDITION: 1414 * there is a question: what strings are defined in programable function 1415 * key of key-number n? 1416 * in order to anwer this question, another escape sequence has appended. 1417 * command sequence is as follows: 1418 * 1419 * "^[Pn|i" (normal mode) 1420 * or 1421 * "^[Pn|I" (shift mode) 1422 * 1423 * then the answer is 1424 * 1425 * "^[Pn|n1;n2;...;nmr" (normal mode) 1426 * or 1427 * "^[Pn|n1;n2;...;nmR" (shift mode) 1428 * 1429 */ 1430 esc_pf_define(sp, c) 1431 SCREEN *sp; 1432 unsigned int c; 1433 { 1434 static bufc = 0; 1435 1436 if (in_str(c, sp->s_estp->terminators)) { 1437 pf_define(pfn, esc_bp - esc_buf + active_buf, c); 1438 sp->s_current_stat &= ~ESCAPE; 1439 active_buf = 0; 1440 pfn = -1; 1441 bufc = 0; 1442 return; 1443 } 1444 /* buffering arguments */ 1445 if (bufc < ESC_BUF_SIZ) { 1446 if (pfn < 0) { 1447 if (c >= '0' && c <= '9') { 1448 *esc_bp = *esc_bp *10 + (c - '0'); 1449 } else if (c == '|') { 1450 pfn = *esc_bp; 1451 *esc_bp = 0; 1452 } else { 1453 sp->s_current_stat &= ~ESCAPE; 1454 active_buf = 0; 1455 pfn = -1; 1456 } 1457 } else { 1458 active_buf = 1; 1459 if (c >= '0' && c <= '9') { 1460 *esc_bp = *esc_bp * 16 + (c - '0'); 1461 } else if (c >= 'a' && c <= 'f') { 1462 *esc_bp = *esc_bp * 16 + (c - 'a' + 10); 1463 } else if (c >= 'A' && c <= 'F') { 1464 *esc_bp = *esc_bp * 16 + (c - 'A' + 10); 1465 } else if (c == ';') { 1466 esc_bp++; 1467 bufc++; 1468 } else { 1469 sp->s_current_stat &= ~ESCAPE; 1470 pfn = -1; 1471 active_buf = 0; 1472 bufc = 0; 1473 } 1474 } 1475 } else { 1476 active_buf = 0; 1477 } 1478 } 1479 1480 pf_define(pfn, length, terminator) 1481 int pfn; 1482 int length; 1483 unsigned int terminator; 1484 { 1485 register Pfk_string *pfk = &pfk_str; 1486 register Key_string *kys = &pfk_str.pfk_string; 1487 1488 if (terminator == 'Z') 1489 return; 1490 1491 if (pfn < 0 || pfn > N_PFK) 1492 return; 1493 if (terminator == 'i' || terminator == 'I') { 1494 pf_answer(pfn, terminator); 1495 return; 1496 } 1497 pfk->pfk_num = pfn ? pfn: 1; 1498 pfk->pfk_shift = (terminator == 'p') ? PF_NORMAL: PF_SHIFT; 1499 kys->key_length = length; 1500 kys->key_string = esc_buf; 1501 kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk); 1502 } 1503 1504 /* 1505 * pf_answer(pfn, terminator) 1506 * this routine answers what strings defined on pfn. 1507 */ 1508 1509 char def_seq[ESC_BUF_SIZ]; 1510 1511 pf_answer(pfn, terminator) 1512 int pfn; 1513 unsigned int terminator; 1514 { 1515 register Pfk_string *pfk = &pfk_str; 1516 register Key_string *kys = &pfk_str.pfk_string; 1517 register char *bp = an_buf; 1518 register char *p = def_seq; 1519 register int length; 1520 register int j; 1521 1522 /* 1523 * function key inquiry 1524 * get string in def_seq 1525 */ 1526 pfk->pfk_num = pfn ? pfn: 1; 1527 pfk->pfk_shift = (terminator == 'i') ? PF_NORMAL: PF_SHIFT; 1528 kys->key_length = ESC_BUF_SIZ; 1529 kys->key_string = def_seq; 1530 kbd_ioctl(SCC_KEYBOARD, KIOCGETS, pfk); 1531 length = kys->key_length; 1532 1533 /* 1534 * function key answer 1535 * put string in an_buf 1536 */ 1537 *bp++ = '\033'; 1538 *bp++ = 'P'; 1539 bp += itoa(pfn, 10, bp); 1540 *bp++ = '|'; 1541 key_str.key_length = bp - an_buf; 1542 key_str.key_string = an_buf; 1543 kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str); 1544 1545 bp = an_buf; 1546 if (length--) { 1547 bp += itoa(*p++ & 0xff, 16, bp); 1548 } 1549 while (length > 0) { 1550 for (j = 0; (j < 10) && (length-- > 0); j++) { 1551 *bp++ = ';'; 1552 bp += itoa(*p++ & 0xff, 16, bp); 1553 } 1554 key_str.key_length = bp - an_buf; 1555 kbd_ioctl(SCC_KEYBOARD, KIOCBACK, (int *)&key_str); 1556 bp = an_buf; 1557 } 1558 *bp++ = (terminator == 'i') ? 'r': 'R'; 1559 key_str.key_length = bp - an_buf; 1560 kbd_ioctl(SCC_KEYBOARD, KIOCBACK, (int *)&key_str); 1561 } 1562 1563 /* 1564 * ignore 1565 * esc_ignore(sp) is not called ordinally work. 1566 */ 1567 esc_ignore(sp) 1568 register SCREEN *sp; 1569 { 1570 sp->s_current_stat &= ~ESCAPE; 1571 } 1572 1573 static char *nmr = "0123456789abcdef"; 1574 /* 1575 * itoa 1576 * this routine converts binary to ascii decimal or hexa number 1577 * according to mod. 1578 */ 1579 static 1580 itoa(n, mod, buf) 1581 register int n; 1582 register int mod; 1583 register char *buf; 1584 { 1585 register int i = 0; 1586 register int cnt; 1587 int first = 1; 1588 int k; 1589 1590 n &= 0xffff; 1591 for (cnt = mod*mod*mod*mod*mod*mod*mod; cnt > 0; cnt /= mod) { 1592 k = n / cnt; 1593 n -= k * cnt; 1594 if (k == 0) { 1595 if (first == 0) { 1596 *buf++ = nmr[k]; 1597 i++; 1598 } 1599 } else { 1600 *buf++ = nmr[k]; 1601 i++; 1602 first = 0; 1603 } 1604 } 1605 if (first == 1) { 1606 *buf++ = '0'; 1607 i++; 1608 } 1609 return(i); 1610 } 1611