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