Commit 7c054d12 authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

Merge remote-tracking branch 'origin/master' into pdgui-refactor

parents e66428d7 c6485c39
......@@ -28,7 +28,7 @@ void my_canvas_draw_new(t_my_canvas *x, t_glist *glist)
sprintf(cbuf, "#%6.6x", x->x_gui.x_bcol);
gui_vmess("gui_gobj_new", "xxsiii", canvas,
x, "iemgui", x1, y1, glist_istoplevel(canvas));
x, "iemgui", x1, y1, glist_istoplevel(glist));
gui_vmess("gui_mycanvas_new", "xxsiiiiii", canvas,
x, cbuf, x1, y1, x1+x->x_vis_w, y1+x->x_vis_h,
x1+x->x_gui.x_w, y1+x->x_gui.x_h);
......
......@@ -402,6 +402,8 @@ void canvas_doaddtemplate(t_symbol *templatesym,
static void glist_writelist(t_gobj *y, t_binbuf *b);
void binbuf_savetext(t_binbuf *bfrom, t_binbuf *bto);
void canvas_writescalar(t_symbol *templatesym, t_word *w, t_binbuf *b,
int amarrayelement)
{
......
......@@ -363,12 +363,6 @@ static t_scalar *template_conformscalar(t_template *tfrom, t_template *tto,
}
else if (ds->ds_type == DT_ARRAY)
{
t_symbol *arraytemplate = ds->ds_fieldtemplate;
if (arraytemplate == tfrom->t_sym ||
arraytemplate == tto->t_sym)
{
return 0;
}
template_conformarray(tfrom, tto, conformaction,
x->sc_vec[i].w_array);
}
......@@ -1744,8 +1738,15 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s,
need to experiment with gop scalars to make sure I'm not breaking
anything */
char tag[MAXPDSTRING];
int index = (array ?
((((char *)data) - array->a_vec) / array->a_elemsize) : -1);
int index;
if (array)
{
int elemsize = array->a_elemsize;
if (!elemsize) elemsize = 1;
index = (((char *)data) - array->a_vec) / elemsize;
}
else
index = -1;
if (x->x_type == gensym("g") || x->x_type == gensym("svg"))
{
sprintf(tag, "dgroup%lx.%lx",
......@@ -2141,7 +2142,22 @@ void svg_register_events(t_gobj *z, t_canvas *c, t_scalar *sc,
t_template *template, t_word *data, t_array *a)
{
t_svg *svg;
int index = (a ? ((((char *)data) - a->a_vec) / a->a_elemsize) : -1);
int index;
if (a)
{
int elemsize = a->a_elemsize;
/* avoid divide-by-zero in case our elemsize is 0. Currently
there's no practical use case for an array of elements which
have zero size as there's no way to differentiate their
visualization. However if [draw array] changes in the future
to allow spacing out element groups or something like that,
we will have to revisit this workaround we're using to get
the element's index. */
if (!elemsize) elemsize = 1;
index = (((char *)data) - a->a_vec) / elemsize;
}
else
index = -1;
char tagbuf[MAXPDSTRING];
if (pd_class(&z->g_pd) == canvas_class)
{
......@@ -2161,9 +2177,8 @@ void svg_register_events(t_gobj *z, t_canvas *c, t_scalar *sc,
sprintf(tagbuf, "draw%lx.%lx", (long unsigned int)z,
(long unsigned int)data);
}
else
else /* legacy drawing commands: curve, drawnumber, etc. */
{
error("scalar: can't set event for unknown drawing command");
return;
}
if (svg->x_events.e_mouseover.a_flag)
......@@ -2230,8 +2245,6 @@ void svg_setattr(t_svg *x, t_symbol *s, t_int argc, t_atom *argv)
the arguments in an existing [draw svg] object. */
void svg_update_args(t_svg *x, t_symbol *s, int argc, t_atom *argv)
{
post("made it to args");
if (argc) post("first arg is %s", atom_getsymbolarg(0, argc, argv)->s_name);
/* "g" doesn't take any args, so check for "svg" arg */
if (atom_getsymbolarg(0, argc, argv) == gensym("svg"))
{
......@@ -4470,35 +4483,48 @@ static int draw_click(t_gobj *z, t_glist *glist,
But the one person I know who uses nested ds arrays hasn't asked for
that, so let's see if we can just make it to the end of this software's
life before that happens. */
static void scalar_spelunkforword(t_scalar *x, t_symbol *s, int word_index,
t_array **array, t_word **data)
{
/* from glob_findinstance */
long obj = 0;
if (sscanf(s->s_name, "x%lx", &obj))
{
t_template *template = template_findbyname(x->sc_template);
if (!template)
{
pd_error(x, "scalar: template disappeared before notification "
"from gui arrived");
static void scalar_spelunkforword(void* word_candidate, t_template* template,
t_word *data, int word_index, t_array **arrayp, t_word **datap)
{
int i, nitems = template->t_n;
t_dataslot *datatypes = template->t_vec;
t_word *wp = data;
for (i = 0; i < nitems; i++, datatypes++, wp++)
{
if (datatypes->ds_type == DT_ARRAY &&
((void *)wp->w_array) == (void *)word_candidate)
{
/* Make sure we're in range, as the array could have been
resized. In that case simply return */
if (word_index >= wp->w_array->a_n) return;
*arrayp = wp->w_array;
*datap = ((t_word *)(wp->w_array->a_vec +
word_index * wp->w_array->a_elemsize));
return;
}
int i, nitems = template->t_n;
t_dataslot *datatypes = template->t_vec;
t_word *wp = x->sc_vec;
for (i = 0; i < nitems; i++, datatypes++, wp++)
}
/* Now swoop through the headers again and recursively search
any arrays for nested data. We do this as a second step so
that toplevel arrays don't take a performance hit from deeply
nested arrays. (Probably not a big deal for click events, but
for complex data structures it could be noticeable for drag
events */
wp = data;
datatypes = template->t_vec;
for (i = 0; i < nitems; i++, datatypes++, wp++)
if (datatypes->ds_type == DT_ARRAY)
{
if (datatypes->ds_type == DT_ARRAY &&
((void *)wp->w_array) == (void *)obj &&
word_index < wp->w_array->a_n)
t_template* t = template_findbyname(wp->w_array->a_templatesym);
if (t)
{
*array = wp->w_array;
*data = ((t_word *)(wp->w_array->a_vec +
word_index * wp->w_array->a_elemsize));
int i, elemsize = wp->w_array->a_elemsize;
char *vec;
for(i = 0, vec = wp->w_array->a_vec; i < wp->w_array->a_n; i++)
scalar_spelunkforword(word_candidate, t,
(t_word *)(wp->w_array->a_vec + i * elemsize),
word_index, arrayp, datap);
}
}
}
}
void draw_notify(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
......@@ -4526,11 +4552,24 @@ void draw_notify(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
or greater then that's what we have */
if (index > -1)
{
scalar_spelunkforword(sc, array_sym, index, &a, &data);
t_template *template = template_findbyname(sc->sc_template);
if (!template)
{
pd_error(sc, "scalar: template disappeared before notification "
"from gui arrived");
return;
}
long word_candidate = 0; /* from glob_findinstance */
if (!sscanf(array_sym->s_name, "x%lx", &word_candidate))
{
pd_error(sc, "scalar: couldn't read array datum from GUI");
return;
}
scalar_spelunkforword((void *)word_candidate, template, sc->sc_vec,
index, &a, &data);
if (!data)
{
pd_error(x, "scalar: couldn't get array data for event "
"callback");
pd_error(x, "scalar: couldn't get array data for event callback");
return;
}
}
......@@ -8460,7 +8499,7 @@ static void drawimage_free(t_drawimage *x)
//sprintf(buf, ".x%lx", (t_int)x);
sprintf(buf, "x%lx", (long unsigned int)x);
pd_unbind(&x->x_obj.ob_pd, gensym(buf));
gui_vmess("gui_drawimage_free", "x", x);
gui_vmess("gui_image_free", "x", x);
}
static void drawimage_setup(void)
......
......@@ -74,7 +74,6 @@ struct _pdinstance
t_symbol *pd_bendin_sym;
t_symbol *pd_touchin_sym;
t_symbol *pd_polytouchin_sym;
t_symbol *pd_midiclkin_sym;
t_symbol *pd_midirealtimein_sym;
};
......
......@@ -478,7 +478,6 @@ static t_pdinstance *pdinstance_donew(int useprefix)
x->pd_bendin_sym = midi_gensym(midiprefix, "#bendin");
x->pd_touchin_sym = midi_gensym(midiprefix, "#touchin");
x->pd_polytouchin_sym = midi_gensym(midiprefix, "#polytouchin");
x->pd_midiclkin_sym = midi_gensym(midiprefix, "#midiclkin");
x->pd_midirealtimein_sym = midi_gensym(midiprefix, "#midirealtimein");
return (x);
}
......
......@@ -14,7 +14,7 @@ extern "C" {
#define PD_MINOR_VERSION 48
#define PD_BUGFIX_VERSION 0
#define PD_TEST_VERSION ""
#define PD_L2ORK_VERSION "2.4.3"
#define PD_L2ORK_VERSION "2.4.7"
#define PDL2ORK
extern int pd_compatibilitylevel; /* e.g., 43 for pd 0.43 compatibility */
......
......@@ -46,7 +46,7 @@ void sys_doflags( void);
#ifdef UNIX
#define USER_CONFIG_DIR ".pd-l2ork"
#define USER_CONFIG_DIR ".purr-data"
static char *sys_prefbuf;
......
......@@ -462,7 +462,7 @@ static t_pd *do_create_abstraction(t_symbol*s, int argc, t_atom *argv)
const char *objectname = s->s_name;
char dirbuf[MAXPDSTRING], classslashclass[MAXPDSTRING], *nameptr;
t_glist *glist = (t_glist *)canvas_getcurrent();
t_canvas *canvas = (t_canvas*)glist_getcanvas(glist);
t_canvas *canvas = (t_canvas*)canvas_getrootfor(glist);
int fd = -1;
t_pd *was = s__X.s_thing;
......
......@@ -239,11 +239,6 @@ void outmidi_polyaftertouch(int portno, int channel, int pitch, int value)
pitch, value);
}
void outmidi_mclk(int portno)
{
sys_queuemidimess(portno, 1, 0xf8, 0,0);
}
void outmidi_byte(int portno, int value)
{
#ifdef USEAPI_ALSA
......@@ -291,7 +286,6 @@ typedef struct midiparser
/* functions in x_midi.c */
void inmidi_realtimein(int portno, int cmd);
void inmidi_clk(double timing);
void inmidi_byte(int portno, int byte);
void inmidi_sysex(int portno, int byte);
void inmidi_noteon(int portno, int channel, int pitch, int velo);
......@@ -316,14 +310,6 @@ static void sys_dispatchnextmidiin( void)
if (byte >= 0xf8)
{
inmidi_realtimein(portno, byte);
if (byte == 0xf8) {
// AG: Not sure what the timebase for the right outlet is supposed
// to be. I'm using msecs right now, which is in line with the other
// tempo-related objects such as metro. Multiply with .001 to
// get seconds instead.
double timing = clock_gettimesince(sys_midiinittime);
inmidi_clk(timing);
}
}
else
{
......
......@@ -440,7 +440,7 @@ EXTERN void alist_init(t_alist *x);
EXTERN void alist_clear(t_alist *x);
EXTERN void alist_list(t_alist *x, t_symbol *s, int argc, t_atom *argv);
EXTERN void alist_anything(t_alist *x, t_symbol *s, int argc, t_atom *argv);
EXTERN void alist_toatoms(t_alist *x, t_atom *to);
EXTERN void alist_clone(t_alist *x, t_alist *y);
EXTERN void alist_toatoms(t_alist *x, t_atom *to, int onset, int count);
EXTERN void alist_clone(t_alist *x, t_alist *y, int onset, int count);
#endif /* __s_stuff_h_ */
......@@ -79,21 +79,33 @@ void alist_init(t_alist *x)
void alist_clear(t_alist *x)
{
if (x->l_n)
int i;
for (i = 0; i < x->l_n; i++)
{
int i;
for (i = 0; i < x->l_n; i++)
if (x->l_vec[i].l_a.a_type == A_POINTER)
gpointer_unset(x->l_vec[i].l_a.a_w.w_gpointer);
}
if (x->l_vec)
freebytes(x->l_vec, x->l_n * sizeof(*x->l_vec));
}
static void alist_copyin(t_alist *x, t_symbol *s, int argc, t_atom *argv,
int where)
{
int i, j;
for (i = 0, j = where; i < argc; i++, j++)
{
x->l_vec[j].l_a = argv[i];
if (x->l_vec[j].l_a.a_type == A_POINTER)
{
if (x->l_vec[i].l_a.a_type == A_POINTER)
gpointer_unset(x->l_vec[i].l_a.a_w.w_gpointer);
x->l_npointer++;
gpointer_copy(x->l_vec[j].l_a.a_w.w_gpointer, &x->l_vec[j].l_p);
x->l_vec[j].l_a.a_w.w_gpointer = &x->l_vec[j].l_p;
}
if (x->l_vec)
freebytes(x->l_vec, x->l_n * sizeof(*x->l_vec));
}
x->l_n = 0;
x->l_npointer = 0;
}
/* set contents to a list */
void alist_list(t_alist *x, t_symbol *s, int argc, t_atom *argv)
{
int i;
......@@ -118,6 +130,7 @@ void alist_list(t_alist *x, t_symbol *s, int argc, t_atom *argv)
}
}
/* set contents to an arbitrary non-list message */
void alist_anything(t_alist *x, t_symbol *s, int argc, t_atom *argv)
{
int i;
......@@ -143,32 +156,32 @@ void alist_anything(t_alist *x, t_symbol *s, int argc, t_atom *argv)
}
}
void alist_toatoms(t_alist *x, t_atom *to)
void alist_toatoms(t_alist *x, t_atom *to, int onset, int count)
{
int i;
for (i = 0; i < x->l_n; i++)
to[i] = x->l_vec[i].l_a;
for (i = 0; i < count; i++)
to[i] = x->l_vec[onset + i].l_a;
}
void alist_clone(t_alist *x, t_alist *y)
void alist_clone(t_alist *x, t_alist *y, int onset, int count)
{
int i;
y->l_pd = alist_class;
y->l_n = x->l_n;
y->l_npointer = x->l_npointer;
y->l_n = count;
y->l_npointer = 0;
if (!(y->l_vec = (t_listelem *)getbytes(y->l_n * sizeof(*y->l_vec))))
{
y->l_n = 0;
error("list_alloc: out of memory");
}
else for (i = 0; i < x->l_n; i++)
else for (i = 0; i < count; i++)
{
y->l_vec[i].l_a = x->l_vec[i].l_a;
y->l_vec[i].l_a = x->l_vec[onset + i].l_a;
if (y->l_vec[i].l_a.a_type == A_POINTER)
{
gpointer_copy(y->l_vec[i].l_a.a_w.w_gpointer, &y->l_vec[i].l_p);
y->l_vec[i].l_a.a_w.w_gpointer = &y->l_vec[i].l_p;
y->l_npointer++;
}
}
}
......@@ -205,20 +218,22 @@ static void list_append_list(t_list_append *x, t_symbol *s,
int argc, t_atom *argv)
{
t_atom *outv;
int outc = x->x_alist.l_n + argc;
int n, outc;
n = x->x_alist.l_n;
outc = n + argc;
XL_ATOMS_ALLOCA(outv, outc);
atoms_copy(argc, argv, outv);
if (x->x_alist.l_npointer)
{
t_alist y;
alist_clone(&x->x_alist, &y);
alist_toatoms(&y, outv+argc);
alist_clone(&x->x_alist, &y, 0, n);
alist_toatoms(&y, outv+argc, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
alist_clear(&y);
}
else
{
alist_toatoms(&x->x_alist, outv+argc);
alist_toatoms(&x->x_alist, outv+argc, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
}
XL_ATOMS_FREEA(outv, outc);
......@@ -228,21 +243,23 @@ static void list_append_anything(t_list_append *x, t_symbol *s,
int argc, t_atom *argv)
{
t_atom *outv;
int outc = x->x_alist.l_n + argc + 1;
int n, outc;
n = x->x_alist.l_n;
outc = n + argc + 1;
XL_ATOMS_ALLOCA(outv, outc);
SETSYMBOL(outv, s);
atoms_copy(argc, argv, outv + 1);
if (x->x_alist.l_npointer)
{
t_alist y;
alist_clone(&x->x_alist, &y);
alist_toatoms(&y, outv + 1 + argc);
alist_clone(&x->x_alist, &y, 0, n);
alist_toatoms(&y, outv + 1 + argc, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
alist_clear(&y);
}
else
{
alist_toatoms(&x->x_alist, outv + 1 + argc);
alist_toatoms(&x->x_alist, outv + 1 + argc, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
}
XL_ATOMS_FREEA(outv, outc);
......@@ -309,20 +326,22 @@ static void list_cat_list(t_list_cat *x, t_symbol *s,
int argc, t_atom *argv)
{
t_atom *outv;
int outc = x->x_alist.l_n + argc;
int n, outc;
n = x->x_alist.l_n;
outc = n + argc;
XL_ATOMS_ALLOCA(outv, outc);
atoms_copy(argc, argv, outv + x->x_alist.l_n);
if (x->x_alist.l_npointer)
{
t_alist y;
alist_clone(&x->x_alist, &y);
alist_toatoms(&y, outv);
alist_clone(&x->x_alist, &y, 0, n);
alist_toatoms(&y, outv, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
alist_clear(&y);
}
else
{
alist_toatoms(&x->x_alist, outv);
alist_toatoms(&x->x_alist, outv, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
}
alist_list(&x->x_alist, s, outc, outv);
......@@ -333,21 +352,23 @@ static void list_cat_anything(t_list_cat *x, t_symbol *s,
int argc, t_atom *argv)
{
t_atom *outv;
int outc = x->x_alist.l_n + argc + 1;
int n, outc;
n = x->x_alist.l_n;
outc = n + argc + 1;
XL_ATOMS_ALLOCA(outv, outc);
SETSYMBOL(outv + x->x_alist.l_n, s);
atoms_copy(argc, argv, outv + x->x_alist.l_n + 1);
if (x->x_alist.l_npointer)
{
t_alist y;
alist_clone(&x->x_alist, &y);
alist_toatoms(&y, outv);
alist_clone(&x->x_alist, &y, 0, n);
alist_toatoms(&y, outv, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
alist_clear(&y);
}
else
{
alist_toatoms(&x->x_alist, outv);
alist_toatoms(&x->x_alist, outv, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
}
if (x->x_alist.l_n <= 1)
......@@ -406,20 +427,22 @@ static void list_prepend_list(t_list_prepend *x, t_symbol *s,
int argc, t_atom *argv)
{
t_atom *outv;
int outc = x->x_alist.l_n + argc;
int n, outc;
n = x->x_alist.l_n;
outc = n + argc;
XL_ATOMS_ALLOCA(outv, outc);
atoms_copy(argc, argv, outv + x->x_alist.l_n);
atoms_copy(argc, argv, outv + n);
if (x->x_alist.l_npointer)
{
t_alist y;
alist_clone(&x->x_alist, &y);
alist_toatoms(&y, outv);
alist_clone(&x->x_alist, &y, 0, n);
alist_toatoms(&y, outv, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
alist_clear(&y);
}
else
{
alist_toatoms(&x->x_alist, outv);
alist_toatoms(&x->x_alist, outv, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
}
XL_ATOMS_FREEA(outv, outc);
......@@ -431,21 +454,23 @@ static void list_prepend_anything(t_list_prepend *x, t_symbol *s,
int argc, t_atom *argv)
{
t_atom *outv;
int outc = x->x_alist.l_n + argc + 1;
int n, outc;
n = x->x_alist.l_n;
outc = n + argc + 1;
XL_ATOMS_ALLOCA(outv, outc);
SETSYMBOL(outv + x->x_alist.l_n, s);
atoms_copy(argc, argv, outv + x->x_alist.l_n + 1);
SETSYMBOL(outv + n, s);
atoms_copy(argc, argv, outv + n + 1);
if (x->x_alist.l_npointer)
{
t_alist y;
alist_clone(&x->x_alist, &y);
alist_toatoms(&y, outv);
alist_clone(&x->x_alist, &y, 0, n);
alist_toatoms(&y, outv, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
alist_clear(&y);
}
else
{
alist_toatoms(&x->x_alist, outv);
alist_toatoms(&x->x_alist, outv, 0, n);
outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv);
}
XL_ATOMS_FREEA(outv, outc);
......@@ -468,6 +493,162 @@ static void list_prepend_setup(void)
}
/* ------------- list store --------------------- */
t_class *list_store_class;
typedef struct _list_store
{
t_object x_obj;
t_alist x_alist;
t_outlet *x_out1;
t_outlet *x_out2;
} t_list_store;
static void *list_store_new(t_symbol *s, int argc, t_atom *argv)
{
t_list_store *x = (t_list_store *)pd_new(list_store_class);
alist_init(&x->x_alist);
alist_list(&x->x_alist, 0, argc, argv);
x->x_out1 = outlet_new(&x->x_obj, &s_list);
x->x_out2 = outlet_new(&x->x_obj, &s_bang);
inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0);
return (x);
}
static void list_store_list(t_list_store *x, t_symbol *s,
int argc, t_atom *argv)
{
t_atom *outv;
int n, outc;
n = x->x_alist.l_n;
outc = n + argc;
ATOMS_ALLOCA(outv, outc);
atoms_copy(argc, argv, outv);
if (x->x_alist.l_npointer)
{
t_alist y;
alist_clone(&x->x_alist, &y, 0, n);
alist_toatoms(&y, outv+argc, 0, n);
outlet_list(x->x_out1, &s_list, outc, outv);
alist_clear(&y);
}
else
{
alist_toatoms(&x->x_alist, outv+argc, 0, n);
outlet_list(x->x_out1, &s_list, outc, outv);
}
ATOMS_FREEA(outv, outc);
}
/* function to restore gpointers after the list has moved in memory */
static void list_store_restore_gpointers(t_list_store *x, int offset, int count)
{
t_listelem *vec = x->x_alist.l_vec + offset;
while (count--)
{
if (vec->l_a.a_type == A_POINTER)