> Hi, > > last weekend, I noticed that after a > > $ wsconsctl keyboard.map+="keysym Caps_Lock = Control_L" > > on my PowerBook G4 the capslock key did *not* any longer behave > like a control key. Instead it just has *no* effect at all, which > isn't very surprising when looking at akbd_capslockwrapper() in > akbd.c. > > Isn't there any reliable way to detect *what* kind of keyboard is > in use and then decide wether the hack in akbd_capslockwrapper() > is necessary or not?
No. But what about this diff? Miod Index: akbd.c =================================================================== RCS file: /cvs/src/sys/dev/adb/akbd.c,v retrieving revision 1.4 diff -u -p -r1.4 akbd.c --- akbd.c 2006/02/12 21:49:08 1.4 +++ akbd.c 2006/03/11 13:23:07 @@ -128,6 +128,7 @@ akbdattach(struct device *parent, struct sc->handler_id = aa_args->handler_id; sc->sc_leds = (u_int8_t)0x00; /* initially off */ + sc->sc_caps = 0; adbinfo.siServiceRtPtr = (Ptr)akbd_adbcomplete; adbinfo.siDataAreaAddr = (caddr_t)sc; @@ -453,6 +454,30 @@ akbd_rawrepeat(void *v) #endif /* + * The ``caps lock'' key is special: since on earlier keyboards, the physical + * key stays down when pressed, we will get a notification of the key press, + * but not of the key release. Then, when it is pressed again, we will not get + * a notification of the key press, but will see the key release. + * + * This is not exactly true. We see the missing release and press events both + * as the release of the power (reset) key. + * + * To avoid confusing them with real power key presses, we maintain two + * states for the caps lock key: logically down (from wscons' point of view), + * and ``physically'' down (from the adb messages point of view), to ignore + * the power key. But since one may press the power key while the caps lock + * is held down, we also have to remember the state of the power key... this + * is quite messy. + */ + +/* + * Values for caps lock state machine + */ +#define CL_DOWN_ADB 0x01 +#define CL_DOWN_LOGICAL 0x02 +#define CL_DOWN_RESET 0x04 + +/* * Given a keyboard ADB event, decode the keycodes and pass them to wskbd. */ void @@ -468,10 +493,24 @@ akbd_processevent(struct akbd_softc *sc, * 0xffff on release, and we ignore it. */ if (event->bytes[0] == event->bytes[1] && - ADBK_KEYVAL(event->bytes[0]) == ADBK_RESET) - break; - akbd_capslockwrapper(sc, event->bytes[0]); - akbd_capslockwrapper(sc, event->bytes[1]); + ADBK_KEYVAL(event->bytes[0]) == ADBK_RESET) { + if (event->bytes[0] == ADBK_KEYDOWN(ADBK_RESET)) + SET(sc->sc_caps, CL_DOWN_RESET); + else { + if (ISSET(sc->sc_caps, CL_DOWN_RESET)) + CLR(sc->sc_caps, CL_DOWN_RESET); + else if (ISSET(sc->sc_caps, CL_DOWN_ADB)) { + akbd_input(sc, ISSET(sc->sc_caps, + CL_DOWN_LOGICAL) ? + ADBK_KEYDOWN(ADBK_CAPSLOCK) : + ADBK_KEYUP(ADBK_CAPSLOCK)); + sc->sc_caps ^= CL_DOWN_LOGICAL; + } + } + } else { + akbd_capslockwrapper(sc, event->bytes[0]); + akbd_capslockwrapper(sc, event->bytes[1]); + } break; default: #ifdef DIAGNOSTIC @@ -486,22 +525,11 @@ akbd_processevent(struct akbd_softc *sc, void akbd_capslockwrapper(struct akbd_softc *sc, int key) { - /* - * Caps lock is special: since on earlier keyboards, the physical - * key stays down when pressed, we will get a notification of the - * key press, but not of the key release. Then, when it is pressed - * again, we will not get a notification of the key press, but will - * see the key release. - * For proper wskbd operation, we should report each capslock - * notification as both events (press and release). - */ - if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK) { - akbd_input(sc, ADBK_KEYDOWN(ADBK_CAPSLOCK)); - akbd_input(sc, ADBK_KEYUP(ADBK_CAPSLOCK)); - } else { - if (key != 0xff) - akbd_input(sc, key); - } + if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK) + sc->sc_caps ^= CL_DOWN_ADB; + + if (key != 0xff) + akbd_input(sc, key); } int adb_polledkey; Index: akbdvar.h =================================================================== RCS file: /cvs/src/sys/dev/adb/akbdvar.h,v retrieving revision 1.1 diff -u -p -r1.1 akbdvar.h --- akbdvar.h 2006/01/18 23:21:17 1.1 +++ akbdvar.h 2006/03/11 13:23:07 @@ -46,7 +46,10 @@ struct akbd_softc { int handler_id; /* type of keyboard */ u_int8_t sc_leds; /* current LED state */ + + int sc_caps; /* capslock key state */ struct device *sc_wskbddev; + #ifdef WSDISPLAY_COMPAT_RAWKBD #define MAXKEYS 20 #define REP_DELAY1 400