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