From 4d8b188f3074948b01f60b8d4fd246ea279f07b8 Mon Sep 17 00:00:00 2001 From: ratchov Date: Fri, 24 May 2024 15:16:09 +0000 Subject: [PATCH] sndiod: Propagate the controls' display string to clients. with help from edd@ and armani@ --- lib/libsndio/amsg.h | 15 +++++++++--- lib/libsndio/sioctl_aucat.c | 2 +- usr.bin/sndiod/dev.c | 48 +++++++++++++++++++++++++++++++++---- usr.bin/sndiod/dev.h | 9 ++++--- usr.bin/sndiod/dev_sioctl.c | 4 ++-- usr.bin/sndiod/opt.c | 4 ++-- usr.bin/sndiod/sock.c | 17 ++++++++++--- usr.bin/sndiod/sock.h | 3 ++- 8 files changed, 83 insertions(+), 19 deletions(-) diff --git a/lib/libsndio/amsg.h b/lib/libsndio/amsg.h index 6d1a185fcbf..331f8113003 100644 --- a/lib/libsndio/amsg.h +++ b/lib/libsndio/amsg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amsg.h,v 1.15 2022/04/29 08:30:48 ratchov Exp $ */ +/* $OpenBSD: amsg.h,v 1.16 2024/05/24 15:16:09 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov * @@ -46,6 +46,13 @@ * limits */ #define AMSG_CTL_NAMEMAX 16 /* max name length */ +#define AMSG_CTL_DISPLAYMAX 32 /* max display string length */ + +/* + * Size of the struct amsg_ctl_desc expected by clients + * using the AMSG_CTLSUB_OLD request + */ +#define AMSG_OLD_DESC_SIZE 92 /* * WARNING: since the protocol may be simultaneously used by static @@ -69,9 +76,10 @@ struct amsg { #define AMSG_HELLO 10 /* say hello, check versions and so ... */ #define AMSG_BYE 11 /* ask server to drop connection */ #define AMSG_AUTH 12 /* send authentication cookie */ -#define AMSG_CTLSUB 13 /* ondesc/onctl subscription */ +#define AMSG_CTLSUB_OLD 13 /* amsg_ctl_desc with no "display" attribute */ #define AMSG_CTLSET 14 /* set control value */ #define AMSG_CTLSYNC 15 /* end of controls descriptions */ +#define AMSG_CTLSUB 16 /* ondesc/onctl subscription */ uint32_t cmd; uint32_t __pad; union { @@ -151,7 +159,8 @@ struct amsg_ctl_desc { uint16_t addr; /* control address */ uint16_t maxval; uint16_t curval; - uint32_t __pad2[3]; + uint32_t __pad2[4]; + char display[AMSG_CTL_DISPLAYMAX]; /* free-format hint */ }; /* diff --git a/lib/libsndio/sioctl_aucat.c b/lib/libsndio/sioctl_aucat.c index 241dcb70ffc..e912e45ac85 100644 --- a/lib/libsndio/sioctl_aucat.c +++ b/lib/libsndio/sioctl_aucat.c @@ -87,7 +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); + strlcpy(desc.display, c->display, SIOCTL_DISPLAYMAX); desc.type = c->type; desc.addr = ntohs(c->addr); desc.maxval = ntohs(c->maxval); diff --git a/usr.bin/sndiod/dev.c b/usr.bin/sndiod/dev.c index eaa29fbf922..b96d70e0ab2 100644 --- a/usr.bin/sndiod/dev.c +++ b/usr.bin/sndiod/dev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.c,v 1.114 2024/05/24 15:01:53 ratchov Exp $ */ +/* $OpenBSD: dev.c,v 1.115 2024/05/24 15:16:09 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -1776,7 +1776,7 @@ slot_new(struct opt *opt, unsigned int id, char *who, s->opt = opt; slot_ctlname(s, ctl_name, CTL_NAMEMAX); ctl_new(CTL_SLOT_LEVEL, s, NULL, - CTL_NUM, "app", ctl_name, -1, "level", + CTL_NUM, "", "app", ctl_name, -1, "level", NULL, -1, 127, s->vol); found: @@ -2413,6 +2413,11 @@ ctl_log(struct ctl *c) default: log_puts("unknown"); } + if (c->display[0] != 0) { + log_puts(" ("); + log_puts(c->display); + log_puts(")"); + } } int @@ -2475,7 +2480,7 @@ ctl_setval(struct ctl *c, int val) */ struct ctl * ctl_new(int scope, void *arg0, void *arg1, - int type, char *gstr, + int type, char *display, char *gstr, char *str0, int unit0, char *func, char *str1, int unit1, int maxval, int val) { @@ -2499,6 +2504,7 @@ ctl_new(int scope, void *arg0, void *arg1, c->type = type; strlcpy(c->func, func, CTL_NAMEMAX); strlcpy(c->group, gstr, CTL_NAMEMAX); + strlcpy(c->display, display, CTL_DISPLAYMAX); strlcpy(c->node0.name, str0, CTL_NAMEMAX); c->node0.unit = unit0; if (c->type == CTL_VEC || c->type == CTL_LIST || c->type == CTL_SEL) { @@ -2644,11 +2650,32 @@ ctl_del(int scope, void *arg0, void *arg1) } } +char * +dev_getdisplay(struct dev *d) +{ + struct ctl *c; + char *display; + + display = ""; + for (c = ctl_list; c != NULL; c = c->next) { + if (c->scope == CTL_HW && + c->u.hw.dev == d && + c->type == CTL_SEL && + strcmp(c->group, d->name) == 0 && + strcmp(c->node0.name, "server") == 0 && + strcmp(c->func, "device") == 0 && + c->curval == 1) + display = c->display; + } + return display; +} + void dev_ctlsync(struct dev *d) { struct ctl *c; struct ctlslot *s; + const char *display; int found, i; found = 0; @@ -2676,10 +2703,23 @@ dev_ctlsync(struct dev *d) } d->master_enabled = 1; ctl_new(CTL_DEV_MASTER, d, NULL, - CTL_NUM, d->name, "output", -1, "level", + CTL_NUM, "", d->name, "output", -1, "level", NULL, -1, 127, d->master); } + /* + * if the hardware's server.device changed, update the display name + */ + display = dev_getdisplay(d); + for (c = ctl_list; c != NULL; c = c->next) { + if (c->scope != CTL_OPT_DEV || + c->u.opt_dev.dev != d || + strcmp(c->display, display) == 0) + continue; + strlcpy(c->display, display, CTL_DISPLAYMAX); + c->desc_mask = ~0; + } + for (s = ctlslot_array, i = 0; i < DEV_NCTLSLOT; i++, s++) { if (s->ops == NULL) continue; diff --git a/usr.bin/sndiod/dev.h b/usr.bin/sndiod/dev.h index 6e7cdf66fa9..49a085bbb56 100644 --- a/usr.bin/sndiod/dev.h +++ b/usr.bin/sndiod/dev.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.h,v 1.45 2024/05/19 00:05:43 jsg Exp $ */ +/* $OpenBSD: dev.h,v 1.46 2024/05/24 15:16:09 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -155,9 +155,11 @@ struct ctl { } u; unsigned int addr; /* slot side control address */ -#define CTL_NAMEMAX 16 /* max name length */ +#define CTL_NAMEMAX 12 /* max name length */ +#define CTL_DISPLAYMAX 24 /* max name length */ char func[CTL_NAMEMAX]; /* parameter function name */ char group[CTL_NAMEMAX]; /* group aka namespace */ + char display[CTL_DISPLAYMAX]; /* free-format hint */ struct ctl_node { char name[CTL_NAMEMAX]; /* stream name */ int unit; @@ -350,7 +352,7 @@ void slot_detach(struct slot *); */ struct ctl *ctl_new(int, void *, void *, - int, char *, char *, int, char *, char *, int, int, int); + int, char *, char *, char *, int, char *, char *, int, int, int); int ctl_del(int, void *, void *); void ctl_log(struct ctl *); int ctl_setval(struct ctl *c, int val); @@ -365,6 +367,7 @@ int ctlslot_visible(struct ctlslot *, struct ctl *); struct ctl *ctlslot_lookup(struct ctlslot *, int); void ctlslot_update(struct ctlslot *); +char *dev_getdisplay(struct dev *); void dev_ctlsync(struct dev *); #endif /* !defined(DEV_H) */ diff --git a/usr.bin/sndiod/dev_sioctl.c b/usr.bin/sndiod/dev_sioctl.c index 7df7dcee781..6ec3e7ae2ee 100644 --- a/usr.bin/sndiod/dev_sioctl.c +++ b/usr.bin/sndiod/dev_sioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev_sioctl.c,v 1.9 2024/05/24 15:00:15 ratchov Exp $ */ +/* $OpenBSD: dev_sioctl.c,v 1.10 2024/05/24 15:16:09 ratchov Exp $ */ /* * Copyright (c) 2014-2020 Alexandre Ratchov * @@ -70,7 +70,7 @@ dev_sioctl_ondesc(void *arg, struct sioctl_desc *desc, int val) } ctl_new(CTL_HW, d, &desc->addr, - desc->type, group, + desc->type, desc->display, group, desc->node0.name, desc->node0.unit, desc->func, desc->node1.name, desc->node1.unit, desc->maxval, val); } diff --git a/usr.bin/sndiod/opt.c b/usr.bin/sndiod/opt.c index 17d2456e78d..195416678d1 100644 --- a/usr.bin/sndiod/opt.c +++ b/usr.bin/sndiod/opt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: opt.c,v 1.10 2024/04/22 10:42:04 ratchov Exp $ */ +/* $OpenBSD: opt.c,v 1.11 2024/05/24 15:16:09 ratchov Exp $ */ /* * Copyright (c) 2008-2011 Alexandre Ratchov * @@ -351,7 +351,7 @@ opt_init(struct opt *o) if (strcmp(o->name, o->dev->name) != 0) { for (d = dev_list; d != NULL; d = d->next) { ctl_new(CTL_OPT_DEV, o, d, - CTL_SEL, o->name, "server", -1, "device", + CTL_SEL, "", o->name, "server", -1, "device", d->name, -1, 1, o->dev == d); } } diff --git a/usr.bin/sndiod/sock.c b/usr.bin/sndiod/sock.c index 7b2fe5d162e..86a78cb67e8 100644 --- a/usr.bin/sndiod/sock.c +++ b/usr.bin/sndiod/sock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.c,v 1.48 2024/05/24 15:03:12 ratchov Exp $ */ +/* $OpenBSD: sock.c,v 1.49 2024/05/24 15:16:09 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -1284,6 +1284,7 @@ sock_execmsg(struct sock *f) dev_midi_vol(s->opt->dev, s); ctl_onval(CTL_SLOT_LEVEL, s, NULL, ctl); break; + case AMSG_CTLSUB_OLD: case AMSG_CTLSUB: #ifdef DEBUG if (log_level >= 3) { @@ -1316,6 +1317,9 @@ sock_execmsg(struct sock *f) } f->ctlops |= SOCK_CTLDESC; f->ctlsyncpending = 1; + f->ctl_desc_size = (cmd == AMSG_CTLSUB) ? + sizeof(struct amsg_ctl_desc) : + AMSG_OLD_DESC_SIZE; } } else f->ctlops &= ~SOCK_CTLDESC; @@ -1613,7 +1617,7 @@ sock_buildmsg(struct sock *f) pc = &c->next; continue; } - if (size + sizeof(struct amsg_ctl_desc) > SOCK_CTLDESC_SIZE) + if (size + f->ctl_desc_size > SOCK_CTLDESC_SIZE) break; desc = (struct amsg_ctl_desc *)(f->ctldesc + size); c->desc_mask &= ~mask; @@ -1632,7 +1636,14 @@ sock_buildmsg(struct sock *f) desc->addr = htons(c->addr); desc->maxval = htons(c->maxval); desc->curval = htons(c->curval); - size += sizeof(struct amsg_ctl_desc); + + /* old clients don't have the 'display' member */ + if (f->ctl_desc_size >= offsetof(struct amsg_ctl_desc, + display) + AMSG_CTL_DISPLAYMAX) { + strlcpy(desc->display, c->display, AMSG_CTL_DISPLAYMAX); + } + + size += f->ctl_desc_size; /* if this is a deleted entry unref it */ if (type == CTL_NONE) { diff --git a/usr.bin/sndiod/sock.h b/usr.bin/sndiod/sock.h index 682be1dfcf8..6fee8aa0cd7 100644 --- a/usr.bin/sndiod/sock.h +++ b/usr.bin/sndiod/sock.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.h,v 1.8 2024/05/24 15:03:12 ratchov Exp $ */ +/* $OpenBSD: sock.h,v 1.9 2024/05/24 15:16:09 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -60,6 +60,7 @@ struct sock { struct port *port; /* midi port */ struct ctlslot *ctlslot; unsigned char *ctldesc; /* temporary buffer */ + size_t ctl_desc_size; /* size of client amsg_ctl_desc */ #define SOCK_CTLDESC 1 /* dump desc and send changes */ #define SOCK_CTLVAL 2 /* send value changes */ unsigned int ctlops; /* bitmap of above */ -- 2.20.1