-/* $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
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 */
};
/*
major=7
-minor=2
+minor=3
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);
-.\" $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>
.\"
.\" 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
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
.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
struct sioctl_sun_hdl {
struct sioctl_hdl sioctl;
+ char display[SIOCTL_DISPLAYMAX];
+ int display_addr;
struct volume output, input;
int fd, events;
};
{AudioCinputs, AudioNvolume},
{AudioCinputs, AudioNinput}
};
+ struct audio_device getdev;
int i;
for (i = 0; i < sizeof(output_names) / sizeof(output_names[0]); i++) {
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
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;
}
-/* $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>
*
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 *);
continue;
if (e1->curval != e2->curval)
return 0;
+ if (strcmp(e1->desc.display,
+ e2->desc.display) != 0)
+ return 0;
}
}
}
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
*/
case SIOCTL_NUM:
case SIOCTL_SW:
printf("*");
+ print_display(p);
break;
case SIOCTL_SEL:
case SIOCTL_VEC:
print_node(&e->desc.node1, mono);
if (p->desc.type != SIOCTL_SEL)
printf(":*");
+ if (e->desc.display[0] != 0)
+ print_display(e);
more = 1;
}
}
case SIOCTL_NUM:
print_num(e);
}
+ print_display(e);
if (comment)
printf("\t# %s", comment);
printf("\n");
case SIOCTL_NUM:
case SIOCTL_SW:
print_num(p);
+ print_display(p);
break;
case SIOCTL_SEL:
case SIOCTL_VEC:
if (more)
printf(",");
print_node(&e->desc.node1, mono);
+ print_display(e);
more = 1;
}
} else {
print_node(&e->desc.node1, mono);
printf(":");
print_num(e);
+ print_display(e);
more = 1;
}
}
print_node(&i->desc.node1, 0);
printf(":0..%d (%u)", i->desc.maxval, i->curval);
}
+ print_display(i);
printf("\n");
}
}
}
}
}
+ 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);