Author: hselasky
Date: Mon Mar 30 15:29:39 2020
New Revision: 359439
URL: https://svnweb.freebsd.org/changeset/base/359439

Log:
  Evaluate modifier keys before the regular keys, so that if a modifier
  key is pressed at the same time as a regular key, that means key with
  modifier is output. Some automated USB keyboards like Yubikeys need this.
  
  This fixes a regression issue after r357861.
  
  Reported by:  Adam McDougall <mcdou...@egr.msu.edu>
  PR:           224592
  PR:           233884
  MFC after:    3 days
  Sponsored by: Mellanox Technologies

Modified:
  head/sys/dev/usb/input/ukbd.c

Modified: head/sys/dev/usb/input/ukbd.c
==============================================================================
--- head/sys/dev/usb/input/ukbd.c       Mon Mar 30 14:24:03 2020        
(r359438)
+++ head/sys/dev/usb/input/ukbd.c       Mon Mar 30 15:29:39 2020        
(r359439)
@@ -499,6 +499,21 @@ ukbd_interrupt(struct ukbd_softc *sc)
 
        UKBD_LOCK_ASSERT();
 
+       /* Check for modifier key changes first */
+       for (key = 0xe0; key != 0xe8; key++) {
+               const uint64_t mask = 1ULL << (key % 64);
+               const uint64_t delta =
+                   sc->sc_odata.bitmap[key / 64] ^
+                   sc->sc_ndata.bitmap[key / 64];
+
+               if (delta & mask) {
+                       if (sc->sc_odata.bitmap[key / 64] & mask)
+                               ukbd_put_key(sc, key | KEY_RELEASE);
+                       else
+                               ukbd_put_key(sc, key | KEY_PRESS);
+               }
+       }
+
        /* Check for key changes */
        for (key = 0; key != UKBD_NKEYCODE; key++) {
                const uint64_t mask = 1ULL << (key % 64);
@@ -509,6 +524,8 @@ ukbd_interrupt(struct ukbd_softc *sc)
                if (mask == 1 && delta == 0) {
                        key += 63;
                        continue;       /* skip empty areas */
+               } else if (ukbd_is_modifier_key(key)) {
+                       continue;
                } else if (delta & mask) {
                        if (sc->sc_odata.bitmap[key / 64] & mask) {
                                ukbd_put_key(sc, key | KEY_RELEASE);
@@ -518,9 +535,6 @@ ukbd_interrupt(struct ukbd_softc *sc)
                                        sc->sc_repeat_key = 0;
                        } else {
                                ukbd_put_key(sc, key | KEY_PRESS);
-
-                               if (ukbd_is_modifier_key(key))
-                                       continue;
 
                                sc->sc_co_basetime = sbinuptime();
                                sc->sc_delay = sc->sc_kbd.kb_delay1;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to