diff options
-rw-r--r-- | share/man/man4/man4.hp300/dnkbd.4 | 9 | ||||
-rw-r--r-- | sys/arch/hp300/dev/dnkbd.c | 55 |
2 files changed, 49 insertions, 15 deletions
diff --git a/share/man/man4/man4.hp300/dnkbd.4 b/share/man/man4/man4.hp300/dnkbd.4 index 772138236fa..fe68796f5a6 100644 --- a/share/man/man4/man4.hp300/dnkbd.4 +++ b/share/man/man4/man4.hp300/dnkbd.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: dnkbd.4,v 1.4 2005/05/06 22:22:51 miod Exp $ +.\" $OpenBSD: dnkbd.4,v 1.5 2006/04/15 23:56:46 miod Exp $ .\" .\" Copyright (c) 2005, Miodrag Vallat .\" @@ -23,7 +23,7 @@ .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd May 6, 2005 +.Dd April 15, 2006 .Dt DNKBD 4 hp300 .Os .Sh NAME @@ -138,3 +138,8 @@ key, and the to .Em F9 functionality to the corresponding keys. +.Pp +Due to hardware pecularities, it is not possible to remap the +.Sq Caps Lock +key as a modifier key, such as +.Sq Control . 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); |