mirror of https://github.com/ericonr/sndio.git
rename grp->func
This commit is contained in:
parent
fc071998df
commit
8468b9f0a0
|
@ -124,7 +124,7 @@ struct amsg_mix_chan {
|
||||||
struct amsg_mix_desc {
|
struct amsg_mix_desc {
|
||||||
struct amsg_mix_chan chan0; /* affected channels */
|
struct amsg_mix_chan chan0; /* affected channels */
|
||||||
struct amsg_mix_chan chan1; /* dito for AMSG_MIX_{SEL,VEC,LIST} */
|
struct amsg_mix_chan chan1; /* dito for AMSG_MIX_{SEL,VEC,LIST} */
|
||||||
char grp[AMSG_MIX_NAMEMAX]; /* parameter group name */
|
char func[AMSG_MIX_NAMEMAX]; /* parameter group name */
|
||||||
uint8_t type; /* see siomix_desc structure */
|
uint8_t type; /* see siomix_desc structure */
|
||||||
uint8_t __pad[1];
|
uint8_t __pad[1];
|
||||||
uint16_t addr; /* control address */
|
uint16_t addr; /* control address */
|
||||||
|
|
|
@ -175,7 +175,7 @@ _siomix_ondesc_cb(struct siomix_hdl *hdl,
|
||||||
DPRINTF("%u -> %s[%s].%s=%s[%s]\n",
|
DPRINTF("%u -> %s[%s].%s=%s[%s]\n",
|
||||||
desc->addr,
|
desc->addr,
|
||||||
desc->chan0.str, desc->chan0.opt,
|
desc->chan0.str, desc->chan0.opt,
|
||||||
desc->grp,
|
desc->func,
|
||||||
desc->chan1.str, desc->chan1.opt);
|
desc->chan1.str, desc->chan1.opt);
|
||||||
}
|
}
|
||||||
if (hdl->desc_cb)
|
if (hdl->desc_cb)
|
||||||
|
|
|
@ -78,7 +78,7 @@ siomix_aucat_rdata(struct siomix_aucat_hdl *hdl)
|
||||||
strlcpy(desc.chan0.opt, c->chan0.opt, SIOMIX_NAMEMAX);
|
strlcpy(desc.chan0.opt, c->chan0.opt, SIOMIX_NAMEMAX);
|
||||||
strlcpy(desc.chan1.str, c->chan1.str, SIOMIX_NAMEMAX);
|
strlcpy(desc.chan1.str, c->chan1.str, SIOMIX_NAMEMAX);
|
||||||
strlcpy(desc.chan1.opt, c->chan1.opt, SIOMIX_NAMEMAX);
|
strlcpy(desc.chan1.opt, c->chan1.opt, SIOMIX_NAMEMAX);
|
||||||
strlcpy(desc.grp, c->grp, SIOMIX_NAMEMAX);
|
strlcpy(desc.func, c->func, SIOMIX_NAMEMAX);
|
||||||
desc.type = c->type;
|
desc.type = c->type;
|
||||||
desc.addr = ntohs(c->addr);
|
desc.addr = ntohs(c->addr);
|
||||||
_siomix_ondesc_cb(&hdl->siomix, &desc, ntohs(c->curval));
|
_siomix_ondesc_cb(&hdl->siomix, &desc, ntohs(c->curval));
|
||||||
|
|
|
@ -129,7 +129,7 @@ struct siomix_desc {
|
||||||
#define SIOMIX_LIST 5 /* element of array of switches */
|
#define SIOMIX_LIST 5 /* element of array of switches */
|
||||||
#define SIOMIX_LABEL 6 /* string attached to chan0 */
|
#define SIOMIX_LABEL 6 /* string attached to chan0 */
|
||||||
unsigned int type; /* one of above */
|
unsigned int type; /* one of above */
|
||||||
char grp[SIOMIX_NAMEMAX]; /* parameter group name */
|
char func[SIOMIX_NAMEMAX]; /* parameter group name */
|
||||||
struct siomix_chan chan0; /* affected channels */
|
struct siomix_chan chan0; /* affected channels */
|
||||||
struct siomix_chan chan1; /* dito for vec, and list */
|
struct siomix_chan chan1; /* dito for vec, and list */
|
||||||
};
|
};
|
||||||
|
@ -175,7 +175,7 @@ label is changing.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Va grp
|
.Va func
|
||||||
attribute is the name of the parameter being controlled.
|
attribute is the name of the parameter being controlled.
|
||||||
There may be no parameters of different types with the same name.
|
There may be no parameters of different types with the same name.
|
||||||
.Pp
|
.Pp
|
||||||
|
@ -197,7 +197,7 @@ Stream names in the
|
||||||
and
|
and
|
||||||
.Va chan1
|
.Va chan1
|
||||||
attributes and
|
attributes and
|
||||||
.Va grp
|
.Va func
|
||||||
are static strings usable as unique identifiers.
|
are static strings usable as unique identifiers.
|
||||||
.Sh Changing and reading control values
|
.Sh Changing and reading control values
|
||||||
Controls are changed with the
|
Controls are changed with the
|
||||||
|
|
|
@ -261,7 +261,7 @@ copyname_num(struct siomix_sun_hdl *hdl,
|
||||||
|
|
||||||
sep = strchr(info->label.name, '_');
|
sep = strchr(info->label.name, '_');
|
||||||
if (sep) {
|
if (sep) {
|
||||||
strlcpy(desc->grp, "mix", SIOMIX_NAMEMAX);
|
strlcpy(desc->func, "mix", SIOMIX_NAMEMAX);
|
||||||
desc->type = SIOMIX_VEC;
|
desc->type = SIOMIX_VEC;
|
||||||
len = sep - info->label.name;
|
len = sep - info->label.name;
|
||||||
if (len >= SIOMIX_NAMEMAX - 1)
|
if (len >= SIOMIX_NAMEMAX - 1)
|
||||||
|
@ -273,7 +273,7 @@ copyname_num(struct siomix_sun_hdl *hdl,
|
||||||
desc->chan1.str, rmin, rnum))
|
desc->chan1.str, rmin, rnum))
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
strlcpy(desc->grp, "level", SIOMIX_NAMEMAX);
|
strlcpy(desc->func, "level", SIOMIX_NAMEMAX);
|
||||||
desc->type = SIOMIX_NUM;
|
desc->type = SIOMIX_NUM;
|
||||||
istr = info->label.name;
|
istr = info->label.name;
|
||||||
if (!copy_ch(hdl, info->mixer_class, istr,
|
if (!copy_ch(hdl, info->mixer_class, istr,
|
||||||
|
@ -299,7 +299,7 @@ copyname_enum(struct siomix_sun_hdl *hdl,
|
||||||
fprintf(stderr, "no separator\n");
|
fprintf(stderr, "no separator\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
strlcpy(desc->grp, info->label.name, SIOMIX_NAMEMAX);
|
strlcpy(desc->func, info->label.name, SIOMIX_NAMEMAX);
|
||||||
while (info->prev >= 0)
|
while (info->prev >= 0)
|
||||||
info = hdl->info + info->prev;
|
info = hdl->info + info->prev;
|
||||||
if (!copy_ch(hdl, info->mixer_class, info->label.name,
|
if (!copy_ch(hdl, info->mixer_class, info->label.name,
|
||||||
|
@ -307,7 +307,7 @@ copyname_enum(struct siomix_sun_hdl *hdl,
|
||||||
return 0;
|
return 0;
|
||||||
desc->chan1.str[0] = 0;
|
desc->chan1.str[0] = 0;
|
||||||
} else {
|
} else {
|
||||||
strlcpy(desc->grp, sep + 1, SIOMIX_NAMEMAX);
|
strlcpy(desc->func, sep + 1, SIOMIX_NAMEMAX);
|
||||||
len = sep - info->label.name;
|
len = sep - info->label.name;
|
||||||
if (len >= SIOMIX_NAMEMAX - 1)
|
if (len >= SIOMIX_NAMEMAX - 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -322,9 +322,9 @@ copyname_enum(struct siomix_sun_hdl *hdl,
|
||||||
* certain cards expose adc[0-1].source and adc[2-3].source
|
* certain cards expose adc[0-1].source and adc[2-3].source
|
||||||
* as different types, which we forbid.
|
* as different types, which we forbid.
|
||||||
*/
|
*/
|
||||||
if (strcmp(desc->grp, "source") == 0) {
|
if (strcmp(desc->func, "source") == 0) {
|
||||||
if (info->type == AUDIO_MIXER_SET)
|
if (info->type == AUDIO_MIXER_SET)
|
||||||
strlcpy(desc->grp, "sources", SIOMIX_NAMEMAX);
|
strlcpy(desc->func, "sources", SIOMIX_NAMEMAX);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ enum_to_sw(struct mixer_devinfo *info, struct siomix_desc *desc)
|
||||||
if (strcmp(v0, "off") == 0 && strcmp(v1, "on") == 0)
|
if (strcmp(v0, "off") == 0 && strcmp(v1, "on") == 0)
|
||||||
goto make_sw;
|
goto make_sw;
|
||||||
if (strcmp(v0, "unplugged") == 0 && strcmp(v1, "plugged") == 0) {
|
if (strcmp(v0, "unplugged") == 0 && strcmp(v1, "plugged") == 0) {
|
||||||
strlcpy(desc->grp,
|
strlcpy(desc->func,
|
||||||
info->un.e.member[1].label.name,
|
info->un.e.member[1].label.name,
|
||||||
SIOMIX_NAMEMAX);
|
SIOMIX_NAMEMAX);
|
||||||
goto make_sw;
|
goto make_sw;
|
||||||
|
|
|
@ -112,7 +112,7 @@ struct siomix_desc {
|
||||||
#define SIOMIX_LIST 5 /* switch, element of a list */
|
#define SIOMIX_LIST 5 /* switch, element of a list */
|
||||||
#define SIOMIX_LABEL 6 /* label attached to chan0 */
|
#define SIOMIX_LABEL 6 /* label attached to chan0 */
|
||||||
unsigned int type; /* one of above */
|
unsigned int type; /* one of above */
|
||||||
char grp[SIOMIX_NAMEMAX]; /* parameter name or label */
|
char func[SIOMIX_NAMEMAX]; /* function name or label */
|
||||||
struct siomix_chan chan0; /* affected channels */
|
struct siomix_chan chan0; /* affected channels */
|
||||||
struct siomix_chan chan1; /* dito for SIOMIX_{VEC,LIST} */
|
struct siomix_chan chan1; /* dito for SIOMIX_{VEC,LIST} */
|
||||||
};
|
};
|
||||||
|
|
|
@ -85,7 +85,7 @@ cmpdesc(struct siomix_desc *d1, struct siomix_desc *d2)
|
||||||
res = d1->type - d2->type;
|
res = d1->type - d2->type;
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
return res;
|
return res;
|
||||||
res = strcmp(d1->grp, d2->grp);
|
res = strcmp(d1->func, d2->func);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
return res;
|
return res;
|
||||||
res = strcmp(d1->chan0.opt, d2->chan0.opt);
|
res = strcmp(d1->chan0.opt, d2->chan0.opt);
|
||||||
|
@ -149,13 +149,13 @@ vecent(struct info *i, char *vstr, char *vopt)
|
||||||
struct info *
|
struct info *
|
||||||
nextgrp(struct info *i)
|
nextgrp(struct info *i)
|
||||||
{
|
{
|
||||||
char *str, *grp;
|
char *str, *func;
|
||||||
|
|
||||||
grp = i->desc.grp;
|
func = i->desc.func;
|
||||||
str = i->desc.chan0.str;
|
str = i->desc.chan0.str;
|
||||||
for (i = i->next; i != NULL; i = i->next) {
|
for (i = i->next; i != NULL; i = i->next) {
|
||||||
if (strcmp(i->desc.chan0.str, str) != 0 ||
|
if (strcmp(i->desc.chan0.str, str) != 0 ||
|
||||||
strcmp(i->desc.grp, grp) != 0)
|
strcmp(i->desc.func, func) != 0)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -167,14 +167,14 @@ nextgrp(struct info *i)
|
||||||
struct info *
|
struct info *
|
||||||
nextpar(struct info *i)
|
nextpar(struct info *i)
|
||||||
{
|
{
|
||||||
char *str, *opt, *grp;
|
char *str, *opt, *func;
|
||||||
|
|
||||||
grp = i->desc.grp;
|
func = i->desc.func;
|
||||||
str = i->desc.chan0.str;
|
str = i->desc.chan0.str;
|
||||||
opt = i->desc.chan0.opt;
|
opt = i->desc.chan0.opt;
|
||||||
for (i = i->next; i != NULL; i = i->next) {
|
for (i = i->next; i != NULL; i = i->next) {
|
||||||
if (strcmp(i->desc.chan0.str, str) != 0 ||
|
if (strcmp(i->desc.chan0.str, str) != 0 ||
|
||||||
strcmp(i->desc.grp, grp) != 0)
|
strcmp(i->desc.func, func) != 0)
|
||||||
break;
|
break;
|
||||||
if (strcmp(i->desc.chan0.opt, opt) != 0)
|
if (strcmp(i->desc.chan0.opt, opt) != 0)
|
||||||
return i;
|
return i;
|
||||||
|
@ -188,14 +188,14 @@ nextpar(struct info *i)
|
||||||
struct info *
|
struct info *
|
||||||
firstent(struct info *g, char *vstr)
|
firstent(struct info *g, char *vstr)
|
||||||
{
|
{
|
||||||
char *astr, *grp;
|
char *astr, *func;
|
||||||
struct info *i;
|
struct info *i;
|
||||||
|
|
||||||
astr = g->desc.chan0.str;
|
astr = g->desc.chan0.str;
|
||||||
grp = g->desc.grp;
|
func = g->desc.func;
|
||||||
for (i = g; i != NULL; i = i->next) {
|
for (i = g; i != NULL; i = i->next) {
|
||||||
if (strcmp(i->desc.chan0.str, astr) != 0 ||
|
if (strcmp(i->desc.chan0.str, astr) != 0 ||
|
||||||
strcmp(i->desc.grp, grp) != 0)
|
strcmp(i->desc.func, func) != 0)
|
||||||
break;
|
break;
|
||||||
if (!isdiag(i))
|
if (!isdiag(i))
|
||||||
continue;
|
continue;
|
||||||
|
@ -213,14 +213,14 @@ firstent(struct info *g, char *vstr)
|
||||||
struct info *
|
struct info *
|
||||||
nextent(struct info *i, int mono)
|
nextent(struct info *i, int mono)
|
||||||
{
|
{
|
||||||
char *str, *opt, *grp;
|
char *str, *opt, *func;
|
||||||
|
|
||||||
grp = i->desc.grp;
|
func = i->desc.func;
|
||||||
str = i->desc.chan0.str;
|
str = i->desc.chan0.str;
|
||||||
opt = i->desc.chan0.opt;
|
opt = i->desc.chan0.opt;
|
||||||
for (i = i->next; i != NULL; i = i->next) {
|
for (i = i->next; i != NULL; i = i->next) {
|
||||||
if (strcmp(i->desc.chan0.str, str) != 0 ||
|
if (strcmp(i->desc.chan0.str, str) != 0 ||
|
||||||
strcmp(i->desc.grp, grp) != 0)
|
strcmp(i->desc.func, func) != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (mono)
|
if (mono)
|
||||||
return i;
|
return i;
|
||||||
|
@ -401,7 +401,7 @@ print_par(struct info *p, int mono)
|
||||||
int more;
|
int more;
|
||||||
|
|
||||||
print_chan(&p->desc.chan0, mono);
|
print_chan(&p->desc.chan0, mono);
|
||||||
printf(".%s=", p->desc.grp);
|
printf(".%s=", p->desc.func);
|
||||||
if (i_flag)
|
if (i_flag)
|
||||||
print_desc(p, mono);
|
print_desc(p, mono);
|
||||||
else
|
else
|
||||||
|
@ -419,7 +419,7 @@ print_par(struct info *p, int mono)
|
||||||
printf("\t#");
|
printf("\t#");
|
||||||
more = 1;
|
more = 1;
|
||||||
}
|
}
|
||||||
printf(" %s=%s", i->desc.grp, i->desc.chan1.str);
|
printf(" %s=%s", i->desc.func, i->desc.chan1.str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -551,7 +551,7 @@ dump(void)
|
||||||
for (i = infolist; i != NULL; i = i->next) {
|
for (i = infolist; i != NULL; i = i->next) {
|
||||||
printf("%03u:", i->ctladdr);
|
printf("%03u:", i->ctladdr);
|
||||||
print_chan(&i->desc.chan0, 0);
|
print_chan(&i->desc.chan0, 0);
|
||||||
printf(".%s", i->desc.grp);
|
printf(".%s", i->desc.func);
|
||||||
printf("=");
|
printf("=");
|
||||||
switch (i->desc.type) {
|
switch (i->desc.type) {
|
||||||
case SIOMIX_LABEL:
|
case SIOMIX_LABEL:
|
||||||
|
@ -578,7 +578,7 @@ cmd(char *line)
|
||||||
{
|
{
|
||||||
char *pos = line;
|
char *pos = line;
|
||||||
struct info *i, *e, *g;
|
struct info *i, *e, *g;
|
||||||
char grp[SIOMIX_NAMEMAX], astr[SIOMIX_NAMEMAX], vstr[SIOMIX_NAMEMAX];
|
char func[SIOMIX_NAMEMAX], astr[SIOMIX_NAMEMAX], vstr[SIOMIX_NAMEMAX];
|
||||||
char aopt[SIOMIX_NAMEMAX], vopt[SIOMIX_NAMEMAX];
|
char aopt[SIOMIX_NAMEMAX], vopt[SIOMIX_NAMEMAX];
|
||||||
unsigned val, npar = 0, nent = 0;
|
unsigned val, npar = 0, nent = 0;
|
||||||
int comma, mode;
|
int comma, mode;
|
||||||
|
@ -590,14 +590,14 @@ cmd(char *line)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pos++;
|
pos++;
|
||||||
if (!parse_name(&pos, grp))
|
if (!parse_name(&pos, func))
|
||||||
return 0;
|
return 0;
|
||||||
for (g = infolist;; g = g->next) {
|
for (g = infolist;; g = g->next) {
|
||||||
if (g == NULL) {
|
if (g == NULL) {
|
||||||
fprintf(stderr, "%s.%s: no such group\n", astr, grp);
|
fprintf(stderr, "%s.%s: no such group\n", astr, func);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strcmp(g->desc.grp, grp) == 0 &&
|
if (strcmp(g->desc.func, func) == 0 &&
|
||||||
strcmp(g->desc.chan0.str, astr) == 0)
|
strcmp(g->desc.chan0.str, astr) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2042,7 +2042,7 @@ ctl_log(struct ctl *c)
|
||||||
{
|
{
|
||||||
ctl_chan_log(&c->chan0);
|
ctl_chan_log(&c->chan0);
|
||||||
log_puts(".");
|
log_puts(".");
|
||||||
log_puts(c->grp);
|
log_puts(c->func);
|
||||||
log_puts("=");
|
log_puts("=");
|
||||||
switch (c->type) {
|
switch (c->type) {
|
||||||
case CTL_NUM:
|
case CTL_NUM:
|
||||||
|
@ -2090,13 +2090,13 @@ dev_uniqname(struct dev *d, char *templ, char *name)
|
||||||
*/
|
*/
|
||||||
struct ctl *
|
struct ctl *
|
||||||
dev_addctl(struct dev *d, int type, int addr,
|
dev_addctl(struct dev *d, int type, int addr,
|
||||||
char *str0, char *opt0, char *grp, char *str1, char *opt1)
|
char *str0, char *opt0, char *func, char *str1, char *opt1)
|
||||||
{
|
{
|
||||||
struct ctl *c;
|
struct ctl *c;
|
||||||
|
|
||||||
c = xmalloc(sizeof(struct ctl));
|
c = xmalloc(sizeof(struct ctl));
|
||||||
c->type = type;
|
c->type = type;
|
||||||
strlcpy(c->grp, grp, CTL_NAMEMAX);
|
strlcpy(c->func, func, CTL_NAMEMAX);
|
||||||
strlcpy(c->chan0.str, str0, CTL_NAMEMAX);
|
strlcpy(c->chan0.str, str0, CTL_NAMEMAX);
|
||||||
strlcpy(c->chan0.opt, opt0, CTL_NAMEMAX);
|
strlcpy(c->chan0.opt, opt0, CTL_NAMEMAX);
|
||||||
if (c->type == CTL_VEC ||
|
if (c->type == CTL_VEC ||
|
||||||
|
|
|
@ -114,7 +114,7 @@ struct ctl {
|
||||||
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 */
|
||||||
char grp[CTL_NAMEMAX]; /* parameter group name */
|
char func[CTL_NAMEMAX]; /* parameter group name */
|
||||||
struct ctl_chan {
|
struct ctl_chan {
|
||||||
char str[CTL_NAMEMAX]; /* stream name */
|
char str[CTL_NAMEMAX]; /* stream name */
|
||||||
char opt[CTL_NAMEMAX];
|
char opt[CTL_NAMEMAX];
|
||||||
|
|
|
@ -71,7 +71,7 @@ dev_siomix_ondesc(void *arg, struct siomix_desc *desc, int val)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c = dev_addctl(d, desc->type, desc->addr,
|
c = dev_addctl(d, desc->type, desc->addr,
|
||||||
desc->chan0.str, desc->chan0.opt, desc->grp,
|
desc->chan0.str, desc->chan0.opt, desc->func,
|
||||||
desc->chan1.str, desc->chan1.opt);
|
desc->chan1.str, desc->chan1.opt);
|
||||||
c->curval = val;
|
c->curval = val;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -1560,7 +1560,7 @@ sock_buildmsg(struct sock *f)
|
||||||
strlcpy(desc->chan1.opt, c->chan1.opt,
|
strlcpy(desc->chan1.opt, c->chan1.opt,
|
||||||
AMSG_MIX_NAMEMAX);
|
AMSG_MIX_NAMEMAX);
|
||||||
desc->type = c->type;
|
desc->type = c->type;
|
||||||
strlcpy(desc->grp, c->grp, AMSG_MIX_NAMEMAX);
|
strlcpy(desc->func, c->func, AMSG_MIX_NAMEMAX);
|
||||||
desc->addr = htons(c->addr);
|
desc->addr = htons(c->addr);
|
||||||
desc->curval = htons(c->curval);
|
desc->curval = htons(c->curval);
|
||||||
desc++;
|
desc++;
|
||||||
|
|
|
@ -66,7 +66,7 @@ mixer_ondesc(void *unused, struct siomix_desc *desc, int val)
|
||||||
if (master_found)
|
if (master_found)
|
||||||
return;
|
return;
|
||||||
if (strcmp(desc->chan0.str, "sndiod0") == 0 &&
|
if (strcmp(desc->chan0.str, "sndiod0") == 0 &&
|
||||||
strcmp(desc->grp, "level") == 0) {
|
strcmp(desc->func, "level") == 0) {
|
||||||
master_found = 1;
|
master_found = 1;
|
||||||
master_addr = desc->addr;
|
master_addr = desc->addr;
|
||||||
master_val = val;
|
master_val = val;
|
||||||
|
|
Loading…
Reference in New Issue