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