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