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