summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/man/man4/man4.hp300/dnkbd.49
-rw-r--r--sys/arch/hp300/dev/dnkbd.c55
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);