sndio: Add a display string to the sioctl_open API
authorratchov <ratchov@openbsd.org>
Fri, 24 May 2024 15:10:26 +0000 (15:10 +0000)
committerratchov <ratchov@openbsd.org>
Fri, 24 May 2024 15:10:26 +0000 (15:10 +0000)
For hardware devices, add a server.device control
with a single item and the device name as display
string.

Add the necessary sndioctl(1) bits to print it.

include/sndio.h
lib/libsndio/shlib_version
lib/libsndio/sioctl_aucat.c
lib/libsndio/sioctl_open.3
lib/libsndio/sioctl_sun.c
usr.bin/sndioctl/sndioctl.c

index 04c7336..2bf7751 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sndio.h,v 1.14 2022/04/29 08:30:48 ratchov Exp $      */
+/*     $OpenBSD: sndio.h,v 1.15 2024/05/24 15:10:26 ratchov Exp $      */
 /*
  * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
  *
 
 /*
  * limits
+ *
+ * For now SIOCTL_DISPLAYMAX is 12 byte only. It nicely fits in the
+ * padding of the sioctl_desc structure: this allows any binary linked
+ * to the library version with no sioctl_desc->display to work with
+ * this library version. Currently, any string reported by the lower
+ * layers fits in the 12-byte buffer. Once larger strings start
+ * being used (or the ABI changes for any other reason) increase
+ * SIOCTL_DISPLAYMAX and properly pad the sioctl_desc structure.
  */
 #define SIOCTL_NAMEMAX         12      /* max name length */
+#define SIOCTL_DISPLAYMAX      12      /* max display string length */
 
 /*
  * private ``handle'' structure
@@ -115,7 +124,7 @@ struct sioctl_desc {
        struct sioctl_node node0;       /* affected node */
        struct sioctl_node node1;       /* dito for SIOCTL_{VEC,LIST,SEL} */
        unsigned int maxval;            /* max value */
-       int __pad[3];
+       char display[SIOCTL_DISPLAYMAX];        /* free-format hint */
 };
 
 /*
index a0ace4f..9521c10 100644 (file)
@@ -1,2 +1,2 @@
 major=7
-minor=2
+minor=3
index b6de274..241dcb7 100644 (file)
@@ -87,6 +87,7 @@ sioctl_aucat_rdata(struct sioctl_aucat_hdl *hdl)
                        strlcpy(desc.node1.name, c->node1.name, SIOCTL_NAMEMAX);
                        desc.node1.unit = (int16_t)ntohs(c->node1.unit);
                        strlcpy(desc.func, c->func, SIOCTL_NAMEMAX);
+                       strlcpy(desc.display, "", SIOCTL_DISPLAYMAX);
                        desc.type = c->type;
                        desc.addr = ntohs(c->addr);
                        desc.maxval = ntohs(c->maxval);
index 9c1dd17..791f3a2 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sioctl_open.3,v 1.13 2022/05/03 13:03:30 ratchov Exp $
+.\" $OpenBSD: sioctl_open.3,v 1.14 2024/05/24 15:10:27 ratchov Exp $
 .\"
 .\" Copyright (c) 2011-2020 Alexandre Ratchov <alex@caoua.org>
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: May 3 2022 $
+.Dd $Mdocdate: May 24 2024 $
 .Dt SIOCTL_OPEN 3
 .Os
 .Sh NAME
@@ -168,6 +168,7 @@ struct sioctl_desc {
        struct sioctl_node node0;       /* affected node */
        struct sioctl_node node1;       /* dito for SIOCTL_{VEC,LIST,SEL} */
        unsigned int maxval;            /* max value */
+       char display[SIOCTL_DISPLAYMAX];        /* free-format hint */
 };
 .Ed
 .Pp
@@ -238,6 +239,11 @@ The
 .Fa maxval
 attribute indicates the maximum value of this control.
 For boolean control types it is set to 1.
+.Pp
+The
+.Fa display
+attribute contains an optional free-format string providing additional
+hints about the control, like the hardware model, or the units.
 .Ss Changing and reading control values
 Controls are changed with the
 .Fn sioctl_setval
index 9547e7c..64129ac 100644 (file)
@@ -53,6 +53,8 @@ struct volume
 
 struct sioctl_sun_hdl {
        struct sioctl_hdl sioctl;
+       char display[SIOCTL_DISPLAYMAX];
+       int display_addr;
        struct volume output, input;
        int fd, events;
 };
@@ -147,6 +149,7 @@ init(struct sioctl_sun_hdl *hdl)
                {AudioCinputs, AudioNvolume},
                {AudioCinputs, AudioNinput}
        };
+       struct audio_device getdev;
        int i;
 
        for (i = 0; i < sizeof(output_names) / sizeof(output_names[0]); i++) {
@@ -165,6 +168,13 @@ init(struct sioctl_sun_hdl *hdl)
                        break;
                }
        }
+
+       hdl->display_addr = 128;
+       if (ioctl(hdl->fd, AUDIO_GETDEV, &getdev) == -1)
+               strlcpy(hdl->display, "unknown", SIOCTL_DISPLAYMAX);
+       else
+               strlcpy(hdl->display, getdev.name, SIOCTL_DISPLAYMAX);
+       DPRINTF("init: server.device: display = %s\n", hdl->display);
 }
 
 static int
