Commit 16ffe950 authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

Vanilla 0.47 backport 4: d_ugen.c, g_array.c, and g_canvas.c

parent ddd99b87
......@@ -11,17 +11,14 @@
interconnections.
*/
#include "m_pd.h"
#include "m_imp.h"
#include <stdlib.h>
#include <stdarg.h>
extern t_class *vinlet_class, *voutlet_class, *canvas_class;
extern t_class *vinlet_class, *voutlet_class, *canvas_class, *text_class;
t_float *obj_findsignalscalar(t_object *x, int m);
static int ugen_loud;
static t_int *dsp_chain;
static int dsp_chainsize;
EXTERN_STRUCT _vinlet;
EXTERN_STRUCT _voutlet;
......@@ -40,7 +37,7 @@ t_int *zero_perform(t_int *w) /* zero out a vector */
{
t_sample *out = (t_sample *)(w[1]);
int n = (int)(w[2]);
while (n--) *out++ = 0;
while (n--) *out++ = 0;
return (w+3);
}
......@@ -48,7 +45,7 @@ t_int *zero_perf8(t_int *w)
{
t_sample *out = (t_sample *)(w[1]);
int n = (int)(w[2]);
for (; n; n -= 8, out += 8)
{
out[0] = 0;
......@@ -67,7 +64,7 @@ void dsp_add_zero(t_sample *out, int n)
{
if (n&7)
dsp_add(zero_perform, 2, out, n);
else
else
dsp_add(zero_perf8, 2, out, n);
}
......@@ -219,11 +216,11 @@ static void block_float(t_block *x, t_floatarg f)
static void block_bang(t_block *x)
{
if (x->x_switched && !x->x_switchon)
if (x->x_switched && !x->x_switchon && pd_this->pd_dspchain)
{
t_int *ip;
x->x_return = 1;
for (ip = dsp_chain + x->x_chainonset; ip; )
for (ip = pd_this->pd_dspchain + x->x_chainonset; ip; )
ip = (*(t_perfroutine)(*ip))(ip);
x->x_return = 0;
}
......@@ -284,7 +281,7 @@ void block_tilde_setup(void)
sizeof(t_block), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
class_addcreator((t_newmethod)switch_new, gensym("switch~"),
A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
class_addmethod(block_class, (t_method)block_set, gensym("set"),
class_addmethod(block_class, (t_method)block_set, gensym("set"),
A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
class_addmethod(block_class, (t_method)block_dsp, gensym("dsp"), A_CANT, 0);
class_addfloat(block_class, block_float);
......@@ -300,40 +297,48 @@ static t_int dsp_done(t_int *w)
void dsp_add(t_perfroutine f, int n, ...)
{
int newsize = dsp_chainsize + n+1, i;
int newsize = pd_this->pd_dspchainsize + n+1, i;
va_list ap;
dsp_chain = t_resizebytes(dsp_chain, dsp_chainsize * sizeof (t_int),
newsize * sizeof (t_int));
dsp_chain[dsp_chainsize-1] = (t_int)f;
pd_this->pd_dspchain = t_resizebytes(pd_this->pd_dspchain,
pd_this->pd_dspchainsize * sizeof (t_int), newsize * sizeof (t_int));
pd_this->pd_dspchain[pd_this->pd_dspchainsize-1] = (t_int)f;
if (ugen_loud)
post("add to chain: %lx",
pd_this->pd_dspchain[pd_this->pd_dspchainsize-1]);
va_start(ap, n);
for (i = 0; i < n; i++)
dsp_chain[dsp_chainsize + i] = va_arg(ap, t_int);
{
pd_this->pd_dspchain[pd_this->pd_dspchainsize + i] = va_arg(ap, t_int);
if (ugen_loud)
post("add to chain: %lx",
pd_this->pd_dspchain[pd_this->pd_dspchainsize + i]);
}
va_end(ap);
dsp_chain[newsize-1] = (t_int)dsp_done;
dsp_chainsize = newsize;
pd_this->pd_dspchain[newsize-1] = (t_int)dsp_done;
pd_this->pd_dspchainsize = newsize;
}
/* at Guenter's suggestion, here's a vectorized version */
void dsp_addv(t_perfroutine f, int n, t_int *vec)
{
int newsize = dsp_chainsize + n+1, i;
dsp_chain = t_resizebytes(dsp_chain, dsp_chainsize * sizeof (t_int),
newsize * sizeof (t_int));
dsp_chain[dsp_chainsize-1] = (t_int)f;
int newsize = pd_this->pd_dspchainsize + n+1, i;
pd_this->pd_dspchain = t_resizebytes(pd_this->pd_dspchain,
pd_this->pd_dspchainsize * sizeof (t_int), newsize * sizeof (t_int));
pd_this->pd_dspchain[pd_this->pd_dspchainsize-1] = (t_int)f;
for (i = 0; i < n; i++)
dsp_chain[dsp_chainsize + i] = vec[i];
dsp_chain[newsize-1] = (t_int)dsp_done;
dsp_chainsize = newsize;
pd_this->pd_dspchain[pd_this->pd_dspchainsize + i] = vec[i];
pd_this->pd_dspchain[newsize-1] = (t_int)dsp_done;
pd_this->pd_dspchainsize = newsize;
}
void dsp_tick(void)
{
if (dsp_chain)
if (pd_this->pd_dspchain)
{
t_int *ip;
for (ip = dsp_chain; ip; ) ip = (*(t_perfroutine)(*ip))(ip);
for (ip = pd_this->pd_dspchain; ip; ) ip = (*(t_perfroutine)(*ip))(ip);
dsp_phase++;
}
}
......@@ -356,17 +361,15 @@ int ilog2(int n)
static t_signal *signal_freelist[MAXLOGSIG+1];
/* list of reusable "borrowed" signals (which don't own sample buffers) */
static t_signal *signal_freeborrowed;
/* list of all signals allocated (not including "borrowed" ones) */
static t_signal *signal_usedlist;
/* call this when DSP is stopped to free all the signals */
void signal_cleanup(void)
{
t_signal *sig;
t_signal **svec, *sig, *sig2;
int i;
while (sig = signal_usedlist)
while ((sig = pd_this->pd_signals))
{
signal_usedlist = sig->s_nextused;
pd_this->pd_signals = sig->s_nextused;
if (!sig->s_isborrowed)
t_freebytes(sig->s_vec, sig->s_vecsize * sizeof (*sig->s_vec));
t_freebytes(sig, sizeof *sig);
......@@ -429,8 +432,9 @@ void signal_makereusable(t_signal *sig)
t_signal *signal_new(int n, t_float sr)
{
int logn, vecsize = 0;
int logn, n2, vecsize = 0;
t_signal *ret, **whichlist;
t_sample *fp;
logn = ilog2(n);
if (n)
{
......@@ -444,7 +448,7 @@ t_signal *signal_new(int n, t_float sr)
whichlist = &signal_freeborrowed;
/* first try to reclaim one from the free list */
if (ret = *whichlist)
if ((ret = *whichlist))
*whichlist = ret->s_nextfree;
else
{
......@@ -460,15 +464,15 @@ t_signal *signal_new(int n, t_float sr)
ret->s_vec = 0;
ret->s_isborrowed = 1;
}
ret->s_nextused = signal_usedlist;
signal_usedlist = ret;
ret->s_nextused = pd_this->pd_signals;
pd_this->pd_signals = ret;
}
ret->s_n = n;
ret->s_vecsize = vecsize;
ret->s_sr = sr;
ret->s_refcount = 0;
ret->s_borrowedfrom = 0;
if (ugen_loud) post("new %lx: %d", ret, ret->s_isborrowed);
if (ugen_loud) post("new %lx: %lx", ret, ret->s_vec);
return (ret);
}
......@@ -487,6 +491,7 @@ void signal_setborrowed(t_signal *sig, t_signal *sig2)
sig->s_vec = sig2->s_vec;
sig->s_n = sig2->s_n;
sig->s_vecsize = sig2->s_vecsize;
if (ugen_loud) post("set borrowed %lx: %lx", sig, sig->s_vec);
}
int signal_compatible(t_signal *s1, t_signal *s2)
......@@ -544,7 +549,7 @@ struct _dspcontext
char dc_toplevel; /* true if "iosigs" is invalid. */
char dc_reblock; /* true if we have to reblock inlets/outlets */
char dc_switched; /* true if we're switched */
};
#define t_dspcontext struct _dspcontext
......@@ -552,24 +557,34 @@ struct _dspcontext
static int ugen_sortno = 0;
static t_dspcontext *ugen_currentcontext;
/* get a new signal for the current context - used by clone~ object */
t_signal *signal_newfromcontext(int borrowed)
{
return (signal_new((borrowed? 0 : ugen_currentcontext->dc_calcsize),
ugen_currentcontext->dc_srate));
}
void ugen_stop(void)
{
if (dsp_chain)
t_signal *s;
int i;
if (pd_this->pd_dspchain)
{
freebytes(dsp_chain, dsp_chainsize * sizeof (t_int));
dsp_chain = 0;
freebytes(pd_this->pd_dspchain,
pd_this->pd_dspchainsize * sizeof (t_int));
pd_this->pd_dspchain = 0;
}
signal_cleanup();
}
void ugen_start(void)
{
ugen_stop();
ugen_sortno++;
dsp_chain = (t_int *)getbytes(sizeof(*dsp_chain));
dsp_chain[0] = (t_int)dsp_done;
dsp_chainsize = 1;
pd_this->pd_dspchain = (t_int *)getbytes(sizeof(*pd_this->pd_dspchain));
pd_this->pd_dspchain[0] = (t_int)dsp_done;
pd_this->pd_dspchainsize = 1;
if (ugen_currentcontext) bug("ugen_start");
}
......@@ -578,12 +593,12 @@ int ugen_getsortno(void)
return (ugen_sortno);
}
#if 0
#if 1
void glob_foo(void *dummy, t_symbol *s, int argc, t_atom *argv)
{
int i, count;
t_signal *sig;
for (count = 0, sig = signal_usedlist; sig;
for (count = 0, sig = pd_this->pd_signals; sig;
count++, sig = sig->s_nextused)
;
post("used signals %d", count);
......@@ -600,7 +615,7 @@ void glob_foo(void *dummy, t_symbol *s, int argc, t_atom *argv)
;
post("free borrowed %d", count);
ugen_loud = argc;
ugen_loud = argc;
}
#endif
......@@ -609,9 +624,15 @@ t_dspcontext *ugen_start_graph(int toplevel, t_signal **sp,
int ninlets, int noutlets)
{
t_dspcontext *dc = (t_dspcontext *)getbytes(sizeof(*dc));
int parent_vecsize, vecsize;
if (ugen_loud) post("ugen_start_graph...");
/* protect against invalid numsignals. This might happen if we have
an abstraction with inlet~/outlet~ opened as a toplevel patch */
if (toplevel)
ninlets = noutlets = 0;
dc->dc_ugenlist = 0;
dc->dc_toplevel = toplevel;
dc->dc_iosigs = sp;
......@@ -629,7 +650,7 @@ void ugen_add(t_dspcontext *dc, t_object *obj)
int i;
t_sigoutlet *uout;
t_siginlet *uin;
x->u_next = dc->dc_ugenlist;
dc->dc_ugenlist = x;
x->u_obj = obj;
......@@ -643,9 +664,6 @@ void ugen_add(t_dspcontext *dc, t_object *obj)
uout->o_connections = 0, uout->o_nconnect = 0;
}
extern t_class *text_class;
#include <stdio.h>
/* and then this to make all the connections. */
void ugen_connect(t_dspcontext *dc, t_object *x1, int outno, t_object *x2,
int inno)
......@@ -664,6 +682,10 @@ void ugen_connect(t_dspcontext *dc, t_object *x1, int outno, t_object *x2,
for (u2 = dc->dc_ugenlist; u2 && u2->u_obj != x2; u2 = u2->u_next);
if (!u1 || !u2 || siginno < 0)
{
if (!u1)
error("object with signal outlets but no DSP method?");
/* check if it's a "text" (i.e., object wasn't created) -
if so fail silently */
t_text *t2 = (t_text *)x2;
// The following only happens if the DAC is on while connecting
// objects. If this is not yet initialized object we don't
......@@ -705,6 +727,7 @@ static int ugen_index(t_dspcontext *dc, t_ugenbox *x)
if (u == x) return (ret);
return (-1);
}
extern t_class *clone_class;
/* put a ugenbox on the chain, recursively putting any others on that
this one might uncover. */
......@@ -712,7 +735,7 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
{
t_sigoutlet *uout;
t_siginlet *uin;
t_sigoutconnect *oc;
t_sigoutconnect *oc, *oc2;
t_class *class = pd_class(&u->u_obj->ob_pd);
int i, n;
/* suppress creating new signals for the outputs of signal
......@@ -721,16 +744,16 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
we delay new signal creation, which will be handled by calling
signal_setborrowed in the ugen_done_graph routine below. */
int nonewsigs = (class == canvas_class ||
(class == vinlet_class) && !(dc->dc_reblock));
((class == vinlet_class) && !(dc->dc_reblock)));
/* when we encounter a subcanvas or a signal outlet, suppress freeing
the input signals as they may be "borrowed" for the super or sub
patch; same exception as above, but also if we're "switched" we
have to do a copy rather than a borrow. */
int nofreesigs = (class == canvas_class ||
(class == voutlet_class) && !(dc->dc_reblock || dc->dc_switched));
int nofreesigs = (class == canvas_class || class == clone_class ||
((class == voutlet_class) && !(dc->dc_reblock || dc->dc_switched)));
t_signal **insig, **outsig, **sig, *s1, *s2, *s3;
t_ugenbox *u2;
if (ugen_loud) post("doit %s %d %d", class_getname(class), nofreesigs,
nonewsigs);
for (i = 0, uin = u->u_in; i < u->u_nin; i++, uin++)
......@@ -738,10 +761,10 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
if (!uin->i_nconnect)
{
t_float *scalar;
s3 = signal_new(dc->dc_vecsize, dc->dc_srate);
s3 = signal_new(dc->dc_calcsize, dc->dc_srate);
/* post("%s: unconnected signal inlet set to zero",
class_getname(u->u_obj->ob_pd)); */
if (scalar = obj_findsignalscalar(u->u_obj, i))
if ((scalar = obj_findsignalscalar(u->u_obj, i)))
dsp_add_scalarcopy(scalar, s3->s_vec, s3->s_n);
else
dsp_add_zero(s3->s_vec, s3->s_n);
......@@ -781,14 +804,14 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
signal_new(0, dc->dc_srate);
}
else
*sig = uout->o_signal = signal_new(dc->dc_vecsize, dc->dc_srate);
*sig = uout->o_signal = signal_new(dc->dc_calcsize, dc->dc_srate);
(*sig)->s_refcount = uout->o_nconnect;
}
/* now call the DSP scheduling routine for the ugen. This
routine must fill in "borrowed" signal outputs in case it's either
a subcanvas or a signal inlet. */
mess1(&u->u_obj->ob_pd, gensym("dsp"), insig);
/* if any output signals aren't connected to anyone, free them
now; otherwise they'll either get freed when the reference count
goes back to zero, or even later as explained above. */
......@@ -800,14 +823,14 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
}
if (ugen_loud)
{
if (u->u_nin + u->u_nout == 0) post("put %s %d",
if (u->u_nin + u->u_nout == 0) post("put %s %d",
class_getname(u->u_obj->ob_pd), ugen_index(dc, u));
else if (u->u_nin + u->u_nout == 1) post("put %s %d (%lx)",
else if (u->u_nin + u->u_nout == 1) post("put %s %d (%lx)",
class_getname(u->u_obj->ob_pd), ugen_index(dc, u), sig[0]);
else if (u->u_nin + u->u_nout == 2) post("put %s %d (%lx %lx)",
else if (u->u_nin + u->u_nout == 2) post("put %s %d (%lx %lx)",
class_getname(u->u_obj->ob_pd), ugen_index(dc, u),
sig[0], sig[1]);
else post("put %s %d (%lx %lx %lx ...)",
else post("put %s %d (%lx %lx %lx ...)",
class_getname(u->u_obj->ob_pd), ugen_index(dc, u),
sig[0], sig[1], sig[2]);
}
......@@ -821,7 +844,7 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
u2 = oc->oc_who;
uin = &u2->u_in[oc->oc_inno];
/* if there's already someone here, sum the two */
if (s2 = uin->i_signal)
if ((s2 = uin->i_signal))
{
s1->s_refcount--;
s2->s_refcount--;
......@@ -865,7 +888,7 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
void ugen_done_graph(t_dspcontext *dc)
{
t_ugenbox *u;
t_ugenbox *u, *u2;
t_sigoutlet *uout;
t_siginlet *uin;
t_sigoutconnect *oc, *oc2;
......@@ -874,7 +897,7 @@ void ugen_done_graph(t_dspcontext *dc)
t_dspcontext *parent_context = dc->dc_parentcontext;
t_float parent_srate;
int parent_vecsize;
int period, frequency, vecsize, calcsize;
int period, frequency, phase, vecsize, calcsize;
t_float srate;
int chainblockbegin; /* DSP chain onset before block prolog code */
int chainblockend; /* and after block epilog code */
......@@ -882,7 +905,7 @@ void ugen_done_graph(t_dspcontext *dc)
int reblock = 0, switched;
int downsample = 1, upsample = 1;
/* debugging printout */
if (ugen_loud)
{
post("ugen_done_graph...");
......@@ -898,7 +921,7 @@ void ugen_done_graph(t_dspcontext *dc)
}
}
}
/* search for an object of class "block~" */
for (u = dc->dc_ugenlist, blk = 0; u; u = u->u_next)
{
......@@ -941,6 +964,7 @@ void ugen_done_graph(t_dspcontext *dc)
(parent_vecsize * realoverlap * upsample);
frequency = (parent_vecsize * realoverlap * upsample)/
(vecsize * downsample);
phase = blk->x_phase;
srate = parent_srate * realoverlap * upsample / downsample;
if (period < 1) period = 1;
if (frequency < 1) frequency = 1;
......@@ -948,7 +972,7 @@ void ugen_done_graph(t_dspcontext *dc)
blk->x_period = period;
blk->x_phase = dsp_phase & (period - 1);
if (! parent_context || (realoverlap != 1) ||
(vecsize != parent_vecsize) ||
(vecsize != parent_vecsize) ||
(downsample != 1) || (upsample != 1))
reblock = 1;
switched = blk->x_switched;
......@@ -960,6 +984,7 @@ void ugen_done_graph(t_dspcontext *dc)
calcsize = (parent_context ? parent_context->dc_calcsize : vecsize);
downsample = upsample = 1;
period = frequency = 1;
phase = 0;
if (!parent_context) reblock = 1;
switched = 0;
}
......@@ -968,7 +993,7 @@ void ugen_done_graph(t_dspcontext *dc)
dc->dc_srate = srate;
dc->dc_vecsize = vecsize;
dc->dc_calcsize = calcsize;
/* if we're reblocking or switched, we now have to create output
signals to fill in for the "borrowed" ones we have now. This
is also possibly true even if we're not blocked/switched, in
......@@ -1003,29 +1028,29 @@ void ugen_done_graph(t_dspcontext *dc)
pointers to their corresponding inlets/outlets on the box we're inside,
if any. Outlets will also need pointers, unless we're switched, in
which case outlet epilog code will kick in. */
for (u = dc->dc_ugenlist; u; u = u->u_next)
{
t_pd *zz = &u->u_obj->ob_pd;
t_signal **outsigs = dc->dc_iosigs;
t_signal **insigs = dc->dc_iosigs, **outsigs = dc->dc_iosigs;
if (outsigs) outsigs += dc->dc_ninlets;
if (pd_class(zz) == vinlet_class)
vinlet_dspprolog((struct _vinlet *)zz,
vinlet_dspprolog((struct _vinlet *)zz,
dc->dc_iosigs, vecsize, calcsize, dsp_phase, period, frequency,
downsample, upsample, reblock, switched);
else if (pd_class(zz) == voutlet_class)
voutlet_dspprolog((struct _voutlet *)zz,
voutlet_dspprolog((struct _voutlet *)zz,
outsigs, vecsize, calcsize, dsp_phase, period, frequency,
downsample, upsample, reblock, switched);
}
chainblockbegin = dsp_chainsize;
}
chainblockbegin = pd_this->pd_dspchainsize;
if (blk && (reblock || switched)) /* add the block DSP prolog */
{
dsp_add(block_prolog, 1, blk);
blk->x_chainonset = dsp_chainsize - 1;
}
blk->x_chainonset = pd_this->pd_dspchainsize - 1;
}
/* Initialize for sorting */
for (u = dc->dc_ugenlist; u; u = u->u_next)
{
......@@ -1035,7 +1060,7 @@ void ugen_done_graph(t_dspcontext *dc)
for (uin = u->u_in, i = u->u_nin; i--; uin++)
uin->i_ngot = 0, uin->i_signal = 0;
}
/* Do the sort */
for (u = dc->dc_ugenlist; u; u = u->u_next)
......@@ -1051,9 +1076,9 @@ void ugen_done_graph(t_dspcontext *dc)
/* check for a DSP loop, which is evidenced here by the presence
of ugens not yet scheduled. */
for (u = dc->dc_ugenlist; u; u = u->u_next)
if (!u->u_done)
if (!u->u_done)
{
t_signal **sigp;
pd_error(u->u_obj,
......@@ -1079,7 +1104,7 @@ void ugen_done_graph(t_dspcontext *dc)
if (blk && (reblock || switched)) /* add block DSP epilog */
dsp_add(block_epilog, 1, blk);
chainblockend = dsp_chainsize;
chainblockend = pd_this->pd_dspchainsize;
/* add epilogs for outlets. */
......@@ -1090,13 +1115,13 @@ void ugen_done_graph(t_dspcontext *dc)
{
t_signal **iosigs = dc->dc_iosigs;
if (iosigs) iosigs += dc->dc_ninlets;
voutlet_dspepilog((struct _voutlet *)zz,
voutlet_dspepilog((struct _voutlet *)zz,
iosigs, vecsize, calcsize, dsp_phase, period, frequency,
downsample, upsample, reblock, switched);
}
}
chainafterall = dsp_chainsize;
chainafterall = pd_this->pd_dspchainsize;
if (blk)
{
blk->x_blocklength = chainblockend - chainblockbegin;
......@@ -1108,8 +1133,9 @@ void ugen_done_graph(t_dspcontext *dc)
{
t_int *ip;
if (!dc->dc_parentcontext)
for (i = dsp_chainsize, ip = dsp_chain; i--; ip++)
post("chain %lx", *ip);
for (i = pd_this->pd_dspchainsize, ip = pd_this->pd_dspchain;
i--; ip++)
post("chain %lx", *ip);
post("... ugen_done_graph done.");
}
/* now delete everything. */
......@@ -1169,8 +1195,8 @@ static void samplerate_tilde_bang(t_samplerate *x)
while (canvas)
{
t_block *b = (t_block *)canvas_getblock(block_class, &canvas);
if (b)
srate *= (t_float)(b->x_upsample) / (t_float)(b->x_downsample);
if (b)
srate *= (t_float)(b->x_upsample) / (t_float)(b->x_downsample);
}
outlet_float(x->x_obj.ob_outlet, srate);
}
......@@ -1192,7 +1218,7 @@ static void samplerate_tilde_setup(void)
/* -------------------- setup routine -------------------------- */
void d_ugen_setup(void)
void d_ugen_setup(void)
{
block_tilde_setup();
samplerate_tilde_setup();
......
......@@ -22,7 +22,7 @@ two, but how? */
which can't send symbols starting with '$' (because the Pd message
interpreter would change them!) */
static t_symbol *sharptodollar(t_symbol *s)
t_symbol *sharptodollar(t_symbol *s)
{
if (*s->s_name == '#')
{
......@@ -85,7 +85,7 @@ void array_resize(t_array *x, int n)
x->a_valid = ++glist_valid;
}
static void array_resize_and_redraw(t_array *array, t_glist *glist, int n)
void array_resize_and_redraw(t_array *array, t_glist *glist, int n)
{
//fprintf(stderr,"array_resize_and_redraw\n");
t_array *a2 = array;
......@@ -93,10 +93,10 @@ static void array_resize_and_redraw(t_array *array, t_glist *glist, int n)
while (a2->a_gp.gp_stub->gs_which == GP_ARRAY)
a2 = a2->a_gp.gp_stub->gs_un.gs_array;
if (vis)
gobj_vis(a2->a_gp.gp_un.gp_gobj, glist, 0);
gobj_vis(&a2->a_gp.gp_un.gp_gobj, glist, 0);
array_resize(array, n);
if (vis)
gobj_vis(a2->a_gp.gp_un.gp_gobj, glist, 1);
gobj_vis(&a2->a_gp.gp_un.gp_gobj, glist, 1);
}
void word_free(t_word *wp, t_template *template);
......@@ -264,6 +264,18 @@ int garray_joc(t_garray *x)
return (x->x_joc);
}
/* get a garray's containing glist */
t_glist *garray_getglist(t_garray *x)
{
return (x->x_glist);