solve polled adb keyboard problems with dropped keys and unsynced caps lock
by queueing polled keys.
This commit is contained in:
parent
31ae0ac1e9
commit
5f15cedc89
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: akbd.c,v 1.20 2002/02/23 10:51:50 dbj Exp $ */
|
||||
/* $NetBSD: akbd.c,v 1.21 2002/02/24 20:20:20 dbj Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998 Colin Wood
|
||||
|
@ -64,6 +64,7 @@ static int akbdmatch __P((struct device *, struct cfdata *, void *));
|
|||
static void akbdattach __P((struct device *, struct device *, void *));
|
||||
void kbd_adbcomplete __P((caddr_t buffer, caddr_t data_area, int adb_command));
|
||||
static void kbd_processevent __P((adb_event_t *event, struct akbd_softc *));
|
||||
static void kbd_passup __P((struct akbd_softc *sc, int));
|
||||
#ifdef notyet
|
||||
static u_char getleds __P((int));
|
||||
static int setleds __P((struct akbd_softc *, u_char));
|
||||
|
@ -243,7 +244,7 @@ akbdattach(parent, self, aux)
|
|||
#endif
|
||||
|
||||
if (akbd_is_console) {
|
||||
wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata);
|
||||
wskbd_cnattach(&akbd_consops, sc, &akbd_keymapdata);
|
||||
}
|
||||
|
||||
a.console = akbd_is_console;
|
||||
|
@ -465,31 +466,53 @@ akbd_ioctl(v, cmd, data, flag, p)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int polledkey;
|
||||
extern int adb_polling;
|
||||
|
||||
void
|
||||
kbd_passup(sc,key)
|
||||
struct akbd_softc *sc;
|
||||
int key;
|
||||
{
|
||||
if (sc->sc_polling) {
|
||||
if (sc->sc_npolledkeys <
|
||||
(sizeof(sc->sc_polledkeys)/sizeof(unsigned char))) {
|
||||
sc->sc_polledkeys[sc->sc_npolledkeys++] = key;
|
||||
}
|
||||
#ifdef ADB_DEBUG
|
||||
else {
|
||||
printf("akbd: dumping polled key 0x%02x\n",key);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
int press, val;
|
||||
int type;
|
||||
|
||||
press = ADBK_PRESS(key);
|
||||
val = ADBK_KEYVAL(key);
|
||||
|
||||
type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
|
||||
|
||||
wskbd_input(sc->sc_wskbddev, type, val);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
kbd_intr(arg)
|
||||
void *arg;
|
||||
{
|
||||
adb_event_t *event = arg;
|
||||
int key, press, val;
|
||||
int type;
|
||||
int key;
|
||||
|
||||
struct akbd_softc *sc = akbd_cd.cd_devs[0];
|
||||
|
||||
key = event->u.k.key;
|
||||
press = ADBK_PRESS(key);
|
||||
val = ADBK_KEYVAL(key);
|
||||
|
||||
type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
|
||||
|
||||
switch (key) {
|
||||
case 57: /* Caps Lock pressed */
|
||||
case 185: /* Caps Lock released */
|
||||
type = WSCONS_EVENT_KEY_DOWN;
|
||||
wskbd_input(sc->sc_wskbddev, type, val);
|
||||
type = WSCONS_EVENT_KEY_UP;
|
||||
key = ADBK_KEYDOWN(ADBK_KEYVAL(key));
|
||||
kbd_passup(sc,key);
|
||||
key = ADBK_KEYUP(ADBK_KEYVAL(key));
|
||||
break;
|
||||
case 245:
|
||||
if (pcmcia_soft_eject)
|
||||
|
@ -501,10 +524,7 @@ kbd_intr(arg)
|
|||
break;
|
||||
}
|
||||
|
||||
if (adb_polling)
|
||||
polledkey = key;
|
||||
else
|
||||
wskbd_input(sc->sc_wskbddev, type, val);
|
||||
kbd_passup(sc,key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -525,20 +545,25 @@ akbd_cngetc(v, type, data)
|
|||
{
|
||||
int key, press, val;
|
||||
int s;
|
||||
struct akbd_softc *sc = v;
|
||||
|
||||
s = splhigh();
|
||||
|
||||
polledkey = -1;
|
||||
KASSERT(sc->sc_polling);
|
||||
KASSERT(adb_polling);
|
||||
|
||||
while (polledkey == -1) {
|
||||
while (sc->sc_npolledkeys == 0) {
|
||||
adb_intr();
|
||||
DELAY(10000); /* XXX */
|
||||
}
|
||||
|
||||
splx(s);
|
||||
|
||||
key = polledkey;
|
||||
key = sc->sc_polledkeys[0];
|
||||
sc->sc_npolledkeys--;
|
||||
memmove(sc->sc_polledkeys,sc->sc_polledkeys+1,
|
||||
sc->sc_npolledkeys * sizeof(unsigned char));
|
||||
|
||||
press = ADBK_PRESS(key);
|
||||
val = ADBK_KEYVAL(key);
|
||||
|
||||
|
@ -551,5 +576,14 @@ akbd_cnpollc(v, on)
|
|||
void *v;
|
||||
int on;
|
||||
{
|
||||
struct akbd_softc *sc = v;
|
||||
sc->sc_polling = on;
|
||||
if (!on) {
|
||||
int i;
|
||||
for(i=0;i<sc->sc_npolledkeys;i++) {
|
||||
kbd_passup(sc,sc->sc_polledkeys[i]);
|
||||
}
|
||||
sc->sc_npolledkeys = 0;
|
||||
}
|
||||
adb_polling = on;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: akbdvar.h,v 1.4 1999/02/17 14:56:56 tsubai Exp $ */
|
||||
/* $NetBSD: akbdvar.h,v 1.5 2002/02/24 20:20:20 dbj Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998 Colin Wood
|
||||
|
@ -48,6 +48,11 @@ struct akbd_softc {
|
|||
|
||||
u_int8_t sc_leds; /* current LED state */
|
||||
struct device *sc_wskbddev;
|
||||
|
||||
int sc_polling;
|
||||
int sc_npolledkeys;
|
||||
unsigned char sc_polledkeys[32];
|
||||
|
||||
};
|
||||
|
||||
/* LED register bits, inverse of actual register value */
|
||||
|
|
Loading…
Reference in New Issue