aboutsummaryrefslogtreecommitdiff
path: root/shared/common/port.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared/common/port.c')
-rw-r--r--shared/common/port.c143
1 files changed, 86 insertions, 57 deletions
diff --git a/shared/common/port.c b/shared/common/port.c
index 65cf59f..556af8f 100644
--- a/shared/common/port.c
+++ b/shared/common/port.c
@@ -2,10 +2,10 @@
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
-/* FIXME inlet/outlet vs inlet~/outlet~ */
/* LATER think about abstractions */
/* LATER sort out escaping rules (also revisit binport.c) */
/* LATER quoting */
+/* LATER rethink inlet/inlet~ case */
#ifdef UNIX
#include <unistd.h>
@@ -19,6 +19,7 @@
#include "g_canvas.h"
#include "unstable/forky.h"
#include "unstable/fragile.h"
+#include "unstable/fringe.h"
#include "common/loud.h"
#include "common/grow.h"
#include "common/binport.h"
@@ -44,6 +45,7 @@ typedef struct _port
t_binbuf *x_oldbb;
t_binbuf *x_newbb;
int x_nobj;
+ int x_withbogus;
int x_inatoms;
t_atom *x_inmess;
int x_outsize;
@@ -58,6 +60,8 @@ typedef struct _port
static t_symbol *portps_bogus;
static t_symbol *portps_cleanup;
+static t_symbol *portps_inlet;
+static t_symbol *portps_outlet;
static t_float port_floatarg(t_port *x, int ndx)
{
@@ -118,7 +122,7 @@ static void port_setxy(t_port *x, int ndx, t_atom *ap)
SETFLOAT(ap, f);
}
-static void import_addclassname(t_binbuf *bb, char *outname, t_atom *inatom)
+static void import_addclassname(t_port *x, char *outname, t_atom *inatom)
{
t_atom at;
if (outname)
@@ -129,15 +133,18 @@ static void import_addclassname(t_binbuf *bb, char *outname, t_atom *inatom)
t_symbol *insym = inatom->a_w.w_symbol;
if (insym != &s_bang && insym != &s_float &&
insym != &s_symbol && insym != &s_list &&
- zgetfn(&pd_objectmaker, insym) == 0)
+ (insym == portps_inlet || insym == portps_outlet ||
+ zgetfn(&pd_objectmaker, insym) == 0))
+
{
+ x->x_withbogus = 1;
SETSYMBOL(&at, portps_bogus);
- binbuf_add(bb, 1, &at);
+ binbuf_add(x->x_newbb, 1, &at);
}
SETSYMBOL(&at, insym);
}
else at = *inatom;
- binbuf_add(bb, 1, &at);
+ binbuf_add(x->x_newbb, 1, &at);
}
static int import_obj(t_port *x, char *name)
@@ -146,7 +153,7 @@ static int import_obj(t_port *x, char *name)
binbuf_addv(x->x_newbb, "ssff",
gensym("#X"), gensym("obj"),
port_xarg(x, ndx), port_yarg(x, ndx + 1));
- import_addclassname(x->x_newbb, name, &x->x_inmess[ndx == 2 ? 6 : 2]);
+ import_addclassname(x, name, &x->x_inmess[ndx == 2 ? 6 : 2]);
binbuf_addsemi(x->x_newbb);
x->x_nobj++;
return (PORT_NEXT);
@@ -163,7 +170,7 @@ static int import_objarg(t_port *x, char *name)
SETSYMBOL(out, gensym("obj")); out++;
port_setxy(x, ndx, out);
binbuf_add(x->x_newbb, 4, x->x_outmess);
- import_addclassname(x->x_newbb, name, &x->x_inmess[ndx == 2 ? 6 : 2]);
+ import_addclassname(x, name, &x->x_inmess[ndx == 2 ? 6 : 2]);
out = x->x_outmess;
for (ndx = 7; ndx < x->x_inatoms; ndx++)
*out++ = *in++;
@@ -204,6 +211,8 @@ static int imaction_vpatcher(t_port *x, char *arg)
static int imaction_patcher(t_port *x, char *arg)
{
+ binbuf_addv(x->x_newbb, "ss;", portps_cleanup, portps_cleanup);
+ x->x_withbogus = 0;
binbuf_addv(x->x_newbb, "ssffss;",
gensym("#X"), gensym("restore"),
port_xarg(x, 2), port_yarg(x, 3),
@@ -238,7 +247,7 @@ static int imaction_scope(t_port *x, char *name)
xpix = (int)out++->a_w.w_float;
ypix = (int)out->a_w.w_float;
binbuf_add(x->x_newbb, 4, x->x_outmess);
- import_addclassname(x->x_newbb, name, &x->x_inmess[2]);
+ import_addclassname(x, name, &x->x_inmess[2]);
out = x->x_outmess;
port_setxy(x, 5, out);
out++->a_w.w_float -= xpix;
@@ -305,16 +314,22 @@ static int imaction_message(t_port *x, char *arg)
return (PORT_NEXT);
}
-/* FIXME this is no longer true */
-static int imaction_inlet(t_port *x, char *arg)
+static int imaction_io(t_port *x, char *arg)
{
- return (import_obj(x, (port_floatarg(x, 5) ? "inlet~" : "inlet")));
-}
-
-/* FIXME this is no longer true */
-static int imaction_outlet(t_port *x, char *arg)
-{
- return (import_obj(x, (port_floatarg(x, 5) ? "outlet~" : "outlet")));
+ binbuf_addv(x->x_newbb, "ssff",
+ gensym("#X"), gensym("obj"),
+ port_xarg(x, 2), port_yarg(x, 3));
+ if (x->x_inmess[1].a_w.w_symbol == portps_inlet ||
+ x->x_inmess[1].a_w.w_symbol == portps_outlet)
+ {
+ t_atom at;
+ SETSYMBOL(&at, portps_bogus);
+ binbuf_add(x->x_newbb, 1, &at);
+ }
+ binbuf_add(x->x_newbb, 1, &x->x_inmess[1]);
+ binbuf_addsemi(x->x_newbb);
+ x->x_nobj++;
+ return (PORT_NEXT);
}
static int imaction_number(t_port *x, char *arg)
@@ -421,10 +436,10 @@ static t_portslot imslots__P[] =
{ "message", imaction_message, 0, 0, 0 },
{ "newobj", import_objarg, 0, &imnode_newobj, 0 },
{ "newex", import_objarg, 0, &imnode_newex, 0 },
- { "inlet", imaction_inlet, 0, 0, 0 },
- { "inlet~", imaction_inlet, 0, 0, 0 },
- { "outlet", imaction_outlet, 0, 0, 0 },
- { "outlet~", imaction_outlet, 0, 0, 0 },
+ { "inlet", imaction_io, 0, 0, 0 },
+ { "inlet~", imaction_io, 0, 0, 0 },
+ { "outlet", imaction_io, 0, 0, 0 },
+ { "outlet~", imaction_io, 0, 0, 0 },
{ "number", imaction_number, 0, 0, 0 },
{ "flonum", imaction_number, 0, 0, 0 },
{ "button", import_obj, "bng", 0, 0 },
@@ -503,8 +518,8 @@ static void port_dochecksetup(t_portnode *node)
}
}
-#define BOGUS_NINLETS 15
-#define BOGUS_NOUTLETS 16
+#define BOGUS_NINLETS 23
+#define BOGUS_NOUTLETS 24
typedef struct _bogus
{
@@ -587,12 +602,7 @@ static void bogus_cleanup(t_bogus *x)
#ifdef PORT_DEBUG
post("%d outlets deleted", i);
#endif
- if (x->x_glist->gl_editor) /* FIXME what is the right condition? */
- {
- t_rtext *rt;
- if (rt = glist_findrtext(x->x_glist, t))
- rtext_retext(rt);
- }
+ glist_retext(x->x_glist, t);
}
else bug("bogus_cleanup");
x->x_glist = 0;
@@ -617,17 +627,13 @@ static void *bogus_new(t_symbol *s, int ac, t_atom *av)
if (av->a_type == A_SYMBOL)
{
t_pd *z;
- typedmess(&pd_objectmaker, av->a_w.w_symbol, ac - 1, av + 1);
- if (z = pd_newest())
+ if (z = forky_newobject(av->a_w.w_symbol, ac - 1, av + 1))
{
- if (pd_checkobject(z))
- {
- t_bogushook *y = (t_bogushook *)pd_new(bogushook_class);
- y->x_who = z;
- y->x_glist = glist;
- pd_bind((t_pd *)y, portps_cleanup);
- y->x_clock = clock_new(y, (t_method)bogushook_tick);
- }
+ t_bogushook *y = (t_bogushook *)pd_new(bogushook_class);
+ y->x_who = z;
+ y->x_glist = glist;
+ pd_bind((t_pd *)y, portps_cleanup);
+ y->x_clock = clock_new(y, (t_method)bogushook_tick);
#ifdef PORT_DEBUG
post("reclaiming %s", av->a_w.w_symbol->s_name);
#endif
@@ -655,22 +661,42 @@ static void bogushook_cleanup(t_bogushook *x)
{
t_text *t = (t_text *)x->x_who;
int ac = binbuf_getnatom(t->te_binbuf);
- if (ac)
+ if (ac > 1)
{
+ int dorecreate = 0;
t_atom *av = binbuf_getvec(t->te_binbuf);
t_binbuf *bb = binbuf_new();
#ifdef PORT_DEBUG
startpost("hook-adjusting");
binbuf_print(t->te_binbuf);
#endif
- binbuf_add(bb, ac - 1, av + 1);
- binbuf_free(t->te_binbuf);
- t->te_binbuf = bb;
- if (x->x_glist->gl_editor) /* FIXME what is the right condition? */
+ ac--; av++;
+ if (av->a_type == A_SYMBOL)
+ {
+ if (av->a_w.w_symbol == portps_outlet)
+ {
+ if (forky_hasfeeders((t_object *)x->x_who, x->x_glist,
+ 0, &s_signal))
+ {
+ t_atom at;
+ SETSYMBOL(&at, gensym("outlet~"));
+ binbuf_add(bb, 1, &at);
+ ac--; av++;
+ dorecreate = 1;
+ }
+ }
+ else if (av->a_w.w_symbol == portps_inlet)
+ {
+ /* LATER */
+ }
+ }
+ if (ac) binbuf_add(bb, ac, av);
+ if (dorecreate) gobj_recreate(x->x_glist, (t_gobj *)t, bb);
+ else
{
- t_rtext *rt;
- if (rt = glist_findrtext(x->x_glist, t))
- rtext_retext(rt);
+ binbuf_free(t->te_binbuf);
+ t->te_binbuf = bb;
+ glist_retext(x->x_glist, t);
}
}
else bug("bogushook_cleanup");
@@ -697,6 +723,8 @@ static void port_checksetup(void)
portps_bogus = gensym("_port.bogus");
portps_cleanup = gensym("_port.cleanup");
+ portps_inlet = gensym("inlet");
+ portps_outlet = gensym("outlet");
if (zgetfn(&pd_objectmaker, portps_bogus) == 0)
{
@@ -720,6 +748,7 @@ static t_port *port_new(void)
{
t_port *x = (t_port *)getbytes(sizeof(*x));
x->x_oldbb = binbuf_new();
+ x->x_withbogus = 0;
x->x_outsize = PORT_INISIZE;
x->x_outatoms = 0;
x->x_outmess = x->x_outini;
@@ -731,6 +760,16 @@ static t_port *port_new(void)
static void port_free(t_port *x)
{
+ if (portps_cleanup->s_thing)
+ {
+ /* clean up toplevel glist */
+ typedmess(portps_cleanup->s_thing, portps_cleanup, 0, 0);
+ /* LATER unbind all bogus objects, and destroy all bogushooks
+ by traversing the portps_cleanup's bindlist, instead of
+ using per-object clocks. Need to have bindlist traversal
+ in Pd API first... Otherwise, consider fragilizing this
+ (and fragilizing grab too). */
+ }
if (x->x_outmess != x->x_outini)
freebytes(x->x_outmess, x->x_outsize * sizeof(*x->x_outmess));
if (x->x_stack != x->x_stackini)
@@ -859,16 +898,6 @@ void import_max(char *fn, char *dir)
while ((stackp != s__X.s_thing) && (stackp = s__X.s_thing))
vmess(stackp, gensym("pop"), "i", 1);
- if (portps_cleanup->s_thing)
- {
- typedmess(portps_cleanup->s_thing, portps_cleanup, 0, 0);
- /* LATER unbind all bogus objects, and destroy all bogushooks
- by traversing the portps_cleanup's bindlist, instead of
- using per-object clocks. Need to have bindlist traversal
- in Pd API first... Otherwise, consider fragilizing this
- (and fragilizing grab too). */
- }
-
#if 0 /* LATER */
pd_doloadbang();
#endif