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