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