aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/hid/hkbd.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/sys/dev/hid/hkbd.c b/sys/dev/hid/hkbd.c
index 65e8b9446e9d..bfd8e12df746 100644
--- a/sys/dev/hid/hkbd.c
+++ b/sys/dev/hid/hkbd.c
@@ -143,8 +143,12 @@ struct hkbd_softc {
struct mtx sc_mtx;
struct task sc_task;
struct callout sc_callout;
+ /* All reported keycodes */
bitstr_t bit_decl(sc_ndata, HKBD_NKEYCODE);
bitstr_t bit_decl(sc_odata, HKBD_NKEYCODE);
+ /* Keycodes reported in array fields only */
+ bitstr_t bit_decl(sc_ndata0, HKBD_NKEYCODE);
+ bitstr_t bit_decl(sc_odata0, HKBD_NKEYCODE);
struct thread *sc_poll_thread;
#ifdef EVDEV_SUPPORT
@@ -520,6 +524,7 @@ hkbd_interrupt(struct hkbd_softc *sc)
}
/* synchronize old data with new data */
+ memcpy(sc->sc_odata0, sc->sc_ndata0, bitstr_size(HKBD_NKEYCODE));
memcpy(sc->sc_odata, sc->sc_ndata, bitstr_size(HKBD_NKEYCODE));
/* check if last key is still pressed */
@@ -654,7 +659,14 @@ hkbd_intr_callback(void *context, void *data, hid_size_t len)
}
/* clear temporary storage */
- memset(&sc->sc_ndata, 0, bitstr_size(HKBD_NKEYCODE));
+ if (bit_test(sc->sc_loc_key_valid, 0) && id == sc->sc_id_loc_key[0]) {
+ bit_foreach(sc->sc_ndata0, HKBD_NKEYCODE, i)
+ bit_clear(sc->sc_ndata, i);
+ memset(&sc->sc_ndata0, 0, bitstr_size(HKBD_NKEYCODE));
+ }
+ bit_foreach(sc->sc_ndata, HKBD_NKEYCODE, i)
+ if (id == sc->sc_id_loc_key[i])
+ bit_clear(sc->sc_ndata, i);
/* clear modifiers */
modifiers = 0;
@@ -686,6 +698,8 @@ hkbd_intr_callback(void *context, void *data, hid_size_t len)
tmp_loc.pos += tmp_loc.size;
if (key == KEY_ERROR) {
DPRINTF("KEY_ERROR\n");
+ memcpy(sc->sc_ndata0, sc->sc_odata0,
+ bitstr_size(HKBD_NKEYCODE));
memcpy(sc->sc_ndata, sc->sc_odata,
bitstr_size(HKBD_NKEYCODE));
return; /* ignore */
@@ -698,6 +712,7 @@ hkbd_intr_callback(void *context, void *data, hid_size_t len)
continue;
/* set key in bitmap */
bit_set(sc->sc_ndata, key);
+ bit_set(sc->sc_ndata0, key);
}
} else if (hid_get_data(buf, len, &sc->sc_loc_key[i])) {
uint32_t key = i;
@@ -1684,6 +1699,8 @@ hkbd_clear_state(keyboard_t *kbd)
#endif
memset(&sc->sc_ndata, 0, bitstr_size(HKBD_NKEYCODE));
memset(&sc->sc_odata, 0, bitstr_size(HKBD_NKEYCODE));
+ memset(&sc->sc_ndata0, 0, bitstr_size(HKBD_NKEYCODE));
+ memset(&sc->sc_odata0, 0, bitstr_size(HKBD_NKEYCODE));
sc->sc_repeat_time = 0;
sc->sc_repeat_key = 0;
}