[cc: tech@, reply-to set to tech@]

> After suspend or hibernate, I lose my designated console keyboard layout 
> (sv) and it reverts to the default (us?)  wsconsctl shows that the 
> encoding to still be sv,
> 
>       keyboard.encoding=sv
> 
> What setting(s) am I missing to preserve the designated layout across 
> suspend/hibernate?

Well, the mux is supposed to be a bit smart and remember a forced
keyboard layout (set with kbd(8) or wsconsctl keyboard.encoding), and
force it on new keyboard attachments.

Except that this only works when the `set encoding' ioctl is issued on
/dev/wskbd, not /dev/wskbd[0-9], which is what kbd(8) and wsconsctl(8)
prefer.

Fear not, for I have a diff for you (which I have been sitting on for
about two years, and only completed and debugged thanks to this
discussion)!

This diff attempts to achieve the following:
- keyboard drivers will now tell wskbd if the keyboard layout they ask
  for is a default value, or a value they are 100% sure of (either
  because your kernel has a XXXKBD_LAYOUT option, or because the
  driver can tell the keyboard layout, e.g. by the country code on USB
  keyboards which provide it, such as Sun's)
- when attaching a keyboard with a non-default layout, the layout will
  become the default layout of the mux for new keyboard attachments if
  the mux doesn't have a layout set already.
- when changing the keyboard layout of a particular keyboard with an
  ioctl (i.e. using kbd(8) or wsconsctl(8)), the layout will become the
  default layout of the mux for new keyboard attachments.

This actually allows special-casing of the WSKBDIO_SETENCODING ioctl in
the mux code to be removed.

If the above is a bit too complicated, let me provide an example.

I am booting a GENERIC kernel with a PS/2 us keyboard. The keyboard
is wskbd0, its layout is the default, ``us''.

  $ wsconsctl 2>/dev/null |grep encoding
  keyboard.encoding=us

Now I am plugging an icelandic USB keyboard with no country information.
It becomes wskbd1, and uses the default layout, ``us''.

  $ wsconsctl 2>/dev/null |grep encoding
  keyboard.encoding=us
  keyboard1.encoding=us

Now I run:

  $ wsconsctl keyboard1.encoding=is
  keyboard1.encoding -> is

Now the PS/2 keyboard is still using the us layout, the USB keyboard is
using the icelandic layout (and I can enter thorns and eths), and the
default setting for new keyboards become icelandic:

  $ wsconsctl 2>/dev/null |grep encoding
  keyboard.encoding=us
  keyboard1.encoding=is

I unplug the USB keyboard. 

  $ wsconsctl 2>/dev/null |grep encoding
  keyboard.encoding=us

I plug the USB keyboard again. It will reattach with an icelandic
keyboard layout, whereas it would use the us layout without that diff:

  $ wsconsctl 2>/dev/null |grep encoding
  keyboard.encoding=us
  keyboard1.encoding=is

Now I plug a Sun USB keyboard with the uk layout (pound sign as shift-3,
etc). Sun keyboards provide country information to the ukbd driver,
which uses it to select the matching layout.

  $ wsconsctl 2>/dev/null |grep encoding
  keyboard.encoding=us
  keyboard1.encoding=is
  keyboard2.encoding=uk

And the uk layout has become the default for new attachments. If I
unplug, then replug, the icelandic keyboard, it will reattach as wskbd1,
and it will pick the default mux layout, which is still icelandic.

  $ wsconsctl 2>/dev/null |grep encoding
  keyboard.encoding=us
  keyboard1.encoding=is
  keyboard2.encoding=uk

Now I unplug both USB keyboards...

  $ wsconsctl 2>/dev/null |grep encoding
  keyboard.encoding=us

... and put the machine to sleep.

  $ zzz

I wake up the system, and connect back the icelandic keyboard:

  $ wsconsctl 2>/dev/null |grep encoding
  keyboard.encoding=us
  keyboard1.encoding=is

Is this the behaviour you would like to get?

Miod

Index: arch/arm/xscale/pxa27x_kpc.c
===================================================================
RCS file: /cvs/src/sys/arch/arm/xscale/pxa27x_kpc.c,v
retrieving revision 1.2
diff -u -p -r1.2 pxa27x_kpc.c
--- arch/arm/xscale/pxa27x_kpc.c        9 Feb 2013 20:36:14 -0000       1.2
+++ arch/arm/xscale/pxa27x_kpc.c        23 Jan 2014 20:32:22 -0000
@@ -50,7 +50,7 @@ struct wscons_keydesc pxa27x_kpc_keydesc
 };
 
 struct wskbd_mapdata pxa27x_kpc_mapdata = {
-       pxa27x_kpc_keydesctab, KB_US,
+       pxa27x_kpc_keydesctab, KB_US | KB_DEFAULT,
 };
 
 void pxa27x_kpc_cngetc(void *, u_int *, int *);
Index: arch/hp300/dev/dnkbd.c
===================================================================
RCS file: /cvs/src/sys/arch/hp300/dev/dnkbd.c,v
retrieving revision 1.18
diff -u -p -r1.18 dnkbd.c
--- arch/hp300/dev/dnkbd.c      9 Nov 2011 14:22:37 -0000       1.18
+++ arch/hp300/dev/dnkbd.c      23 Jan 2014 20:32:22 -0000
@@ -201,7 +201,7 @@ struct wskbd_mapdata dnkbd_keymapdata = 
 #ifdef DNKBD_LAYOUT
        DNKBD_LAYOUT
 #else
-       KB_US
+       KB_US | KB_DEFAULT
 #endif
 };
 
Index: arch/luna88k/dev/lunaws.c
===================================================================
RCS file: /cvs/src/sys/arch/luna88k/dev/lunaws.c,v
retrieving revision 1.9
diff -u -p -r1.9 lunaws.c
--- arch/luna88k/dev/lunaws.c   22 May 2013 11:35:02 -0000      1.9
+++ arch/luna88k/dev/lunaws.c   23 Jan 2014 20:32:23 -0000
@@ -87,7 +87,7 @@ const struct wskbd_mapdata omkbd_keymapd
 #ifdef OMKBD_LAYOUT
        OMKBD_LAYOUT,
 #else
-       KB_JP,
+       KB_JP | KB_DEFAULT,
 #endif
 };
 
Index: arch/sgi/hpc/z8530kbd.c
===================================================================
RCS file: /cvs/src/sys/arch/sgi/hpc/z8530kbd.c,v
retrieving revision 1.4
diff -u -p -r1.4 z8530kbd.c
--- arch/sgi/hpc/z8530kbd.c     29 Apr 2012 09:01:38 -0000      1.4
+++ arch/sgi/hpc/z8530kbd.c     23 Jan 2014 20:32:25 -0000
@@ -163,7 +163,7 @@ static struct zsops zskbd_zsops = {
 extern const struct wscons_keydesc wssgi_keydesctab[];
 const struct wskbd_mapdata sgikbd_wskbd_keymapdata = {
        wssgi_keydesctab,
-       KB_US
+       KB_US | KB_DEFAULT
 };
 
 const struct wskbd_accessops zskbd_wskbd_accessops = {
Index: arch/vax/dec/dzkbd.c
===================================================================
RCS file: /cvs/src/sys/arch/vax/dec/dzkbd.c,v
retrieving revision 1.14
diff -u -p -r1.14 dzkbd.c
--- arch/vax/dec/dzkbd.c        20 Aug 2008 16:31:41 -0000      1.14
+++ arch/vax/dec/dzkbd.c        23 Jan 2014 20:32:26 -0000
@@ -113,7 +113,7 @@ const struct wskbd_mapdata dzkbd_keymapd
 #ifdef LKKBD_LAYOUT
        LKKBD_LAYOUT,
 #else
-       KB_US,
+       KB_US | KB_DEFAULT,
 #endif
 };
 
Index: arch/vax/vxt/qsckbd.c
===================================================================
RCS file: /cvs/src/sys/arch/vax/vxt/qsckbd.c,v
retrieving revision 1.1
diff -u -p -r1.1 qsckbd.c
--- arch/vax/vxt/qsckbd.c       27 Aug 2006 16:55:41 -0000      1.1
+++ arch/vax/vxt/qsckbd.c       23 Jan 2014 20:32:26 -0000
@@ -127,7 +127,7 @@ const struct wskbd_mapdata qsckbd_keymap
 #ifdef LKKBD_LAYOUT
        LKKBD_LAYOUT,
 #else
-       KB_US,
+       KB_US | KB_DEFAULT,
 #endif
 };
 
Index: arch/zaurus/dev/zaurus_kbd.c
===================================================================
RCS file: /cvs/src/sys/arch/zaurus/dev/zaurus_kbd.c,v
retrieving revision 1.33
diff -u -p -r1.33 zaurus_kbd.c
--- arch/zaurus/dev/zaurus_kbd.c        9 Nov 2011 14:22:37 -0000       1.33
+++ arch/zaurus/dev/zaurus_kbd.c        23 Jan 2014 20:32:26 -0000
@@ -151,7 +151,7 @@ struct wskbd_consops zkbd_consops = {
 
 struct wskbd_mapdata zkbd_keymapdata = {
         zkbd_keydesctab,   
-        KB_US,
+        KB_US | KB_DEFAULT,
 };
 
 
Index: arch/zaurus/dev/zaurus_remote.c
===================================================================
RCS file: /cvs/src/sys/arch/zaurus/dev/zaurus_remote.c,v
retrieving revision 1.1
diff -u -p -r1.1 zaurus_remote.c
--- arch/zaurus/dev/zaurus_remote.c     17 Nov 2005 05:26:31 -0000      1.1
+++ arch/zaurus/dev/zaurus_remote.c     23 Jan 2014 20:32:26 -0000
@@ -153,7 +153,7 @@ static const struct wscons_keydesc zrc_k
 };
 
 struct wskbd_mapdata zrc_keymapdata = {
-       zrc_keydesctab, KB_US
+       zrc_keydesctab, KB_US | KB_DEFAULT
 };
 
 
Index: dev/adb/akbd.c
===================================================================
RCS file: /cvs/src/sys/dev/adb/akbd.c,v
retrieving revision 1.13
diff -u -p -r1.13 akbd.c
--- dev/adb/akbd.c      22 Aug 2013 11:46:38 -0000      1.13
+++ dev/adb/akbd.c      23 Jan 2014 20:32:27 -0000
@@ -80,7 +80,7 @@ struct wskbd_mapdata akbd_keymapdata = {
 #ifdef AKBD_LAYOUT
        AKBD_LAYOUT,
 #else
-       KB_US,
+       KB_US | KB_DEFAULT,
 #endif
 };
 
Index: dev/hil/hilkbd.c
===================================================================
RCS file: /cvs/src/sys/dev/hil/hilkbd.c,v
retrieving revision 1.15
diff -u -p -r1.15 hilkbd.c
--- dev/hil/hilkbd.c    9 Nov 2011 14:22:37 -0000       1.15
+++ dev/hil/hilkbd.c    23 Jan 2014 20:32:27 -0000
@@ -104,7 +104,7 @@ struct wskbd_mapdata hilkbd_keymapdata =
 #ifdef HILKBD_LAYOUT
        HILKBD_LAYOUT,
 #else
-       KB_US,
+       KB_US | KB_DEFAULT,
 #endif
 };
 
@@ -113,7 +113,7 @@ struct wskbd_mapdata hilkbd_keymapdata_p
 #ifdef HILKBD_LAYOUT
        HILKBD_LAYOUT,
 #else
-       KB_US,
+       KB_US | KB_DEFAULT,
 #endif
 };
 
Index: dev/pckbc/pckbd.c
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/pckbd.c,v
retrieving revision 1.34
diff -u -p -r1.34 pckbd.c
--- dev/pckbc/pckbd.c   15 Feb 2013 10:20:07 -0000      1.34
+++ dev/pckbc/pckbd.c   23 Jan 2014 20:32:28 -0000
@@ -157,7 +157,7 @@ const struct wskbd_mapdata pckbd_keymapd
 #ifdef PCKBD_LAYOUT
        PCKBD_LAYOUT,
 #else
-       KB_US,
+       KB_US | KB_DEFAULT,
 #endif
 };
 
Index: dev/sun/sunkbdmap.c
===================================================================
RCS file: /cvs/src/sys/dev/sun/sunkbdmap.c,v
retrieving revision 1.5
diff -u -p -r1.5 sunkbdmap.c
--- dev/sun/sunkbdmap.c 29 Nov 2012 14:51:27 -0000      1.5
+++ dev/sun/sunkbdmap.c 23 Jan 2014 20:32:29 -0000
@@ -1162,7 +1162,7 @@ struct wskbd_mapdata sunkbd_keymapdata =
 #ifdef SUNKBD_LAYOUT
        SUNKBD_LAYOUT,
 #else
-       KB_US,
+       KB_US | KB_DEFAULT,
 #endif
 };
 
@@ -1171,6 +1171,6 @@ struct wskbd_mapdata sunkbd5_keymapdata 
 #ifdef SUNKBD5_LAYOUT
        SUNKBD5_LAYOUT,
 #else
-       KB_US,
+       KB_US | KB_DEFAULT,
 #endif
 };
Index: dev/usb/ukbd.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ukbd.c,v
retrieving revision 1.62
diff -u -p -r1.62 ukbd.c
--- dev/usb/ukbd.c      15 Nov 2013 08:17:44 -0000      1.62
+++ dev/usb/ukbd.c      23 Jan 2014 20:32:29 -0000
@@ -265,7 +265,7 @@ ukbd_attach(struct device *parent, struc
 #ifdef UKBD_LAYOUT
                layout = UKBD_LAYOUT;
 #else
-               layout = KB_US;
+               layout = KB_US | KB_DEFAULT;
 #endif
        }
 
Index: dev/wscons/wskbd.c
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wskbd.c,v
retrieving revision 1.75
diff -u -p -r1.75 wskbd.c
--- dev/wscons/wskbd.c  4 Nov 2013 11:57:26 -0000       1.75
+++ dev/wscons/wskbd.c  23 Jan 2014 20:32:29 -0000
@@ -122,8 +122,6 @@ int wskbddebug = 0;
 #include <dev/wscons/wsmuxvar.h>
 
 struct wskbd_internal {
-       const struct wskbd_mapdata *t_keymap;
-
        const struct wskbd_consops *t_consops;
        void    *t_consaccesscookie;
 
@@ -138,6 +136,9 @@ struct wskbd_internal {
        keysym_t t_symbols[MAXKEYSYMSPERKEY];
 
        struct wskbd_softc *t_sc;       /* back pointer */
+
+       struct wskbd_mapdata t_keymap;  /* translation map table and
+                                          current layout */
 };
 
 struct wskbd_softc {
@@ -165,7 +166,6 @@ struct wskbd_softc {
 
        int     sc_maplen;              /* number of entries in sc_map */
        struct wscons_keymap *sc_map;   /* current translation map */
-       kbd_t   sc_layout; /* current layout */
 
        int     sc_refcnt;
        u_char  sc_dying;               /* device is being detached */
@@ -307,6 +307,8 @@ wskbd_update_layout(struct wskbd_interna
                id->t_flags |= WSKFL_METAESC;
        else
                id->t_flags &= ~WSKFL_METAESC;
+
+       id->t_keymap.layout = enc;
 }
 
 /*
@@ -354,7 +356,9 @@ wskbd_attach(struct device *parent, stru
 {
        struct wskbd_softc *sc = (struct wskbd_softc *)self;
        struct wskbddev_attach_args *ap = aux;
+       kbd_t layout;
 #if NWSMUX > 0
+       struct wsmux_softc *wsmux_sc;
        int mux, error;
 #endif
 
@@ -370,8 +374,11 @@ wskbd_attach(struct device *parent, stru
                /* printf(" (mux %d ignored for console)", mux); */
                mux = -1;
        }
-       if (mux >= 0)
+       if (mux >= 0) {
                printf(" mux %d", mux);
+               wsmux_sc = wsmux_getmux(mux);
+       } else
+               wsmux_sc = NULL;
 #else
 #if 0  /* not worth keeping, especially since the default value is not -1... */
        if (sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux >= 0)
@@ -384,8 +391,7 @@ wskbd_attach(struct device *parent, stru
        } else {
                sc->id = malloc(sizeof(struct wskbd_internal),
                    M_DEVBUF, M_WAITOK | M_ZERO);
-               sc->id->t_keymap = ap->keymap;
-               wskbd_update_layout(sc->id, ap->keymap->layout);
+               bcopy(ap->keymap, &sc->id->t_keymap, sizeof(sc->id->t_keymap));
        }
 
 #if NWSDISPLAY > 0
@@ -400,11 +406,36 @@ wskbd_attach(struct device *parent, stru
        sc->sc_translating = 1;
        sc->sc_ledstate = -1; /* force update */
 
-       if (wskbd_load_keymap(sc->id->t_keymap,
-           &sc->sc_map, &sc->sc_maplen) != 0)
-               panic("cannot load keymap");
-
-       sc->sc_layout = sc->id->t_keymap->layout;
+       /*
+        * If this layout is the default choice of the driver (i.e. the
+        * driver doesn't know better), pick the existing layout of the
+        * current mux, if any.
+        */
+       layout = sc->id->t_keymap.layout;
+#if NWSMUX > 0
+       if (layout & KB_DEFAULT) {
+               if (wsmux_sc != NULL && wsmux_get_layout(wsmux_sc) != KB_NONE)
+                       layout = wsmux_get_layout(wsmux_sc);
+       }
+#endif
+       for (;;) {
+               if (wskbd_load_keymap(&sc->id->t_keymap, layout, &sc->sc_map,
+                   &sc->sc_maplen) == 0)
+                       break;
+#if NWSMUX > 0
+               if (layout == sc->id->t_keymap.layout)
+                       panic("cannot load keymap");
+               if (wsmux_sc != NULL && wsmux_get_layout(wsmux_sc) != KB_NONE) {
+                       printf("\n%s: cannot load keymap, "
+                           "falling back to default\n%s",
+                           sc->sc_base.me_dv.dv_xname,
+                           sc->sc_base.me_dv.dv_xname);
+                       layout = wsmux_get_layout(wsmux_sc);
+               } else
+#endif
+                       panic("cannot load keymap");
+       }
+       wskbd_update_layout(sc->id, layout);
 
        /* set default bell and key repeat data */
        sc->sc_bell_data = wskbd_default_bell_data;
@@ -427,11 +458,21 @@ wskbd_attach(struct device *parent, stru
        printf("\n");
 
 #if NWSMUX > 0
-       if (mux >= 0) {
-               error = wsmux_attach_sc(wsmux_getmux(mux), &sc->sc_base);
+       if (wsmux_sc != NULL) {
+               error = wsmux_attach_sc(wsmux_sc, &sc->sc_base);
                if (error)
                        printf("%s: attach error=%d\n",
                            sc->sc_base.me_dv.dv_xname, error);
+
+               /*
+                * Try and set this encoding as the mux default if it
+                * hasn't any yet, and if this is not a driver default
+                * layout (i.e. parent driver pretends to know better).
+                * Note that wsmux_set_layout() rejects layouts with
+                * KB_DEFAULT set.
+                */
+               if (wsmux_get_layout(wsmux_sc) == KB_NONE)
+                       wsmux_set_layout(wsmux_sc, layout);
        }
 #endif
 
@@ -451,7 +492,6 @@ wskbd_attach(struct device *parent, stru
                }
        }
 #endif
-
 }
 
 void    
@@ -461,7 +501,7 @@ wskbd_cnattach(const struct wskbd_consop
 
        KASSERT(!wskbd_console_initted);
 
-       wskbd_console_data.t_keymap = mapdata;
+       bcopy(mapdata, &wskbd_console_data.t_keymap, sizeof(*mapdata));
        wskbd_update_layout(&wskbd_console_data, mapdata->layout);
 
        wskbd_console_data.t_consops = consops;
@@ -479,10 +519,11 @@ wskbd_cndetach(void)
 {
        KASSERT(wskbd_console_initted);
 
-       wskbd_console_data.t_keymap = 0;
+       wskbd_console_data.t_keymap.keydesc = NULL;
+       wskbd_console_data.t_keymap.layout = KB_NONE;
 
-       wskbd_console_data.t_consops = 0;
-       wskbd_console_data.t_consaccesscookie = 0;
+       wskbd_console_data.t_consops = NULL;
+       wskbd_console_data.t_consaccesscookie = NULL;
 
 #if NWSDISPLAY > 0
        wsdisplay_unset_cons_kbd();
@@ -510,7 +551,7 @@ wskbd_repeat(void *v)
                /* deliver keys */
                if (sc->sc_displaydv != NULL)
                        wsdisplay_kbdinput(sc->sc_displaydv,
-                           sc->id->t_keymap->layout,
+                           sc->id->t_keymap.layout,
                            sc->id->t_symbols, sc->sc_repeating);
        } else {
                /* queue event */
@@ -629,7 +670,7 @@ wskbd_input(struct device *dev, u_int ty
                                }
 #endif
                                wsdisplay_kbdinput(sc->sc_displaydv,
-                                   sc->id->t_keymap->layout,
+                                   sc->id->t_keymap.layout,
                                    sc->id->t_symbols, num);
                        }
 
@@ -955,7 +996,6 @@ wskbd_displayioctl(struct device *dev, u
        struct wskbd_bell_data *ubdp, *kbdp;
        struct wskbd_keyrepeat_data *ukdp, *kkdp;
        struct wskbd_map_data *umdp;
-       struct wskbd_mapdata md;
        kbd_t enc;
        void *buf;
        int len, error;
@@ -1070,9 +1110,9 @@ getkeyrepeat:
                                          &sc->sc_map, &sc->sc_maplen);
                        memcpy(sc->sc_map, buf, len);
                        /* drop the variant bits handled by the map */
-                       sc->sc_layout = KB_USER |
-                             (KB_VARIANT(sc->sc_layout) & KB_HANDLEDBYWSKBD);
-                       wskbd_update_layout(sc->id, sc->sc_layout);
+                       enc = KB_USER | (KB_VARIANT(sc->id->t_keymap.layout) &
+                           KB_HANDLEDBYWSKBD);
+                       wskbd_update_layout(sc->id, enc);
                }
                free(buf, M_TEMP);
                return(error);
@@ -1086,28 +1126,30 @@ getkeyrepeat:
                return(error);
 
        case WSKBDIO_GETENCODING:
-               *((kbd_t *) data) = sc->sc_layout;
+               *((kbd_t *)data) = sc->id->t_keymap.layout & ~KB_DEFAULT;
                return(0);
 
        case WSKBDIO_SETENCODING:
                enc = *((kbd_t *)data);
                if (KB_ENCODING(enc) == KB_USER) {
                        /* user map must already be loaded */
-                       if (KB_ENCODING(sc->sc_layout) != KB_USER)
+                       if (KB_ENCODING(sc->id->t_keymap.layout) != KB_USER)
                                return (EINVAL);
                        /* map variants make no sense */
                        if (KB_VARIANT(enc) & ~KB_HANDLEDBYWSKBD)
                                return (EINVAL);
                } else {
-                       md = *(sc->id->t_keymap); /* structure assignment */
-                       md.layout = enc;
-                       error = wskbd_load_keymap(&md, &sc->sc_map,
-                                                 &sc->sc_maplen);
+                       error = wskbd_load_keymap(&sc->id->t_keymap, enc,
+                           &sc->sc_map, &sc->sc_maplen);
                        if (error)
-                               return(error);
+                               return (error);
                }
-               sc->sc_layout = enc;
                wskbd_update_layout(sc->id, enc);
+#if NWSMUX > 0
+               /* Update mux default layout */
+               if (sc->sc_base.me_parent != NULL)
+                       wsmux_set_layout(sc->sc_base.me_parent, enc);
+#endif
                return (0);
        }
 
@@ -1528,7 +1570,7 @@ wskbd_translate(struct wskbd_internal *i
                kp = sc->sc_map + value;
        } else {
                kp = &kpbuf;
-               wskbd_get_mapentry(id->t_keymap, value, kp);
+               wskbd_get_mapentry(&id->t_keymap, value, kp);
        }
 
        /* if this key has a command, process it first */
Index: dev/wscons/wskbdutil.c
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wskbdutil.c,v
retrieving revision 1.10
diff -u -p -r1.10 wskbdutil.c
--- dev/wscons/wskbdutil.c      5 Dec 2012 23:20:22 -0000       1.10
+++ dev/wscons/wskbdutil.c      23 Jan 2014 20:32:29 -0000
@@ -395,7 +395,7 @@ wskbd_init_keymap(int newlen, struct wsc
 }
 
 int
-wskbd_load_keymap(const struct wskbd_mapdata *mapdata,
+wskbd_load_keymap(const struct wskbd_mapdata *mapdata, kbd_t layout,
     struct wscons_keymap **map, int *maplen)
 {
        int i, s, kc, stack_ptr;
@@ -404,7 +404,7 @@ wskbd_load_keymap(const struct wskbd_map
        kbd_t cur;
        keysym_t ksg;
 
-       for (cur = mapdata->layout & ~KB_HANDLEDBYWSKBD, stack_ptr = 0;
+       for (cur = layout & ~KB_HANDLEDBYWSKBD, stack_ptr = 0;
             cur != 0; stack_ptr++) {
                mp = mapdata->keydesc;
                while (mp->map_size > 0) {
Index: dev/wscons/wsksymdef.h
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wsksymdef.h,v
retrieving revision 1.35
diff -u -p -r1.35 wsksymdef.h
--- dev/wscons/wsksymdef.h      18 Oct 2013 22:06:42 -0000      1.35
+++ dev/wscons/wsksymdef.h      23 Jan 2014 20:32:30 -0000
@@ -735,15 +735,16 @@
 #define KB_LV                  0x1b00
 #define KB_IS                  0x1c00
 
-#define KB_NODEAD              0x000001 /* disable dead accents */
-#define KB_DECLK               0x000002 /* DEC LKnnn layout */
-#define KB_LK401               0x000004 /* DEC LK401 instead LK201 */
-#define KB_SWAPCTRLCAPS                0x000008 /* swap Left-Control and 
Caps-Lock */
-#define KB_DVORAK              0x000010 /* Dvorak layout */
-#define KB_METAESC             0x000020 /* generate ESC prefix on ALT-key */
-#define KB_IOPENER             0x000040 /* f1-f12 -> ESC,f1-f11 */
-#define KB_MACHDEP             0x000080 /* machine dependent */
-#define        KB_APPLE                0x010000 /* Apple specific layout */
+#define KB_NODEAD              0x00000001 /* disable dead accents */
+#define KB_DECLK               0x00000002 /* DEC LKnnn layout */
+#define KB_LK401               0x00000004 /* DEC LK401 instead LK201 */
+#define KB_SWAPCTRLCAPS                0x00000008 /* swap Left-Control and 
Caps-Lock */
+#define KB_DVORAK              0x00000010 /* Dvorak layout */
+#define KB_METAESC             0x00000020 /* generate ESC prefix on ALT-key */
+#define KB_IOPENER             0x00000040 /* f1-f12 -> ESC,f1-f11 */
+#define KB_MACHDEP             0x00000080 /* machine dependent */
+#define        KB_APPLE                0x00010000 /* Apple specific layout */
+#define        KB_DEFAULT              0x80000000 /* (attach-only) default 
layout */
 
 #define KB_ENCTAB \
        { KB_USER,      "user" }, \
Index: dev/wscons/wsksymvar.h
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wsksymvar.h,v
retrieving revision 1.7
diff -u -p -r1.7 wsksymvar.h
--- dev/wscons/wsksymvar.h      26 Jun 2008 05:42:19 -0000      1.7
+++ dev/wscons/wsksymvar.h      23 Jan 2014 20:32:30 -0000
@@ -60,7 +60,7 @@ struct wskbd_mapdata {
 };
 
 /* layout variant bits ignored by mapping code */
-#define KB_HANDLEDBYWSKBD KB_METAESC
+#define KB_HANDLEDBYWSKBD      (KB_METAESC | KB_DEFAULT)
 
 /*
  * Utility functions.
@@ -68,7 +68,7 @@ struct wskbd_mapdata {
 void   wskbd_get_mapentry(const struct wskbd_mapdata *, int,
                                 struct wscons_keymap *);
 void   wskbd_init_keymap(int, struct wscons_keymap **, int *);
-int    wskbd_load_keymap(const struct wskbd_mapdata *,
+int    wskbd_load_keymap(const struct wskbd_mapdata *, kbd_t,
                                struct wscons_keymap **, int *);
 keysym_t wskbd_compose_value(keysym_t *);
 
Index: dev/wscons/wsmux.c
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wsmux.c,v
retrieving revision 1.25
diff -u -p -r1.25 wsmux.c
--- dev/wscons/wsmux.c  2 Dec 2013 02:36:22 -0000       1.25
+++ dev/wscons/wsmux.c  23 Jan 2014 20:32:30 -0000
@@ -519,13 +519,8 @@ wsmux_do_ioctl(struct device *dv, u_long
                if (!error)
                        ok = 1;
        }
-       if (ok) {
+       if (ok)
                error = 0;
-               if (cmd == WSKBDIO_SETENCODING) {
-                       sc->sc_kbd_layout = *((kbd_t *)data);
-               }
-
-       }
 
        return (error);
 }
@@ -633,10 +628,6 @@ wsmux_attach_sc(struct wsmux_softc *sc, 
                                (void)wsevsrc_ioctl(me, WSKBDIO_SETMODE,
                                                    &sc->sc_rawkbd, FWRITE, 0);
 #endif
-                               if (sc->sc_kbd_layout != KB_NONE)
-                                       (void)wsevsrc_ioctl(me,
-                                           WSKBDIO_SETENCODING,
-                                           &sc->sc_kbd_layout, FWRITE, 0);
                        }
                }
        }
@@ -821,3 +812,16 @@ wsmux_set_display(struct wsmux_softc *sc
        return (error);
 }
 #endif /* NWSDISPLAY > 0 */
+
+uint32_t
+wsmux_get_layout(struct wsmux_softc *sc)
+{
+       return sc->sc_kbd_layout;
+}
+
+void
+wsmux_set_layout(struct wsmux_softc *sc, uint32_t layout)
+{
+       if ((layout & KB_DEFAULT) == 0)
+               sc->sc_kbd_layout = layout;
+}
Index: dev/wscons/wsmuxvar.h
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wsmuxvar.h,v
retrieving revision 1.9
diff -u -p -r1.9 wsmuxvar.h
--- dev/wscons/wsmuxvar.h       2 Dec 2013 02:36:22 -0000       1.9
+++ dev/wscons/wsmuxvar.h       23 Jan 2014 20:32:30 -0000
@@ -93,6 +93,8 @@ struct        wsmux_softc *wsmux_create(const c
 int    wsmux_attach_sc(struct wsmux_softc *, struct wsevsrc *);
 void   wsmux_detach_sc(struct wsevsrc *);
 int    wsmux_set_display(struct wsmux_softc *, struct device *);
+uint32_t wsmux_get_layout(struct wsmux_softc *);
+void   wsmux_set_layout(struct wsmux_softc *, uint32_t);
 
 int    wskbd_add_mux(int, struct wsmux_softc *);
 int    wsmouse_add_mux(int, struct wsmux_softc *);

Reply via email to