version 1.44, 2021/03/03 10:19:06 |
version 1.45, 2021/11/01 14:43:25 |
|
|
unsigned int sock_sesrefs = 0; /* connections to the session */ |
unsigned int sock_sesrefs = 0; /* connections to the session */ |
uint8_t sock_sescookie[AMSG_COOKIELEN]; /* owner of the session */ |
uint8_t sock_sescookie[AMSG_COOKIELEN]; /* owner of the session */ |
|
|
|
/* |
|
* Old clients used to send dev number and opt name. This routine |
|
* finds proper opt pointer for the given device. |
|
*/ |
|
static struct opt * |
|
legacy_opt(int devnum, char *optname) |
|
{ |
|
struct dev *d; |
|
struct opt *o; |
|
|
|
d = dev_bynum(devnum); |
|
if (d == NULL) |
|
return NULL; |
|
if (strcmp(optname, "default") == 0) { |
|
for (o = opt_list; o != NULL; o = o->next) { |
|
if (strcmp(o->name, d->name) == 0) |
|
return o; |
|
} |
|
return NULL; |
|
} else { |
|
o = opt_byname(optname); |
|
return (o != NULL && o->dev == d) ? o : NULL; |
|
} |
|
} |
|
|
|
/* |
|
* If control slot is associated to a particular opt, then |
|
* remove the unused group part of the control name to make mixer |
|
* look nicer |
|
*/ |
|
static char * |
|
ctlgroup(struct sock *f, struct ctl *c) |
|
{ |
|
if (f->ctlslot->opt == NULL) |
|
return c->group; |
|
if (strcmp(c->group, f->ctlslot->opt->name) == 0) |
|
return ""; |
|
if (strcmp(c->group, f->ctlslot->opt->dev->name) == 0) |
|
return ""; |
|
return c->group; |
|
} |
|
|
void |
void |
sock_log(struct sock *f) |
sock_log(struct sock *f) |
{ |
{ |
|
|
void |
void |
sock_close(struct sock *f) |
sock_close(struct sock *f) |
{ |
{ |
struct dev *d; |
struct opt *o; |
struct sock **pf; |
struct sock **pf; |
unsigned int tags, i; |
unsigned int tags, i; |
|
|
|
|
if (f->midi) { |
if (f->midi) { |
tags = midi_tags(f->midi); |
tags = midi_tags(f->midi); |
for (i = 0; i < DEV_NMAX; i++) { |
for (i = 0; i < DEV_NMAX; i++) { |
if ((tags & (1 << i)) && (d = dev_bynum(i)) != NULL) |
if ((tags & (1 << i)) && (o = opt_bynum(i)) != NULL) |
dev_unref(d); |
opt_unref(o); |
} |
} |
midi_del(f->midi); |
midi_del(f->midi); |
f->midi = NULL; |
f->midi = NULL; |
|
|
{ |
{ |
struct amsg_hello *p = &f->rmsg.u.hello; |
struct amsg_hello *p = &f->rmsg.u.hello; |
struct port *c; |
struct port *c; |
struct dev *d; |
|
struct opt *opt; |
struct opt *opt; |
unsigned int mode; |
unsigned int mode; |
unsigned int id; |
unsigned int id; |
|
|
if (f->midi == NULL) |
if (f->midi == NULL) |
return 0; |
return 0; |
/* XXX: add 'devtype' to libsndio */ |
/* XXX: add 'devtype' to libsndio */ |
if (p->devnum < 16) { |
if (p->devnum == AMSG_NODEV) { |
d = dev_bynum(p->devnum); |
opt = opt_byname(p->opt); |
if (d == NULL) |
if (opt == NULL) |
return 0; |
return 0; |
opt = opt_byname(d, p->opt); |
if (!opt_ref(opt)) |
|
return 0; |
|
midi_tag(f->midi, opt->num); |
|
} else if (p->devnum < 16) { |
|
opt = legacy_opt(p->devnum, p->opt); |
if (opt == NULL) |
if (opt == NULL) |
return 0; |
return 0; |
if (!dev_ref(d)) |
if (!opt_ref(opt)) |
return 0; |
return 0; |
midi_tag(f->midi, opt->num); |
midi_tag(f->midi, opt->num); |
} else if (p->devnum < 32) { |
} else if (p->devnum < 32) { |
midi_tag(f->midi, p->devnum); |
midi_tag(f->midi, p->devnum); |
} else if (p->devnum < 48) { |
} else if (p->devnum < 48) { |
c = port_bynum(p->devnum - 32); |
c = port_alt_ref(p->devnum - 32); |
if (c == NULL || !port_ref(c)) |
if (c == NULL) |
return 0; |
return 0; |
f->port = c; |
f->port = c; |
midi_link(f->midi, c->midi); |
midi_link(f->midi, c->midi); |
|
|
return 1; |
return 1; |
} |
} |
if (mode & MODE_CTLMASK) { |
if (mode & MODE_CTLMASK) { |
d = dev_bynum(p->devnum); |
if (p->devnum == AMSG_NODEV) { |
if (d == NULL) { |
opt = opt_byname(p->opt); |
if (log_level >= 2) { |
if (opt == NULL) |
sock_log(f); |
return 0; |
log_puts(": "); |
} else { |
log_putu(p->devnum); |
opt = legacy_opt(p->devnum, p->opt); |
log_puts(": no such device\n"); |
if (opt == NULL) |
} |
return 0; |
return 0; |
|
} |
} |
opt = opt_byname(d, p->opt); |
|
if (opt == NULL) |
|
return 0; |
|
f->ctlslot = ctlslot_new(opt, &sock_ctlops, f); |
f->ctlslot = ctlslot_new(opt, &sock_ctlops, f); |
if (f->ctlslot == NULL) { |
if (f->ctlslot == NULL) { |
if (log_level >= 2) { |
if (log_level >= 2) { |
|
|
f->ctlsyncpending = 0; |
f->ctlsyncpending = 0; |
return 1; |
return 1; |
} |
} |
d = dev_bynum(p->devnum); |
opt = (p->devnum == AMSG_NODEV) ? |
if (d == NULL) |
opt_byname(p->opt) : legacy_opt(p->devnum, p->opt); |
return 0; |
|
opt = opt_byname(d, p->opt); |
|
if (opt == NULL) |
if (opt == NULL) |
return 0; |
return 0; |
f->slot = slot_new(opt, id, p->who, &sock_slotops, f, mode); |
f->slot = slot_new(opt, id, p->who, &sock_slotops, f, mode); |
|
|
c->val_mask &= ~mask; |
c->val_mask &= ~mask; |
type = ctlslot_visible(f->ctlslot, c) ? |
type = ctlslot_visible(f->ctlslot, c) ? |
c->type : CTL_NONE; |
c->type : CTL_NONE; |
strlcpy(desc->group, (f->ctlslot->opt == NULL || |
strlcpy(desc->group, ctlgroup(f, c), AMSG_CTL_NAMEMAX); |
strcmp(c->group, f->ctlslot->opt->dev->name) != 0) ? |
|
c->group : "", |
|
AMSG_CTL_NAMEMAX); |
|
strlcpy(desc->node0.name, c->node0.name, |
strlcpy(desc->node0.name, c->node0.name, |
AMSG_CTL_NAMEMAX); |
AMSG_CTL_NAMEMAX); |
desc->node0.unit = ntohs(c->node0.unit); |
desc->node0.unit = ntohs(c->node0.unit); |