Device layer rollup commit.
[dragonfly.git] / sys / dev / video / pcvt / i386 / pcvt_kbd.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 and Holger Veit.
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  * This code is derived from software contributed to 386BSD by
14  * Holger Veit.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  * 3. All advertising materials mentioning features or use of this software
25  *    must display the following acknowledgement:
26  *      This product includes software developed by Hellmuth Michaelis,
27  *      Brian Dunford-Shore and Joerg Wunsch.
28  * 4. The name authors may not be used to endorse or promote products
29  *    derived from this software without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
32  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41  */
42
43 /*---------------------------------------------------------------------------*
44  *
45  *      pcvt_kbd.c      VT220 Driver Keyboard Interface Code
46  *      ----------------------------------------------------
47  *
48  *      Last Edit-Date: [Mon Dec 27 14:01:50 1999]
49  *
50  * $FreeBSD: src/sys/i386/isa/pcvt/pcvt_kbd.c,v 1.32.2.1 2000/10/29 16:59:28 dwmalone Exp $
51  * $DragonFly: src/sys/dev/video/pcvt/i386/Attic/pcvt_kbd.c,v 1.5 2004/05/19 22:52:54 dillon Exp $
52  *
53  *---------------------------------------------------------------------------*/
54
55 #include "use_vt.h"
56 #include "opt_ddb.h"
57
58 #if NVT > 0
59
60 #include "pcvt_hdr.h"   /* global include */
61
62 #define LEDSTATE_UPDATE_PENDING (1 << 3)
63
64 static void fkey1(void), fkey2(void),  fkey3(void),  fkey4(void);
65 static void fkey5(void), fkey6(void),  fkey7(void),  fkey8(void);
66 static void fkey9(void), fkey10(void), fkey11(void), fkey12(void);
67
68 static void sfkey1(void), sfkey2(void),  sfkey3(void),  sfkey4(void);
69 static void sfkey5(void), sfkey6(void),  sfkey7(void),  sfkey8(void);
70 static void sfkey9(void), sfkey10(void), sfkey11(void), sfkey12(void);
71
72 static void cfkey1(void), cfkey2(void),  cfkey3(void),  cfkey4(void);
73 static void cfkey5(void), cfkey6(void),  cfkey7(void),  cfkey8(void);
74 static void cfkey9(void), cfkey10(void), cfkey11(void), cfkey12(void);
75
76 static void     doreset ( void );
77 static void     ovlinit ( int force );
78 static void     settpmrate ( int rate );
79 static void     setlockkeys ( int snc );
80 #ifndef _DEV_KBD_KBDREG_H_
81 static int      kbc_8042cmd ( int val );
82 #endif /* !_DEV_KBD_KBDREG_H_ */
83 static int      getokeydef ( unsigned key, struct kbd_ovlkey *thisdef );
84 static int      getckeydef ( unsigned key, struct kbd_ovlkey *thisdef );
85 static int      rmkeydef ( int key );
86 static int      setkeydef ( struct kbd_ovlkey *data );
87 static u_char * xlatkey2ascii( U_short key );
88
89 static int      ledstate  = LEDSTATE_UPDATE_PENDING;    /* keyboard led's */
90 static int      tpmrate   = KBD_TPD500|KBD_TPM100;
91 static u_char   altkpflag = 0;
92 static u_short  altkpval  = 0;
93
94 static u_short *scrollback_savedscreen = (u_short *)0;
95 static size_t scrnsv_size = (size_t)-1;
96 static void scrollback_save_screen ( void );
97 static void scrollback_restore_screen ( void );
98
99 #if PCVT_SHOWKEYS
100 u_char rawkeybuf[80];
101 #endif
102
103 #include "pcvt_kbd.h"   /* tables etc */
104
105 #if PCVT_SHOWKEYS
106 /*---------------------------------------------------------------------------*
107  *      keyboard debugging: put kbd communication char into some buffer
108  *---------------------------------------------------------------------------*/
109 static void showkey (char delim, u_char val)
110 {
111         int rki;
112
113         for(rki = 3; rki < 80; rki++)           /* shift left buffer */
114                 rawkeybuf[rki-3] = rawkeybuf[rki];
115
116         rawkeybuf[77] = delim;          /* delimiter */
117
118         rki = (val & 0xf0) >> 4;        /* ms nibble */
119
120         if(rki <= 9)
121                 rki = rki + '0';
122         else
123                 rki = rki - 10 + 'A';
124
125         rawkeybuf[78] = rki;
126
127         rki = val & 0x0f;               /* ls nibble */
128
129         if(rki <= 9)
130                 rki = rki + '0';
131         else
132                 rki = rki - 10 + 'A';
133
134         rawkeybuf[79] = rki;
135 }
136 #endif  /* PCVT_SHOWKEYS */
137
138 /*---------------------------------------------------------------------------*
139  *      function to switch to another virtual screen
140  *---------------------------------------------------------------------------*/
141 static void
142 do_vgapage(int page)
143 {
144         if(critical_scroll)             /* executing critical region ? */
145                 switch_page = page;     /* yes, auto switch later */
146         else
147                 vgapage(page);          /* no, switch now */
148 }
149
150
151 /*
152  * This code from Lon Willett enclosed in #if PCVT_UPDLED_LOSES_INTR is
153  * abled because it crashes FreeBSD 1.1.5.1 at boot time.
154  * The cause is obviously that the timeout queue is not yet initialized
155  * timeout is called from here the first time.
156  * Anyway it is a pointer in the right direction so it is included for
157  * reference here.
158  */
159
160 #define PCVT_UPDLED_LOSES_INTR  0       /* disabled for now */
161
162 #if PCVT_UPDLED_LOSES_INTR || defined(_DEV_KBD_KBDREG_H_)
163
164 /*---------------------------------------------------------------------------*
165  *      check for lost keyboard interrupts
166  *---------------------------------------------------------------------------*/
167
168 /*
169  * The two commands to change the LEDs generate two KEYB_R_ACK responses
170  * from the keyboard, which aren't explicitly checked for (maybe they
171  * should be?).  However, when a lot of other I/O is happening, one of
172  * the interrupts sometimes gets lost (I'm not sure of the details of
173  * how and why and what hardware this happens with).
174  *
175  * This may have had something to do with spltty() previously not being
176  * called before the kbd_cmd() calls in update_led().
177  *
178  * This is a real problem, because normally the keyboard is only polled
179  * by pcrint(), and no more interrupts will be generated until the ACK
180  * has been read.  So the keyboard is hung.  This code polls a little
181  * while after changing the LEDs to make sure that this hasn't happened.
182  *
183  * XXX Quite possibly we should poll the kbd on a regular basis anyway,
184  * in the interest of robustness.  It may be possible that interrupts
185  * get lost other times as well.
186  */
187
188 static int lost_intr_timeout_queued = 0;
189 static struct callout_handle lost_intr_ch =
190     CALLOUT_HANDLE_INITIALIZER(&lost_intr_ch);
191
192 static void
193 check_for_lost_intr (void *arg)
194 {
195 #ifndef _DEV_KBD_KBDREG_H_
196         lost_intr_timeout_queued = 0;
197         if (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)
198         {
199                 int opri = spltty ();
200                 pcrint ();
201                 splx (opri);
202         }
203 #else
204         int opri;
205
206         lost_intr_timeout_queued = 0;
207         if (kbd && (*kbdsw[kbd->kb_index]->lock)(kbd, TRUE)) {
208                 opri = spltty ();
209                 (*kbdsw[kbd->kb_index]->lock)(kbd, FALSE);
210                 if ((*kbdsw[kbd->kb_index]->check)(kbd))
211                         pcrint (0);
212                 splx (opri);
213         }
214
215         lost_intr_ch = timeout(check_for_lost_intr, (void *)NULL, hz);
216         lost_intr_timeout_queued = 1;
217 #endif /* !_DEV_KBD_KBDREG_H_ */
218 }
219
220 #endif /* PCVT_UPDLED_LOSES_INTR || defined(_DEV_KBD_KBDREG_H_) */
221
222 /*---------------------------------------------------------------------------*
223  *      update keyboard led's
224  *---------------------------------------------------------------------------*/
225 void
226 update_led(void)
227 {
228 #if !PCVT_NO_LED_UPDATE
229
230         /* Don't update LED's unless necessary. */
231
232         int opri, new_ledstate;
233
234         opri = spltty();
235 #ifndef _DEV_KBD_KBDREG_H_
236         new_ledstate = (vsp->scroll_lock) |
237                        (vsp->num_lock * 2) |
238                        (vsp->caps_lock * 4);
239 #else
240         new_ledstate = ((vsp->scroll_lock) ? LED_SCR : 0) |
241                        ((vsp->num_lock) ? LED_NUM : 0) |
242                        ((vsp->caps_lock) ? LED_CAP : 0);
243 #endif /* _DEV_KBD_KBDREG_H_ */
244
245         if (new_ledstate != ledstate)
246         {
247 #ifndef _DEV_KBD_KBDREG_H_
248                 int response1, response2;
249
250                 ledstate = LEDSTATE_UPDATE_PENDING;
251
252                 if(kbd_cmd(KEYB_C_LEDS) != 0)
253                 {
254                         printf("Keyboard LED command timeout\n");
255                         splx(opri);
256                         return;
257                 }
258
259                 /*
260                  * For some keyboards or keyboard controllers, it is an
261                  * error to issue a command without waiting long enough
262                  * for an ACK for the previous command.  The keyboard
263                  * gets confused, and responds with KEYB_R_RESEND, but
264                  * we ignore that.  Wait for the ACK here.  The busy
265                  * waiting doesn't matter much, since we lose anyway by
266                  * busy waiting to send the command.
267                  *
268                  * XXX actually wait for any response, since we can't
269                  * handle normal scancodes here.
270                  *
271                  * XXX all this should be interrupt driven.  Issue only
272                  * one command at a time wait for a ACK before proceeding.
273                  * Retry after a timeout or on receipt of a KEYB_R_RESEND.
274                  * KEYB_R_RESENDs seem to be guaranteed by working
275                  * keyboard controllers with broken (or disconnected)
276                  * keyboards.  There is another code for keyboard
277                  * reconnects.  The keyboard hardware is very simple and
278                  * well designed :-).
279                  */
280                 response1 = kbd_response();
281
282                 if(kbd_cmd(new_ledstate) != 0) {
283                         printf("Keyboard LED data timeout\n");
284                         splx(opri);
285                         return;
286                 }
287                 response2 = kbd_response();
288
289                 if (response1 == KEYB_R_ACK && response2 == KEYB_R_ACK)
290                         ledstate = new_ledstate;
291                 else
292                         printf(
293                         "Keyboard LED command not ACKed (responses %#x %#x)\n",
294                                response1, response2);
295 #else /* _DEV_KBD_KBDREG_H_ */
296
297                 if (kbd == NULL) {
298                         ledstate = new_ledstate;
299                         splx(opri);
300                 } else {
301                         ledstate = LEDSTATE_UPDATE_PENDING;
302                         splx(opri);
303                         if ((*kbdsw[kbd->kb_index]->ioctl)(kbd, KDSETLED,
304                                         (caddr_t)&new_ledstate) == 0) 
305                                 ledstate = new_ledstate;
306                 }
307
308 #endif /* !_DEV_KBD_KBDREG_H_ */
309
310 #if PCVT_UPDLED_LOSES_INTR
311                 if (lost_intr_timeout_queued)
312                         untimeout(check_for_lost_intr, NULL, lost_intr_ch);
313
314                 lost_intr_ch = timeout(check_for_lost_intr, NULL, hz);
315                 lost_intr_timeout_queued = 1;
316 #endif /* PCVT_UPDLED_LOSES_INTR */
317
318         }
319
320 #ifndef _DEV_KBD_KBDREG_H_
321         splx(opri);
322 #endif 
323
324 #endif /* !PCVT_NO_LED_UPDATE */
325 }
326
327 /*---------------------------------------------------------------------------*
328  *      set typematic rate
329  *---------------------------------------------------------------------------*/
330 static void
331 settpmrate(int rate)
332 {
333 #ifndef _DEV_KBD_KBDREG_H_
334         tpmrate = rate & 0x7f;
335         if(kbd_cmd(KEYB_C_TYPEM) != 0)
336                 printf("Keyboard TYPEMATIC command timeout\n");
337         else if(kbd_cmd(tpmrate) != 0)
338                 printf("Keyboard TYPEMATIC data timeout\n");
339 #else
340         if (kbd == NULL)
341                 return;
342         tpmrate = rate & 0x7f;
343         if ((*kbdsw[kbd->kb_index]->ioctl)(kbd, KDSETRAD, (caddr_t)&tpmrate))
344                 printf("pcvt: failed to set keyboard TYPEMATIC.\n");
345 #endif /* !_DEV_KBD_KBDREG_H_ */
346 }
347
348 #ifndef _DEV_KBD_KBDREG_H_
349 /*---------------------------------------------------------------------------*
350  *      Pass command to keyboard controller (8042)
351  *---------------------------------------------------------------------------*/
352 static int
353 kbc_8042cmd(int val)
354 {
355         unsigned timeo;
356
357         timeo = 100000;         /* > 100 msec */
358         while (inb(CONTROLLER_CTRL) & STATUS_INPBF)
359                 if (--timeo == 0)
360                         return (-1);
361         outb(CONTROLLER_CTRL, val);
362         return (0);
363 }
364
365 /*---------------------------------------------------------------------------*
366  *      Pass command to keyboard itself
367  *---------------------------------------------------------------------------*/
368 int
369 kbd_cmd(int val)
370 {
371         unsigned timeo;
372
373         timeo = 100000;         /* > 100 msec */
374         while (inb(CONTROLLER_CTRL) & STATUS_INPBF)
375                 if (--timeo == 0)
376                         return (-1);
377         outb(CONTROLLER_DATA, val);
378
379 #if PCVT_SHOWKEYS
380         showkey ('>', val);
381 #endif  /* PCVT_SHOWKEYS */
382
383         return (0);
384 }
385
386 /*---------------------------------------------------------------------------*
387  *      Read response from keyboard
388  *      NB: make sure to call spltty() before kbd_cmd(), kbd_response().
389  *---------------------------------------------------------------------------*/
390 int
391 kbd_response(void)
392 {
393         u_char ch;
394         unsigned timeo;
395
396         timeo = 500000;         /* > 500 msec (KEYB_R_SELFOK requires 87) */
397         while (!(inb(CONTROLLER_CTRL) & STATUS_OUTPBF))
398                 if (--timeo == 0)
399                         return (-1);
400
401         PCVT_KBD_DELAY();               /* 7 us delay */
402         ch = inb(CONTROLLER_DATA);
403
404 #if PCVT_SHOWKEYS
405         showkey ('<', ch);
406 #endif  /* PCVT_SHOWKEYS */
407
408         return ch;
409 }
410 #endif /* _DEV_KBD_KBDREG_H_ */
411
412 #if PCVT_SCANSET > 1
413 /*---------------------------------------------------------------------------*
414  *      switch PC scan code emulation mode
415  *---------------------------------------------------------------------------*/
416 void
417 kbd_emulate_pc(int do_emulation)
418 {
419 #ifndef _DEV_KBD_KBDREG_H_
420         int cmd, timeo = 10000;
421
422         cmd = COMMAND_SYSFLG|COMMAND_IRQEN; /* common base cmd */
423
424 #if !PCVT_USEKBDSEC
425         cmd |= COMMAND_INHOVR;
426 #endif
427
428         if(do_emulation)
429                 cmd |= COMMAND_PCSCAN;
430
431         kbc_8042cmd(CONTR_WRITE);
432         while (inb(CONTROLLER_CTRL) & STATUS_INPBF)
433                 if (--timeo == 0)
434                         break;
435         outb(CONTROLLER_DATA, cmd);
436 #else
437         set_controller_command_byte(*(KBDC *)kbd->kb_data, KBD_TRANSLATION, 
438                 (do_emulation) ? KBD_TRANSLATION : 0);
439 #endif /* !_DEV_KBD_KBDREG_H_ */
440 }
441
442 #endif /* PCVT_SCANSET > 1 */
443
444
445 #ifndef PCVT_NONRESP_KEYB_TRY
446 #define PCVT_NONRESP_KEYB_TRY   25      /* no of times to try to detect */
447 #endif                                  /* a nonresponding keyboard     */
448
449 /*---------------------------------------------------------------------------*
450  *      try to force keyboard into a known state ..
451  *---------------------------------------------------------------------------*/
452 static
453 void doreset(void)
454 {
455 #ifndef _DEV_KBD_KBDREG_H_
456         int again = 0;
457         int once = 0;
458         int response, opri;
459
460         /* Enable interrupts and keyboard, etc. */
461         if (kbc_8042cmd(CONTR_WRITE) != 0)
462                 printf("pcvt: doreset() - timeout controller write command\n");
463
464 #if PCVT_USEKBDSEC              /* security enabled */
465
466 #  if PCVT_SCANSET == 2
467 #    define KBDINITCMD COMMAND_SYSFLG|COMMAND_IRQEN
468 #  else /* PCVT_SCANSET != 2 */
469 #    define KBDINITCMD COMMAND_PCSCAN|COMMAND_SYSFLG|COMMAND_IRQEN
470 #  endif /* PCVT_SCANSET == 2 */
471
472 #else /* ! PCVT_USEKBDSEC */    /* security disabled */
473
474 #  if PCVT_SCANSET == 2
475 #    define KBDINITCMD COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN
476 #  else /* PCVT_SCANSET != 2 */
477 #    define KBDINITCMD COMMAND_PCSCAN|COMMAND_INHOVR|COMMAND_SYSFLG\
478         |COMMAND_IRQEN
479 #  endif /* PCVT_SCANSET == 2 */
480
481 #endif /* PCVT_USEKBDSEC */
482
483         if (kbd_cmd(KBDINITCMD) != 0)
484                 printf("pcvt: doreset() - timeout writing keyboard init command\n");
485
486         /*
487          * Discard any stale keyboard activity.  The 0.1 boot code isn't
488          * very careful and sometimes leaves a KEYB_R_RESEND.  Versions
489          * between 1992 and Oct 1996 didn't have the delay and sometimes
490          * left a KEYB_R_RESEND.
491          */
492         while (1) {
493                 if (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)
494                         kbd_response();
495                 else {
496                         DELAY(10000);
497                         if (!(inb(CONTROLLER_CTRL) & STATUS_OUTPBF))
498                                 break;
499                 }
500         }
501
502         /* Start keyboard reset */
503
504         opri = spltty ();
505
506         if (kbd_cmd(KEYB_C_RESET) != 0)
507         {
508                 printf("pcvt: doreset() - timeout for keyboard reset command\n");
509                 outb(CONTROLLER_DATA, KEYB_C_RESET);    /* force */
510         }
511
512         /* Wait for the first response to reset and handle retries */
513         while ((response = kbd_response()) != KEYB_R_ACK)
514         {
515                 if (response < 0)
516                 {
517                         if(!again)      /* print message only once ! */
518                                 printf("pcvt: doreset() - response != ack and response < 0 [one time only msg]\n");
519                         response = KEYB_R_RESEND;
520                 }
521                 else if (response == KEYB_R_RESEND)
522                 {
523                         if(!again)      /* print message only once ! */
524                                 printf("pcvt: doreset() - got KEYB_R_RESEND response ... [one time only msg]\n");
525                 }
526                 if (response == KEYB_R_RESEND)
527                 {
528                         if(++again > PCVT_NONRESP_KEYB_TRY)
529                         {
530                                 printf("pcvt: doreset() - Caution - no PC keyboard detected!\n");
531                                 keyboard_type = KB_UNKNOWN;
532                                 splx(opri);
533                                 return;
534                         }
535
536                         if((kbd_cmd(KEYB_C_RESET) != 0) && (once == 0))
537                         {
538                                 once++;         /* print message only once ! */
539                                 printf("pcvt: doreset() - timeout for loop keyboard reset command [one time only msg]\n");
540                                 outb(CONTROLLER_DATA, KEYB_C_RESET);    /* force */
541                         }
542                 }
543         }
544
545         /* Wait for the second response to reset */
546
547         while ((response = kbd_response()) != KEYB_R_SELFOK)
548         {
549                 if (response < 0)
550                 {
551                         printf("pcvt: doreset() - response != OK and resonse < 0\n");
552                         /*
553                          * If KEYB_R_SELFOK never arrives, the loop will
554                          * finish here unless the keyboard babbles or
555                          * STATUS_OUTPBF gets stuck.
556                          */
557                         break;
558                 }
559         }
560
561         splx (opri);
562
563 #if PCVT_KEYBDID
564
565         opri = spltty ();
566
567         if(kbd_cmd(KEYB_C_ID) != 0)
568         {
569                 printf("pcvt: doreset() - timeout for keyboard ID command\n");
570                 keyboard_type = KB_UNKNOWN;
571         }
572         else
573         {
574
575 r_entry:
576
577                 if((response = kbd_response()) == KEYB_R_MF2ID1)
578                 {
579                         if((response = kbd_response()) == KEYB_R_MF2ID2)
580                         {
581                                 keyboard_type = KB_MFII;
582                         }
583                         else if(response == KEYB_R_MF2ID2HP)
584                         {
585                                 keyboard_type = KB_MFII;
586                         }
587                         else
588                         {
589                                 printf("\npcvt: doreset() - kbdid, response 2 = [%d]\n",
590                                        response);
591                                 keyboard_type = KB_UNKNOWN;
592                         }
593                 }
594                 else if (response == KEYB_R_ACK)
595                 {
596                         goto r_entry;
597                 }
598                 else if (response == -1)
599                 {
600                         keyboard_type = KB_AT;
601                 }
602                 else
603                 {
604                         printf("\npcvt: doreset() - kbdid, response 1 = [%d]\n", response);
605                 }
606         }
607
608         splx (opri);
609
610 #else /* PCVT_KEYBDID */
611
612         keyboard_type = KB_MFII;        /* force it .. */
613
614 #endif /* PCVT_KEYBDID */
615
616 #else /* _DEV_KBD_KBDREG_H_ */
617         int type;
618
619         if (!reset_keyboard)    /* no, we are not ready to reset */
620                 return;
621
622         if (lost_intr_timeout_queued) {
623                 untimeout(check_for_lost_intr, (void *)NULL, lost_intr_ch);
624                 lost_intr_timeout_queued = 0;
625         }
626
627         if (kbd == NULL)
628                 return;         /* shouldn't happen */
629         kbd_configure(0);
630
631         ledstate = LEDSTATE_UPDATE_PENDING;
632
633 #if PCVT_USEKBDSEC              /* security enabled */
634
635 #  if PCVT_SCANSET == 2
636 #    define KBDINITCMD 0
637 #  else /* PCVT_SCANSET != 2 */
638 #    define KBDINITCMD KBD_TRANSLATION
639 #  endif /* PCVT_SCANSET == 2 */
640
641 #else /* ! PCVT_USEKBDSEC */    /* security disabled */
642
643 #  if PCVT_SCANSET == 2
644 #    define KBDINITCMD KBD_OVERRIDE_KBD_LOCK
645 #  else /* PCVT_SCANSET != 2 */
646 #    define KBDINITCMD KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK
647 #  endif /* PCVT_SCANSET == 2 */
648
649 #endif /* PCVT_USEKBDSEC */
650
651         set_controller_command_byte(*(KBDC *)kbd->kb_data,
652                 KBD_OVERRIDE_KBD_LOCK | KBD_TRANSLATION, KBDINITCMD);
653
654         keyboard_type = KB_MFII;        /* force it .. */
655 #if PCVT_KEYBDID
656         type = KB_101;
657         (*kbdsw[kbd->kb_index]->ioctl)(kbd, KDGKBTYPE, (caddr_t)&type);
658         switch (type)
659         {
660         case KB_84:
661                 keyboard_type = KB_AT;
662                 break;
663         case KB_101:
664                 keyboard_type = KB_MFII;
665                 break;
666         default:
667                 keyboard_type = KB_UNKNOWN;
668                 break;
669         }
670 #endif /* PCVT_KEYBDID */
671
672         update_led();
673
674         lost_intr_ch = timeout(check_for_lost_intr, (void *)NULL, hz);
675         lost_intr_timeout_queued = 1;
676
677 #endif /* !_DEV_KBD_KBDREG_H_ */
678 }
679
680 /*---------------------------------------------------------------------------*
681  *      init keyboard code
682  *---------------------------------------------------------------------------*/
683 void
684 kbd_code_init(void)
685 {
686         doreset();
687         ovlinit(0);
688         keyboard_is_initialized = 1;
689 }
690
691 /*---------------------------------------------------------------------------*
692  *      init keyboard code, this initializes the keyboard subsystem
693  *      just "a bit" so the very very first ddb session is able to
694  *      get proper keystrokes - in other words, it's a hack ....
695  *---------------------------------------------------------------------------*/
696 void
697 kbd_code_init1(void)
698 {
699         doreset();
700         keyboard_is_initialized = 1;
701 }
702
703 /*---------------------------------------------------------------------------*
704  *      init keyboard overlay table
705  *---------------------------------------------------------------------------*/
706 static
707 void ovlinit(int force)
708 {
709         int i;
710
711         if(force || ovlinitflag==0)
712         {
713                 if(ovlinitflag == 0 &&
714                    (ovltbl = (Ovl_tbl *)malloc(sizeof(Ovl_tbl) * OVLTBL_SIZE,
715                                                M_DEVBUF, M_WAITOK)) == NULL)
716                         panic("pcvt_kbd: malloc of Ovl_tbl failed");
717
718                 for(i=0; i<OVLTBL_SIZE; i++)
719                 {
720                         ovltbl[i].keynum =
721                         ovltbl[i].type = 0;
722                         ovltbl[i].unshift[0] =
723                         ovltbl[i].shift[0] =
724                         ovltbl[i].ctrl[0] =
725                         ovltbl[i].altgr[0] = 0;
726                         ovltbl[i].subu =
727                         ovltbl[i].subs =
728                         ovltbl[i].subc =
729                         ovltbl[i].suba = KBD_SUBT_STR;  /* just strings .. */
730                 }
731                 for(i=0; i<=MAXKEYNUM; i++)
732                         key2ascii[i].type &= KBD_MASK;
733                 ovlinitflag = 1;
734         }
735 }
736
737 /*---------------------------------------------------------------------------*
738  *      get original key definition
739  *---------------------------------------------------------------------------*/
740 static int
741 getokeydef(unsigned key, Ovl_tbl *thisdef)
742 {
743         if(key == 0 || key > MAXKEYNUM)
744                 return EINVAL;
745
746         thisdef->keynum = key;
747         thisdef->type = key2ascii[key].type;
748
749         if(key2ascii[key].unshift.subtype == STR)
750         {
751                 bcopy((u_char *)(key2ascii[key].unshift.what.string),
752                        thisdef->unshift, CODE_SIZE);
753                 thisdef->subu = KBD_SUBT_STR;
754         }
755         else
756         {
757                 bcopy("", thisdef->unshift, CODE_SIZE);
758                 thisdef->subu = KBD_SUBT_FNC;
759         }
760
761         if(key2ascii[key].shift.subtype == STR)
762         {
763                 bcopy((u_char *)(key2ascii[key].shift.what.string),
764                        thisdef->shift, CODE_SIZE);
765                 thisdef->subs = KBD_SUBT_STR;
766         }
767         else
768         {
769                 bcopy("",thisdef->shift,CODE_SIZE);
770                 thisdef->subs = KBD_SUBT_FNC;
771         }
772
773         if(key2ascii[key].ctrl.subtype == STR)
774         {
775                 bcopy((u_char *)(key2ascii[key].ctrl.what.string),
776                        thisdef->ctrl, CODE_SIZE);
777                 thisdef->subc = KBD_SUBT_STR;
778         }
779         else
780         {
781                 bcopy("",thisdef->ctrl,CODE_SIZE);
782                 thisdef->subc = KBD_SUBT_FNC;
783         }
784
785         /* deliver at least anything for ALTGR settings ... */
786
787         if(key2ascii[key].unshift.subtype == STR)
788         {
789                 bcopy((u_char *)(key2ascii[key].unshift.what.string),
790                        thisdef->altgr, CODE_SIZE);
791                 thisdef->suba = KBD_SUBT_STR;
792         }
793         else
794         {
795                 bcopy("",thisdef->altgr, CODE_SIZE);
796                 thisdef->suba = KBD_SUBT_FNC;
797         }
798         return 0;
799 }
800
801 /*---------------------------------------------------------------------------*
802  *      get current key definition
803  *---------------------------------------------------------------------------*/
804 static int
805 getckeydef(unsigned key, Ovl_tbl *thisdef)
806 {
807         u_short type = key2ascii[key].type;
808
809         if(key>MAXKEYNUM)
810                 return EINVAL;
811
812         if(type & KBD_OVERLOAD)
813                 *thisdef = ovltbl[key2ascii[key].ovlindex];
814         else
815                 getokeydef(key,thisdef);
816
817         return 0;
818 }
819
820 /*---------------------------------------------------------------------------*
821  *      translate keynumber and returns ptr to associated ascii string
822  *      if key is bound to a function, executes it, and ret empty ptr
823  *---------------------------------------------------------------------------*/
824 static u_char *
825 xlatkey2ascii(U_short key)
826 {
827         static u_char   capchar[2] = {0, 0};
828 #if PCVT_META_ESC
829         static u_char   metachar[3] = {0x1b, 0, 0};
830 #else
831         static u_char   metachar[2] = {0, 0};
832 #endif
833         static Ovl_tbl  thisdef;
834         int             n;
835         void            (*fnc)(void);
836
837         if(key==0)                      /* ignore the NON-KEY */
838                 return 0;
839
840         getckeydef(key&0x7F, &thisdef); /* get the current ASCII value */
841
842         thisdef.type &= KBD_MASK;
843
844         if(key&0x80)                    /* special handling of ALT-KEYPAD */
845         {
846                 /* is the ALT Key released? */
847                 if(thisdef.type==KBD_META || thisdef.type==KBD_ALTGR)
848                 {
849                         if(altkpflag)   /* have we been in altkp mode? */
850                         {
851                                 capchar[0] = altkpval;
852                                 altkpflag = 0;
853                                 altkpval = 0;
854                                 return capchar;
855                         }
856                 }
857                 return 0;
858         }
859
860         switch(thisdef.type)            /* convert the keys */
861         {
862                 case KBD_BREAK:
863                 case KBD_ASCII:
864                 case KBD_FUNC:
865                         fnc = NULL;
866                         more_chars = NULL;
867
868                         if(altgr_down)
869                         {
870                                 more_chars = (u_char *)thisdef.altgr;
871                         }
872                         else if(!ctrl_down && (shift_down || vsp->shift_lock))
873                         {
874                                 if(key2ascii[key].shift.subtype == STR)
875                                         more_chars = (u_char *)thisdef.shift;
876                                 else
877                                         fnc = key2ascii[key].shift.what.func;
878                         }
879
880                         else if(ctrl_down)
881                         {
882                                 if(key2ascii[key].ctrl.subtype == STR)
883                                         more_chars = (u_char *)thisdef.ctrl;
884                                 else
885                                         fnc = key2ascii[key].ctrl.what.func;
886                         }
887
888                         else
889                         {
890                                 if(key2ascii[key].unshift.subtype == STR)
891                                         more_chars = (u_char *)thisdef.unshift;
892                                 else
893                                         fnc = key2ascii[key].unshift.what.func;
894                         }
895
896                         if(fnc)
897                                 (*fnc)();       /* execute function */
898
899                         if((more_chars != NULL) && (more_chars[1] == 0))
900                         {
901                                 if(vsp->caps_lock && more_chars[0] >= 'a'
902                                    && more_chars[0] <= 'z')
903                                 {
904                                         capchar[0] = *more_chars - ('a'-'A');
905                                         more_chars = capchar;
906                                 }
907                                 if(meta_down)
908                                 {
909 #if PCVT_META_ESC
910                                         metachar[1] = *more_chars;
911 #else
912                                         metachar[0] = *more_chars | 0x80;
913 #endif
914                                         more_chars = metachar;
915                                 }
916                         }
917                         return(more_chars);
918
919                 case KBD_KP:
920                         fnc = NULL;
921                         more_chars = NULL;
922
923                         if(meta_down)
924                         {
925                                 switch(key)
926                                 {
927                                         case 95:        /* / */
928                                                 altkpflag = 0;
929                                                 more_chars =
930                                                  (u_char *)"\033OQ";
931                                                 return(more_chars);
932
933                                         case 100:       /* * */
934                                                 altkpflag = 0;
935                                                 more_chars =
936                                                  (u_char *)"\033OR";
937                                                 return(more_chars);
938
939                                         case 105:       /* - */
940                                                 altkpflag = 0;
941                                                 more_chars =
942                                                  (u_char *)"\033OS";
943                                                 return(more_chars);
944                                 }
945                         }
946
947                         if(meta_down || altgr_down)
948                         {
949                                 if((n = keypad2num[key-91]) >= 0)
950                                 {
951                                         if(!altkpflag)
952                                         {
953                                                 /* start ALT-KP mode */
954                                                 altkpflag = 1;
955                                                 altkpval = 0;
956                                         }
957                                         altkpval *= 10;
958                                         altkpval += n;
959                                 }
960                                 else
961                                         altkpflag = 0;
962                                 return 0;
963                         }
964
965                         if(!(vsp->num_lock))
966                         {
967                                 if(key2ascii[key].shift.subtype == STR)
968                                         more_chars = (u_char *)thisdef.shift;
969                                 else
970                                         fnc = key2ascii[key].shift.what.func;
971                         }
972                         else
973                         {
974                                 if(key2ascii[key].unshift.subtype == STR)
975                                         more_chars = (u_char *)thisdef.unshift;
976                                 else
977                                         fnc = key2ascii[key].unshift.what.func;
978                         }
979
980                         if(fnc)
981                                 (*fnc)();       /* execute function */
982                         return(more_chars);
983
984                 case KBD_CURSOR:
985                         fnc = NULL;
986                         more_chars = NULL;
987
988                         if(vsp->ckm)
989                         {
990                                 if(key2ascii[key].shift.subtype == STR)
991                                         more_chars = (u_char *)thisdef.shift;
992                                 else
993                                         fnc = key2ascii[key].shift.what.func;
994                         }
995                         else
996                         {
997                                 if(key2ascii[key].unshift.subtype == STR)
998                                         more_chars = (u_char *)thisdef.unshift;
999                                 else
1000                                         fnc = key2ascii[key].unshift.what.func;
1001                         }
1002
1003                         if(fnc)
1004                                 (*fnc)();       /* execute function */
1005                         return(more_chars);
1006
1007                 case KBD_NUM:           /*  special kp-num handling */
1008                         more_chars = NULL;
1009
1010                         if(meta_down)
1011                         {
1012                                 more_chars = (u_char *)"\033OP"; /* PF1 */
1013                         }
1014                         else
1015                         {
1016                                 vsp->num_lock ^= 1;
1017                                 update_led();
1018                         }
1019                         return(more_chars);
1020
1021                 case KBD_RETURN:
1022                         more_chars = NULL;
1023
1024                         if(!(vsp->num_lock))
1025                         {
1026                                 more_chars = (u_char *)thisdef.shift;
1027                         }
1028                         else
1029                         {
1030                                 more_chars = (u_char *)thisdef.unshift;
1031                         }
1032                         if(vsp->lnm && (*more_chars == '\r'))
1033                         {
1034                                 more_chars = (u_char *)"\r\n"; /* CR LF */
1035                         }
1036                         if(meta_down)
1037                         {
1038 #if PCVT_META_ESC
1039                                 metachar[1] = *more_chars;
1040 #else
1041                                 metachar[0] = *more_chars | 0x80;
1042 #endif
1043                                 more_chars = metachar;
1044                         }
1045                         return(more_chars);
1046
1047                 case KBD_META:          /* these keys are       */
1048                 case KBD_ALTGR:         /*  handled directly    */
1049                 case KBD_SCROLL:        /*  by the keyboard     */
1050                 case KBD_CAPS:          /*  handler - they are  */
1051                 case KBD_SHFTLOCK:      /*  ignored here        */
1052                 case KBD_CTL:
1053                 case KBD_NONE:
1054                 default:
1055                         return 0;
1056         }
1057 }
1058
1059 /*---------------------------------------------------------------------------*
1060  *      get keystrokes from the keyboard.
1061  *      if noblock = 0, wait until a key is pressed.
1062  *      else return NULL if no characters present.
1063  *---------------------------------------------------------------------------*/
1064
1065 #if PCVT_KBD_FIFO
1066 extern  u_char  pcvt_kbd_fifo[];
1067 extern  int     pcvt_kbd_rptr;
1068 extern  short   pcvt_kbd_count;
1069 #endif
1070
1071 u_char *
1072 sgetc(int noblock)
1073 {
1074         u_char          *cp;
1075         u_char          dt = 0;
1076         u_char          key = 0;
1077         u_short         type;
1078
1079 #if PCVT_KBD_FIFO && PCVT_SLOW_INTERRUPT
1080         int             s;
1081 #endif
1082
1083         static u_char   kbd_lastkey = 0; /* last keystroke */
1084
1085         static struct
1086         {
1087                 u_char extended: 1;     /* extended prefix seen */
1088                 u_char ext1: 1;         /* extended prefix 1 seen */
1089                 u_char breakseen: 1;    /* break code seen */
1090                 u_char vshift: 1;       /* virtual shift pending */
1091                 u_char vcontrol: 1;     /* virtual control pending */
1092                 u_char sysrq: 1;        /* sysrq pressed */
1093         } kbd_status = {0};
1094
1095 #ifdef XSERVER
1096         static char     keybuf[2] = {0}; /* the second 0 is a delimiter! */
1097 #endif /* XSERVER */
1098
1099 #ifdef _DEV_KBD_KBDREG_H_
1100         int             c;
1101 #endif /* _DEV_KBD_KBDREG_H_ */
1102
1103 loop:
1104
1105         if(noblock == 31337)
1106         {
1107                 vsp->scrolling = 1;
1108                 goto scroll_reset;
1109         }
1110
1111 #ifdef XSERVER
1112
1113 #ifndef _DEV_KBD_KBDREG_H_
1114
1115 #if PCVT_KBD_FIFO
1116
1117         /* see if there is data from the keyboard available either from */
1118         /* the keyboard fifo or from the 8042 keyboard controller       */
1119
1120         if (pcvt_kbd_count || (inb(CONTROLLER_CTRL) & STATUS_OUTPBF))
1121         {
1122                 if (!pcvt_kbd_count)    /* source = 8042 */
1123                 {
1124                         PCVT_KBD_DELAY();       /* 7 us delay */
1125                         dt = inb(CONTROLLER_DATA);      /* get from obuf */
1126                 }
1127                 else                    /* source = keyboard fifo */
1128                 {
1129                         dt = pcvt_kbd_fifo[pcvt_kbd_rptr++];
1130                         PCVT_DISABLE_INTR();
1131                         pcvt_kbd_count--;
1132                         PCVT_ENABLE_INTR();
1133                         if (pcvt_kbd_rptr >= PCVT_KBD_FIFO_SZ)
1134                                 pcvt_kbd_rptr = 0;
1135                 }
1136
1137 #else /* !PCVT_KB_FIFO */
1138
1139         /* see if there is data from the keyboard available from the 8042 */
1140
1141         if (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)
1142         {
1143                 PCVT_KBD_DELAY();               /* 7 us delay */
1144                 dt = inb(CONTROLLER_DATA);      /* yes, get data */
1145
1146 #endif /* !PCVT_KBD_FIFO */
1147
1148 #else /* _DEV_KBD_KBDREG_H_ */
1149
1150 #if PCVT_KBD_FIFO
1151         if (pcvt_kbd_count) {
1152                 dt = pcvt_kbd_fifo[pcvt_kbd_rptr++];
1153                 PCVT_DISABLE_INTR();
1154                 pcvt_kbd_count--;
1155                 PCVT_ENABLE_INTR();
1156                 if (pcvt_kbd_rptr >= PCVT_KBD_FIFO_SZ)
1157                         pcvt_kbd_rptr = 0;
1158         } else
1159 #endif /* PCVT_KBD_FIFO */
1160         if (!noblock) {
1161                 while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, TRUE)) == -1)
1162                         ;
1163                 dt = c;
1164         } else {
1165                 if ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) == -1)
1166                         return NULL;
1167                 dt = c;
1168         }
1169
1170         {
1171
1172 #endif /* !_DEV_KBD_KBDREG_H_ */
1173
1174                 /*
1175                  * If x mode is active, only care for locking keys, then
1176                  * return the scan code instead of any key translation.
1177                  * Additionally, this prevents us from any attempts to
1178                  * execute pcvt internal functions caused by keys (such
1179                  * as screen flipping).
1180                  * XXX For now, only the default locking key definitions
1181                  * are recognized (i.e. if you have overloaded you "A" key
1182                  * as NUMLOCK, that wont effect X mode:-)
1183                  * Changing this would be nice, but would require modifi-
1184                  * cations to the X server. After having this, X will
1185                  * deal with the LEDs itself, so we are committed.
1186                  */
1187                 /*
1188                  * Iff PCVT_USL_VT_COMPAT is defined, the behaviour has
1189                  * been fixed. We need not care about any keys here, since
1190                  * there are ioctls that deal with the lock key / LED stuff.
1191                  */
1192                 if (pcvt_kbd_raw)
1193                 {
1194                         keybuf[0] = dt;
1195
1196 #if PCVT_FREEBSD > 210
1197                         add_keyboard_randomness(dt);
1198 #endif  /* PCVT_FREEBSD > 210 */
1199
1200 #if !PCVT_USL_VT_COMPAT
1201                         if ((dt & 0x80) == 0)
1202                                 /* key make */
1203                                 switch(dt)
1204                                 {
1205                                 case 0x45:
1206                                         /* XXX on which virt screen? */                                 vsp->num_lock ^= 1;
1207                                         update_led();
1208                                         break;
1209
1210                                 case 0x3a:
1211                                         vsp->caps_lock ^= 1;
1212                                         update_led();
1213                                         break;
1214
1215                                 case 0x46:
1216                                         vsp->scroll_lock ^= 1;
1217                                         update_led();
1218                                         break;
1219                                 }
1220 #endif /* !PCVT_USL_VT_COMPAT */
1221
1222 #if PCVT_EMU_MOUSE
1223                         /*
1224                          * The (mouse systems) mouse emulator. The mouse
1225                          * device allocates the first device node that is
1226                          * not used by a virtual terminal. (E.g., you have
1227                          * eight vtys, /dev/ttyv0 thru /dev/ttyv7, so the
1228                          * mouse emulator were /dev/ttyv8.)
1229                          * Currently the emulator only works if the keyboard
1230                          * is in raw (PC scan code) mode. This is the typic-
1231                          * al case when running the X server.
1232                          * It is activated if the num locks LED is active
1233                          * for the current vty, and if the mouse device
1234                          * has been opened by at least one process. It
1235                          * grabs the numerical keypad events (but only
1236                          * the "non-extended", so the separate arrow keys
1237                          * continue to work), and three keys for the "mouse
1238                          * buttons", preferrably F1 thru F3. Any of the
1239                          * eight directions (N, NE, E, SE, S, SW, W, NW)
1240                          * is supported, and frequent key presses (less
1241                          * than e.g. half a second between key presses)
1242                          * cause the emulator to accelerate the pointer
1243                          * movement by 6, while single presses result in
1244                          * single moves, so each point can be reached.
1245                          */
1246                         /*
1247                          * NB: the following code is spagghetti.
1248                          * Only eat it with lotta tomato ketchup and
1249                          * Parmesan cheese:-)
1250                          */
1251                         /*
1252                          * look whether we will have to steal the keys
1253                          * and cook them into mouse events
1254                          */
1255                         if(vsp->num_lock && mouse.opened)
1256                         {
1257                                 int button, accel, i;
1258                                 enum mouse_dir
1259                                 {
1260                                         MOUSE_NW, MOUSE_N, MOUSE_NE,
1261                                         MOUSE_W,  MOUSE_0, MOUSE_E,
1262                                         MOUSE_SW, MOUSE_S, MOUSE_SE
1263                                 }
1264                                 move;
1265                                 struct timeval now;
1266                                 dev_t dummy;
1267                                 struct tty *mousetty;
1268
1269                                 dummy = make_adhoc_dev(&pc_cdevsw, mouse.minor);
1270                                 mousetty = get_pccons(dummy);
1271
1272                                 /*
1273                                  * strings to send for each mouse event,
1274                                  * indexed by the movement direction and
1275                                  * the "accelerator" value (TRUE for frequent
1276                                  * key presses); note that the first byte
1277                                  * of each string is actually overwritten
1278                                  * by the current button value before sending
1279                                  * the string
1280                                  */
1281                                 static u_char mousestrings[2][MOUSE_SE+1][5] =
1282                                 {
1283                                 {
1284                                         /* first, the non-accelerated strings*/
1285                                         {0x87,  -1,   1,   0,   0}, /* NW */
1286                                         {0x87,   0,   1,   0,   0}, /* N */
1287                                         {0x87,   1,   1,   0,   0}, /* NE */
1288                                         {0x87,  -1,   0,   0,   0}, /* W */
1289                                         {0x87,   0,   0,   0,   0}, /* 0 */
1290                                         {0x87,   1,   0,   0,   0}, /* E */
1291                                         {0x87,  -1,  -1,   0,   0}, /* SW */
1292                                         {0x87,   0,  -1,   0,   0}, /* S */
1293                                         {0x87,   1,  -1,   0,   0}  /* SE */
1294                                 },
1295                                 {
1296                                         /* now, 6 steps at once */
1297                                         {0x87,  -4,   4,   0,   0}, /* NW */
1298                                         {0x87,   0,   6,   0,   0}, /* N */
1299                                         {0x87,   4,   4,   0,   0}, /* NE */
1300                                         {0x87,  -6,   0,   0,   0}, /* W */
1301                                         {0x87,   0,   0,   0,   0}, /* 0 */
1302                                         {0x87,   6,   0,   0,   0}, /* E */
1303                                         {0x87,  -4,  -4,   0,   0}, /* SW */
1304                                         {0x87,   0,  -6,   0,   0}, /* S */
1305                                         {0x87,   4,  -4,   0,   0}  /* SE */
1306                                 }
1307                                 };
1308
1309                                 if(dt == 0xe0)
1310                                 {
1311                                         /* ignore extended scan codes */
1312                                         mouse.extendedseen = 1;
1313                                         goto no_mouse_event;
1314                                 }
1315                                 if(mouse.extendedseen)
1316                                 {
1317                                         mouse.extendedseen = 0;
1318                                         goto no_mouse_event;
1319                                 }
1320                                 mouse.extendedseen = 0;
1321
1322                                 /*
1323                                  * Note that we cannot use a switch here
1324                                  * since we want to have the keycodes in
1325                                  * a variable
1326                                  */
1327                                 if((dt & 0x7f) == mousedef.leftbutton) {
1328                                         button = 4;
1329                                         goto do_button;
1330                                 }
1331                                 else if((dt & 0x7f) == mousedef.middlebutton) {
1332                                         button = 2;
1333                                         goto do_button;
1334                                 }
1335                                 else if((dt & 0x7f) == mousedef.rightbutton) {
1336                                         button = 1;
1337                                 do_button:
1338
1339                                         /*
1340                                          * i would really like to give
1341                                          * some acustical support
1342                                          * (pling/plong); i am not sure
1343                                          * whether it is safe to call
1344                                          * sysbeep from within an intr
1345                                          * service, since it calls
1346                                          * timeout in turn which mani-
1347                                          * pulates the spl mask - jw
1348                                          */
1349
1350 # define PLING sysbeep(PCVT_SYSBEEPF / 1500, 2)
1351 # define PLONG sysbeep(PCVT_SYSBEEPF / 1200, 2)
1352
1353                                         if(mousedef.stickybuttons)
1354                                         {
1355                                                 if(dt & 0x80) {
1356                                                         mouse.breakseen = 1;
1357                                                         return (u_char *)0;
1358                                                 }
1359                                                 else if(mouse.buttons == button
1360                                                         && !mouse.breakseen) {
1361                                                         /* ignore repeats */
1362                                                         return (u_char *)0;
1363                                                 }
1364                                                 else
1365                                                         mouse.breakseen = 0;
1366                                                 if(mouse.buttons == button) {
1367                                                         /* release it */
1368                                                         mouse.buttons = 0;
1369                                                         PLONG;
1370                                                 } else {
1371                                                         /*
1372                                                          * eventually, release
1373                                                          * any other button,
1374                                                          * and stick this one
1375                                                          */
1376                                                         mouse.buttons = button;
1377                                                         PLING;
1378                                                 }
1379                                         }
1380                                         else
1381                                         {
1382                                                 if(dt & 0x80) {
1383                                                         mouse.buttons &=
1384                                                                 ~button;
1385                                                         PLONG;
1386                                                 }
1387                                                 else if((mouse.buttons
1388                                                         & button) == 0) {
1389                                                         mouse.buttons |=
1390                                                                 button;
1391                                                         PLING;
1392                                                 }
1393                                                 /*else: ignore same btn press*/
1394                                         }
1395                                         move = MOUSE_0;
1396                                         accel = 0;
1397                                 }
1398 # undef PLING
1399 # undef PLONG
1400                                 else switch(dt & 0x7f)
1401                                 {
1402                                 /* the arrow keys - KP 1 thru KP 9 */
1403                                 case 0x47:      move = MOUSE_NW; goto do_move;
1404                                 case 0x48:      move = MOUSE_N; goto do_move;
1405                                 case 0x49:      move = MOUSE_NE; goto do_move;
1406                                 case 0x4b:      move = MOUSE_W; goto do_move;
1407                                 case 0x4c:      move = MOUSE_0; goto do_move;
1408                                 case 0x4d:      move = MOUSE_E; goto do_move;
1409                                 case 0x4f:      move = MOUSE_SW; goto do_move;
1410                                 case 0x50:      move = MOUSE_S; goto do_move;
1411                                 case 0x51:      move = MOUSE_SE;
1412                                 do_move:
1413                                         if(dt & 0x80)
1414                                                 /*
1415                                                  * arrow key break events are
1416                                                  * of no importance for us
1417                                                  */
1418                                                 return (u_char *)0;
1419                                         /*
1420                                          * see whether the last move did
1421                                          * happen "recently", i.e. before
1422                                          * less than half a second
1423                                          */
1424                                         getmicrotime(&now);
1425                                         timevalsub(&now, &mouse.lastmove);
1426                                         getmicrotime(&mouse.lastmove);
1427                                         accel = (now.tv_sec == 0
1428                                                  && now.tv_usec
1429                                                  < mousedef.acceltime);
1430                                         break;
1431
1432                                 default: /* not a mouse-emulating key */
1433                                         goto no_mouse_event;
1434                                 }
1435                                 mousestrings[accel][move][0] =
1436                                         0x80 + (~mouse.buttons & 7);
1437                                 /* finally, send the string */
1438                                 for(i = 0; i < 5; i++)
1439                                         (*linesw[mousetty->t_line].l_rint)
1440                                                 (mousestrings[accel][move][i],
1441                                                  mousetty);
1442                                 return (u_char *)0; /* not a kbd event */
1443                         }
1444 no_mouse_event:
1445
1446 #endif /* PCVT_EMU_MOUSE */
1447
1448                         return ((u_char *)keybuf);
1449                 }
1450         }
1451
1452 #else /* !XSERVER */
1453
1454 #ifndef  _DEV_KBD_KBDREG_H_
1455
1456 #  if PCVT_KBD_FIFO
1457
1458         /* see if there is data from the keyboard available either from */
1459         /* the keyboard fifo or from the 8042 keyboard controller       */
1460
1461         if (pcvt_kbd_count || (inb(CONTROLLER_CTRL) & STATUS_OUTPBF))
1462         {
1463                 if (!noblock || kbd_polling)    /* source = 8042 */
1464                 {
1465                         PCVT_KBD_DELAY();       /* 7 us delay */
1466                         dt = inb(CONTROLLER_DATA);
1467                 }
1468                 else                    /* source = keyboard fifo */
1469                 {
1470                         dt = pcvt_kbd_fifo[pcvt_kbd_rptr++]; /* yes, get it ! */
1471                         PCVT_DISABLE_INTR();
1472                         pcvt_kbd_count--;
1473                         PCVT_ENABLE_INTR();
1474                         if (pcvt_kbd_rptr >= PCVT_KBD_FIFO_SZ)
1475                                 pcvt_kbd_rptr = 0;
1476                 }
1477         }
1478
1479 #else /* !PCVT_KBD_FIFO */
1480
1481         /* see if there is data from the keyboard available from the 8042 */
1482
1483         if(inb(CONTROLLER_CTRL) & STATUS_OUTPBF)
1484         {
1485                 PCVT_KBD_DELAY();               /* 7 us delay */
1486                 dt = inb(CONTROLLER_DATA);      /* yes, get data ! */
1487         }
1488
1489 #endif /* !PCVT_KBD_FIFO */
1490
1491 #else /* _DEV_KBD_KBDREG_H_ */
1492
1493 #if PCVT_KBD_FIFO
1494         if (pcvt_kbd_count) {
1495                 dt = pcvt_kbd_fifo[pcvt_kbd_rptr++];
1496                 PCVT_DISABLE_INTR();
1497                 pcvt_kbd_count--;
1498                 PCVT_ENABLE_INTR();
1499                 if (pcvt_kbd_rptr >= PCVT_KBD_FIFO_SZ)
1500                         pcvt_kbd_rptr = 0;
1501         } else
1502 #endif /* PCVT_KBD_FIFO */
1503         if (!noblock) {
1504                 while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, TRUE)) == -1)
1505                         ;
1506                 dt = c;
1507         } else {
1508                 if ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) == -1)
1509                         return NULL;
1510                 dt = c;
1511         }
1512
1513 #endif /* !_DEV_KBD_KBDREG_H_ */
1514
1515 #endif /* !XSERVER */
1516
1517 #ifndef _DEV_KBD_KBDREG_H_
1518         else
1519         {
1520                 if(noblock)
1521                         return NULL;
1522                 else
1523                         goto loop;
1524         }
1525 #endif /* !_DEV_KBD_KBDREG_H_ */
1526
1527 #if PCVT_SHOWKEYS
1528         showkey (' ', dt);
1529 #endif  /* PCVT_SHOWKEYS */
1530
1531         /* lets look what we got */
1532         switch(dt)
1533         {
1534                 case KEYB_R_OVERRUN0:   /* keyboard buffer overflow */
1535
1536 #if PCVT_SCANSET == 2
1537                 case KEYB_R_SELFOK:     /* keyboard selftest ok */
1538 #endif /* PCVT_SCANSET == 2 */
1539
1540                 case KEYB_R_ECHO:       /* keyboard response to KEYB_C_ECHO */
1541                 case KEYB_R_ACK:        /* acknowledge after command has rx'd*/
1542                 case KEYB_R_SELFBAD:    /* keyboard selftest FAILED */
1543                 case KEYB_R_DIAGBAD:    /* keyboard self diagnostic failure */
1544                 case KEYB_R_RESEND:     /* keyboard wants us to resend cmnd */
1545                 case KEYB_R_OVERRUN1:   /* keyboard buffer overflow */
1546                         break;
1547
1548                 case KEYB_R_EXT1:       /* keyboard extended scancode pfx 2 */
1549                         kbd_status.ext1 = 1;
1550                         /* FALLTHROUGH */
1551                 case KEYB_R_EXT0:       /* keyboard extended scancode pfx 1 */
1552                         kbd_status.extended = 1;
1553                         break;
1554
1555 #if PCVT_SCANSET == 2
1556                 case KEYB_R_BREAKPFX:   /* break code prefix for set 2 and 3 */
1557                         kbd_status.breakseen = 1;
1558                         break;
1559 #endif /* PCVT_SCANSET == 2 */
1560
1561                 default:
1562                         goto regular;   /* regular key */
1563         }
1564
1565         if(noblock)
1566                 return NULL;
1567         else
1568                 goto loop;
1569
1570         /* got a normal scan key */
1571 regular:
1572
1573 #if PCVT_FREEBSD > 210
1574         add_keyboard_randomness(dt);
1575 #endif  /* PCVT_FREEBSD > 210 */
1576
1577 #if PCVT_SCANSET == 1
1578         kbd_status.breakseen = dt & 0x80 ? 1 : 0;
1579         dt &= 0x7f;
1580 #endif  /* PCVT_SCANSET == 1 */
1581
1582         /*   make a keycode from scan code      */
1583         if(dt >= sizeof scantokey / sizeof(u_char))
1584                 key = 0;
1585         else
1586                 key = kbd_status.extended ? extscantokey[dt] : scantokey[dt];
1587
1588         if(kbd_status.ext1 && key == 64)
1589                 /* virtual control key */
1590                 key = 129;
1591
1592         kbd_status.extended = kbd_status.ext1 = 0;
1593
1594         if ((key == 85) && shift_down && kbd_lastkey != 85)
1595         {
1596                 if (vsp->scr_offset > (vsp->screen_rows - 1))
1597                 {
1598                         if (!vsp->scrolling)
1599                         {
1600                                 vsp->scrolling += vsp->screen_rows - 2;
1601                                 if (vsp->Scrollback)
1602                                 {
1603                                         scrollback_save_screen();
1604                                         if (vsp->scr_offset == vsp->max_off)
1605                                         {
1606                                                 bcopy(vsp->Scrollback +
1607                                                       vsp->maxcol,
1608                                                       vsp->Scrollback,
1609                                                       vsp->maxcol *
1610                                                       vsp->max_off * CHR);
1611                                                 vsp->scr_offset--;
1612                                         }
1613                                         bcopy(vsp->Crtat + vsp->cur_offset -
1614                                               vsp->col, vsp->Scrollback +
1615                                               ((vsp->scr_offset + 1) *
1616                                               vsp->maxcol), vsp->maxcol * CHR);
1617                                 }
1618
1619                                 if (vsp->cursor_on)
1620                                         sw_cursor(0);
1621                         }
1622
1623                         vsp->scrolling += vsp->screen_rows - 1;
1624
1625                         if (vsp->scrolling > vsp->scr_offset)
1626                                 vsp->scrolling = vsp->scr_offset;
1627
1628                         bcopy(vsp->Scrollback + ((vsp->scr_offset -
1629                               vsp->scrolling) * vsp->maxcol), vsp->Crtat,
1630                               vsp->screen_rows * vsp->maxcol * CHR);
1631                 }
1632
1633                 kbd_lastkey = 85;
1634                 goto loop;
1635         }
1636         else if ((key == 86) && shift_down && kbd_lastkey != 86)
1637         {
1638
1639 scroll_reset:
1640                 if (vsp->scrolling > 0)
1641                 {
1642                         vsp->scrolling -= vsp->screen_rows - 1;
1643                         if (vsp->scrolling < 0)
1644                                 vsp->scrolling = 0;
1645
1646                         if (vsp->scrolling <= vsp->screen_rows)
1647                         {
1648                                 vsp->scrolling = 0;
1649                                 scrollback_restore_screen();
1650                         }
1651                         else
1652                         {
1653                                 bcopy(vsp->Scrollback + ((vsp->scr_offset -
1654                                       vsp->scrolling) * vsp->maxcol),
1655                                       vsp->Crtat, vsp->screen_rows *
1656                                       vsp->maxcol * CHR);
1657                         }
1658                 }
1659
1660                 if (vsp->scrolling == 0)
1661                 {
1662                         if (vsp->cursor_on)
1663                         {
1664                                 sw_cursor(1);
1665                         }
1666                 }
1667
1668                 if (noblock == 31337)
1669                         return NULL;
1670
1671                 if (key != 86)
1672                 {
1673                         goto regular;
1674                 }
1675                 else
1676                 {
1677                         kbd_lastkey = 86;
1678                         goto loop;
1679                 }
1680         }
1681         else if (vsp->scrolling && key != 128 && key != 44 && key != 85 &&
1682                  key != 86)
1683         {
1684                 vsp->scrolling = 1;
1685                 goto scroll_reset;
1686         }
1687
1688 #if PCVT_CTRL_ALT_DEL           /*   Check for cntl-alt-del     */
1689         if((key == 76) && ctrl_down && (meta_down||altgr_down))
1690                 shutdown_nice(0);
1691 #endif /* PCVT_CTRL_ALT_DEL */
1692
1693 #if !(PCVT_NETBSD || PCVT_FREEBSD >= 200)
1694 #include "use_ddb.h"
1695 #endif /* !(PCVT_NETBSD || PCVT_FREEBSD >= 200) */
1696
1697 #if NDDB > 0 || defined(DDB)             /*   Check for cntl-alt-esc    */
1698
1699         if((key == 110) && ctrl_down && (meta_down || altgr_down))
1700         {
1701                 static u_char in_Debugger;
1702
1703                 if(!in_Debugger)
1704                 {
1705                         in_Debugger = 1;
1706 #if PCVT_FREEBSD
1707                         /* the string is actually not used... */
1708                         Debugger("kbd");
1709 #else
1710                         Debugger();
1711 #endif
1712                         in_Debugger = 0;
1713                         if(noblock)
1714                                 return NULL;
1715                         else
1716                                 goto loop;
1717                 }
1718         }
1719 #endif /* NDDB > 0 || defined(DDB) */
1720
1721         /* look for keys with special handling */
1722         if(key == 128)
1723         {
1724                 /*
1725                  * virtual shift; sent around PrtScr, and around the arrow
1726                  * keys if the NumLck LED is on
1727                  */
1728                 kbd_status.vshift = !kbd_status.breakseen;
1729                 key = 0;        /* no key */
1730         }
1731         else if(key == 129)
1732         {
1733                 /*
1734                  * virtual control - the most ugly thingie at all
1735                  * the Pause key sends:
1736                  * <virtual control make> <numlock make> <virtual control
1737                  * break> <numlock break>
1738                  */
1739                 if(!kbd_status.breakseen)
1740                         kbd_status.vcontrol = 1;
1741                 /* else: let the numlock hook clear this */
1742                 key = 0;        /* no key */
1743         }
1744         else if(key == 90)
1745         {
1746                 /* NumLock, look whether this is rather a Pause */
1747                 if(kbd_status.vcontrol)
1748                         key = 126;
1749                 /*
1750                  * if this is the final break code of a Pause key,
1751                  * clear the virtual control status, too
1752                  */
1753                 if(kbd_status.vcontrol && kbd_status.breakseen)
1754                         kbd_status.vcontrol = 0;
1755         }
1756         else if(key == 127)
1757         {
1758                 /*
1759                  * a SysRq; some keyboards are brain-dead enough to
1760                  * repeat the SysRq key make code by sending PrtScr
1761                  * make codes; other keyboards do not repeat SysRq
1762                  * at all. We keep track of the SysRq state here.
1763                  */
1764                 kbd_status.sysrq = !kbd_status.breakseen;
1765         }
1766         else if(key == 124)
1767         {
1768                 /*
1769                  * PrtScr; look whether this is really PrtScr or rather
1770                  * a silly repeat of a SysRq key
1771                  */
1772                 if(kbd_status.sysrq)
1773                         /* ignore the garbage */
1774                         key = 0;
1775         }
1776
1777         /* in NOREPEAT MODE ignore the key if it was the same as before */
1778
1779         if(!kbrepflag && key == kbd_lastkey && !kbd_status.breakseen)
1780         {
1781                 if(noblock)
1782                         return NULL;
1783                 else
1784                         goto loop;
1785         }
1786
1787         type = key2ascii[key].type;
1788
1789         if(type & KBD_OVERLOAD)
1790                 type = ovltbl[key2ascii[key].ovlindex].type;
1791
1792         type &= KBD_MASK;
1793
1794         switch(type)
1795         {
1796                 case KBD_SHFTLOCK:
1797                         if(!kbd_status.breakseen && key != kbd_lastkey)
1798                         {
1799                                 vsp->shift_lock ^= 1;
1800                         }
1801                         break;
1802
1803                 case KBD_CAPS:
1804                         if(!kbd_status.breakseen && key != kbd_lastkey)
1805                         {
1806                                 vsp->caps_lock ^= 1;
1807                                 update_led();
1808                         }
1809                         break;
1810
1811                 case KBD_SCROLL:
1812                         if(!kbd_status.breakseen && key != kbd_lastkey)
1813                         {
1814                                 vsp->scroll_lock ^= 1;
1815                                 update_led();
1816
1817                                 if(!(vsp->scroll_lock))
1818                                 {
1819                                         /* someone may be sleeping */
1820                                         wakeup((caddr_t)&(vsp->scroll_lock));
1821                                 }
1822                         }
1823                         break;
1824
1825                 case KBD_SHIFT:
1826                         shift_down = kbd_status.breakseen ? 0 : 1;
1827                         break;
1828
1829                 case KBD_META:
1830                         meta_down = kbd_status.breakseen ? 0 : 0x80;
1831                         break;
1832
1833                 case KBD_ALTGR:
1834                         altgr_down = kbd_status.breakseen ? 0 : 1;
1835                         break;
1836
1837                 case KBD_CTL:
1838                         ctrl_down = kbd_status.breakseen ? 0 : 1;
1839                         break;
1840
1841                 case KBD_NONE:
1842                 default:
1843                         break;                  /* deliver a key */
1844         }
1845
1846         if(kbd_status.breakseen)
1847         {
1848                 key |= 0x80;
1849                 kbd_status.breakseen = 0;
1850                 kbd_lastkey = 0; /* -hv- I know this is a bug with */
1851         }                        /* N-Key-Rollover, but I ignore that */
1852         else                     /* because avoidance is too complicated */
1853                 kbd_lastkey = key;
1854
1855         cp = xlatkey2ascii(key);        /* have a key */
1856
1857         if(cp == NULL && !noblock)
1858                 goto loop;
1859
1860         return cp;
1861 }
1862
1863 /*---------------------------------------------------------------------------*
1864  *      reflect status of locking keys & set led's
1865  *---------------------------------------------------------------------------*/
1866 static void
1867 setlockkeys(int snc)
1868 {
1869         vsp->scroll_lock = snc & 1;
1870         vsp->num_lock    = (snc & 2) ? 1 : 0;
1871         vsp->caps_lock   = (snc & 4) ? 1 : 0;
1872         update_led();
1873 }
1874
1875 /*---------------------------------------------------------------------------*
1876  *      remove a key definition
1877  *---------------------------------------------------------------------------*/
1878 static int
1879 rmkeydef(int key)
1880 {
1881         Ovl_tbl *ref;
1882
1883         if(key==0 || key > MAXKEYNUM)
1884                 return EINVAL;
1885
1886         if(key2ascii[key].type & KBD_OVERLOAD)
1887         {
1888                 ref = &ovltbl[key2ascii[key].ovlindex];
1889                 ref->keynum = 0;
1890                 ref->type = 0;
1891                 ref->unshift[0] =
1892                 ref->shift[0] =
1893                 ref->ctrl[0] =
1894                 ref->altgr[0] = 0;
1895                 key2ascii[key].type &= KBD_MASK;
1896         }
1897         return 0;
1898 }
1899
1900 /*---------------------------------------------------------------------------*
1901  *      overlay a key
1902  *---------------------------------------------------------------------------*/
1903 static int
1904 setkeydef(Ovl_tbl *data)
1905 {
1906         int i;
1907
1908         if( data->keynum > MAXKEYNUM             ||
1909             (data->type & KBD_MASK) == KBD_BREAK ||
1910             (data->type & KBD_MASK) > KBD_SHFTLOCK)
1911                 return EINVAL;
1912
1913         data->unshift[KBDMAXOVLKEYSIZE] =
1914         data->shift[KBDMAXOVLKEYSIZE] =
1915         data->ctrl[KBDMAXOVLKEYSIZE] =
1916         data->altgr[KBDMAXOVLKEYSIZE] = 0;
1917
1918         data->subu =
1919         data->subs =
1920         data->subc =
1921         data->suba = KBD_SUBT_STR;              /* just strings .. */
1922
1923         data->type |= KBD_OVERLOAD;             /* mark overloaded */
1924
1925         /* if key already overloaded, use that slot else find free slot */
1926
1927         if(key2ascii[data->keynum].type & KBD_OVERLOAD)
1928         {
1929                 i = key2ascii[data->keynum].ovlindex;
1930         }
1931         else
1932         {
1933                 for(i=0; i<OVLTBL_SIZE; i++)
1934                         if(ovltbl[i].keynum==0)
1935                                 break;
1936
1937                 if(i==OVLTBL_SIZE)
1938                         return ENOSPC;  /* no space, abuse of ENOSPC(!) */
1939         }
1940
1941         ovltbl[i] = *data;              /* copy new data string */
1942
1943         key2ascii[data->keynum].type |= KBD_OVERLOAD;   /* mark key */
1944         key2ascii[data->keynum].ovlindex = i;
1945
1946         return 0;
1947 }
1948
1949 /*---------------------------------------------------------------------------*
1950  *      keyboard ioctl's entry
1951  *---------------------------------------------------------------------------*/
1952 int
1953 kbdioctl(Dev_t dev, int cmd, caddr_t data, int flag)
1954 {
1955         int key;
1956
1957         switch(cmd)
1958         {
1959                 case KBDRESET:
1960                         doreset();
1961                         ovlinit(1);
1962                         settpmrate(KBD_TPD500|KBD_TPM100);
1963                         setlockkeys(0);
1964                         break;
1965
1966                 case KBDGTPMAT:
1967                         *(int *)data = tpmrate;
1968                         break;
1969
1970                 case KBDSTPMAT:
1971                         settpmrate(*(int *)data);
1972                         break;
1973
1974                 case KBDGREPSW:
1975                         *(int *)data = kbrepflag;
1976                         break;
1977
1978                 case KBDSREPSW:
1979                         kbrepflag = (*(int *)data) & 1;
1980                         break;
1981
1982                 case KBDGLEDS:
1983                         *(int *)data = ledstate;
1984                         break;
1985
1986                 case KBDSLEDS:
1987                         update_led();   /* ? */
1988                         break;
1989
1990                 case KBDGLOCK:
1991                         *(int *)data = ( (vsp->scroll_lock) |
1992                                          (vsp->num_lock * 2) |
1993                                          (vsp->caps_lock * 4));
1994                         break;
1995
1996                 case KBDSLOCK:
1997                         setlockkeys(*(int *)data);
1998                         break;
1999
2000                 case KBDGCKEY:
2001                         key = ((Ovl_tbl *)data)->keynum;
2002                         return getckeydef(key,(Ovl_tbl *)data);
2003
2004                 case KBDSCKEY:
2005                         key = ((Ovl_tbl *)data)->keynum;
2006                         return setkeydef((Ovl_tbl *)data);
2007
2008                 case KBDGOKEY:
2009                         key = ((Ovl_tbl *)data)->keynum;
2010                         return getokeydef(key,(Ovl_tbl *)data);
2011
2012                 case KBDRMKEY:
2013                         key = *(int *)data;
2014                         return rmkeydef(key);
2015
2016                 case KBDDEFAULT:
2017                         ovlinit(1);
2018                         break;
2019
2020                 default:
2021                         /* proceed with vga ioctls */
2022                         return -1;
2023         }
2024         return 0;
2025 }
2026
2027 #if PCVT_EMU_MOUSE
2028 /*--------------------------------------------------------------------------*
2029  *      mouse emulator ioctl
2030  *--------------------------------------------------------------------------*/
2031 int
2032 mouse_ioctl(Dev_t dev, int cmd, caddr_t data)
2033 {
2034         struct mousedefs *def = (struct mousedefs *)data;
2035
2036         switch(cmd)
2037         {
2038                 case KBDMOUSEGET:
2039                         *def = mousedef;
2040                         break;
2041
2042                 case KBDMOUSESET:
2043                         mousedef = *def;
2044                         break;
2045
2046                 default:
2047                         return -1;
2048         }
2049         return 0;
2050 }
2051 #endif  /* PCVT_EMU_MOUSE */
2052
2053 #if PCVT_USL_VT_COMPAT
2054 /*---------------------------------------------------------------------------*
2055  *      convert ISO-8859 style keycode into IBM 437
2056  *---------------------------------------------------------------------------*/
2057 static __inline u_char
2058 iso2ibm(u_char c)
2059 {
2060         if(c < 0x80)
2061                 return c;
2062         return iso2ibm437[c - 0x80];
2063 }
2064
2065 /*---------------------------------------------------------------------------*
2066  *      build up a USL style keyboard map
2067  *---------------------------------------------------------------------------*/
2068 void
2069 get_usl_keymap(keymap_t *map)
2070 {
2071         int i;
2072
2073         bzero((caddr_t)map, sizeof(keymap_t));
2074
2075         map->n_keys = 0x59;     /* that many keys we know about */
2076
2077         for(i = 1; i < N_KEYNUMS; i++)
2078         {
2079                 Ovl_tbl kdef;
2080                 u_char c;
2081                 int j;
2082                 int idx = key2scan1[i];
2083
2084                 if(idx == 0 || idx >= map->n_keys)
2085                         continue;
2086
2087                 getckeydef(i, &kdef);
2088                 kdef.type &= KBD_MASK;
2089                 switch(kdef.type)
2090                 {
2091                 case KBD_ASCII:
2092                 case KBD_RETURN:
2093                         map->key[idx].map[0] = iso2ibm(kdef.unshift[0]);
2094                         map->key[idx].map[1] = iso2ibm(kdef.shift[0]);
2095                         map->key[idx].map[2] = map->key[idx].map[3] =
2096                                 iso2ibm(kdef.ctrl[0]);
2097                         map->key[idx].map[4] = map->key[idx].map[5] =
2098                                 iso2ibm(c = kdef.altgr[0]);
2099                         /*
2100                          * XXX this is a hack
2101                          * since we currently do not map strings to AltGr +
2102                          * shift, we attempt to use the unshifted AltGr
2103                          * definition here and try to toggle the case
2104                          * this should at least work for ISO8859 letters,
2105                          * but also for (e.g.) russian KOI-8 style
2106                          */
2107                         if((c & 0x7f) >= 0x40)
2108                                 map->key[idx].map[5] = iso2ibm(c ^ 0x20);
2109                         break;
2110
2111                 case KBD_FUNC:
2112                         /* we are only interested in F1 thru F12 here */
2113                         if(i >= 112 && i <= 123) {
2114                                 map->key[idx].map[0] = i - 112 + 27;
2115                                 map->key[idx].spcl = 0x80;
2116                         }
2117                         break;
2118
2119                 case KBD_SHIFT:
2120                         c = i == 44? 2 /* lSh */: 3 /* rSh */; goto special;
2121
2122                 case KBD_CAPS:
2123                         c = 4; goto special;
2124
2125                 case KBD_NUM:
2126                         c = 5; goto special;
2127
2128                 case KBD_SCROLL:
2129                         c = 6; goto special;
2130
2131                 case KBD_META:
2132                         c = 7; goto special;
2133
2134                 case KBD_CTL:
2135                         c = 9; goto special;
2136                 special:
2137                         for(j = 0; j < NUM_STATES; j++)
2138                                 map->key[idx].map[j] = c;
2139                         map->key[idx].spcl = 0xff;
2140                         break;
2141
2142                 default:
2143                         break;
2144                 }
2145         }
2146 }
2147
2148 #endif /* PCVT_USL_VT_COMPAT */
2149
2150 /*---------------------------------------------------------------------------*
2151  *      switch keypad to numeric mode
2152  *---------------------------------------------------------------------------*/
2153 void
2154 vt_keynum(struct video_state *svsp)
2155 {
2156         svsp->num_lock = 1;
2157         update_led();
2158 }
2159
2160 /*---------------------------------------------------------------------------*
2161  *      switch keypad to application mode
2162  *---------------------------------------------------------------------------*/
2163 void
2164 vt_keyappl(struct video_state *svsp)
2165 {
2166         svsp->num_lock = 0;
2167         update_led();
2168 }
2169
2170 #if !PCVT_VT220KEYB     /* !PCVT_VT220KEYB, HP-like Keyboard layout */
2171
2172 /*---------------------------------------------------------------------------*
2173  *      function bound to function key 1
2174  *---------------------------------------------------------------------------*/
2175 static void
2176 fkey1(void)
2177 {
2178         if(!meta_down)
2179         {
2180                 if((vsp->vt_pure_mode == M_HPVT)
2181                    && (vsp->which_fkl == SYS_FKL))
2182                         toggl_columns(vsp);
2183                 else
2184                         more_chars = (u_char *)"\033[17~";      /* F6 */
2185         }
2186         else
2187         {
2188                 if(vsp->vt_pure_mode == M_PUREVT
2189                    || (vsp->which_fkl == USR_FKL))
2190                         more_chars = (u_char *)"\033[26~";      /* F14 */
2191         }
2192 }
2193
2194 /*---------------------------------------------------------------------------*
2195  *      function bound to function key 2
2196  *---------------------------------------------------------------------------*/
2197 static void
2198 fkey2(void)
2199 {
2200         if(!meta_down)
2201         {
2202                 if((vsp->vt_pure_mode == M_HPVT)
2203                    && (vsp->which_fkl == SYS_FKL))
2204                         vt_ris(vsp);
2205                 else
2206                         more_chars = (u_char *)"\033[18~";      /* F7 */
2207         }
2208         else
2209         {
2210                 if(vsp->vt_pure_mode == M_PUREVT
2211                    || (vsp->which_fkl == USR_FKL))
2212                         more_chars = (u_char *)"\033[28~";      /* HELP */
2213         }
2214 }
2215
2216 /*---------------------------------------------------------------------------*
2217  *      function bound to function key 3
2218  *---------------------------------------------------------------------------*/
2219 static void
2220 fkey3(void)
2221 {
2222         if(!meta_down)
2223         {
2224                 if((vsp->vt_pure_mode == M_HPVT)
2225                    && (vsp->which_fkl == SYS_FKL))
2226                         toggl_24l(vsp);
2227                 else
2228                         more_chars = (u_char *)"\033[19~";      /* F8 */
2229         }
2230         else
2231         {
2232                 if(vsp->vt_pure_mode == M_PUREVT
2233                    || (vsp->which_fkl == USR_FKL))
2234                         more_chars = (u_char *)"\033[29~";      /* DO */
2235         }
2236 }
2237
2238 /*---------------------------------------------------------------------------*
2239  *      function bound to function key 4
2240  *---------------------------------------------------------------------------*/
2241 static void
2242 fkey4(void)
2243 {
2244         if(!meta_down)
2245         {
2246
2247 #if PCVT_SHOWKEYS
2248                 if((vsp->vt_pure_mode == M_HPVT)
2249                    && (vsp->which_fkl == SYS_FKL))
2250                         toggl_kbddbg(vsp);
2251                 else
2252                         more_chars = (u_char *)"\033[20~";      /* F9 */
2253 #else
2254                 if(vsp->vt_pure_mode == M_PUREVT
2255                    || (vsp->which_fkl == USR_FKL))
2256                         more_chars = (u_char *)"\033[20~";      /* F9 */
2257 #endif /* PCVT_SHOWKEYS */
2258
2259         }
2260         else
2261         {
2262                 if(vsp->vt_pure_mode == M_PUREVT
2263                    || (vsp->which_fkl == USR_FKL))
2264                         more_chars = (u_char *)"\033[31~";      /* F17 */
2265         }
2266 }
2267
2268 /*---------------------------------------------------------------------------*
2269  *      function bound to function key 5
2270  *---------------------------------------------------------------------------*/
2271 static void
2272 fkey5(void)
2273 {
2274         if(!meta_down)
2275         {
2276                 if((vsp->vt_pure_mode == M_HPVT)
2277                    && (vsp->which_fkl == SYS_FKL))
2278                         toggl_bell(vsp);
2279                 else
2280                         more_chars = (u_char *)"\033[21~";      /* F10 */
2281         }
2282         else
2283         {
2284                 if(vsp->vt_pure_mode == M_PUREVT
2285                    || (vsp->which_fkl == USR_FKL))
2286                         more_chars = (u_char *)"\033[32~";      /* F18 */
2287         }
2288 }
2289
2290 /*---------------------------------------------------------------------------*
2291  *      function bound to function key 6
2292  *---------------------------------------------------------------------------*/
2293 static void
2294 fkey6(void)
2295 {
2296         if(!meta_down)
2297         {
2298                 if((vsp->vt_pure_mode == M_HPVT)
2299                    && (vsp->which_fkl == SYS_FKL))
2300                         toggl_sevenbit(vsp);
2301                 else
2302                         more_chars = (u_char *)"\033[23~";      /* F11 */
2303         }
2304         else
2305         {
2306                 if(vsp->vt_pure_mode == M_PUREVT
2307                    || (vsp->which_fkl == USR_FKL))
2308                         more_chars = (u_char *)"\033[33~";      /* F19 */
2309         }
2310 }
2311
2312 /*---------------------------------------------------------------------------*
2313  *      function bound to function key 7
2314  *---------------------------------------------------------------------------*/
2315 static void
2316 fkey7(void)
2317 {
2318         if(!meta_down)
2319         {
2320                 if((vsp->vt_pure_mode == M_HPVT)
2321                    && (vsp->which_fkl == SYS_FKL))
2322                         toggl_dspf(vsp);
2323                 else
2324                         more_chars = (u_char *)"\033[24~";      /* F12 */
2325         }
2326         else
2327         {
2328                 if(vsp->vt_pure_mode == M_PUREVT
2329                    || (vsp->which_fkl == USR_FKL))
2330                         more_chars = (u_char *)"\033[34~";      /* F20 */
2331         }
2332 }
2333
2334 /*---------------------------------------------------------------------------*
2335  *      function bound to function key 8
2336  *---------------------------------------------------------------------------*/
2337 static void
2338 fkey8(void)
2339 {
2340         if(!meta_down)
2341         {
2342                 if((vsp->vt_pure_mode == M_HPVT)
2343                    && (vsp->which_fkl == SYS_FKL))
2344                         toggl_awm(vsp);
2345                 else
2346                         more_chars = (u_char *)"\033[25~";      /* F13 */
2347         }
2348         else
2349         {
2350                 if(vsp->vt_pure_mode == M_PUREVT
2351                    || (vsp->which_fkl == USR_FKL))
2352                         more_chars = (u_char *)"\033[35~";      /* F21 ? !! */
2353         }
2354 }
2355
2356 /*---------------------------------------------------------------------------*
2357  *      function bound to function key 9
2358  *---------------------------------------------------------------------------*/
2359 static void
2360 fkey9(void)
2361 {
2362         if(meta_down)
2363         {
2364                 if(vsp->vt_pure_mode == M_PUREVT)
2365                         return;
2366
2367                 if(vsp->labels_on)      /* toggle label display on/off */
2368                         fkl_off(vsp);
2369                 else
2370                         fkl_on(vsp);
2371         }
2372         else
2373         {
2374                 do_vgapage(0);
2375         }
2376 }
2377
2378 /*---------------------------------------------------------------------------*
2379  *      function bound to function key 10
2380  *---------------------------------------------------------------------------*/
2381 static void
2382 fkey10(void)
2383 {
2384         if(meta_down)
2385         {
2386                 if(vsp->vt_pure_mode != M_PUREVT && vsp->labels_on)
2387                 {
2388                         if(vsp->which_fkl == USR_FKL)
2389                                 sw_sfkl(vsp);
2390                         else if(vsp->which_fkl == SYS_FKL)
2391                                 sw_ufkl(vsp);
2392                 }
2393         }
2394         else
2395         {
2396                 do_vgapage(1);
2397         }
2398 }
2399
2400 /*---------------------------------------------------------------------------*
2401  *      function bound to function key 11
2402  *---------------------------------------------------------------------------*/
2403 static void
2404 fkey11(void)
2405 {
2406         if(meta_down)
2407         {
2408                 if(vsp->vt_pure_mode == M_PUREVT)
2409                         set_emulation_mode(vsp, M_HPVT);
2410                 else if(vsp->vt_pure_mode == M_HPVT)
2411                         set_emulation_mode(vsp, M_PUREVT);
2412         }
2413         else
2414         {
2415                 do_vgapage(2);
2416         }
2417 }
2418
2419 /*---------------------------------------------------------------------------*
2420  *      function bound to function key 12
2421  *---------------------------------------------------------------------------*/
2422 static void
2423 fkey12(void)
2424 {
2425         if(meta_down)
2426         {
2427                 if(current_video_screen + 1 > totalscreens-1)
2428                         do_vgapage(0);
2429                 else
2430                         do_vgapage(current_video_screen + 1);
2431         }
2432         else
2433         {
2434                 do_vgapage(3);
2435         }
2436 }
2437
2438 /*---------------------------------------------------------------------------*
2439  *      function bound to SHIFTED function key 1
2440  *---------------------------------------------------------------------------*/
2441 static void
2442 sfkey1(void)
2443 {
2444         if(!meta_down)
2445         {
2446                 if(vsp->ukt.length[0])  /* entry available ? */
2447                         more_chars = (u_char *)
2448                                 &(vsp->udkbuf[vsp->ukt.first[0]]);
2449         }
2450         else
2451         {
2452                 if(vsp->ukt.length[9])  /* entry available ? */
2453                         more_chars = (u_char *)
2454                                 &(vsp->udkbuf[vsp->ukt.first[9]]);
2455         }
2456 }
2457
2458 /*---------------------------------------------------------------------------*
2459  *      function bound to SHIFTED function key 2
2460  *---------------------------------------------------------------------------*/
2461 static void
2462 sfkey2(void)
2463 {
2464         if(!meta_down)
2465         {
2466                 if(vsp->ukt.length[1])  /* entry available ? */
2467                         more_chars = (u_char *)
2468                                 &(vsp->udkbuf[vsp->ukt.first[1]]);
2469         }
2470         else
2471         {
2472                 if(vsp->ukt.length[11]) /* entry available ? */
2473                         more_chars = (u_char *)
2474                                 &(vsp->udkbuf[vsp->ukt.first[11]]);
2475         }
2476 }
2477
2478 /*---------------------------------------------------------------------------*
2479  *      function bound to SHIFTED function key 3
2480  *---------------------------------------------------------------------------*/
2481 static void
2482 sfkey3(void)
2483 {
2484         if(!meta_down)
2485         {
2486                 if(vsp->ukt.length[2])  /* entry available ? */
2487                         more_chars = (u_char *)
2488                                 &(vsp->udkbuf[vsp->ukt.first[2]]);
2489         }
2490         else
2491         {
2492                 if(vsp->ukt.length[12]) /* entry available ? */
2493                         more_chars = (u_char *)
2494                                 &(vsp->udkbuf[vsp->ukt.first[12]]);
2495         }
2496 }
2497
2498 /*---------------------------------------------------------------------------*
2499  *      function bound to SHIFTED function key 4
2500  *---------------------------------------------------------------------------*/
2501 static void
2502 sfkey4(void)
2503 {
2504         if(!meta_down)
2505         {
2506                 if(vsp->ukt.length[3])  /* entry available ? */
2507                         more_chars = (u_char *)
2508                                 &(vsp->udkbuf[vsp->ukt.first[3]]);
2509         }
2510         else
2511         {
2512                 if(vsp->ukt.length[13]) /* entry available ? */
2513                         more_chars = (u_char *)
2514                                 &(vsp->udkbuf[vsp->ukt.first[13]]);
2515         }
2516 }
2517
2518 /*---------------------------------------------------------------------------*
2519  *      function bound to SHIFTED function key 5
2520  *---------------------------------------------------------------------------*/
2521 static void
2522 sfkey5(void)
2523 {
2524         if(!meta_down)
2525         {
2526                 if(vsp->ukt.length[4])  /* entry available ? */
2527                         more_chars = (u_char *)
2528                                 &(vsp->udkbuf[vsp->ukt.first[4]]);
2529         }
2530         else
2531         {
2532                 if(vsp->ukt.length[14]) /* entry available ? */
2533                         more_chars = (u_char *)
2534                                 &(vsp->udkbuf[vsp->ukt.first[14]]);
2535         }
2536 }
2537
2538 /*---------------------------------------------------------------------------*
2539  *      function bound to SHIFTED function key 6
2540  *---------------------------------------------------------------------------*/
2541 static void
2542 sfkey6(void)
2543 {
2544         if(!meta_down)
2545         {
2546                 if(vsp->ukt.length[6])  /* entry available ? */
2547                         more_chars = (u_char *)
2548                                 &(vsp->udkbuf[vsp->ukt.first[6]]);
2549         }
2550         else
2551         {
2552                 if(vsp->ukt.length[15]) /* entry available ? */
2553                         more_chars = (u_char *)
2554                                 &(vsp->udkbuf[vsp->ukt.first[15]]);
2555         }
2556 }
2557
2558 /*---------------------------------------------------------------------------*
2559  *      function bound to SHIFTED function key 7
2560  *---------------------------------------------------------------------------*/
2561 static void
2562 sfkey7(void)
2563 {
2564         if(!meta_down)
2565         {
2566                 if(vsp->ukt.length[7])  /* entry available ? */
2567                         more_chars = (u_char *)
2568                                 &(vsp->udkbuf[vsp->ukt.first[7]]);
2569         }
2570         else
2571         {
2572                 if(vsp->ukt.length[16]) /* entry available ? */
2573                         more_chars = (u_char *)
2574                                 &(vsp->udkbuf[vsp->ukt.first[16]]);
2575         }
2576 }
2577
2578 /*---------------------------------------------------------------------------*
2579  *      function bound to SHIFTED function key 8
2580  *---------------------------------------------------------------------------*/
2581 static void
2582 sfkey8(void)
2583 {
2584         if(!meta_down)
2585         {
2586                 if(vsp->ukt.length[8])  /* entry available ? */
2587                         more_chars = (u_char *)
2588                                 &(vsp->udkbuf[vsp->ukt.first[8]]);
2589         }
2590         else
2591         {
2592                 if(vsp->ukt.length[17]) /* entry available ? */
2593                         more_chars = (u_char *)
2594                                 &(vsp->udkbuf[vsp->ukt.first[17]]);
2595         }
2596 }
2597 /*---------------------------------------------------------------------------*
2598  *      function bound to SHIFTED function key 9
2599  *---------------------------------------------------------------------------*/
2600 static void
2601 sfkey9(void)
2602 {
2603 }
2604
2605 /*---------------------------------------------------------------------------*
2606  *      function bound to SHIFTED function key 10
2607  *---------------------------------------------------------------------------*/
2608 static void
2609 sfkey10(void)
2610 {
2611 }
2612
2613 /*---------------------------------------------------------------------------*
2614  *      function bound to SHIFTED function key 11
2615  *---------------------------------------------------------------------------*/
2616 static void
2617 sfkey11(void)
2618 {
2619 }
2620
2621 /*---------------------------------------------------------------------------*
2622  *      function bound to SHIFTED function key 12
2623  *---------------------------------------------------------------------------*/
2624 static void
2625 sfkey12(void)
2626 {
2627 }
2628
2629 /*---------------------------------------------------------------------------*
2630  *      function bound to control function key 1
2631  *---------------------------------------------------------------------------*/
2632 static void
2633 cfkey1(void)
2634 {
2635         if(meta_down)
2636                 do_vgapage(0);
2637 }
2638
2639 /*---------------------------------------------------------------------------*
2640  *      function bound to control function key 2
2641  *---------------------------------------------------------------------------*/
2642 static void
2643 cfkey2(void)
2644 {
2645         if(meta_down)
2646                 do_vgapage(1);
2647 }
2648
2649 /*---------------------------------------------------------------------------*
2650  *      function bound to control function key 3
2651  *---------------------------------------------------------------------------*/
2652 static void
2653 cfkey3(void)
2654 {
2655         if(meta_down)
2656                 do_vgapage(2);
2657 }
2658
2659 /*---------------------------------------------------------------------------*
2660  *      function bound to control function key 4
2661  *---------------------------------------------------------------------------*/
2662 static void
2663 cfkey4(void)
2664 {
2665         if(meta_down)
2666                 do_vgapage(3);
2667 }
2668
2669 /*---------------------------------------------------------------------------*
2670  *      function bound to control function key 5
2671  *---------------------------------------------------------------------------*/
2672 static void
2673 cfkey5(void)
2674 {
2675         if(meta_down)
2676                 do_vgapage(4);
2677 }
2678
2679 /*---------------------------------------------------------------------------*
2680  *      function bound to control function key 6
2681  *---------------------------------------------------------------------------*/
2682 static void
2683 cfkey6(void)
2684 {
2685         if(meta_down)
2686                 do_vgapage(5);
2687 }
2688
2689 /*---------------------------------------------------------------------------*
2690  *      function bound to control function key 7
2691  *---------------------------------------------------------------------------*/
2692 static void
2693 cfkey7(void)
2694 {
2695         if(meta_down)
2696                 do_vgapage(6);
2697 }
2698
2699 /*---------------------------------------------------------------------------*
2700  *      function bound to control function key 8
2701  *---------------------------------------------------------------------------*/
2702 static void
2703 cfkey8(void)
2704 {
2705         if(meta_down)
2706                 do_vgapage(7);
2707 }
2708
2709 /*---------------------------------------------------------------------------*
2710  *      function bound to control function key 9
2711  *---------------------------------------------------------------------------*/
2712 static void
2713 cfkey9(void)
2714 {
2715         if(meta_down)
2716                 do_vgapage(8);
2717 }
2718
2719 /*---------------------------------------------------------------------------*
2720  *      function bound to control function key 10
2721  *---------------------------------------------------------------------------*/
2722 static void
2723 cfkey10(void)
2724 {
2725         if(meta_down)
2726                 do_vgapage(9);
2727 }
2728
2729 /*---------------------------------------------------------------------------*
2730  *      function bound to control function key 11
2731  *---------------------------------------------------------------------------*/
2732 static void
2733 cfkey11(void)
2734 {
2735         if(meta_down)
2736                 do_vgapage(10);
2737 }
2738
2739 /*---------------------------------------------------------------------------*
2740  *      function bound to control function key 12
2741  *---------------------------------------------------------------------------*/
2742 static void
2743 cfkey12(void)
2744 {
2745         if(meta_down)
2746                 do_vgapage(11);
2747 }
2748
2749 #else   /* PCVT_VT220  -  VT220-like Keyboard layout */
2750
2751 /*---------------------------------------------------------------------------*
2752  *      function bound to function key 1
2753  *---------------------------------------------------------------------------*/
2754 static void
2755 fkey1(void)
2756 {
2757         if(meta_down)
2758                 more_chars = (u_char *)"\033[23~"; /* F11 */
2759         else
2760                 do_vgapage(0);
2761 }
2762
2763 /*---------------------------------------------------------------------------*
2764  *      function bound to function key 2
2765  *---------------------------------------------------------------------------*/
2766 static void
2767 fkey2(void)
2768 {
2769         if(meta_down)
2770                 more_chars = (u_char *)"\033[24~"; /* F12 */
2771         else
2772                 do_vgapage(1);
2773 }
2774
2775 /*---------------------------------------------------------------------------*
2776  *      function bound to function key 3
2777  *---------------------------------------------------------------------------*/
2778 static void
2779 fkey3(void)
2780 {
2781         if(meta_down)
2782                 more_chars = (u_char *)"\033[25~"; /* F13 */
2783         else
2784                 do_vgapage(2);
2785 }
2786
2787 /*---------------------------------------------------------------------------*
2788  *      function bound to function key 4
2789  *---------------------------------------------------------------------------*/
2790 static void
2791 fkey4(void)
2792 {
2793         if(meta_down)
2794                 more_chars = (u_char *)"\033[26~"; /* F14 */
2795         else
2796                 do_vgapage(3);
2797 }
2798
2799 /*---------------------------------------------------------------------------*
2800  *      function bound to function key 5
2801  *---------------------------------------------------------------------------*/
2802 static void
2803 fkey5(void)
2804 {
2805         if(meta_down)
2806                 more_chars = (u_char *)"\033[28~"; /* Help */
2807         else
2808         {
2809                 if((current_video_screen + 1) > totalscreens-1)
2810                         do_vgapage(0);
2811                 else
2812                         do_vgapage(current_video_screen + 1);
2813         }
2814 }
2815
2816 /*---------------------------------------------------------------------------*
2817  *      function bound to function key 6
2818  *---------------------------------------------------------------------------*/
2819 static void
2820 fkey6(void)
2821 {
2822         if(meta_down)
2823                 more_chars = (u_char *)"\033[29~"; /* DO */
2824         else
2825                 more_chars = (u_char *)"\033[17~"; /* F6 */
2826 }
2827
2828 /*---------------------------------------------------------------------------*
2829  *      function bound to function key 7
2830  *---------------------------------------------------------------------------*/
2831 static void
2832 fkey7(void)
2833 {
2834         if(meta_down)
2835                 more_chars = (u_char *)"\033[31~"; /* F17 */
2836         else
2837                 more_chars = (u_char *)"\033[18~"; /* F7 */
2838 }
2839
2840 /*---------------------------------------------------------------------------*
2841  *      function bound to function key 8
2842  *---------------------------------------------------------------------------*/
2843 static void
2844 fkey8(void)
2845 {
2846         if(meta_down)
2847                 more_chars = (u_char *)"\033[32~"; /* F18 */
2848         else
2849                 more_chars = (u_char *)"\033[19~"; /* F8 */
2850 }
2851
2852 /*---------------------------------------------------------------------------*
2853  *      function bound to function key 9
2854  *---------------------------------------------------------------------------*/
2855 static void
2856 fkey9(void)
2857 {
2858         if(meta_down)
2859                 more_chars = (u_char *)"\033[33~"; /* F19 */
2860         else
2861                 more_chars = (u_char *)"\033[20~"; /* F9 */
2862 }
2863
2864 /*---------------------------------------------------------------------------*
2865  *      function bound to function key 10
2866  *---------------------------------------------------------------------------*/
2867 static void
2868 fkey10(void)
2869 {
2870         if(meta_down)
2871                 more_chars = (u_char *)"\033[34~"; /* F20 */
2872         else
2873                 more_chars = (u_char *)"\033[21~"; /* F10 */
2874 }
2875
2876 /*---------------------------------------------------------------------------*
2877  *      function bound to function key 11
2878  *---------------------------------------------------------------------------*/
2879 static void
2880 fkey11(void)
2881 {
2882         if(meta_down)
2883                 more_chars = (u_char *)"\0x8FP"; /* PF1 */
2884         else
2885                 more_chars = (u_char *)"\033[23~"; /* F11 */
2886 }
2887
2888 /*---------------------------------------------------------------------------*
2889  *      function bound to function key 12
2890  *---------------------------------------------------------------------------*/
2891 static void
2892 fkey12(void)
2893 {
2894         if(meta_down)
2895                 more_chars = (u_char *)"\0x8FQ"; /* PF2 */
2896         else
2897                 more_chars = (u_char *)"\033[24~"; /* F12 */
2898 }
2899
2900 /*---------------------------------------------------------------------------*
2901  *      function bound to SHIFTED function key 1
2902  *---------------------------------------------------------------------------*/
2903 static void
2904 sfkey1(void)
2905 {
2906         if(meta_down)
2907         {
2908                 if(vsp->ukt.length[6])  /* entry available ? */
2909                         more_chars = (u_char *)
2910                                 &(vsp->udkbuf[vsp->ukt.first[6]]);
2911                 else
2912                         more_chars = (u_char *)"\033[23~"; /* F11 */
2913         }
2914         else
2915         {
2916                 do_vgapage(4);
2917         }
2918 }
2919
2920 /*---------------------------------------------------------------------------*
2921  *      function bound to SHIFTED function key 2
2922  *---------------------------------------------------------------------------*/
2923 static void
2924 sfkey2(void)
2925 {
2926         if(meta_down)
2927         {
2928                 if(vsp->ukt.length[7])  /* entry available ? */
2929                         more_chars = (u_char *)
2930                                 &(vsp->udkbuf[vsp->ukt.first[7]]);
2931                 else
2932                         more_chars = (u_char *)"\033[24~"; /* F12 */
2933         }
2934         else
2935         {
2936                 do_vgapage(5);
2937         }
2938 }
2939
2940 /*---------------------------------------------------------------------------*
2941  *      function bound to SHIFTED function key 3
2942  *---------------------------------------------------------------------------*/
2943 static void
2944 sfkey3(void)
2945 {
2946         if(meta_down)
2947         {
2948                 if(vsp->ukt.length[8])  /* entry available ? */
2949                         more_chars = (u_char *)
2950                                 &(vsp->udkbuf[vsp->ukt.first[8]]);
2951                 else
2952                         more_chars = (u_char *)"\033[25~"; /* F13 */
2953         }
2954         else
2955         {
2956                 do_vgapage(6);
2957         }
2958 }
2959
2960 /*---------------------------------------------------------------------------*
2961  *      function bound to SHIFTED function key 4
2962  *---------------------------------------------------------------------------*/
2963 static void
2964 sfkey4(void)
2965 {
2966         if(meta_down)
2967         {
2968                 if(vsp->ukt.length[9])  /* entry available ? */
2969                         more_chars = (u_char *)
2970                                 &(vsp->udkbuf[vsp->ukt.first[9]]);
2971                 else
2972                         more_chars = (u_char *)"\033[26~"; /* F14 */
2973         }
2974         else
2975         {
2976                 do_vgapage(7);
2977         }
2978 }
2979
2980 /*---------------------------------------------------------------------------*
2981  *      function bound to SHIFTED function key 5
2982  *---------------------------------------------------------------------------*/
2983 static void
2984 sfkey5(void)
2985 {
2986         if(meta_down)
2987         {
2988                 if(vsp->ukt.length[11]) /* entry available ? */
2989                         more_chars = (u_char *)
2990                                 &(vsp->udkbuf[vsp->ukt.first[11]]);
2991                 else
2992                         more_chars = (u_char *)"\033[28~"; /* Help */
2993         }
2994         else
2995         {
2996                 if(current_video_screen <= 0)
2997                         do_vgapage(totalscreens-1);
2998                 else
2999                         do_vgapage(current_video_screen - 1);
3000         }
3001 }
3002
3003 /*---------------------------------------------------------------------------*
3004  *      function bound to SHIFTED function key 6
3005  *---------------------------------------------------------------------------*/
3006 static void
3007 sfkey6(void)
3008 {
3009         if(!meta_down)
3010         {
3011                 if(vsp->ukt.length[0])  /* entry available ? */
3012                         more_chars = (u_char *)
3013                                 &(vsp->udkbuf[vsp->ukt.first[0]]);
3014                 else
3015                         more_chars = (u_char *)"\033[17~"; /* F6 */
3016         }
3017         else if(vsp->ukt.length[12])    /* entry available ? */
3018                         more_chars = (u_char *)
3019                                 &(vsp->udkbuf[vsp->ukt.first[12]]);
3020              else
3021                         more_chars = (u_char *)"\033[29~"; /* DO */
3022 }
3023
3024 /*---------------------------------------------------------------------------*
3025  *      function bound to SHIFTED function key 7
3026  *---------------------------------------------------------------------------*/
3027 static void
3028 sfkey7(void)
3029 {
3030         if(!meta_down)
3031         {
3032                 if(vsp->ukt.length[1])  /* entry available ? */
3033                         more_chars = (u_char *)
3034                                 &(vsp->udkbuf[vsp->ukt.first[1]]);
3035                 else
3036                         more_chars = (u_char *)"\033[18~"; /* F7 */
3037         }
3038         else if(vsp->ukt.length[14])    /* entry available ? */
3039                         more_chars = (u_char *)
3040                                 &(vsp->udkbuf[vsp->ukt.first[14]]);
3041              else
3042                         more_chars = (u_char *)"\033[31~"; /* F17 */
3043 }
3044
3045 /*---------------------------------------------------------------------------*
3046  *      function bound to SHIFTED function key 8
3047  *---------------------------------------------------------------------------*/
3048 static void
3049 sfkey8(void)
3050 {
3051         if(!meta_down)
3052         {
3053                 if(vsp->ukt.length[2])  /* entry available ? */
3054                         more_chars = (u_char *)
3055                                 &(vsp->udkbuf[vsp->ukt.first[2]]);
3056                 else
3057                         more_chars = (u_char *)"\033[19~"; /* F8 */
3058         }
3059         else if(vsp->ukt.length[14])    /* entry available ? */
3060                         more_chars = (u_char *)
3061                                 &(vsp->udkbuf[vsp->ukt.first[15]]);
3062              else
3063                         more_chars = (u_char *)"\033[32~"; /* F18 */
3064 }
3065
3066 /*---------------------------------------------------------------------------*
3067  *      function bound to SHIFTED function key 9
3068  *---------------------------------------------------------------------------*/
3069 static void
3070 sfkey9(void)
3071 {
3072         if(!meta_down)
3073         {
3074                 if(vsp->ukt.length[3])  /* entry available ? */
3075                         more_chars = (u_char *)
3076                                 &(vsp->udkbuf[vsp->ukt.first[3]]);
3077                 else
3078                         more_chars = (u_char *)"\033[20~"; /* F9 */
3079         }
3080         else if(vsp->ukt.length[16])    /* entry available ? */
3081                         more_chars = (u_char *)
3082                                 &(vsp->udkbuf[vsp->ukt.first[16]]);
3083              else
3084                         more_chars = (u_char *)"\033[33~"; /* F19 */
3085 }
3086
3087 /*---------------------------------------------------------------------------*
3088  *      function bound to SHIFTED function key 10
3089  *---------------------------------------------------------------------------*/
3090 static void
3091 sfkey10(void)
3092 {
3093         if(!meta_down)
3094         {
3095                 if(vsp->ukt.length[4])  /* entry available ? */
3096                         more_chars = (u_char *)
3097                                 &(vsp->udkbuf[vsp->ukt.first[4]]);
3098                 else
3099                         more_chars = (u_char *)"\033[21~"; /* F10 */
3100         }
3101         else if(vsp->ukt.length[17])    /* entry available ? */
3102                         more_chars = (u_char *)
3103                                 &(vsp->udkbuf[vsp->ukt.first[17]]);
3104              else
3105                         more_chars = (u_char *)"\033[34~"; /* F20 */
3106 }
3107
3108 /*---------------------------------------------------------------------------*
3109  *      function bound to SHIFTED function key 11
3110  *---------------------------------------------------------------------------*/
3111 static void
3112 sfkey11(void)
3113 {
3114         if(!meta_down)
3115         {
3116                 if(vsp->ukt.length[6])  /* entry available ? */
3117                         more_chars = (u_char *)
3118                                 &(vsp->udkbuf[vsp->ukt.first[6]]);
3119                 else
3120                         more_chars = (u_char *)"\033[23~"; /* F11 */
3121         }
3122 }
3123
3124 /*---------------------------------------------------------------------------*
3125  *      function bound to SHIFTED function key 12
3126  *---------------------------------------------------------------------------*/
3127 static void
3128 sfkey12(void)
3129 {
3130         if(!meta_down)
3131         {
3132                 if(vsp->ukt.length[7])  /* entry available ? */
3133                         more_chars = (u_char *)
3134                                 &(vsp->udkbuf[vsp->ukt.first[7]]);
3135                 else
3136                         more_chars = (u_char *)"\033[24~"; /* F12 */
3137         }
3138 }
3139
3140 /*---------------------------------------------------------------------------*
3141  *      function bound to control function key 1
3142  *---------------------------------------------------------------------------*/
3143 static void
3144 cfkey1(void)
3145 {
3146         if(vsp->which_fkl == SYS_FKL)
3147                 toggl_columns(vsp);
3148 }
3149
3150 /*---------------------------------------------------------------------------*
3151  *      function bound to control function key 2
3152  *---------------------------------------------------------------------------*/
3153 static void
3154 cfkey2(void)
3155 {
3156         if(vsp->which_fkl == SYS_FKL)
3157                 vt_ris(vsp);
3158 }
3159
3160 /*---------------------------------------------------------------------------*
3161  *      function bound to control function key 3
3162  *---------------------------------------------------------------------------*/
3163 static void
3164 cfkey3(void)
3165 {
3166         if(vsp->which_fkl == SYS_FKL)
3167                 toggl_24l(vsp);
3168 }
3169
3170 /*---------------------------------------------------------------------------*
3171  *      function bound to control function key 4
3172  *---------------------------------------------------------------------------*/
3173 static void
3174 cfkey4(void)
3175 {
3176
3177 #if PCVT_SHOWKEYS
3178         if(vsp->which_fkl == SYS_FKL)
3179                 toggl_kbddbg(vsp);
3180 #endif /* PCVT_SHOWKEYS */
3181
3182 }
3183
3184 /*---------------------------------------------------------------------------*
3185  *      function bound to control function key 5
3186  *---------------------------------------------------------------------------*/
3187 static void
3188 cfkey5(void)
3189 {
3190         if(vsp->which_fkl == SYS_FKL)
3191                 toggl_bell(vsp);
3192 }
3193
3194 /*---------------------------------------------------------------------------*
3195  *      function bound to control function key 6
3196  *---------------------------------------------------------------------------*/
3197 static void
3198 cfkey6(void)
3199 {
3200         if(vsp->which_fkl == SYS_FKL)
3201                 toggl_sevenbit(vsp);
3202 }
3203
3204 /*---------------------------------------------------------------------------*
3205  *      function bound to control function key 7
3206  *---------------------------------------------------------------------------*/
3207 static void
3208 cfkey7(void)
3209 {
3210         if(vsp->which_fkl == SYS_FKL)
3211                 toggl_dspf(vsp);
3212 }
3213
3214 /*---------------------------------------------------------------------------*
3215  *      function bound to control function key 8
3216  *---------------------------------------------------------------------------*/
3217 static void
3218 cfkey8(void)
3219 {
3220         if(vsp->which_fkl == SYS_FKL)
3221                 toggl_awm(vsp);
3222 }
3223
3224 /*---------------------------------------------------------------------------*
3225  *      function bound to control function key 9
3226  *---------------------------------------------------------------------------*/
3227 static void
3228 cfkey9(void)
3229 {
3230         if(vsp->labels_on)      /* toggle label display on/off */
3231                 fkl_off(vsp);
3232         else
3233                 fkl_on(vsp);
3234 }
3235
3236 /*---------------------------------------------------------------------------*
3237  *      function bound to control function key 10
3238  *---------------------------------------------------------------------------*/
3239 static void
3240 cfkey10(void)
3241 {
3242         if(vsp->labels_on)      /* toggle user/system fkey labels */
3243         {
3244                 if(vsp->which_fkl == USR_FKL)
3245                         sw_sfkl(vsp);
3246                 else if(vsp->which_fkl == SYS_FKL)
3247                         sw_ufkl(vsp);
3248         }
3249 }
3250
3251 /*---------------------------------------------------------------------------*
3252  *      function bound to control function key 11
3253  *---------------------------------------------------------------------------*/
3254 static void
3255 cfkey11(void)
3256 {
3257         if(vsp->vt_pure_mode == M_PUREVT)
3258                 set_emulation_mode(vsp, M_HPVT);
3259         else if(vsp->vt_pure_mode == M_HPVT)
3260                 set_emulation_mode(vsp, M_PUREVT);
3261 }
3262
3263 /*---------------------------------------------------------------------------*
3264  *      function bound to control function key 12
3265  *---------------------------------------------------------------------------*/
3266 static void
3267 cfkey12(void)
3268 {
3269 }
3270
3271 #endif  /* PCVT_VT220KEYB */
3272
3273 /*---------------------------------------------------------------------------*
3274  *      
3275  *---------------------------------------------------------------------------*/
3276 static void
3277 scrollback_save_screen(void)
3278 {
3279         int x = spltty();
3280         size_t s;
3281
3282         s = sizeof(u_short) * vsp->screen_rowsize * vsp->maxcol;
3283
3284         if (scrollback_savedscreen)
3285                 free(scrollback_savedscreen, M_TEMP);
3286
3287         scrnsv_size = s;
3288
3289         if (!(scrollback_savedscreen = (u_short *)malloc(s, M_TEMP, M_NOWAIT)))
3290         {
3291                 splx(x);
3292                 return;
3293         }
3294         bcopy(vsp->Crtat, scrollback_savedscreen, scrnsv_size);
3295         splx(x);
3296 }
3297
3298 /*---------------------------------------------------------------------------*
3299  *      
3300  *---------------------------------------------------------------------------*/
3301 static void
3302 scrollback_restore_screen(void)
3303 {
3304         if (scrollback_savedscreen)
3305                 bcopy(scrollback_savedscreen, vsp->Crtat, scrnsv_size);
3306 }
3307  
3308
3309 #endif  /* NVT > 0 */
3310
3311 /* ------------------------------- EOF -------------------------------------*/