summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryokota <yokota@FreeBSD.org>2001-07-20 13:05:57 +0000
committeryokota <yokota@FreeBSD.org>2001-07-20 13:05:57 +0000
commit5bdd55fe335c85187c6f689240776d3578198a03 (patch)
tree4326f68a54d447c94f4a84c2fb697802d2377223
parent4b023c5a9f160b15b1ae45ac500512e1209b8c02 (diff)
downloadFreeBSD-src-5bdd55fe335c85187c6f689240776d3578198a03.zip
FreeBSD-src-5bdd55fe335c85187c6f689240776d3578198a03.tar.gz
Return consistent key action codes at key press and release
events. Otherwise you would see unexpected results if shift or locking keys are defined to give different actions depending on other shift/locking keys' state. Please keep the ukbd module and the kernel in sync, otherwise the USB keyboard won't work after this change. MFC after: 10 days
-rw-r--r--sys/dev/atkbdc/atkbd.c2
-rw-r--r--sys/dev/atkbdc/atkbd_atkbdc.c1
-rw-r--r--sys/dev/atkbdc/atkbd_isa.c1
-rw-r--r--sys/dev/kbd/atkbd.c2
-rw-r--r--sys/dev/kbd/kbd.c193
-rw-r--r--sys/dev/kbd/kbdreg.h1
-rw-r--r--sys/dev/usb/ukbd.c2
-rw-r--r--sys/isa/atkbd_isa.c1
8 files changed, 108 insertions, 95 deletions
diff --git a/sys/dev/atkbdc/atkbd.c b/sys/dev/atkbdc/atkbd.c
index 05a98f4..0e8be30 100644
--- a/sys/dev/atkbdc/atkbd.c
+++ b/sys/dev/atkbdc/atkbd.c
@@ -49,6 +49,7 @@
#include <vm/pmap.h>
#endif /* __i386__ */
+#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
#include <dev/kbd/atkbdreg.h>
#include <dev/kbd/atkbdcreg.h>
@@ -167,7 +168,6 @@ atkbd_timeout(void *arg)
/* LOW-LEVEL */
#include <machine/limits.h>
-#include <sys/kbio.h>
#define ATKBD_DEFAULT 0
diff --git a/sys/dev/atkbdc/atkbd_atkbdc.c b/sys/dev/atkbdc/atkbd_atkbdc.c
index 1941612..130b986 100644
--- a/sys/dev/atkbdc/atkbd_atkbdc.c
+++ b/sys/dev/atkbdc/atkbd_atkbdc.c
@@ -37,6 +37,7 @@
#include <machine/resource.h>
#include <sys/rman.h>
+#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
#include <dev/kbd/atkbdreg.h>
#include <dev/kbd/atkbdcreg.h>
diff --git a/sys/dev/atkbdc/atkbd_isa.c b/sys/dev/atkbdc/atkbd_isa.c
index 1941612..130b986 100644
--- a/sys/dev/atkbdc/atkbd_isa.c
+++ b/sys/dev/atkbdc/atkbd_isa.c
@@ -37,6 +37,7 @@
#include <machine/resource.h>
#include <sys/rman.h>
+#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
#include <dev/kbd/atkbdreg.h>
#include <dev/kbd/atkbdcreg.h>
diff --git a/sys/dev/kbd/atkbd.c b/sys/dev/kbd/atkbd.c
index 05a98f4..0e8be30 100644
--- a/sys/dev/kbd/atkbd.c
+++ b/sys/dev/kbd/atkbd.c
@@ -49,6 +49,7 @@
#include <vm/pmap.h>
#endif /* __i386__ */
+#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
#include <dev/kbd/atkbdreg.h>
#include <dev/kbd/atkbdcreg.h>
@@ -167,7 +168,6 @@ atkbd_timeout(void *arg)
/* LOW-LEVEL */
#include <machine/limits.h>
-#include <sys/kbio.h>
#define ATKBD_DEFAULT 0
diff --git a/sys/dev/kbd/kbd.c b/sys/dev/kbd/kbd.c
index ce55b65..e53015b 100644
--- a/sys/dev/kbd/kbd.c
+++ b/sys/dev/kbd/kbd.c
@@ -139,6 +139,7 @@ kbd_init_struct(keyboard_t *kbd, char *name, int type, int unit, int config,
kbd->kb_delay1 = KB_DELAY1; /* these values are advisory only */
kbd->kb_delay2 = KB_DELAY2;
kbd->kb_count = 0L;
+ bzero(kbd->kb_lastact, sizeof(kbd->kb_lastact));
}
void
@@ -1018,107 +1019,111 @@ genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate,
|| ((key->flgs & FLAG_LOCK_N) && (state & NLKED)) )
i ^= 1;
- action = key->map[i];
if (up) { /* break: key released */
- if (key->spcl & (0x80 >> i)) {
- /* special keys */
- switch (action) {
- case LSHA:
- if (state & SHIFTAON) {
- set_lockkey_state(kbd, state, ALK);
- state &= ~ALKDOWN;
- }
- action = LSH;
- /* FALL THROUGH */
- case LSH:
- state &= ~SHIFTS1;
- break;
- case RSHA:
- if (state & SHIFTAON) {
- set_lockkey_state(kbd, state, ALK);
- state &= ~ALKDOWN;
- }
- action = RSH;
- /* FALL THROUGH */
- case RSH:
- state &= ~SHIFTS2;
- break;
- case LCTRA:
- if (state & SHIFTAON) {
- set_lockkey_state(kbd, state, ALK);
- state &= ~ALKDOWN;
- }
- action = LCTR;
- /* FALL THROUGH */
- case LCTR:
- state &= ~CTLS1;
- break;
- case RCTRA:
- if (state & SHIFTAON) {
- set_lockkey_state(kbd, state, ALK);
- state &= ~ALKDOWN;
- }
- action = RCTR;
- /* FALL THROUGH */
- case RCTR:
- state &= ~CTLS2;
- break;
- case LALTA:
- if (state & SHIFTAON) {
- set_lockkey_state(kbd, state, ALK);
- state &= ~ALKDOWN;
- }
- action = LALT;
- /* FALL THROUGH */
- case LALT:
- state &= ~ALTS1;
- break;
- case RALTA:
- if (state & SHIFTAON) {
- set_lockkey_state(kbd, state, ALK);
- state &= ~ALKDOWN;
- }
- action = RALT;
- /* FALL THROUGH */
- case RALT:
- state &= ~ALTS2;
- break;
- case ASH:
- state &= ~AGRS1;
- break;
- case META:
- state &= ~METAS1;
- break;
- case NLK:
- state &= ~NLKDOWN;
- break;
- case CLK:
+ action = kbd->kb_lastact[keycode];
+ kbd->kb_lastact[keycode] = NOP;
+ switch (action) {
+ case LSHA:
+ if (state & SHIFTAON) {
+ set_lockkey_state(kbd, state, ALK);
+ state &= ~ALKDOWN;
+ }
+ action = LSH;
+ /* FALL THROUGH */
+ case LSH:
+ state &= ~SHIFTS1;
+ break;
+ case RSHA:
+ if (state & SHIFTAON) {
+ set_lockkey_state(kbd, state, ALK);
+ state &= ~ALKDOWN;
+ }
+ action = RSH;
+ /* FALL THROUGH */
+ case RSH:
+ state &= ~SHIFTS2;
+ break;
+ case LCTRA:
+ if (state & SHIFTAON) {
+ set_lockkey_state(kbd, state, ALK);
+ state &= ~ALKDOWN;
+ }
+ action = LCTR;
+ /* FALL THROUGH */
+ case LCTR:
+ state &= ~CTLS1;
+ break;
+ case RCTRA:
+ if (state & SHIFTAON) {
+ set_lockkey_state(kbd, state, ALK);
+ state &= ~ALKDOWN;
+ }
+ action = RCTR;
+ /* FALL THROUGH */
+ case RCTR:
+ state &= ~CTLS2;
+ break;
+ case LALTA:
+ if (state & SHIFTAON) {
+ set_lockkey_state(kbd, state, ALK);
+ state &= ~ALKDOWN;
+ }
+ action = LALT;
+ /* FALL THROUGH */
+ case LALT:
+ state &= ~ALTS1;
+ break;
+ case RALTA:
+ if (state & SHIFTAON) {
+ set_lockkey_state(kbd, state, ALK);
+ state &= ~ALKDOWN;
+ }
+ action = RALT;
+ /* FALL THROUGH */
+ case RALT:
+ state &= ~ALTS2;
+ break;
+ case ASH:
+ state &= ~AGRS1;
+ break;
+ case META:
+ state &= ~METAS1;
+ break;
+ case NLK:
+ state &= ~NLKDOWN;
+ break;
+ case CLK:
#ifndef PC98
- state &= ~CLKDOWN;
+ state &= ~CLKDOWN;
#else
- state &= ~CLKED;
- i = state & LOCK_MASK;
- (*kbdsw[kbd->kb_index]->ioctl)(kbd, KDSETLED,
- (caddr_t)&i);
+ state &= ~CLKED;
+ i = state & LOCK_MASK;
+ (*kbdsw[kbd->kb_index]->ioctl)(kbd, KDSETLED,
+ (caddr_t)&i);
#endif
- break;
- case SLK:
- state &= ~SLKDOWN;
- break;
- case ALK:
- state &= ~ALKDOWN;
- break;
- }
- *shiftstate = state & ~SHIFTAON;
- return (SPCLKEY | RELKEY | action);
+ break;
+ case SLK:
+ state &= ~SLKDOWN;
+ break;
+ case ALK:
+ state &= ~ALKDOWN;
+ break;
+ case NOP:
+ /* release events of regular keys are not reported */
+ *shiftstate &= ~SHIFTAON;
+ return NOKEY;
}
- /* release events of regular keys are not reported */
- *shiftstate &= ~SHIFTAON;
- return NOKEY;
+ *shiftstate = state & ~SHIFTAON;
+ return (SPCLKEY | RELKEY | action);
} else { /* make: key pressed */
+ action = key->map[i];
state &= ~SHIFTAON;
if (key->spcl & (0x80 >> i)) {
/* special keys */
+ if (kbd->kb_lastact[keycode] == NOP)
+ kbd->kb_lastact[keycode] = action;
+ if (kbd->kb_lastact[keycode] != action)
+ action = NOP;
switch (action) {
/* LOCKING KEYS */
case NLK:
@@ -1198,6 +1203,9 @@ genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate,
case META:
state |= METAS1;
break;
+ case NOP:
+ *shiftstate = state;
+ return NOKEY;
default:
/* is this an accent (dead) key? */
*shiftstate = state;
@@ -1230,6 +1238,7 @@ genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate,
return (SPCLKEY | action);
} else {
/* regular keys */
+ kbd->kb_lastact[keycode] = NOP;
*shiftstate = state;
if (*accents > 0) {
/* make an accented char */
diff --git a/sys/dev/kbd/kbdreg.h b/sys/dev/kbd/kbdreg.h
index 55e0cef..3745dc1 100644
--- a/sys/dev/kbd/kbdreg.h
+++ b/sys/dev/kbd/kbdreg.h
@@ -89,6 +89,7 @@ struct keyboard {
#define KB_DELAY1 500
#define KB_DELAY2 100
unsigned long kb_count; /* # of processed key strokes */
+ u_char kb_lastact[NUM_KEYS/2];
};
#define KBD_IS_VALID(k) ((k)->kb_flags & KB_VALID)
diff --git a/sys/dev/usb/ukbd.c b/sys/dev/usb/ukbd.c
index b127b8a..4e531bf 100644
--- a/sys/dev/usb/ukbd.c
+++ b/sys/dev/usb/ukbd.c
@@ -66,6 +66,7 @@
#include <dev/usb/usb_quirks.h>
#include <dev/usb/hid.h>
+#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
#define UKBD_EMULATE_ATSCANCODE 1
@@ -231,7 +232,6 @@ ukbd_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0);
#include <machine/limits.h>
-#include <sys/kbio.h>
#define UKBD_DEFAULT 0
diff --git a/sys/isa/atkbd_isa.c b/sys/isa/atkbd_isa.c
index 1941612..130b986 100644
--- a/sys/isa/atkbd_isa.c
+++ b/sys/isa/atkbd_isa.c
@@ -37,6 +37,7 @@
#include <machine/resource.h>
#include <sys/rman.h>
+#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
#include <dev/kbd/atkbdreg.h>
#include <dev/kbd/atkbdcreg.h>
OpenPOWER on IntegriCloud