diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index b30d7d5ba86c0d3bf9316298b12e5152fd2725b0..47b5ebfcd446dca1ebdeea6dff22508db1ee8c5b 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -155,10 +155,20 @@ t_canvasenvironment *canvas_getenv(t_canvas *x) return (x->gl_env); } -int canvas_getdollarzero( void) +extern t_class *messresponder_class; +extern t_glist *messresponder_getglist(t_pd *x); + +int canvas_getdollarzero(t_pd *x) { - t_canvas *x = canvas_getcurrent(); - t_canvasenvironment *env = (x ? canvas_getenv(x) : 0); + t_canvas *cnv; + /* binbuf_eval can send us a NULL target... */ + if (x && pd_class(x) == messresponder_class) + { + cnv = messresponder_getglist(x); + } + else + cnv = canvas_getcurrent(); + t_canvasenvironment *env = (cnv ? canvas_getenv(cnv) : 0); if (env) return (env->ce_dollarzero); else return (0); diff --git a/pd/src/g_text.c b/pd/src/g_text.c index 52c0f02c601476f0cc2c5f928ade08e6b76f5147..7c7fc16022f73d242a06c80c821e6952e01c4aa3 100644 --- a/pd/src/g_text.c +++ b/pd/src/g_text.c @@ -550,6 +550,7 @@ void canvas_objfor(t_glist *gl, t_text *x, int argc, t_atom *argv) typedef struct _messresponder { t_pd mr_pd; + t_glist *mr_glist; t_outlet *mr_outlet; } t_messresponder; @@ -561,7 +562,7 @@ typedef struct _message t_clock *m_clock; } t_message; -static t_class *messresponder_class; +t_class *messresponder_class; static void messresponder_bang(t_messresponder *x) { @@ -596,13 +597,17 @@ static void messresponder_anything(t_messresponder *x, outlet_anything(x->mr_outlet, s, argc, argv); } +/* get the glist cached in a message responder */ +t_glist *messresponder_getglist(t_pd *x) +{ + return ((t_messresponder *)x)->mr_glist; +} + static void message_bang(t_message *x) { /* we do canvas_setcurrent/unsetcurrent to substitute canvas instance number for $0 */ - canvas_setcurrent((t_canvas *)x->m_glist); binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 0, 0); - canvas_unsetcurrent((t_canvas *)x->m_glist); } static void message_float(t_message *x, t_float f) @@ -611,9 +616,7 @@ static void message_float(t_message *x, t_float f) SETFLOAT(&at, f); /* we do canvas_setcurrent/unsetcurrent to substitute canvas instance number for $0 */ - canvas_setcurrent((t_canvas *)x->m_glist); binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at); - canvas_unsetcurrent((t_canvas *)x->m_glist); } static void message_symbol(t_message *x, t_symbol *s) @@ -622,9 +625,7 @@ static void message_symbol(t_message *x, t_symbol *s) SETSYMBOL(&at, s); /* we do canvas_setcurrent/unsetcurrent to substitute canvas instance number for $0 */ - canvas_setcurrent((t_canvas *)x->m_glist); binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at); - canvas_unsetcurrent((t_canvas *)x->m_glist); } static void message_blob(t_message *x, t_blob *st) @@ -633,9 +634,7 @@ static void message_blob(t_message *x, t_blob *st) SETBLOB(&at, st); /* we do canvas_setcurrent/unsetcurrent to substitute canvas instance number for $0 */ - canvas_setcurrent((t_canvas *)x->m_glist); binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at); - canvas_unsetcurrent((t_canvas *)x->m_glist); } static void message_list(t_message *x, t_symbol *s, int argc, t_atom *argv) @@ -645,9 +644,7 @@ static void message_list(t_message *x, t_symbol *s, int argc, t_atom *argv) // but will this break anything? /* we do canvas_setcurrent/unsetcurrent to substitute canvas instance number for $0 */ - canvas_setcurrent((t_canvas *)x->m_glist); binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, argc, argv); - canvas_unsetcurrent(x->m_glist); } static void message_set(t_message *x, t_symbol *s, int argc, t_atom *argv) @@ -779,6 +776,7 @@ void canvas_msg(t_glist *gl, t_symbol *s, int argc, t_atom *argv) t_message *x = (t_message *)pd_new(message_class); x->m_messresponder.mr_pd = messresponder_class; x->m_messresponder.mr_outlet = outlet_new(&x->m_text, &s_float); + x->m_messresponder.mr_glist = gl; x->m_text.te_width = 0; /* don't know it yet. */ x->m_text.te_type = T_MESSAGE; x->m_text.te_iemgui = 0; diff --git a/pd/src/m_binbuf.c b/pd/src/m_binbuf.c index 1b96e33d3ac05fecf798498b3277e80ce47a104c..69922d50eedbd3cb9e1c903083534ce05d071869 100644 --- a/pd/src/m_binbuf.c +++ b/pd/src/m_binbuf.c @@ -549,7 +549,7 @@ int binbuf_resize(t_binbuf *x, int newsize) return (new != 0); } -int canvas_getdollarzero( void); +int canvas_getdollarzero(t_pd *x); /* JMZ: * s points to the first character after the $ @@ -602,7 +602,8 @@ int binbuf_expanddollsym(char*s, char*buf,t_atom dollar0, int ac, t_atom *av, /* LATER remove the dependence on the current canvas for $0; should be another argument. */ -t_symbol *binbuf_realizedollsym(t_symbol *s, int ac, t_atom *av, int tonew) +static t_symbol *binbuf_dorealizedollsym(t_pd *target, t_symbol *s, int ac, + t_atom *av, int tonew) { char buf[MAXPDSTRING]; char buf2[MAXPDSTRING]; @@ -610,7 +611,7 @@ t_symbol *binbuf_realizedollsym(t_symbol *s, int ac, t_atom *av, int tonew) char*substr; int next=0, i=MAXPDSTRING; t_atom dollarnull; - SETFLOAT(&dollarnull, canvas_getdollarzero()); + SETFLOAT(&dollarnull, canvas_getdollarzero(target)); while(i--)buf2[i]=0; #if 1 @@ -637,7 +638,7 @@ t_symbol *binbuf_realizedollsym(t_symbol *s, int ac, t_atom *av, int tonew) * JMZ: i am not sure what this means, so i might have broken it * it seems like that if "tonew" is set and the $arg cannot be expanded * (or the dollarsym is in reality a A_DOLLAR) - * 0 is returned from binbuf_realizedollsym + * 0 is returned from binbuf_dorealizedollsym * this happens, when expanding in a message-box, but does not happen * when the A_DOLLSYM is the name of a subpatch */ @@ -664,6 +665,11 @@ done: return (gensym(buf2)); } +t_symbol *binbuf_realizedollsym(t_symbol *s, int ac, t_atom *av, int tonew) +{ + return binbuf_dorealizedollsym(0, s, ac, av, tonew); +} + #define SMALLMSG 5 #define HUGEMSG 1000 #ifdef MSW @@ -681,12 +687,28 @@ done: #define ATOMS_FREEA(x, n) (freebytes((x), (n) * sizeof(t_atom))) #endif +t_pd *pd_mess_from_responder(t_pd *x); +static void binbuf_error(t_pd *x, const char *fmt, ...) +{ + char buf[MAXPDSTRING]; + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, MAXPDSTRING-1, fmt, ap); + va_end(ap); + if (x) + pd_error(pd_mess_from_responder(x), buf); + else + error(buf); +} + void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv) { t_atom smallstack[SMALLMSG], *mstack, *msp; t_atom *at = x->b_vec; int ac = x->b_n; int nargs, maxnargs = 0; + /* initial target for referencing $0 in msg boxes after a semicolon */ + t_pd * init_target = target; //first we need to check if the list of arguments has $@ //fprintf(stderr,"=========\nbinbuf_eval argc:%d ac:%d\n", argc, (int)ac); @@ -769,13 +791,18 @@ void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv) /* would it make sense to consider $@ here? */ if (at->a_w.w_index <= 0 || at->a_w.w_index > argc) { - error("$%d: not enough arguments supplied", - at->a_w.w_index); + binbuf_error(init_target, + "$%d: %s", + at->a_w.w_index, + (at->a_w.w_index == 0 ? + "symbol needed as message destination" : + "not enough arguments supplied")); goto cleanup; } else if (argv[at->a_w.w_index-1].a_type != A_SYMBOL) { - error("$%d: symbol needed as message destination", + binbuf_error(init_target, + "$%d: symbol needed as message destination", at->a_w.w_index); goto cleanup; } @@ -783,10 +810,11 @@ void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv) } else if (at->a_type == A_DOLLSYM) { - if (!(s = binbuf_realizedollsym(at->a_w.w_symbol, + if (!(s = binbuf_dorealizedollsym(init_target, at->a_w.w_symbol, argc, argv, 0))) { - error("$%s: not enough arguments supplied", + binbuf_error(init_target, + "$%s: not enough arguments supplied", at->a_w.w_symbol->s_name); goto cleanup; } @@ -794,7 +822,8 @@ void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv) else s = atom_getsymbol(at); if (!(target = s->s_thing)) { - error("%s: no such object", s->s_name); + binbuf_error(init_target, + "%s: no such object", s->s_name); cleanup: do at++, ac--; while (ac && at->a_type != A_SEMI); @@ -865,25 +894,27 @@ void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv) else if (at->a_w.w_index > 0 && at->a_w.w_index <= argc) *msp = argv[at->a_w.w_index-1]; else if (at->a_w.w_index == 0) - SETFLOAT(msp, canvas_getdollarzero()); + SETFLOAT(msp, canvas_getdollarzero(init_target)); else { if (target == &pd_objectmaker) SETFLOAT(msp, 0); else { - error("$%d: argument number out of range", + binbuf_error(init_target, + "$%d: argument number out of range", at->a_w.w_index); SETFLOAT(msp, 0); } } break; case A_DOLLSYM: - s9 = binbuf_realizedollsym(at->a_w.w_symbol, argc, argv, - target == &pd_objectmaker); + s9 = binbuf_dorealizedollsym(init_target, at->a_w.w_symbol, + argc, argv, target == &pd_objectmaker); if (!s9) { - error("%s: argument number out of range", + binbuf_error(init_target, + "%s: argument number out of range", at->a_w.w_symbol->s_name); SETSYMBOL(msp, at->a_w.w_symbol); } diff --git a/pd/src/x_text.c b/pd/src/x_text.c index f8e1a9b3fdab096dde5125b32348190e1eb11b80..4c2f99f63aff4b13a9dd7178e328605edd5343ef 100644 --- a/pd/src/x_text.c +++ b/pd/src/x_text.c @@ -1355,7 +1355,7 @@ static void text_sequence_doit(t_text_sequence *x, int argc, t_atom *argv) if (i >= n) i = 0x7fffffff; x->x_onset = i; - /* generate output list, realizing dolar sign atoms. Allocate one + /* generate output list, realizing dollar sign atoms. Allocate one extra atom in case we want to prepend a symbol later */ ATOMS_ALLOCA(outvec, nfield+1); for (i = 0, ap = vec+onset; i < nfield; i++, ap++)