Hi,
landry@ reported that he ended up with the wrong encoding in X11 while
having a ucc keyboard attached and /etc/kbdtype being present. The
advertised encoding of a wsmux is a bit fragile as the last attached
device will dictate it. If this happens to be a ucc keyboard, KB_US will
always be the advertised encoding as its encoding is immutable and
/etc/kbdtype is ignored.

Instead, do not advertise the encoding for ucc devices when the parent
mux queries its attached devices. However, asking the device directly
(i.e. bypassing the mux) still returns the encoding as wsconsctl(8)
would otherwise report an error.

Comments? OK?

Index: dev/wscons/wskbd.c
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wskbd.c,v
retrieving revision 1.108
diff -u -p -r1.108 wskbd.c
--- dev/wscons/wskbd.c  20 Sep 2021 17:32:39 -0000      1.108
+++ dev/wscons/wskbd.c  20 Oct 2021 05:31:56 -0000
@@ -205,6 +205,8 @@ int wskbd_detach(struct device *, int);
 int    wskbd_activate(struct device *, int);
 
 int    wskbd_displayioctl(struct device *, u_long, caddr_t, int, struct proc 
*);
+int    wskbd_displayioctl_sc(struct wskbd_softc *, u_long, caddr_t, int,
+    struct proc *, int);
 
 void   update_leds(struct wskbd_internal *);
 void   update_modifier(struct wskbd_internal *, u_int, int, int);
@@ -217,7 +219,7 @@ void        change_displayparam(struct wskbd_so
 #endif
 
 int    wskbd_do_ioctl_sc(struct wskbd_softc *, u_long, caddr_t, int,
-           struct proc *);
+    struct proc *, int);
 void   wskbd_deliver_event(struct wskbd_softc *sc, u_int type, int value);
 
 #if NWSMUX > 0
@@ -925,7 +927,14 @@ wskbdread(dev_t dev, struct uio *uio, in
 int
 wskbdioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
 {
-       return (wskbd_do_ioctl(wskbd_cd.cd_devs[minor(dev)], cmd, data, 
flag,p));
+       struct wskbd_softc *sc = wskbd_cd.cd_devs[minor(dev)];
+       int error;
+
+       sc->sc_refcnt++;
+       error = wskbd_do_ioctl_sc(sc, cmd, data, flag, p, 0);
+       if (--sc->sc_refcnt < 0)
+               wakeup(sc);
+       return (error);
 }
 
 /* A wrapper around the ioctl() workhorse to make reference counting easy. */
@@ -937,7 +946,7 @@ wskbd_do_ioctl(struct device *dv, u_long
        int error;
 
        sc->sc_refcnt++;
-       error = wskbd_do_ioctl_sc(sc, cmd, data, flag, p);
+       error = wskbd_do_ioctl_sc(sc, cmd, data, flag, p, 1);
        if (--sc->sc_refcnt < 0)
                wakeup(sc);
        return (error);
@@ -945,7 +954,7 @@ wskbd_do_ioctl(struct device *dv, u_long
 
 int
 wskbd_do_ioctl_sc(struct wskbd_softc *sc, u_long cmd, caddr_t data, int flag,
-     struct proc *p)
+    struct proc *p, int evsrc)
 {
        struct wseventvar *evar;
        int error;
@@ -983,7 +992,7 @@ wskbd_do_ioctl_sc(struct wskbd_softc *sc
         * Try the keyboard driver for WSKBDIO ioctls.  It returns -1
         * if it didn't recognize the request.
         */
-       error = wskbd_displayioctl(&sc->sc_base.me_dv, cmd, data, flag, p);
+       error = wskbd_displayioctl_sc(sc, cmd, data, flag, p, evsrc);
        return (error != -1 ? error : ENOTTY);
 }
 
@@ -992,10 +1001,18 @@ wskbd_do_ioctl_sc(struct wskbd_softc *sc
  * Some of these have no real effect in raw mode, however.
  */
 int
-wskbd_displayioctl(struct device *dev, u_long cmd, caddr_t data, int flag,
+wskbd_displayioctl(struct device *dv, u_long cmd, caddr_t data, int flag,
     struct proc *p)
 {
-       struct wskbd_softc *sc = (struct wskbd_softc *)dev;
+       struct wskbd_softc *sc = (struct wskbd_softc *)dv;
+
+       return (wskbd_displayioctl_sc(sc, cmd, data, flag, p, 1));
+}
+
+int
+wskbd_displayioctl_sc(struct wskbd_softc *sc, u_long cmd, caddr_t data,
+    int flag, struct proc *p, int evsrc)
+{
        struct wskbd_bell_data *ubdp, *kbdp;
        struct wskbd_keyrepeat_data *ukdp, *kkdp;
        struct wskbd_map_data *umdp;
@@ -1134,6 +1151,9 @@ getkeyrepeat:
                return(error);
 
        case WSKBDIO_GETENCODING:
+               /* Do not advertise encoding to the parent mux. */
+               if (evsrc && (sc->id->t_keymap.layout & KB_NOENCODING))
+                       return (ENOTTY);
                *((kbd_t *)data) = sc->id->t_keymap.layout & ~KB_DEFAULT;
                return(0);
 

Reply via email to