Mark Kettenis <mark.kette...@xs4all.nl> writes:

>> Date: Thu, 29 Sep 2016 14:19:43 +0200 (CEST)
>> From: Mark Kettenis <mark.kette...@xs4all.nl>
>> 
>> This diff adds a WSKBDIO_GETENCODINGS ioctl and uses it to print a
>> list of supported encodings like the old kvm groveling code did.  The
>> ioctl will clamp the number of entries that are returns to the number
>> that was passed in.  This means that if the number returned is the
>> same as the number passed in, there might be more entries and you
>> probably want to retry with a larger buffer.  The new implementation
>> does this.
>
> Thanks to tb@ for testing this on a ramdisk.  Here is a slightly
> better diff that frees the allocated memory.
>
> ok?

Looks fine to me, ok jca@

Nitpicking below,

>
> Index: sys/dev/wscons/wsconsio.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v
> retrieving revision 1.75
> diff -u -p -r1.75 wsconsio.h
> --- sys/dev/wscons/wsconsio.h 14 Sep 2016 03:25:51 -0000      1.75
> +++ sys/dev/wscons/wsconsio.h 29 Sep 2016 18:12:48 -0000
> @@ -207,6 +207,12 @@ struct wskbd_backlight {
>  #define              WSKBD_TRANSLATED        0
>  #define              WSKBD_RAW               1
>  
> +struct wskbd_encoding_data {
> +     int     nencodings;
> +     kbd_t   *encodings;
> +};
> +#define WSKBDIO_GETENCODINGS _IOWR('W', 21, struct wskbd_encoding_data)
> +
>  /*
>   * Mouse ioctls (32 - 63)
>   */
> Index: sys/dev/wscons/wskbd.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/wscons/wskbd.c,v
> retrieving revision 1.83
> diff -u -p -r1.83 wskbd.c
> --- sys/dev/wscons/wskbd.c    12 Dec 2015 12:30:18 -0000      1.83
> +++ sys/dev/wscons/wskbd.c    29 Sep 2016 18:12:48 -0000
> @@ -1001,9 +1001,11 @@ 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_encoding_data *uedp;
>       kbd_t enc;
>       void *buf;
>       int len, error;
> +     int count, i;

Maybe merge those two lines?

>  
>       switch (cmd) {
>       case WSKBDIO_BELL:
> @@ -1159,6 +1161,20 @@ getkeyrepeat:
>                       wsmux_set_layout(sc->sc_base.me_parent, enc);
>  #endif
>               return (0);
> +
> +     case WSKBDIO_GETENCODINGS:
> +             uedp = (struct wskbd_encoding_data *)data;
> +             for (count = 0; sc->id->t_keymap.keydesc[count].name; count++)
> +                     ;
> +             if (uedp->nencodings > count)
> +                     uedp->nencodings = count;
> +             for (i = 0; i < uedp->nencodings; i++) {
> +                     error = copyout(&sc->id->t_keymap.keydesc[i].name,
> +                         &uedp->encodings[i], sizeof(kbd_t));
> +                     if (error)
> +                             return (error);
> +             }
> +             return(0);
+space                ^

>  
>       case WSKBDIO_GETBACKLIGHT:
>               if (wskbd_get_backlight != NULL)
> Index: sbin/kbd/kbd_wscons.c
> ===================================================================
> RCS file: /cvs/src/sbin/kbd/kbd_wscons.c,v
> retrieving revision 1.30
> diff -u -p -r1.30 kbd_wscons.c
> --- sbin/kbd/kbd_wscons.c     27 Sep 2016 22:03:49 -0000      1.30
> +++ sbin/kbd/kbd_wscons.c     29 Sep 2016 18:12:48 -0000
> @@ -34,6 +34,7 @@
>  #include <fcntl.h>
>  #include <limits.h>
>  #include <stdio.h>
> +#include <stdlib.h>
>  #include <string.h>
>  #include <unistd.h>
>  
> @@ -82,31 +83,83 @@ struct nameint kbdvar_tab[] = {
>  
>  extern char *__progname;
>  
> -void kbd_show_enc(int idx);
> +void kbd_show_enc(struct wskbd_encoding_data *encs, int idx);
> +void kbd_get_encs(int fd, struct wskbd_encoding_data *encs);
>  void kbd_list(void);
>  void kbd_set(char *name, int verbose);
>  
>  void
> -kbd_show_enc(int idx)
> +kbd_show_enc(struct wskbd_encoding_data *encs, int idx)
>  {
> +     int found;
> +     kbd_t encoding, variant;
> +     struct nameint *n;
>       int i;
>  
>       printf("tables available for %s keyboard:\nencoding\n\n",
>           kbtype_tab[idx]);
>  
> -     for (i = 0; kbdenc_tab[i].value; i++)
> -             printf("%s\n", kbdenc_tab[i].name);
> +     for (i = 0; i < encs->nencodings; i++) {
> +             n = &kbdenc_tab[0];
> +             found = 0;
> +             encoding = encs->encodings[i];
> +             while (n->value) {
> +                     if (n->value == KB_ENCODING(encoding)) {
> +                             printf("%s", n->name);
> +                             found++;
> +                     }
> +                     n++;
> +             }

This looks a lot like a for loop.

> +             if (found == 0)
> +                     printf("<encoding 0x%04x>", KB_ENCODING(encoding));
> +             n = &kbdvar_tab[0];
> +             found = 0;
> +             variant = KB_VARIANT(encoding);
> +             while (n->value) {
> +                     if ((n->value & KB_VARIANT(encoding)) == n->value) {
> +                             printf(".%s", n->name);
> +                             variant &= ~n->value;
> +                     }
> +                     n++;
> +             }
> +             if (variant != 0)
> +                     printf(".<variant 0x%08x>", variant);
> +             printf("\n");
> +     }
>       printf("\n");
>  }
>  
>  void
> +kbd_get_encs(int fd, struct wskbd_encoding_data *encs)
> +{
> +     int nencodings = 64;
> +
> +     encs->nencodings = nencodings;
> +     while (encs->nencodings == nencodings) {
> +             encs->encodings = reallocarray(encs->encodings,
> +                 encs->nencodings, sizeof(kbd_t));
> +             if (encs->encodings == NULL)
> +                     err(1, "reallocarray");

Or just err(1, NULL).

> +             if (ioctl(fd, WSKBDIO_GETENCODINGS, encs) < 0)
> +                     err(1, "WSKBDIO_GETENCODINGS");
> +             if (encs->nencodings == nencodings) {
> +                     nencodings *= 2;
> +                     encs->nencodings = nencodings;
> +             }
> +     }
> +}
> +
> +void
>  kbd_list(void)
>  {
>       int     kbds[SA_MAX];
> -     int     fd, i, kbtype;
> +     struct wskbd_encoding_data encs[SA_MAX];
> +     int     fd, i, kbtype, t;
>       char    device[PATH_MAX];
> +     int j;

j is unused.

>  
> -     bzero(kbds, sizeof(kbds));
> +     memset(kbds, 0, sizeof(kbds));
> +     memset(encs, 0, sizeof(encs));
>  
>       /* Go through all keyboards. */
>       for (i = 0; i < NUM_KBD; i++) {
> @@ -120,41 +173,53 @@ kbd_list(void)
>                       switch (kbtype) {
>                       case WSKBD_TYPE_PC_XT:
>                       case WSKBD_TYPE_PC_AT:
> -                             kbds[SA_PCKBD]++;
> +                             t = SA_PCKBD;
>                               break;
>                       case WSKBD_TYPE_USB:
> -                             kbds[SA_UKBD]++;
> +                             t = SA_UKBD;
>                               break;
>                       case WSKBD_TYPE_ADB:
> -                             kbds[SA_AKBD]++;
> +                             t = SA_AKBD;
>                               break;
>                       case WSKBD_TYPE_LK201:
>                       case WSKBD_TYPE_LK401:
> -                             kbds[SA_LKKBD]++;
> +                             t = SA_LKKBD;
>                               break;
>                       case WSKBD_TYPE_SUN:
> -                             kbds[SA_SUNKBD]++;
> +                             t = SA_SUNKBD;
>                               break;
>                       case WSKBD_TYPE_SUN5:
> -                             kbds[SA_SUN5KBD]++;
> +                             t = SA_SUN5KBD;
>                               break;
>                       case WSKBD_TYPE_HIL:
> -                             kbds[SA_HILKBD]++;
> +                             t = SA_HILKBD;
>                               break;
>                       case WSKBD_TYPE_GSC:
> -                             kbds[SA_GSCKBD]++;
> +                             t = SA_GSCKBD;
>                               break;
>                       case WSKBD_TYPE_SGI:
> -                             kbds[SA_SGIKBD]++;
> +                             t = SA_SGIKBD;
> +                             break;
> +                     default:
> +                             t = SA_MAX;
>                               break;
>                       };
> +
> +                     if (t != SA_MAX) {
> +                             kbds[t]++;
> +                             if (encs[t].encodings == NULL)
> +                                     kbd_get_encs(fd, &encs[t]);
> +                     }
>                       close(fd);
>               }
>       }
>  
>       for (i = 0; i < SA_MAX; i++)
>               if (kbds[i] != 0)
> -                     kbd_show_enc(i);
> +                     kbd_show_enc(&encs[i], i);
> +
> +     for (i = 0; i < SA_MAX; i++)
> +             free(encs[i].encodings);
>  }
>  
>  void
>

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to