1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7 *
8 * %sccs.include.redist.c%
9 *
10 * from: $Hdr: vt100esc.c,v 4.300 91/06/09 06:14:59 root Rel41 $ SONY
11 *
12 * @(#)vt100esc.c 8.1 (Berkeley) 06/10/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 */
jiskanji(sp,c)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 */
esc_top_level(sp,c)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 */
recover(sp)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 */
in_str(c,string)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 */
esc_csi(sp,c)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 */
esc_csi_ansi(sp,esc_bp,terminator)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 */
csr_pos(sp,x,y)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 */
erase_disp(sp,pn)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 */
erase_line(sp,pn)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 */
insert_line(sp,pn)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 */
delete_line(sp,pn)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 */
delete_char(sp,pn)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 */
esc_csi_dec(sp,c)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
change_csr_key_pad(applic)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 */
esc_store_csr(sp)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 */
esc_restore_csr(sp)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 */
esc_index(sp)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 */
esc_next_line(sp)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 */
esc_tab_set(sp)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 */
esc_rev_index(sp)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 */
esc_numeric_kpad(sp)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 */
esc_application_kpad(sp)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
change_aux_key_pad(applic)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 */
esc_line_size(sp,c)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 */
esc_char_setr(sp,c)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 */
esc_char_setl(sp,c)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 */
esc_kanji_set(sp,c)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 */
esc_parm_set(sp,c)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
parm_set(sp,parm,terminator)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 */
spr(s,fmt,ad,dummy)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 */
esc_pf_define(sp,c)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
pf_define(pfn,length,terminator)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
pf_answer(pfn,terminator)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 */
esc_ignore(sp)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
itoa(n,mod,buf)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