diff options
author | N.N. <krzyszcz@users.sourceforge.net> | 2004-02-19 22:23:18 +0000 |
---|---|---|
committer | N.N. <krzyszcz@users.sourceforge.net> | 2004-02-19 22:23:18 +0000 |
commit | d0f6986345970955d6390a6953c35babf587c262 (patch) | |
tree | b9c55d804a317558da506f9655ff495856ef47d8 /toxy/plustot.qlist.c | |
parent | d405128358369b5b7424c086c67345d12edfde7d (diff) |
many small improvements in toxy, plustot added
svn path=/trunk/externals/miXed/; revision=1321
Diffstat (limited to 'toxy/plustot.qlist.c')
-rw-r--r-- | toxy/plustot.qlist.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/toxy/plustot.qlist.c b/toxy/plustot.qlist.c new file mode 100644 index 0000000..b49aeb1 --- /dev/null +++ b/toxy/plustot.qlist.c @@ -0,0 +1,212 @@ +/* Copyright (c) 2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#include <string.h> +#include "m_pd.h" +#include "unstable/fragile.h" +#include "common/loud.h" +#include "toxy/plusbob.h" +#include "plustot.h" + +#define PLUSTOT_QLIST_DEBUG + +/* Need only an access to x_binbuf field. */ +typedef struct _qlist +{ + t_object x_ob; + t_outlet *x_bangout; + void *x_binbuf; +} t_qlist; + +typedef struct _plusproxy_qlist +{ + t_pd pp_pd; + struct _plustot_qlist *pp_master; +} t_plusproxy_qlist; + +typedef struct _plustot_qlist +{ + t_object x_ob; + t_glist *x_glist; + t_plustob *x_tob; + t_outlet *x_rightout; + t_plusproxy_qlist *x_proxy; +} t_plustot_qlist; + +static t_class *plusproxy_qlist_class; +static t_class *plustot_qlist_class; + +static t_binbuf *plustot_qlist_usurp(t_plustot_qlist *x) +{ + static t_symbol *types[2]; + static int ntypes = 0; + t_object *booty; + if (ntypes == 0) + { + types[0] = gensym("qlist"); + types[1] = gensym("textfile"); + ntypes = 2; + } + if (booty = fragile_outlet_destination( + ((t_object *)x)->ob_outlet, ntypes, types, + (t_pd *)x, "(connect left outlet to a qlist or textfile)")) + { + t_binbuf *bb = ((t_qlist *)booty)->x_binbuf; +#ifdef PLUSTOT_QLIST_DEBUG + post("booty '%s' at %x:", class_getname(*(t_pd *)booty), (int)booty); + binbuf_print(bb); +#endif + return (bb); + } + else return (0); +} + +static t_plusproxy_qlist *plusproxy_qlist_new(t_plustot_qlist *master) +{ + t_plusproxy_qlist *pp = (t_plusproxy_qlist *)pd_new(plusproxy_qlist_class); + pp->pp_master = master; + return (pp); +} + +static void plusproxy_qlist_symbol(t_plusproxy_qlist *pp, t_symbol *s) +{ + t_plustot_qlist *x = pp->pp_master; + Tcl_Interp *interp = 0; + if (plustag_isvalid(s, 0)) + { + t_plustin *tin; + Tcl_Obj *ob; + if ((tin = plustag_tobtin(s, PLUSBOB_OWNER)) && + (ob = plustob_getvalue((t_plustob *)s))) + { + t_binbuf *bb; + if (bb = plustot_qlist_usurp(x)) + { + int nlists; + Tcl_Obj **lists; + interp = plustin_getinterp(tin); + if (Tcl_ListObjGetElements(interp, ob, + &nlists, &lists) == TCL_OK) + { + int lc; + Tcl_Obj **lp; + binbuf_clear(bb); + for (lc = 0, lp = lists; lc < nlists; lc++, lp++) + { + int natoms; + Tcl_Obj **atoms; + if (Tcl_ListObjGetElements(interp, *lp, + &natoms, &atoms) == TCL_OK) + { + int ac; + Tcl_Obj **ap; + for (ac = 0, ap = atoms; ac < natoms; ac++, ap++) + { + double d; + int len; + char *ptr; + Tcl_IncrRefCount(*ap); + if (Tcl_GetDoubleFromObj(interp, + *ap, &d) == TCL_OK) + { + t_atom at; + SETFLOAT(&at, (float)d); + binbuf_add(bb, 1, &at); + } + else if ((ptr = Tcl_GetStringFromObj(*ap, &len)) + && len) + { + t_atom at; + if (ptr[len - 1]) + { + char buf[MAXPDSTRING]; + if (len > MAXPDSTRING - 1) + len = MAXPDSTRING - 1; + strncpy(buf, ptr, len); + buf[len] = 0; + ptr = buf; + } + SETSYMBOL(&at, gensym(ptr)); + binbuf_add(bb, 1, &at); + } + /* FIXME else */ + Tcl_DecrRefCount(*ap); + } + binbuf_addsemi(bb); + } + else + { + binbuf_clear(bb); + goto notalist; + } + } + } + else goto notalist; + } + } + } + return; +notalist: + if (interp) plusloud_tclerror((t_pd *)x, interp, "not a list"); +} + +static void plustot_qlist_bang(t_plustot_qlist *x) +{ + t_binbuf *bb; + if (bb = plustot_qlist_usurp(x)) + { + if (plustob_setbinbuf(x->x_tob, bb)) + outlet_plusbob(x->x_rightout, (t_plusbob *)x->x_tob); + } +} + +static void plustot_qlist_free(t_plustot_qlist *x) +{ + plusbob_release((t_plusbob *)x->x_tob); + if (x->x_proxy) pd_free((t_pd *)x->x_proxy); +} + +void *plustot_qlist_new(t_symbol *s, int ac, t_atom *av) +{ + t_plustot_qlist *x = 0; + t_glist *glist = canvas_getcurrent(); + t_plustin *tin = 0; + t_plustob *tob = 0; + if ((tin = plustin_glistprovide(glist, PLUSTIN_GLIST_ANY, 0)) && + (tob = plustob_new(tin, 0))) + { + x = (t_plustot_qlist *)pd_new(plustot_qlist_class); + plusbob_preserve((t_plusbob *)tob); + plusbob_setowner((t_plusbob *)tob, (t_pd *)x); + plustob_setlist(tob, ac, av); + x->x_glist = glist; + x->x_tob = tob; + x->x_proxy = plusproxy_qlist_new(x); + inlet_new((t_object *)x, (t_pd *)x->x_proxy, 0, 0); + outlet_new((t_object *)x, &s_anything); + x->x_rightout = outlet_new((t_object *)x, &s_symbol); + } + else + { + loud_error(0, "+qlist: cannot initialize"); + if (tin) + { + plusbob_preserve((t_plusbob *)tin); + plusbob_release((t_plusbob *)tin); + } + } + return (x); +} + +void plustot_qlist_setup(void) +{ + plustot_qlist_class = class_new(gensym("+qlist"), 0, + (t_method)plustot_qlist_free, + sizeof(t_plustot_qlist), 0, 0); + class_addbang(plustot_qlist_class, plustot_qlist_bang); + + plusproxy_qlist_class = class_new(gensym("+qlist proxy"), 0, 0, + sizeof(t_plusproxy_qlist), CLASS_PD, 0); + class_addsymbol(plusproxy_qlist_class, plusproxy_qlist_symbol); +} |