From d6adb9253f9b30158ad19c12215f79b23e37efdc Mon Sep 17 00:00:00 2001
From: Ivica Ico Bukvic <ico@vt.edu>
Date: Wed, 29 Dec 2010 02:38:00 -0500
Subject: [PATCH] Pd-0.42.5-extended-l2ork-dev-20101228.tar.bz2

---
 src/g_array.c          |   85 ++-
 src/g_canvas.c         |   26 +
 src/g_editor.c         |   64 +-
 src/g_graph.c          |   12 +-
 src/g_rtext.c          |  275 ++++----
 src/m_pd.h             |    2 +-
 src/pd.tk              |   62 +-
 src/x_connective.c.old | 1525 ----------------------------------------
 8 files changed, 339 insertions(+), 1712 deletions(-)
 delete mode 100644 src/x_connective.c.old

diff --git a/src/g_array.c b/src/g_array.c
index 96f7044d0..90eafe5c6 100644
--- a/src/g_array.c
+++ b/src/g_array.c
@@ -134,6 +134,8 @@ struct _garray
     char x_saveit;          /* true if we should save this with parent */
     char x_listviewing;     /* true if list view window is open */
     char x_hidename;        /* don't print name above graph */
+	int x_style;			/* so much simpler to keep it here */
+	t_symbol *x_send;		/* send_changed hook */
 };
 
 static t_pd *garray_arraytemplatecanvas;
@@ -199,6 +201,9 @@ static t_garray *graph_scalar(t_glist *gl, t_symbol *s, t_symbol *templatesym,
     x->x_listviewing = 0;
     glist_add(gl, &x->x_gobj);
     x->x_glist = gl;
+	char buf[MAXPDSTRING];
+	sprintf(buf, "%s_changed", x->x_realname->s_name);
+	x->x_send = gensym(buf);
     return (x);
 }
 
@@ -255,7 +260,7 @@ int garray_getname(t_garray *x, t_symbol **namep)
 
         /* if there is one garray in a graph, reset the graph's coordinates
             to fit a new size and style for the garray */
-static void garray_fittograph(t_garray *x, int n, int style)
+void garray_fittograph(t_garray *x, int n)
 {
     t_array *array = garray_getarray(x);
     t_glist *gl = x->x_glist;
@@ -263,7 +268,7 @@ static void garray_fittograph(t_garray *x, int n, int style)
     {
         vmess(&gl->gl_pd, gensym("bounds"), "ffff",
             0., gl->gl_y1, (double)
-                (style == PLOTSTYLE_POINTS || n == 1 ? n : n-1),
+                (x->x_style == PLOTSTYLE_POINTS || n == 1 ? n : n-1),
                     gl->gl_y2);
                 /* close any dialogs that might have the wrong info now... */
         gfxstub_deleteforkey(gl);
@@ -323,15 +328,16 @@ t_garray *graph_array(t_glist *gl, t_symbol *s, t_symbol *templateargsym,
     saveit = ((flags & 1) != 0);
     x = graph_scalar(gl, s, templatesym, saveit);
     x->x_hidename = ((flags & 8) >> 3);
+	x->x_style = style;
 
     if (n <= 0)
         n = 100;
     array_resize(x->x_scalar->sc_vec[zonset].w_array, n);
 
     template_setfloat(template, gensym("style"), x->x_scalar->sc_vec,
-        style, 1);
+        x->x_style, 1);
     template_setfloat(template, gensym("linewidth"), x->x_scalar->sc_vec, 
-        ((style == PLOTSTYLE_POINTS) ? 2 : 1), 1);
+        ((x->x_style == PLOTSTYLE_POINTS) ? 2 : 1), 1);
     if (x2 = pd_findbyclass(gensym("#A"), garray_class))
         pd_unbind(x2, gensym("#A"));
 
@@ -394,7 +400,8 @@ void glist_arraydialog(t_glist *parent, t_symbol *s, int argc, t_atom *argv)
             (size > 1 ? size-1 : size), -1, xdraw+30, ydraw+30, xdraw+30+GLIST_DEFGRAPHWIDTH, ydraw+30+GLIST_DEFGRAPHHEIGHT);
     a = graph_array(gl, sharptodollar(name), &s_float, size, flags);
     canvas_dirty(parent, 1);
-	canvas_redraw(glist_getcanvas(parent));
+	//canvas_redraw(glist_getcanvas(parent));
+	garray_fittograph(a, (int)size);
 	sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (long unsigned int)glist_getcanvas(parent));
 }
 
