summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorhannken <hannken@NetBSD.org>1998-04-07 13:43:16 +0000
committerhannken <hannken@NetBSD.org>1998-04-07 13:43:16 +0000
commit64f1bb73d6654f79c1c0895ed55be9ddb71b9d62 (patch)
tree5d94cc759445ec391427ca8e1c205b96da0f0f82 /sys/dev
parentb80f703f77b2b9fc759df49a5fd9d3bda71dbac0 (diff)
Initial import of MI keyboard translation for dev/wscons.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pckbc/files.pckbc4
-rw-r--r--sys/dev/pckbc/pckbd.c367
-rw-r--r--sys/dev/pckbc/pckbd_scancodes.h35
-rw-r--r--sys/dev/pckbc/pckbd_scancodes_us.c135
-rw-r--r--sys/dev/pckbc/pckbdreg.h5
-rw-r--r--sys/dev/wscons/files.wscons5
-rw-r--r--sys/dev/wscons/wsconsio.h36
-rw-r--r--sys/dev/wscons/wsdisplay.c7
-rw-r--r--sys/dev/wscons/wskbd.c431
-rw-r--r--sys/dev/wscons/wskbdmap_mfii.h195
-rw-r--r--sys/dev/wscons/wskbdutil.c550
-rw-r--r--sys/dev/wscons/wskbdvar.h11
-rw-r--r--sys/dev/wscons/wsksymdef.h407
-rw-r--r--sys/dev/wscons/wsksymvar.h39
14 files changed, 1769 insertions, 458 deletions
diff --git a/sys/dev/pckbc/files.pckbc b/sys/dev/pckbc/files.pckbc
index 5a3554a6d2f..799d965ac48 100644
--- a/sys/dev/pckbc/files.pckbc
+++ b/sys/dev/pckbc/files.pckbc
@@ -1,11 +1,9 @@
-# $NetBSD: files.pckbc,v 1.1 1998/03/22 15:41:29 drochner Exp $
+# $NetBSD: files.pckbc,v 1.2 1998/04/07 13:43:16 hannken Exp $
# devices attached at pckbc, for use with wscons
device pckbd: wskbddev
attach pckbd at pckbc
file dev/pckbc/pckbd.c pckbd needs-flag
-file dev/pckbc/pckbd_scancodes_us.c pckbd
-#file dev/pckbc/pckbd_scancodes_de.c pckbd
device psm: wsmousedev
attach psm at pckbc
diff --git a/sys/dev/pckbc/pckbd.c b/sys/dev/pckbc/pckbd.c
index 4b828386c71..0bd0e9f2f80 100644
--- a/sys/dev/pckbc/pckbd.c
+++ b/sys/dev/pckbc/pckbd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pckbd.c,v 1.1 1998/03/22 15:41:27 drochner Exp $ */
+/* $NetBSD: pckbd.c,v 1.2 1998/04/07 13:43:16 hannken Exp $ */
/*-
* Copyright (c) 1993, 1994, 1995 Charles Hannum. All rights reserved.
@@ -58,8 +58,9 @@
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wskbdvar.h>
-
-#include <dev/pckbc/pckbd_scancodes.h>
+#include <dev/wscons/wsksymdef.h>
+#include <dev/wscons/wsksymvar.h>
+#include <dev/wscons/wskbdmap_mfii.h>
#include "locators.h"
@@ -68,11 +69,6 @@ struct pckbd_internal {
pckbc_tag_t t_kbctag;
int t_kbcslot;
- pckbd_scan_def *t_scancodes;
-
- int extended;
- u_char shift_state, lock_state;
-
struct pckbd_softc *t_sc; /* back pointer */
};
@@ -81,6 +77,9 @@ struct pckbd_softc {
struct pckbd_internal *id;
int sc_lastchar;
+ int sc_extended;
+ int sc_extended1;
+ int sc_led_state;
struct device *sc_wskbddev;
};
@@ -96,15 +95,15 @@ struct cfattach pckbd_ca = {
sizeof(struct pckbd_softc), pckbdprobe, pckbdattach,
};
+void pckbd_set_leds __P((void *, int));
int pckbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
-const char *pckbd_translate __P((void *, u_int, int));
const struct wskbd_accessops pckbd_accessops = {
+ pckbd_set_leds,
pckbd_ioctl,
- pckbd_translate,
};
-int pckbd_cngetc __P((void *));
+void pckbd_cngetc __P((void *, u_int *, int *));
void pckbd_cnpollc __P((void *, int));
const struct wskbd_consops pckbd_consops = {
@@ -116,7 +115,10 @@ int pckbd_set_xtscancode __P((pckbc_tag_t, pckbc_slot_t));
void pckbd_init __P((struct pckbd_internal *, pckbc_tag_t, pckbc_slot_t,
int));
void pckbd_input __P((void *, int));
-void pckbd_update_leds __P((struct pckbd_internal *));
+
+static int pckbd_decode __P((struct pckbd_softc *, u_int *, int *));
+static int pckbd_led_encode __P((int));
+static int pckbd_led_decode __P((int));
struct pckbd_internal pckbd_consdata;
@@ -262,6 +264,13 @@ pckbdattach(parent, self, aux)
pckbc_set_inputhandler(sc->id->t_kbctag, sc->id->t_kbcslot,
pckbd_input, sc);
+#ifdef PCKBD_LAYOUT
+ a.layout = PCKBD_LAYOUT;
+#else
+ a.layout = KB_US;
+#endif
+ a.keydesc = wscons_keydesctab;
+ a.num_keydescs = sizeof(wscons_keydesctab)/sizeof(wscons_keydesctab[0]);
a.console = isconsole;
a.accessops = &pckbd_accessops;
a.accesscookie = sc->id;
@@ -273,6 +282,47 @@ pckbdattach(parent, self, aux)
sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
}
+static int pckbd_decode(sc, type, data)
+ struct pckbd_softc *sc;
+ u_int *type;
+ int *data;
+{
+ if (*data == KBR_EXTENDED0) {
+ sc->sc_extended = 1;
+ return(0);
+ } else if (*data == KBR_EXTENDED1) {
+ sc->sc_extended1 = 2;
+ return(0);
+ }
+
+ /* process BREAK key (EXT1 1D 45 EXT1 9D C5) map to (unused) code 7F */
+ if (sc->sc_extended1 == 2 && (*data == 0x1d || *data == 0x9d)) {
+ sc->sc_extended1 = 1;
+ return(0);
+ } else if (sc->sc_extended1 == 1 && (*data == 0x45 || *data == 0xc5)) {
+ sc->sc_extended1 = 0;
+ *data = (*data & 0x80) | 0x7f;
+ } else if (sc->sc_extended1 > 0) {
+ sc->sc_extended1 = 0;
+ }
+
+ /* Always ignore typematic keys */
+ if (*data == sc->sc_lastchar)
+ return(0);
+ sc->sc_lastchar = *data;
+
+ if (*data & 0x80)
+ *type = WSCONS_EVENT_KEY_UP;
+ else
+ *type = WSCONS_EVENT_KEY_DOWN;
+
+ /* map extended keys to (unused) codes 128-254 */
+ *data = (*data & 0x7f) | (sc->sc_extended ? 0x80 : 0);
+
+ sc->sc_extended = 0;
+ return(1);
+}
+
void
pckbd_init(t, kbctag, kbcslot, console)
struct pckbd_internal *t;
@@ -283,19 +333,52 @@ pckbd_init(t, kbctag, kbcslot, console)
t->t_isconsole = console;
t->t_kbctag = kbctag;
t->t_kbcslot = kbcslot;
- t->t_scancodes = pckbd_scan_codes_us;
- t->extended = 0;
- t->shift_state = t->lock_state = 0;
+}
+
+static int
+pckbd_led_encode(led)
+ int led;
+{
+ int res;
+
+ res = 0;
+
+ if (led & WSKBD_LED_SCROLL)
+ res |= 0x01;
+ if (led & WSKBD_LED_NUM)
+ res |= 0x02;
+ if (led & WSKBD_LED_CAPS)
+ res |= 0x04;
+ return(res);
+}
+
+static int
+pckbd_led_decode(led)
+ int led;
+{
+ int res;
+
+ res = 0;
+ if (led & 0x01)
+ res |= WSKBD_LED_SCROLL;
+ if (led & 0x02)
+ res |= WSKBD_LED_NUM;
+ if (led & 0x04)
+ res |= WSKBD_LED_CAPS;
+ return(res);
}
void
-pckbd_update_leds(t)
- struct pckbd_internal *t;
+pckbd_set_leds(v, leds)
+ void *v;
+ int leds;
{
+ struct pckbd_internal *t = v;
u_char cmd[2];
cmd[0] = KBC_MODEIND;
- cmd[1] = t->lock_state;
+ cmd[1] = pckbd_led_encode(leds);
+ t->t_sc->sc_led_state = cmd[1];
(void) pckbc_enqueue_cmd(t->t_kbctag, t->t_kbcslot, cmd, 2, 0, 0, 0);
}
@@ -312,22 +395,8 @@ pckbd_input(vsc, data)
struct pckbd_softc *sc = vsc;
int type;
- /* Always ignore typematic keys */
- if (data == sc->sc_lastchar)
- return;
- sc->sc_lastchar = data;
-
- switch (data) {
- case KBR_EXTENDED:
- type = WSCONS_EVENT_KEY_OTHER;
- break;
- default:
- type = (data & 0x80) ? WSCONS_EVENT_KEY_UP :
- WSCONS_EVENT_KEY_DOWN;
- data &= ~0x80;
- break;
- }
- wskbd_input(sc->sc_wskbddev, type, data);
+ if (pckbd_decode(sc, &type, &data))
+ wskbd_input(sc->sc_wskbddev, type, data);
}
int
@@ -349,190 +418,19 @@ pckbd_ioctl(v, cmd, data, flag, p)
char cmd[2];
int res;
cmd[0] = KBC_MODEIND;
- cmd[1] = *(int*)data;
+ cmd[1] = pckbd_led_encode(*(int *)data);
+ t->t_sc->sc_led_state = cmd[1];
res = pckbc_enqueue_cmd(t->t_kbctag, t->t_kbcslot, cmd, 2, 0,
1, 0);
return (res);
}
+ case WSKBDIO_GETLEDS:
+ *(int *)data = pckbd_led_decode(t->t_sc->sc_led_state);
+ return(0);
}
return -1;
}
-/*
- * Get characters from the keyboard. If none are present, return NULL.
- */
-const char *
-pckbd_translate(v, type, value)
- void *v;
- u_int type;
- int value;
-{
- struct pckbd_internal *t = v;
- u_char dt = value;
- static u_char capchar[2];
-
- if (type == WSCONS_EVENT_KEY_OTHER && dt == KBR_EXTENDED) {
- t->extended = 1;
- return NULL;
- }
-
-#ifdef DDB
- /*
- * Check for cntl-alt-esc.
- */
- if (t->t_isconsole && (type == WSCONS_EVENT_KEY_DOWN) &&
- (dt == 1) && ((t->shift_state & (CTL | ALT)) == (CTL | ALT))
- /* XXX && we're not already in the debugger */) {
- Debugger();
-#if 0
- dt |= 0x80; /* discard esc (ddb discarded ctl-alt) */
-#else
- t->extended = 0;
- return (NULL);
-#endif
- }
-#endif
-
- /* XXX XXX temporary hack to get virtual consoles working */
- if (t->t_sc && ((t->shift_state & (CTL | ALT)) == (CTL | ALT)) &&
- (dt >= 59 && dt <= 66)) {
- if (type == WSCONS_EVENT_KEY_DOWN)
- wskbd_ctlinput(t->t_sc->sc_wskbddev, dt - 59);
- t->extended = 0;
- return (NULL);
- }
-
- /*
- * Check for make/break.
- */
- if (type == WSCONS_EVENT_KEY_UP) {
- /*
- * break
- */
- switch (t->t_scancodes[dt].type) {
- case NUM:
- t->shift_state &= ~NUM;
- break;
- case CAPS:
- t->shift_state &= ~CAPS;
- break;
- case SCROLL:
- t->shift_state &= ~SCROLL;
- break;
- case SHIFT:
- t->shift_state &= ~SHIFT;
- break;
- case ALT:
- if (t->extended)
- t->shift_state &= ~ALTGR;
- else
- t->shift_state &= ~ALT;
- break;
- case CTL:
- t->shift_state &= ~CTL;
- break;
- }
- } else if (type == WSCONS_EVENT_KEY_DOWN) {
- /*
- * make
- */
- /* fix numeric / on non US keyboard */
- if (t->extended && dt == 53) {
- capchar[0] = '/';
- t->extended = 0;
- return capchar;
- }
-
- switch (t->t_scancodes[dt].type) {
- /*
- * locking keys
- */
- case NUM:
- if (t->shift_state & NUM)
- break;
- t->shift_state |= NUM;
- t->lock_state ^= NUM;
- pckbd_update_leds(t);
- break;
- case CAPS:
- if (t->shift_state & CAPS)
- break;
- t->shift_state |= CAPS;
- t->lock_state ^= CAPS;
- pckbd_update_leds(t);
- break;
- case SCROLL:
- if (t->shift_state & SCROLL)
- break;
- t->shift_state |= SCROLL;
- t->lock_state ^= SCROLL;
- if (t->t_sc)
- wskbd_holdscreen(t->t_sc->sc_wskbddev,
- t->lock_state & SCROLL);
- pckbd_update_leds(t);
- break;
- /*
- * non-locking keys
- */
- case SHIFT:
- t->shift_state |= SHIFT;
- break;
- case ALT:
- if (t->extended)
- t->shift_state |= ALTGR;
- else
- t->shift_state |= ALT;
- break;
- case CTL:
- t->shift_state |= CTL;
- break;
- case ASCII:
- /* control has highest priority */
- if (t->shift_state & CTL)
- capchar[0] = t->t_scancodes[dt].ctl[0];
- else if (t->shift_state & ALTGR)
- capchar[0] = t->t_scancodes[dt].altgr[0];
- else if (t->shift_state & SHIFT)
- capchar[0] = t->t_scancodes[dt].shift[0];
- else
- capchar[0] = t->t_scancodes[dt].unshift[0];
- if ((t->lock_state & CAPS) && capchar[0] >= 'a' &&
- capchar[0] <= 'z') {
- capchar[0] -= ('a' - 'A');
- }
- capchar[0] |= (t->shift_state & ALT);
- t->extended = 0;
- return capchar;
- case NONE:
- break;
- case FUNC: {
- char *more_chars;
- if (t->shift_state & SHIFT)
- more_chars = t->t_scancodes[dt].shift;
- else if (t->shift_state & CTL)
- more_chars = t->t_scancodes[dt].ctl;
- else
- more_chars = t->t_scancodes[dt].unshift;
- t->extended = 0;
- return more_chars;
- }
- case KP: {
- char *more_chars;
- if (t->shift_state & (SHIFT | CTL) ||
- (t->lock_state & NUM) == 0 || t->extended)
- more_chars = t->t_scancodes[dt].shift;
- else
- more_chars = t->t_scancodes[dt].unshift;
- t->extended = 0;
- return more_chars;
- }
- }
- }
-
- t->extended = 0;
- return (NULL);
-}
-
int
pckbd_cnattach(kbctag, kbcslot)
pckbc_tag_t kbctag;
@@ -546,47 +444,18 @@ pckbd_cnattach(kbctag, kbcslot)
}
/* ARGSUSED */
-int
-pckbd_cngetc(v)
+void
+pckbd_cngetc(v, type, data)
void *v;
+ u_int *type;
+ int *data;
{
- register const char *cp = NULL;
- u_int type;
- int data;
-#if 0
- static u_char last;
-#endif
-
- do {
- /* wait for byte */
- do {
- data = pckbc_poll_data(pckbd_consdata.t_kbctag,
- pckbd_consdata.t_kbcslot);
- } while (data == -1);
-
-#if 0
- /* Ignore typematic keys */
- if (data == last)
- continue;
- last = data;
-#endif
-
- switch (data) {
- case KBR_EXTENDED:
- type = WSCONS_EVENT_KEY_OTHER;
- break;
- default:
- type = (data & 0x80) ? WSCONS_EVENT_KEY_UP :
- WSCONS_EVENT_KEY_DOWN;
- data &= ~0x80;
- break;
- }
-
- cp = pckbd_translate(&pckbd_consdata, type, data);
- } while (!cp);
- if (*cp == '\r')
- return ('\n');
- return (*cp);
+ for (;;) {
+ *data = pckbc_poll_data(pckbd_consdata.t_kbctag,
+ pckbd_consdata.t_kbcslot);
+ if (pckbd_decode(pckbd_consdata.t_sc, type, data))
+ return;
+ }
}
void
diff --git a/sys/dev/pckbc/pckbd_scancodes.h b/sys/dev/pckbc/pckbd_scancodes.h
deleted file mode 100644
index 46ab19ab926..00000000000
--- a/sys/dev/pckbc/pckbd_scancodes.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* $NetBSD: pckbd_scancodes.h,v 1.1 1998/03/22 15:41:28 drochner Exp $ */
-
-#define PCKBD_CODE_SIZE 4 /* Use a max of 4 for now... */
-#define PCKBD_NUM_KEYS 128 /* Number of scan codes */
-
-typedef struct {
- u_short type;
- char unshift[PCKBD_CODE_SIZE];
- char shift[PCKBD_CODE_SIZE];
- char ctl[PCKBD_CODE_SIZE];
- char altgr[PCKBD_CODE_SIZE];
-} pckbd_scan_def;
-
-/*
- * DANGER WIL ROBINSON -- the values of SCROLL, NUM, CAPS, and ALT are
- * important.
- */
-#define SCROLL 0x0001 /* stop output */
-#define NUM 0x0002 /* numeric shift cursors vs. numeric */
-#define CAPS 0x0004 /* caps shift -- swaps case of letter */
-#define SHIFT 0x0008 /* keyboard shift */
-#define CTL 0x0010 /* control shift -- allows ctl function */
-#define ASCII 0x0020 /* ascii code for this key */
-#define ALTGR 0x0040 /* Alt graphic */
-#define ALT 0x0080 /* alternate shift -- alternate chars */
-#define FUNC 0x0100 /* function key */
-#define KP 0x0200 /* Keypad keys */
-#define NONE 0x0400 /* no function */
-
-extern pckbd_scan_def
- pckbd_scan_codes_de[],
- pckbd_scan_codes_fi[],
- pckbd_scan_codes_fr[],
- pckbd_scan_codes_no[],
- pckbd_scan_codes_us[];
diff --git a/sys/dev/pckbc/pckbd_scancodes_us.c b/sys/dev/pckbc/pckbd_scancodes_us.c
deleted file mode 100644
index e318a736cf1..00000000000
--- a/sys/dev/pckbc/pckbd_scancodes_us.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* $NetBSD: pckbd_scancodes_us.c,v 1.1 1998/03/22 15:41:28 drochner Exp $ */
-
-#include <sys/types.h>
-#include <dev/pckbc/pckbd_scancodes.h>
-
-pckbd_scan_def pckbd_scan_codes_us[] = {
- { NONE, "", "", "", }, /* 0 unused */
- { ASCII, "\033", "\033", "\033", }, /* 1 ESCape */
- { ASCII, "1", "!", "!", }, /* 2 1 */
- { ASCII, "2", "@", "\000", }, /* 3 2 */
- { ASCII, "3", "#", "#", }, /* 4 3 */
- { ASCII, "4", "$", "$", }, /* 5 4 */
- { ASCII, "5", "%", "%", }, /* 6 5 */
- { ASCII, "6", "^", "\036", }, /* 7 6 */
- { ASCII, "7", "&", "&", }, /* 8 7 */
- { ASCII, "8", "*", "\010", }, /* 9 8 */
- { ASCII, "9", "(", "(", }, /* 10 9 */
- { ASCII, "0", ")", ")", }, /* 11 0 */
- { ASCII, "-", "_", "\037", }, /* 12 - */
- { ASCII, "=", "+", "+", }, /* 13 = */
- { ASCII, "\177", "\177", "\010", }, /* 14 backspace */
- { ASCII, "\t", "\177\t", "\t", }, /* 15 tab */
- { ASCII, "q", "Q", "\021", }, /* 16 q */
- { ASCII, "w", "W", "\027", }, /* 17 w */
- { ASCII, "e", "E", "\005", }, /* 18 e */
- { ASCII, "r", "R", "\022", }, /* 19 r */
- { ASCII, "t", "T", "\024", }, /* 20 t */
- { ASCII, "y", "Y", "\031", }, /* 21 y */
- { ASCII, "u", "U", "\025", }, /* 22 u */
- { ASCII, "i", "I", "\011", }, /* 23 i */
- { ASCII, "o", "O", "\017", }, /* 24 o */
- { ASCII, "p", "P", "\020", }, /* 25 p */
- { ASCII, "[", "{", "\033", }, /* 26 [ */
- { ASCII, "]", "}", "\035", }, /* 27 ] */
- { ASCII, "\r", "\r", "\n", }, /* 28 return */
- { CTL, "", "", "", }, /* 29 control */
- { ASCII, "a", "A", "\001", }, /* 30 a */
- { ASCII, "s", "S", "\023", }, /* 31 s */
- { ASCII, "d", "D", "\004", }, /* 32 d */
- { ASCII, "f", "F", "\006", }, /* 33 f */
- { ASCII, "g", "G", "\007", }, /* 34 g */
- { ASCII, "h", "H", "\010", }, /* 35 h */
- { ASCII, "j", "J", "\n", }, /* 36 j */
- { ASCII, "k", "K", "\013", }, /* 37 k */
- { ASCII, "l", "L", "\014", }, /* 38 l */
- { ASCII, ";", ":", ";", }, /* 39 ; */
- { ASCII, "'", "\"", "'", }, /* 40 ' */
- { ASCII, "`", "~", "`", }, /* 41 ` */
- { SHIFT, "", "", "", }, /* 42 shift */
- { ASCII, "\\", "|", "\034", }, /* 43 \ */
- { ASCII, "z", "Z", "\032", }, /* 44 z */
- { ASCII, "x", "X", "\030", }, /* 45 x */
- { ASCII, "c", "C", "\003", }, /* 46 c */
- { ASCII, "v", "V", "\026", }, /* 47 v */
- { ASCII, "b", "B", "\002", }, /* 48 b */
- { ASCII, "n", "N", "\016", }, /* 49 n */
- { ASCII, "m", "M", "\r", }, /* 50 m */
- { ASCII, ",", "<", "<", }, /* 51 , */
- { ASCII, ".", ">", ">", }, /* 52 . */
- { ASCII, "/", "?", "\037", }, /* 53 / */
- { SHIFT, "", "", "", }, /* 54 shift */
- { KP, "*", "*", "*", }, /* 55 kp * */
- { ALT, "", "", "", }, /* 56 alt */
- { ASCII, " ", " ", "\000", }, /* 57 space */
- { CAPS, "", "", "", }, /* 58 caps */
- { FUNC, "\033[M", "\033[Y", "\033[k", }, /* 59 f1 */
- { FUNC, "\033[N", "\033[Z", "\033[l", }, /* 60 f2 */
- { FUNC, "\033[O", "\033[a", "\033[m", }, /* 61 f3 */
- { FUNC, "\033[P", "\033[b", "\033[n", }, /* 62 f4 */
- { FUNC, "\033[Q", "\033[c", "\033[o", }, /* 63 f5 */
- { FUNC, "\033[R", "\033[d", "\033[p", }, /* 64 f6 */
- { FUNC, "\033[S", "\033[e", "\033[q", }, /* 65 f7 */
- { FUNC, "\033[T", "\033[f", "\033[r", }, /* 66 f8 */
- { FUNC, "\033[U", "\033[g", "\033[s", }, /* 67 f9 */
- { FUNC, "\033[V", "\033[h", "\033[t", }, /* 68 f10 */
- { NUM, "", "", "", }, /* 69 num lock */
- { SCROLL, "", "", "", }, /* 70 scroll lock */
- { KP, "7", "\033[H", "7", }, /* 71 kp 7 */
- { KP, "8", "\033[A", "8", }, /* 72 kp 8 */
- { KP, "9", "\033[I", "9", }, /* 73 kp 9 */
- { KP, "-", "-", "-", }, /* 74 kp - */
- { KP, "4", "\033[D", "4", }, /* 75 kp 4 */
- { KP, "5", "\033[E", "5", }, /* 76 kp 5 */
- { KP, "6", "\033[C", "6", }, /* 77 kp 6 */
- { KP, "+", "+", "+", }, /* 78 kp + */
- { KP, "1", "\033[F", "1", }, /* 79 kp 1 */
- { KP, "2", "\033[B", "2", }, /* 80 kp 2 */
- { KP, "3", "\033[G", "3", }, /* 81 kp 3 */
- { KP, "0", "\033[L", "0", }, /* 82 kp 0 */
- { KP, ".", "\177", ".", }, /* 83 kp . */
- { NONE, "", "", "", }, /* 84 0 */
- { NONE, "100", "", "", }, /* 85 0 */
- { NONE, "101", "", "", }, /* 86 0 */
- { FUNC, "\033[W", "\033[i", "\033[u", }, /* 87 f11 */
- { FUNC, "\033[X", "\033[j", "\033[v", }, /* 88 f12 */
- { NONE, "102", "", "", }, /* 89 0 */
- { NONE, "103", "", "", }, /* 90 0 */
- { NONE, "", "", "", }, /* 91 0 */
- { NONE, "", "", "", }, /* 92 0 */
- { NONE, "", "", "", }, /* 93 0 */
- { NONE, "", "", "", }, /* 94 0 */
- { NONE, "", "", "", }, /* 95 0 */
- { NONE, "", "", "", }, /* 96 0 */
- { NONE, "", "", "", }, /* 97 0 */
- { NONE, "", "", "", }, /* 98 0 */
- { NONE, "", "", "", }, /* 99 0 */
- { NONE, "", "", "", }, /* 100 */
- { NONE, "", "", "", }, /* 101 */
- { NONE, "", "", "", }, /* 102 */
- { NONE, "", "", "", }, /* 103 */
- { NONE, "", "", "", }, /* 104 */
- { NONE, "", "", "", }, /* 105 */
- { NONE, "", "", "", }, /* 106 */
- { NONE, "", "", "", }, /* 107 */
- { NONE, "", "", "", }, /* 108 */
- { NONE, "", "", "", }, /* 109 */
- { NONE, "", "", "", }, /* 110 */
- { NONE, "", "", "", }, /* 111 */
- { NONE, "", "", "", }, /* 112 */
- { NONE, "", "", "", }, /* 113 */
- { NONE, "", "", "", }, /* 114 */
- { NONE, "", "", "", }, /* 115 */
- { NONE, "", "", "", }, /* 116 */
- { NONE, "", "", "", }, /* 117 */
- { NONE, "", "", "", }, /* 118 */
- { NONE, "", "", "", }, /* 119 */
- { NONE, "", "", "", }, /* 120 */
- { NONE, "", "", "", }, /* 121 */
- { NONE, "", "", "", }, /* 122 */
- { NONE, "", "", "", }, /* 123 */
- { NONE, "", "", "", }, /* 124 */
- { NONE, "", "", "", }, /* 125 */
- { NONE, "", "", "", }, /* 126 */
- { NONE, "", "", "", }, /* 127 */
-};
diff --git a/sys/dev/pckbc/pckbdreg.h b/sys/dev/pckbc/pckbdreg.h
index 8eefbd0ee95..211645e58b3 100644
--- a/sys/dev/pckbc/pckbdreg.h
+++ b/sys/dev/pckbc/pckbdreg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pckbdreg.h,v 1.1 1998/03/22 15:41:28 drochner Exp $ */
+/* $NetBSD: pckbdreg.h,v 1.2 1998/04/07 13:43:16 hannken Exp $ */
/*
* Keyboard definitions
@@ -16,7 +16,8 @@
#define KBC_ECHO 0xEE /* request an echo from the keyboard */
/* keyboard responses */
-#define KBR_EXTENDED 0xE0 /* extended key sequence */
+#define KBR_EXTENDED0 0xE0 /* extended key sequence */
+#define KBR_EXTENDED1 0xE1 /* extended key sequence */
#define KBR_RESEND 0xFE /* needs resend of command */
#define KBR_ACK 0xFA /* received a valid command */
#define KBR_OVERRUN 0x00 /* flooded */
diff --git a/sys/dev/wscons/files.wscons b/sys/dev/wscons/files.wscons
index 4f109570f50..5579a0ed3d1 100644
--- a/sys/dev/wscons/files.wscons
+++ b/sys/dev/wscons/files.wscons
@@ -1,4 +1,4 @@
-# $NetBSD: files.wscons,v 1.1 1998/03/22 14:24:02 drochner Exp $
+# $NetBSD: files.wscons,v 1.2 1998/04/07 13:43:17 hannken Exp $
#
# "Workstation Console" glue; attaches frame buffer to emulator & keyboard,
@@ -43,6 +43,9 @@ file dev/wscons/wsevent.c
file dev/wscons/wskbd.c
wskbd | wsdisplaydev | wsemuldisplaydev | wskbddev
needs-flag
+file dev/wscons/wskbdutil.c
+ wskbd | wsdisplaydev | wsemuldisplaydev | wskbddev
+ needs-flag
file dev/wscons/wsmouse.c
wsmouse | wsmousedev needs-flag
diff --git a/sys/dev/wscons/wsconsio.h b/sys/dev/wscons/wsconsio.h
index b8723b32f13..6712c91166c 100644
--- a/sys/dev/wscons/wsconsio.h
+++ b/sys/dev/wscons/wsconsio.h
@@ -1,4 +1,4 @@
-/* $NetBSD: wsconsio.h,v 1.1 1998/03/22 14:24:02 drochner Exp $ */
+/* $NetBSD: wsconsio.h,v 1.2 1998/04/07 13:43:17 hannken Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -30,8 +30,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __ALPHA_INCLUDE_WSCONSIO_H_
-#define __ALPHA_INCLUDE_WSCONSIO_H_
+#ifndef _DEV_WSCONS_WSCONSIO_H_
+#define _DEV_WSCONS_WSCONSIO_H_
/*
* WSCONS (wsdisplay, wskbd, wsmouse) exported interfaces.
@@ -45,6 +45,7 @@
#include <sys/types.h>
#include <sys/ioccom.h>
+#include <dev/wscons/wsksymvar.h>
/*
@@ -115,7 +116,32 @@ struct wskbd_keyrepeat_data {
#define WSKBDIO_GETDEFAULTKEYREPEAT \
_IOR('W', 10, struct wskbd_keyrepeat_data)
-#define WSKBDIO_SETLEDS _IOW('W', 11, int)
+/* Get/set keyboard leds */
+#define WSKBD_LED_CAPS 0x01
+#define WSKBD_LED_NUM 0x02
+#define WSKBD_LED_SCROLL 0x04
+#define WSKBD_LED_COMPOSE 0x08
+
+#define WSKBDIO_SETLEDS _IOR('W', 11, int)
+#define WSKBDIO_GETLEDS _IOW('W', 12, int)
+
+/* Manipulate keysym groups. */
+struct wskbd_map_data {
+ u_int maplen; /* number of entries in map */
+ struct wscons_keymap *map; /* map to get or set */
+};
+#define WSKBDIO_GETMAP _IOWR('W', 13, struct wskbd_map_data)
+#define WSKBDIO_SETMAP _IOW('W', 14, struct wskbd_map_data)
+#define WSKBDIO_GETENCODING _IOR('W', 15, int)
+#define WSKBDIO_SETENCODING _IOW('W', 16, int)
+
+/* Manipulate strings of function keys */
+struct wskbd_string_data {
+ u_int keycode; /* keycode to change */
+ char value[WSKBD_STRING_LEN]; /* string data */
+};
+#define WSKBDIO_GETSTRING _IOR('W', 17, struct wskbd_string_data)
+#define WSKBDIO_SETSTRING _IOW('W', 18, struct wskbd_string_data)
/*
* Mouse ioctls (32 - 63)
@@ -219,4 +245,4 @@ struct wsdisplay_font {
/* XXX NOT YET DEFINED */
/* Mapping information retrieval. */
-#endif /* __ALPHA_INCLUDE_WSCONSIO_H_ */
+#endif /* _DEV_WSCONS_WSCONSIO_H_ */
diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c
index 5eef450666a..30307dd9ee7 100644
--- a/sys/dev/wscons/wsdisplay.c
+++ b/sys/dev/wscons/wsdisplay.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wsdisplay.c,v 1.2 1998/03/27 18:26:22 drochner Exp $ */
+/* $NetBSD: wsdisplay.c,v 1.3 1998/04/07 13:43:17 hannken Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -33,7 +33,7 @@
static const char _copyright[] __attribute__ ((unused)) =
"Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.";
static const char _rcsid[] __attribute__ ((unused)) =
- "$NetBSD: wsdisplay.c,v 1.2 1998/03/27 18:26:22 drochner Exp $";
+ "$NetBSD: wsdisplay.c,v 1.3 1998/04/07 13:43:17 hannken Exp $";
#include <sys/param.h>
#include <sys/conf.h>
@@ -902,6 +902,9 @@ wsdisplay_switch(dev, no)
struct wsscreen *ws;
int s;
+ if (no < 0 || no >= WSDISPLAY_MAXSCREEN)
+ return (ENXIO);
+
ws = sc->sc_scr[no];
if (!ws)
return (ENXIO);
diff --git a/sys/dev/wscons/wskbd.c b/sys/dev/wscons/wskbd.c
index 86a4064d567..efb719af7bb 100644
--- a/sys/dev/wscons/wskbd.c
+++ b/sys/dev/wscons/wskbd.c
@@ -1,8 +1,11 @@
-/* $NetBSD: wskbd.c,v 1.1 1998/03/22 14:24:03 drochner Exp $ */
+/* $NetBSD: wskbd.c,v 1.2 1998/04/07 13:43:17 hannken Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
*
+ * Keysym translator:
+ * Contributed to The NetBSD Foundation by Juergen Hannken-Illjes.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -33,7 +36,7 @@
static const char _copyright[] __attribute__ ((unused)) =
"Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.";
static const char _rcsid[] __attribute__ ((unused)) =
- "$NetBSD: wskbd.c,v 1.1 1998/03/22 14:24:03 drochner Exp $";
+ "$NetBSD: wskbd.c,v 1.2 1998/04/07 13:43:17 hannken Exp $";
/*
* Copyright (c) 1992, 1993
@@ -92,6 +95,7 @@ static const char _rcsid[] __attribute__ ((unused)) =
#include <sys/proc.h>
#include <sys/syslog.h>
#include <sys/systm.h>
+#include <sys/malloc.h>
#include <sys/tty.h>
#include <sys/signalvar.h>
#include <sys/errno.h>
@@ -99,6 +103,8 @@ static const char _rcsid[] __attribute__ ((unused)) =
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wskbdvar.h>
+#include <dev/wscons/wsksymdef.h>
+#include <dev/wscons/wsksymvar.h>
#include <dev/wscons/wseventvar.h>
#include <dev/wscons/wscons_callbacks.h>
@@ -122,14 +128,53 @@ struct wskbd_softc {
u_int sc_repeatstrlen; /* repeated character (string) len */
int sc_translating; /* xlate to chars for emulation */
+
+ int sc_keydesc_len;
+ const struct wscons_keydesc *sc_keydesc;
+ int sc_layout; /* name of current translation map */
+ int sc_modifiers;
+ int sc_led_state;
+ int sc_maplen; /* number of entries in sc_map */
+ struct wscons_keymap *sc_map; /* current translation map */
+ int sc_composelen; /* remaining entries in sc_composebuf */
+ keysym_t sc_composebuf[2];
};
+#define MOD_SHIFT_L (1 << 0)
+#define MOD_SHIFT_R (1 << 1)
+#define MOD_SHIFTLOCK (1 << 2)
+#define MOD_CAPSLOCK (1 << 3)
+#define MOD_CONTROL_L (1 << 4)
+#define MOD_CONTROL_R (1 << 5)
+#define MOD_META_L (1 << 6)
+#define MOD_META_R (1 << 7)
+#define MOD_MODESHIFT (1 << 8)
+#define MOD_NUMLOCK (1 << 9)
+#define MOD_COMPOSE (1 << 10)
+#define MOD_HOLDSCREEN (1 << 11)
+#define MOD_COMMAND (1 << 12)
+#define MOD_COMMAND1 (1 << 13)
+#define MOD_COMMAND2 (1 << 14)
+
+#define MOD_ANYSHIFT (MOD_SHIFT_L | MOD_SHIFT_R | MOD_SHIFTLOCK)
+#define MOD_ANYCONTROL (MOD_CONTROL_L | MOD_CONTROL_R)
+#define MOD_ANYMETA (MOD_META_L | MOD_META_R)
+
+#define MOD_ONESET(sc, mask) (((sc)->sc_modifiers & (mask)) != 0)
+#define MOD_ALLSET(sc, mask) (((sc)->sc_modifiers & (mask)) == (mask))
+
#ifdef __BROKEN_INDIRECT_CONFIG
int wskbd_match __P((struct device *, void *, void *));
#else
int wskbd_match __P((struct device *, struct cfdata *, void *));
#endif
void wskbd_attach __P((struct device *, struct device *, void *));
+static inline void update_leds __P((struct wskbd_softc *));
+static inline void update_modifier __P((struct wskbd_softc *, u_int, int, int));
+static void internal_command __P((struct wskbd_softc *, u_int *, keysym_t));
+static char *wskbd_translate __P((struct wskbd_softc *, u_int, int));
+static void wskbd_holdscreen __P((struct wskbd_softc *, int));
+
struct cfattach wskbd_ca = {
sizeof (struct wskbd_softc), wskbd_match, wskbd_attach,
@@ -244,10 +289,18 @@ wskbd_attach(parent, self, aux)
sc->sc_accessops = ap->accessops;
sc->sc_accesscookie = ap->accesscookie;
+ sc->sc_layout = ap->layout;
+ sc->sc_keydesc = ap->keydesc;
+ sc->sc_keydesc_len = ap->num_keydescs;
sc->sc_ready = 0; /* sanity */
sc->sc_repeating = 0;
sc->sc_translating = 1;
+ if (wskbd_load_keymap(sc->sc_layout,
+ sc->sc_keydesc, sc->sc_keydesc_len,
+ &sc->sc_map, &sc->sc_maplen) != 0)
+ panic("cannot load keymap");
+
if (ap->console) {
KASSERT(wskbd_console_initted);
KASSERT(wskbd_console_device == NULL);
@@ -317,8 +370,7 @@ wskbd_input(dev, type, value)
* send upstream.
*/
if (sc->sc_translating) {
- cp = (*sc->sc_accessops->translate)(sc->sc_accesscookie,
- type, value);
+ cp = wskbd_translate(sc, type, value);
if (cp != NULL) {
sc->sc_repeatstr = cp;
sc->sc_repeatstrlen = strlen(cp);
@@ -362,25 +414,26 @@ wskbd_input(dev, type, value)
WSEVENT_WAKEUP(&sc->sc_events);
}
-void wskbd_ctlinput(dev, val)
- struct device *dev;
- int val;
-{
- struct wskbd_softc *sc = (struct wskbd_softc *)dev;
-
- if (sc->sc_displaydv != NULL)
- wsdisplay_switch(sc->sc_displaydv, val); /* XXX XXX */
-}
-
-void
-wskbd_holdscreen(dev, hold)
- struct device *dev;
+static void
+wskbd_holdscreen(sc, hold)
+ struct wskbd_softc *sc;
int hold;
{
- struct wskbd_softc *sc = (struct wskbd_softc *)dev;
+ int new_state;
- if (sc->sc_displaydv != NULL)
+ if (sc->sc_displaydv != NULL) {
wsdisplay_kbdholdscreen(sc->sc_displaydv, hold);
+ new_state = sc->sc_led_state;
+ if (hold)
+ new_state |= WSKBD_LED_SCROLL;
+ else
+ new_state &= ~WSKBD_LED_SCROLL;
+ if (new_state != sc->sc_led_state) {
+ (*sc->sc_accessops->asyn_set_leds)(sc->sc_accesscookie,
+ new_state);
+ sc->sc_led_state = new_state;
+ }
+ }
}
int
@@ -505,7 +558,10 @@ wskbd_displayioctl(dev, cmd, data, flag, p)
struct wskbd_softc *sc = (struct wskbd_softc *)dev;
struct wskbd_bell_data *ubdp, *kbdp;
struct wskbd_keyrepeat_data *ukdp, *kkdp;
- int error;
+ struct wskbd_string_data *usdp;
+ struct wskbd_map_data *umdp;
+ void *buf;
+ int len, error;
switch (cmd) {
#define SETBELL(dstp, srcp, dfltp) \
@@ -599,6 +655,61 @@ getkeyrepeat:
goto getkeyrepeat;
#undef SETKEYREPEAT
+
+ case WSKBDIO_SETMAP:
+ if ((flag & FWRITE) == 0)
+ return (EACCES);
+ umdp = (struct wskbd_map_data *)data;
+ len = umdp->maplen*sizeof(struct wscons_keymap);
+ buf = malloc(len, M_TEMP, M_WAITOK);
+ error = copyin(umdp->map, buf, len);
+ if (error == 0) {
+ wskbd_init_keymap(umdp->maplen,
+ &sc->sc_map, &sc->sc_maplen);
+ bcopy(buf, sc->sc_map, len);
+ }
+ free(buf, M_TEMP);
+ return(error);
+
+ case WSKBDIO_GETMAP:
+ umdp = (struct wskbd_map_data *)data;
+ if (umdp->maplen > sc->sc_maplen)
+ umdp->maplen = sc->sc_maplen;
+ error = copyout(sc->sc_map, umdp->map,
+ umdp->maplen*sizeof(struct wscons_keymap));
+ return(error);
+
+ case WSKBDIO_GETENCODING:
+ *((kbd_t *) data) = sc->sc_layout;
+ return(0);
+
+ case WSKBDIO_SETENCODING:
+ if ((flag & FWRITE) == 0)
+ return (EACCES);
+ error = wskbd_load_keymap(*((kbd_t *)data), sc->sc_keydesc,
+ sc->sc_keydesc_len, &sc->sc_map,
+ &sc->sc_maplen);
+ if (error == 0)
+ sc->sc_layout = *((kbd_t *)data);
+ return(error);
+
+ case WSKBDIO_GETSTRING:
+ usdp = (struct wskbd_string_data *)data;
+ if (usdp->keycode < 0 || usdp->keycode >= sc->sc_maplen)
+ return(EINVAL);
+ buf = wskbd_get_string(usdp->keycode);
+ if (buf == NULL)
+ return(EINVAL);
+ bcopy(buf, usdp->value, WSKBD_STRING_LEN);
+ return(0);
+
+ case WSKBDIO_SETSTRING:
+ if ((flag & FWRITE) == 0)
+ return (EACCES);
+ usdp = (struct wskbd_string_data *)data;
+ if (usdp->keycode < 0 || usdp->keycode >= sc->sc_maplen)
+ return(EINVAL);
+ return(wskbd_set_string(usdp->keycode, usdp->value));
}
/*
@@ -670,6 +781,9 @@ int
wskbd_cngetc(dev)
dev_t dev;
{
+ u_int type;
+ int data;
+ char *cp;
if (!wskbd_console_initted)
return 0;
@@ -678,7 +792,13 @@ wskbd_cngetc(dev)
!wskbd_console_device->sc_translating)
return 0;
- return ((*wskbd_console_ops->getc)(wskbd_console_cookie));
+ do {
+ (*wskbd_console_ops->getc)(wskbd_console_cookie,
+ &type, &data);
+ cp = wskbd_translate(wskbd_console_device, type, data);
+ } while (cp == NULL || cp[1] != '\0');
+
+ return(cp[0]);
}
void
@@ -696,3 +816,272 @@ wskbd_cnpollc(dev, poll)
(*wskbd_console_ops->pollc)(wskbd_console_cookie, poll);
}
+
+static inline void
+update_leds(sc)
+ struct wskbd_softc *sc;
+{
+ int new_state;
+
+ new_state = 0;
+ if (sc->sc_modifiers & (MOD_SHIFTLOCK | MOD_CAPSLOCK))
+ new_state |= WSKBD_LED_CAPS;
+ if (sc->sc_modifiers & MOD_NUMLOCK)
+ new_state |= WSKBD_LED_NUM;
+ if (sc->sc_modifiers & MOD_COMPOSE)
+ new_state |= WSKBD_LED_COMPOSE;
+ if (sc->sc_modifiers & MOD_HOLDSCREEN)
+ new_state |= WSKBD_LED_SCROLL;
+
+ if (new_state != sc->sc_led_state) {
+ (*sc->sc_accessops->asyn_set_leds)(sc->sc_accesscookie,
+ new_state);
+ sc->sc_led_state = new_state;
+ }
+}
+
+static inline void
+update_modifier(sc, type, toggle, mask)
+ struct wskbd_softc *sc;
+ u_int type;
+ int toggle;
+ int mask;
+{
+ if (toggle) {
+ if (type == WSCONS_EVENT_KEY_DOWN)
+ sc->sc_modifiers ^= mask;
+ } else {
+ if (type == WSCONS_EVENT_KEY_DOWN)
+ sc->sc_modifiers |= mask;
+ else
+ sc->sc_modifiers &= ~mask;
+ }
+}
+
+static void
+internal_command(sc, type, ksym)
+ struct wskbd_softc *sc;
+ u_int *type;
+ keysym_t ksym;
+{
+ switch (ksym) {
+ case KS_Cmd:
+ update_modifier(sc, *type, 0, MOD_COMMAND);
+ break;
+
+ case KS_Cmd1:
+ update_modifier(sc, *type, 0, MOD_COMMAND1);
+ break;
+
+ case KS_Cmd2:
+ update_modifier(sc, *type, 0, MOD_COMMAND2);
+ break;
+ }
+
+ if (*type != WSCONS_EVENT_KEY_DOWN ||
+ (! MOD_ONESET(sc, MOD_COMMAND) &&
+ ! MOD_ALLSET(sc, MOD_COMMAND1 | MOD_COMMAND2)))
+ return;
+
+ switch (ksym) {
+#ifdef DDB
+ case KS_Cmd_Debugger:
+ if (sc->sc_isconsole)
+ Debugger();
+ /* discard this key (ddb discarded command modifiers) */
+ *type = WSCONS_EVENT_KEY_UP;
+ break;
+#endif
+
+ case KS_Cmd_Screen0:
+ case KS_Cmd_Screen1:
+ case KS_Cmd_Screen2:
+ case KS_Cmd_Screen3:
+ case KS_Cmd_Screen4:
+ case KS_Cmd_Screen5:
+ case KS_Cmd_Screen6:
+ case KS_Cmd_Screen7:
+ case KS_Cmd_Screen8:
+ case KS_Cmd_Screen9:
+ wsdisplay_switch(sc->sc_displaydv, ksym - KS_Cmd_Screen0);
+ break;
+ }
+}
+
+static char *
+wskbd_translate(sc, type, value)
+ struct wskbd_softc *sc;
+ u_int type;
+ int value;
+{
+ keysym_t ksym, res, *group;
+ struct wscons_keymap *kp;
+ static char result[2];
+
+ if (value < 0 || value >= sc->sc_maplen) {
+#ifdef DEBUG
+ printf("wskbd_translate: keycode %d out of range\n", value);
+#endif
+ return(NULL);
+ }
+
+ kp = sc->sc_map + value;
+
+ /* if this key has a command, process it first */
+ if (kp->command != KS_voidSymbol)
+ internal_command(sc, &type, kp->command);
+
+ /* Now update modifiers */
+ switch (kp->group1[0]) {
+ case KS_Shift_L:
+ update_modifier(sc, type, 0, MOD_SHIFT_L);
+ break;
+
+ case KS_Shift_R:
+ update_modifier(sc, type, 0, MOD_SHIFT_R);
+ break;
+
+ case KS_Shift_Lock:
+ update_modifier(sc, type, 1, MOD_SHIFTLOCK);
+ break;
+
+ case KS_Caps_Lock:
+ update_modifier(sc, type, 1, MOD_CAPSLOCK);
+ break;
+
+ case KS_Control_L:
+ update_modifier(sc, type, 0, MOD_CONTROL_L);
+ break;
+
+ case KS_Control_R:
+ update_modifier(sc, type, 0, MOD_CONTROL_R);
+ break;
+
+ case KS_Alt_L:
+ update_modifier(sc, type, 0, MOD_META_L);
+ break;
+
+ case KS_Alt_R:
+ update_modifier(sc, type, 0, MOD_META_R);
+ break;
+
+ case KS_Mode_switch:
+ update_modifier(sc, type, 0, MOD_MODESHIFT);
+ break;
+
+ case KS_Num_Lock:
+ update_modifier(sc, type, 1, MOD_NUMLOCK);
+ break;
+
+ case KS_Hold_Screen:
+ update_modifier(sc, type, 1, MOD_HOLDSCREEN);
+ wskbd_holdscreen(sc, sc->sc_modifiers & MOD_HOLDSCREEN);
+ break;
+ }
+
+ /* If this is a key release or we are in command mode, we are done */
+ if (type != WSCONS_EVENT_KEY_DOWN || MOD_ONESET(sc, MOD_COMMAND) ||
+ MOD_ALLSET(sc, MOD_COMMAND1 | MOD_COMMAND2)) {
+ update_leds(sc);
+ return(NULL);
+ }
+
+ /* Get the keysym */
+ if (sc->sc_modifiers & MOD_MODESHIFT)
+ group = & kp->group2[0];
+ else
+ group = & kp->group1[0];
+
+ if ((sc->sc_modifiers & MOD_NUMLOCK) != 0 &&
+ KS_GROUP(group[1]) == KS_GROUP_Keypad) {
+ if (MOD_ONESET(sc, MOD_ANYSHIFT))
+ ksym = group[0];
+ else
+ ksym = group[1];
+ } else if (! MOD_ONESET(sc, MOD_ANYSHIFT | MOD_CAPSLOCK)) {
+ ksym = group[0];
+ } else if (MOD_ONESET(sc, MOD_CAPSLOCK)) {
+ if (! MOD_ONESET(sc, MOD_SHIFT_L | MOD_SHIFT_R))
+ ksym = group[0];
+ else
+ ksym = group[1];
+ if (ksym >= KS_a && ksym <= KS_z)
+ ksym += KS_A - KS_a;
+ else if (ksym >= KS_agrave && ksym <= KS_thorn &&
+ ksym != KS_division)
+ ksym += KS_Agrave - KS_agrave;
+ } else if (MOD_ONESET(sc, MOD_ANYSHIFT)) {
+ ksym = group[1];
+ } else {
+ ksym = group[0];
+ }
+
+ /* Process compose sequence and dead accents */
+ res = KS_voidSymbol;
+
+ switch (KS_GROUP(ksym)) {
+ case KS_GROUP_Ascii:
+ case KS_GROUP_Keypad:
+ case KS_GROUP_Function:
+ res = ksym;
+ break;
+
+ case KS_GROUP_Mod:
+ if (ksym == KS_Multi_key) {
+ update_modifier(sc, 1, 0, MOD_COMPOSE);
+ sc->sc_composelen = 2;
+ }
+ break;
+
+ case KS_GROUP_Dead:
+ if (sc->sc_composelen == 0) {
+ update_modifier(sc, 1, 0, MOD_COMPOSE);
+ sc->sc_composelen = 1;
+ sc->sc_composebuf[0] = ksym;
+ } else
+ res = ksym;
+ break;
+ }
+
+ if (res == KS_voidSymbol) {
+ update_leds(sc);
+ return(NULL);
+ }
+
+ if (sc->sc_composelen > 0) {
+ sc->sc_composebuf[2 - sc->sc_composelen] = res;
+ if (--sc->sc_composelen == 0) {
+ res = wskbd_compose_value(sc->sc_composebuf);
+ update_modifier(sc, 0, 0, MOD_COMPOSE);
+ } else {
+ return(NULL);
+ }
+ }
+
+ update_leds(sc);
+
+ /* We are done, return the string */
+ if (KS_GROUP(res) == KS_GROUP_Ascii) {
+ if (MOD_ONESET(sc, MOD_ANYCONTROL)) {
+ if ((res >= KS_at && res <= KS_z) || res == KS_space)
+ res = res & 0x1f;
+ else if (res == KS_2)
+ res = 0x00;
+ else if (res >= KS_3 && res <= KS_7)
+ res = KS_Escape + (res - KS_3);
+ else if (res == KS_8)
+ res = KS_Delete;
+ }
+ if (MOD_ONESET(sc, MOD_ANYMETA))
+ res |= 0x80;
+ }
+
+ if (KS_GROUP(res) == KS_GROUP_Ascii ||
+ (KS_GROUP(res) == KS_GROUP_Keypad && (res & 0x80) == 0)) {
+ result[0] = res & 0xff;
+ result[1] = '\0';
+ return(result);
+ } else {
+ return(wskbd_get_string(res));
+ }
+}
diff --git a/sys/dev/wscons/wskbdmap_mfii.h b/sys/dev/wscons/wskbdmap_mfii.h
new file mode 100644
index 00000000000..13b3c1221d0
--- /dev/null
+++ b/sys/dev/wscons/wskbdmap_mfii.h
@@ -0,0 +1,195 @@
+/* $NetBSD: wskbdmap_mfii.h,v 1.1 1998/04/07 13:43:17 hannken Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Juergen Hannken-Illjes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define KC(n) (0xe000 | (n)) /* see wsksymvar.h */
+
+static const keysym_t wscons_keydesc_us[] = {
+/* pos command normal shifted */
+ KC(1), KS_Cmd_Debugger, KS_Escape,
+ KC(2), KS_1, KS_exclam,
+ KC(3), KS_2, KS_at,
+ KC(4), KS_3, KS_numbersign,
+ KC(5), KS_4, KS_dollar,
+ KC(6), KS_5, KS_percent,
+ KC(7), KS_6, KS_asciicircum,
+ KC(8), KS_7, KS_ampersand,
+ KC(9), KS_8, KS_asterisk,
+ KC(10), KS_9, KS_parenleft,
+ KC(11), KS_0, KS_parenright,
+ KC(12), KS_minus, KS_underscore,
+ KC(13), KS_equal, KS_plus,
+ KC(14), KS_BackSpace,
+ KC(15), KS_Tab,
+ KC(16), KS_q,
+ KC(17), KS_w,
+ KC(18), KS_e,
+ KC(19), KS_r,
+ KC(20), KS_t,
+ KC(21), KS_y,
+ KC(22), KS_u,
+ KC(23), KS_i,
+ KC(24), KS_o,
+ KC(25), KS_p,
+ KC(26), KS_bracketleft, KS_braceleft,
+ KC(27), KS_bracketright, KS_braceright,
+ KC(28), KS_Return,
+ KC(29), KS_Cmd1, KS_Control_L,
+ KC(30), KS_a,
+ KC(31), KS_s,
+ KC(32), KS_d,
+ KC(33), KS_f,
+ KC(34), KS_g,
+ KC(35), KS_h,
+ KC(36), KS_j,
+ KC(37), KS_k,
+ KC(38), KS_l,
+ KC(39), KS_semicolon, KS_colon,
+ KC(40), KS_apostrophe, KS_quotedbl,
+ KC(41), KS_grave, KS_asciitilde,
+ KC(42), KS_Shift_L,
+ KC(43), KS_backslash, KS_bar,
+ KC(44), KS_z,
+ KC(45), KS_x,
+ KC(46), KS_c,
+ KC(47), KS_v,
+ KC(48), KS_b,
+ KC(49), KS_n,
+ KC(50), KS_m,
+ KC(51), KS_comma, KS_less,
+ KC(52), KS_period, KS_greater,
+ KC(53), KS_slash, KS_question,
+ KC(54), KS_Shift_R,
+ KC(55), KS_KP_Multiply,
+ KC(56), KS_Cmd2, KS_Alt_L,
+ KC(57), KS_space,
+ KC(58), KS_Caps_Lock,
+ KC(59), KS_Cmd_Screen0, KS_f1,
+ KC(60), KS_Cmd_Screen1, KS_f2,
+ KC(61), KS_Cmd_Screen2, KS_f3,
+ KC(62), KS_Cmd_Screen3, KS_f4,
+ KC(63), KS_Cmd_Screen4, KS_f5,
+ KC(64), KS_Cmd_Screen5, KS_f6,
+ KC(65), KS_Cmd_Screen6, KS_f7,
+ KC(66), KS_Cmd_Screen7, KS_f8,
+ KC(67), KS_Cmd_Screen8, KS_f9,
+ KC(68), KS_Cmd_Screen9, KS_f10,
+ KC(69), KS_Num_Lock,
+ KC(70), KS_Hold_Screen,
+ KC(71), KS_KP_Home, KS_KP_7,
+ KC(72), KS_KP_Up, KS_KP_8,
+ KC(73), KS_KP_Prior, KS_KP_9,
+ KC(74), KS_KP_Subtract,
+ KC(75), KS_KP_Left, KS_KP_4,
+ KC(76), KS_KP_Begin, KS_KP_5,
+ KC(77), KS_KP_Right, KS_KP_6,
+ KC(78), KS_KP_Add,
+ KC(79), KS_KP_End, KS_KP_1,
+ KC(80), KS_KP_Down, KS_KP_2,
+ KC(81), KS_KP_Next, KS_KP_3,
+ KC(82), KS_KP_Insert, KS_KP_0,
+ KC(83), KS_KP_Delete, KS_KP_Decimal,
+ KC(87), KS_f11,
+ KC(88), KS_f12,
+ /* 127, break, */
+ KC(156), KS_KP_Enter,
+ KC(157), KS_Control_R,
+ /* 170, print screen, */
+ KC(181), KS_KP_Divide,
+ /* 183, print screen, */
+ KC(184), KS_Alt_R, KS_Multi_key,
+ KC(199), KS_Home,
+ KC(200), KS_Up,
+ KC(201), KS_Prior,
+ KC(203), KS_Left,
+ KC(205), KS_Right,
+ KC(207), KS_End,
+ KC(208), KS_Down,
+ KC(209), KS_Next,
+ KC(210), KS_Insert,
+ KC(211), KS_Delete,
+ /* 219, left win, */
+ /* 220, right win, */
+ /* 221, menu, */
+};
+
+static const keysym_t wscons_keydesc_de[] = {
+/* pos normal shifted altgr shift-altgr */
+ KC(3), KS_2, KS_quotedbl, KS_twosuperior,
+ KC(4), KS_3, KS_section, KS_threesuperior,
+ KC(7), KS_6, KS_ampersand,
+ KC(8), KS_7, KS_slash, KS_braceleft,
+ KC(9), KS_8, KS_parenleft, KS_bracketleft,
+ KC(10), KS_9, KS_parenright, KS_bracketright,
+ KC(11), KS_0, KS_equal, KS_braceright,
+ KC(12), KS_ssharp, KS_question, KS_backslash,
+ KC(13), KS_dead_acute, KS_dead_grave,
+ KC(16), KS_q, KS_Q, KS_at,
+ KC(21), KS_z,
+ KC(26), KS_udiaeresis,
+ KC(27), KS_plus, KS_asterisk, KS_dead_tilde,
+ KC(39), KS_odiaeresis,
+ KC(40), KS_adiaeresis,
+ KC(41), KS_dead_circumflex,KS_dead_abovering,
+ KC(43), KS_numbersign, KS_apostrophe,
+ KC(44), KS_y,
+ KC(50), KS_m, KS_M, KS_mu,
+ KC(51), KS_comma, KS_semicolon,
+ KC(52), KS_period, KS_colon,
+ KC(53), KS_minus, KS_underscore,
+ KC(86), KS_less, KS_greater, KS_bar, KS_brokenbar,
+ KC(184), KS_Mode_switch, KS_Multi_key,
+};
+
+static const keysym_t wscons_keydesc_de_nodead[] = {
+/* pos normal shifted altgr shift-altgr */
+ KC(13), KS_apostrophe, KS_grave,
+ KC(27), KS_plus, KS_asterisk, KS_asciitilde,
+ KC(41), KS_asciicircum, KS_degree,
+};
+
+#define KBD_MAP(name, base, map) \
+ { name, base, sizeof(map)/sizeof(keysym_t), map }
+
+static const struct wscons_keydesc wscons_keydesctab[] = {
+ KBD_MAP(KB_US, 0, wscons_keydesc_us),
+ KBD_MAP(KB_DE, KB_US, wscons_keydesc_de),
+ KBD_MAP(KB_DE | KB_NODEAD, KB_DE, wscons_keydesc_de_nodead),
+};
+
+#undef KBD_MAP
+#undef KC
diff --git a/sys/dev/wscons/wskbdutil.c b/sys/dev/wscons/wskbdutil.c
new file mode 100644
index 00000000000..6e6b4e52463
--- /dev/null
+++ b/sys/dev/wscons/wskbdutil.c
@@ -0,0 +1,550 @@
+/* $NetBSD: wskbdutil.c,v 1.1 1998/04/07 13:43:17 hannken Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Juergen Hannken-Illjes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/errno.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <dev/wscons/wsksymdef.h>
+#include <dev/wscons/wsksymvar.h>
+
+static struct compose_tab_s {
+ keysym_t elem[2];
+ keysym_t result;
+} compose_tab[] = {
+ { { KS_plus, KS_plus }, KS_numbersign },
+ { { KS_a, KS_a }, KS_at },
+ { { KS_parenleft, KS_parenleft }, KS_bracketleft },
+ { { KS_slash, KS_slash }, KS_backslash },
+ { { KS_parenright, KS_parenright }, KS_bracketright },
+ { { KS_parenleft, KS_minus }, KS_braceleft },
+ { { KS_slash, KS_minus }, KS_bar },
+ { { KS_parenright, KS_minus }, KS_braceright },
+ { { KS_exclam, KS_exclam }, KS_exclamdown },
+ { { KS_c, KS_slash }, KS_cent },
+ { { KS_l, KS_minus }, KS_sterling },
+ { { KS_y, KS_minus }, KS_yen },
+ { { KS_s, KS_o }, KS_section },
+ { { KS_x, KS_o }, KS_currency },
+ { { KS_c, KS_o }, KS_copyright },
+ { { KS_less, KS_less }, KS_guillemotleft },
+ { { KS_greater, KS_greater }, KS_guillemotright },
+ { { KS_question, KS_question }, KS_questiondown },
+ { { KS_dead_acute, KS_space }, KS_acute },
+ { { KS_dead_grave, KS_space }, KS_grave },
+ { { KS_dead_tilde, KS_space }, KS_asciitilde },
+ { { KS_dead_circumflex, KS_space }, KS_asciicircum },
+ { { KS_dead_circumflex, KS_A }, KS_Acircumflex },
+ { { KS_dead_diaeresis, KS_A }, KS_Adiaeresis },
+ { { KS_dead_grave, KS_A }, KS_Agrave },
+ { { KS_dead_abovering, KS_A }, KS_Aring },
+ { { KS_dead_tilde, KS_A }, KS_Atilde },
+ { { KS_dead_cedilla, KS_C }, KS_Ccedilla },
+ { { KS_dead_acute, KS_E }, KS_Eacute },
+ { { KS_dead_circumflex, KS_E }, KS_Ecircumflex },
+ { { KS_dead_diaeresis, KS_E }, KS_Ediaeresis },
+ { { KS_dead_grave, KS_E }, KS_Egrave },
+ { { KS_dead_acute, KS_I }, KS_Iacute },
+ { { KS_dead_circumflex, KS_I }, KS_Icircumflex },
+ { { KS_dead_diaeresis, KS_I }, KS_Idiaeresis },
+ { { KS_dead_grave, KS_I }, KS_Igrave },
+ { { KS_dead_tilde, KS_N }, KS_Ntilde },
+ { { KS_dead_acute, KS_O }, KS_Oacute },
+ { { KS_dead_circumflex, KS_O }, KS_Ocircumflex },
+ { { KS_dead_diaeresis, KS_O }, KS_Odiaeresis },
+ { { KS_dead_grave, KS_O }, KS_Ograve },
+ { { KS_dead_tilde, KS_O }, KS_Otilde },
+ { { KS_dead_acute, KS_U }, KS_Uacute },
+ { { KS_dead_circumflex, KS_U }, KS_Ucircumflex },
+ { { KS_dead_diaeresis, KS_U }, KS_Udiaeresis },
+ { { KS_dead_grave, KS_U }, KS_Ugrave },
+ { { KS_dead_acute, KS_Y }, KS_Yacute },
+ { { KS_dead_acute, KS_a }, KS_aacute },
+ { { KS_dead_circumflex, KS_a }, KS_acircumflex },
+ { { KS_dead_diaeresis, KS_a }, KS_adiaeresis },
+ { { KS_dead_grave, KS_a }, KS_agrave },
+ { { KS_dead_abovering, KS_a }, KS_aring },
+ { { KS_dead_tilde, KS_a }, KS_atilde },
+ { { KS_dead_cedilla, KS_c }, KS_ccedilla },
+ { { KS_dead_acute, KS_e }, KS_eacute },
+ { { KS_dead_circumflex, KS_e }, KS_ecircumflex },
+ { { KS_dead_diaeresis, KS_e }, KS_ediaeresis },
+ { { KS_dead_grave, KS_e }, KS_egrave },
+ { { KS_dead_acute, KS_i }, KS_iacute },
+ { { KS_dead_circumflex, KS_i }, KS_icircumflex },
+ { { KS_dead_diaeresis, KS_i }, KS_idiaeresis },
+ { { KS_dead_grave, KS_i }, KS_igrave },
+ { { KS_dead_tilde, KS_n }, KS_ntilde },
+ { { KS_dead_acute, KS_o }, KS_oacute },
+ { { KS_dead_circumflex, KS_o }, KS_ocircumflex },
+ { { KS_dead_diaeresis, KS_o }, KS_odiaeresis },
+ { { KS_dead_grave, KS_o }, KS_ograve },
+ { { KS_dead_tilde, KS_o }, KS_otilde },
+ { { KS_dead_acute, KS_u }, KS_uacute },
+ { { KS_dead_circumflex, KS_u }, KS_ucircumflex },
+ { { KS_dead_diaeresis, KS_u }, KS_udiaeresis },
+ { { KS_dead_grave, KS_u }, KS_ugrave },
+ { { KS_dead_acute, KS_y }, KS_yacute },
+ { { KS_dead_diaeresis, KS_y }, KS_ydiaeresis },
+ { { KS_quotedbl, KS_A }, KS_Adiaeresis },
+ { { KS_quotedbl, KS_E }, KS_Ediaeresis },
+ { { KS_quotedbl, KS_I }, KS_Idiaeresis },
+ { { KS_quotedbl, KS_O }, KS_Odiaeresis },
+ { { KS_quotedbl, KS_U }, KS_Udiaeresis },
+ { { KS_quotedbl, KS_a }, KS_adiaeresis },
+ { { KS_quotedbl, KS_e }, KS_ediaeresis },
+ { { KS_quotedbl, KS_i }, KS_idiaeresis },
+ { { KS_quotedbl, KS_o }, KS_odiaeresis },
+ { { KS_quotedbl, KS_u }, KS_udiaeresis },
+ { { KS_quotedbl, KS_y }, KS_ydiaeresis },
+ { { KS_acute, KS_A }, KS_Aacute },
+ { { KS_asciicircum, KS_A }, KS_Acircumflex },
+ { { KS_grave, KS_A }, KS_Agrave },
+ { { KS_asterisk, KS_A }, KS_Aring },
+ { { KS_asciitilde, KS_A }, KS_Atilde },
+ { { KS_cedilla, KS_C }, KS_Ccedilla },
+ { { KS_acute, KS_E }, KS_Eacute },
+ { { KS_asciicircum, KS_E }, KS_Ecircumflex },
+ { { KS_grave, KS_E }, KS_Egrave },
+ { { KS_acute, KS_I }, KS_Iacute },
+ { { KS_asciicircum, KS_I }, KS_Icircumflex },
+ { { KS_grave, KS_I }, KS_Igrave },
+ { { KS_asciitilde, KS_N }, KS_Ntilde },
+ { { KS_acute, KS_O }, KS_Oacute },
+ { { KS_asciicircum, KS_O }, KS_Ocircumflex },
+ { { KS_grave, KS_O }, KS_Ograve },
+ { { KS_asciitilde, KS_O }, KS_Otilde },
+ { { KS_acute, KS_U }, KS_Uacute },
+ { { KS_asciicircum, KS_U }, KS_Ucircumflex },
+ { { KS_grave, KS_U }, KS_Ugrave },
+ { { KS_acute, KS_Y }, KS_Yacute },
+ { { KS_acute, KS_a }, KS_aacute },
+ { { KS_asciicircum, KS_a }, KS_acircumflex },
+ { { KS_grave, KS_a }, KS_agrave },
+ { { KS_asterisk, KS_a }, KS_aring },
+ { { KS_asciitilde, KS_a }, KS_atilde },
+ { { KS_cedilla, KS_c }, KS_ccedilla },
+ { { KS_acute, KS_e }, KS_eacute },
+ { { KS_asciicircum, KS_e }, KS_ecircumflex },
+ { { KS_grave, KS_e }, KS_egrave },
+ { { KS_acute, KS_i }, KS_iacute },
+ { { KS_asciicircum, KS_i }, KS_icircumflex },
+ { { KS_grave, KS_i }, KS_igrave },
+ { { KS_asciitilde, KS_n }, KS_ntilde },
+ { { KS_acute, KS_o }, KS_oacute },
+ { { KS_asciicircum, KS_o }, KS_ocircumflex },
+ { { KS_grave, KS_o }, KS_ograve },
+ { { KS_asciitilde, KS_o }, KS_otilde },
+ { { KS_acute, KS_u }, KS_uacute },
+ { { KS_asciicircum, KS_u }, KS_ucircumflex },
+ { { KS_grave, KS_u }, KS_ugrave },
+ { { KS_acute, KS_y }, KS_yacute }
+};
+
+#define COMPOSE_SIZE sizeof(compose_tab)/sizeof(compose_tab[0])
+
+static struct string_tab_s {
+ keysym_t ksym;
+ char value[WSKBD_STRING_LEN];
+} string_tab[] = {
+ { KS_f1, "\033[OP" },
+ { KS_f2, "\033[OQ" },
+ { KS_f3, "\033[OR" },
+ { KS_f4, "\033[OS" },
+ { KS_f5, "\033[15~" },
+ { KS_f6, "\033[17~" },
+ { KS_f7, "\033[18~" },
+ { KS_f8, "\033[19~" },
+ { KS_f9, "\033[20~" },
+ { KS_f10, "\033[21~" },
+ { KS_f11, "\033[23~" },
+ { KS_f12, "\033[24~" },
+ { KS_f13, "\033[25~" },
+ { KS_f14, "\033[26~" },
+ { KS_f15, "\033[28~" },
+ { KS_f16, "\033[29~" },
+ { KS_f17, "\033[31~" },
+ { KS_f18, "\033[32~" },
+ { KS_f19, "\033[33~" },
+ { KS_f20, "\033[34~" },
+ { KS_F1, "\033[OP" },
+ { KS_F2, "\033[OQ" },
+ { KS_F3, "\033[OR" },
+ { KS_F4, "\033[OS" },
+ { KS_F5, "\033[15~" },
+ { KS_F6, "\033[17~" },
+ { KS_F7, "\033[18~" },
+ { KS_F8, "\033[19~" },
+ { KS_F9, "\033[20~" },
+ { KS_F10, "\033[21~" },
+ { KS_F11, "\033[23~" },
+ { KS_F12, "\033[24~" },
+ { KS_F13, "\033[25~" },
+ { KS_F14, "\033[26~" },
+ { KS_F15, "\033[28~" },
+ { KS_F16, "\033[29~" },
+ { KS_F17, "\033[31~" },
+ { KS_F18, "\033[32~" },
+ { KS_F19, "\033[33~" },
+ { KS_F20, "\033[34~" },
+ { KS_KP_F1, "\033[OP" },
+ { KS_KP_F2, "\033[OQ" },
+ { KS_KP_F3, "\033[OR" },
+ { KS_KP_F4, "\033[OS" },
+ { KS_KP_Home, "\033[H" },
+ { KS_Home, "\033[H" },
+ { KS_KP_Left, "\033[D" },
+ { KS_Left, "\033[D" },
+ { KS_KP_Up, "\033[A" },
+ { KS_Up, "\033[A" },
+ { KS_KP_Right, "\033[C" },
+ { KS_Right, "\033[C" },
+ { KS_KP_Down, "\033[B" },
+ { KS_Down, "\033[B" },
+ { KS_KP_Prior, "\033[I" },
+ { KS_Prior, "\033[I" },
+ { KS_KP_Next, "\033[G" },
+ { KS_Next, "\033[G" },
+ { KS_KP_End, "\033[F" },
+ { KS_End, "\033[F" },
+ { KS_KP_Begin, "\033[H" },
+ { KS_KP_Insert, "\033[L" },
+ { KS_Insert, "\033[L" },
+ { KS_KP_Delete, "\b" }
+};
+
+#define STRING_SIZE sizeof(string_tab)/sizeof(string_tab[0])
+
+static int compose_tab_inorder = 0;
+static int string_tab_inorder = 0;
+
+static inline int compose_tab_cmp __P((struct compose_tab_s *, struct compose_tab_s *));
+static keysym_t ksym_upcase __P((keysym_t));
+
+static inline int
+compose_tab_cmp(i, j)
+ struct compose_tab_s *i, *j;
+{
+ if (i->elem[0] == j->elem[0])
+ return(i->elem[1] - j->elem[1]);
+ else
+ return(i->elem[0] - j->elem[0]);
+}
+
+keysym_t
+wskbd_compose_value(compose_buf)
+ keysym_t *compose_buf;
+{
+ int i, j, r;
+ struct compose_tab_s v;
+
+ if (! compose_tab_inorder) {
+ /* Insertion sort. */
+ for (i = 1; i < COMPOSE_SIZE; i++) {
+ v = compose_tab[i];
+ /* find correct slot, moving others up */
+ for (j = i; --j >= 0 && compose_tab_cmp(& v, & compose_tab[j]) < 0; )
+ compose_tab[j + 1] = compose_tab[j];
+ compose_tab[j + 1] = v;
+ }
+ compose_tab_inorder = 1;
+ }
+
+ for (j = 0, i = COMPOSE_SIZE; i != 0; i /= 2) {
+ if (compose_tab[j + i/2].elem[0] == compose_buf[0]) {
+ if (compose_tab[j + i/2].elem[1] == compose_buf[1])
+ return(compose_tab[j + i/2].result);
+ r = compose_tab[j + i/2].elem[1] < compose_buf[1];
+ } else
+ r = compose_tab[j + i/2].elem[0] < compose_buf[0];
+ if (r) {
+ j += i/2 + 1;
+ i--;
+ }
+ }
+
+ return(KS_voidSymbol);
+}
+
+char *
+wskbd_get_string(sym)
+ keysym_t sym;
+{
+ int i, j;
+ struct string_tab_s v;
+
+ if (! string_tab_inorder) {
+ /* Insertion sort. */
+ for (i = 1; i < STRING_SIZE; i++) {
+ v = string_tab[i];
+ /* find correct slot, moving others up */
+ for (j = i; --j >= 0 && v.ksym < string_tab[j].ksym; )
+ string_tab[j + 1] = string_tab[j];
+ string_tab[j + 1] = v;
+ }
+ string_tab_inorder = 1;
+ }
+
+ for (j = 0, i = STRING_SIZE; i != 0; i /= 2) {
+ if (string_tab[j + i/2].ksym == sym)
+ return(string_tab[j + i/2].value);
+ else if (string_tab[j + i/2].ksym < sym) {
+ j += i/2 + 1;
+ i--;
+ }
+ }
+
+ return(NULL);
+}
+
+int
+wskbd_set_string(sym, data)
+ keysym_t sym;
+ char *data;
+{
+ int i, j;
+ struct string_tab_s v;
+
+ if (! string_tab_inorder) {
+ /* Insertion sort. */
+ for (i = 1; i < STRING_SIZE; i++) {
+ v = string_tab[i];
+ /* find correct slot, moving others up */
+ for (j = i; --j >= 0 && v.ksym < string_tab[j].ksym; )
+ string_tab[j + 1] = string_tab[j];
+ string_tab[j + 1] = v;
+ }
+ string_tab_inorder = 1;
+ }
+
+ for (j = 0, i = STRING_SIZE; i != 0; i /= 2) {
+ if (string_tab[j + i/2].ksym == sym) {
+ bcopy(data, string_tab[j + i/2].value, WSKBD_STRING_LEN);
+ return(0);
+ } else if (string_tab[j + i/2].ksym < sym) {
+ j += i/2 + 1;
+ i--;
+ }
+ }
+
+ return(EINVAL);
+}
+
+static const u_char latin1_to_upper[256] = {
+/* 0 8 1 9 2 a 3 b 4 c 5 d 6 e 7 f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */
+ 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 6 */
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 6 */
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 7 */
+ 'X', 'Y', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d */
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* e */
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* e */
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, /* f */
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00, /* f */
+};
+
+static keysym_t
+ksym_upcase(ksym)
+ keysym_t ksym;
+{
+ if (ksym >= KS_f1 && ksym <= KS_f20)
+ return(KS_F1 - KS_f1 + ksym);
+
+ if (KS_GROUP(ksym) == KS_GROUP_Ascii &&
+ latin1_to_upper[ksym & 0xff] != 0x00)
+ return(latin1_to_upper[ksym & 0xff] | KS_GROUP_Ascii);
+
+ return(ksym);
+}
+
+void
+wskbd_init_keymap(newlen, map, maplen)
+ int newlen;
+ struct wscons_keymap **map;
+ int *maplen;
+{
+ int i;
+
+ if (newlen != *maplen) {
+ if (*maplen > 0)
+ free(*map, M_TEMP);
+ *maplen = newlen;
+ *map = malloc(newlen*sizeof(struct wscons_keymap),
+ M_TEMP, M_WAITOK);
+ }
+
+ for (i = 0; i < *maplen; i++) {
+ (*map)[i].command = KS_voidSymbol;
+ (*map)[i].group1[0] = KS_voidSymbol;
+ (*map)[i].group1[1] = KS_voidSymbol;
+ (*map)[i].group2[0] = KS_voidSymbol;
+ (*map)[i].group2[1] = KS_voidSymbol;
+ }
+}
+
+int
+wskbd_load_keymap(name, kdesc, kdesclen, map, maplen)
+ kbd_t name;
+ const struct wscons_keydesc *kdesc;
+ int kdesclen;
+ struct wscons_keymap **map;
+ int *maplen;
+{
+ int i, s, kc, found, stack[10], stack_ptr;
+ const keysym_t *kp;
+ const struct wscons_keydesc *mp;
+ kbd_t cur;
+
+ for (cur = name, stack_ptr = 0; cur != 0; stack_ptr++) {
+ for (i = found = 0; i < kdesclen; i++)
+ if (cur == 0 || kdesc[i].name == cur) {
+ found = 1;
+ break;
+ }
+
+ if (stack_ptr == sizeof(stack)/sizeof(stack[0]))
+ panic("wskbd_load_keymap: %d: recursion too deep", name);
+ if (! found)
+ return(EINVAL);
+
+ stack[stack_ptr] = i;
+ cur = kdesc[i].base;
+ }
+
+ for (i = 0, s = stack_ptr - 1; s >= 0; s--) {
+ mp = kdesc + stack[s];
+ for (kp = mp->map; kp < mp->map + mp->map_size; kp++)
+ if (KS_GROUP(*kp) == KS_GROUP_Keycode && KS_VALUE(*kp) > i)
+ i = KS_VALUE(*kp);
+ }
+
+ wskbd_init_keymap(i + 1, map, maplen);
+
+ for (s = stack_ptr - 1; s >= 0; s--) {
+ mp = kdesc + stack[s];
+ for (kp = mp->map; kp < mp->map + mp->map_size; ) {
+ if (KS_GROUP(*kp) != KS_GROUP_Keycode)
+ panic("wskbd_load_keymap: %d(%d): bad entry",
+ mp->name, *kp);
+
+ kc = KS_VALUE(*kp);
+ kp++;
+
+ if (KS_GROUP(*kp) == KS_GROUP_Command ||
+ *kp == KS_Cmd || *kp == KS_Cmd1 || *kp == KS_Cmd2) {
+ (*map)[kc].command = *kp;
+ kp++;
+ }
+
+ for (i = 0; kp + i < mp->map + mp->map_size; i++)
+ if (KS_GROUP(kp[i]) == KS_GROUP_Keycode)
+ break;
+
+ if (i > 4)
+ panic("wskbd_load_keymap: %d(%d): bad entry",
+ mp->name, *kp);
+
+ switch (i) {
+ case 0:
+ (*map)[kc].group1[0] = KS_voidSymbol;
+ (*map)[kc].group1[1] = KS_voidSymbol;
+ (*map)[kc].group2[0] = KS_voidSymbol;
+ (*map)[kc].group2[1] = KS_voidSymbol;
+ break;
+
+ case 1:
+ (*map)[kc].group1[0] = kp[0];
+ (*map)[kc].group1[1] = ksym_upcase(kp[0]);
+ (*map)[kc].group2[0] = (*map)[kc].group1[0];
+ (*map)[kc].group2[1] = (*map)[kc].group1[1];
+ break;
+
+ case 2:
+ (*map)[kc].group1[0] = kp[0];
+ (*map)[kc].group1[1] = kp[1];
+ (*map)[kc].group2[0] = (*map)[kc].group1[0];
+ (*map)[kc].group2[1] = (*map)[kc].group1[1];
+ break;
+
+ case 3:
+ (*map)[kc].group1[0] = kp[0];
+ (*map)[kc].group1[1] = kp[1];
+ (*map)[kc].group2[0] = kp[2];
+ (*map)[kc].group2[1] = ksym_upcase(kp[2]);
+ break;
+
+ case 4:
+ (*map)[kc].group1[0] = kp[0];
+ (*map)[kc].group1[1] = kp[1];
+ (*map)[kc].group2[0] = kp[2];
+ (*map)[kc].group2[1] = kp[3];
+ break;
+
+ }
+
+ kp += i;
+ }
+ }
+
+ return(0);
+}
diff --git a/sys/dev/wscons/wskbdvar.h b/sys/dev/wscons/wskbdvar.h
index 5983d5a3d9c..0d1dfa5dbec 100644
--- a/sys/dev/wscons/wskbdvar.h
+++ b/sys/dev/wscons/wskbdvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: wskbdvar.h,v 1.1 1998/03/22 14:24:03 drochner Exp $ */
+/* $NetBSD: wskbdvar.h,v 1.2 1998/04/07 13:43:17 hannken Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -41,9 +41,9 @@
* with these functions, which is passed to them when they are invoked.
*/
struct wskbd_accessops {
+ void (*asyn_set_leds) __P((void *, int));
int (*ioctl) __P((void *v, u_long cmd, caddr_t data, int flag,
struct proc *p));
- const char *(*translate) __P((void *v, u_int type, int value));
};
/*
@@ -53,7 +53,7 @@ struct wskbd_accessops {
* with these functions, which is passed to them when they are invoked.
*/
struct wskbd_consops {
- int (*getc) __P((void *));
+ void (*getc) __P((void *, u_int *, int *));
void (*pollc) __P((void *, int));
};
@@ -63,6 +63,9 @@ struct wskbd_consops {
*/
struct wskbddev_attach_args {
int console; /* is it console? */
+ int layout; /* initial layout */
+ int num_keydescs; /* number of maps */
+ const struct wscons_keydesc *keydesc; /* array of maps */
const struct wskbd_accessops *accessops; /* access ops */
void *accesscookie; /* access cookie */
};
@@ -80,9 +83,7 @@ int wskbddevprint __P((void *, const char *));
/*
* Callbacks from the keyboard driver to the wskbd interface driver.
*/
-void wskbd_holdscreen __P((struct device *kbddev, int hold));
void wskbd_input __P((struct device *kbddev, u_int type, int value));
-void wskbd_ctlinput __P((struct device *kbddev, int));
/*
* Console interface.
diff --git a/sys/dev/wscons/wsksymdef.h b/sys/dev/wscons/wsksymdef.h
new file mode 100644
index 00000000000..6b48dc6e8d9
--- /dev/null
+++ b/sys/dev/wscons/wsksymdef.h
@@ -0,0 +1,407 @@
+#ifndef _DEV_WSCONS_WSKSYMDEF_H_
+#define _DEV_WSCONS_WSKSYMDEF_H_
+
+/*
+ * Keysymbols encoded as 16-bit Unicode. Special symbols
+ * are encoded in the private area (0xe000 - 0xf8ff).
+ * The area 0xe000 - 0xefff is used in wskbdmap.c and may
+ * never be assigned to any keysym.
+ * Currently only ISO Latin-1 subset is supported.
+ */
+
+/*
+ * Group Ascii (ISO Latin1) character in low byte
+ */
+
+#define KS_BackSpace 0x08
+#define KS_Tab 0x09
+#define KS_Linefeed 0x0a
+#define KS_Clear 0x0b
+#define KS_Return 0x0d
+#define KS_Escape 0x1b
+#define KS_space 0x20
+#define KS_exclam 0x21
+#define KS_quotedbl 0x22
+#define KS_numbersign 0x23
+#define KS_dollar 0x24
+#define KS_percent 0x25
+#define KS_ampersand 0x26
+#define KS_apostrophe 0x27
+#define KS_parenleft 0x28
+#define KS_parenright 0x29
+#define KS_asterisk 0x2a
+#define KS_plus 0x2b
+#define KS_comma 0x2c
+#define KS_minus 0x2d
+#define KS_period 0x2e
+#define KS_slash 0x2f
+#define KS_0 0x30
+#define KS_1 0x31
+#define KS_2 0x32
+#define KS_3 0x33
+#define KS_4 0x34
+#define KS_5 0x35
+#define KS_6 0x36
+#define KS_7 0x37
+#define KS_8 0x38
+#define KS_9 0x39
+#define KS_colon 0x3a
+#define KS_semicolon 0x3b
+#define KS_less 0x3c
+#define KS_equal 0x3d
+#define KS_greater 0x3e
+#define KS_question 0x3f
+#define KS_at 0x40
+#define KS_A 0x41
+#define KS_B 0x42
+#define KS_C 0x43
+#define KS_D 0x44
+#define KS_E 0x45
+#define KS_F 0x46
+#define KS_G 0x47
+#define KS_H 0x48
+#define KS_I 0x49
+#define KS_J 0x4a
+#define KS_K 0x4b
+#define KS_L 0x4c
+#define KS_M 0x4d
+#define KS_N 0x4e
+#define KS_O 0x4f
+#define KS_P 0x50
+#define KS_Q 0x51
+#define KS_R 0x52
+#define KS_S 0x53
+#define KS_T 0x54
+#define KS_U 0x55
+#define KS_V 0x56
+#define KS_W 0x57
+#define KS_X 0x58
+#define KS_Y 0x59
+#define KS_Z 0x5a
+#define KS_bracketleft 0x5b
+#define KS_backslash 0x5c
+#define KS_bracketright 0x5d
+#define KS_asciicircum 0x5e
+#define KS_underscore 0x5f
+#define KS_grave 0x60
+#define KS_a 0x61
+#define KS_b 0x62
+#define KS_c 0x63
+#define KS_d 0x64
+#define KS_e 0x65
+#define KS_f 0x66
+#define KS_g 0x67
+#define KS_h 0x68
+#define KS_i 0x69
+#define KS_j 0x6a
+#define KS_k 0x6b
+#define KS_l 0x6c
+#define KS_m 0x6d
+#define KS_n 0x6e
+#define KS_o 0x6f
+#define KS_p 0x70
+#define KS_q 0x71
+#define KS_r 0x72
+#define KS_s 0x73
+#define KS_t 0x74
+#define KS_u 0x75
+#define KS_v 0x76
+#define KS_w 0x77
+#define KS_x 0x78
+#define KS_y 0x79
+#define KS_z 0x7a
+#define KS_braceleft 0x7b
+#define KS_bar 0x7c
+#define KS_braceright 0x7d
+#define KS_asciitilde 0x7e
+#define KS_Delete 0x7f
+
+#define KS_nobreakspace 0xa0
+#define KS_exclamdown 0xa1
+#define KS_cent 0xa2
+#define KS_sterling 0xa3
+#define KS_currency 0xa4
+#define KS_yen 0xa5
+#define KS_brokenbar 0xa6
+#define KS_section 0xa7
+#define KS_diaeresis 0xa8
+#define KS_copyright 0xa9
+#define KS_ordfeminine 0xaa
+#define KS_guillemotleft 0xab
+#define KS_notsign 0xac
+#define KS_hyphen 0xad
+#define KS_registered 0xae
+#define KS_macron 0xaf
+#define KS_degree 0xb0
+#define KS_plusminus 0xb1
+#define KS_twosuperior 0xb2
+#define KS_threesuperior 0xb3
+#define KS_acute 0xb4
+#define KS_mu 0xb5
+#define KS_paragraph 0xb6
+#define KS_periodcentered 0xb7
+#define KS_cedilla 0xb8
+#define KS_onesuperior 0xb9
+#define KS_masculine 0xba
+#define KS_guillemotright 0xbb
+#define KS_onequarter 0xbc
+#define KS_onehalf 0xbd
+#define KS_threequarters 0xbe
+#define KS_questiondown 0xbf
+#define KS_Agrave 0xc0
+#define KS_Aacute 0xc1
+#define KS_Acircumflex 0xc2
+#define KS_Atilde 0xc3
+#define KS_Adiaeresis 0xc4
+#define KS_Aring 0xc5
+#define KS_AE 0xc6
+#define KS_Ccedilla 0xc7
+#define KS_Egrave 0xc8
+#define KS_Eacute 0xc9
+#define KS_Ecircumflex 0xca
+#define KS_Ediaeresis 0xcb
+#define KS_Igrave 0xcc
+#define KS_Iacute 0xcd
+#define KS_Icircumflex 0xce
+#define KS_Idiaeresis 0xcf
+#define KS_ETH 0xd0
+#define KS_Ntilde 0xd1
+#define KS_Ograve 0xd2
+#define KS_Oacute 0xd3
+#define KS_Ocircumflex 0xd4
+#define KS_Otilde 0xd5
+#define KS_Odiaeresis 0xd6
+#define KS_multiply 0xd7
+#define KS_Ooblique 0xd8
+#define KS_Ugrave 0xd9
+#define KS_Uacute 0xda
+#define KS_Ucircumflex 0xdb
+#define KS_Udiaeresis 0xdc
+#define KS_Yacute 0xdd
+#define KS_THORN 0xde
+#define KS_ssharp 0xdf
+#define KS_agrave 0xe0
+#define KS_aacute 0xe1
+#define KS_acircumflex 0xe2
+#define KS_atilde 0xe3
+#define KS_adiaeresis 0xe4
+#define KS_aring 0xe5
+#define KS_ae 0xe6
+#define KS_ccedilla 0xe7
+#define KS_egrave 0xe8
+#define KS_eacute 0xe9
+#define KS_ecircumflex 0xea
+#define KS_ediaeresis 0xeb
+#define KS_igrave 0xec
+#define KS_iacute 0xed
+#define KS_icircumflex 0xee
+#define KS_idiaeresis 0xef
+#define KS_eth 0xf0
+#define KS_ntilde 0xf1
+#define KS_ograve 0xf2
+#define KS_oacute 0xf3
+#define KS_ocircumflex 0xf4
+#define KS_otilde 0xf5
+#define KS_odiaeresis 0xf6
+#define KS_division 0xf7
+#define KS_oslash 0xf8
+#define KS_ugrave 0xf9
+#define KS_uacute 0xfa
+#define KS_ucircumflex 0xfb
+#define KS_udiaeresis 0xfc
+#define KS_yacute 0xfd
+#define KS_thorn 0xfe
+#define KS_ydiaeresis 0xff
+
+/*
+ * Group Dead (dead accents)
+ */
+
+#define KS_dead_grave 0x0300
+#define KS_dead_acute 0x0301
+#define KS_dead_circumflex 0x0302
+#define KS_dead_tilde 0x0303
+#define KS_dead_diaeresis 0x0308
+#define KS_dead_abovering 0x030a
+#define KS_dead_cedilla 0x0327
+
+/*
+ * Group 1 (modifiers)
+ */
+
+#define KS_Shift_L 0xf101
+#define KS_Shift_R 0xf102
+#define KS_Control_L 0xf103
+#define KS_Control_R 0xf104
+#define KS_Caps_Lock 0xf105
+#define KS_Shift_Lock 0xf106
+#define KS_Alt_L 0xf107
+#define KS_Alt_R 0xf108
+#define KS_Multi_key 0xf109
+#define KS_Mode_switch 0xf10a
+#define KS_Num_Lock 0xf10b
+#define KS_Hold_Screen 0xf10c
+#define KS_Cmd 0xf10d
+#define KS_Cmd1 0xf10e
+#define KS_Cmd2 0xf10f
+
+/*
+ * Group 2 (keypad) character in low byte
+ */
+
+#define KS_KP_F1 0xf291
+#define KS_KP_F2 0xf292
+#define KS_KP_F3 0xf293
+#define KS_KP_F4 0xf294
+#define KS_KP_Home 0xf295
+#define KS_KP_Left 0xf296
+#define KS_KP_Up 0xf297
+#define KS_KP_Right 0xf298
+#define KS_KP_Down 0xf299
+#define KS_KP_Prior 0xf29a
+#define KS_KP_Next 0xf29b
+#define KS_KP_End 0xf29c
+#define KS_KP_Begin 0xf29d
+#define KS_KP_Insert 0xf29e
+#define KS_KP_Delete 0xf29f
+
+#define KS_KP_Space 0xf220
+#define KS_KP_Tab 0xf209
+#define KS_KP_Enter 0xf20d
+#define KS_KP_Equal 0xf23d
+#define KS_KP_Multiply 0xf22a
+#define KS_KP_Add 0xf22b
+#define KS_KP_Separator 0xf22c
+#define KS_KP_Subtract 0xf22d
+#define KS_KP_Decimal 0xf22e
+#define KS_KP_Divide 0xf22f
+#define KS_KP_0 0xf230
+#define KS_KP_1 0xf231
+#define KS_KP_2 0xf232
+#define KS_KP_3 0xf233
+#define KS_KP_4 0xf234
+#define KS_KP_5 0xf235
+#define KS_KP_6 0xf236
+#define KS_KP_7 0xf237
+#define KS_KP_8 0xf238
+#define KS_KP_9 0xf239
+
+/*
+ * Group 3 (function)
+ */
+
+#define KS_f1 0xf300
+#define KS_f2 0xf301
+#define KS_f3 0xf302
+#define KS_f4 0xf303
+#define KS_f5 0xf304
+#define KS_f6 0xf305
+#define KS_f7 0xf306
+#define KS_f8 0xf307
+#define KS_f9 0xf308
+#define KS_f10 0xf309
+#define KS_f11 0xf30a
+#define KS_f12 0xf30b
+#define KS_f13 0xf30c
+#define KS_f14 0xf30d
+#define KS_f15 0xf30e
+#define KS_f16 0xf30f
+#define KS_f17 0xf310
+#define KS_f18 0xf311
+#define KS_f19 0xf312
+#define KS_f20 0xf313
+
+#define KS_F1 0xf340
+#define KS_F2 0xf341
+#define KS_F3 0xf342
+#define KS_F4 0xf343
+#define KS_F5 0xf344
+#define KS_F6 0xf345
+#define KS_F7 0xf346
+#define KS_F8 0xf347
+#define KS_F9 0xf348
+#define KS_F10 0xf349
+#define KS_F11 0xf34a
+#define KS_F12 0xf34b
+#define KS_F13 0xf34c
+#define KS_F14 0xf34d
+#define KS_F15 0xf34e
+#define KS_F16 0xf34f
+#define KS_F17 0xf350
+#define KS_F18 0xf351
+#define KS_F19 0xf352
+#define KS_F20 0xf353
+
+#define KS_Home 0xf381
+#define KS_Prior 0xf382
+#define KS_Next 0xf383
+#define KS_Up 0xf384
+#define KS_Down 0xf385
+#define KS_Left 0xf386
+#define KS_Right 0xf387
+#define KS_End 0xf388
+#define KS_Insert 0xf389
+
+/*
+ * Group 4 (command)
+ */
+
+#define KS_Cmd_Screen0 0xf400
+#define KS_Cmd_Screen1 0xf401
+#define KS_Cmd_Screen2 0xf402
+#define KS_Cmd_Screen3 0xf403
+#define KS_Cmd_Screen4 0xf404
+#define KS_Cmd_Screen5 0xf405
+#define KS_Cmd_Screen6 0xf406
+#define KS_Cmd_Screen7 0xf407
+#define KS_Cmd_Screen8 0xf408
+#define KS_Cmd_Screen9 0xf409
+#define KS_Cmd_Debugger 0xf420
+
+/*
+ * Group 5 (internal)
+ */
+
+#define KS_voidSymbol 0xf500
+
+/*
+ * keysym groups
+ */
+
+#define KS_GROUP_Mod 0xf100
+#define KS_GROUP_Keypad 0xf200
+#define KS_GROUP_Function 0xf300
+#define KS_GROUP_Command 0xf400
+#define KS_GROUP_Internal 0xf500
+#define KS_GROUP_Dead 0xf800 /* not encoded in keysym */
+#define KS_GROUP_Ascii 0xf801 /* not encoded in keysym */
+#define KS_GROUP_Keycode 0xf802 /* not encoded in keysym */
+
+#define KS_GROUP(k) ((k) >= 0x0300 && (k) < 0x0370 ? KS_GROUP_Dead : \
+ (((k) & 0xf000) == 0xe000 ? KS_GROUP_Keycode : \
+ (((k) & 0xf800) == 0xf000 ? ((k) & 0xff00) : \
+ KS_GROUP_Ascii)))
+
+#define KS_VALUE(k) (((k) & 0xf000) == 0xe000 ? ((k) & 0x0fff) : \
+ (((k) & 0xf800) == 0xf000 ? ((k) & 0x00ff) : (k)))
+
+/*
+ * Keyboard types: 8bit encoding, 8bit variant
+ */
+
+#define KB_ENCODING(e) ((e) & 0xff00)
+#define KB_VARIANT(e) ((e) & 0x00ff)
+
+#define KB_USER 0x0100
+#define KB_US 0x0200
+#define KB_DE 0x0300
+
+#define KB_NODEAD 0x0001
+
+#define KB_NAMETAB \
+ { KB_USER, "user" }, \
+ { KB_US, "us" }, \
+ { KB_DE, "de" }, \
+ { KB_NODEAD, "nodead" }
+
+#endif /* !_DEV_WSCONS_WSKSYMDEF_H_ */
diff --git a/sys/dev/wscons/wsksymvar.h b/sys/dev/wscons/wsksymvar.h
new file mode 100644
index 00000000000..d624a53d24a
--- /dev/null
+++ b/sys/dev/wscons/wsksymvar.h
@@ -0,0 +1,39 @@
+#ifndef _DEV_WSCONS_WSKSYMVAR_H_
+#define _DEV_WSCONS_WSKSYMVAR_H_
+
+#define WSKBD_STRING_LEN 8 /* Function keys, 7 chars+NUL */
+
+#ifndef _KERNEL
+#include <sys/types.h>
+#endif
+
+typedef u_int16_t keysym_t;
+typedef u_int16_t kbd_t;
+
+struct wscons_keymap {
+ keysym_t command;
+ keysym_t group1[2];
+ keysym_t group2[2];
+};
+
+#ifdef _KERNEL
+struct wscons_keydesc {
+ kbd_t name; /* name of this map */
+ kbd_t base; /* map this one is based on */
+ int map_size; /* size of map */
+ const keysym_t *map; /* the map itself */
+};
+
+/*
+ * Utility functions.
+ */
+void wskbd_init_keymap __P((int, struct wscons_keymap **, int *));
+int wskbd_load_keymap __P((kbd_t, const struct wscons_keydesc *, int,
+ struct wscons_keymap **, int *));
+keysym_t wskbd_compose_value __P((keysym_t *));
+char * wskbd_get_string __P((keysym_t));
+int wskbd_set_string __P((keysym_t, char *));
+
+#endif
+
+#endif /* !_DEV_WSCONS_WSKSYMVAR_H_ */