1 /*
2 * Copyright (c) 1999, 2000 Hellmuth Michaelis
3 *
4 * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
5 *
6 * Copyright (c) 1992, 1993 Brian Dunford-Shore.
7 *
8 * All rights reserved.
9 *
10 * This code is derived from software contributed to Berkeley by
11 * William Jolitz and Don Ahn.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 * This product includes software developed by Hellmuth Michaelis,
24 * Brian Dunford-Shore and Joerg Wunsch.
25 * 4. The name authors may not be used to endorse or promote products
26 * derived from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
29 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
30 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
31 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
33 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
37 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*---------------------------------------------------------------------------*
41 *
42 * pcvt_out.c VT220 Terminal Emulator
43 * ---------------------------------------
44 *
45 * Last Edit-Date: [Tue Jun 5 17:27:48 2001]
46 *
47 * $FreeBSD: releng/5.3/sys/i386/isa/pcvt/pcvt_out.c 111119 2003-02-19 05:47:46Z imp $
48 *
49 *---------------------------------------------------------------------------*/
50
51 #define PCVT_INCLUDE_VT_SELATTR /* get inline function from pcvt_hdr.h */
52
53 #include <i386/isa/pcvt/pcvt_hdr.h> /* global include */
54 #include <vm/vm.h>
55 #include <vm/vm_param.h>
56 #include <vm/pmap.h>
57
58 extern u_short csd_ascii[]; /* pcvt_tbl.h */
59 extern u_short csd_supplemental[];
60
61 static void write_char (struct video_state *svsp, int attrib, int ch);
62 static void check_scroll ( struct video_state *svsp );
63 static void hp_entry ( int ch, struct video_state *svsp );
64 static void vt_coldinit ( void );
65 static void wrfkl ( int num, u_char *string, struct video_state *svsp );
66 static void writefkl ( int num, u_char *string, struct video_state *svsp );
67 static int check_scrollback ( struct video_state *svsp );
68
69 /*---------------------------------------------------------------------------*
70 * do character set transformation and write to display memory (inline)
71 *---------------------------------------------------------------------------*/
72
73 #define video (svsp->Crtat + svsp->cur_offset)
74
75 static __inline void write_char (svsp, attrib, ch)
76 struct video_state *svsp;
77 u_short attrib, ch; /* XXX inefficient interface */
78 {
79 if ((ch >= 0x20) && (ch <= 0x7f)) /* use GL if ch >= 0x20 */
80 {
81 if(!svsp->ss) /* single shift G2/G3 -> GL ? */
82 {
83 *video = attrib | (*svsp->GL)[ch-0x20];
84 }
85 else
86 {
87 *video = attrib | (*svsp->Gs)[ch-0x20];
88 svsp->ss = 0;
89 }
90 }
91 else
92 {
93 svsp->ss = 0;
94
95 if(ch >= 0x80) /* display controls C1 */
96 {
97 if(ch >= 0xA0) /* use GR if ch >= 0xA0 */
98 {
99 *video = attrib | (*svsp->GR)[ch-0xA0];
100 }
101 else
102 {
103 if(vgacs[svsp->vga_charset].secondloaded)
104 {
105 *video = attrib | ((ch-0x60) | CSH);
106 }
107 else /* use normal ibm charset for
108 control display */
109 {
110 *video = attrib | ch;
111 }
112 }
113 }
114 else /* display controls C0 */
115 {
116 if(vgacs[svsp->vga_charset].secondloaded)
117 {
118 *video = attrib | (ch | CSH);
119 }
120 else /* use normal ibm charset for control display*/
121 {
122 *video = attrib | ch;
123 }
124 }
125 }
126 }
127
128 /*---------------------------------------------------------------------------*
129 * emulator main entry
130 *---------------------------------------------------------------------------*/
131 void
132 sput (u_char *s, int kernel, int len, int page)
133 {
134 register struct video_state *svsp;
135 u_short attrib;
136 u_short ch;
137 u_short extra;
138
139 if(page >= PCVT_NSCREENS) /* failsafe */
140 page = 0;
141
142 svsp = &vs[page]; /* pointer to current screen state */
143
144 if(do_initialization) /* first time called ? */
145 vt_coldinit(); /* yes, we have to init ourselves */
146
147 if(svsp == vsp) /* on current displayed page ? */
148 {
149 cursor_pos_valid = 0; /* do not update cursor */
150
151 #if PCVT_SCREENSAVER
152 if(scrnsv_active) /* screen blanked ? */
153 pcvt_scrnsv_reset(); /* unblank NOW ! */
154 else
155 reset_screen_saver = 1; /* do it asynchronously */
156 #endif /* PCVT_SCREENSAVER */
157
158 }
159
160 attrib = kernel ? kern_attr : svsp->c_attr;
161
162 while (len-- > 0)
163 if((ch = *(s++)) > 0)
164 {
165 if(svsp->sevenbit)
166 ch &= 0x7f;
167
168 if(((ch <= 0x1f) || (ch == 0x7f)) && (svsp->transparent == 0))
169 {
170
171 /* always process control-chars in the range 0x00..0x1f, 0x7f !!! */
172
173 if(svsp->dis_fnc)
174 {
175 if(svsp->lastchar && svsp->m_awm
176 && (svsp->lastrow == svsp->row))
177 {
178 svsp->cur_offset++;
179 svsp->col = 0;
180 svsp->lastchar = 0;
181 check_scroll(svsp);
182 }
183
184 if(svsp->irm)
185 bcopy((svsp->Crtat + svsp->cur_offset),
186 (svsp->Crtat + svsp->cur_offset) + 1,
187 (((svsp->maxcol)-1) - svsp->col)*CHR);
188
189 write_char(svsp, attrib, ch);
190
191 vt_selattr(svsp);
192
193 if(svsp->col >= ((svsp->maxcol)-1)
194 && ch != 0x0a && ch != 0x0b && ch != 0x0c)
195 {
196 svsp->lastchar = 1;
197 svsp->lastrow = svsp->row;
198 }
199 else if(ch == 0x0a || ch == 0x0b || ch == 0x0c)
200 {
201 svsp->cur_offset -= svsp->col;
202 svsp->cur_offset += svsp->maxcol;
203 svsp->col = 0;
204 svsp->lastchar = 0;
205 check_scroll(svsp); /* check scroll up */
206 }
207 else
208 {
209 svsp->cur_offset++;
210 svsp->col++;
211 svsp->lastchar = 0;
212 }
213 }
214 else
215 {
216 switch(ch)
217 {
218 case 0x00: /* NUL */
219 case 0x01: /* SOH */
220 case 0x02: /* STX */
221 case 0x03: /* ETX */
222 case 0x04: /* EOT */
223 case 0x05: /* ENQ */
224 case 0x06: /* ACK */
225 break;
226
227 case 0x07: /* BEL */
228 if(svsp->bell_on)
229 sysbeep(PCVT_SYSBEEPF/1500, hz/4);
230 break;
231
232 case 0x08: /* BS */
233 if(svsp->col > 0)
234 {
235 svsp->cur_offset--;
236 svsp->col--;
237 }
238 break;
239
240 case 0x09: /* TAB */
241 while(svsp->col < ((svsp->maxcol)-1))
242 {
243 svsp->cur_offset++;
244 if(svsp->
245 tab_stops[++svsp->col])
246 break;
247 }
248 break;
249
250 case 0x0a: /* LF */
251 case 0x0b: /* VT */
252 case 0x0c: /* FF */
253 if (check_scrollback(svsp))
254 {
255 extra = (svsp->cur_offset %
256 svsp->maxcol) ?
257 svsp->col : 0;
258 bcopy(svsp->Crtat +
259 svsp->cur_offset - extra,
260 svsp->Scrollback +
261 (svsp->scr_offset *
262 svsp->maxcol),
263 svsp->maxcol * CHR);
264 }
265 if(svsp->lnm)
266 {
267 svsp->cur_offset -= svsp->col;
268 svsp->cur_offset +=
269 svsp->maxcol;
270 svsp->col = 0;
271 }
272 else
273 {
274 svsp->cur_offset +=
275 svsp->maxcol;
276 }
277 check_scroll(svsp);
278 break;
279
280 case 0x0d: /* CR */
281 svsp->cur_offset -= svsp->col;
282 svsp->col = 0;
283 break;
284
285 case 0x0e: /* SO */
286 svsp->GL = &svsp->G1;
287 break;
288
289 case 0x0f: /* SI */
290 svsp->GL = &svsp->G0;
291 break;
292
293 case 0x10: /* DLE */
294 case 0x11: /* DC1/XON */
295 case 0x12: /* DC2 */
296 case 0x13: /* DC3/XOFF */
297 case 0x14: /* DC4 */
298 case 0x15: /* NAK */
299 case 0x16: /* SYN */
300 case 0x17: /* ETB */
301 break;
302
303 case 0x18: /* CAN */
304 svsp->state = STATE_INIT;
305 clr_parms(svsp);
306 break;
307
308 case 0x19: /* EM */
309 break;
310
311 case 0x1a: /* SUB */
312 svsp->state = STATE_INIT;
313 clr_parms(svsp);
314 break;
315
316 case 0x1b: /* ESC */
317 svsp->state = STATE_ESC;
318 clr_parms(svsp);
319 break;
320
321 case 0x1c: /* FS */
322 case 0x1d: /* GS */
323 case 0x1e: /* RS */
324 case 0x1f: /* US */
325 case 0x7f: /* DEL */
326 break;
327 }
328 }
329 }
330 else
331 {
332
333 /* char range 0x20...0x73, 0x80...0xff processing */
334 /* depends on current state */
335
336 switch(svsp->state)
337 {
338 case STATE_INIT:
339 if(svsp->lastchar && svsp->m_awm &&
340 (svsp->lastrow == svsp->row))
341 {
342 svsp->cur_offset++;
343 svsp->col = 0;
344 svsp->lastchar = 0;
345
346 if (check_scrollback(svsp))
347 {
348 bcopy(svsp->Crtat +
349 svsp->cur_offset -
350 svsp->maxcol,
351 svsp->Scrollback +
352 (svsp->scr_offset *
353 svsp->maxcol),
354 svsp->maxcol * CHR);
355 }
356 check_scroll(svsp);
357 }
358
359 if(svsp->irm)
360 bcopy ((svsp->Crtat
361 + svsp->cur_offset),
362 (svsp->Crtat
363 + svsp->cur_offset) + 1,
364 (((svsp->maxcol)-1)
365 - svsp->col) * CHR);
366
367 write_char(svsp, attrib, ch);
368
369 vt_selattr(svsp);
370
371 if(svsp->col >= ((svsp->maxcol)-1))
372 {
373 svsp->lastchar = 1;
374 svsp->lastrow = svsp->row;
375 }
376 else
377 {
378 svsp->lastchar = 0;
379 svsp->cur_offset++;
380 svsp->col++;
381 }
382 break;
383
384 case STATE_ESC:
385 switch(ch)
386 {
387 case ' ': /* ESC sp family */
388 svsp->state = STATE_BLANK;
389 break;
390
391 case '#': /* ESC # family */
392 svsp->state = STATE_HASH;
393 break;
394
395 case '&': /* ESC & family (HP) */
396 if(svsp->vt_pure_mode ==
397 M_HPVT)
398 {
399 svsp->state =
400 STATE_AMPSND;
401 svsp->hp_state =
402 SHP_INIT;
403 }
404 else
405 svsp->state =
406 STATE_INIT;
407 break;
408
409 case '(': /* ESC ( family */
410 svsp->state = STATE_BROPN;
411 break;
412
413 case ')': /* ESC ) family */
414 svsp->state = STATE_BRCLO;
415 break;
416
417 case '*': /* ESC * family */
418 svsp->state = STATE_STAR;
419 break;
420
421 case '+': /* ESC + family */
422 svsp->state = STATE_PLUS;
423 break;
424
425 case '-': /* ESC - family */
426 svsp->state = STATE_MINUS;
427 break;
428
429 case '.': /* ESC . family */
430 svsp->state = STATE_DOT;
431 break;
432
433 case '/': /* ESC / family */
434 svsp->state = STATE_SLASH;
435 break;
436
437 case '7': /* SAVE CURSOR */
438 vt_sc(svsp);
439 svsp->state = STATE_INIT;
440 break;
441
442 case '8': /* RESTORE CURSOR */
443 vt_rc(svsp);
444 if (!kernel)
445 attrib = svsp->c_attr;
446 svsp->state = STATE_INIT;
447 break;
448
449 case '=': /* keypad application mode */
450 #if !PCVT_INHIBIT_NUMLOCK
451 vt_keyappl(svsp);
452 #endif
453 svsp->state = STATE_INIT;
454 break;
455
456 case '>': /* keypad numeric mode */
457 #if !PCVT_INHIBIT_NUMLOCK
458 vt_keynum(svsp);
459 #endif
460 svsp->state = STATE_INIT;
461 break;
462
463 case 'D': /* INDEX */
464 vt_ind(svsp);
465 svsp->state = STATE_INIT;
466 break;
467
468 case 'E': /* NEXT LINE */
469 vt_nel(svsp);
470 svsp->state = STATE_INIT;
471 break;
472
473 case 'H': /* set TAB at current col */
474 svsp->tab_stops[svsp->col] = 1;
475 svsp->state = STATE_INIT;
476 break;
477
478 case 'M': /* REVERSE INDEX */
479 vt_ri(svsp);
480 svsp->state = STATE_INIT;
481 break;
482
483 case 'N': /* SINGLE SHIFT G2 */
484 svsp->Gs = &svsp->G2;
485 svsp->ss = 1;
486 svsp->state = STATE_INIT;
487 break;
488
489 case 'O': /* SINGLE SHIFT G3 */
490 svsp->Gs = &svsp->G3;
491 svsp->ss = 1;
492 svsp->state = STATE_INIT;
493 break;
494
495 case 'P': /* DCS detected */
496 svsp->dcs_state = DCS_INIT;
497 svsp->state = STATE_DCS;
498 break;
499
500 case 'Z': /* What are you = ESC [ c */
501 vt_da(svsp);
502 svsp->state = STATE_INIT;
503 break;
504
505 case '[': /* CSI detected */
506 clr_parms(svsp);
507 svsp->state = STATE_CSI;
508 break;
509
510 case '\\': /* String Terminator */
511 svsp->state = STATE_INIT;
512 break;
513
514 case 'c': /* hard reset */
515 vt_ris(svsp);
516 if (!kernel)
517 attrib = svsp->c_attr;
518 svsp->state = STATE_INIT;
519 break;
520
521 #if PCVT_SETCOLOR
522 case 'd': /* set color sgr */
523 if(color)
524 {
525 /* set shiftwidth=4 */
526 sgr_tab_color
527 [svsp->
528 vtsgr] =
529 svsp->c_attr
530 >> 8;
531 user_attr =
532 sgr_tab_color
533 [0] << 8;
534 }
535 svsp->state = STATE_INIT;
536 break;
537 #endif /* PCVT_SETCOLOR */
538 case 'n': /* Lock Shift G2 -> GL */
539 svsp->GL = &svsp->G2;
540 svsp->state = STATE_INIT;
541 break;
542
543 case 'o': /* Lock Shift G3 -> GL */
544 svsp->GL = &svsp->G3;
545 svsp->state = STATE_INIT;
546 break;
547
548 case '}': /* Lock Shift G2 -> GR */
549 svsp->GR = &svsp->G2;
550 svsp->state = STATE_INIT;
551 break;
552
553 case '|': /* Lock Shift G3 -> GR */
554 svsp->GR = &svsp->G3;
555 svsp->state = STATE_INIT;
556 break;
557
558 case '~': /* Lock Shift G1 -> GR */
559 svsp->GR = &svsp->G1;
560 svsp->state = STATE_INIT;
561 break;
562
563 default:
564 svsp->state = STATE_INIT;
565 break;
566 }
567 break;
568
569 case STATE_BLANK: /* ESC space [FG], which are */
570 svsp->state = STATE_INIT; /* currently ignored*/
571 break;
572
573 case STATE_HASH:
574 switch(ch)
575 {
576 case '3': /* double height top half */
577 case '4': /*double height bottom half*/
578 case '5': /*single width sngle height*/
579 case '6': /*double width sngle height*/
580 svsp->state = STATE_INIT;
581 break;
582
583 case '8': /* fill sceen with 'E's */
584 vt_aln(svsp);
585 svsp->state = STATE_INIT;
586 break;
587
588 default: /* anything else */
589 svsp->state = STATE_INIT;
590 break;
591 }
592 break;
593
594 case STATE_BROPN: /* designate G0 */
595 case STATE_BRCLO: /* designate G1 */
596 case STATE_STAR: /* designate G2 */
597 case STATE_PLUS: /* designate G3 */
598 case STATE_MINUS: /* designate G1 (96) */
599 case STATE_DOT: /* designate G2 (96) */
600 case STATE_SLASH: /* designate G3 (96) */
601 svsp->which[svsp->whichi++] = ch;
602 if(ch >= 0x20 && ch <= 0x2f
603 && svsp->whichi <= 2)
604 break;
605 else if(ch >=0x30 && ch <= 0x7e)
606 {
607 svsp->which[svsp->whichi] = '\0';
608 vt_designate(svsp);
609 }
610 svsp->whichi = 0;
611 svsp->state = STATE_INIT;
612 break;
613
614 case STATE_CSIQM: /* DEC private modes */
615 switch(ch)
616 {
617 case '':
618 case '1':
619 case '2':
620 case '3':
621 case '4':
622 case '5':
623 case '6':
624 case '7':
625 case '8':
626 case '9': /* parameters */
627 svsp->parms[svsp->parmi] *= 10;
628 svsp->parms[svsp->parmi] +=
629 (ch -'');
630 break;
631
632 case ';': /* next parameter */
633 svsp->parmi =
634 (svsp->parmi+1 < MAXPARMS) ?
635 svsp->parmi+1 : svsp->parmi;
636 break;
637
638 case 'h': /* set mode */
639 vt_set_dec_priv_qm(svsp);
640 svsp->state = STATE_INIT;
641 break;
642
643 case 'l': /* reset mode */
644 vt_reset_dec_priv_qm(svsp);
645 svsp->state = STATE_INIT;
646 break;
647
648 case 'n': /* Reports */
649 vt_dsr(svsp);
650 svsp->state = STATE_INIT;
651 break;
652
653 case 'K': /* selective erase in line */
654 vt_sel(svsp);
655 svsp->state = STATE_INIT;
656 break;
657
658 case 'J':/*selective erase in display*/
659 vt_sed(svsp);
660 svsp->state = STATE_INIT;
661 break;
662
663 default:
664 svsp->state = STATE_INIT;
665 break;
666
667 }
668 break;
669
670 case STATE_CSI:
671 switch(ch)
672 {
673 case '':
674 case '1':
675 case '2':
676 case '3':
677 case '4':
678 case '5':
679 case '6':
680 case '7':
681 case '8':
682 case '9': /* parameters */
683 svsp->parms[svsp->parmi] *= 10;
684 svsp->parms[svsp->parmi] +=
685 (ch -'');
686 break;
687
688 case ';': /* next parameter */
689 svsp->parmi =
690 (svsp->parmi+1 < MAXPARMS) ?
691 svsp->parmi+1 : svsp->parmi;
692 break;
693
694 case '?': /* ESC [ ? family */
695 svsp->state = STATE_CSIQM;
696 break;
697
698 case '@': /* insert char */
699 vt_ic(svsp);
700 svsp->state = STATE_INIT;
701 break;
702
703 case '"': /* select char attribute */
704 svsp->state = STATE_SCA;
705 break;
706
707 case '\'': /* for DECELR/DECSLE */
708 /* XXX */ /* another state needed -hm */
709 break;
710
711 case '!': /* soft terminal reset */
712 svsp->state = STATE_STR;
713 break;
714
715 case 'A': /* cursor up */
716 vt_cuu(svsp);
717 svsp->state = STATE_INIT;
718 break;
719
720 case 'B': /* cursor down */
721 vt_cud(svsp);
722 svsp->state = STATE_INIT;
723 break;
724
725 case 'C': /* cursor forward */
726 vt_cuf(svsp);
727 svsp->state = STATE_INIT;
728 break;
729
730 case 'D': /* cursor backward */
731 vt_cub(svsp);
732 svsp->state = STATE_INIT;
733 break;
734
735 case 'H': /* direct cursor addressing*/
736 vt_curadr(svsp);
737 svsp->state = STATE_INIT;
738 break;
739
740 case 'J': /* erase screen */
741 vt_clreos(svsp);
742 svsp->state = STATE_INIT;
743 break;
744
745 case 'K': /* erase line */
746 vt_clreol(svsp);
747 svsp->state = STATE_INIT;
748 if (svsp->scr_offset > 0 &&
749 svsp == vsp)
750 svsp->scr_offset--;
751 break;
752
753 case 'L': /* insert line */
754 vt_il(svsp);
755 svsp->state = STATE_INIT;
756 break;
757
758 case 'M': /* delete line */
759 vt_dl(svsp);
760 svsp->state = STATE_INIT;
761 break;
762
763 case 'P': /* delete character */
764 vt_dch(svsp);
765 svsp->state = STATE_INIT;
766 break;
767
768 case 'S': /* scroll up */
769 vt_su(svsp);
770 svsp->state = STATE_INIT;
771 break;
772
773 case 'T': /* scroll down */
774 vt_sd(svsp);
775 svsp->state = STATE_INIT;
776 break;
777
778 case 'X': /* erase character */
779 vt_ech(svsp);
780 svsp->state = STATE_INIT;
781 break;
782
783 case 'c': /* device attributes */
784 vt_da(svsp);
785 svsp->state = STATE_INIT;
786 break;
787
788 case 'f': /* direct cursor addressing*/
789 vt_curadr(svsp);
790 svsp->state = STATE_INIT;
791 break;
792
793 case 'g': /* clear tabs */
794 vt_clrtab(svsp);
795 svsp->state = STATE_INIT;
796 break;
797
798 case 'h': /* set mode(s) */
799 vt_set_ansi(svsp);
800 svsp->state = STATE_INIT;
801 break;
802
803 case 'i': /* media copy */
804 vt_mc(svsp);
805 svsp->state = STATE_INIT;
806 break;
807
808 case 'l': /* reset mode(s) */
809 vt_reset_ansi(svsp);
810 svsp->state = STATE_INIT;
811 break;
812
813 case 'm': /* select graphic rendition*/
814 vt_sgr(svsp);
815 if (!kernel)
816 attrib = svsp->c_attr;
817 svsp->state = STATE_INIT;
818 break;
819
820 case 'n': /* reports */
821 vt_dsr(svsp);
822 svsp->state = STATE_INIT;
823 break;
824
825 case 'r': /* set scrolling region */
826 vt_stbm(svsp);
827 svsp->state = STATE_INIT;
828 break;
829
830 case 'x': /*request/report parameters*/
831 vt_reqtparm(svsp);
832 svsp->state = STATE_INIT;
833 break;
834
835 case 'y': /* invoke selftest(s) */
836 vt_tst(svsp);
837 svsp->state = STATE_INIT;
838 break;
839
840 case 'z': /* DECELR, ignored */
841 case '{': /* DECSLE, ignored */
842 svsp->state = STATE_INIT;
843 break;
844
845 default:
846 svsp->state = STATE_INIT;
847 break;
848 }
849 break;
850
851 case STATE_AMPSND:
852 hp_entry(ch,svsp);
853 break;
854
855 case STATE_DCS:
856 vt_dcsentry(ch,svsp);
857 break;
858
859 case STATE_SCA:
860 switch(ch)
861 {
862 case 'q':
863 vt_sca(svsp);
864 svsp->state = STATE_INIT;
865 break;
866
867 default:
868 svsp->state = STATE_INIT;
869 break;
870 }
871 break;
872
873 case STATE_STR:
874 switch(ch)
875 {
876 case 'p': /* soft terminal reset */
877 vt_str(svsp);
878 if (!kernel)
879 attrib = svsp->c_attr;
880 svsp->state = STATE_INIT;
881 break;
882
883 default:
884 svsp->state = STATE_INIT;
885 break;
886 }
887 break;
888
889 default: /* failsafe */
890 svsp->state = STATE_INIT;
891 break;
892
893 }
894 }
895
896 svsp->row = svsp->cur_offset / svsp->maxcol; /* current row update */
897
898 /* take care of last character on line behaviour */
899
900 if(svsp->lastchar && (svsp->col < ((svsp->maxcol)-1)))
901 svsp->lastchar = 0;
902 }
903
904 if(svsp == vsp) /* on current displayed page ? */
905 cursor_pos_valid = 1; /* position is valid now */
906 }
907
908 /*---------------------------------------------------------------------------*
909 * this is the absolute cold initialization of the emulator
910 *---------------------------------------------------------------------------*/
911 static void
912 vt_coldinit(void)
913 {
914 u_short volatile *cp;
915 u_short was;
916 int nscr, charset;
917 int equipment;
918 u_short *SaveCrtat;
919 struct video_state *svsp;
920
921 Crtat = (u_short *)MONO_BUF; /* XXX assume static relocation works */
922 SaveCrtat = Crtat;
923 cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
924
925 do_initialization = 0; /* reset init necessary flag */
926
927 /* get the equipment byte from the RTC chip */
928
929 equipment = ((rtcin(RTC_EQUIPMENT)) >> 4) & 0x03;
930
931 switch(equipment)
932 {
933 case EQ_EGAVGA:
934
935 /* set memory start to CGA == B8000 */
936
937 Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
938
939 /* find out, what monitor is connected */
940
941 was = *cp;
942 *cp = (u_short) 0xA55A;
943 if (*cp != 0xA55A)
944 {
945 addr_6845 = MONO_BASE;
946 color = 0;
947 }
948 else
949 {
950 *cp = was;
951 addr_6845 = CGA_BASE;
952 color = 1;
953 }
954
955 if(vga_test()) /* EGA or VGA ? */
956 {
957 adaptor_type = VGA_ADAPTOR;
958 totalfonts = 8;
959
960 if(color == 0)
961 {
962 mda2egaorvga();
963 Crtat = SaveCrtat; /* mono start */
964 }
965
966 /* find out which chipset we are running on */
967 vga_type = vga_chipset();
968 }
969 else
970 {
971 adaptor_type = EGA_ADAPTOR;
972 totalfonts = 4;
973
974 if(color == 0)
975 {
976 mda2egaorvga();
977 Crtat = SaveCrtat; /* mono start */
978 }
979 }
980
981 /* decouple ega/vga charsets and intensity */
982 set_2ndcharset();
983
984 break;
985
986 case EQ_40COLOR: /* XXX should panic in 40 col mode ! */
987 case EQ_80COLOR:
988 Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
989 addr_6845 = CGA_BASE;
990 adaptor_type = CGA_ADAPTOR;
991 color = 1;
992 totalfonts = 0;
993 break;
994
995 case EQ_80MONO:
996 addr_6845 = MONO_BASE;
997 adaptor_type = MDA_ADAPTOR;
998 color = 0;
999 totalfonts = 0;
1000 break;
1001 }
1002
1003 /* establish default colors */
1004
1005 if(color)
1006 {
1007 kern_attr = (COLOR_KERNEL_FG | COLOR_KERNEL_BG) << 8;
1008 user_attr = sgr_tab_color[0] << 8;
1009 }
1010 else
1011 {
1012 kern_attr = (MONO_KERNEL_FG | MONO_KERNEL_BG) << 8;
1013 if(adaptor_type == MDA_ADAPTOR)
1014 user_attr = sgr_tab_imono[0] << 8;
1015 else
1016 user_attr = sgr_tab_mono[0] << 8;
1017 }
1018
1019 totalscreens = 1; /* for now until malloced */
1020
1021 for(nscr = 0, svsp = vs; nscr < PCVT_NSCREENS; nscr++, svsp++)
1022 {
1023 svsp->Crtat = Crtat; /* all same until malloc'ed */
1024 svsp->Memory = Crtat; /* until malloc'ed */
1025 svsp->Scrollback = 0; /* until malloc'ed */
1026 svsp->scr_offset = 0; /* scrollback offset (lines) */
1027 svsp->scrolling = 0; /* current scrollback page */
1028 svsp->cur_offset = 0; /* cursor offset */
1029 svsp->c_attr = user_attr; /* non-kernel attributes */
1030 svsp->bell_on = 1; /* enable bell */
1031 svsp->sevenbit = 0; /* set to 8-bit path */
1032 svsp->dis_fnc = 0; /* disable display functions */
1033 svsp->transparent = 0; /* disable internal tranparency */
1034 svsp->lastchar = 0; /* VTxxx behaviour of last */
1035 /* char on line */
1036 svsp->report_chars = NULL; /* VTxxx reports init */
1037 svsp->report_count = 0; /* VTxxx reports init */
1038 svsp->state = STATE_INIT; /* main state machine init */
1039 svsp->m_awm = 1; /* enable auto wrap mode */
1040 svsp->m_om = 0; /* origin mode = absolute */
1041 svsp->sc_flag = 0; /* init saved cursor flag */
1042 svsp->which_fkl = SYS_FKL; /* display system fkey-labels */
1043 svsp->labels_on = 1; /* if in HP-mode, display */
1044 /* fkey-labels */
1045 svsp->attribute = 0; /* HP mode init */
1046 svsp->key = 0; /* HP mode init */
1047 svsp->l_len = 0; /* HP mode init */
1048 svsp->s_len = 0; /* HP mode init */
1049 svsp->m_len = 0; /* HP mode init */
1050 svsp->i = 0; /* HP mode init */
1051 svsp->vt_pure_mode = M_PUREVT; /* initial mode: pure VT220*/
1052 svsp->vga_charset = CH_SET0; /* use bios default charset */
1053
1054 #if PCVT_24LINESDEF /* true compatibility */
1055 svsp->screen_rows = 24; /* default 24 rows on screen */
1056 #else /* full screen */
1057 svsp->screen_rows = 25; /* default 25 rows on screen */
1058 #endif /* PCVT_24LINESDEF */
1059
1060 svsp->screen_rowsize = 25; /* default 25 rows on screen */
1061 svsp->max_off = svsp->screen_rowsize * SCROLLBACK_PAGES - 1;
1062 svsp->scrr_beg = 0; /* scrolling region begin row*/
1063 svsp->scrr_len = svsp->screen_rows; /* scrolling region length*/
1064 svsp->scrr_end = svsp->scrr_len - 1;/* scrolling region end */
1065
1066 if(nscr == 0)
1067 {
1068 if(adaptor_type == VGA_ADAPTOR)
1069 {
1070 /* only VGA can read cursor shape registers ! */
1071 /* Preserve initial cursor shape */
1072 outb(addr_6845,CRTC_CURSTART);
1073 svsp->cursor_start = inb(addr_6845+1);
1074 outb(addr_6845,CRTC_CUREND);
1075 svsp->cursor_end = inb(addr_6845+1);
1076 }
1077 else
1078 {
1079 /* MDA,HGC,CGA,EGA registers are write-only */
1080 svsp->cursor_start = 0;
1081 svsp->cursor_end = 15;
1082 }
1083 }
1084 else
1085 {
1086 svsp->cursor_start = vs[0].cursor_start;
1087 svsp->cursor_end = vs[0].cursor_end;
1088 }
1089
1090 #ifdef FAT_CURSOR
1091 svsp->cursor_start = 0;
1092 svsp->cursor_end = 15; /* cursor lower scanline */
1093 #endif
1094
1095 svsp->cursor_on = 1; /* cursor is on */
1096 svsp->ckm = 1; /* normal cursor key mode */
1097 svsp->irm = 0; /* replace mode */
1098 svsp->lnm = 0; /* CR only */
1099 svsp->selchar = 0; /* selective attribute off */
1100 svsp->G0 = csd_ascii; /* G0 = ascii */
1101 svsp->G1 = csd_ascii; /* G1 = ascii */
1102 svsp->G2 = csd_supplemental; /* G2 = supplemental */
1103 svsp->G3 = csd_supplemental; /* G3 = supplemental */
1104 svsp->GL = &svsp->G0; /* GL = G0 */
1105 svsp->GR = &svsp->G2; /* GR = G2 */
1106 svsp->whichi = 0; /* char set designate init */
1107 svsp->which[0] = '\0'; /* char set designate init */
1108 svsp->hp_state = SHP_INIT; /* init HP mode state machine*/
1109 svsp->dcs_state = DCS_INIT; /* init DCS mode state machine*/
1110 svsp->ss = 0; /* init single shift 2/3 */
1111 svsp->Gs = NULL; /* Gs single shift 2/3 */
1112 svsp->maxcol = SCR_COL80; /* 80 columns now (MUST!!!) */
1113 svsp->wd132col = 0; /* help good old WD .. */
1114 svsp->scroll_lock = 0; /* scrollock off */
1115
1116 #if PCVT_INHIBIT_NUMLOCK
1117 svsp->num_lock = 0; /* numlock off */
1118 #else
1119 svsp->num_lock = 1; /* numlock on */
1120 #endif
1121
1122 svsp->caps_lock = 0; /* capslock off */
1123 svsp->shift_lock = 0; /* shiftlock off */
1124
1125 #if PCVT_24LINESDEF /* true compatibility */
1126 svsp->force24 = 1; /* force 24 lines */
1127 #else /* maximum screen size */
1128 svsp->force24 = 0; /* no 24 lines force yet */
1129 #endif /* PCVT_24LINESDEF */
1130
1131 vt_clearudk(svsp); /* clear vt220 udk's */
1132
1133 vt_str(svsp); /* init emulator */
1134
1135 if(nscr == 0)
1136 {
1137 /*
1138 * Preserve data on the startup screen that
1139 * precedes the cursor position. Leave the
1140 * cursor where it was found.
1141 */
1142 unsigned cursorat;
1143 int filllen;
1144
1145 /* CRTC regs 0x0e and 0x0f are r/w everywhere */
1146
1147 outb(addr_6845, CRTC_CURSORH);
1148 cursorat = inb(addr_6845+1) << 8;
1149 outb(addr_6845, CRTC_CURSORL);
1150 cursorat |= inb(addr_6845+1);
1151
1152 /*
1153 * Reject cursors that are more than one row off a
1154 * 25-row screen. syscons sets the cursor offset
1155 * to 0xffff. The scroll up fixup fails for this
1156 * because the assignment to svsp->row overflows
1157 * and perhaps for other reasons.
1158 */
1159 if (cursorat > 25 * svsp->maxcol)
1160 cursorat = 25 * svsp->maxcol;
1161
1162 svsp->cur_offset = cursorat;
1163 svsp->row = cursorat / svsp->maxcol;
1164 svsp->col = cursorat % svsp->maxcol;
1165
1166 if (svsp->row >= svsp->screen_rows)
1167 {
1168
1169 /*
1170 * Scroll up; this should only happen when
1171 * PCVT_24LINESDEF is set
1172 */
1173 int nscroll =
1174 svsp->row + 1
1175 - svsp->screen_rows;
1176 bcopy (svsp->Crtat
1177 + nscroll*svsp->maxcol,
1178 svsp->Crtat,
1179 svsp->screen_rows
1180 * svsp->maxcol * CHR);
1181 svsp->row -= nscroll;
1182 svsp->cur_offset -=
1183 nscroll * svsp->maxcol;
1184 }
1185
1186 filllen = (svsp->maxcol * svsp->screen_rowsize)
1187 - svsp->cur_offset;
1188
1189 if (filllen > 0)
1190 fillw(user_attr | ' ',
1191 svsp->Crtat+svsp->cur_offset,
1192 filllen);
1193 }
1194
1195 #ifdef XSERVER
1196 svsp->smode.mode = VT_AUTO;
1197 svsp->smode.relsig = svsp->smode.acqsig =
1198 svsp->smode.frsig = 0;
1199 svsp->proc = 0;
1200 svsp->pid = svsp->vt_status = 0;
1201 #endif /* XSERVER */
1202
1203 }
1204
1205 for(charset = 0;charset < NVGAFONTS;charset++)
1206 {
1207 vgacs[charset].loaded = 0; /* not populated yet */
1208 vgacs[charset].secondloaded = 0; /* not populated yet */
1209
1210 switch(adaptor_type)
1211 {
1212 case VGA_ADAPTOR:
1213
1214 /*
1215 * for a VGA, do not assume any
1216 * constant - instead, read the actual
1217 * values. This avoid problems with
1218 * LCD displays that apparently happen
1219 * to use font matrices up to 19
1220 * scan lines and 475 scan lines
1221 * total in order to make use of the
1222 * whole screen area
1223 */
1224
1225 outb(addr_6845, CRTC_VDE);
1226 vgacs[charset].scr_scanlines =
1227 inb(addr_6845 + 1);
1228 outb(addr_6845, CRTC_MAXROW);
1229 vgacs[charset].char_scanlines =
1230 inb(addr_6845 + 1);
1231 break;
1232
1233 case EGA_ADAPTOR:
1234 /* 0x5D for 25 lines */
1235 vgacs[charset].scr_scanlines = 0x5D;
1236 /* 0x4D for 25 lines */
1237 vgacs[charset].char_scanlines = 0x4D;
1238 break;
1239
1240 case CGA_ADAPTOR:
1241 case MDA_ADAPTOR:
1242 default:
1243 /* These shouldn't be used for CGA/MDA */
1244 vgacs[charset].scr_scanlines = 0;
1245 vgacs[charset].char_scanlines = 0;
1246 break;
1247 }
1248 vgacs[charset].screen_size = SIZ_25ROWS; /* set screen size */
1249 }
1250
1251 vgacs[0].loaded = 1; /* The BIOS loaded this at boot */
1252
1253 /* set cursor for first screen */
1254
1255 outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
1256 outb(addr_6845+1,vs[0].cursor_start);
1257 outb(addr_6845,CRTC_CUREND); /* cursor end reg */
1258 outb(addr_6845+1,vs[0].cursor_end);
1259
1260 /* this is to satisfy ddb */
1261
1262 if(!keyboard_is_initialized)
1263 kbd_code_init1();
1264 }
1265
1266 /*---------------------------------------------------------------------------*
1267 * get kernel memory for virtual screens
1268 *
1269 * CAUTION: depends on "can_do_132col" being set properly, or
1270 * depends on vga_type() being run before calling this !!!
1271 *
1272 *---------------------------------------------------------------------------*/
1273 void
1274 vt_coldmalloc(void)
1275 {
1276 int nscr;
1277 int screen_max_size;
1278
1279 /* we need to initialize in case we are not the console */
1280
1281 if(do_initialization)
1282 vt_coldinit();
1283
1284 switch(adaptor_type)
1285 {
1286 default:
1287 case MDA_ADAPTOR:
1288 case CGA_ADAPTOR:
1289 screen_max_size = MAXROW_MDACGA * MAXCOL_MDACGA * CHR;
1290 break;
1291
1292 case EGA_ADAPTOR:
1293 screen_max_size = MAXROW_EGA * MAXCOL_EGA * CHR;
1294 break;
1295
1296 case VGA_ADAPTOR:
1297 if(can_do_132col)
1298 screen_max_size =
1299 MAXROW_VGA * MAXCOL_SVGA * CHR;
1300 else
1301 screen_max_size =
1302 MAXROW_VGA * MAXCOL_VGA * CHR;
1303 }
1304
1305 for(nscr = 0; nscr < PCVT_NSCREENS; nscr++)
1306 {
1307 if((vs[nscr].Memory = (u_short *)malloc(screen_max_size * 2,
1308 M_DEVBUF, M_WAITOK)) == NULL)
1309 {
1310 printf("pcvt: screen memory malloc failed, "
1311 "NSCREEN=%d, nscr=%d\n",
1312 PCVT_NSCREENS, nscr);
1313 break;
1314 }
1315
1316 if(nscr != 0)
1317 {
1318 vs[nscr].Crtat = vs[nscr].Memory;
1319 fillw(user_attr | ' ',
1320 vs[nscr].Crtat,
1321 vs[nscr].maxcol * vs[nscr].screen_rowsize);
1322 totalscreens++;
1323 }
1324
1325 vs[nscr].scrollback_pages = SCROLLBACK_PAGES;
1326
1327 reallocate_scrollbuffer(&(vs[nscr]), vs[nscr].scrollback_pages);
1328 }
1329 }
1330
1331 /*---------------------------------------------------------------------------*
1332 * check if we must scroll up screen
1333 *---------------------------------------------------------------------------*/
1334 static void
1335 check_scroll(struct video_state *svsp)
1336 {
1337 if(!svsp->abs_write)
1338 {
1339 /* we write within scroll region */
1340
1341 if(svsp->cur_offset >= ((svsp->scrr_end + 1) * svsp->maxcol))
1342 {
1343 /* the following piece of code has to be protected */
1344 /* from trying to switch to another virtual screen */
1345 /* while being in there ... */
1346
1347 critical_scroll = 1; /* flag protect ON */
1348
1349 roll_up(svsp, 1); /* rolling up .. */
1350
1351 svsp->cur_offset -= svsp->maxcol;/* update position */
1352
1353 if(switch_page != -1) /* someone wanted to switch ? */
1354 {
1355 vgapage(switch_page); /* yes, then switch ! */
1356 switch_page = -1; /* reset switch flag */
1357 }
1358
1359 critical_scroll = 0; /* flag protect OFF */
1360 }
1361 }
1362 else
1363 {
1364 /* clip, if outside of screen */
1365
1366 if (svsp->cur_offset >= svsp->screen_rows * svsp->maxcol)
1367 svsp->cur_offset -= svsp->maxcol;
1368 }
1369 }
1370
1371 /*---------------------------------------------------------------------------*
1372 *
1373 *---------------------------------------------------------------------------*/
1374 static int
1375 check_scrollback(struct video_state *svsp)
1376 {
1377 /* still waiting for scrollback memory or not on current page */
1378 if (!svsp->Scrollback || svsp != vsp)
1379 return 0;
1380
1381 /* remove first line of scrollback buffer to make room for new line */
1382 if (svsp->scr_offset == svsp->max_off)
1383 {
1384 bcopy(svsp->Scrollback + svsp->maxcol, svsp->Scrollback,
1385 svsp->maxcol * svsp->max_off * CHR);
1386 }
1387 else
1388 {
1389 /* still room left, increase scroll offset (lines) */
1390 svsp->scr_offset++;
1391 }
1392 return 1;
1393 }
1394
1395 /*---------------------------------------------------------------------------*
1396 * write to one user function key label
1397 *---------------------------------------------------------------------------*/
1398 static void
1399 writefkl(int num, u_char *string, struct video_state *svsp)
1400 {
1401 if((num < 0) || (num > 7)) /* range ok ? */
1402 return;
1403
1404 strncpy(svsp->ufkl[num], string, 16); /* save string in static array */
1405
1406 if(svsp->which_fkl == USR_FKL)
1407 wrfkl(num,string,svsp);
1408 }
1409
1410 /*---------------------------------------------------------------------------*
1411 * write to one system function key label
1412 *---------------------------------------------------------------------------*/
1413 void
1414 swritefkl(int num, u_char *string, struct video_state *svsp)
1415 {
1416 if((num < 0) || (num > 7)) /* range ok ? */
1417 return;
1418
1419 strncpy(svsp->sfkl[num], string, 16); /* save string in static array */
1420
1421 if(svsp->which_fkl == SYS_FKL)
1422 wrfkl(num,string,svsp);
1423 }
1424
1425 /*---------------------------------------------------------------------------*
1426 * write function key label onto screen
1427 *---------------------------------------------------------------------------*/
1428 static void
1429 wrfkl(int num, u_char *string, struct video_state *svsp)
1430 {
1431 register u_short *p;
1432 register u_short *p1;
1433 register int cnt = 0;
1434
1435 if(!svsp->labels_on || (svsp->vt_pure_mode == M_PUREVT))
1436 return;
1437
1438 p = (svsp->Crtat
1439 + (svsp->screen_rows * svsp->maxcol)); /* screen_rows+1 line */
1440
1441 if(svsp->maxcol == SCR_COL80)
1442 {
1443 if(num < 4) /* labels 1 .. 4 */
1444 p += (num * LABEL_LEN);
1445 else /* labels 5 .. 8 */
1446 p += ((num * LABEL_LEN) + LABEL_MID + 1);
1447 }
1448 else
1449 {
1450 if(num < 4) /* labels 1 .. 4 */
1451 p += (num * (LABEL_LEN + 6));
1452 else /* labels 5 .. 8 */
1453 p += ((num * (LABEL_LEN + 6)) + LABEL_MID + 11);
1454
1455 }
1456 p1 = p + svsp->maxcol; /* second label line */
1457
1458 while((*string != '\0') && (cnt < 8))
1459 {
1460 *p = ((0x70 << 8) + (*string & 0xff));
1461 p++;
1462 string++;
1463 cnt++;
1464 }
1465 while(cnt < 8)
1466 {
1467 *p = ((0x70 << 8) + ' ');
1468 p++;
1469 cnt++;
1470 }
1471
1472 while((*string != '\0') && (cnt < 16))
1473 {
1474 *p1 = ((0x70 << 8) + (*string & 0xff));
1475 p1++;
1476 string++;
1477 cnt++;
1478 }
1479 while(cnt < 16)
1480 {
1481 *p1 = ((0x70 << 8) + ' ');
1482 p1++;
1483 cnt++;
1484 }
1485 }
1486
1487 /*---------------------------------------------------------------------------*
1488 * remove (=blank) function key labels, row/col and status line
1489 *---------------------------------------------------------------------------*/
1490 void
1491 fkl_off(struct video_state *svsp)
1492 {
1493 register u_short *p;
1494 register int num;
1495 register int size;
1496
1497 svsp->labels_on = 0;
1498
1499 if((vgacs[svsp->vga_charset].screen_size==SIZ_28ROWS) && svsp->force24)
1500 size = 4;
1501 else
1502 size = 3;
1503
1504 p = (svsp->Crtat + (svsp->screen_rows * svsp->maxcol));
1505
1506 for(num = 0; num < (size * svsp->maxcol); num++)
1507 *p++ = ' ';
1508 }
1509
1510 /*---------------------------------------------------------------------------*
1511 * (re-) display function key labels, row/col and status line
1512 *---------------------------------------------------------------------------*/
1513 void
1514 fkl_on(struct video_state *svsp)
1515 {
1516 svsp->labels_on = 1;
1517
1518 if(svsp->which_fkl == SYS_FKL)
1519 sw_sfkl(svsp);
1520 else if(svsp->which_fkl == USR_FKL)
1521 sw_ufkl(svsp);
1522 }
1523
1524 /*---------------------------------------------------------------------------*
1525 * set emulation mode, switch between pure VTxxx mode and HP/VTxxx mode
1526 *---------------------------------------------------------------------------*/
1527 void
1528 set_emulation_mode(struct video_state *svsp, int mode)
1529 {
1530 if(svsp->vt_pure_mode == mode)
1531 return;
1532
1533 clr_parms(svsp); /* escape parameter init */
1534 svsp->state = STATE_INIT; /* initial state */
1535 svsp->scrr_beg = 0; /* start of scrolling region */
1536 svsp->sc_flag = 0; /* invalidate saved cursor position */
1537 svsp->transparent = 0; /* disable control code processing */
1538
1539 if(mode == M_HPVT) /* vt-pure -> hp/vt-mode */
1540 {
1541 svsp->screen_rows = svsp->screen_rowsize - 3;
1542 if (svsp->force24 && svsp->screen_rows == 25)
1543 svsp->screen_rows = 24;
1544
1545 if (svsp->row >= svsp->screen_rows) {
1546 /* Scroll up */
1547 int nscroll = svsp->row + 1 - svsp->screen_rows;
1548 bcopy (svsp->Crtat + nscroll * svsp->maxcol,
1549 svsp->Crtat,
1550 svsp->screen_rows * svsp->maxcol * CHR);
1551 svsp->row -= nscroll;
1552 svsp->cur_offset -= nscroll * svsp->maxcol;
1553 }
1554
1555 svsp->vt_pure_mode = M_HPVT;
1556
1557 if (svsp->vs_tty)
1558 svsp->vs_tty->t_winsize.ws_row = svsp->screen_rows;
1559
1560 svsp->scrr_len = svsp->screen_rows;
1561 svsp->scrr_end = svsp->scrr_len - 1;
1562
1563 update_hp(svsp);
1564 }
1565 else if(mode == M_PUREVT) /* hp/vt-mode -> vt-pure */
1566 {
1567 fillw(user_attr | ' ',
1568 svsp->Crtat + svsp->screen_rows * svsp->maxcol,
1569 (svsp->screen_rowsize - svsp->screen_rows)
1570 * svsp->maxcol);
1571
1572 svsp->vt_pure_mode = M_PUREVT;
1573
1574 svsp->screen_rows = svsp->screen_rowsize;
1575 if (svsp->force24 && svsp->screen_rows == 25)
1576 svsp->screen_rows = 24;
1577
1578 if (svsp->vs_tty)
1579 svsp->vs_tty->t_winsize.ws_row = svsp->screen_rows;
1580
1581 svsp->scrr_len = svsp->screen_rows;
1582 svsp->scrr_end = svsp->scrr_len - 1;
1583 }
1584
1585 if (svsp->vs_tty && svsp->vs_tty->t_pgrp) {
1586 PGRP_LOCK(svsp->vs_tty->t_pgrp);
1587 pgsignal(svsp->vs_tty->t_pgrp, SIGWINCH, 1);
1588 PGRP_UNLOCK(svsp->vs_tty->t_pgrp);
1589 }
1590 }
1591
1592 /*---------------------------------------------------------------------------*
1593 * initialize user function key labels
1594 *---------------------------------------------------------------------------*/
1595 void
1596 init_ufkl(struct video_state *svsp)
1597 {
1598 writefkl(0,(u_char *)" f1",svsp); /* init fkey labels */
1599 writefkl(1,(u_char *)" f2",svsp);
1600 writefkl(2,(u_char *)" f3",svsp);
1601 writefkl(3,(u_char *)" f4",svsp);
1602 writefkl(4,(u_char *)" f5",svsp);
1603 writefkl(5,(u_char *)" f6",svsp);
1604 writefkl(6,(u_char *)" f7",svsp);
1605 writefkl(7,(u_char *)" f8",svsp);
1606 }
1607
1608 /*---------------------------------------------------------------------------*
1609 * initialize system user function key labels
1610 *---------------------------------------------------------------------------*/
1611 void
1612 init_sfkl(struct video_state *svsp)
1613 {
1614 /* 1234567812345678 */
1615 if(can_do_132col)
1616 /* 1234567812345678 */
1617 swritefkl(0,(u_char *)"132 COLUMNS ",svsp);
1618 else
1619 swritefkl(0,(u_char *)" ",svsp);
1620
1621 /* 1234567812345678 */
1622 swritefkl(1,(u_char *)"SOFT-RSTTERMINAL",svsp);
1623
1624 if(svsp->force24)
1625 swritefkl(2,(u_char *)"FORCE24 ENABLE *",svsp);
1626 else
1627 swritefkl(2,(u_char *)"FORCE24 ENABLE ",svsp);
1628
1629 #if PCVT_SHOWKEYS /* 1234567812345678 */
1630 if(svsp == &vs[0])
1631 swritefkl(3,(u_char *)"KEYBSCANDISPLAY ",svsp);
1632 else
1633 swritefkl(3,(u_char *)" ",svsp);
1634 #else
1635 swritefkl(3,(u_char *)" ",svsp);
1636 #endif /* PCVT_SHOWKEYS */
1637
1638 /* 1234567812345678 */
1639 if(svsp->bell_on)
1640 swritefkl(4,(u_char *)"BELL ENABLE *",svsp);
1641 else
1642 swritefkl(4,(u_char *)"BELL ENABLE ",svsp);
1643
1644 if(svsp->sevenbit)
1645 swritefkl(5,(u_char *)"8-BIT ENABLE ",svsp);
1646 else
1647 swritefkl(5,(u_char *)"8-BIT ENABLE *",svsp);
1648
1649 swritefkl(6,(u_char *)"DISPLAY FUNCTNS ",svsp);
1650
1651 swritefkl(7,(u_char *)"AUTOWRAPENABLE *",svsp);
1652 /* 1234567812345678 */
1653 }
1654
1655 /*---------------------------------------------------------------------------*
1656 * switch display to user function key labels
1657 *---------------------------------------------------------------------------*/
1658 void
1659 sw_ufkl(struct video_state *svsp)
1660 {
1661 int i;
1662 svsp->which_fkl = USR_FKL;
1663 for(i = 0; i < 8; i++)
1664 wrfkl(i,svsp->ufkl[i],svsp);
1665 }
1666
1667 /*---------------------------------------------------------------------------*
1668 * switch display to system function key labels
1669 *---------------------------------------------------------------------------*/
1670 void
1671 sw_sfkl(struct video_state *svsp)
1672 {
1673 int i;
1674 svsp->which_fkl = SYS_FKL;
1675 for(i = 0; i < 8; i++)
1676 wrfkl(i,svsp->sfkl[i],svsp);
1677 }
1678
1679 /*---------------------------------------------------------------------------*
1680 * toggle force 24 lines
1681 *---------------------------------------------------------------------------*/
1682 void
1683 toggl_24l(struct video_state *svsp)
1684 {
1685 if(svsp->which_fkl == SYS_FKL)
1686 {
1687 if(svsp->force24)
1688 {
1689 svsp->force24 = 0;
1690 swritefkl(2,(u_char *)"FORCE24 ENABLE ",svsp);
1691 }
1692 else
1693 {
1694 svsp->force24 = 1;
1695 swritefkl(2,(u_char *)"FORCE24 ENABLE *",svsp);
1696 }
1697 set_screen_size(svsp, vgacs[(svsp->vga_charset)].screen_size);
1698 }
1699 }
1700
1701 #if PCVT_SHOWKEYS
1702 /*---------------------------------------------------------------------------*
1703 * toggle keyboard scancode display
1704 *---------------------------------------------------------------------------*/
1705 void
1706 toggl_kbddbg(struct video_state *svsp)
1707 {
1708 if((svsp->which_fkl == SYS_FKL) && (svsp == &vs[0]))
1709 {
1710 if(keyboard_show)
1711 {
1712 keyboard_show = 0;
1713 swritefkl(3,(u_char *)"KEYBSCANDISPLAY ",svsp);
1714 }
1715 else
1716 {
1717 keyboard_show = 1;
1718 swritefkl(3,(u_char *)"KEYBSCANDISPLAY*",svsp);
1719 }
1720 }
1721 }
1722 #endif /* PCVT_SHOWKEYS */
1723
1724 /*---------------------------------------------------------------------------*
1725 * toggle display functions
1726 *---------------------------------------------------------------------------*/
1727 void
1728 toggl_dspf(struct video_state *svsp)
1729 {
1730 if(svsp->which_fkl == SYS_FKL)
1731 {
1732 if(svsp->dis_fnc)
1733 {
1734 svsp->dis_fnc = 0;
1735 swritefkl(6,(u_char *)"DISPLAY FUNCTNS ",svsp);
1736 }
1737 else
1738 {
1739 svsp->dis_fnc = 1;
1740 swritefkl(6,(u_char *)"DISPLAY FUNCTNS*",svsp);
1741 }
1742 }
1743 }
1744
1745 /*---------------------------------------------------------------------------*
1746 * auto wrap on/off
1747 *---------------------------------------------------------------------------*/
1748 void
1749 toggl_awm(struct video_state *svsp)
1750 {
1751 if(svsp->which_fkl == SYS_FKL)
1752 {
1753 if(svsp->m_awm)
1754 {
1755 svsp->m_awm = 0;
1756 swritefkl(7,(u_char *)"AUTOWRAPENABLE ",svsp);
1757 }
1758 else
1759 {
1760 svsp->m_awm = 1;
1761 swritefkl(7,(u_char *)"AUTOWRAPENABLE *",svsp);
1762 }
1763 }
1764 }
1765
1766 /*---------------------------------------------------------------------------*
1767 * bell on/off
1768 *---------------------------------------------------------------------------*/
1769 void
1770 toggl_bell(struct video_state *svsp)
1771 {
1772 if(svsp->which_fkl == SYS_FKL)
1773 {
1774 if(svsp->bell_on)
1775 {
1776 svsp->bell_on = 0;
1777 swritefkl(4,(u_char *)"BELL ENABLE ",svsp);
1778 }
1779 else
1780 {
1781 svsp->bell_on = 1;
1782 swritefkl(4,(u_char *)"BELL ENABLE *",svsp);
1783 }
1784 }
1785 }
1786
1787 /*---------------------------------------------------------------------------*
1788 * 7/8 bit usage
1789 *---------------------------------------------------------------------------*/
1790 void
1791 toggl_sevenbit(struct video_state *svsp)
1792 {
1793 if(svsp->which_fkl == SYS_FKL)
1794 {
1795 if(svsp->sevenbit)
1796 {
1797 svsp->sevenbit = 0;
1798 swritefkl(5,(u_char *)"8-BIT ENABLE *",svsp);
1799 }
1800 else
1801 {
1802 svsp->sevenbit = 1;
1803 swritefkl(5,(u_char *)"8-BIT ENABLE ",svsp);
1804 }
1805 }
1806 }
1807
1808 /*---------------------------------------------------------------------------*
1809 * 80 / 132 columns
1810 *---------------------------------------------------------------------------*/
1811 void
1812 toggl_columns(struct video_state *svsp)
1813 {
1814 if(svsp->which_fkl == SYS_FKL)
1815 {
1816 if(svsp->maxcol == SCR_COL132)
1817 {
1818 if(vt_col(svsp, SCR_COL80))
1819 svsp->maxcol = 80;
1820 }
1821 else
1822 {
1823 if(vt_col(svsp, SCR_COL132))
1824 svsp->maxcol = 132;
1825 }
1826 }
1827 }
1828
1829 /*---------------------------------------------------------------------------*
1830 * toggle vga 80/132 column operation
1831 *---------------------------------------------------------------------------*/
1832 int
1833 vt_col(struct video_state *svsp, int cols)
1834 {
1835 if(vga_col(svsp, cols) == 0)
1836 return(0);
1837
1838 if(cols == SCR_COL80)
1839 swritefkl(0,(u_char *)"132 COLUMNS ",svsp);
1840 else
1841 swritefkl(0,(u_char *)"132 COLUMNS*",svsp);
1842
1843 fillw(user_attr | ' ',
1844 svsp->Crtat,
1845 svsp->maxcol * svsp->screen_rowsize);
1846
1847 clr_parms(svsp); /* escape parameter init */
1848 svsp->state = STATE_INIT; /* initial state */
1849 svsp->col = 0; /* init row */
1850 svsp->row = 0; /* init col */
1851 svsp->cur_offset = 0; /* cursor offset init */
1852 svsp->sc_flag = 0; /* invalidate saved cursor position */
1853 svsp->scrr_beg = 0; /* reset scrolling region */
1854 svsp->scrr_len = svsp->screen_rows; /*reset scrolling region legnth */
1855 svsp->scrr_end = svsp->scrr_len - 1;
1856 svsp->transparent = 0; /* disable control code processing */
1857 svsp->selchar = 0; /* selective attr off */
1858 vt_initsel(svsp); /* re-init sel attr */
1859
1860 update_hp(svsp); /* update labels, row/col, page ind */
1861
1862 /* Update winsize struct to reflect screen size */
1863
1864 if(svsp->vs_tty)
1865 {
1866 svsp->vs_tty->t_winsize.ws_row = svsp->screen_rows;
1867 svsp->vs_tty->t_winsize.ws_col = svsp->maxcol;
1868
1869 svsp->vs_tty->t_winsize.ws_xpixel =
1870 (cols == SCR_COL80)? 720: 1056;
1871 svsp->vs_tty->t_winsize.ws_ypixel = 400;
1872
1873 if(svsp->vs_tty->t_pgrp) {
1874 PGRP_LOCK(svsp->vs_tty->t_pgrp);
1875 pgsignal(svsp->vs_tty->t_pgrp, SIGWINCH, 1);
1876 PGRP_UNLOCK(svsp->vs_tty->t_pgrp);
1877 }
1878 }
1879
1880 reallocate_scrollbuffer(svsp, svsp->scrollback_pages);
1881 return(1);
1882 }
1883
1884 /*---------------------------------------------------------------------------*
1885 * update HP stuff on screen
1886 *---------------------------------------------------------------------------*/
1887 void
1888 update_hp(struct video_state *svsp)
1889 {
1890 if(svsp->vt_pure_mode != M_HPVT)
1891 return;
1892
1893 fillw (user_attr | ' ',
1894 svsp->Crtat + svsp->screen_rows * svsp->maxcol,
1895 (svsp->screen_rowsize - svsp->screen_rows) * svsp->maxcol);
1896
1897 if (!svsp->labels_on)
1898 return;
1899
1900 /* update fkey labels */
1901
1902 fkl_off(svsp);
1903 fkl_on(svsp);
1904
1905 if(vsp == svsp)
1906 {
1907 /* update current displayed screen indicator */
1908
1909 *((svsp->Crtat + ((svsp->screen_rows + 2) * svsp->maxcol))
1910 + svsp->maxcol - 3) = user_attr | '[';
1911 *((svsp->Crtat + ((svsp->screen_rows + 2) * svsp->maxcol))
1912 + svsp->maxcol - 2) = user_attr | (current_video_screen +
1913 (current_video_screen < 10 ? '' : ('a' - 10)));
1914 *((svsp->Crtat + ((svsp->screen_rows + 2) * svsp->maxcol))
1915 + svsp->maxcol - 1) = user_attr | ']';
1916 }
1917 }
1918
1919 /*---------------------------------------------------------------------------*
1920 * initialize ANSI escape sequence parameter buffers
1921 *---------------------------------------------------------------------------*/
1922 void
1923 clr_parms(struct video_state *svsp)
1924 {
1925 register int i;
1926 for(i=0; i < MAXPARMS; i++)
1927 svsp->parms[i] = 0;
1928 svsp->parmi = 0;
1929 }
1930
1931
1932 /*---------------------------------------------------------------------------*
1933 *
1934 * partial HP 2392 ANSI mode Emulator
1935 * ==================================
1936 *
1937 * this part takes over the emulation of some escape sequences
1938 * needed to handle the function key labels
1939 *
1940 * They are modeled after the corresponding escape sequences
1941 * introduced with the HP2392 terminals from Hewlett-Packard.
1942 *
1943 * see:
1944 * "HP2392A, Display Terminal Reference Manual",
1945 * HP Manual Part Number 02390-90001
1946 * and:
1947 * Reference Manual Supplement
1948 * "2392A Display Terminal Option 049, ANSI Operation"
1949 * HP Manual Part Number 02390-90023EN
1950 *
1951 *---------------------------------------------------------------------------*/
1952
1953 static void
1954 hp_entry(int ch, struct video_state *svsp)
1955 {
1956 switch(svsp->hp_state)
1957 {
1958 case SHP_INIT:
1959 switch(ch)
1960 {
1961 case 'f':
1962 svsp->hp_state = SHP_AND_F;
1963 svsp->attribute = 0;
1964 svsp->key = 0;
1965 svsp->l_len = 0;
1966 svsp->s_len = 0;
1967 svsp->i = 0;
1968 break;
1969
1970 case 'j':
1971 svsp->m_len = 0;
1972 svsp->hp_state = SHP_AND_J;
1973 break;
1974
1975 case 's':
1976 svsp->hp_state = SHP_AND_ETE;
1977 break;
1978
1979 default:
1980 svsp->hp_state = SHP_INIT;
1981 svsp->state = STATE_INIT;
1982 break;
1983 }
1984 break;
1985
1986 case SHP_AND_F:
1987 if((ch >= '') && (ch <= '8'))
1988 {
1989 svsp->attribute = ch;
1990 svsp->hp_state = SHP_AND_Fa;
1991 }
1992 else
1993 {
1994 svsp->hp_state = SHP_INIT;
1995 svsp->state = STATE_INIT;
1996 }
1997 break;
1998
1999 case SHP_AND_Fa:
2000 if(ch == 'a')
2001 svsp->hp_state = SHP_AND_Fak;
2002 else if(ch == 'k')
2003 {
2004 svsp->key = svsp->attribute;
2005 svsp->hp_state = SHP_AND_Fakd;
2006 }
2007 else
2008 {
2009 svsp->hp_state = SHP_INIT;
2010 svsp->state = STATE_INIT;
2011 }
2012 break;
2013
2014 case SHP_AND_Fak:
2015 if((ch >= '1') && (ch <= '8'))
2016 {
2017 svsp->key = ch;
2018 svsp->hp_state = SHP_AND_Fak1;
2019 }
2020 else
2021 {
2022 svsp->hp_state = SHP_INIT;
2023 svsp->state = STATE_INIT;
2024 }
2025 break;
2026
2027 case SHP_AND_Fak1:
2028 if(ch == 'k')
2029 svsp->hp_state = SHP_AND_Fakd;
2030 else
2031 {
2032 svsp->hp_state = SHP_INIT;
2033 svsp->state = STATE_INIT;
2034 }
2035 break;
2036
2037 case SHP_AND_Fakd:
2038 if(svsp->l_len > 16)
2039 {
2040 svsp->hp_state = SHP_INIT;
2041 svsp->state = STATE_INIT;
2042 }
2043 else if(ch >= '' && ch <= '9')
2044 {
2045 svsp->l_len *= 10;
2046 svsp->l_len += (ch -'');
2047 }
2048 else if(ch == 'd')
2049 svsp->hp_state = SHP_AND_FakdL;
2050 else
2051 {
2052 svsp->hp_state = SHP_INIT;
2053 svsp->state = STATE_INIT;
2054 }
2055 break;
2056
2057 case SHP_AND_FakdL:
2058 if(svsp->s_len > 80)
2059 {
2060 svsp->hp_state = SHP_INIT;
2061 svsp->state = STATE_INIT;
2062 }
2063 else if(ch >= '' && ch <= '9')
2064 {
2065 svsp->s_len *= 10;
2066 svsp->s_len += (ch -'');
2067 }
2068 else if(ch == 'L')
2069 {
2070 svsp->hp_state = SHP_AND_FakdLl;
2071 svsp->transparent = 1;
2072 }
2073 else
2074 {
2075 svsp->hp_state = SHP_INIT;
2076 svsp->state = STATE_INIT;
2077 }
2078 break;
2079
2080 case SHP_AND_FakdLl:
2081 svsp->l_buf[svsp->i] = ch;
2082 if(svsp->i >= svsp->l_len-1)
2083 {
2084 svsp->hp_state = SHP_AND_FakdLls;
2085 svsp->i = 0;
2086 if(svsp->s_len == 0)
2087 {
2088 svsp->state = STATE_INIT;
2089 svsp->hp_state = SHP_INIT;
2090 svsp->transparent = 0;
2091 svsp->i = 0;
2092 svsp->l_buf[svsp->l_len] = '\0';
2093 svsp->s_buf[svsp->s_len] = '\0';
2094 writefkl((svsp->key - '' -1),
2095 svsp->l_buf, svsp);
2096 }
2097 }
2098 else
2099 svsp->i++;
2100 break;
2101
2102 case SHP_AND_FakdLls:
2103 svsp->s_buf[svsp->i] = ch;
2104 if(svsp->i >= svsp->s_len-1)
2105 {
2106 svsp->state = STATE_INIT;
2107 svsp->hp_state = SHP_INIT;
2108 svsp->transparent = 0;
2109 svsp->i = 0;
2110 svsp->l_buf[svsp->l_len] = '\0';
2111 svsp->s_buf[svsp->s_len] = '\0';
2112 writefkl((svsp->key - '' -1), svsp->l_buf,
2113 svsp);
2114 }
2115 else
2116 svsp->i++;
2117 break;
2118
2119 case SHP_AND_J:
2120 switch(ch)
2121 {
2122 case '@': /* enable user keys, remove */
2123 /* all labels & status from */
2124 /* screen */
2125 svsp->hp_state = SHP_INIT;
2126 svsp->state = STATE_INIT;
2127 fkl_off(svsp);
2128 break;
2129
2130 case 'A': /* enable & display "modes" */
2131 svsp->hp_state = SHP_INIT;
2132 svsp->state = STATE_INIT;
2133 fkl_on(svsp);
2134 sw_sfkl(svsp);
2135 break;
2136
2137 case 'B': /* enable & display "user" */
2138 svsp->hp_state = SHP_INIT;
2139 svsp->state = STATE_INIT;
2140 fkl_on(svsp);
2141 sw_ufkl(svsp);
2142 break;
2143
2144 case 'C': /* remove (clear) status line*/
2145 /* and restore current labels*/
2146 svsp->hp_state = SHP_INIT;
2147 svsp->state = STATE_INIT;
2148 fkl_on(svsp);
2149 break;
2150
2151 case 'R': /* enable usr/menu keys */
2152 /* and fkey label modes */
2153 svsp->hp_state = SHP_INIT;
2154 svsp->state = STATE_INIT;
2155 break;
2156
2157 case 'S': /* disable usr/menu keys */
2158 /* and fkey label modes */
2159 svsp->hp_state = SHP_INIT;
2160 svsp->state = STATE_INIT;
2161 break;
2162
2163 case '':
2164 case '1':
2165 case '2':
2166 case '3':
2167 case '4':
2168 case '5':
2169 case '6':
2170 case '7':
2171 case '8':
2172 case '9': /* parameters for esc & j xx L mm */
2173 svsp->m_len *= 10;
2174 svsp->m_len += (ch -'');
2175 break;
2176
2177 case 'L':
2178 svsp->hp_state = SHP_AND_JL;
2179 svsp->i = 0;
2180 svsp->transparent = 1;
2181 break;
2182
2183 default:
2184 svsp->hp_state = SHP_INIT;
2185 svsp->state = STATE_INIT;
2186 break;
2187
2188 }
2189 break;
2190
2191
2192 case SHP_AND_JL:
2193 svsp->m_buf[svsp->i] = ch;
2194 if(svsp->i >= svsp->m_len-1)
2195 {
2196 svsp->state = STATE_INIT;
2197 svsp->hp_state = SHP_INIT;
2198 svsp->transparent = 0;
2199 svsp->i = 0;
2200 svsp->m_buf[svsp->m_len] = '\0';
2201 /* display status line */
2202 /* needs to be implemented */
2203 /* see 2392 man, 3-14 */
2204
2205 }
2206 else
2207 svsp->i++;
2208 break;
2209
2210 case SHP_AND_ETE: /* eat chars until uppercase */
2211 if(ch >= '@' && ch <= 'Z')
2212 {
2213 svsp->hp_state = SHP_INIT;
2214 svsp->state = STATE_INIT;
2215 svsp->transparent = 0;
2216 }
2217 break;
2218
2219 default:
2220 svsp->hp_state = SHP_INIT;
2221 svsp->state = STATE_INIT;
2222 svsp->transparent = 0;
2223 break;
2224 }
2225 }
2226
2227 /* ------------------------- E O F ------------------------------------------*/
Cache object: 7705db29e6049be4a2a4dff7e4509674
|