@@ -405,9 +412,9 @@ void garray_arraydialog(t_garray *x, t_symbol *name, t_floatarg fsize,
     int flags = fflags;
     int saveit = ((flags & 1) != 0);
     int style = ((flags & 6) >> 1);
-    t_float stylewas = template_getfloat(
+    /*t_float stylewas = template_getfloat(
         template_findbyname(x->x_scalar->sc_template),
-            gensym("style"), x->x_scalar->sc_vec, 1);
+            gensym("style"), x->x_scalar->sc_vec, 1);*/
     if (deleteit != 0)
     {
         glist_delete(x->x_glist, &x->x_gobj);
@@ -457,10 +464,16 @@ void garray_arraydialog(t_garray *x, t_symbol *name, t_floatarg fsize,
             size = 1;
         if (size != a->a_n)
             garray_resize(x, size);
-        else if (style != stylewas)
-            garray_fittograph(x, size, style);
+        else if (style != x->x_style) {
+			x->x_style = style;
+            garray_fittograph(x, size);
+		}
         template_setfloat(scalartemplate, gensym("style"),
-            x->x_scalar->sc_vec, (t_float)style, 0);
+            x->x_scalar->sc_vec, (t_float)x->x_style, 0);
+
+		char buf[MAXPDSTRING];
+		sprintf(buf, "%s_changed", x->x_realname->s_name);
+		x->x_send = gensym(buf);
 
         garray_setsaveit(x, (saveit != 0));
         garray_redraw(x);
@@ -504,6 +517,7 @@ void garray_arrayviewlist_fillpage(t_garray *x,
                                    t_float page,
                                    t_float fTopItem)
 {
+	//fprintf(stderr,"garray_fillpage\n");
     int i, xonset=0, yonset=0, type=0, elemsize=0, topItem;
     t_float yval;
     char cmdbuf[200];
@@ -634,6 +648,7 @@ static t_float array_motion_xperpix;
 static t_float array_motion_yperpix;
 static int array_motion_lastx;
 static int array_motion_fatten;
+static t_garray* array_garray;
 
     /* LATER protect against the template changing or the scalar disappearing
     probably by attaching a gpointer here ... */
@@ -642,6 +657,9 @@ static void array_motion(void *z, t_floatarg dx, t_floatarg dy)
 {
     array_motion_xcumulative += dx * array_motion_xperpix;
     array_motion_ycumulative += dy * array_motion_yperpix;
+
+	t_glist *graph = array_garray->x_glist;
+
     if (array_motion_xfield)
     {
             /* it's an x, y plot */
@@ -690,6 +708,15 @@ static void array_motion(void *z, t_floatarg dx, t_floatarg dy)
                     (t_word *)(((char *)array_motion_wp) +
                         array_motion_elemsize * array_motion_lastx),
                             1);
+		if (graph->gl_y1 > graph->gl_y2) {
+			if (newy > graph->gl_y1) newy = graph->gl_y1;
+			if (newy < graph->gl_y2) newy = graph->gl_y2;
+		}
+		else {
+			if (newy < graph->gl_y1) newy = graph->gl_y1;
+			if (newy > graph->gl_y2) newy = graph->gl_y2;
+		}
+		//fprintf(stderr, "y = %f\n", newy);
         t_float ydiff = newy - oldy;
         if (thisx < 0) thisx = 0;
         else if (thisx >= array_motion_npoints)
@@ -708,10 +735,15 @@ static void array_motion(void *z, t_floatarg dx, t_floatarg dy)
          }
          array_motion_lastx = thisx;
     }
+	//fprintf(stderr, "%f %f\n", graph->gl_y1, graph->gl_y2);
+
     if (array_motion_scalar)
         scalar_redraw(array_motion_scalar, array_motion_glist);
     if (array_motion_array)
         array_redraw(array_motion_array, array_motion_glist);
+
+	/* send a bang to the associated send to reflect the change via mouse click/drag */
+	if (array_garray->x_send->s_thing) pd_bang(array_garray->x_send->s_thing);
 }
 
 int scalar_doclick(t_word *data, t_template *template, t_scalar *sc,
@@ -1011,14 +1043,19 @@ static void garray_delete(t_gobj *z, t_glist *glist)
 
 static void garray_vis(t_gobj *z, t_glist *glist, int vis)
 {
+	//fprintf(stderr,"garray_vis %d\n", vis);
     t_garray *x = (t_garray *)z;
-    gobj_vis(&x->x_scalar->sc_gobj, glist, vis);
+	gobj_vis(&x->x_scalar->sc_gobj, glist, vis);
+	//if (((t_glist *)z)->gl_isgraph)
+	//	fprintf(stderr,"garray_vis am_graph\n");
 }
 
 static int garray_click(t_gobj *z, t_glist *glist,
     int xpix, int ypix, int shift, int alt, int dbl, int doit)
 {
+	//fprintf(stderr,"garray_click\n");
     t_garray *x = (t_garray *)z;
+	array_garray = x;
     return (gobj_click(&x->x_scalar->sc_gobj, glist,
         xpix, ypix, shift, alt, dbl, doit));
 }
@@ -1044,10 +1081,10 @@ static void garray_save(t_gobj *z, t_binbuf *b)
             x->x_scalar->sc_template->s_name);
         return;
     }
-    style = template_getfloat(scalartemplate, gensym("style"),
-            x->x_scalar->sc_vec, 0);    
-    filestyle = (style == PLOTSTYLE_POINTS ? 1 : 
-        (style == PLOTSTYLE_POLY ? 0 : style)); 
+    /* style = template_getfloat(scalartemplate, gensym("style"),
+            x->x_scalar->sc_vec, 0); */
+    filestyle = (x->x_style == PLOTSTYLE_POINTS ? 1 : 
+        (x->x_style == PLOTSTYLE_POLY ? 0 : x->x_style)); 
     binbuf_addv(b, "sssisi;", gensym("#X"), gensym("array"),
         x->x_name, array->a_n, &s_float,
             x->x_saveit + 2 * filestyle + 8*x->x_hidename);
@@ -1091,6 +1128,7 @@ void garray_usedindsp(t_garray *x)
 
 static void garray_doredraw(t_gobj *client, t_glist *glist)
 {
+	//fprintf(stderr,"garray_doredraw\n");
     t_garray *x = (t_garray *)client;
     if (glist_isvisible(x->x_glist))
     {
@@ -1101,6 +1139,7 @@ static void garray_doredraw(t_gobj *client, t_glist *glist)
 
 void garray_redraw(t_garray *x)
 {
+	//fprintf(stderr,"garray_redraw\n");
     if (glist_isvisible(x->x_glist))
         sys_queuegui(&x->x_gobj, x->x_glist, garray_doredraw);
     /* jsarlo { */
@@ -1108,6 +1147,7 @@ void garray_redraw(t_garray *x)
        performance reasons */
     else
     {
+	  //fprintf(stderr,"garray_redraw_listviewing\n");
       if (x->x_listviewing)
         sys_vgui("pdtk_array_listview_fillpage %s\n",
                  x->x_realname->s_name);
@@ -1389,7 +1429,16 @@ static void garray_rename(t_garray *x, t_symbol *s)
     }
     /* } jsarlo */
     pd_unbind(&x->x_gobj.g_pd, x->x_realname);
-    pd_bind(&x->x_gobj.g_pd, x->x_realname = x->x_name = s);
+
+	x->x_name = s;
+	x->x_realname = canvas_realizedollar(x->x_glist, x->x_name);
+
+    pd_bind(&x->x_gobj.g_pd, x->x_realname);
+
+	char buf[MAXPDSTRING];
+	sprintf(buf, "%s_changed", x->x_realname->s_name);
+	x->x_send = gensym(buf);
+
     garray_redraw(x);
 }
 
@@ -1476,9 +1525,9 @@ void garray_resize(t_garray *x, t_floatarg f)
     t_array *array = garray_getarray(x);
     t_glist *gl = x->x_glist;
     int n = (f < 1 ? 1 : f);
-    garray_fittograph(x, n, template_getfloat(
+    garray_fittograph(x, n);/*template_getfloat(
         template_findbyname(x->x_scalar->sc_template),
-            gensym("style"), x->x_scalar->sc_vec, 1));
+            gensym("style"), x->x_scalar->sc_vec, 1));*/
     array_resize_and_redraw(array, x->x_glist, n);
     if (x->x_usedindsp)
         canvas_update_dsp();
diff --git a/src/g_canvas.c b/src/g_canvas.c
index 14101ec8a..5c44d4103 100644
--- a/src/g_canvas.c
+++ b/src/g_canvas.c
@@ -1004,6 +1004,12 @@ void canvas_closebang(t_canvas *x)
       }
 }
 
+/* needed for readjustment of garrays */
+extern t_array *garray_getarray(t_garray *x);
+extern void garray_fittograph(t_garray *x, int n);
+extern t_rtext *glist_findrtext(t_glist *gl, t_text *who);
+extern void rtext_gettext(t_rtext *x, char **buf, int *bufsize);
+
 static void canvas_relocate(t_canvas *x, t_symbol *canvasgeom,
     t_symbol *topgeom)
 {
@@ -1017,6 +1023,26 @@ static void canvas_relocate(t_canvas *x, t_symbol *canvasgeom,
     if (cw > 5 && ch > 5)
         canvas_setbounds(x, txpix, typix,
             txpix + cw, typix + ch);
+	/* readjust garrays (if any) */
+	t_gobj *g, *gg = NULL;
+	t_garray *ga = NULL;
+	t_array *a = NULL;
+	int  num_elem = 0;
+
+	for (g = x->gl_list; g; g = g->g_next) {
+		//fprintf(stderr, "searching\n");
+
+		//for subpatch garrays
+		if (pd_class(&g->g_pd) == garray_class) {
+			//fprintf(stderr,"found ya\n");
+			ga = (t_garray *)g;
+			if (ga) {
+				a = garray_getarray(ga);
+				num_elem = a->a_n;
+				garray_fittograph(ga, num_elem);
+			}
+		}
+	}
 }
 
 void canvas_popabstraction(t_canvas *x)
diff --git a/src/g_editor.c b/src/g_editor.c
index 7c12ba5d5..52ef02b74 100644
--- a/src/g_editor.c
+++ b/src/g_editor.c
@@ -1125,8 +1125,14 @@ void canvas_map(t_canvas *x, t_floatarg f);
     /* we call this when we want the window to become visible, mapped, and
     in front of all windows; or with "f" zero, when we want to get rid of
     the window. */
+//extern t_array *garray_getarray(t_garray *x);
+//extern void garray_fittograph(t_garray *x, int n);
+//extern t_rtext *glist_findrtext(t_glist *gl, t_text *who);
+//extern void rtext_gettext(t_rtext *x, char **buf, int *bufsize);
+
 void canvas_vis(t_canvas *x, t_floatarg f)
 {
+	//fprintf(stderr,"canvas_vis %f\n", f);
     char buf[30];
     int flag = (f != 0);
     if (x != glist_getcanvas(x))
@@ -1145,11 +1151,12 @@ void canvas_vis(t_canvas *x, t_floatarg f)
 #else
             sys_vgui("raise .x%lx\n", x);
             sys_vgui("focus .x%lx.c\n", x);
-            sys_vgui("wm deiconify .x%lx\n", x);  
+            sys_vgui("wm deiconify .x%lx\n", x);
 #endif
         }
         else
         {
+			//fprintf(stderr,"new window\n");
             canvas_create_editor(x);
             sys_vgui("pdtk_canvas_new .x%lx %d %d +%d+%d %d\n", x,
                 (int)(x->gl_screenx2 - x->gl_screenx1),
@@ -1158,6 +1165,57 @@ void canvas_vis(t_canvas *x, t_floatarg f)
                 x->gl_edit);
             canvas_reflecttitle(x);
             x->gl_havewindow = 1;
+/*
+			//newly opened arrays created prior to pd-l2ork require fittograph
+			t_gobj *g, *gg = NULL;
+			t_garray *ga = NULL;
+			t_array *a = NULL;
+			int  num_elem = 0;
+			t_text *t = NULL;
+			int objnamesize;
+			char *objname;
+
+			for (g = x->gl_list; g; g = g->g_next) {
+				//fprintf(stderr, "searching\n");
+
+				//for subpatch garrays
+				if (pd_class(&g->g_pd) == garray_class) {
+					//fprintf(stderr,"found ya\n");
+					ga = (t_garray *)g;
+					if (ga) {
+						a = garray_getarray(ga);
+						num_elem = a->a_n;
+						garray_fittograph(ga, num_elem);
+					}
+				}
+				//for garrays in gop inside a newly opened patch window
+				else {
+					t_text *t = (t_text *)g;
+					t_rtext *y = glist_findrtext(x, t);
+					if (y) {
+						rtext_gettext(y, &objname, &objnamesize);
+						//fprintf(stderr,"objname %s\n", objname);					
+						if (!strcmp(objname, "graph ")) {
+							//fprintf(stderr,"got a graph\n");
+							for (gg = ((t_glist *)g)->gl_list; gg; gg = gg->g_next) {
+								//fprintf(stderr, "sub-searching\n");
+								if (pd_class(&gg->g_pd) == garray_class) {
+									//fprintf(stderr,"sub found ya\n");
+									ga = (t_garray *)gg;
+									if (ga) {
+										a = garray_getarray(ga);
+										num_elem = a->a_n;
+										garray_fittograph(ga, num_elem);
+										canvas_dirty(x, 2);
+									}
+								}
+							}					
+						}
+						//else fprintf(stderr,"fail %d >%s< >graph<\n", strcmp(objname, "graph"), objname);
+					}
+				}
+			}
+*/
             canvas_updatewindowlist();
         }
     }
@@ -1918,7 +1976,7 @@ void canvas_doconnect(t_canvas *x, int xpos, int ypos, int which, int doit)
                 {
                     sys_vgui(".x%x.c itemconfigure %s -outline %s -fill %s -width 1\n",
                            	x, canvas_cnct_inlet_tag,
-							(last_inlet_filter ? "black" : (outlet_issignal ? "$signal_cord" : "$msg_cord")),
+							(last_inlet_filter ? "black" : (obj_issignaloutlet(ob1, closest1) ? "$signal_cord" : "$msg_cord")),
 							(inlet_issignal ? "$signal_nlet" : "$msg_nlet"));
                     canvas_cnct_inlet_tag[0] = 0;                  
                 }
@@ -1962,7 +2020,7 @@ void canvas_doconnect(t_canvas *x, int xpos, int ypos, int which, int doit)
                     //sys_vgui(".x%x.c raise %s\n",
                     //         x,
                     //         canvas_cnct_inlet_tag);
-					inlet_issignal = obj_issignaloutlet(ob2, closest2);
+					inlet_issignal = obj_issignalinlet(ob2, closest2);
                 }
                 canvas_setcursor(x, CURSOR_EDITMODE_CONNECT);
             }
diff --git a/src/g_graph.c b/src/g_graph.c
index 38d17e69f..8700a22f1 100644
--- a/src/g_graph.c
+++ b/src/g_graph.c
@@ -561,7 +561,7 @@ t_float glist_pixelstoy(t_glist *x, t_float ypix)
     {
         int x1, y1, x2, y2;
         if (!x->gl_owner)
-            bug("glist_pixelstox");
+            bug("glist_pixelstoy");
         graph_graphrect(&x->gl_gobj, x->gl_owner, &x1, &y1, &x2, &y2);
         return (x->gl_y1 + (x->gl_y2 - x->gl_y1) * 
             (ypix - y1) / (y2 - y1));
@@ -859,8 +859,9 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis)
                 glist_getfont(x), sys_fontweight, tag);
 
             /* draw contents of graph as glist */