@@ -407,12 +417,27 @@ static int
 sioctl_sun_ondesc(struct sioctl_hdl *addr)
 {
        struct sioctl_sun_hdl *hdl = (struct sioctl_sun_hdl *)addr;
+       struct sioctl_desc desc;
 
        if (!scanvol(hdl, &hdl->output) ||
            !scanvol(hdl, &hdl->input)) {
                hdl->sioctl.eof = 1;
                return 0;
        }
+
+       /* report "server.device" control */
+       memset(&desc, 0, sizeof(struct sioctl_desc));
+       desc.type = SIOCTL_SEL;
+       desc.maxval = 1;
+       strlcpy(desc.func, "device", SIOCTL_NAMEMAX);
+       strlcpy(desc.node0.name, "server", SIOCTL_NAMEMAX);
+       desc.node0.unit = -1;
+       strlcpy(desc.node1.name, "0", SIOCTL_NAMEMAX);
+       desc.node1.unit = -1;
+       strlcpy(desc.display, hdl->display, SIOCTL_DISPLAYMAX);
+       desc.addr = hdl->display_addr;
+       _sioctl_ondesc_cb(&hdl->sioctl, &desc, 1);
+
        _sioctl_ondesc_cb(&hdl->sioctl, NULL, 0);
        return 1;
 }
index 2bda6e7..3751be7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sndioctl.c,v 1.20 2024/04/22 10:49:01 ratchov Exp $   */
+/*     $OpenBSD: sndioctl.c,v 1.21 2024/05/24 15:10:27 ratchov Exp $   */
 /*
  * Copyright (c) 2014-2020 Alexandre Ratchov <alex@caoua.org>
  *
@@ -47,6 +47,7 @@ int matchpar(struct info *, char *, int);
 int matchent(struct info *, char *, int);
 int ismono(struct info *);
 void print_node(struct sioctl_node *, int);
+void print_display(struct info *);
 void print_desc(struct info *, int);
 void print_num(struct info *);
 void print_ent(struct info *, char *);
@@ -310,6 +311,9 @@ ismono(struct info *g)
                                                continue;
                                        if (e1->curval != e2->curval)
                                                return 0;
+                                       if (strcmp(e1->desc.display,
+                                               e2->desc.display) != 0)
+                                               return 0;
                                }
                        }
                }
@@ -329,6 +333,28 @@ print_node(struct sioctl_node *c, int mono)
                printf("[%d]", c->unit);
 }
 
+/*
+ * print display string, with '(' and ')' and non-printable chars removed
+ * in order to match command syntax
+ */
+void
+print_display(struct info *p)
+{
+       char buf[SIOCTL_NAMEMAX], *s, *d;
+       unsigned int c;
+
+       s = p->desc.display;
+       d = buf;
+       while ((c = *s++) != 0) {
+               if (c == '(' || c == ')' || c < ' ')
+                       continue;
+               *d++ = c;
+       }
+       *d = 0;
+       if (buf[0] != 0)
+               printf("(%s)", buf);
+}
+
 /*
  * print info about the parameter
  */
@@ -342,6 +368,7 @@ print_desc(struct info *p, int mono)
        case SIOCTL_NUM:
        case SIOCTL_SW:
                printf("*");
+               print_display(p);
                break;
        case SIOCTL_SEL:
        case SIOCTL_VEC:
@@ -359,6 +386,8 @@ print_desc(struct info *p, int mono)
                        print_node(&e->desc.node1, mono);
                        if (p->desc.type != SIOCTL_SEL)
                                printf(":*");
+                       if (e->desc.display[0] != 0)
+                               print_display(e);
                        more = 1;
                }
        }
@@ -404,6 +433,7 @@ print_ent(struct info *e, char *comment)
        case SIOCTL_NUM:
                print_num(e);
        }
+       print_display(e);
        if (comment)
                printf("\t# %s", comment);
        printf("\n");
@@ -422,6 +452,7 @@ print_val(struct info *p, int mono)
        case SIOCTL_NUM:
        case SIOCTL_SW:
                print_num(p);
+               print_display(p);
                break;
        case SIOCTL_SEL:
        case SIOCTL_VEC:
@@ -439,6 +470,7 @@ print_val(struct info *p, int mono)
                                        if (more)
                                                printf(",");
                                        print_node(&e->desc.node1, mono);
+                                       print_display(e);
                                        more = 1;
                                }
                        } else {
@@ -447,6 +479,7 @@ print_val(struct info *p, int mono)
                                print_node(&e->desc.node1, mono);
                                printf(":");
                                print_num(e);
+                               print_display(e);
                                more = 1;
                        }
                }
@@ -631,6 +664,7 @@ dump(void)
                        print_node(&i->desc.node1, 0);
                        printf(":0..%d (%u)", i->desc.maxval, i->curval);
                }
+               print_display(i);
                printf("\n");
        }
 }
@@ -753,6 +787,12 @@ cmd(char *line)
                                        }
                                }
                        }
+                       if (*pos == '(') {
+                               while (*pos != 0) {
+                                       if (*pos++ == ')')
+                                               break;
+                               }
+                       }
                        if (nent == 0) {
                                /* XXX: use print_node()-like routine */
                                fprintf(stderr, "%s[%d]: invalid value\n", vstr, vunit);