diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2006-04-15 23:56:49 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2006-04-15 23:56:49 +0000 |
commit | 559f51061543f80d8911154d0530475af20ff578 (patch) | |
tree | f18200e5391e5c6bfab09fe210ddc965f7d0646e /sys | |
parent | b0c58e2e690f6f44e3a0f832769a5845907eaa56 (diff) |
Caps Lock key is special, even in raw mode, on the Domain keyboard, exactly
like on ADB keyboards. Must have been the 80's keyboard fashion.
So when we see a Caps Lock event, produce the missing event as well for
acceptable behaviour.
This does not allow the Caps Lock key to be used for chording, though,
so document this in the manpage (honestly, Ctrl and Caps Lock being adjacent,
there is no point in swapping them on Domain keyboards, but you never know).
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/hp300/dev/dnkbd.c | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/sys/arch/hp300/dev/dnkbd.c b/sys/arch/hp300/dev/dnkbd.c index 6294ea7a44f..8e260715503 100644 --- a/sys/arch/hp300/dev/dnkbd.c +++ b/sys/arch/hp300/dev/dnkbd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dnkbd.c,v 1.10 2005/12/21 19:40:42 miod Exp $ */ +/* $OpenBSD: dnkbd.c,v 1.11 2006/04/15 23:56:48 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -67,6 +67,7 @@ * Keyboard key codes */ +#define DNKEY_CAPSLOCK 0x7e #define DNKEY_REPEAT 0x7f #define DNKEY_RELEASE 0x80 #define DNKEY_CHANNEL 0xff @@ -206,6 +207,7 @@ struct wskbd_mapdata dnkbd_keymapdata = { typedef enum { EVENT_NONE, EVENT_KEYBOARD, EVENT_MOUSE } dnevent; void dnevent_kbd(struct dnkbd_softc *, int); +void dnevent_kbd_internal(struct dnkbd_softc *, int); void dnevent_mouse(struct dnkbd_softc *, u_int8_t *); void dnkbd_attach_subdevices(struct dnkbd_softc *); void dnkbd_bellstop(void *); @@ -574,10 +576,6 @@ dnkbd_decode(int keycode, u_int *type, int *key) void dnevent_kbd(struct dnkbd_softc *sc, int dat) { - u_int type; - int key; - int s; - if (!ISSET(sc->sc_flags, SF_PLUGGED)) return; @@ -587,6 +585,29 @@ dnevent_kbd(struct dnkbd_softc *sc, int dat) if (!ISSET(sc->sc_flags, SF_ENABLED)) return; + /* + * Even in raw mode, the caps lock key is treated specially: + * first key press causes event 0x7e, release causes no event; + * then a new key press causes nothing, and release causes + * event 0xfe. Moreover, while kept down, it does not produce + * repeat events. + * + * So the best we can do is fake the missed events, but this + * will not allow the capslock key to be remapped as a control + * key since it will not be possible to chord it with anything. + */ + dnevent_kbd_internal(sc, dat); + if ((dat & ~DNKEY_RELEASE) == DNKEY_CAPSLOCK) + dnevent_kbd_internal(sc, dat ^ DNKEY_RELEASE); +} + +void +dnevent_kbd_internal(struct dnkbd_softc *sc, int dat) +{ + u_int type; + int key; + int s; + dnkbd_decode(dat, &type, &key); #ifdef WSDISPLAY_COMPAT_RAWKBD @@ -943,20 +964,28 @@ dnmouse_disable(void *v) void dnkbd_cngetc(void *v, u_int *type, int *data) { + static int lastdat = 0; struct dnkbd_softc *sc = v; int s; int dat; - for (;;) { - s = splhigh(); - dat = dnkbd_pollin(sc->sc_regs, 10000); - if (dat != -1) { - if (dnkbd_input(sc, dat) == EVENT_KEYBOARD) { - splx(s); - break; + /* Take care of caps lock */ + if ((lastdat & ~DNKEY_RELEASE) == DNKEY_CAPSLOCK) { + dat = lastdat ^ DNKEY_RELEASE; + lastdat = 0; + } else { + for (;;) { + s = splhigh(); + dat = dnkbd_pollin(sc->sc_regs, 10000); + if (dat != -1) { + if (dnkbd_input(sc, dat) == EVENT_KEYBOARD) { + splx(s); + break; + } } + splx(s); } - splx(s); + lastdat = dat; } dnkbd_decode(dat, type, data); |