-        for (g = x->gl_list; g; g = g->g_next)
+        for (g = x->gl_list; g; g = g->g_next) {
             gobj_vis(g, x, 1);
+		}
     }
     else
     {
@@ -897,6 +898,7 @@ static void graph_graphrect(t_gobj *z, t_glist *glist,
 static void graph_getrect(t_gobj *z, t_glist *glist,
     int *xp1, int *yp1, int *xp2, int *yp2)
 {
+	//fprintf(stderr,"graph_getrect\n");
     int x1 = 0x7fffffff, y1 = 0x7fffffff, x2 = -0x7fffffff, y2 = -0x7fffffff;
     t_glist *x = (t_glist *)z;
     if (x->gl_isgraph)
@@ -907,6 +909,12 @@ static void graph_getrect(t_gobj *z, t_glist *glist,
         int x21, y21, x22, y22;
 
         graph_graphrect(z, glist, &x1, &y1, &x2, &y2);
+		/* fix visibility of edge items */
+	    x1 -= 1;
+	    y1 -= 1;
+	    //x2 += 1;
+	    y2 += 1;
+
         if (canvas_showtext(x))
         {
             text_widgetbehavior.w_getrectfn(z, glist, &x21, &y21, &x22, &y22);
diff --git a/src/g_rtext.c b/src/g_rtext.c
index 0cbe219a0..163615161 100644
--- a/src/g_rtext.c
+++ b/src/g_rtext.c
@@ -157,142 +157,144 @@ extern int sys_oldtclversion;
 static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp,
     int *indexp)
 {
-    t_float dispx, dispy;
-    char smallbuf[200], *tempbuf;
-    int outchars = 0, nlines = 0, ncolumns = 0,
-        pixwide, pixhigh, font, fontwidth, fontheight, findx, findy;
-    int reportedindex = 0;
-    t_canvas *canvas = glist_getcanvas(x->x_glist);
-    int widthspec = x->x_text->te_width;
-    int widthlimit = (widthspec ? widthspec : BOXWIDTH);
-    int inindex = 0;
-    int selstart = 0, selend = 0;
-        /* if we're a GOP (the new, "goprect" style) borrow the font size
-        from the inside to preserve the spacing */
-    if (pd_class(&x->x_text->te_pd) == canvas_class &&
-        ((t_glist *)(x->x_text))->gl_isgraph &&
-        ((t_glist *)(x->x_text))->gl_goprect)
-            font =  glist_getfont((t_glist *)(x->x_text));
-    else font = glist_getfont(x->x_glist);
-    fontwidth = sys_fontwidth(font);
-    fontheight = sys_fontheight(font);
-    findx = (*widthp + (fontwidth/2)) / fontwidth;
-    findy = *heightp / fontheight;
-    if (x->x_bufsize >= 100)
-         tempbuf = (char *)t_getbytes(2 * x->x_bufsize + 1);
-    else tempbuf = smallbuf;
-    while (x->x_bufsize - inindex > 0)
-    {
-        int inchars = x->x_bufsize - inindex;
-        int maxindex = (inchars > widthlimit ? widthlimit : inchars);
-        int eatchar = 1;
-        int foundit = firstone(x->x_buf + inindex, '\n', maxindex);
-        if (foundit < 0)
-        {
-            if (inchars > widthlimit)
-            {
-                foundit = lastone(x->x_buf + inindex, ' ', maxindex);
-                if (foundit < 0)
-                {
-                    foundit = maxindex;
-                    eatchar = 0;
-                }
-            }
-            else
-            {
-                foundit = inchars;
-                eatchar = 0;
-            }
-        }
-        if (nlines == findy)
-        {
-            int actualx = (findx < 0 ? 0 :
-                (findx > foundit ? foundit : findx));
-            *indexp = inindex + actualx;
-            reportedindex = 1;
-        }
-        strncpy(tempbuf+outchars, x->x_buf + inindex, foundit);
-        if (x->x_selstart >= inindex &&
-            x->x_selstart <= inindex + foundit + eatchar)
-                selstart = x->x_selstart + outchars - inindex;
-        if (x->x_selend >= inindex &&
-            x->x_selend <= inindex + foundit + eatchar)
-                selend = x->x_selend + outchars - inindex;
-        outchars += foundit;
-        inindex += (foundit + eatchar);
-        if (inindex < x->x_bufsize)
-            tempbuf[outchars++] = '\n';
-        if (foundit > ncolumns)
-            ncolumns = foundit;
-        nlines++;
-    }
-    if (!reportedindex)
-        *indexp = outchars;
-    dispx = text_xpix(x->x_text, x->x_glist);
-    dispy = text_ypix(x->x_text, x->x_glist);
-    if (nlines < 1) nlines = 1;
-    if (!widthspec)
-    {
-        while (ncolumns < 3)
-        {
-            tempbuf[outchars++] = ' ';
-            ncolumns++;
-        }
-    }
-    else ncolumns = widthspec;
-    pixwide = ncolumns * fontwidth + (LMARGIN + RMARGIN);
-    pixhigh = nlines * fontheight + (TMARGIN + BMARGIN);
-
-    if (action == SEND_FIRST)
-        sys_vgui("pdtk_text_new .x%lx.c %s %f %f {%.*s} %d %s\n",
-            canvas, x->x_tag,
-            dispx + LMARGIN, dispy + TMARGIN,
-            outchars, tempbuf, sys_hostfontsize(font),
-            (glist_isselected(x->x_glist,
-                &x->x_glist->gl_gobj)? "$select_color" : "$text_color"));
-    else if (action == SEND_UPDATE)
-    {
-		/*fprintf(stderr, "SEND_UPDATE canvas_class=%d isgraph=%d goprect=%d\n",
-			(pd_class(&x->x_text->te_pd) == canvas_class ? 1 : 0),
-			((t_glist *)(x->x_text))->gl_isgraph,
-			((t_glist *)(x->x_text))->gl_goprect );*/
-        sys_vgui("pdtk_text_set .x%lx.c %s {%.*s}\n",
-            canvas, x->x_tag, outchars, tempbuf);
-		/*if ( pd_class(&x->x_text->te_pd) == canvas_class &&
-        	((t_glist *)(x->x_text))->gl_isgraph &&
-        	(((t_glist *)(x->x_text))->gl_goprect) ) {
-			fprintf(stderr, "do not update outlets\n");
+	if (x) {
+		t_float dispx, dispy;
+		char smallbuf[200], *tempbuf;
+		int outchars = 0, nlines = 0, ncolumns = 0,
+		    pixwide, pixhigh, font, fontwidth, fontheight, findx, findy;
+		int reportedindex = 0;
+		t_canvas *canvas = glist_getcanvas(x->x_glist);
+		int widthspec = x->x_text->te_width;
+		int widthlimit = (widthspec ? widthspec : BOXWIDTH);
+		int inindex = 0;
+		int selstart = 0, selend = 0;
+		    /* if we're a GOP (the new, "goprect" style) borrow the font size
+		    from the inside to preserve the spacing */
+		if (pd_class(&x->x_text->te_pd) == canvas_class &&
+		    ((t_glist *)(x->x_text))->gl_isgraph &&
+		    ((t_glist *)(x->x_text))->gl_goprect)
+		        font =  glist_getfont((t_glist *)(x->x_text));
+		else font = glist_getfont(x->x_glist);
+		fontwidth = sys_fontwidth(font);
+		fontheight = sys_fontheight(font);
+		findx = (*widthp + (fontwidth/2)) / fontwidth;
+		findy = *heightp / fontheight;
+		if (x->x_bufsize >= 100)
+		     tempbuf = (char *)t_getbytes(2 * x->x_bufsize + 1);
+		else tempbuf = smallbuf;
+		while (x->x_bufsize - inindex > 0)
+		{
+		    int inchars = x->x_bufsize - inindex;
+		    int maxindex = (inchars > widthlimit ? widthlimit : inchars);
+		    int eatchar = 1;
+		    int foundit = firstone(x->x_buf + inindex, '\n', maxindex);
+		    if (foundit < 0)
+		    {
+		        if (inchars > widthlimit)
+		        {
+		            foundit = lastone(x->x_buf + inindex, ' ', maxindex);
+		            if (foundit < 0)
+		            {
+		                foundit = maxindex;
+		                eatchar = 0;
+		            }
+		        }
+		        else
+		        {
+		            foundit = inchars;
+		            eatchar = 0;
+		        }
+		    }
+		    if (nlines == findy)
+		    {
+		        int actualx = (findx < 0 ? 0 :
+		            (findx > foundit ? foundit : findx));
+		        *indexp = inindex + actualx;
+		        reportedindex = 1;
+		    }
+		    strncpy(tempbuf+outchars, x->x_buf + inindex, foundit);
+		    if (x->x_selstart >= inindex &&
+		        x->x_selstart <= inindex + foundit + eatchar)
+		            selstart = x->x_selstart + outchars - inindex;
+		    if (x->x_selend >= inindex &&
+		        x->x_selend <= inindex + foundit + eatchar)
+		            selend = x->x_selend + outchars - inindex;
+		    outchars += foundit;
+		    inindex += (foundit + eatchar);
+		    if (inindex < x->x_bufsize)
+		        tempbuf[outchars++] = '\n';
+		    if (foundit > ncolumns)
+		        ncolumns = foundit;
+		    nlines++;
 		}
-		else */
-		if (pixwide != x->x_drawnwidth || pixhigh != x->x_drawnheight) 
-            text_drawborder(x->x_text, x->x_glist, x->x_tag,
-                pixwide, pixhigh, 0);
-        if (x->x_active)
-        {
-            if (selend > selstart)
-            {
-                sys_vgui(".x%lx.c select from %s %d\n", canvas, 
-                    x->x_tag, selstart);
-                sys_vgui(".x%lx.c select to %s %d\n", canvas, 
-                    x->x_tag, selend + (sys_oldtclversion ? 0 : -1));
-                sys_vgui(".x%lx.c focus \"\"\n", canvas);        
-            }
-            else
-            {
-                sys_vgui(".x%lx.c select clear\n", canvas);
-                sys_vgui(".x%lx.c icursor %s %d\n", canvas, x->x_tag,
-                    selstart);
-                sys_vgui(".x%lx.c focus %s\n", canvas, x->x_tag);        
-            }
-        }
-    }
-    x->x_drawnwidth = pixwide;
-    x->x_drawnheight = pixhigh;
-    
-    *widthp = pixwide;
-    *heightp = pixhigh;
-    if (tempbuf != smallbuf)
-        t_freebytes(tempbuf, 2 * x->x_bufsize + 1);
+		if (!reportedindex)
+		    *indexp = outchars;
+		dispx = text_xpix(x->x_text, x->x_glist);
+		dispy = text_ypix(x->x_text, x->x_glist);
+		if (nlines < 1) nlines = 1;
+		if (!widthspec)
+		{
+		    while (ncolumns < 3)
+		    {
+		        tempbuf[outchars++] = ' ';
+		        ncolumns++;
+		    }
+		}
+		else ncolumns = widthspec;
+		pixwide = ncolumns * fontwidth + (LMARGIN + RMARGIN);
+		pixhigh = nlines * fontheight + (TMARGIN + BMARGIN);
+
+		if (action == SEND_FIRST)
+		    sys_vgui("pdtk_text_new .x%lx.c %s %f %f {%.*s} %d %s\n",
+		        canvas, x->x_tag,
+		        dispx + LMARGIN, dispy + TMARGIN,
+		        outchars, tempbuf, sys_hostfontsize(font),
+		        (glist_isselected(x->x_glist,
+		            &x->x_glist->gl_gobj)? "$select_color" : "$text_color"));
+		else if (action == SEND_UPDATE)
+		{
+			/*fprintf(stderr, "SEND_UPDATE canvas_class=%d isgraph=%d goprect=%d\n",
+				(pd_class(&x->x_text->te_pd) == canvas_class ? 1 : 0),
+				((t_glist *)(x->x_text))->gl_isgraph,
+				((t_glist *)(x->x_text))->gl_goprect );*/
+		    sys_vgui("pdtk_text_set .x%lx.c %s {%.*s}\n",
+		        canvas, x->x_tag, outchars, tempbuf);
+			/*if ( pd_class(&x->x_text->te_pd) == canvas_class &&
+		    	((t_glist *)(x->x_text))->gl_isgraph &&
+		    	(((t_glist *)(x->x_text))->gl_goprect) ) {
+				fprintf(stderr, "do not update outlets\n");
+			}
+			else */
+			if (pixwide != x->x_drawnwidth || pixhigh != x->x_drawnheight) 
+		        text_drawborder(x->x_text, x->x_glist, x->x_tag,
+		            pixwide, pixhigh, 0);
+		    if (x->x_active)
+		    {
+		        if (selend > selstart)
+		        {
+		            sys_vgui(".x%lx.c select from %s %d\n", canvas, 
+		                x->x_tag, selstart);
+		            sys_vgui(".x%lx.c select to %s %d\n", canvas, 
+		                x->x_tag, selend + (sys_oldtclversion ? 0 : -1));
+		            sys_vgui(".x%lx.c focus \"\"\n", canvas);        
+		        }
+		        else
+		        {
+		            sys_vgui(".x%lx.c select clear\n", canvas);
+		            sys_vgui(".x%lx.c icursor %s %d\n", canvas, x->x_tag,
+		                selstart);
+		            sys_vgui(".x%lx.c focus %s\n", canvas, x->x_tag);        
+		        }
+		    }
+		}
+		x->x_drawnwidth = pixwide;
+		x->x_drawnheight = pixhigh;
+		
+		*widthp = pixwide;
+		*heightp = pixhigh;
+		if (tempbuf != smallbuf)
+		    t_freebytes(tempbuf, 2 * x->x_bufsize + 1);
+	}
 }
 
 void rtext_retext(t_rtext *x)
@@ -384,7 +386,8 @@ void rtext_draw(t_rtext *x)
 
 void rtext_erase(t_rtext *x)
 {
-    sys_vgui(".x%lx.c delete %s\n", glist_getcanvas(x->x_glist), x->x_tag);
+	if (x && x->x_glist)
+	    sys_vgui(".x%lx.c delete %s\n", glist_getcanvas(x->x_glist), x->x_tag);
 }
 
 void rtext_displace(t_rtext *x, int dx, int dy)
diff --git a/src/m_pd.h b/src/m_pd.h
index 845680ba3..db2165965 100644
--- a/src/m_pd.h
+++ b/src/m_pd.h
@@ -11,7 +11,7 @@ extern "C" {
 #define PD_MAJOR_VERSION 0
 #define PD_MINOR_VERSION 42
 #define PD_BUGFIX_VERSION 5
-#define PD_TEST_VERSION "extended-l2ork-20101222"
+#define PD_TEST_VERSION "extended-l2ork-20101228"
 
 /* old name for "MSW" flag -- we have to take it for the sake of many old
 "nmakefiles" for externs, which will define NT and not MSW */
diff --git a/src/pd.tk b/src/pd.tk
index 9a2379ed1..24a7248a0 100644
--- a/src/pd.tk
+++ b/src/pd.tk
@@ -457,7 +457,8 @@ if {$pd_nt == 0} {
     }
 }
 
-set pd_deffont {courier 10}
+#set pd_deffont {courier 10}
+set pd_deffont console_font
 
 set help_top_directory $pd_guidir/doc
 
@@ -2331,23 +2332,30 @@ proc pdtk_array_listview_new {id arrayName page} {
     global fontname fontweight
     set pd_array_listview_page($arrayName) $page
     set pd_array_listview_id($arrayName) $id
-    set windowName [format ".%s Array Window" $arrayName]
+    set windowName [format ".%sArrayWindow" $arrayName]
     if [winfo exists $windowName] then [destroy $windowName]
     toplevel $windowName
+	wm geometry $windowName 220x400
+	wm minsize $windowName 220 400
+	#pdtk_standardkeybindings $windowName
+	bind $windowName <Control-w> {destroy %W}
+	bind $windowName <Control-q> {menu_quit}
+	match_linux_wm [list $windowName configure]
     wm protocol $windowName WM_DELETE_WINDOW \
         "pdtk_array_listview_close $id $arrayName"
     wm title $windowName [concat $arrayName "(list view)"]
     # FIXME
     set font 9
-    set $windowName.lb [listbox $windowName.lb -height 20 -width 25\
+    set $windowName.lb [match_linux_wm [list listbox $windowName.lb \
+							-height 20 -width 25 \
                             -selectmode extended \
-                            -relief solid -background white -borderwidth 1 \
                             -font [format {{%s} %d %s} $fontname $font $fontweight]\
-                            -yscrollcommand "$windowName.lb.sb set"]
+                            -yscrollcommand "$windowName.lb.sb set"]]
     set $windowName.lb.sb [match_linux_wm [list scrollbar $windowName.lb.sb \
                                -command "$windowName.lb yview" -orient vertical]]
-    place configure $windowName.lb.sb -relheight 1 -relx 0.9 -relwidth 0.1
+    #place configure $windowName.lb.sb -relheight 1 -relx 0.9 -relwidth 0.1
     pack $windowName.lb -expand 1 -fill both
+	pack $windowName.lb.sb -side right -fill y
     bind $windowName.lb <Double-ButtonPress-1> \
         "pdtk_array_listview_edit $arrayName $page $font"
     # handle copy/paste
@@ -2360,12 +2368,12 @@ proc pdtk_array_listview_new {id arrayName page} {
                 "pdtk_array_listview_popup $arrayName"
         } 
     }
-    set $windowName.prevBtn [button $windowName.prevBtn -text "<-" \
-                                 -command "pdtk_array_listview_changepage $arrayName -1"]
-    set $windowName.nextBtn [button $windowName.nextBtn -text "->" \
-                                 -command "pdtk_array_listview_changepage $arrayName 1"]
-    pack $windowName.prevBtn -side left -ipadx 20 -pady 10 -anchor s
-    pack $windowName.nextBtn -side right -ipadx 20 -pady 10 -anchor s
+    set $windowName.prevBtn [match_linux_wm [list button $windowName.prevBtn -text "<-" \
+                                 -command "pdtk_array_listview_changepage $arrayName -1"]]
+    set $windowName.nextBtn [match_linux_wm [list button $windowName.nextBtn -text "->" \
+                                 -command "pdtk_array_listview_changepage $arrayName 1"]]
+    pack $windowName.prevBtn -side left -expand 1 -padx 3 -pady 3
+    pack $windowName.nextBtn -side left -expand 1 -padx 3 -pady 3
     focus $windowName
 }
 
@@ -2856,11 +2864,11 @@ proc pdtk_canvas_getscroll {name} {
 		set canvasheight [ expr {abs($ymaxval-$yminval)} ]
 
 		if {$::scroll($parentname) == 1} {
-			if {$winwidth > $canvaswidth} {
+			if {$winwidth >= $canvaswidth} {
 				pack forget $parentname.scrollhort
 				set ::xscrollable($parentname) 0
 			}
-			if {$winheight > $canvasheight} {
+			if {$winheight >= $canvasheight} {
 				pack forget $parentname.scrollvert
 				set ::yscrollable($parentname) 0
 			}
@@ -4491,11 +4499,11 @@ proc pdtk_array_dialog {id name n flags newone canvas} {
         pack $id.deleteme -side top
     }
     # jsarlo
-    # if {$newone == 0} {
-    #    match_linux_wm [list button $id.listview -text {View list}\
-    #        -command "array_viewlist $id $name 0"]
-    #    pack $id.listview -side left
-    #}
+    if {$newone == 0} {
+        match_linux_wm [list button $id.listview -text {View list}\
+           -command "array_viewlist $id"]
+        pack $id.listview -side left -padx 3 -pady 3
+    }
     # end jsarlo
     match_linux_wm [list frame $id.buttonframe]
     pack $id.buttonframe -side bottom -fill x
@@ -4848,15 +4856,15 @@ proc pdtk_data_dialog {name stuff} {
     	-command [concat dodata_send $name]]
 	match_linux_wm [list button $name.buttonframe.ok -text {OK (Ctrl t)}\
     	-command [concat dodata_ok $name]]
-    pack $name.buttonframe.send -side left -expand 1
-    pack $name.buttonframe.ok -side left -expand 1
+    pack $name.buttonframe.ok -side right -expand 0 -pady 3
+    pack $name.buttonframe.send -side right -expand 0 -pady 3
 
     match_linux_wm [list text $name.text -relief sunken -bd 1 -height 40 -width 60 \
         -yscrollcommand "$name.scroll set" -font $pd_deffont \
 		-highlightthickness 0 -takefocus 0]
     match_linux_wm [list scrollbar $name.scroll -command "$name.text yview"]
-    pack $name.scroll -side right -fill y -pady 3
-    pack $name.text -side left -fill both -expand 1 -pady 3
+    pack $name.scroll -side right -fill y
+    pack $name.text -side left -fill both -expand 1
     $name.text insert end $stuff
     focus $name.text
 }
@@ -5096,15 +5104,15 @@ proc pdtk_pd_texteditor {stuff} {
 			-command "texteditor_send $name.text"]
 		match_linux_wm [list button $name.buttons.ok -text {OK (Ctrl t)}\
 			-command "texteditor_ok $name.text"]
-		pack $name.buttons.send -side left -expand 1
-		pack $name.buttons.ok -side left -expand 1
+		pack $name.buttons.ok -side right -expand 0 -padx 3 -pady 3
+		pack $name.buttons.send -side right -expand 0 -padx 3 -pady 3
 
 		match_linux_wm [list text $name.text -relief sunken -bd 1 -height 12 -width 60 \
 		    -yscrollcommand "$name.scroll set" -font $pd_deffont \
 			-highlightthickness 0 -takefocus 0]
 		match_linux_wm [list scrollbar $name.scroll -command "$name.text yview"]
-		pack $name.scroll -side right -fill y -pady 3
-		pack $name.text -side left -fill both -expand 1 -pady 3
+		pack $name.scroll -side right -fill y
+		pack $name.text -side left -fill both -expand 1
 		$name.text insert end $stuff
 		focus $name.text
 	}
diff --git a/src/x_connective.c.old b/src/x_connective.c.old
deleted file mode 100644
index 1422a074e..000000000
--- a/src/x_connective.c.old
+++ /dev/null
@@ -1,1525 +0,0 @@
-/* Copyright (c) 1997-1999 Miller Puckette.
-* For information on usage and redistribution, and for a DISCLAIMER OF ALL
-* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */
-
-/* connective objects */
-
-#include "m_pd.h"
-
-#include <string.h>
-#include <stdio.h>
-extern t_pd *newest;
-
-/* -------------------------- int ------------------------------ */
-static t_class *pdint_class;
-
-typedef struct _pdint
-{
-    t_object x_obj;
-    t_float x_f;
-} t_pdint;
-
-static void *pdint_new(t_floatarg f)
-{
-    t_pdint *x = (t_pdint *)pd_new(pdint_class);
-    x->x_f = f;
-    outlet_new(&x->x_obj, &s_float);
-    floatinlet_new(&x->x_obj, &x->x_f);
-    return (x);
-}
-
-static void pdint_bang(t_pdint *x)
-{
-    outlet_float(x->x_obj.ob_outlet, (t_float)(int)(x->x_f));
-}
-
-static void pdint_float(t_pdint *x, t_float f)
-{
-    outlet_float(x->x_obj.ob_outlet, (t_float)(int)(x->x_f = f));
-}
-
-void pdint_setup(void)
-{
-    pdint_class = class_new(gensym("int"), (t_newmethod)pdint_new, 0,
-        sizeof(t_pdint), 0, A_DEFFLOAT, 0);
-    class_addcreator((t_newmethod)pdint_new, gensym("i"), A_DEFFLOAT, 0);
-    class_addbang(pdint_class, pdint_bang);
-    class_addfloat(pdint_class, pdint_float);
-}
-
-/* -------------------------- float ------------------------------ */
-static t_class *pdfloat_class;
-
-typedef struct _pdfloat
-{
-    t_object x_obj;
-    t_float x_f;
-} t_pdfloat;
-
-    /* "float," "symbol," and "bang" are special because
-    they're created by short-circuited messages to the "new"
-    object which are handled specially in pd_typedmess(). */
-
-static void *pdfloat_new(t_pd *dummy, t_float f)
-{
-    t_pdfloat *x = (t_pdfloat *)pd_new(pdfloat_class);
-    x->x_f = f;
-    outlet_new(&x->x_obj, &s_float);
-    floatinlet_new(&x->x_obj, &x->x_f);
-    newest = &x->x_obj.ob_pd;
-    return (x);
-}
-
-static void *pdfloat_new2(t_floatarg f)
-{
-    return (pdfloat_new(0, f));
-}
-
-static void pdfloat_bang(t_pdfloat *x)
-{
-    outlet_float(x->x_obj.ob_outlet, x->x_f);
-}
-
-static void pdfloat_float(t_pdfloat *x, t_float f)
-{
-    outlet_float(x->x_obj.ob_outlet, x->x_f = f);
-}
-
-void pdfloat_setup(void)
-{
-    pdfloat_class = class_new(gensym("float"), (t_newmethod)pdfloat_new, 0,
-        sizeof(t_pdfloat), 0, A_FLOAT, 0);
-    class_addcreator((t_newmethod)pdfloat_new2, gensym("f"), A_DEFFLOAT, 0);
-    class_addbang(pdfloat_class, pdfloat_bang);
-    class_addfloat(pdfloat_class, (t_method)pdfloat_float);
-}
-
-/* -------------------------- symbol ------------------------------ */
-static t_class *pdsymbol_class;
-
-typedef struct _pdsymbol
-{
-    t_object x_obj;
-    t_symbol *x_s;
-} t_pdsymbol;
-
-static void *pdsymbol_new(t_pd *dummy, t_symbol *s)
-{
-    t_pdsymbol *x = (t_pdsymbol *)pd_new(pdsymbol_class);
-    x->x_s = s;
-    outlet_new(&x->x_obj, &s_symbol);
-    symbolinlet_new(&x->x_obj, &x->x_s);
-    newest = &x->x_obj.ob_pd;
-    return (x);
-}
-
-static void pdsymbol_bang(t_pdsymbol *x)
-{
-    outlet_symbol(x->x_obj.ob_outlet, x->x_s);
-}
-
-static void pdsymbol_symbol(t_pdsymbol *x, t_symbol *s)
-{
-    outlet_symbol(x->x_obj.ob_outlet, x->x_s = s);
-}
-
-static void pdsymbol_anything(t_pdsymbol *x, t_symbol *s, int ac, t_atom *av)
-{
-    outlet_symbol(x->x_obj.ob_outlet, x->x_s = s);
-}
-
-    /* For "list" message don't just output "list"; if empty, we want to
-    bang the symbol and if it starts with a symbol, we output that.
-    Otherwise it's not clear what we should do so we just go for the
-    "anything" method.  LATER figure out if there are other places where
-    empty lists aren't equivalent to "bang"???  Should Pd's message passer
-    always check and call the more specific method, or should it be the 
-    object's responsibility?  Dunno... */
-static void pdsymbol_list(t_pdsymbol *x, t_symbol *s, int ac, t_atom *av)
-{
-    if (!ac)
-        pdsymbol_bang(x);
-    else if (av->a_type == A_SYMBOL)
-        pdsymbol_symbol(x, av->a_w.w_symbol);
-    else pdsymbol_anything(x, s, ac, av);
-}
-
-void pdsymbol_setup(void)
-{
-    pdsymbol_class = class_new(gensym("symbol"), (t_newmethod)pdsymbol_new, 0,
-        sizeof(t_pdsymbol), 0, A_SYMBOL, 0);
-    class_addbang(pdsymbol_class, pdsymbol_bang);
-    class_addsymbol(pdsymbol_class, pdsymbol_symbol);
-    class_addanything(pdsymbol_class, pdsymbol_anything);
-}
-
-/* -------------------------- bang ------------------------------ */
-static t_class *bang_class;
-
-typedef struct _bang
-{
-    t_object x_obj;
-} t_bang;
-
-static void *bang_new(t_pd *dummy)
-{
-    t_bang *x = (t_bang *)pd_new(bang_class);
-    outlet_new(&x->x_obj, &s_bang);
-    newest = &x->x_obj.ob_pd;
-    return (x);
-}
-
-static void *bang_new2(t_bang f)
-{
-    return (bang_new(0));
-}
-
-static void bang_bang(t_bang *x)
-{
-    outlet_bang(x->x_obj.ob_outlet);
-}
-
-void bang_setup(void)
-{
-    bang_class = class_new(gensym("bang"), (t_newmethod)bang_new, 0,
-        sizeof(t_bang), 0, 0);
-    class_addcreator((t_newmethod)bang_new2, gensym("b"), 0);
-    class_addbang(bang_class, bang_bang);
-    class_addfloat(bang_class, bang_bang);
-    class_addsymbol(bang_class, bang_bang);
-    class_addlist(bang_class, bang_bang);
-    class_addanything(bang_class, bang_bang);
-}
-
-/* -------------------- send ------------------------------ */
-
-static t_class *send_class;
-
-typedef struct _send
-{
-    t_object x_obj;
-    t_symbol *x_sym;
-} t_send;
-
-static void send_bang(t_send *x)
-{
-    if (x->x_sym->s_thing) pd_bang(x->x_sym->s_thing);
-}
-
-static void send_float(t_send *x, t_float f)
-{
-    if (x->x_sym->s_thing) pd_float(x->x_sym->s_thing, f);
-}
-
-static void send_symbol(t_send *x, t_symbol *s)
-{
-    if (x->x_sym->s_thing) pd_symbol(x->x_sym->s_thing, s);
-}
-
-static void send_pointer(t_send *x, t_gpointer *gp)
-{
-    if (x->x_sym->s_thing) pd_pointer(x->x_sym->s_thing, gp);
-}
-
-static void send_list(t_send *x, t_symbol *s, int argc, t_atom *argv)
-{
-    if (x->x_sym->s_thing) pd_list(x->x_sym->s_thing, s, argc, argv);
-}
-
-static void send_anything(t_send *x, t_symbol *s, int argc, t_atom *argv)
-{
-    if (x->x_sym->s_thing) typedmess(x->x_sym->s_thing, s, argc, argv);
-}
-
-static void *send_new(t_symbol *s)
-{
-    t_send *x = (t_send *)pd_new(send_class);
-    if (!*s->s_name)
-        symbolinlet_new(&x->x_obj, &x->x_sym);
-    x->x_sym = s;
-    return (x);
-}
-
-static void send_setup(void)
-{
-    send_class = class_new(gensym("send"), (t_newmethod)send_new, 0,
-        sizeof(t_send), 0, A_DEFSYM, 0);
-    class_addcreator((t_newmethod)send_new, gensym("s"), A_DEFSYM, 0);
-    class_addbang(send_class, send_bang);
-    class_addfloat(send_class, send_float);
-    class_addsymbol(send_class, send_symbol);
-    class_addpointer(send_class, send_pointer);
-    class_addlist(send_class, send_list);
-    class_addanything(send_class, send_anything);
-}
-/* -------------------- receive ------------------------------ */
-
-static t_class *receive_class;
-
-typedef struct _receive
-{
-    t_object x_obj;
-    t_symbol *x_sym;
-} t_receive;
-
-static void receive_bang(t_receive *x)
-{
-    outlet_bang(x->x_obj.ob_outlet);
-}
-
-static void receive_float(t_receive *x, t_float f)
-{
-    outlet_float(x->x_obj.ob_outlet, f);
-}
-
-static void receive_symbol(t_receive *x, t_symbol *s)
-{
-    outlet_symbol(x->x_obj.ob_outlet, s);
-}
-
-static void receive_pointer(t_receive *x, t_gpointer *gp)
-{
-    outlet_pointer(x->x_obj.ob_outlet, gp);
-}
-
-static void receive_list(t_receive *x, t_symbol *s, int argc, t_atom *argv)
-{
-    outlet_list(x->x_obj.ob_outlet, s, argc, argv);
-}
-
-static void receive_anything(t_receive *x, t_symbol *s, int argc, t_atom *argv)
-{
-    outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
-}
-
-static void *receive_new(t_symbol *s)
-{
-    t_receive *x = (t_receive *)pd_new(receive_class);
-    x->x_sym = s;
-    pd_bind(&x->x_obj.ob_pd, s);
-    outlet_new(&x->x_obj, 0);
-    return (x);
-}
-
-static void receive_free(t_receive *x)
-{
-    pd_unbind(&x->x_obj.ob_pd, x->x_sym);
-}
-
-static void receive_setup(void)
-{
-    receive_class = class_new(gensym("receive"), (t_newmethod)receive_new, 
-        (t_method)receive_free, sizeof(t_receive), CLASS_NOINLET, A_DEFSYM, 0);
-    class_addcreator((t_newmethod)receive_new, gensym("r"), A_DEFSYM, 0);
-    class_addbang(receive_class, receive_bang);
-    class_addfloat(receive_class, (t_method)receive_float);
-    class_addsymbol(receive_class, receive_symbol);
-    class_addpointer(receive_class, receive_pointer);
-    class_addlist(receive_class, receive_list);
-    class_addanything(receive_class, receive_anything);
-}
-
-/* -------------------------- select ------------------------------ */
-
-static t_class *sel1_class;
-
-typedef struct _sel1
-{
-    t_object x_obj;
-    t_atom x_atom;
-    t_outlet *x_outlet1;
-    t_outlet *x_outlet2;
-} t_sel1;
-
-static void sel1_float(t_sel1 *x, t_float f)
-{
-    if (x->x_atom.a_type == A_FLOAT && f == x->x_atom.a_w.w_float)
-        outlet_bang(x->x_outlet1);
-    else outlet_float(x->x_outlet2, f);
-}
-
-static void sel1_symbol(t_sel1 *x, t_symbol *s)
-{
-    if (x->x_atom.a_type == A_SYMBOL && s == x->x_atom.a_w.w_symbol)
-        outlet_bang(x->x_outlet1);
-    else outlet_symbol(x->x_outlet2, s);
-}
-
-static t_class *sel2_class;
-
-typedef struct _selectelement
-{
-    t_word e_w;
-    t_outlet *e_outlet;
-} t_selectelement;
-
-typedef struct _sel2
-{
-    t_object x_obj;
-    t_atomtype x_type;
-    t_int x_nelement;
-    t_selectelement *x_vec;
-    t_outlet *x_rejectout;
-} t_sel2;
-
-static void sel2_float(t_sel2 *x, t_float f)
-{
-    t_selectelement *e;
-    int nelement;
-    if (x->x_type == A_FLOAT)
-    {
-        for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
-            if (e->e_w.w_float == f)
-        {
-            outlet_bang(e->e_outlet);
-            return;
-        }
-    }
-    outlet_float(x->x_rejectout, f);
-}
-
-static void sel2_symbol(t_sel2 *x, t_symbol *s)
-{
-    t_selectelement *e;
-    int nelement;
-    if (x->x_type == A_SYMBOL)
-    {
-        for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
-            if (e->e_w.w_symbol == s)
-        {
-            outlet_bang(e->e_outlet);
-            return;
-        }
-    }
-    outlet_symbol(x->x_rejectout, s);
-}
-
-static void sel2_free(t_sel2 *x)
-{
-    freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
-}
-
-static void *select_new(t_symbol *s, int argc, t_atom *argv)
-{
-    t_atom a;
-    if (argc == 0)
-    {
-        argc = 1;
-        SETFLOAT(&a, 0);
-        argv = &a;
-    }
-    if (argc == 1)
-    {
-        t_sel1 *x = (t_sel1 *)pd_new(sel1_class);
-        x->x_atom = *argv;
-        x->x_outlet1 = outlet_new(&x->x_obj, &s_bang);
-        if (argv->a_type == A_FLOAT)
-        {
-            floatinlet_new(&x->x_obj, &x->x_atom.a_w.w_float);
-            x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
-        }
-        else
-        {
-            symbolinlet_new(&x->x_obj, &x->x_atom.a_w.w_symbol);
-            x->x_outlet2 = outlet_new(&x->x_obj, &s_symbol);
-        }
-        return (x);
-    }
-    else
-    {
-        int n;
-        t_selectelement *e;
-        t_sel2 *x = (t_sel2 *)pd_new(sel2_class);
-        x->x_nelement = argc;
-        x->x_vec = (t_selectelement *)getbytes(argc * sizeof(*x->x_vec));
-        x->x_type = argv[0].a_type;
-        for (n = 0, e = x->x_vec; n < argc; n++, e++)
-        {
-            e->e_outlet = outlet_new(&x->x_obj, &s_bang);
-            if ((x->x_type = argv->a_type) == A_FLOAT)
-                e->e_w.w_float = atom_getfloatarg(n, argc, argv);
-            else e->e_w.w_symbol = atom_getsymbolarg(n, argc, argv);
-        }
-        x->x_rejectout = outlet_new(&x->x_obj, &s_float);
-        return (x);
-    }
-
-}
-
-void select_setup(void)
-{
-    sel1_class = class_new(gensym("select"), 0, 0,
-        sizeof(t_sel1), 0, 0);
-    class_addfloat(sel1_class, sel1_float);
-    class_addsymbol(sel1_class, sel1_symbol);
-
-    sel2_class = class_new(gensym("select"), 0, (t_method)sel2_free,
-        sizeof(t_sel2), 0, 0);
-    class_addfloat(sel2_class, sel2_float);
-    class_addsymbol(sel2_class, sel2_symbol);
-
-    class_addcreator((t_newmethod)select_new, gensym("select"),  A_GIMME, 0);
-    class_addcreator((t_newmethod)select_new, gensym("sel"),  A_GIMME, 0);
-}
-
-/* -------------------------- route ------------------------------ */
-
-static t_class *route_class;
-
-typedef struct _routeelement
-{
-    t_word e_w;
-    t_outlet *e_outlet;
-} t_routeelement;
-
-typedef struct _route
-{
-    t_object x_obj;
-    t_atomtype x_type;
-    t_int x_nelement;
-    t_routeelement *x_vec;
-    t_outlet *x_rejectout;
-} t_route;
-
-static void route_anything(t_route *x, t_symbol *sel, int argc, t_atom *argv)
-{
-    t_routeelement *e;
-    int nelement;
-    if (x->x_type == A_SYMBOL) 
-    {
-        for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
-            if (e->e_w.w_symbol == sel)
-        {
-            if (argc > 0 && argv[0].a_type == A_SYMBOL)
-                outlet_anything(e->e_outlet, argv[0].a_w.w_symbol,
-                    argc-1, argv+1);
-            else outlet_list(e->e_outlet, 0, argc, argv);
-            return;
-        }
-    }
-    outlet_anything(x->x_rejectout, sel, argc, argv);
-}
-
-static void route_list(t_route *x, t_symbol *sel, int argc, t_atom *argv)
-{
-    t_routeelement *e;
-    int nelement;
-    if (x->x_type == A_FLOAT)
-    {
-        t_float f;
-        if (!argc) return;
-        f = atom_getfloat(argv);
-        for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
-            if (e->e_w.w_float == f)
-        {
-            if (argc > 1 && argv[1].a_type == A_SYMBOL)
-                outlet_anything(e->e_outlet, argv[1].a_w.w_symbol,
-                    argc-2, argv+2);
-            else outlet_list(e->e_outlet, 0, argc-1, argv+1);
-            return;
-        }
-    }
-    else    /* symbol arguments */
-    {
-        if (argc > 1)       /* 2 or more args: treat as "list" */
-        {
-            for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
-            {
-                if (e->e_w.w_symbol == &s_list)
-                {
-                    if (argc > 0 && argv[0].a_type == A_SYMBOL)
-                        outlet_anything(e->e_outlet, argv[0].a_w.w_symbol,
-                            argc-1, argv+1);
-                    else outlet_list(e->e_outlet, 0, argc, argv);
-                    return;
-                }
-            }
-        }
-        else if (argc == 0)         /* no args: treat as "bang" */
-        {
-            for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
-            {
-                if (e->e_w.w_symbol == &s_bang)
-                {
-                    outlet_bang(e->e_outlet);
-                    return;
-                }
-            }
-        }
-        else if (argv[0].a_type == A_FLOAT)     /* one float arg */
-        {
-            for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
-            {
-                if (e->e_w.w_symbol == &s_float)
-                {
-                    outlet_float(e->e_outlet, argv[0].a_w.w_float);
-                    return;
-                }
-            }
-        }
-        else
-        {
-            for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
-            {
-                if (e->e_w.w_symbol == &s_symbol)
-                {
-                    outlet_symbol(e->e_outlet, argv[0].a_w.w_symbol);
-                    return;
-                }
-            }
-        }
-    }
-    outlet_list(x->x_rejectout, 0, argc, argv);
-}
-
-
-static void route_free(t_route *x)
-{
-    freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
-}
-
-static void *route_new(t_symbol *s, int argc, t_atom *argv)
-{
-    int n;
-    t_routeelement *e;
-    t_route *x = (t_route *)pd_new(route_class);
-    t_atom a;
-    if (argc == 0)
-    {
-        argc = 1;
-        SETFLOAT(&a, 0);
-        argv = &a;
-    }
-    x->x_type = argv[0].a_type;
-    x->x_nelement = argc;
-    x->x_vec = (t_routeelement *)getbytes(argc * sizeof(*x->x_vec));
-    for (n = 0, e = x->x_vec; n < argc; n++, e++)
-    {
-        e->e_outlet = outlet_new(&x->x_obj, &s_list);
-        if (x->x_type == A_FLOAT)
-            e->e_w.w_float = atom_getfloatarg(n, argc, argv);
-        else e->e_w.w_symbol = atom_getsymbolarg(n, argc, argv);
-    }
-    x->x_rejectout = outlet_new(&x->x_obj, &s_list);
-    return (x);
-}
-
-void route_setup(void)
-{
-    route_class = class_new(gensym("route"), (t_newmethod)route_new,
-        (t_method)route_free, sizeof(t_route), 0, A_GIMME, 0);
-    class_addlist(route_class, route_list);
-    class_addanything(route_class, route_anything);
-}
-
-/* -------------------------- pack ------------------------------ */
-
-static t_class *pack_class;
-
-typedef struct _pack
-{
-    t_object x_obj;
-    t_int x_n;              /* number of args */
-    t_atom *x_vec;          /* input values */
-    t_int x_nptr;           /* number of pointers */
-    t_gpointer *x_gpointer; /* the pointers */
-    t_atom *x_outvec;       /* space for output values */
-} t_pack;
-
-static void *pack_new(t_symbol *s, int argc, t_atom *argv)
-{
-    t_pack *x = (t_pack *)pd_new(pack_class);
-    t_atom defarg[2], *ap, *vec, *vp;
-    t_gpointer *gp;
-    int nptr = 0;
-    int i;
-    if (!argc)
-    {
-        argv = defarg;
-        argc = 2;
-        SETFLOAT(&defarg[0], 0);
-        SETFLOAT(&defarg[1], 0);
-    }
-
-    x->x_n = argc;
-    vec = x->x_vec = (t_atom *)getbytes(argc * sizeof(*x->x_vec));
-    x->x_outvec = (t_atom *)getbytes(argc * sizeof(*x->x_outvec));
-
-    for (i = argc, ap = argv; i--; ap++)
-        if (ap->a_type == A_SYMBOL && *ap->a_w.w_symbol->s_name == 'p')
-            nptr++;
-
-    gp = x->x_gpointer = (t_gpointer *)t_getbytes(nptr * sizeof (*gp));
-    x->x_nptr = nptr;
-
-    for (i = 0, vp = x->x_vec, ap = argv; i < argc; i++, ap++, vp++)
-    {
-        if (ap->a_type == A_FLOAT)
-        {
-            *vp = *ap;
-            if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float);
-        }
-        else if (ap->a_type == A_SYMBOL)
-        {
-            char c = *ap->a_w.w_symbol->s_name;
-            if (c == 's')
-            {
-                SETSYMBOL(vp, &s_symbol);
-                if (i) symbolinlet_new(&x->x_obj, &vp->a_w.w_symbol);
-            }
-            else if (c == 'p')
-            {
-                vp->a_type = A_POINTER;
-                vp->a_w.w_gpointer = gp;
-                gpointer_init(gp);
-                if (i) pointerinlet_new(&x->x_obj, gp);
-                gp++;
-            }
-            else
-            {
-                if (c != 'f') pd_error(x, "pack: %s: bad type",
-                    ap->a_w.w_symbol->s_name);
-                SETFLOAT(vp, 0);
-                if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float);
-            }
-        }
-    }
-    outlet_new(&x->x_obj, &s_list);
-    return (x);
-}
-
-static void pack_bang(t_pack *x)
-{
-    int i, reentered = 0, size = x->x_n * sizeof (t_atom);
-    t_gpointer *gp;
-    t_atom *outvec;
-    for (i = x->x_nptr, gp = x->x_gpointer; i--; gp++)
-        if (!gpointer_check(gp, 1))
-    {
-        pd_error(x, "pack: stale pointer");
-        return;
-    }
-        /* reentrancy protection.  The first time through use the pre-allocated
-        x_outvec; if we're reentered we have to allocate new memory. */
-    if (!x->x_outvec)
-    {
-            /* LATER figure out how to deal with reentrancy and pointers... */
-        if (x->x_nptr)
-            post("pack_bang: warning: reentry with pointers unprotected");
-        outvec = t_getbytes(size);
-        reentered = 1;
-    }
-    else
-    {
-        outvec = x->x_outvec;
-        x->x_outvec = 0;
-    }
-    memcpy(outvec, x->x_vec, size);
-    outlet_list(x->x_obj.ob_outlet, &s_list, x->x_n, outvec);
-    if (reentered)
-        t_freebytes(outvec, size);
-    else x->x_outvec = outvec;
-}
-
-static void pack_pointer(t_pack *x, t_gpointer *gp)
-{
-    if (x->x_vec->a_type == A_POINTER)
-    {
-        gpointer_unset(x->x_gpointer);
-        *x->x_gpointer = *gp;
-        if (gp->gp_stub) gp->gp_stub->gs_refcount++;
-        pack_bang(x);
-    }
-    else pd_error(x, "pack_pointer: wrong type");
-}
-
-static void pack_float(t_pack *x, t_float f)
-{
-    if (x->x_vec->a_type == A_FLOAT)
-    {
-        x->x_vec->a_w.w_float = f;
-        pack_bang(x);
-    }
-    else pd_error(x, "pack_float: wrong type");
-}
-
-static void pack_symbol(t_pack *x, t_symbol *s)
-{
-    if (x->x_vec->a_type == A_SYMBOL)
-    {
-        x->x_vec->a_w.w_symbol = s;
-        pack_bang(x);
-    }
-    else pd_error(x, "pack_symbol: wrong type");
-}
-
-static void pack_list(t_pack *x, t_symbol *s, int ac, t_atom *av)
-{
-    obj_list(&x->x_obj, 0, ac, av);
-}
-
-static void pack_anything(t_pack *x, t_symbol *s, int ac, t_atom *av)
-{
-    t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom));
-    int i;
-    for (i = 0; i < ac; i++)
-        av2[i + 1] = av[i];
-    SETSYMBOL(av2, s);
-    obj_list(&x->x_obj, 0, ac+1, av2);
-    freebytes(av2, (ac + 1) * sizeof(t_atom));
-}
-
-static void pack_free(t_pack *x)
-{
-    t_gpointer *gp;
-    int i;
-    for (gp = x->x_gpointer, i = x->x_nptr; i--; gp++)
-        gpointer_unset(gp);
-    freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
-    freebytes(x->x_outvec, x->x_n * sizeof(*x->x_outvec));
-    freebytes(x->x_gpointer, x->x_nptr * sizeof(*x->x_gpointer));
-}
-
-static void pack_setup(void)
-{
-    pack_class = class_new(gensym("pack"), (t_newmethod)pack_new,
-        (t_method)pack_free, sizeof(t_pack), 0, A_GIMME, 0);
-    class_addbang(pack_class, pack_bang);
-    class_addpointer(pack_class, pack_pointer);
-    class_addfloat(pack_class, pack_float);
-    class_addsymbol(pack_class, pack_symbol);
-    class_addlist(pack_class, pack_list);
-    class_addanything(pack_class, pack_anything);
-}
-
-/* -------------------------- unpack ------------------------------ */
-
-static t_class *unpack_class;
-
-typedef struct unpackout
-{
-    t_atomtype u_type;
-    t_outlet *u_outlet;
-} t_unpackout;
-
-typedef struct _unpack
-{
-    t_object x_obj;
-    t_int x_n;
-    t_unpackout *x_vec;
-} t_unpack;
-
-static void *unpack_new(t_symbol *s, int argc, t_atom *argv)
-{
-    t_unpack *x = (t_unpack *)pd_new(unpack_class);
-    t_atom defarg[2], *ap;
-    t_unpackout *u;
-    int i;
-    if (!argc)
-    {
-        argv = defarg;
-        argc = 2;
-        SETFLOAT(&defarg[0], 0);
-        SETFLOAT(&defarg[1], 0);
-    }
-    x->x_n = argc;
-    x->x_vec = (t_unpackout *)getbytes(argc * sizeof(*x->x_vec));
-    for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++)
-    {
-        t_atomtype type = ap->a_type;
-        if (type == A_SYMBOL)
-        {
-            char c = *ap->a_w.w_symbol->s_name;
-            if (c == 's')
-            {
-                u->u_type = A_SYMBOL;
-                u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
-            }
-            else if (c == 'p')
-            {
-                u->u_type =  A_POINTER;
-                u->u_outlet = outlet_new(&x->x_obj, &s_pointer);
-            }
-            else
-            {
-                if (c != 'f') pd_error(x, "unpack: %s: bad type",
-                    ap->a_w.w_symbol->s_name);
-                u->u_type = A_FLOAT;
-                u->u_outlet = outlet_new(&x->x_obj, &s_float);
-            }
-        }
-        else
-        {
-            u->u_type =  A_FLOAT;
-            u->u_outlet = outlet_new(&x->x_obj, &s_float);
-        }
-    }
-    return (x);
-}
-
-static void unpack_list(t_unpack *x, t_symbol *s, int argc, t_atom *argv)
-{
-    t_atom *ap;
-    t_unpackout *u;
-    int i;
-    if (argc > x->x_n) argc = x->x_n;
-    for (i = argc, u = x->x_vec + i, ap = argv + i; u--, ap--, i--;)
-    {
-        t_atomtype type = u->u_type;
-        if (type != ap->a_type)
-            pd_error(x, "unpack: type mismatch");
-        else if (type == A_FLOAT)
-            outlet_float(u->u_outlet, ap->a_w.w_float);
-        else if (type == A_SYMBOL)
-            outlet_symbol(u->u_outlet, ap->a_w.w_symbol);
-        else outlet_pointer(u->u_outlet, ap->a_w.w_gpointer);
-    }
-}
-
-static void unpack_anything(t_unpack *x, t_symbol *s, int ac, t_atom *av)
-{
-    t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom));
-    int i;
-    for (i = 0; i < ac; i++)
-        av2[i + 1] = av[i];
-    SETSYMBOL(av2, s);
-    unpack_list(x, 0, ac+1, av2);
-    freebytes(av2, (ac + 1) * sizeof(t_atom));
-}
-
-static void unpack_free(t_unpack *x)
-{
-    freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
-}
-
-static void unpack_setup(void)
-{
-    unpack_class = class_new(gensym("unpack"), (t_newmethod)unpack_new,
-        (t_method)unpack_free, sizeof(t_unpack), 0, A_GIMME, 0);
-    class_addlist(unpack_class, unpack_list);
-    class_addanything(unpack_class, unpack_anything);
-}
-
-/* -------------------------- trigger ------------------------------ */
-
-static t_class *trigger_class;
-#define TR_BANG 0
-#define TR_FLOAT 1
-#define TR_SYMBOL 2
-#define TR_POINTER 3
-#define TR_LIST 4
-#define TR_ANYTHING 5
-
-typedef struct triggerout
-{
-    int u_type;         /* outlet type from above */
-    t_outlet *u_outlet;
-} t_triggerout;
-
-typedef struct _trigger
-{
-    t_object x_obj;
-    t_int x_n;
-    t_triggerout *x_vec;
-} t_trigger;
-
-static void *trigger_new(t_symbol *s, int argc, t_atom *argv)
-{
-    t_trigger *x = (t_trigger *)pd_new(trigger_class);
-    t_atom defarg[2], *ap;
-    t_triggerout *u;
-    int i;
-    if (!argc)
-    {
-        argv = defarg;
-        argc = 2;
-        SETSYMBOL(&defarg[0], &s_bang);
-        SETSYMBOL(&defarg[1], &s_bang);
-    }
-    x->x_n = argc;
-    x->x_vec = (t_triggerout *)getbytes(argc * sizeof(*x->x_vec));
-    for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++)
-    {
-        t_atomtype thistype = ap->a_type;
-        char c;
-        if (thistype == TR_SYMBOL) c = ap->a_w.w_symbol->s_name[0];
-        else if (thistype == TR_FLOAT) c = 'f';
-        else c = 0;
-        if (c == 'p')
-            u->u_type = TR_POINTER,
-                u->u_outlet = outlet_new(&x->x_obj, &s_pointer);
-        else if (c == 'f')
-            u->u_type = TR_FLOAT, u->u_outlet = outlet_new(&x->x_obj, &s_float);
-        else if (c == 'b')
-            u->u_type = TR_BANG, u->u_outlet = outlet_new(&x->x_obj, &s_bang);
-        else if (c == 'l')
-            u->u_type = TR_LIST, u->u_outlet = outlet_new(&x->x_obj, &s_list);
-        else if (c == 's')
-            u->u_type = TR_SYMBOL,
-                u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
-        else if (c == 'a')
-            u->u_type = TR_ANYTHING,
-                u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
-        else
-        {
-            pd_error(x, "trigger: %s: bad type", ap->a_w.w_symbol->s_name);
-            u->u_type = TR_FLOAT, u->u_outlet = outlet_new(&x->x_obj, &s_float);
-        }
-    }
-    return (x);
-}
-
-static void trigger_list(t_trigger *x, t_symbol *s, int argc, t_atom *argv)
-{
-    t_triggerout *u;
-    int i;
-    for (i = x->x_n, u = x->x_vec + i; u--, i--;)
-    {
-        if (u->u_type == TR_FLOAT)
-            outlet_float(u->u_outlet, (argc ? atom_getfloat(argv) : 0));
-        else if (u->u_type == TR_BANG)
-            outlet_bang(u->u_outlet);
-        else if (u->u_type == TR_SYMBOL)
-            outlet_symbol(u->u_outlet,
-                (argc ? atom_getsymbol(argv) : &s_symbol));
-        else if (u->u_type == TR_POINTER)
-        {
-            if (!argc || argv->a_type != TR_POINTER)
-                pd_error(x, "unpack: bad pointer");
-            else outlet_pointer(u->u_outlet, argv->a_w.w_gpointer);
-        }
-        else outlet_list(u->u_outlet, &s_list, argc, argv);
-    }
-}
-
-static void trigger_anything(t_trigger *x, t_symbol *s, int argc, t_atom *argv)
-{
-    t_triggerout *u;
-    int i;
-    for (i = x->x_n, u = x->x_vec + i; u--, i--;)
-    {
-        if (u->u_type == TR_BANG)
-            outlet_bang(u->u_outlet);
-        else if (u->u_type == TR_ANYTHING)
-            outlet_anything(u->u_outlet, s, argc, argv);
-        else pd_error(x, "trigger: can only convert 's' to 'b' or 'a'");
-    }
-}
-
-static void trigger_bang(t_trigger *x)
-{
-    trigger_list(x, 0, 0, 0);
-}
-
-static void trigger_pointer(t_trigger *x, t_gpointer *gp)
-{
-    t_atom at;
-    SETPOINTER(&at, gp);
-    trigger_list(x, 0, 1, &at);
-}
-
-static void trigger_float(t_trigger *x, t_float f)
-{
-    t_atom at;
-    SETFLOAT(&at, f);
-    trigger_list(x, 0, 1, &at);
-}
-
-static void trigger_symbol(t_trigger *x, t_symbol *s)
-{
-    t_atom at;
-    SETSYMBOL(&at, s);
-    trigger_list(x, 0, 1, &at);
-}
-
-static void trigger_free(t_trigger *x)
-{
-    freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
-}
-
-static void trigger_setup(void)
-{
-    trigger_class = class_new(gensym("trigger"), (t_newmethod)trigger_new,
-        (t_method)trigger_free, sizeof(t_trigger), 0, A_GIMME, 0);
-    class_addcreator((t_newmethod)trigger_new, gensym("t"), A_GIMME, 0);
-    class_addlist(trigger_class, trigger_list);
-    class_addbang(trigger_class, trigger_bang);
-    class_addpointer(trigger_class, trigger_pointer);
-    class_addfloat(trigger_class, (t_method)trigger_float);
-    class_addsymbol(trigger_class, trigger_symbol);
-    class_addanything(trigger_class, trigger_anything);
-}
-
-/* -------------------------- spigot ------------------------------ */
-static t_class *spigot_class;
-
-typedef struct _spigot
-{
-    t_object x_obj;
-    t_float x_state;
-} t_spigot;
-
-static void *spigot_new(t_floatarg f)
-{
-    t_spigot *x = (t_spigot *)pd_new(spigot_class);
-    floatinlet_new(&x->x_obj, &x->x_state);
-    outlet_new(&x->x_obj, 0);
-    x->x_state = f;
-    return (x);
-}
-
-static void spigot_bang(t_spigot *x)
-{
-    if (x->x_state != 0) outlet_bang(x->x_obj.ob_outlet);
-}
-
-static void spigot_pointer(t_spigot *x, t_gpointer *gp)
-{
-    if (x->x_state != 0) outlet_pointer(x->x_obj.ob_outlet, gp);
-}
-
-static void spigot_float(t_spigot *x, t_float f)
-{
-    if (x->x_state != 0) outlet_float(x->x_obj.ob_outlet, f);
-}
-
-static void spigot_symbol(t_spigot *x, t_symbol *s)
-{
-    if (x->x_state != 0) outlet_symbol(x->x_obj.ob_outlet, s);
-}
-
-static void spigot_list(t_spigot *x, t_symbol *s, int argc, t_atom *argv)
-{
-    if (x->x_state != 0) outlet_list(x->x_obj.ob_outlet, s, argc, argv);
-}
-
-static void spigot_anything(t_spigot *x, t_symbol *s, int argc, t_atom *argv)
-{
-    if (x->x_state != 0) outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
-}
-
-static void spigot_setup(void)
-{
-    spigot_class = class_new(gensym("spigot"), (t_newmethod)spigot_new, 0,
-        sizeof(t_spigot), 0, A_DEFFLOAT, 0);
-    class_addbang(spigot_class, spigot_bang);
-    class_addpointer(spigot_class, spigot_pointer);
-    class_addfloat(spigot_class, spigot_float);
-    class_addsymbol(spigot_class, spigot_symbol);
-    class_addlist(spigot_class, spigot_list);
-    class_addanything(spigot_class, spigot_anything);
-}
-
-/* --------------------------- moses ----------------------------- */
-static t_class *moses_class;
-
-typedef struct _moses
-{
-    t_object x_ob;
-    t_outlet *x_out2;
-    t_float x_y;
-} t_moses;
-
-static void *moses_new(t_floatarg f)
-{
-    t_moses *x = (t_moses *)pd_new(moses_class);
-    floatinlet_new(&x->x_ob, &x->x_y);
-    outlet_new(&x->x_ob, &s_float);
-    x->x_out2 = outlet_new(&x->x_ob, &s_float);
-    x->x_y = f;
-    return (x);
-}
-
-static void moses_float(t_moses *x, t_float f)
-{
-    if (f < x->x_y) outlet_float(x->x_ob.ob_outlet, f);
-    else outlet_float(x->x_out2, f);
-}
-
-static void moses_setup(void)
-{
-    moses_class = class_new(gensym("moses"), (t_newmethod)moses_new, 0,
-        sizeof(t_moses), 0, A_DEFFLOAT, 0);
-    class_addfloat(moses_class, moses_float);
-}
-
-/* ----------------------- until --------------------- */
-
-static t_class *until_class;
-
-typedef struct _until
-{
-    t_object x_obj;
-    int x_run;
-    int x_count;
-} t_until;
-
-static void *until_new(void)
-{
-    t_until *x = (t_until *)pd_new(until_class);
-    inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2"));
-    outlet_new(&x->x_obj, &s_bang);
-    x->x_run = 0;
-    return (x);
-}
-
-static void until_bang(t_until *x)
-{
-    x->x_run = 1;
-    x->x_count = -1;
-    while (x->x_run && x->x_count)
-        x->x_count--, outlet_bang(x->x_obj.ob_outlet);
-}
-
-static void until_float(t_until *x, t_float f)
-{
-    if (f < 0)
-        f = 0;
-    x->x_run = 1;
-    x->x_count = f;
-    while (x->x_run && x->x_count)
-        x->x_count--, outlet_bang(x->x_obj.ob_outlet);
-}
-
-static void until_bang2(t_until *x)
-{
-    x->x_run = 0;
-}
-
-static void until_setup(void)
-{
-    until_class = class_new(gensym("until"), (t_newmethod)until_new, 0,
-        sizeof(t_until), 0, 0);
-    class_addbang(until_class, until_bang);
-    class_addfloat(until_class, until_float);
-    class_addmethod(until_class, (t_method)until_bang2, gensym("bang2"), 0);
-}
-
-/* ----------------------- makefilename --------------------- */
-
-static t_class *makefilename_class;
-
-typedef struct _makefilename
-{
-    t_object x_obj;
-    t_symbol *x_format;
-    t_atomtype x_accept;
-    int x_intconvert;
-} t_makefilename;
-
-static void makefilename_scanformat(t_makefilename *x)
-{
-    int num=0, infmt=0;
-    char *str,*chr;
-    if (!x->x_format) return;
-    x->x_accept = A_NULL;
-    for (str=x->x_format->s_name; *str; str++) {
-        if (!infmt && *str=='%') {
-            infmt=1;
-            continue;
-        }
-        if (infmt) {
-            if (strchr("-.#0123456789",*str)!=0)
-                continue;
-            if (*str=='s') {
-                x->x_accept = A_SYMBOL;
-                x->x_intconvert = 0;
-                break;
-            }
-            if (strchr("fgGeE",*str)!=0) {
-                x->x_accept = A_FLOAT;
-                x->x_intconvert = 0;
-                break;
-            }
-            if (strchr("xXdiouc",*str)!=0) {
-                x->x_accept = A_FLOAT;
-                x->x_intconvert = 1;
-                break;
-            }
-            infmt=0;
-        }
-    }
-}
-
-static void *makefilename_new(t_symbol *s)
-{
-    t_makefilename *x = (t_makefilename *)pd_new(makefilename_class);
-    if (!s || !*s->s_name)
-        s = gensym("file.%d");
-    outlet_new(&x->x_obj, &s_symbol);
-    x->x_format = s;
-    x->x_accept = A_NULL;
-    x->x_intconvert = 0;
-    makefilename_scanformat(x);
-    return (x);
-}
-
-static void makefilename_float(t_makefilename *x, t_floatarg f)
-{
-    char buf[MAXPDSTRING];
-    if (x->x_accept == A_FLOAT) {
-        if (x->x_intconvert)
-    sprintf(buf, x->x_format->s_name, (int)f);
-        else
-            sprintf(buf, x->x_format->s_name, f);
-    }
-    else
-        sprintf(buf, x->x_format->s_name, "");
-    if (buf[0]!=0)
-    outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
-}
-
-static void makefilename_symbol(t_makefilename *x, t_symbol *s)
-{
-    char buf[MAXPDSTRING];
-    if (x->x_accept == A_SYMBOL)
-    sprintf(buf, x->x_format->s_name, s->s_name);
-    else
-        sprintf(buf, x->x_format->s_name, 0);
-    if (buf[0]!=0)
-    outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
-}
-
-static void makefilename_set(t_makefilename *x, t_symbol *s)
-{
-    x->x_format = s;
-    makefilename_scanformat(x);
-}
-
-static void makefilename_setup(void)
-{
-    makefilename_class = class_new(gensym("makefilename"),
-    (t_newmethod)makefilename_new, 0,
-        sizeof(t_makefilename), 0, A_DEFSYM, 0);
-    class_addfloat(makefilename_class, makefilename_float);
-    class_addsymbol(makefilename_class, makefilename_symbol);
-    class_addmethod(makefilename_class, (t_method)makefilename_set,
-        gensym("set"), A_SYMBOL, 0);
-}
-
-/* -------------------------- swap ------------------------------ */
-static t_class *swap_class;
-
-typedef struct _swap
-{
-    t_object x_obj;
-    t_outlet *x_out2;
-    t_float x_f1;
-    t_float x_f2;
-} t_swap;
-
-static void *swap_new(t_floatarg f)
-{
-    t_swap *x = (t_swap *)pd_new(swap_class);
-    x->x_f2 = f;
-    x->x_f1 = 0;
-    outlet_new(&x->x_obj, &s_float);
-    x->x_out2 = outlet_new(&x->x_obj, &s_float);
-    floatinlet_new(&x->x_obj, &x->x_f2);
-    return (x);
-}
-
-static void swap_bang(t_swap *x)
-{
-    outlet_float(x->x_out2, x->x_f1);
-    outlet_float(x->x_obj.ob_outlet, x->x_f2);
-}
-
-static void swap_float(t_swap *x, t_float f)
-{
-    x->x_f1 = f;
-    swap_bang(x);
-}
-
-void swap_setup(void)
-{
-    swap_class = class_new(gensym("swap"), (t_newmethod)swap_new, 0,
-        sizeof(t_swap), 0, A_DEFFLOAT, 0);
-    class_addcreator((t_newmethod)swap_new, gensym("fswap"), A_DEFFLOAT, 0);
-    class_addbang(swap_class, swap_bang);
-    class_addfloat(swap_class, swap_float);
-}
-
-/* -------------------------- change ------------------------------ */
-static t_class *change_class;
-
-typedef struct _change
-{
-    t_object x_obj;
-    t_float x_f;
-} t_change;
-
-static void *change_new(t_floatarg f)
-{
-    t_change *x = (t_change *)pd_new(change_class);
-    x->x_f = f;
-    outlet_new(&x->x_obj, &s_float);
-    return (x);
-}
-
-static void change_bang(t_change *x)
-{
-    outlet_float(x->x_obj.ob_outlet, x->x_f);
-}
-
-static void change_float(t_change *x, t_float f)
-{
-    if (f != x->x_f)
-    {
-        x->x_f = f;
-        outlet_float(x->x_obj.ob_outlet, x->x_f);
-    }
-}
-
-static void change_set(t_change *x, t_float f)
-{
-    x->x_f = f;
-}
-
-void change_setup(void)
-{
-    change_class = class_new(gensym("change"), (t_newmethod)change_new, 0,
-        sizeof(t_change), 0, A_DEFFLOAT, 0);
-    class_addbang(change_class, change_bang);
-    class_addfloat(change_class, change_float);
-    class_addmethod(change_class, (t_method)change_set, gensym("set"),
-        A_DEFFLOAT, 0);
-}
-
-/* -------------------- value ------------------------------ */
-
-static t_class *value_class, *vcommon_class;
-
-typedef struct vcommon
-{
-    t_pd c_pd;
-    int c_refcount;
-    t_float c_f;
-} t_vcommon;
-
-typedef struct _value
-{
-    t_object x_obj;
-    t_symbol *x_sym;
-    t_float *x_floatstar;
-} t_value;
-
-    /* get a pointer to a named floating-point variable.  The variable
-    belongs to a "vcommon" object, which is created if necessary. */
-t_float *value_get(t_symbol *s)
-{
-    t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
-    if (!c)
-    {
-        c = (t_vcommon *)pd_new(vcommon_class);
-        c->c_f = 0;
-        c->c_refcount = 0;
-        pd_bind(&c->c_pd, s);
-    }
-    c->c_refcount++;
-    return (&c->c_f);
-}
-
-    /* release a variable.  This only frees the "vcommon" resource when the
-    last interested party releases it. */
-void value_release(t_symbol *s)
-{
-    t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
-    if (c)
-    {
-        if (!--c->c_refcount)
-        {
-            pd_unbind(&c->c_pd, s);
-            pd_free(&c->c_pd);
-        }
-    }
-    else bug("value_release");
-}
-
-/*
- * value_getfloat -- obtain the float value of a "value" object 
- *                  return 0 on success, 1 otherwise
- */
-int
-value_getfloat(t_symbol *s, t_float *f) 
-{
-    t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
-    if (!c)
-        return (1);
-    *f = c->c_f;
-    return (0); 
-}
- 
-/*
- * value_setfloat -- set the float value of a "value" object
- *                  return 0 on success, 1 otherwise
- */
-int
-value_setfloat(t_symbol *s, t_float f)
-{
-    t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
-    if (!c)
-        return (1);
-    c->c_f = f; 
-    return (0); 
-}
-
-static void *value_new(t_symbol *s)
-{
-    t_value *x = (t_value *)pd_new(value_class);
-    x->x_sym = s;
-    x->x_floatstar = value_get(s);
-    outlet_new(&x->x_obj, &s_float);
-    return (x);
-}
-
-static void value_bang(t_value *x)
-{
-    outlet_float(x->x_obj.ob_outlet, *x->x_floatstar);
-}
-
-static void value_float(t_value *x, t_float f)
-{
-    *x->x_floatstar = f;
-}
-
-static void value_ff(t_value *x)
-{
-    value_release(x->x_sym);
-}
-
-static void value_setup(void)
-{
-    value_class = class_new(gensym("value"), (t_newmethod)value_new,
-        (t_method)value_ff,
-        sizeof(t_value), 0, A_DEFSYM, 0);
-    class_addcreator((t_newmethod)value_new, gensym("v"), A_DEFSYM, 0);
-    class_addbang(value_class, value_bang);
-    class_addfloat(value_class, value_float);
-    vcommon_class = class_new(gensym("value"), 0, 0,
-        sizeof(t_vcommon), CLASS_PD, 0);
-}
-
-/* -------------- overall setup routine for this file ----------------- */
-
-void x_connective_setup(void)
-{
-    pdint_setup();
-    pdfloat_setup();
-    pdsymbol_setup();
-    bang_setup();
-    send_setup();
-    receive_setup();
-    select_setup();
-    route_setup();
-    pack_setup();
-    unpack_setup();
-    trigger_setup();
-    spigot_setup();
-    moses_setup();
-    until_setup();
-    makefilename_setup();
-    swap_setup();
-    change_setup();
-    value_setup();
-}
-- 
GitLab