Add SIOCTL_SEL control type

This commit is contained in:
Alexandre Ratchov 2020-06-16 07:16:26 +02:00
parent 9bfc9cf713
commit 14b0682012
5 changed files with 52 additions and 14 deletions

View File

@ -127,6 +127,7 @@ struct sioctl_desc {
#define SIOCTL_SW 3 /* on/off switch (0 or 1) */ #define SIOCTL_SW 3 /* on/off switch (0 or 1) */
#define SIOCTL_VEC 4 /* number, element of vector */ #define SIOCTL_VEC 4 /* number, element of vector */
#define SIOCTL_LIST 5 /* switch, element of a list */ #define SIOCTL_LIST 5 /* switch, element of a list */
#define SIOCTL_SEL 6 /* element of a selector */
unsigned int type; /* one of above */ unsigned int type; /* one of above */
char func[SIOCTL_NAMEMAX]; /* function name, ex. "level" */ char func[SIOCTL_NAMEMAX]; /* function name, ex. "level" */
char group[SIOCTL_NAMEMAX]; /* group this control belongs to */ char group[SIOCTL_NAMEMAX]; /* group this control belongs to */
@ -167,6 +168,10 @@ from the line input to the speaker.
An element of an array of on/off switches. An element of an array of on/off switches.
For instance the line-in position of the For instance the line-in position of the
speaker source selector. speaker source selector.
.It SIOCTL_SEL
Same as
.Va SIOCTL_LIST
but exactly one element is selected at a time.
.El .El
.Pp .Pp
The The
@ -182,9 +187,10 @@ attributes indicate the names of the controlled nodes, typically
channels of audio streams. channels of audio streams.
.Va node1 .Va node1
is meaningful for is meaningful for
.Va SIOCTL_VEC .Va SIOCTL_VEC ,
.Va SIOCTL_LIST ,
and and
.Va SIOCTL_LIST .Va SIOCTL_SEL
only. only.
.Pp .Pp
Names in the Names in the

View File

@ -108,6 +108,7 @@ struct sioctl_desc {
#define SIOCTL_SW 3 /* on/off switch (0 or 1) */ #define SIOCTL_SW 3 /* on/off switch (0 or 1) */
#define SIOCTL_VEC 4 /* number, element of vector */ #define SIOCTL_VEC 4 /* number, element of vector */
#define SIOCTL_LIST 5 /* switch, element of a list */ #define SIOCTL_LIST 5 /* switch, element of a list */
#define SIOCTL_SEL 6 /* element of a selector */
unsigned int type; /* one of above */ unsigned int type; /* one of above */
char func[SIOCTL_NAMEMAX]; /* function name, ex. "level" */ char func[SIOCTL_NAMEMAX]; /* function name, ex. "level" */
char group[SIOCTL_NAMEMAX]; /* group this control belongs to */ char group[SIOCTL_NAMEMAX]; /* group this control belongs to */

View File

@ -107,7 +107,8 @@ cmpdesc(struct sioctl_desc *d1, struct sioctl_desc *d2)
if (res != 0) if (res != 0)
return res; return res;
res = d1->node0.unit - d2->node0.unit; res = d1->node0.unit - d2->node0.unit;
if (d1->type == SIOCTL_VEC || if (d1->type == SIOCTL_SEL ||
d1->type == SIOCTL_VEC ||
d1->type == SIOCTL_LIST) { d1->type == SIOCTL_LIST) {
if (res != 0) if (res != 0)
return res; return res;
@ -297,6 +298,7 @@ ismono(struct info *g)
return 0; return 0;
} }
break; break;
case SIOCTL_SEL:
case SIOCTL_VEC: case SIOCTL_VEC:
case SIOCTL_LIST: case SIOCTL_LIST:
for (p2 = g; p2 != NULL; p2 = nextpar(p2)) { for (p2 = g; p2 != NULL; p2 = nextpar(p2)) {
@ -345,6 +347,7 @@ print_desc(struct info *p, int mono)
case SIOCTL_SW: case SIOCTL_SW:
printf("*"); printf("*");
break; break;
case SIOCTL_SEL:
case SIOCTL_VEC: case SIOCTL_VEC:
case SIOCTL_LIST: case SIOCTL_LIST:
more = 0; more = 0;
@ -358,7 +361,8 @@ print_desc(struct info *p, int mono)
if (more) if (more)
printf(","); printf(",");
print_node(&e->desc.node1, mono); print_node(&e->desc.node1, mono);
printf(":*"); if (p->desc.type != SIOCTL_SEL)
printf(":*");
more = 1; more = 1;
} }
} }
@ -394,6 +398,7 @@ print_ent(struct info *e, char *comment)
case SIOCTL_NONE: case SIOCTL_NONE:
printf("<removed>\n"); printf("<removed>\n");
break; break;
case SIOCTL_SEL:
case SIOCTL_VEC: case SIOCTL_VEC:
case SIOCTL_LIST: case SIOCTL_LIST:
print_node(&e->desc.node1, 0); print_node(&e->desc.node1, 0);
@ -422,6 +427,7 @@ print_val(struct info *p, int mono)
case SIOCTL_SW: case SIOCTL_SW:
print_num(p); print_num(p);
break; break;
case SIOCTL_SEL:
case SIOCTL_VEC: case SIOCTL_VEC:
case SIOCTL_LIST: case SIOCTL_LIST:
more = 0; more = 0;
@ -621,6 +627,9 @@ dump(void)
case SIOCTL_SW: case SIOCTL_SW:
printf("0..%d (%u)", i->desc.maxval, i->curval); printf("0..%d (%u)", i->desc.maxval, i->curval);
break; break;
case SIOCTL_SEL:
print_node(&i->desc.node1, 0);
break;
case SIOCTL_VEC: case SIOCTL_VEC:
case SIOCTL_LIST: case SIOCTL_LIST:
print_node(&i->desc.node1, 0); print_node(&i->desc.node1, 0);
@ -700,6 +709,7 @@ cmd(char *line)
npar++; npar++;
} }
break; break;
case SIOCTL_SEL:
case SIOCTL_VEC: case SIOCTL_VEC:
case SIOCTL_LIST: case SIOCTL_LIST:
for (i = g; i != NULL; i = nextpar(i)) { for (i = g; i != NULL; i = nextpar(i)) {
@ -889,17 +899,36 @@ ondesc(void *arg, struct sioctl_desc *d, int curval)
void void
onctl(void *arg, unsigned addr, unsigned val) onctl(void *arg, unsigned addr, unsigned val)
{ {
struct info *i; struct info *i, *j;
for (i = infolist; i != NULL; i = i->next) { i = infolist;
if (i->ctladdr != addr) for (;;) {
continue; if (i == NULL)
if (i->curval != val) { return;
i->curval = val; if (i->ctladdr == addr)
if (m_flag) break;
print_ent(i, "changed"); i = i->next;
}
} }
if (i->curval == val) {
print_ent(i, "eq");
return;
}
if (i->desc.type == SIOCTL_SEL) {
for (j = infolist; j != NULL; j = j->next) {
if (strcmp(i->desc.group, j->desc.group) != 0 ||
strcmp(i->desc.node0.name, j->desc.node0.name) != 0 ||
strcmp(i->desc.func, j->desc.func) != 0 ||
i->desc.node0.unit != j->desc.node0.unit)
continue;
j->curval = (i->ctladdr == j->ctladdr);
}
} else
i->curval = val;
if (m_flag)
print_ent(i, "changed");
} }
int int

View File

@ -2297,6 +2297,7 @@ ctl_log(struct ctl *c)
break; break;
case CTL_VEC: case CTL_VEC:
case CTL_LIST: case CTL_LIST:
case CTL_SEL:
ctl_node_log(&c->node1); ctl_node_log(&c->node1);
log_puts(":"); log_puts(":");
log_putu(c->curval); log_putu(c->curval);
@ -2321,7 +2322,7 @@ dev_addctl(struct dev *d, char *gstr, int type, int addr,
strlcpy(c->group, gstr, CTL_NAMEMAX); strlcpy(c->group, gstr, CTL_NAMEMAX);
strlcpy(c->node0.name, str0, CTL_NAMEMAX); strlcpy(c->node0.name, str0, CTL_NAMEMAX);
c->node0.unit = unit0; c->node0.unit = unit0;
if (c->type == CTL_VEC || c->type == CTL_LIST) { if (c->type == CTL_VEC || c->type == CTL_LIST || c->type == CTL_SEL) {
strlcpy(c->node1.name, str1, CTL_NAMEMAX); strlcpy(c->node1.name, str1, CTL_NAMEMAX);
c->node1.unit = unit1; c->node1.unit = unit1;
} else } else

View File

@ -126,6 +126,7 @@ struct ctl {
#define CTL_SW 3 /* on/off switch, only bit 7 counts */ #define CTL_SW 3 /* on/off switch, only bit 7 counts */
#define CTL_VEC 4 /* number, element of vector */ #define CTL_VEC 4 /* number, element of vector */
#define CTL_LIST 5 /* switch, element of a list */ #define CTL_LIST 5 /* switch, element of a list */
#define CTL_SEL 6 /* element of a selector */
unsigned int type; /* one of above */ unsigned int type; /* one of above */
unsigned int addr; /* control address */ unsigned int addr; /* control address */
#define CTL_NAMEMAX 16 /* max name lenght */ #define CTL_NAMEMAX 16 /* max name lenght */