aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorN.N. <krzyszcz@users.sourceforge.net>2005-06-13 20:41:52 +0000
committerN.N. <krzyszcz@users.sourceforge.net>2005-06-13 20:41:52 +0000
commit4155426928eab2265d78f4860c35e09057dde840 (patch)
treed261c307f9d6d3f1d34a4ed3fafde7420d0d227a
parentaebe147ae46e27127faa5c9d777de6b9ab822cc9 (diff)
toxy alpha19 and pddp alpha3 (see notes.txt for toxy and pddp)
svn path=/trunk/externals/miXed/; revision=3170
-rw-r--r--bin/pddp/pddpserver.tcl27
-rw-r--r--bin/pddp/pkgIndex.tcl2
-rw-r--r--pddp/build_counter4
-rw-r--r--pddp/notes.txt6
-rw-r--r--pddp/pddplink.c31
-rw-r--r--test/toxy/editors/bpf.wid2
-rw-r--r--test/toxy/setup.wid9
-rw-r--r--toxy/build_counter4
-rw-r--r--toxy/notes.txt40
-rw-r--r--toxy/plustot.c479
-rw-r--r--toxy/plustot.env.c2
-rw-r--r--toxy/plustot.h13
-rw-r--r--toxy/plustot.in.c2
-rw-r--r--toxy/plustot.out.c2
-rw-r--r--toxy/plustot.print.c2
-rw-r--r--toxy/plustot.qlist.c3
-rw-r--r--toxy/plustot.var.c2
-rw-r--r--toxy/pluswidget.c72
18 files changed, 506 insertions, 196 deletions
diff --git a/bin/pddp/pddpserver.tcl b/bin/pddp/pddpserver.tcl
index 4b96be2..eb01207 100644
--- a/bin/pddp/pddpserver.tcl
+++ b/bin/pddp/pddpserver.tcl
@@ -303,15 +303,32 @@ proc ::pddp::srvTimeout {sock} {
srvError $sock 408
}
-# FIXME test if "path" has its patch window already open...
-proc ::pddp::srvPdHandler {sock path} {
+proc ::pddp::srvPdOpen {path} {
+ global menu_windowlist
+ set name [file tail $path]
set dir [file dirname $path]
- set tail [file tail $path]
- if {[catch {pd [concat pd open $tail $dir \;]}]} {
+ # FIXME white space in $name and $dir
+ # FIXME this is a fragile hack, there should be an "openx" message to pd...
+ foreach en $menu_windowlist {
+ set wd [lindex $en 1]
+ set nm [lindex $en 0]
+ set dr [lindex [wm title $wd] end]
+ if {[string equal $name $nm] && [string equal $dir $dr]} {
+ # FIXME test on windows
+ raise $wd
+ focus -force $wd
+ return
+ }
+ }
+ pd [concat pd open $name $dir \;]
+ # FIXME raise and focus on windows?
+}
+
+proc ::pddp::srvPdHandler {sock path} {
+ if {[catch {::pddp::srvPdOpen $path}]} {
srvError $sock 504
} else {
srvError $sock 204
- # FIXME raise; focus (test on windows)
}
}
diff --git a/bin/pddp/pkgIndex.tcl b/bin/pddp/pkgIndex.tcl
index a3abe3d..10b89a6 100644
--- a/bin/pddp/pkgIndex.tcl
+++ b/bin/pddp/pkgIndex.tcl
@@ -5,6 +5,6 @@ proc LoadPddp { version dir } {
source [file join $dir pddpboot.tcl]
}
-set version "0.1.0.2"
+set version "0.1.0.3"
package ifneeded pddp $version [list LoadPddp $version $dir]
diff --git a/pddp/build_counter b/pddp/build_counter
index 627f0ec..9a4c0ab 100644
--- a/pddp/build_counter
+++ b/pddp/build_counter
@@ -1,7 +1,7 @@
#define PDDP_VERSION "0.1"
#define PDDP_RELEASE "alpha"
-#define PDDP_BUILD 2
+#define PDDP_BUILD 3
#if 0
-PDDP_SNAPSHOT = 0.1-alpha2
+PDDP_SNAPSHOT = 0.1-alpha3
#endif
diff --git a/pddp/notes.txt b/pddp/notes.txt
index 168f51e..f087ed8 100644
--- a/pddp/notes.txt
+++ b/pddp/notes.txt
@@ -4,6 +4,12 @@ TODO for pddp
DONE for pddp
+alpha3
+ * .pd back-link tries not to open patches that are already open:
+ if a patch window already exists, it is raised and given focus instead
+ * new option "-gop" (visible in a gop)
+ * bug fix: unclickable in gop, unless visible
+
alpha2
* loading tcl scripts through "package require pddp":
. storing them in an immediate subdirectory of the path of pddplink's binary
diff --git a/pddp/pddplink.c b/pddp/pddplink.c
index d746bbd..307db62 100644
--- a/pddp/pddplink.c
+++ b/pddp/pddplink.c
@@ -25,6 +25,7 @@ typedef struct _pddplink
t_object x_ob;
t_glist *x_glist;
int x_isboxed;
+ int x_isgopvisible;
char *x_vistext;
int x_vissize;
int x_vislength;
@@ -113,23 +114,22 @@ static void pddplink_activate(t_gobj *z, t_glist *glist, int state)
static void pddplink_vis(t_gobj *z, t_glist *glist, int vis)
{
t_pddplink *x = (t_pddplink *)z;
+ t_rtext *y;
if (vis)
{
- if (glist->gl_havewindow)
+ if ((glist->gl_havewindow || x->x_isgopvisible)
+ && (y = glist_findrtext(glist, (t_text *)x)))
{
- t_rtext *y = glist_findrtext(glist, (t_text *)x);
rtext_draw(y);
sys_vgui(".x%lx.c itemconfigure %s -text {%s} -fill magenta\n",
- glist, rtext_gettag(y), x->x_vistext);
+ glist_getcanvas(glist), rtext_gettag(y), x->x_vistext);
}
}
else
{
- if (glist->gl_havewindow)
- {
- t_rtext *y = glist_findrtext(glist, (t_text *)x);
+ if ((glist->gl_havewindow || x->x_isgopvisible)
+ && (y = glist_findrtext(glist, (t_text *)x)))
rtext_erase(y);
- }
}
}
@@ -188,10 +188,15 @@ static void pddplink_click(t_pddplink *x, t_floatarg xpos, t_floatarg ypos,
static int pddplink_wbclick(t_gobj *z, t_glist *glist, int xpix, int ypix,
int shift, int alt, int dbl, int doit)
{
- if (doit)
- pddplink_click((t_pddplink *)z, (t_floatarg)xpix, (t_floatarg)ypix,
- (t_floatarg)shift, 0, (t_floatarg)alt);
- return (1);
+ t_pddplink *x = (t_pddplink *)z;
+ if (glist->gl_havewindow || x->x_isgopvisible)
+ {
+ if (doit)
+ pddplink_click(x, (t_floatarg)xpix, (t_floatarg)ypix,
+ (t_floatarg)shift, 0, (t_floatarg)alt);
+ return (1);
+ }
+ else return (0);
}
static int pddplink_isoption(char *name)
@@ -294,6 +299,7 @@ static void *pddplink_new(t_symbol *s, int ac, t_atom *av)
t_pddplink xgen, *x;
int skip;
xgen.x_isboxed = 0;
+ xgen.x_isgopvisible = 0;
xgen.x_vistext = 0;
xgen.x_vissize = 0;
if (xgen.x_ulink = pddplink_nextsymbol(ac, av, 0, &skip))
@@ -307,6 +313,8 @@ static void *pddplink_new(t_symbol *s, int ac, t_atom *av)
av += skip;
if (opt == gensym("-box"))
xgen.x_isboxed = 1;
+ else if (opt == gensym("-gop"))
+ xgen.x_isgopvisible = 1;
else if (opt == gensym("-text"))
{
t_symbol *nextsym = pddplink_nextsymbol(ac, av, 1, &skip);
@@ -323,6 +331,7 @@ static void *pddplink_new(t_symbol *s, int ac, t_atom *av)
x->x_dirsym = canvas_getdir(x->x_glist); /* FIXME */
x->x_isboxed = xgen.x_isboxed;
+ x->x_isgopvisible = xgen.x_isgopvisible;
x->x_vistext = xgen.x_vistext;
x->x_vissize = xgen.x_vissize;
x->x_vislength = (x->x_vistext ? strlen(x->x_vistext) : 0);
diff --git a/test/toxy/editors/bpf.wid b/test/toxy/editors/bpf.wid
index 1b30646..6fa7f45 100644
--- a/test/toxy/editors/bpf.wid
+++ b/test/toxy/editors/bpf.wid
@@ -1,4 +1,4 @@
-catch {console show}
+::toxy::console show
::toxy::package_require BLT "e:/Tcl/bin/BLT24.dll"
namespace eval ::toxy::bpf {}
diff --git a/test/toxy/setup.wid b/test/toxy/setup.wid
index 05e0164..0794ce8 100644
--- a/test/toxy/setup.wid
+++ b/test/toxy/setup.wid
@@ -19,6 +19,15 @@ proc ::toxy::package_require {pkg dll} {
}
}
+# valid options: "show", "hide"
+proc ::toxy::console {op} {
+ if {[catch {::console $op}]} {
+ if {[catch {package require tkcon}] == 0} {
+ tkcon $op
+ }
+ }
+}
+
# FIXME this should be explicitly requested
# In order to keep the state after tk canvas has been destroyed
# try setting -variable and -textvariable traces
diff --git a/toxy/build_counter b/toxy/build_counter
index 5b97c5e..375ead7 100644
--- a/toxy/build_counter
+++ b/toxy/build_counter
@@ -1,7 +1,7 @@
#define TOXY_VERSION "0.1"
#define TOXY_RELEASE "alpha"
-#define TOXY_BUILD 18
+#define TOXY_BUILD 19
#if 0
-TOXY_SNAPSHOT = 0.1-alpha18
+TOXY_SNAPSHOT = 0.1-alpha19
#endif
diff --git a/toxy/notes.txt b/toxy/notes.txt
index 10401a5..43a2a63 100644
--- a/toxy/notes.txt
+++ b/toxy/notes.txt
@@ -10,10 +10,48 @@ TODO for toxy
* plustot:
. do not evaluate if fresh, unless explicitly forced to (are side-effects
to be modal, requested with a flag, or triggered with a message?)
- . creation time evaluation
+ . pull inputs
DONE for toxy
+alpha19
+ * plustot
+ . rules for slot creation:
+ - there is always at least one slot, although it may be deaf
+ - if a command contains a pseudo-scalar, there is exactly one,
+ listening slot
+ - if a command contains pseudo-array elements, there are as many slots
+ as the highest index + 1 (but not more than 256, a sanity limit);
+ listening slots are created for explicitly used elements, all other
+ slots are deaf
+ - mixing pseudo-scalar and pseudo-array forms in a single command
+ is prohibited
+ - if a command does not contain pseudo-variables, there is exactly one,
+ deaf slot
+ . firing rules established for push inputs:
+ - firing (evaluation with output) is executed iff all listening slots
+ have data and a) a hot slot receives input, or b) any slot receives
+ an explicit firing request ('bang' message)
+ - $Hin and $Cin forms of pseudo-variables: each slot may be explicitly
+ declared hot (Hin) or cold (Cin), overriding the default rule (leftmost
+ slot, if listening, is hot, others are cold) observed when the plain
+ form, $in, is used
+ - $Tin form of pseudo-variables, which is a ``pure dataflow'' variant
+ of $Hin: a hot slot, which looses data after evaluation (all other
+ kinds of slots keep data after evaluation, unless explicitly 'cleared')
+ - 'set' message accepted in all inlets as the `cold' input
+ - 'bang' message accepted in all inlets as the firing trigger
+ . evaluation without output:
+ - executed iff all listening slots have data and a) an object has
+ just been created (creation time evaluation), or b) an object
+ received an explicit evaluation request ('eval' message)
+ - creation time evaluation suppresses all error messages, explicit
+ evaluation does not
+ . message 'clear' in any inlet clears its slot of data
+ . message 'clearall' in leftmost inlet clears all listening slots
+ . appearance: converting dot-sequences to valid Tcl for presentation
+ . bug fix: made unclickable in gop
+
alpha18
* plustot:
. adjusted to the new, stubified +bob handling
diff --git a/toxy/plustot.c b/toxy/plustot.c
index 31c2b0b..865b39c 100644
--- a/toxy/plustot.c
+++ b/toxy/plustot.c
@@ -391,6 +391,23 @@ Tcl_Obj *plusatom_tobvalue(t_atom *ap, t_pd *caller)
return (0);
}
+int plustob_clear(t_plustob *tob)
+{
+ if (!tob->tob_tin)
+ {
+ /* FIXME */
+ loud_warning(0, "+tot", "+To: environment missing");
+ return (0);
+ }
+ if (tob->tob_value)
+ {
+ PLUSDEBUG_DECRREFCOUNT(tob->tob_value, "plustob_clear");
+ tob->tob_value = 0;
+ return (1);
+ }
+ else return (0);
+}
+
Tcl_Obj *plustob_set(t_plustob *tob, t_plustin *tin, Tcl_Obj *ob)
{
if (tin != tob->tob_tin)
@@ -803,6 +820,7 @@ static int plusvar_ifshared(t_plusbob *bob, Tcl_Obj *ob)
return (1);
}
+/* synchronize a Tcl variable to a +var */
/* LATER try making it more efficient */
static Tcl_Obj *plusvar_postset(t_plusvar *var)
{
@@ -816,7 +834,7 @@ static Tcl_Obj *plusvar_postset(t_plusvar *var)
tob->tob_value, 0);
if (!rob)
{
- if (Tcl_UnsetVar2(interp, var->var_name, 0,
+ if (Tcl_UnsetVar2(interp, var->var_name, var->var_index,
TCL_LEAVE_ERR_MSG) == TCL_OK)
rob = Tcl_ObjSetVar2(interp, var->var_part1, var->var_part2,
tob->tob_value, TCL_LEAVE_ERR_MSG);
@@ -837,7 +855,7 @@ static Tcl_Obj *plusvar_postset(t_plusvar *var)
}
else
{
- if (Tcl_UnsetVar2(interp, var->var_name, 0,
+ if (Tcl_UnsetVar2(interp, var->var_name, var->var_index,
TCL_LEAVE_ERR_MSG) != TCL_OK)
plusloud_tclerror(0, interp, "cannot unset variable");
rob = 0;
@@ -846,6 +864,7 @@ static Tcl_Obj *plusvar_postset(t_plusvar *var)
return (rob);
}
+/* move a +var's value into a Tcl variable */
Tcl_Obj *plusvar_push(t_plusvar *var)
{
if (((t_plustob *)var)->tob_value)
@@ -854,6 +873,7 @@ Tcl_Obj *plusvar_push(t_plusvar *var)
return (0);
}
+/* move a Tcl variable's value into a +var */
Tcl_Obj *plusvar_pull(t_plusvar *var)
{
Tcl_Obj *rob;
@@ -869,6 +889,12 @@ Tcl_Obj *plusvar_pull(t_plusvar *var)
return (rob);
}
+void plusvar_clear(t_plusvar *var, int doit)
+{
+ if (plustob_clear((t_plustob *)var) && doit)
+ plusvar_postset(var);
+}
+
Tcl_Obj *plusvar_set(t_plusvar *var, Tcl_Obj *ob, int doit)
{
t_plustob *tob = (t_plustob *)var;
@@ -907,15 +933,16 @@ Tcl_Obj *plusvar_setlist(t_plusvar *var, int ac, t_atom *av, int doit)
/* LATER derive +string from +bob */
-typedef struct _plusstring
+struct _plusstring
{
int ps_len;
char *ps_buf;
int ps_refcount;
-} t_plusstring;
+};
/* Resolving dot-separators, unless script is empty. */
-t_plusstring *plusstring_fromatoms(int ac, t_atom *av, t_scriptlet *script)
+static t_plusstring *plusstring_fromatoms(t_symbol *s, int ac, t_atom *av,
+ t_scriptlet *script)
{
t_plusstring *ps = 0;
char *buf;
@@ -924,18 +951,37 @@ t_plusstring *plusstring_fromatoms(int ac, t_atom *av, t_scriptlet *script)
{
char *start;
scriptlet_reset(script);
+ if (s && s != &s_)
+ {
+ t_atom at;
+ SETSYMBOL(&at, s);
+ scriptlet_add(script, 1, 1, 1, &at);
+ }
scriptlet_add(script, 1, 1, ac, av);
start = scriptlet_getcontents(script, &length);
buf = copybytes(start, length);
}
else
{
+ char string[MAXPDSTRING];
char *newbuf;
- buf = getbytes(0);
- length = 0;
+ if (s && s != &s_)
+ {
+ t_atom at;
+ SETSYMBOL(&at, s);
+ atom_string(&at, string, MAXPDSTRING);
+ length = strlen(string) + 1;
+ buf = getbytes(length);
+ strcpy(buf, string);
+ buf[length-1] = ' ';
+ }
+ else
+ {
+ buf = getbytes(0);
+ length = 0;
+ }
while (ac--)
{
- char string[MAXPDSTRING];
int newlength;
if ((av->a_type == A_SEMI || av->a_type == A_COMMA) &&
length && buf[length-1] == ' ') length--;
@@ -983,75 +1029,43 @@ void plusstring_release(t_plusstring *ps)
}
}
-typedef struct _plusword
+char *plusstring_get(t_plusstring *ps, int *lenp)
{
- int pw_type;
- Tcl_Obj *pw_ob;
- Tcl_Token *pw_ndxv; /* index part of this word (if array variable) */
- int pw_ndxc; /* numComponents of the above */
-} t_plusword;
-
-#define PLUSTOT_MAXINLETS 256 /* LATER rethink */
-#define PLUSTOT_INIMAXWORDS 16
+ *lenp = ps->ps_len;
+ return (ps->ps_buf);
+}
-/* LATER elaborate */
-#define PLUSTOT_ERRUNKNOWN -1
-#define PLUSTOT_ERROTHER -2
+struct _plustot;
+#define t_plustot struct _plustot
+static int plustot_doit(t_plustot *x, int sendit);
typedef struct _plusproxy
{
t_pd pp_pd;
- t_pd *pp_master;
+ t_plustot *pp_master;
t_plusvar *pp_var;
int pp_ndx;
- int pp_doit;
+ int pp_ishot;
+ int pp_istransient;
int pp_warned;
} t_plusproxy;
-typedef struct _plustot
-{
- t_plusobject x_plusobject;
- t_glist *x_glist;
- t_plustob *x_tob; /* interpreter's result (after invocation) */
- t_scriptlet *x_script;
- Tcl_Obj *x_cname; /* command name, main validation flag */
- Tcl_CmdInfo x_cinfo;
- t_plusstring *x_ctail; /* command arguments, parse validation flag */
- Tcl_Parse x_tailparse;
- int x_maxwords; /* as allocated */
- int x_nwords; /* as used, including command name */
- t_plusword *x_words; /* arguments, not evaluated */
- t_plusword x_wordsini[PLUSTOT_INIMAXWORDS];
- int x_maxargs; /* == maxwords, except during growing */
- int x_argc; /* 0 or nwords, except during evaluation */
- Tcl_Obj **x_argv; /* command name and evaluated arguments */
- Tcl_Obj *x_argvini[PLUSTOT_INIMAXWORDS];
- int x_pseudoscalar;
- int x_nproxies;
- t_plusproxy **x_proxies;
- t_plusproxy *x_mainproxy; /* == x_proxies[0], unless pseudo-scalar */
- int x_grabwarned;
-} t_plustot;
-
static t_class *plusproxy_class;
-static t_class *plustot_class;
-/* Create a variable here only for the main slot. Other slots are to be
- filled during the second parsing pass, in order to fill only the slots
- that are actually referenced. If ndx is negative, then create
- a pseudo-scalar, otherwise this is a pseudo-array element. */
-static t_plusproxy *plusproxy_new(t_pd *master, int ndx, t_plustin *tin)
+/* Variable is to be created during the second parsing pass, in order to give
+ it an actual name, and in order to fill only the slots that are actually
+ referenced. If ndx is negative, then this is a pseudo-scalar, otherwise
+ this is a pseudo-array element. */
+static t_plusproxy *plusproxy_new(t_plustot *master, int ndx,
+ int ishot, int istransient,
+ t_plustin *tin)
{
t_plusproxy *pp = (t_plusproxy *)pd_new(plusproxy_class);
pp->pp_master = master;
- pp->pp_var = (ndx > 0 ? 0 : plusvar_new("in", (ndx ? 0 : "0"), tin));
- if (pp->pp_var)
- {
- plusbob_preserve((t_plusbob *)pp->pp_var);
- plusbob_setowner((t_plusbob *)pp->pp_var, master);
- }
+ pp->pp_var = 0;
pp->pp_ndx = ndx;
- pp->pp_doit = (ndx < 1);
+ pp->pp_ishot = ishot;
+ pp->pp_istransient = istransient;
pp->pp_warned = 0;
return (pp);
}
@@ -1060,51 +1074,84 @@ static void plusproxy_free(t_plusproxy *pp)
{
#ifdef PLUSTOT_DEBUG
loudbug_post("plusproxy_free (%s %d)",
- (pp->pp_var ? pp->pp_var->var_name : "empty"), pp->pp_ndx);
+ (pp->pp_var ? pp->pp_var->var_name : "deaf"), pp->pp_ndx);
#endif
if (pp->pp_var)
plusbob_release((t_plusbob *)pp->pp_var);
}
-static void plusproxy_emptyhit(t_plusproxy *pp)
+static void plusproxy_deafhit(t_plusproxy *pp)
{
if (!pp->pp_warned)
{
- loud_error(pp->pp_master, "empty slot hit");
+ loud_error((t_pd *)pp->pp_master, "deaf slot hit");
pp->pp_warned = 1;
}
}
+static void plusproxy_clear(t_plusproxy *pp)
+{
+ if (pp->pp_var)
+ plusvar_clear(pp->pp_var, 1);
+ else
+ plusproxy_deafhit(pp);
+}
+
static void plusproxy_bang(t_plusproxy *pp)
{
if (pp->pp_var)
- plusvar_push(pp->pp_var);
+ plustot_doit(pp->pp_master, 1);
else
- plusproxy_emptyhit(pp);
+ plusproxy_deafhit(pp);
}
static void plusproxy_float(t_plusproxy *pp, t_float f)
{
if (pp->pp_var)
- plusvar_setfloat(pp->pp_var, f, pp->pp_doit);
- else
- plusproxy_emptyhit(pp);
+ {
+ plusvar_setfloat(pp->pp_var, f, 0);
+ if (pp->pp_ishot)
+ plustot_doit(pp->pp_master, 1);
+ }
+ else plusproxy_deafhit(pp);
}
static void plusproxy_symbol(t_plusproxy *pp, t_symbol *s)
{
if (pp->pp_var)
- plusvar_setsymbol(pp->pp_var, s, pp->pp_doit);
- else
- plusproxy_emptyhit(pp);
+ {
+ plusvar_setsymbol(pp->pp_var, s, 0);
+ if (pp->pp_ishot)
+ plustot_doit(pp->pp_master, 1);
+ }
+ else plusproxy_deafhit(pp);
}
static void plusproxy_list(t_plusproxy *pp, t_symbol *s, int ac, t_atom *av)
{
if (pp->pp_var)
- plusvar_setlist(pp->pp_var, ac, av, pp->pp_doit);
- else
- plusproxy_emptyhit(pp);
+ {
+ plusvar_setlist(pp->pp_var, ac, av, 0);
+ if (pp->pp_ishot)
+ plustot_doit(pp->pp_master, 1);
+ }
+ else plusproxy_deafhit(pp);
+}
+
+static void plusproxy_set(t_plusproxy *pp, t_symbol *s, int ac, t_atom *av)
+{
+ if (pp->pp_var)
+ {
+ if (ac == 1)
+ {
+ if (av->a_type == A_FLOAT)
+ plusvar_setfloat(pp->pp_var, av->a_w.w_float, 0);
+ else if (av->a_type == A_SYMBOL)
+ plusvar_setsymbol(pp->pp_var, av->a_w.w_symbol, 0);
+ }
+ else plusvar_setlist(pp->pp_var, ac, av, 0);
+ }
+ else plusproxy_deafhit(pp);
}
#ifdef PLUSTOT_DEBUG
@@ -1114,15 +1161,64 @@ static void plusproxy_debug(t_plusproxy *pp)
t_symbol *id = plusenv_getid((t_plusenv *)tin);
t_symbol *glname = plustin_getglistname(tin);
loudbug_post("+proxy %d, glist %x",
- pp->pp_ndx, (int)((t_plustot *)pp->pp_master)->x_glist);
+ pp->pp_ndx, (int)((t_plusobject *)pp->pp_master)->po_glist);
loudbug_post(" plustin '%s' (%s) over %x", (id ? id->s_name : "default"),
(glname ? glname->s_name : "<anonymous>"),
(int)tin->tin_interp);
}
#endif
+typedef struct _plusword
+{
+ int pw_type;
+ Tcl_Obj *pw_ob;
+ Tcl_Token *pw_ndxv; /* index part of this word (if array variable) */
+ int pw_ndxc; /* numComponents of the above */
+} t_plusword;
+
+#define PLUSTOT_MAXINLETS 256 /* LATER rethink */
+#define PLUSTOT_INIMAXWORDS 16
+
+/* LATER elaborate */
+#define PLUSTOT_ERRUNKNOWN -1
+#define PLUSTOT_ERROTHER -2
+
+struct _plustot
+{
+ t_plusobject x_plusobject;
+ t_plustob *x_tob; /* interpreter's result (after invocation) */
+ t_scriptlet *x_script;
+ Tcl_Obj *x_cname; /* command name, main validation flag */
+ Tcl_CmdInfo x_cinfo;
+ t_plusstring *x_ctail; /* command arguments, parse validation flag */
+ Tcl_Parse x_tailparse;
+ int x_maxwords; /* as allocated */
+ int x_nwords; /* as used, including command name */
+ t_plusword *x_words; /* arguments, not evaluated */
+ t_plusword x_wordsini[PLUSTOT_INIMAXWORDS];
+ int x_maxargs; /* == maxwords, except during growing */
+ int x_argc; /* 0 or nwords, except during evaluation */
+ Tcl_Obj **x_argv; /* command name and evaluated arguments */
+ Tcl_Obj *x_argvini[PLUSTOT_INIMAXWORDS];
+ int x_pseudoscalar;
+ int x_nproxies;
+ t_plusproxy **x_proxies;
+ t_plusproxy *x_mainproxy; /* == x_proxies[0] or null if 1st slot deaf */
+ t_plusproxy *x_deafproxy; /* dummy/x_proxies[0] if deaf, else null */
+ int x_grabwarned;
+ int x_isloud;
+};
+
+static t_class *plustot_class;
+
+static void plustot_tclerror(t_plustot *x, Tcl_Interp *interp, char *msg)
+{
+ if (x->x_isloud)
+ plusloud_tclerror((t_pd *)x, interp, msg);
+}
+
/* First pass (!doit): determine number of slots.
- Second pass (doit): create variables for non-empty slots. */
+ Second pass (doit): create variables for listening slots. */
static int plustot_usevariable(t_plustot *x, Tcl_Token *tp, int doit)
{
int nc = tp->numComponents;
@@ -1147,10 +1243,18 @@ static int plustot_usevariable(t_plustot *x, Tcl_Token *tp, int doit)
tp++;
if (nc && tp->type == TCL_TOKEN_TEXT)
{
- if (strncmp(tp->start, "in", tp->size))
+ int ishot = 0, iscold = 0, istransient = 0;
+ if (strncmp(tp->start, "Hin", tp->size) == 0)
+ ishot = 1;
+ else if (strncmp(tp->start, "Cin", tp->size) == 0)
+ iscold = 1;
+ else if (strncmp(tp->start, "Tin", tp->size) == 0)
+ istransient = ishot = 1;
+ if (!ishot && !iscold && strncmp(tp->start, "in", tp->size))
{
/* regular variable */
- /* LATER consider tracing it (2nd pass) */
+ /* LATER it should be write-traced (2nd pass, but only if there are
+ pull inputs) in order to know when the object becomes stale */
}
else
{
@@ -1214,15 +1318,35 @@ static int plustot_usevariable(t_plustot *x, Tcl_Token *tp, int doit)
}
else if (inno < x->x_nproxies)
{
- if (inno > 0 && !x->x_proxies[inno]->pp_var)
+ t_plusproxy *pp = x->x_proxies[inno];
+ if (!pp->pp_var)
{
t_plusvar *var;
- char buf[8];
- sprintf(buf, "%d", inno);
- var = plusvar_new("in", buf, x->x_tob->tob_tin);
+ char buf[8], *ptr;
+ if (x->x_pseudoscalar)
+ ptr = 0;
+ else
+ sprintf(ptr = buf, "%d", inno);
+ if (istransient)
+ {
+ pp->pp_istransient = pp->pp_ishot = 1;
+ var = plusvar_new("Tin", ptr, x->x_tob->tob_tin);
+ }
+ else if (ishot)
+ {
+ pp->pp_ishot = 1;
+ var = plusvar_new("Hin", ptr, x->x_tob->tob_tin);
+ }
+ else if (iscold)
+ {
+ pp->pp_ishot = 0;
+ var = plusvar_new("Cin", ptr, x->x_tob->tob_tin);
+ }
+ /* keep defaults, as set in plustot_makeproxies(): */
+ else var = plusvar_new("in", ptr, x->x_tob->tob_tin);
plusbob_preserve((t_plusbob *)var);
plusbob_setowner((t_plusbob *)var, (t_pd *)x);
- x->x_proxies[inno]->pp_var = var;
+ pp->pp_var = var;
}
}
else
@@ -1376,28 +1500,42 @@ static int plustot_makeproxies(t_plustot *x)
Tcl_Interp *interp = x->x_tob->tob_tin->tin_interp;
if (interp)
{
- if (x->x_nproxies == 1)
+ if (x->x_nproxies == 0)
{
- x->x_mainproxy =
- plusproxy_new((t_pd *)x, (x->x_pseudoscalar ? -1 : 0),
- x->x_tob->tob_tin);
+ x->x_proxies = 0;
+ x->x_mainproxy = 0;
+ x->x_deafproxy = plusproxy_new(x, -2, 0, 0, x->x_tob->tob_tin);
}
- else if (x->x_nproxies > 1 && !x->x_pseudoscalar)
+ else if (x->x_nproxies == 1
+ || (x->x_nproxies > 1 && !x->x_pseudoscalar))
{
if (x->x_proxies = getbytes(x->x_nproxies * sizeof(*x->x_proxies)))
{
int i;
- for (i = 0; i < x->x_nproxies; i++)
- x->x_proxies[i] =
- plusproxy_new((t_pd *)x, i, x->x_tob->tob_tin);
+ x->x_proxies[0] =
+ plusproxy_new(x, (x->x_pseudoscalar ? -1 : 0), 1, 0,
+ x->x_tob->tob_tin);
for (i = 1; i < x->x_nproxies; i++)
+ {
+ x->x_proxies[i] =
+ plusproxy_new(x, i, 0, 0, x->x_tob->tob_tin);
plusinlet_new(&x->x_plusobject,
(t_pd *)x->x_proxies[i], 0, 0);
- x->x_mainproxy = x->x_proxies[0];
- /* second pass: traverse non-empty slots, create variables */
+ }
+ /* second pass: traverse listening slots, create variables */
plustot_parsevariables(x, interp,
x->x_ctail->ps_buf, x->x_ctail->ps_len,
&x->x_tailparse, 1);
+ if (x->x_proxies[0]->pp_var)
+ {
+ x->x_mainproxy = x->x_proxies[0];
+ x->x_deafproxy = 0;
+ }
+ else
+ {
+ x->x_mainproxy = 0;
+ x->x_deafproxy = x->x_proxies[0];
+ }
}
else goto proxiesfailed;
}
@@ -1437,7 +1575,7 @@ static int plustot_resetwords(t_plustot *x)
for (i = 1; i < x->x_nwords; i++)
PLUSDEBUG_DECRREFCOUNT(x->x_words[i].pw_ob, "plustot_resetwords");
x->x_nwords = 0;
- if (x->x_ctail)
+ if (x->x_ctail) /* does object command exist && is parse valid? */
{
int nwords = x->x_tailparse.numWords + 1;
if (nwords > x->x_maxwords)
@@ -1464,7 +1602,7 @@ static int plustot_resetargs(t_plustot *x)
PLUSDEBUG_DECRREFCOUNT(x->x_argv[i], "plustot_resetargs");
x->x_argc = 0;
x->x_argv[0] = x->x_cname;
- if (x->x_ctail)
+ if (x->x_ctail) /* does object command exist && is parse valid? */
{
int nargs = x->x_maxwords;
if (nargs > x->x_maxargs)
@@ -1588,7 +1726,7 @@ static int plustot_argsfromwords(t_plustot *x, Tcl_Interp *interp)
}
else
{
- plusloud_tclerror((t_pd *)x, interp, "bad word (command)");
+ plustot_tclerror(x, interp, "bad word (command)");
goto evalfailed;
}
}
@@ -1610,7 +1748,7 @@ static int plustot_argsfromwords(t_plustot *x, Tcl_Interp *interp)
}
else
{
- plusloud_tclerror((t_pd *)x, interp, "bad index");
+ plustot_tclerror(x, interp, "bad index");
goto evalfailed;
}
}
@@ -1624,7 +1762,7 @@ static int plustot_argsfromwords(t_plustot *x, Tcl_Interp *interp)
}
else
{
- plusloud_tclerror((t_pd *)x, interp, "bad word (variable)");
+ plustot_tclerror(x, interp, "bad word (variable)");
goto evalfailed;
}
}
@@ -1687,7 +1825,7 @@ static int plustot_argsfromtokens(t_plustot *x, Tcl_Interp *interp)
else
{
PLUSDEBUG_ENDPOST("plustot_argsfromtokens");
- plusloud_tclerror((t_pd *)x, interp, "bad token");
+ plustot_tclerror(x, interp, "bad token");
while (--i)
PLUSDEBUG_DECRREFCOUNT(x->x_argv[i],
"plustot_argsfromtokens");
@@ -1717,7 +1855,7 @@ static int plustot_push(t_plustot *x)
if (x->x_proxies)
{
int i;
- for (i = 1; i < x->x_nproxies; i++)
+ for (i = 0; i < x->x_nproxies; i++)
if (x->x_proxies[i]->pp_var)
if (!plusvar_push(x->x_proxies[i]->pp_var))
return (0);
@@ -1725,7 +1863,20 @@ static int plustot_push(t_plustot *x)
return (1);
}
-static int plustot_doit(t_plustot *x)
+static void plustot_cleartransients(t_plustot *x)
+{
+ if (x->x_proxies)
+ {
+ int i;
+ for (i = 0; i < x->x_nproxies; i++)
+ if (x->x_proxies[i]->pp_var && x->x_proxies[i]->pp_istransient)
+ plusvar_clear(x->x_proxies[i]->pp_var, 1);
+ }
+}
+
+/* This is the seed of it all: if sendit == 1, this routine executes
+ a full firing step, otherwise, it performs a plain evaluation. */
+static int plustot_doit(t_plustot *x, int sendit)
{
int result = 0;
Tcl_Interp *interp = x->x_tob->tob_tin->tin_interp;
@@ -1738,19 +1889,22 @@ static int plustot_doit(t_plustot *x)
if (plustob_grabresult(x->x_tob))
result = 1;
}
- else plusloud_tclerror((t_pd *)x, interp, "command failed");
+ else plustot_tclerror(x, interp, "command failed");
/* Although args are to be reset in the next call to
plustot_argsfromwords(), however, plusvar_preset() will be called
first, so, unless reset is done here, $ins would be shared there.
LATER rethink. */
plustot_resetargs(x);
+ plustot_cleartransients(x);
}
+ if (result && sendit)
+ outlet_plusbob(((t_object *)x)->ob_outlet, (t_plusbob *)x->x_tob);
return (result);
}
static void plustot_eval(t_plustot *x)
{
- plustot_doit(x);
+ plustot_doit(x, 0);
}
static void plustot_get(t_plustot *x)
@@ -1763,15 +1917,25 @@ static void plustot_get(t_plustot *x)
static void plustot_set(t_plustot *x, t_symbol *s, int ac, t_atom *av)
{
if (x->x_mainproxy)
+ plusproxy_set(x->x_mainproxy, s, ac, av);
+ else if (x->x_deafproxy)
+ plusproxy_deafhit(x->x_deafproxy);
+}
+
+static void plustot_clear(t_plustot *x)
+{
+ if (x->x_mainproxy)
+ plusproxy_clear(x->x_mainproxy);
+}
+
+static void plustot_clearall(t_plustot *x)
+{
+ if (x->x_proxies)
{
- if (ac == 1)
- {
- if (av->a_type == A_FLOAT)
- plusproxy_float(x->x_mainproxy, av->a_w.w_float);
- else if (av->a_type == A_SYMBOL)
- plusproxy_symbol(x->x_mainproxy, av->a_w.w_symbol);
- }
- else plusproxy_list(x->x_mainproxy, s, ac, av);
+ int i;
+ for (i = 0; i < x->x_nproxies; i++)
+ if (x->x_proxies[i]->pp_var)
+ plusvar_clear(x->x_proxies[i]->pp_var, 1);
}
}
@@ -1779,32 +1943,32 @@ static void plustot_bang(t_plustot *x)
{
if (x->x_mainproxy)
plusproxy_bang(x->x_mainproxy);
- if (plustot_doit(x))
- outlet_plusbob(((t_object *)x)->ob_outlet, (t_plusbob *)x->x_tob);
+ else
+ plustot_doit(x, 1);
}
static void plustot_float(t_plustot *x, t_float f)
{
if (x->x_mainproxy)
plusproxy_float(x->x_mainproxy, f);
- if (plustot_doit(x))
- outlet_plusbob(((t_object *)x)->ob_outlet, (t_plusbob *)x->x_tob);
+ else if (x->x_deafproxy)
+ plusproxy_deafhit(x->x_deafproxy);
}
static void plustot_symbol(t_plustot *x, t_symbol *s)
{
if (x->x_mainproxy)
plusproxy_symbol(x->x_mainproxy, s);
- if (plustot_doit(x))
- outlet_plusbob(((t_object *)x)->ob_outlet, (t_plusbob *)x->x_tob);
+ else if (x->x_deafproxy)
+ plusproxy_deafhit(x->x_deafproxy);
}
static void plustot_list(t_plustot *x, t_symbol *s, int ac, t_atom *av)
{
if (x->x_mainproxy)
plusproxy_list(x->x_mainproxy, s, ac, av);
- if (plustot_doit(x))
- outlet_plusbob(((t_object *)x)->ob_outlet, (t_plusbob *)x->x_tob);
+ else if (x->x_deafproxy)
+ plusproxy_deafhit(x->x_deafproxy);
}
static void plustot_tot(t_plustot *x, t_symbol *s, int ac, t_atom *av)
@@ -1862,10 +2026,11 @@ static void plustot_save(t_gobj *z, t_binbuf *bb)
#ifdef PLUSTOT_DEBUG
static void plustot_debug(t_plustot *x)
{
+ t_plusobject *po = (t_plusobject *)x;
t_plustin *tin = x->x_tob->tob_tin;
t_symbol *id = plusenv_getid((t_plusenv *)tin);
t_symbol *glname = plustin_getglistname(tin);
- loudbug_post("+tot, glist %x", (int)x->x_glist);
+ loudbug_post("+tot, glist %x", (int)po->po_glist);
loudbug_post(" plustin '%s' (%s) over %x", (id ? id->s_name : "default"),
(glname ? glname->s_name : "<anonymous>"),
(int)tin->tin_interp);
@@ -1879,7 +2044,7 @@ static void plustot_free(t_plustot *x)
int i;
plusbob_release((t_plusbob *)x->x_tob);
if (x->x_cname) PLUSDEBUG_DECRREFCOUNT(x->x_cname, "plustot_free");
- if (x->x_ctail)
+ if (x->x_ctail) /* does object command exist && is parse valid? */
{
for (i = 1; i < x->x_nwords; i++)
PLUSDEBUG_DECRREFCOUNT(x->x_words[i].pw_ob, "plustot_free");
@@ -1892,13 +2057,14 @@ static void plustot_free(t_plustot *x)
Tcl_FreeParse(&x->x_tailparse);
plusstring_release(x->x_ctail);
}
- if (x->x_mainproxy) pd_free((t_pd *)x->x_mainproxy);
if (x->x_proxies)
{
- for (i = 1; i < x->x_nproxies; i++)
+ for (i = 0; i < x->x_nproxies; i++)
pd_free((t_pd *)x->x_proxies[i]);
freebytes(x->x_proxies, x->x_nproxies * sizeof(*x->x_proxies));
}
+ else if (x->x_deafproxy)
+ pd_free((t_pd *)x->x_deafproxy);
if (x->x_script) scriptlet_free(x->x_script);
plusobject_free(&x->x_plusobject);
}
@@ -1941,23 +2107,25 @@ static void *plustot_new(t_symbol *s, int ac, t_atom *av)
return (0);
}
}
-#if 0
- /* FIXME forgot where this constraint came from, debug carefully... */
- if (ac)
-#endif
- {
- ctail = plusstring_fromatoms(ac, av, script);
- plusstring_preserve(ctail);
- }
+ /* If ac == 0, ctail is an empty plusstring, but not null. We rely
+ on getbytes(0), copybytes(x, 0), and freebytes(x, 0) being safe.
+ LATER reconsider using a separate parse validation flag, while
+ moving tests for a null ctail to where they really belong. */
+ ctail = plusstring_fromatoms(0, ac, av, script);
+ plusstring_preserve(ctail);
}
if ((tin = plustin_glistprovide(glist, PLUSTIN_GLIST_ANY, 0)) &&
(tob = plustob_new(tin, 0)))
{
- x = (t_plustot *)plusobject_new(plustot_class, cmdname, ac, av);
+ t_plusstring *vistext = plusstring_fromatoms(cmdname, ac, av, script);
+ plusstring_preserve(vistext);
+ x = (t_plustot *)
+ plusobject_new(plustot_class, cmdname, ac, av, vistext);
+ plusstring_release(vistext);
+ x->x_isloud = 1;
/* tin already preserved (plustob_new() did it) */
plusbob_preserve((t_plusbob *)tob);
plusbob_setowner((t_plusbob *)tob, (t_pd *)x);
- x->x_glist = glist;
x->x_tob = tob;
scriptlet_setowner(script, (t_pd *)x);
x->x_script = script;
@@ -1971,6 +2139,7 @@ static void *plustot_new(t_symbol *s, int ac, t_atom *av)
x->x_nproxies = 0;
x->x_proxies = 0;
x->x_mainproxy = 0;
+ x->x_deafproxy = 0;
x->x_grabwarned = 0;
if (cmdname && *cmdname->s_name)
{
@@ -1991,7 +2160,8 @@ static void *plustot_new(t_symbol *s, int ac, t_atom *av)
else loud_error((t_pd *)x, "command '%s' does not exist",
cmdname->s_name);
if (x->x_cname && ctail)
- {
+ { /* object command exists, now parse the arguments: */
+ /* 1. do syntax validation and locate pseudo-variables */
int nvars =
plustot_parsevariables(x, interp,
ctail->ps_buf, ctail->ps_len,
@@ -2000,18 +2170,34 @@ static void *plustot_new(t_symbol *s, int ac, t_atom *av)
{
int res = 1;
x->x_ctail = ctail;
- if (x->x_nproxies)
- res = plustot_makeproxies(x);
+ /* 2. create input slots */
+ res = plustot_makeproxies(x);
if (res)
+ /* 3. shallow objectifying: create a Tcl_Obj for
+ each argument; subcommand arguments will be
+ compiled to bytecode during first evaluation --
+ either below, or when the +tot object fires. */
res = plustot_makewords(x);
- if (!res)
+ if (res)
+ {
+ /* creation time evaluation, LATER rethink:
+ should this be immediate or scheduled? */
+ x->x_isloud = 0;
+ plustot_doit(x, 0);
+ x->x_isloud = 1;
+ }
+ else
+ {
+ /* here we invalidate parse, but leave the command
+ valid, LATER revisit */
x->x_ctail = 0;
+ }
Tcl_FreeParse(&x->x_tailparse);
}
else
{
if (nvars == PLUSTOT_ERRUNKNOWN)
- plusloud_tclerror((t_pd *)x, interp,
+ plustot_tclerror(x, interp,
"parsing command arguments failed");
else
Tcl_FreeParse(&x->x_tailparse);
@@ -2039,7 +2225,8 @@ static void *plustot_new(t_symbol *s, int ac, t_atom *av)
}
void plusobject_widgetfree(t_plusobject *po);
-void plusobject_widgetcreate(t_plusobject *po, t_symbol *s, int ac, t_atom *av);
+void plusobject_widgetcreate(t_plusobject *po, t_symbol *s, int ac, t_atom *av,
+ t_plusstring *ps);
void plusclass_widgetsetup(t_class *c);
void plusobject_free(t_plusobject *po)
@@ -2047,12 +2234,14 @@ void plusobject_free(t_plusobject *po)
plusobject_widgetfree(po);
}
-t_plusobject *plusobject_new(t_class *c, t_symbol *s, int ac, t_atom *av)
+t_plusobject *plusobject_new(t_class *c, t_symbol *s, int ac, t_atom *av,
+ t_plusstring *ps)
{
t_plusobject *po = (t_plusobject *)pd_new(c);
+ po->po_glist = canvas_getcurrent();
po->po_ninlets = 1;
po->po_noutlets = 0;
- plusobject_widgetcreate(po, s, ac, av);
+ plusobject_widgetcreate(po, s, ac, av, ps);
return (po);
}
@@ -2094,6 +2283,10 @@ void plustot_setup(void)
class_addlist(plustot_class, plustot_list);
class_addmethod(plustot_class, (t_method)plustot_eval,
gensym("eval"), 0);
+ class_addmethod(plustot_class, (t_method)plustot_clear,
+ gensym("clear"), 0);
+ class_addmethod(plustot_class, (t_method)plustot_clearall,
+ gensym("clearall"), 0);
class_addmethod(plustot_class, (t_method)plustot_set,
gensym("set"), A_GIMME, 0);
class_addmethod(plustot_class, (t_method)plustot_get,
@@ -2109,6 +2302,10 @@ void plustot_setup(void)
class_addfloat(plusproxy_class, plusproxy_float);
class_addsymbol(plusproxy_class, plusproxy_symbol);
class_addlist(plusproxy_class, plusproxy_list);
+ class_addmethod(plusproxy_class, (t_method)plusproxy_clear,
+ gensym("clear"), 0);
+ class_addmethod(plusproxy_class, (t_method)plusproxy_set,
+ gensym("set"), A_GIMME, 0);
#ifdef PLUSTOT_DEBUG
class_addmethod(plustot_class, (t_method)plustot_debug,
diff --git a/toxy/plustot.env.c b/toxy/plustot.env.c
index 23ec82f..ba28bbb 100644
--- a/toxy/plustot.env.c
+++ b/toxy/plustot.env.c
@@ -111,7 +111,7 @@ void *plustot_env_new(t_symbol *s, int ac, t_atom *av)
|| (tin = plustin_glistprovide(gl, PLUSTIN_GLIST_THIS, 1)))
{
int warned = 0;
- x = (t_plustot_env *)plusobject_new(plustot_env_class, s, ac, av);
+ x = (t_plustot_env *)plusobject_new(plustot_env_class, s, ac, av, 0);
x->x_tin = tin;
plusbob_preserve((t_plusbob *)tin);
x->x_glist = gl;
diff --git a/toxy/plustot.h b/toxy/plustot.h
index 509e100..0cc6fa6 100644
--- a/toxy/plustot.h
+++ b/toxy/plustot.h
@@ -23,12 +23,16 @@ EXTERN_STRUCT _plustob;
EXTERN_STRUCT _plusvar;
#define t_plusvar struct _plusvar
+EXTERN_STRUCT _plusstring;
+#define t_plusstring struct _plusstring
+
EXTERN_STRUCT _pluswidget;
#define t_pluswidget struct _pluswidget
typedef struct _plusobject
{
t_object po_ob;
+ t_glist *po_glist;
t_pluswidget *po_widget;
int po_ninlets;
int po_noutlets;
@@ -65,6 +69,7 @@ t_plustin *plustag_tobtin(t_symbol *s, t_pd *caller);
Tcl_Obj *plustag_tobvalue(t_symbol *s, t_pd *caller);
Tcl_Obj *plusatom_tobvalue(t_atom *ap, t_pd *caller);
+int plustob_clear(t_plustob *tob);
Tcl_Obj *plustob_set(t_plustob *tob, t_plustin *tin, Tcl_Obj *ob);
Tcl_Obj *plustob_setfloat(t_plustob *tob, t_float f);
Tcl_Obj *plustob_setsymbol(t_plustob *tob, t_symbol *s);
@@ -78,13 +83,19 @@ t_plusvar *plusvar_create(t_plustype *tp, t_plustin *tin, Tcl_Obj *ob,
t_plusvar *plusvar_new(char *name, char *index, t_plustin *tin);
Tcl_Obj *plusvar_push(t_plusvar *var);
Tcl_Obj *plusvar_pull(t_plusvar *var);
+void plusvar_clear(t_plusvar *var, int doit);
Tcl_Obj *plusvar_set(t_plusvar *var, Tcl_Obj *ob, int doit);
Tcl_Obj *plusvar_setfloat(t_plusvar *var, t_float f, int doit);
Tcl_Obj *plusvar_setsymbol(t_plusvar *var, t_symbol *s, int doit);
Tcl_Obj *plusvar_setlist(t_plusvar *var, int ac, t_atom *av, int doit);
+void plusstring_preserve(t_plusstring *ps);
+void plusstring_release(t_plusstring *ps);
+char *plusstring_get(t_plusstring *ps, int *lenp);
+
void plusobject_free(t_plusobject *po);
-t_plusobject *plusobject_new(t_class *c, t_symbol *s, int ac, t_atom *av);
+t_plusobject *plusobject_new(t_class *c, t_symbol *s, int ac, t_atom *av,
+ t_plusstring *ps);
t_inlet *plusinlet_new(t_plusobject *po, t_pd *dest,
t_symbol *s1, t_symbol *s2);
t_outlet *plusoutlet_new(t_plusobject *po, t_symbol *s);
diff --git a/toxy/plustot.in.c b/toxy/plustot.in.c
index 3cb3b6c..37c1bc9 100644
--- a/toxy/plustot.in.c
+++ b/toxy/plustot.in.c
@@ -87,7 +87,7 @@ void *plustot_in_new(t_symbol *s, int ac, t_atom *av)
if ((tin = plustin_glistprovide(glist, PLUSTIN_GLIST_ANY, 0)) &&
(tob = plustob_new(tin, 0)))
{
- x = (t_plustot_in *)plusobject_new(plustot_in_class, s, ac, av);
+ x = (t_plustot_in *)plusobject_new(plustot_in_class, s, ac, av, 0);
plusbob_preserve((t_plusbob *)tob);
plusbob_setowner((t_plusbob *)tob, (t_pd *)x);
plustob_setlist(tob, ac, av);
diff --git a/toxy/plustot.out.c b/toxy/plustot.out.c
index 564e907..80c64dc 100644
--- a/toxy/plustot.out.c
+++ b/toxy/plustot.out.c
@@ -58,7 +58,7 @@ static void plustot_out_free(t_plustot_out *x)
void *plustot_out_new(t_symbol *s, int ac, t_atom *av)
{
t_plustot_out *x =
- (t_plustot_out *)plusobject_new(plustot_out_class, s, ac, av);
+ (t_plustot_out *)plusobject_new(plustot_out_class, s, ac, av, 0);
x->x_bb = binbuf_new();
plusoutlet_new(&x->x_plusobject, &s_anything);
return (x);
diff --git a/toxy/plustot.print.c b/toxy/plustot.print.c
index 889ded3..b622d8f 100644
--- a/toxy/plustot.print.c
+++ b/toxy/plustot.print.c
@@ -81,7 +81,7 @@ static void plustot_print_free(t_plustot_print *x)
void *plustot_print_new(t_symbol *s, int ac, t_atom *av)
{
t_plustot_print *x =
- (t_plustot_print *)plusobject_new(plustot_print_class, s, ac, av);
+ (t_plustot_print *)plusobject_new(plustot_print_class, s, ac, av, 0);
x->x_label = (ac && av->a_type == A_SYMBOL ? av->a_w.w_symbol : 0);
x->x_bb = binbuf_new();
return (x);
diff --git a/toxy/plustot.qlist.c b/toxy/plustot.qlist.c
index 4be5430..a098df3 100644
--- a/toxy/plustot.qlist.c
+++ b/toxy/plustot.qlist.c
@@ -180,7 +180,8 @@ void *plustot_qlist_new(t_symbol *s, int ac, t_atom *av)
if ((tin = plustin_glistprovide(glist, PLUSTIN_GLIST_ANY, 0)) &&
(tob = plustob_new(tin, 0)))
{
- x = (t_plustot_qlist *)plusobject_new(plustot_qlist_class, s, ac, av);
+ x = (t_plustot_qlist *)
+ plusobject_new(plustot_qlist_class, s, ac, av, 0);
plusbob_preserve((t_plusbob *)tob);
plusbob_setowner((t_plusbob *)tob, (t_pd *)x);
plustob_setlist(tob, ac, av);
diff --git a/toxy/plustot.var.c b/toxy/plustot.var.c
index 9cb2453..338c044 100644
--- a/toxy/plustot.var.c
+++ b/toxy/plustot.var.c
@@ -88,7 +88,7 @@ void *plustot_var_new(t_symbol *s, int ac, t_atom *av)
(tin = plustin_glistprovide(glist, PLUSTIN_GLIST_ANY, 0)) &&
(var = plusvar_new(av->a_w.w_symbol->s_name, 0, tin)))
{
- x = (t_plustot_var *)plusobject_new(plustot_var_class, s, ac, av);
+ x = (t_plustot_var *)plusobject_new(plustot_var_class, s, ac, av, 0);
plusbob_preserve((t_plusbob *)var);
plusbob_setowner((t_plusbob *)var, (t_pd *)x);
plusvar_setlist(var, ac - 1, av + 1, 1);
diff --git a/toxy/pluswidget.c b/toxy/pluswidget.c
index 050b2a1..0deb11a 100644
--- a/toxy/pluswidget.c
+++ b/toxy/pluswidget.c
@@ -20,10 +20,11 @@
struct _pluswidget
{
- char *pw_vistext; /* binbuf_gettext()-style (no null termination) */
- int pw_vissize;
- int pw_rtextactive;
- int pw_ishit;
+ t_plusstring *pw_visstring;
+ char *pw_visbuf; /* binbuf_gettext()-style: no null termination */
+ int pw_vissize;
+ int pw_rtextactive;
+ int pw_ishit;
};
/* Code that might be merged back to g_text.c starts here: */
@@ -145,7 +146,7 @@ static void pluswidget_select(t_gobj *z, t_glist *glist, int state)
glist, rtext_gettag(y));
else
sys_vgui(".x%lx.c itemconfigure %s -text {%.*s} -fill brown\n",
- glist, rtext_gettag(y), pw->pw_vissize, pw->pw_vistext);
+ glist, rtext_gettag(y), pw->pw_vissize, pw->pw_visbuf);
}
}
@@ -174,7 +175,7 @@ static void pluswidget_vis(t_gobj *z, t_glist *glist, int vis)
pluswidget_drawborder((t_text *)z, glist, rtext_gettag(y), 1);
rtext_draw(y);
sys_vgui(".x%lx.c itemconfigure %s -text {%.*s} -fill brown\n",
- glist, rtext_gettag(y), pw->pw_vissize, pw->pw_vistext);
+ glist, rtext_gettag(y), pw->pw_vissize, pw->pw_visbuf);
}
}
else
@@ -191,9 +192,13 @@ static void pluswidget_vis(t_gobj *z, t_glist *glist, int vis)
static int pluswidget_click(t_gobj *z, t_glist *glist, int xpix, int ypix,
int shift, int alt, int dbl, int doit)
{
- if (doit)
- pd_bang((t_pd *)z);
- return (1);
+ if (glist->gl_havewindow)
+ {
+ if (doit)
+ pd_bang((t_pd *)z);
+ return (1);
+ }
+ else return (0);
}
static t_widgetbehavior pluswidget_widgetbehavior =
@@ -214,33 +219,50 @@ void plusobject_widgetfree(t_plusobject *po)
t_pluswidget *pw = po->po_widget;
if (pw)
{
- if (pw->pw_vistext)
- freebytes(pw->pw_vistext, pw->pw_vissize);
+ if (pw->pw_visstring)
+ plusstring_release(pw->pw_visstring);
+ else if (pw->pw_visbuf)
+ freebytes(pw->pw_visbuf, pw->pw_vissize);
freebytes(pw, sizeof(*pw));
}
}
-void plusobject_widgetcreate(t_plusobject *po, t_symbol *s, int ac, t_atom *av)
+/* assuming non-null ps will remain constant, LATER rethink */
+void plusobject_widgetcreate(t_plusobject *po, t_symbol *s, int ac, t_atom *av,
+ t_plusstring *ps)
{
t_pluswidget *pw = getbytes(sizeof(*pw));
- t_binbuf *inbb = binbuf_new();
- if (!s || s == &s_)
- s = plusps_tot;
- po->po_widget = pw;
- if ((s != totps_plustot && s != plusps_tot) || ac == 0)
+ pw->pw_visstring = 0;
+ if (ps)
{
- t_atom at;
- if (s == totps_plustot)
+ plusstring_preserve(ps);
+ pw->pw_visbuf = plusstring_get(ps, &pw->pw_vissize);
+ if (pw->pw_vissize > 0)
+ pw->pw_visstring = ps;
+ else
+ plusstring_release(ps);
+ }
+ if (pw->pw_visstring == 0)
+ {
+ t_binbuf *inbb = binbuf_new();
+ if (!s || s == &s_)
s = plusps_tot;
- SETSYMBOL (&at, s);
- binbuf_add(inbb, 1, &at);
+ if ((s != totps_plustot && s != plusps_tot) || ac == 0)
+ {
+ t_atom at;
+ if (s == totps_plustot)
+ s = plusps_tot;
+ SETSYMBOL (&at, s);
+ binbuf_add(inbb, 1, &at);
+ }
+ if (ac > 0)
+ binbuf_add(inbb, ac, av);
+ binbuf_gettext(inbb, &pw->pw_visbuf, &pw->pw_vissize);
+ binbuf_free(inbb);
}
- if (ac > 0)
- binbuf_add(inbb, ac, av);
- binbuf_gettext(inbb, &pw->pw_vistext, &pw->pw_vissize);
- binbuf_free(inbb);
pw->pw_rtextactive = 0;
pw->pw_ishit = 0;
+ po->po_widget = pw;
}
void plusclass_widgetsetup(t_class *c)