diff --git a/src/d_delay.c.orig b/src/d_delay.c.orig
deleted file mode 100644
index 3571e89a6e79994e402bfdc89d07c4a7519e3f9a..0000000000000000000000000000000000000000
--- a/src/d_delay.c.orig
+++ /dev/null
@@ -1,325 +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.  */
-
-/*  send~, delread~, throw~, catch~ */
-
-#include "m_pd.h"
-extern int ugen_getsortno(void);
-
-#define DEFDELVS 64             /* LATER get this from canvas at DSP time */
-static int delread_zero = 0;    /* four bytes of zero for delread~, vd~ */
-
-/* ----------------------------- delwrite~ ----------------------------- */
-static t_class *sigdelwrite_class;
-
-typedef struct delwritectl
-{
-    int c_n;
-    t_sample *c_vec;
-    int c_phase;
-} t_delwritectl;
-
-typedef struct _sigdelwrite
-{
-    t_object x_obj;
-    t_symbol *x_sym;
-    t_delwritectl x_cspace;
-    int x_sortno;   /* DSP sort number at which this was last put on chain */
-    int x_rsortno;  /* DSP sort # for first delread or write in chain */
-    int x_vecsize;  /* vector size for delread~ to use */
-    t_float x_f;
-} t_sigdelwrite;
-
-#define XTRASAMPS 4
-#define SAMPBLK 4
-
-    /* routine to check that all delwrites/delreads/vds have same vecsize */
-static void sigdelwrite_checkvecsize(t_sigdelwrite *x, int vecsize)
-{
-    if (x->x_rsortno != ugen_getsortno())
-    {
-        x->x_vecsize = vecsize;
-        x->x_rsortno = ugen_getsortno();
-    }
-    /*
-        LATER this should really check sample rate and blocking, once that is
-        supported.  Probably we don't actually care about vecsize.
-        For now just suppress this check. */
-#if 0
-    else if (vecsize != x->x_vecsize)
-        pd_error(x, "delread/delwrite/vd vector size mismatch");
-#endif
-}
-
-#include <stdio.h>
-
-static void *sigdelwrite_new(t_symbol *s, t_floatarg msec)
-{
-    int nsamps;
-    t_sigdelwrite *x = (t_sigdelwrite *)pd_new(sigdelwrite_class);
-    if (!*s->s_name) s = gensym("delwrite~");
-    pd_bind(&x->x_obj.ob_pd, s);
-    x->x_sym = s;
-	if (msec == 0) msec = 1000;
-    nsamps = msec * sys_getsr() * (t_float)(0.001f);
-    if (nsamps < 1) nsamps = 1;
-    nsamps += ((- nsamps) & (SAMPBLK - 1));
-    nsamps += DEFDELVS;
-    x->x_cspace.c_n = nsamps;
-    x->x_cspace.c_vec =
-        (t_sample *)getbytes((nsamps + XTRASAMPS) * sizeof(t_sample));
-    x->x_cspace.c_phase = XTRASAMPS;
-    x->x_sortno = 0;
-    x->x_vecsize = 0;
-    x->x_f = 0;
-    return (x);
-}
-
-static t_int *sigdelwrite_perform(t_int *w)
-{
-    t_sample *in = (t_sample *)(w[1]);
-    t_delwritectl *c = (t_delwritectl *)(w[2]);
-    int n = (int)(w[3]);
-    int phase = c->c_phase, nsamps = c->c_n;
-    t_sample *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS);
-    phase += n;
-
-    while (n--)
-    {
-        t_sample f = *in++;
-        if (PD_BIGORSMALL(f))
-            f = 0;
-        *bp++ = f;
-        if (bp == ep)
-        {
-            vp[0] = ep[-4];
-            vp[1] = ep[-3];
-            vp[2] = ep[-2];
-            vp[3] = ep[-1];
-            bp = vp + XTRASAMPS;
-            phase -= nsamps;
-        }
-    }
-    bp = vp + c->c_phase;
-
-    c->c_phase = phase; 
-    return (w+4);
-}
-
-static void sigdelwrite_dsp(t_sigdelwrite *x, t_signal **sp)
-{
-    dsp_add(sigdelwrite_perform, 3, sp[0]->s_vec, &x->x_cspace, sp[0]->s_n);
-    x->x_sortno = ugen_getsortno();
-    sigdelwrite_checkvecsize(x, sp[0]->s_n);
-}
-
-static void sigdelwrite_free(t_sigdelwrite *x)
-{
-    pd_unbind(&x->x_obj.ob_pd, x->x_sym);
-    freebytes(x->x_cspace.c_vec,
-        (x->x_cspace.c_n + XTRASAMPS) * sizeof(t_sample));
-}
-
-static void sigdelwrite_setup(void)
-{
-    sigdelwrite_class = class_new(gensym("delwrite~"), 
-        (t_newmethod)sigdelwrite_new, (t_method)sigdelwrite_free,
-        sizeof(t_sigdelwrite), 0, A_DEFSYM, A_DEFFLOAT, 0);
-    CLASS_MAINSIGNALIN(sigdelwrite_class, t_sigdelwrite, x_f);
-    class_addmethod(sigdelwrite_class, (t_method)sigdelwrite_dsp,
-        gensym("dsp"), 0);
-}
-
-/* ----------------------------- delread~ ----------------------------- */
-static t_class *sigdelread_class;
-
-typedef struct _sigdelread
-{
-    t_object x_obj;
-    t_symbol *x_sym;
-    t_float x_deltime;  /* delay in msec */
-    int x_delsamps;     /* delay in samples */
-    t_float x_sr;       /* samples per msec */
-    t_float x_n;        /* vector size */
-    int x_zerodel;      /* 0 or vecsize depending on read/write order */
-} t_sigdelread;
-
-static void sigdelread_float(t_sigdelread *x, t_float f);
-
-static void *sigdelread_new(t_symbol *s, t_floatarg f)
-{
-    t_sigdelread *x = (t_sigdelread *)pd_new(sigdelread_class);
-    x->x_sym = s;
-    x->x_sr = 1;
-    x->x_n = 1;
-    x->x_zerodel = 0;
-    sigdelread_float(x, f);
-    outlet_new(&x->x_obj, &s_signal);
-    return (x);
-}
-
-static void sigdelread_float(t_sigdelread *x, t_float f)
-{
-    int samps;
-    t_sigdelwrite *delwriter =
-        (t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
-    x->x_deltime = f;
-    if (delwriter)
-    {
-        int delsize = delwriter->x_cspace.c_n;
-        x->x_delsamps = (int)(0.5 + x->x_sr * x->x_deltime)
-            + x->x_n - x->x_zerodel;
-        if (x->x_delsamps < x->x_n) x->x_delsamps = x->x_n;
-        else if (x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS)
-            x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS;
-    }
-}
-
-static t_int *sigdelread_perform(t_int *w)
-{
-    t_sample *out = (t_sample *)(w[1]);
-    t_delwritectl *c = (t_delwritectl *)(w[2]);
-    int delsamps = *(int *)(w[3]);
-    int n = (int)(w[4]);
-    int phase = c->c_phase - delsamps, nsamps = c->c_n;
-    t_sample *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS);
-    if (phase < 0) phase += nsamps;
-    bp = vp + phase;
-
-    while (n--)
-    {
-        *out++ = *bp++;
-        if (bp == ep) bp -= nsamps;
-    }
-    return (w+5);
-}
-
-static void sigdelread_dsp(t_sigdelread *x, t_signal **sp)
-{
-    t_sigdelwrite *delwriter =
-        (t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
-    x->x_sr = sp[0]->s_sr * 0.001;
-    x->x_n = sp[0]->s_n;
-    if (delwriter)
-    {
-        sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
-        x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
-            0 : delwriter->x_vecsize);
-        sigdelread_float(x, x->x_deltime);
-        dsp_add(sigdelread_perform, 4,
-            sp[0]->s_vec, &delwriter->x_cspace, &x->x_delsamps, sp[0]->s_n);
-    }
-    else if (*x->x_sym->s_name)
-        error("delread~: %s: no such delwrite~",x->x_sym->s_name);
-}
-
-static void sigdelread_setup(void)
-{
-    sigdelread_class = class_new(gensym("delread~"),
-        (t_newmethod)sigdelread_new, 0,
-        sizeof(t_sigdelread), 0, A_DEFSYM, A_DEFFLOAT, 0);
-    class_addmethod(sigdelread_class, (t_method)sigdelread_dsp,
-        gensym("dsp"), 0);
-    class_addfloat(sigdelread_class, (t_method)sigdelread_float);
-}
-
-
-/* ----------------------------- vd~ ----------------------------- */
-static t_class *sigvd_class;
-
-typedef struct _sigvd
-{
-    t_object x_obj;
-    t_symbol *x_sym;
-    t_float x_sr;       /* samples per msec */
-    int x_zerodel;      /* 0 or vecsize depending on read/write order */
-    t_float x_f;
-} t_sigvd;
-
-static void *sigvd_new(t_symbol *s)
-{
-    t_sigvd *x = (t_sigvd *)pd_new(sigvd_class);
-    if (!*s->s_name) s = gensym("vd~");
-    x->x_sym = s;
-    x->x_sr = 1;
-    x->x_zerodel = 0;
-    outlet_new(&x->x_obj, &s_signal);
-    x->x_f = 0;
-    return (x);
-}
-
-static t_int *sigvd_perform(t_int *w)
-{
-    t_sample *in = (t_sample *)(w[1]);
-    t_sample *out = (t_sample *)(w[2]);
-    t_delwritectl *ctl = (t_delwritectl *)(w[3]);
-    t_sigvd *x = (t_sigvd *)(w[4]);
-    int n = (int)(w[5]);
-
-    int nsamps = ctl->c_n;
-    t_sample limit = nsamps - n - 1;
-    t_sample fn = n-1;
-    t_sample *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase;
-    t_sample zerodel = x->x_zerodel;
-    while (n--)
-    {
-        t_sample delsamps = x->x_sr * *in++ - zerodel, frac;
-        int idelsamps;
-        t_sample a, b, c, d, cminusb;
-        if (delsamps < 1.00001f) delsamps = 1.00001f;
-        if (delsamps > limit) delsamps = limit;
-        delsamps += fn;
-        fn = fn - 1.0f;
-        idelsamps = delsamps;
-        frac = delsamps - (t_sample)idelsamps;
-        bp = wp - idelsamps;
-        if (bp < vp + 4) bp += nsamps;
-        d = bp[-3];
-        c = bp[-2];
-        b = bp[-1];
-        a = bp[0];
-        cminusb = c-b;
-        *out++ = b + frac * (
-            cminusb - 0.1666667f * (1.-frac) * (
-                (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
-            )
-        );
-    }
-    return (w+6);
-}
-
-static void sigvd_dsp(t_sigvd *x, t_signal **sp)
-{
-    t_sigdelwrite *delwriter =
-        (t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
-    x->x_sr = sp[0]->s_sr * 0.001;
-    if (delwriter)
-    {
-        sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
-        x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
-            0 : delwriter->x_vecsize);
-        dsp_add(sigvd_perform, 5,
-            sp[0]->s_vec, sp[1]->s_vec,
-                &delwriter->x_cspace, x, sp[0]->s_n);
-    }
-    else error("vd~: %s: no such delwrite~",x->x_sym->s_name);
-}
-
-static void sigvd_setup(void)
-{
-    sigvd_class = class_new(gensym("vd~"), (t_newmethod)sigvd_new, 0,
-        sizeof(t_sigvd), 0, A_DEFSYM, 0);
-    class_addmethod(sigvd_class, (t_method)sigvd_dsp, gensym("dsp"), 0);
-    CLASS_MAINSIGNALIN(sigvd_class, t_sigvd, x_f);
-}
-
-/* ----------------------- global setup routine ---------------- */
-
-void d_delay_setup(void)
-{
-    sigdelwrite_setup();
-    sigdelread_setup();
-    sigvd_setup();
-}
-
diff --git a/src/g_canvas.c b/src/g_canvas.c
index 0fee01389f44f284daab0a0bc7d58b65175c0c01..dd9fdd15747c2ca1837e9679ba4f36cc4a960164 100644
--- a/src/g_canvas.c
+++ b/src/g_canvas.c
@@ -709,16 +709,18 @@ void canvas_map(t_canvas *x, t_floatarg f)
     t_gobj *y;
     if (flag)
     {
-        if (!glist_isvisible(x))
-        {
+		//fprintf(stderr,"canvas_map 1\n");
+        //if (!glist_isvisible(x))
+        //{
+			//fprintf(stderr,"canvas_map 1 isvisible\n");
             t_selection *sel;
             if (!x->gl_havewindow)
             {
                 bug("canvas_map");
                 canvas_vis(x, 1);
             }
-			else if (x->gl_mapped == 0)
-				canvas_vis(x, 1);
+			//else if (x->gl_mapped == 0)
+			//	canvas_vis(x, 1);
 
 			/* 	if parent has editor enabled and we're a sub-patch,
 				(but not an abstraction) match its edit mode to that
@@ -741,23 +743,30 @@ void canvas_map(t_canvas *x, t_floatarg f)
 				//canvas_setcursor(x, CURSOR_EDITMODE_NOTHING);
 			//}
 
-            for (y = x->gl_list; y; y = y->g_next)
+			if (!x->gl_list) {
+				//if there are no objects on the canvas
+				//fprintf(stderr,"window is empty\n");
+				canvas_create_editor(x);
+			}
+            else for (y = x->gl_list; y; y = y->g_next) {
                 gobj_vis(y, x, 1);
-			if (x->gl_editor && x->gl_editor->e_selection)
-            	for (sel = x->gl_editor->e_selection; sel; sel = sel->sel_next)
-                	gobj_select(sel->sel_what, x, 1);
+				if (x->gl_editor && x->gl_editor->e_selection)
+		        	for (sel = x->gl_editor->e_selection; sel; sel = sel->sel_next)
+		            	gobj_select(sel->sel_what, x, 1);
+			}
             x->gl_mapped = 1;
             canvas_drawlines(x);
             if (x->gl_isgraph && x->gl_goprect)
                 canvas_drawredrect(x, 1);
             sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x);
-        }
+        //}
     }
     else
     {
+		//fprintf(stderr,"canvas_map 0\n");
         if (glist_isvisible(x))
         {
-                /* just clear out the whole canvas */
+            /* just clear out the whole canvas */
 			sys_vgui(".x%lx.c dtag all selected\n", x);
             sys_vgui(".x%lx.c delete all\n", x);
             x->gl_mapped = 0;
diff --git a/src/g_canvas.c.orig b/src/g_canvas.c.orig
deleted file mode 100644
index 2f032a12d6ef37c4983669f6072f170bfd3dbfeb..0000000000000000000000000000000000000000
--- a/src/g_canvas.c.orig
+++ /dev/null
@@ -1,1819 +0,0 @@
-/* Copyright (c) 1997-2001 Miller Puckette and others.
-* For information on usage and redistribution, and for a DISCLAIMER OF ALL
-* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */
-
-/* this file defines the "glist" class, also known as "canvas" (the two used
-to be different but are now unified except for some fossilized names.) */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "m_pd.h"
-#include "m_imp.h"
-#include "s_stuff.h"
-#include "g_canvas.h"
-#include <string.h>
-#include "g_all_guis.h"
-#include "g_magicglass.h"
-
-// jsarlo
-typedef struct _magicGlass
-{
-    t_object x_obj;
-    t_object *x_connectedObj;
-    int x_connectedOutno;
-    int x_visible;
-    char x_string[4096];
-    char x_old_string[4096];
-    int x_x;
-    int x_y;
-    int x_c;
-    float x_sigF;
-    int x_dspOn;
-    int x_viewOn;
-    float x_maxSample;
-    int x_sampleCount;
-    t_clock *x_clearClock;
-	t_clock *x_flashClock;
-	unsigned int x_maxSize;
-	unsigned int x_issignal;
-};
-// end jsarlo
-
-    /* LATER consider adding font size to this struct (see glist_getfont()) */
-struct _canvasenvironment
-{
-    t_symbol *ce_dir;      /* directory patch lives in */
-    int ce_argc;           /* number of "$" arguments */
-    t_atom *ce_argv;       /* array of "$" arguments */
-    int ce_dollarzero;     /* value of "$0" */
-    t_namelist *ce_path;   /* search path */
-};
-
-#define GLIST_DEFCANVASWIDTH 450
-#define GLIST_DEFCANVASHEIGHT 300
-
-#ifdef __APPLE__
-#define GLIST_DEFCANVASYLOC 22
-#else
-#define GLIST_DEFCANVASYLOC 0
-#endif
-
-/* ---------------------- variables --------------------------- */
-
-extern t_pd *newest;
-t_class *canvas_class;
-int canvas_dspstate;                /* whether DSP is on or off */  
-t_canvas *canvas_editing;           /* last canvas to start text edting */ 
-t_canvas *canvas_whichfind;         /* last canvas we did a find in */ 
-t_canvas *canvas_list;              /* list of all root canvases */
-
-/* ------------------ forward function declarations --------------- */
-static void canvas_start_dsp(void);
-static void canvas_stop_dsp(void);
-static void canvas_drawlines(t_canvas *x);
-static void canvas_setbounds(t_canvas *x, int x1, int y1, int x2, int y2);
-void canvas_reflecttitle(t_canvas *x);
-static void canvas_addtolist(t_canvas *x);
-static void canvas_takeofflist(t_canvas *x);
-static void canvas_pop(t_canvas *x, t_floatarg fvis);
-
-/* --------- functions to handle the canvas environment ----------- */
-
-static t_symbol *canvas_newfilename = &s_;
-static t_symbol *canvas_newdirectory = &s_;
-static int canvas_newargc;
-static t_atom *canvas_newargv;
-
-static void glist_doupdatewindowlist(t_glist *gl, char *sbuf)
-{
-    t_gobj *g;
-    if (glist_amreloadingabstractions)  /* not if we're in a reload */
-        return;
-    if (!gl->gl_owner)
-    {
-        /* this is a canvas; if we have a window, put on "windows" list */
-        t_canvas *canvas = (t_canvas *)gl;
-        if (canvas->gl_havewindow)
-        {
-            if (strlen(sbuf) + strlen(gl->gl_name->s_name) + 100 <= 1024)
-            {
-                char tbuf[1024];
-                sprintf(tbuf, "{{%s} .x%lx} ", gl->gl_name->s_name,
-                    (t_int)canvas);
-                strcat(sbuf, tbuf);
-            }
-        }
-    }
-    for (g = gl->gl_list; g; g = g->g_next)
-    {
-        if (pd_class(&g->g_pd) == canvas_class)
-            glist_doupdatewindowlist((t_glist *)g, sbuf);
-    }
-    return;
-}
-
-    /* maintain the list of visible toplevels for the GUI's "windows" menu */
-void canvas_updatewindowlist( void)
-{
-    t_canvas *x;
-    char sbuf[1024];
-    strcpy(sbuf, "set menu_windowlist {");
-        /* find all root canvases */
-    for (x = canvas_list; x; x = x->gl_next)
-        glist_doupdatewindowlist(x, sbuf);
-    /* next line updates the window menu state before -postcommand tries it */
-    strcat(sbuf, "}\npdtk_fixwindowmenu\n");
-    sys_gui(sbuf);
-}
-
-    /* add a glist the list of "root" canvases (toplevels without parents.) */
-static void canvas_addtolist(t_canvas *x)
-{
-    x->gl_next = canvas_list;
-    canvas_list = x;
-}
-
-static void canvas_takeofflist(t_canvas *x)
-{
-        /* take it off the window list */
-    if (x == canvas_list) canvas_list = x->gl_next;
-    else
-    {
-        t_canvas *z;
-        for (z = canvas_list; z->gl_next != x; z = z->gl_next)
-            ;
-        z->gl_next = x->gl_next;
-    }
-}
-
-
-void canvas_setargs(int argc, t_atom *argv)
-{
-        /* if there's an old one lying around free it here.  This
-        happens if an abstraction is loaded but never gets as far
-        as calling canvas_new(). */
-    if (canvas_newargv)
-        freebytes(canvas_newargv, canvas_newargc * sizeof(t_atom));
-    canvas_newargc = argc;
-    canvas_newargv = copybytes(argv, argc * sizeof(t_atom));
-}
-
-void glob_setfilename(void *dummy, t_symbol *filesym, t_symbol *dirsym)
-{
-    canvas_newfilename = filesym;
-    canvas_newdirectory = dirsym;
-}
-
-t_canvas *canvas_getcurrent(void)
-{
-    return ((t_canvas *)pd_findbyclass(&s__X, canvas_class));
-}
-
-void canvas_setcurrent(t_canvas *x)
-{
-    pd_pushsym(&x->gl_pd);
-}
-
-void canvas_unsetcurrent(t_canvas *x)
-{
-    pd_popsym(&x->gl_pd);
-}
-
-t_canvasenvironment *canvas_getenv(t_canvas *x)
-{
-    if (!x) bug("canvas_getenv");
-    while (!x->gl_env)
-        if (!(x = x->gl_owner))
-            bug("t_canvasenvironment");
-    return (x->gl_env);
-}
-
-int canvas_getdollarzero( void)
-{
-    t_canvas *x = canvas_getcurrent();
-    t_canvasenvironment *env = (x ? canvas_getenv(x) : 0);
-    if (env)
-        return (env->ce_dollarzero);
-    else return (0);
-}
-
-void canvas_getargs(int *argcp, t_atom **argvp)
-{
-    t_canvasenvironment *e = canvas_getenv(canvas_getcurrent());
-    *argcp = e->ce_argc;
-    *argvp = e->ce_argv;
-}
-
-t_symbol *canvas_realizedollar(t_canvas *x, t_symbol *s)
-{
-    t_symbol *ret;
-    char *name = s->s_name;
-    if (strchr(name, '$'))
-    {
-        t_canvasenvironment *env = canvas_getenv(x);
-        canvas_setcurrent(x);
-        ret = binbuf_realizedollsym(s, env->ce_argc, env->ce_argv, 1);
-        canvas_unsetcurrent(x);
-    }
-    else ret = s;
-    return (ret);
-}
-
-t_symbol *canvas_getcurrentdir(void)
-{
-    t_canvasenvironment *e = canvas_getenv(canvas_getcurrent());
-    return (e->ce_dir);
-}
-
-t_symbol *canvas_getdir(t_canvas *x)
-{
-    t_canvasenvironment *e = canvas_getenv(x);
-    return (e->ce_dir);
-}
-
-void canvas_makefilename(t_canvas *x, char *file, char *result, int resultsize)
-{
-    char *dir = canvas_getenv(x)->ce_dir->s_name;
-    if (file[0] == '/' || (file[0] && file[1] == ':') || !*dir)
-    {
-        strncpy(result, file, resultsize);
-        result[resultsize-1] = 0;
-    }
-    else
-    {
-        int nleft;
-        strncpy(result, dir, resultsize);
-        result[resultsize-1] = 0;
-        nleft = resultsize - strlen(result) - 1;
-        if (nleft <= 0) return;
-        strcat(result, "/");
-        strncat(result, file, nleft);
-        result[resultsize-1] = 0;
-    }           
-}
-
-void canvas_rename(t_canvas *x, t_symbol *s, t_symbol *dir)
-{
-    if (strcmp(x->gl_name->s_name, "Pd"))
-        pd_unbind(&x->gl_pd, canvas_makebindsym(x->gl_name));
-    x->gl_name = s;
-    if (strcmp(x->gl_name->s_name, "Pd"))
-        pd_bind(&x->gl_pd, canvas_makebindsym(x->gl_name));
-    if (glist_isvisible(x))
-        canvas_reflecttitle(x);
-    if (dir && dir != &s_)
-    {
-        t_canvasenvironment *e = canvas_getenv(x);
-        e->ce_dir = dir;
-    }
-}
-
-/* --------------- traversing the set of lines in a canvas ----------- */
-
-int canvas_getindex(t_canvas *x, t_gobj *y)
-{
-    t_gobj *y2;
-    int indexno;
-    for (indexno = 0, y2 = x->gl_list; y2 && y2 != y; y2 = y2->g_next)
-        indexno++;
-    return (indexno);
-}
-
-void linetraverser_start(t_linetraverser *t, t_canvas *x)
-{
-    t->tr_ob = 0;
-    t->tr_x = x;
-    t->tr_nextoc = 0;
-    t->tr_nextoutno = t->tr_nout = 0;
-}
-
-t_outconnect *linetraverser_next(t_linetraverser *t)
-{
-    t_outconnect *rval = t->tr_nextoc;
-    int outno;
-    while (!rval)
-    {
-        outno = t->tr_nextoutno;
-        while (outno == t->tr_nout)
-        {
-            t_gobj *y;
-            t_object *ob = 0;
-            if (!t->tr_ob) y = t->tr_x->gl_list;
-            else y = t->tr_ob->ob_g.g_next;
-            for (; y; y = y->g_next)
-                if (ob = pd_checkobject(&y->g_pd)) break;
-            if (!ob) return (0);
-            t->tr_ob = ob;
-            t->tr_nout = obj_noutlets(ob);
-            outno = 0;
-            if (glist_isvisible(t->tr_x))
-                gobj_getrect(y, t->tr_x,
-                    &t->tr_x11, &t->tr_y11, &t->tr_x12, &t->tr_y12);
-            else t->tr_x11 = t->tr_y11 = t->tr_x12 = t->tr_y12 = 0;
-        }
-        t->tr_nextoutno = outno + 1;
-        rval = obj_starttraverseoutlet(t->tr_ob, &t->tr_outlet, outno);
-        t->tr_outno = outno;
-    }
-    t->tr_nextoc = obj_nexttraverseoutlet(rval, &t->tr_ob2,
-        &t->tr_inlet, &t->tr_inno);
-    t->tr_nin = obj_ninlets(t->tr_ob2);
-    if (!t->tr_nin) bug("drawline");
-    if (glist_isvisible(t->tr_x))
-    {
-        int inplus = (t->tr_nin == 1 ? 1 : t->tr_nin - 1);
-        int outplus = (t->tr_nout == 1 ? 1 : t->tr_nout - 1);
-        gobj_getrect(&t->tr_ob2->ob_g, t->tr_x,
-            &t->tr_x21, &t->tr_y21, &t->tr_x22, &t->tr_y22);
-        t->tr_lx1 = t->tr_x11 +
-            ((t->tr_x12 - t->tr_x11 - IOWIDTH) * t->tr_outno) /
-                outplus + IOMIDDLE;
-        t->tr_ly1 = t->tr_y12;
-        t->tr_lx2 = t->tr_x21 +
-            ((t->tr_x22 - t->tr_x21 - IOWIDTH) * t->tr_inno)/inplus +
-                IOMIDDLE;
-        t->tr_ly2 = t->tr_y21;
-    }
-    else
-    {
-        t->tr_x21 = t->tr_y21 = t->tr_x22 = t->tr_y22 = 0;
-        t->tr_lx1 = t->tr_ly1 = t->tr_lx2 = t->tr_ly2 = 0;
-    }
-    return (rval);
-}
-
-void linetraverser_skipobject(t_linetraverser *t)
-{
-    t->tr_nextoc = 0;
-    t->tr_nextoutno = t->tr_nout;
-}
-
-/* -------------------- the canvas object -------------------------- */
-int glist_valid = 10000;
-
-//static void canvas_manual_pd_free(t_canvas *x) {
-//	sys_flushtogui();
-//	pd_free(&x->gl_pd);
-//}
-
-void glist_init(t_glist *x)
-{
-        /* zero out everyone except "pd" field */
-    memset(((char *)x) + sizeof(x->gl_pd), 0, sizeof(*x) - sizeof(x->gl_pd));
-    x->gl_stub = gstub_new(x, 0);
-    x->gl_valid = ++glist_valid;
-    x->gl_xlabel = (t_symbol **)t_getbytes(0);
-    x->gl_ylabel = (t_symbol **)t_getbytes(0);
-}
-
-    /* make a new glist.  It will either be a "root" canvas or else
-    it appears as a "text" object in another window (canvas_getcurrent() 
-    tells us which.) */
-t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv)
-{
-	/*	first alloc one byte or redundant memory to prevent creation of objects with the same "name"
-		which leads to double-action invoked from every single action and eventually possible crashes
-
-		we keep a list of these redundant allocations and destroy them when pd quits */
-	//if (x->gl_owner && x->gl_env) {
-/*
-		t_redundant_mem *new_rm = (t_redundant_mem *)t_getbytes(sizeof(*new_rm));
-		new_rm->rm_what = (int)getbytes(1);
-		if (rm_start == NULL) {
-			//fprintf(stderr,"first allocation\n");
-			rm_start = new_rm;
-			rm_end = new_rm;
-		}
-		else if (rm_start == rm_end) {
-			//fprintf(stderr,"second allocation\n");
-			rm_end = new_rm;
-			rm_start->rm_next = rm_end;
-		}
-		else {
-			//fprintf(stderr,"allocation\n");
-			rm_end->rm_next = new_rm;
-			rm_end = new_rm;
-		}
-*/
-	//}
-
-    t_canvas *x = (t_canvas *)pd_new(canvas_class);
-
-	/* now that we've created a new canvas, add canvas info to the new_rm */
-	//new_rm->rm_canvas = x;
-
-    t_canvas *owner = canvas_getcurrent();
-    t_symbol *s = &s_;
-    int vis = 0, width = GLIST_DEFCANVASWIDTH, height = GLIST_DEFCANVASHEIGHT;
-    int xloc = 0, yloc = GLIST_DEFCANVASYLOC;
-    int font = (owner ? owner->gl_font : sys_defaultfont);
-
-    glist_init(x);
-    // jsarlo
-    x->gl_magic_glass = magicGlass_new((int)x);
-    // end jsarlo
-
-	//if we are root canvas set the clock for script based destructor of the window
-	//if (!owner) {
-	//	x->gl_destroy = clock_new(x, (t_method)canvas_manual_pd_free);
-	//}
-
-    x->gl_obj.te_type = T_OBJECT;
-    if (!owner)
-        canvas_addtolist(x);
-    /* post("canvas %lx, owner %lx", x, owner); */
-
-    if (argc == 5)  /* toplevel: x, y, w, h, font */
-    {
-        xloc = atom_getintarg(0, argc, argv);
-        yloc = atom_getintarg(1, argc, argv);
-        width = atom_getintarg(2, argc, argv);
-        height = atom_getintarg(3, argc, argv);
-        font = atom_getintarg(4, argc, argv);
-    }
-    else if (argc == 6)  /* subwindow: x, y, w, h, name, vis */
-    {
-        xloc = atom_getintarg(0, argc, argv);
-        yloc = atom_getintarg(1, argc, argv);
-        width = atom_getintarg(2, argc, argv);
-        height = atom_getintarg(3, argc, argv);
-        s = atom_getsymbolarg(4, argc, argv);
-        vis = atom_getintarg(5, argc, argv);
-    }
-        /* (otherwise assume we're being created from the menu.) */
-
-    if (canvas_newdirectory->s_name[0])
-    {
-        static int dollarzero = 1000;
-        t_canvasenvironment *env = x->gl_env =
-            (t_canvasenvironment *)getbytes(sizeof(*x->gl_env));
-        if (!canvas_newargv)
-            canvas_newargv = getbytes(0);
-        env->ce_dir = canvas_newdirectory;
-        env->ce_argc = canvas_newargc;
-        env->ce_argv = canvas_newargv;
-        env->ce_dollarzero = dollarzero++;
-        env->ce_path = 0;
-        canvas_newdirectory = &s_;
-        canvas_newargc = 0;
-        canvas_newargv = 0;
-    }
-    else x->gl_env = 0;
-
-    if (yloc < GLIST_DEFCANVASYLOC)
-        yloc = GLIST_DEFCANVASYLOC;
-    if (xloc < 0)
-        xloc = 0;
-    x->gl_x1 = 0;
-    x->gl_y1 = 0;
-    x->gl_x2 = 1;
-    x->gl_y2 = 1;
-    canvas_setbounds(x, xloc, yloc, xloc + width, yloc + height);
-    x->gl_owner = owner;
-    x->gl_name = (*s->s_name ? s : 
-        (canvas_newfilename ? canvas_newfilename : gensym("Pd")));
-    if (strcmp(x->gl_name->s_name, "Pd"))
-        pd_bind(&x->gl_pd, canvas_makebindsym(x->gl_name));
-    x->gl_loading = 1;
-	//fprintf(stderr,"loading = 1 .x%lx owner=.x%lx\n", x, x->gl_owner);
-    x->gl_goprect = 0;      /* no GOP rectangle unless it's turned on later */
-        /* cancel "vis" flag if we're a subpatch of an
-         abstraction inside another patch.  A separate mechanism prevents
-         the toplevel abstraction from showing up. */
-    if (vis && gensym("#X")->s_thing && 
-        ((*gensym("#X")->s_thing) == canvas_class))
-    {
-        t_canvas *zzz = (t_canvas *)(gensym("#X")->s_thing);
-        while (zzz && !zzz->gl_env)
-            zzz = zzz->gl_owner;
-        if (zzz && canvas_isabstraction(zzz) && zzz->gl_owner)
-            vis = 0;
-    }
-    x->gl_willvis = vis;
-    x->gl_edit = !strncmp(x->gl_name->s_name, "Untitled", 8);
-    x->gl_font = sys_nearestfontsize(font);
-    pd_pushsym(&x->gl_pd);
-
-    return(x);
-}
-
-void canvas_setgraph(t_glist *x, int flag, int nogoprect);
-
-static void canvas_coords(t_glist *x, t_symbol *s, int argc, t_atom *argv)
-{
-    x->gl_x1 = atom_getfloatarg(0, argc, argv);
-    x->gl_y1 = atom_getfloatarg(1, argc, argv);
-    x->gl_x2 = atom_getfloatarg(2, argc, argv);
-    x->gl_y2 = atom_getfloatarg(3, argc, argv);
-    x->gl_pixwidth = atom_getintarg(4, argc, argv);
-    x->gl_pixheight = atom_getintarg(5, argc, argv);
-    if (argc <= 7)
-        canvas_setgraph(x, atom_getintarg(6, argc, argv), 1);
-    else
-    {
-        x->gl_xmargin = atom_getintarg(7, argc, argv);
-        x->gl_ymargin = atom_getintarg(8, argc, argv);
-        canvas_setgraph(x, atom_getintarg(6, argc, argv), 0);
-    }
-}
-
-    /* make a new glist and add it to this glist.  It will appear as
-    a "graph", not a text object.  */
-t_glist *glist_addglist(t_glist *g, t_symbol *sym,
-    t_float x1, t_float y1, t_float x2, t_float y2,
-    t_float px1, t_float py1, t_float px2, t_float py2)
-{
-    static int gcount = 0;
-    int zz;
-    int menu = 0;
-    char *str;
-    t_glist *x = (t_glist *)pd_new(canvas_class);
-    glist_init(x);
-    x->gl_obj.te_type = T_OBJECT;
-    if (!*sym->s_name)
-    {
-        char buf[40];
-        sprintf(buf, "graph%d", ++gcount);
-        sym = gensym(buf);
-        menu = 1;
-    }
-    else if (!strncmp((str = sym->s_name), "graph", 5)
-        && (zz = atoi(str + 5)) > gcount)
-            gcount = zz;
-        /* in 0.34 and earlier, the pixel rectangle and the y bounds were
-        reversed; this would behave the same, except that the dialog window
-        would be confusing.  The "correct" way is to have "py1" be the value
-        that is higher on the screen. */
-    if (py2 < py1)
-    {
-        t_float zz;
-        zz = y2;
-        y2 = y1;
-        y1 = zz;
-        zz = py2;
-        py2 = py1;
-        py1 = zz;
-    }
-    if (x1 == x2 || y1 == y2)
-        x1 = 0, x2 = 100, y1 = 1, y2 = -1;
-	if (px1 != 0 && px2 == 0) px2 = px1 + GLIST_DEFGRAPHWIDTH;
-	if (py1 != 0 && py2 == py1) py2 = py1 + GLIST_DEFGRAPHHEIGHT;
-    if (px1 >= px2 || py1 >= py2)
-        px1 = 100, py1 = 20, px2 = 100 + GLIST_DEFGRAPHWIDTH,
-            py2 = 20 + GLIST_DEFGRAPHHEIGHT;
-
-    x->gl_name = sym;
-    x->gl_x1 = x1;
-    x->gl_x2 = x2;
-    x->gl_y1 = y1;
-    x->gl_y2 = y2;
-    x->gl_obj.te_xpix = px1;
-    x->gl_obj.te_ypix = py1;
-    x->gl_pixwidth = px2 - px1;
-    x->gl_pixheight = py2 - py1;
-    x->gl_font =  (canvas_getcurrent() ?
-        canvas_getcurrent()->gl_font : sys_defaultfont);
-    x->gl_screenx1 = x->gl_screeny1 = 0;
-    x->gl_screenx2 = 450;
-    x->gl_screeny2 = 300;
-    if (strcmp(x->gl_name->s_name, "Pd"))
-        pd_bind(&x->gl_pd, canvas_makebindsym(x->gl_name));
-    x->gl_owner = g;
-    x->gl_isgraph = 1;
-    x->gl_goprect = 0;
-    x->gl_obj.te_binbuf = binbuf_new();
-    binbuf_addv(x->gl_obj.te_binbuf, "s", gensym("graph"));
-    if (!menu)
-        pd_pushsym(&x->gl_pd);
-    glist_add(g, &x->gl_gobj);
-	sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (long unsigned int)glist_getcanvas(g));
-    return (x);
-}
-
-    /* call glist_addglist from a Pd message */
-void glist_glist(t_glist *g, t_symbol *s, int argc, t_atom *argv)
-{
-	pd_vmess(&g->gl_pd, gensym("editmode"), "i", 1);
-    t_symbol *sym = atom_getsymbolarg(0, argc, argv);
-	/* if we wish to put a graph where the mouse is we need to replace bogus name */
-	if (!strcmp(sym->s_name, "NULL")) sym = &s_;  
-    t_float x1 = atom_getfloatarg(1, argc, argv);  
-    t_float y1 = atom_getfloatarg(2, argc, argv);  
-    t_float x2 = atom_getfloatarg(3, argc, argv);  
-    t_float y2 = atom_getfloatarg(4, argc, argv);  
-    t_float px1 = atom_getfloatarg(5, argc, argv);  
-    t_float py1 = atom_getfloatarg(6, argc, argv);  
-    t_float px2 = atom_getfloatarg(7, argc, argv);  
-    t_float py2 = atom_getfloatarg(8, argc, argv);
-    glist_addglist(g, sym, x1, y1, x2, y2, px1, py1, px2, py2);
-}
-
-    /* return true if the glist should appear as a graph on parent;
-    otherwise it appears as a text box. */
-int glist_isgraph(t_glist *x)
-{
-  return (x->gl_isgraph|(x->gl_hidetext<<1));
-}
-
-    /* This is sent from the GUI to inform a toplevel that its window has been
-    moved or resized. */
-static void canvas_setbounds(t_canvas *x, int x1, int y1, int x2, int y2)
-{
-    int heightwas = y2 - y1;
-    int heightchange = y2 - y1 - (x->gl_screeny2 - x->gl_screeny1);
-    if (x->gl_screenx1 == x1 && x->gl_screeny1 == y1 &&
-        x->gl_screenx2 == x2 && x->gl_screeny2 == y2)
-            return;
-    x->gl_screenx1 = x1;
-    x->gl_screeny1 = y1;
-    x->gl_screenx2 = x2;
-    x->gl_screeny2 = y2;
-    if (!glist_isgraph(x) && (x->gl_y2 < x->gl_y1)) 
-    {
-            /* if it's flipped so that y grows upward,
-            fix so that zero is bottom edge and redraw.  This is
-            only appropriate if we're a regular "text" object on the
-            parent. */
-        t_float diff = x->gl_y1 - x->gl_y2;
-        t_gobj *y;
-        x->gl_y1 = heightwas * diff;
-        x->gl_y2 = x->gl_y1 - diff;
-            /* and move text objects accordingly; they should stick
-            to the bottom, not the top. */
-        for (y = x->gl_list; y; y = y->g_next)
-            if (pd_checkobject(&y->g_pd))
-                gobj_displace(y, x, 0, heightchange);
-        canvas_redraw(x);
-    }
-}
-
-t_symbol *canvas_makebindsym(t_symbol *s)
-{
-    char buf[MAXPDSTRING];
-    strcpy(buf, "pd-");
-    strcat(buf, s->s_name);
-    return (gensym(buf));
-}
-
-void canvas_reflecttitle(t_canvas *x)
-{
-	//fprintf(stderr,"canvas_reflecttitle\n");
-    char namebuf[MAXPDSTRING];
-    t_canvasenvironment *env = canvas_getenv(x);
-    if (env->ce_argc)
-    {
-        int i;
-        strcpy(namebuf, " (");
-        for (i = 0; i < env->ce_argc; i++)
-        {
-            if (strlen(namebuf) > MAXPDSTRING/2 - 5)
-                break;
-            if (i != 0)
-                strcat(namebuf, " ");
-            atom_string(&env->ce_argv[i], namebuf + strlen(namebuf), 
-                MAXPDSTRING/2);
-        }
-        strcat(namebuf, ")");
-    }
-    else namebuf[0] = 0;
-#ifdef __APPLE__
-    sys_vgui("wm attributes .x%lx -modified %d -titlepath {%s/%s}\n",
-        x, x->gl_dirty, canvas_getdir(x)->s_name, x->gl_name->s_name);
-    sys_vgui("wm title .x%lx {%s%s}\n", x, x->gl_name->s_name, namebuf);
-#else
-	if(glist_istoplevel(x) || !x->gl_isgraph || x->gl_isgraph && x->gl_havewindow || x->gl_loading || x->gl_dirty) {
-		/*fprintf(stderr,"%d %d %d %d %d\n", glist_istoplevel(x), !x->gl_isgraph,
-			x->gl_isgraph && x->gl_havewindow, x->gl_loading,
-			x->gl_dirty);*/
-	    sys_vgui("wm title .x%lx {%s%c%s - %s}\n", 
-	        x, x->gl_name->s_name, (x->gl_dirty? '*' : ' '), namebuf,
-            canvas_getdir(x)->s_name);
-	}
-#endif
-}
-
-    /* mark a glist dirty or clean */
-void canvas_dirty(t_canvas *x, t_floatarg n)
-{
-    t_canvas *x2 = canvas_getrootfor(x);
-    if (glist_amreloadingabstractions)
-        return;
-    if ((unsigned)n != x2->gl_dirty)
-    {
-        x2->gl_dirty = n;
-        if (glist_isvisible(x2))
-            canvas_reflecttitle(x2);
-    }
-}
-
-void canvas_drawredrect(t_canvas *x, int doit)
-{
-    if (doit)
-        sys_vgui(".x%lx.c create line\
-            %d %d %d %d %d %d %d %d %d %d -fill #ff8080 -tags GOP\n",
-            glist_getcanvas(x),
-            x->gl_xmargin, x->gl_ymargin,
-            x->gl_xmargin + x->gl_pixwidth, x->gl_ymargin,
-            x->gl_xmargin + x->gl_pixwidth, x->gl_ymargin + x->gl_pixheight,
-            x->gl_xmargin, x->gl_ymargin + x->gl_pixheight,
-            x->gl_xmargin, x->gl_ymargin);
-    else sys_vgui(".x%lx.c delete GOP\n",  glist_getcanvas(x));
-}
-
-    /* the window becomes "mapped" (visible and not miniaturized) or
-    "unmapped" (either miniaturized or just plain gone.)  This should be
-    called from the GUI after the fact to "notify" us that we're mapped. */
-void canvas_map(t_canvas *x, t_floatarg f)
-{
-	//fprintf(stderr,"canvas_map\n");
-    int flag = (f != 0);
-    t_gobj *y;
-    if (flag)
-    {
-        if (!glist_isvisible(x))
-        {
-            t_selection *sel;
-            if (!x->gl_havewindow)
-            {
-                bug("canvas_map");
-                canvas_vis(x, 1);
-            }
-
-			/* 	if parent has editor enabled and we're a sub-patch,
-				(but not an abstraction) match its edit mode to that
-				of its parent patch. */
-			/*t_glist *parentx;
-			if (!canvas_isabstraction(x)) {
-				if (x->gl_owner) {
-					parentx = x->gl_owner;
-					while (parentx->gl_owner)
-						parentx = parentx->gl_owner;
-					if (parentx->gl_edit)
-						canvas_editmode(x, 1);
-					else if (x->gl_edit)
-						canvas_editmode(x, 0);
-				}
-			}*/
-			/*	for parent windows, let's make sure the cursor is updated
-				as soon as the window is open (if in edit mode) */
-			//else if (x->gl_edit) {
-				//canvas_setcursor(x, CURSOR_EDITMODE_NOTHING);
-			//}
-
-            for (y = x->gl_list; y; y = y->g_next)
-                gobj_vis(y, x, 1);
-            for (sel = x->gl_editor->e_selection; sel; sel = sel->sel_next)
-                gobj_select(sel->sel_what, x, 1);
-            x->gl_mapped = 1;
-            canvas_drawlines(x);
-            if (x->gl_isgraph && x->gl_goprect)
-                canvas_drawredrect(x, 1);
-            sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x);
-        }
-    }
-    else
-    {
-        if (glist_isvisible(x))
-        {
-                /* just clear out the whole canvas */
-			sys_vgui(".x%lx.c dtag all selected\n", x);
-            sys_vgui(".x%lx.c delete all\n", x);
-            x->gl_mapped = 0;
-        }
-    }
-}
-
-void canvas_redraw(t_canvas *x)
-{
-    if (glist_isvisible(x))
-    {
-        canvas_map(x, 0);
-        canvas_map(x, 1);
-		
-		/* now re-highlight our selection */
-	    t_selection *y;
-    	for (y = x->gl_editor->e_selection; y; y = y->sel_next)		
-			gobj_select(y->sel_what, x, 1);
-    }
-}
-
-
-    /* we call this on a non-toplevel glist to "open" it into its
-    own window. */
-void glist_menu_open(t_glist *x)
-{
-    if (glist_isvisible(x) && !glist_istoplevel(x))
-    {
-        t_glist *gl2 = x->gl_owner;
-        if (!gl2) 
-            bug("glist_menu_open");  /* shouldn't happen but not dangerous */
-        else
-        {
-                /* erase ourself in parent window */
-            gobj_vis(&x->gl_gobj, gl2, 0);
-                    /* get rid of our editor (and subeditors) */
-            if (x->gl_editor)
-                canvas_destroy_editor(x);
-            x->gl_havewindow = 1;
-                    /* redraw ourself in parent window (blanked out this time) */
-            gobj_vis(&x->gl_gobj, gl2, 1);
-        }
-    }
-    canvas_vis(x, 1);
-}
-
-int glist_isvisible(t_glist *x)
-{
-    return ((!x->gl_loading) && glist_getcanvas(x)->gl_mapped);
-}
-
-int glist_istoplevel(t_glist *x)
-{
-        /* we consider a graph "toplevel" if it has its own window
-        or if it appears as a box in its parent window so that we
-        don't draw the actual contents there. */
-    return (x->gl_havewindow || !x->gl_isgraph);
-}
-
-int glist_getfont(t_glist *x)
-{
-    while (!x->gl_env)
-        if (!(x = x->gl_owner))
-            bug("t_canvasenvironment");
-    return (x->gl_font);
-}
-
-void canvas_free(t_canvas *x)
-{
-    t_gobj *y;
-    int dspstate = canvas_suspend_dsp();
-    // jsarlo
-    if (x->gl_magic_glass)
-      magicGlass_free(x->gl_magic_glass);
-    // end jsarlo
-
-	//delete clock for gl_destroy
-	//if (x->gl_destroy) clock_free(x->gl_destroy);
-
-    canvas_noundo(x);
-    if (canvas_editing == x)
-        canvas_editing = 0;
-    if (canvas_whichfind == x)
-        canvas_whichfind = 0;
-    glist_noselect(x);
-    while (y = x->gl_list)
-        glist_delete(x, y);
-    if (x == glist_getcanvas(x))
-        canvas_vis(x, 0);
-
-    if (strcmp(x->gl_name->s_name, "Pd"))
-        pd_unbind(&x->gl_pd, canvas_makebindsym(x->gl_name));
-    if (x->gl_env)
-    {
-        freebytes(x->gl_env->ce_argv, x->gl_env->ce_argc * sizeof(t_atom));
-        freebytes(x->gl_env, sizeof(*x->gl_env));
-    }
-    canvas_resume_dsp(dspstate);
-    glist_cleanup(x);
-    gfxstub_deleteforkey(x);        /* probably unnecessary */
-    if (!x->gl_owner)
-        canvas_takeofflist(x);
-}
-
-/* ----------------- lines ---------- */
-
-static void canvas_drawlines(t_canvas *x)
-{
-    t_linetraverser t;
-    t_outconnect *oc;
-    int issignal;
-    
-        linetraverser_start(&t, x);
-        while (oc = linetraverser_next(&t))
-    {
-        issignal = (outlet_getsymbol(t.tr_outlet) == &s_signal ? 1 : 0);
-        sys_vgui(".x%lx.c create line %d %d %d %d -width %d -fill %s \
--tags {l%lx all_cords}\n",
-                 glist_getcanvas(x), t.tr_lx1, t.tr_ly1, t.tr_lx2, t.tr_ly2, 
-                 (issignal ? 2:1), (issignal ? "$signal_cord" : "$msg_cord"),
-                 oc);
-    }
-}
-
-void canvas_fixlinesfor(t_canvas *x, t_text *text)
-{
-    t_linetraverser t;
-    t_outconnect *oc;
-
-    linetraverser_start(&t, x);
-    while (oc = linetraverser_next(&t))
-    {
-        if (t.tr_ob == text || t.tr_ob2 == text)
-        {
-            sys_vgui(".x%lx.c coords l%lx %d %d %d %d\n",
-                glist_getcanvas(x), oc,
-                    t.tr_lx1, t.tr_ly1, t.tr_lx2, t.tr_ly2);
-        }
-    }
-}
-
-    /* kill all lines for the object */
-void canvas_deletelinesfor(t_canvas *x, t_text *text)
-{
-    t_linetraverser t;
-    t_outconnect *oc;
-    linetraverser_start(&t, x);
-    while (oc = linetraverser_next(&t))
-    {
-        if (t.tr_ob == text || t.tr_ob2 == text)
-        {
-            if (x->gl_editor)
-            {
-                sys_vgui(".x%lx.c delete l%lx\n",
-                    glist_getcanvas(x), oc);
-            }
-            obj_disconnect(t.tr_ob, t.tr_outno, t.tr_ob2, t.tr_inno);
-        }
-    }
-}
-
-    /* 	delete all lines for the object 
-		for efficient redrawing of connections */
-void canvas_eraselinesfor(t_canvas *x, t_text *text)
-{
-    t_linetraverser t;
-    t_outconnect *oc;
-    linetraverser_start(&t, x);
-    while (oc = linetraverser_next(&t))
-    {
-        if (t.tr_ob == text || t.tr_ob2 == text)
-        {
-            if (x->gl_editor)
-            {
-                sys_vgui(".x%lx.c delete l%lx\n",
-                    glist_getcanvas(x), oc);
-            }
-        }
-    }
-}
-
-
-    /* kill all lines for one inlet or outlet */
-void canvas_deletelinesforio(t_canvas *x, t_text *text,
-    t_inlet *inp, t_outlet *outp)
-{
-    t_linetraverser t;
-    t_outconnect *oc;
-    linetraverser_start(&t, x);
-    while (oc = linetraverser_next(&t))
-    {
-        if ((t.tr_ob == text && t.tr_outlet == outp) ||
-            (t.tr_ob2 == text && t.tr_inlet == inp))
-        {
-            if (x->gl_editor)
-            {
-                sys_vgui(".x%lx.c delete l%lx\n",
-                    glist_getcanvas(x), oc);
-            }
-            obj_disconnect(t.tr_ob, t.tr_outno, t.tr_ob2, t.tr_inno);
-        }
-    }
-}
-
-static void canvas_pop(t_canvas *x, t_floatarg fvis)
-{
-    if (fvis != 0)
-        canvas_vis(x, 1);
-    pd_popsym(&x->gl_pd);
-    canvas_resortinlets(x);
-    canvas_resortoutlets(x);
-    x->gl_loading = 0;
-	//fprintf(stderr,"loading = 0 .x%lx owner=.x%lx\n", x, x->gl_owner);
-}
-
-void canvas_objfor(t_glist *gl, t_text *x, int argc, t_atom *argv);
-
-
-void canvas_restore(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
-{
-    t_pd *z;
-    if (argc > 3)
-    {
-        t_atom *ap=argv+3;
-        if (ap->a_type == A_SYMBOL)
-        {
-            t_canvasenvironment *e = canvas_getenv(canvas_getcurrent());
-            canvas_rename(x, binbuf_realizedollsym(ap->a_w.w_symbol,
-                e->ce_argc, e->ce_argv, 1), 0);
-        }
-    }
-    canvas_pop(x, x->gl_willvis);
-
-    if (!(z = gensym("#X")->s_thing)) error("canvas_restore: out of context");
-    else if (*z != canvas_class) error("canvas_restore: wasn't a canvas");
-    else
-    {
-        t_canvas *x2 = (t_canvas *)z;
-        x->gl_owner = x2;
-        canvas_objfor(x2, &x->gl_obj, argc, argv);
-    }
-}
-
-static void canvas_loadbangabstractions(t_canvas *x)
-{
-    t_gobj *y;
-    t_symbol *s = gensym("loadbang");
-    for (y = x->gl_list; y; y = y->g_next)
-        if (pd_class(&y->g_pd) == canvas_class)
-    {
-        if (canvas_isabstraction((t_canvas *)y))
-            canvas_loadbang((t_canvas *)y);
-        else
-            canvas_loadbangabstractions((t_canvas *)y);
-    }
-}
-
-void canvas_loadbangsubpatches(t_canvas *x)
-{
-    t_gobj *y;
-    t_symbol *s = gensym("loadbang");
-    for (y = x->gl_list; y; y = y->g_next)
-        if (pd_class(&y->g_pd) == canvas_class)
-    {
-        if (!canvas_isabstraction((t_canvas *)y))
-            canvas_loadbangsubpatches((t_canvas *)y);
-    }
-    for (y = x->gl_list; y; y = y->g_next)
-        if ((pd_class(&y->g_pd) != canvas_class) &&
-            zgetfn(&y->g_pd, s))
-                pd_vmess(&y->g_pd, s, "");
-}
-
-void canvas_loadbang(t_canvas *x)
-{
-    t_gobj *y;
-    canvas_loadbangabstractions(x);
-    canvas_loadbangsubpatches(x);
-}
-/* JMZ:
- * initbang is emitted after the canvas is done, but before the parent canvas is done
- * therefore, initbangs cannot reach to the outlets
- */
-void canvas_initbang(t_canvas *x)
-{
-    t_gobj *y;
-    t_symbol *s = gensym("initbang");
-    /* run "initbang" for all subpatches, but NOT for the child abstractions */
-    for (y = x->gl_list; y; y = y->g_next)
-      if (pd_class(&y->g_pd) == canvas_class)
-        {
-          if (!canvas_isabstraction((t_canvas *)y))
-            canvas_initbang((t_canvas *)y);
-        }
-
-    /* call the initbang()-method for objects that have one */
-    for (y = x->gl_list; y; y = y->g_next)
-      {
-        if ((pd_class(&y->g_pd) != canvas_class) && zgetfn(&y->g_pd, s))
-          {
-            pd_vmess(&y->g_pd, s, "");
-          }
-      }
-}
-/* JMZ:
- * closebang is emitted before the canvas is destroyed
- * and BEFORE subpatches/abstractions in this canvas are destroyed
- */
-void canvas_closebang(t_canvas *x)
-{
-    t_gobj *y;
-    t_symbol *s = gensym("closebang");
-
-    /* call the closebang()-method for objects that have one 
-     * but NOT for subpatches/abstractions: these are called separately
-     * from g_graph:glist_delete()
-     */
-    for (y = x->gl_list; y; y = y->g_next)
-      {
-        if ((pd_class(&y->g_pd) != canvas_class) && zgetfn(&y->g_pd, s))
-          {
-            pd_vmess(&y->g_pd, s, "");
-          }
-      }
-}
-
-/* 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)
-{
-    int cxpix, cypix, cw, ch, txpix, typix, tw, th;
-    if (sscanf(canvasgeom->s_name, "%dx%d+%d+%d", &cw, &ch, &cxpix, &cypix)
-        < 4 ||
-        sscanf(topgeom->s_name, "%dx%d+%d+%d", &tw, &th, &txpix, &typix) < 4)
-        bug("canvas_relocate");
-            /* for some reason this is initially called with cw=ch=1 so
-            we just suppress that here. */
-    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)
-{
-    newest = &x->gl_pd;
-    pd_popsym(&x->gl_pd);
-    //x->gl_loading = 1;
-	//fprintf(stderr,"loading = 1 .x%lx owner=.x%lx\n", x, x->gl_owner);
-    canvas_resortinlets(x);
-    canvas_resortoutlets(x);
-    x->gl_loading = 0;
-	//fprintf(stderr,"loading = 0 .x%lx owner=.x%lx\n", x, x->gl_owner);
-}
-
-void canvas_logerror(t_object *y)
-{
-#ifdef LATER
-    canvas_vis(x, 1);
-    if (!glist_isselected(x, &y->ob_g))
-        glist_select(x, &y->ob_g);
-#endif
-}
-
-/* -------------------------- subcanvases ---------------------- */
-
-static void *subcanvas_new(t_symbol *s)
-{
-    t_atom a[6];
-    t_canvas *x, *z = canvas_getcurrent();
-    if (!*s->s_name) s = gensym("/SUBPATCH/");
-    SETFLOAT(a, 0);
-    SETFLOAT(a+1, GLIST_DEFCANVASYLOC);
-    SETFLOAT(a+2, GLIST_DEFCANVASWIDTH);
-    SETFLOAT(a+3, GLIST_DEFCANVASHEIGHT);
-    SETSYMBOL(a+4, s);
-    SETFLOAT(a+5, 1);
-    x = canvas_new(0, 0, 6, a);
-    x->gl_owner = z;
-    canvas_pop(x, 1);
-    return (x);
-}
-
-static void canvas_click(t_canvas *x,
-    t_floatarg xpos, t_floatarg ypos,
-        t_floatarg shift, t_floatarg ctrl, t_floatarg alt)
-{
-    canvas_vis(x, 1);
-}
-
-
-    /* find out from subcanvas contents how much to fatten the box */
-void canvas_fattensub(t_canvas *x,
-    int *xp1, int *yp1, int *xp2, int *yp2)
-{
-    t_gobj *y;
-    *xp2 += 50;     /* fake for now */
-    *yp2 += 50;
-}
-
-static void canvas_rename_method(t_canvas *x, t_symbol *s, int ac, t_atom *av)
-{
-    if (ac && av->a_type == A_SYMBOL)
-        canvas_rename(x, av->a_w.w_symbol, 0);
-    else if (ac && av->a_type == A_DOLLSYM)
-    {
-        t_canvasenvironment *e = canvas_getenv(x);
-        canvas_setcurrent(x);
-        canvas_rename(x, binbuf_realizedollsym(av->a_w.w_symbol,
-            e->ce_argc, e->ce_argv, 1), 0); 
-        canvas_unsetcurrent(x);
-    }
-    else canvas_rename(x, gensym("Pd"), 0);
-}
-
-/* ------------------ table ---------------------------*/
-
-static int tabcount = 0;
-
-static void *table_new(t_symbol *s, t_floatarg f)
-{
-    t_atom a[9];
-    t_glist *gl;
-    t_canvas *x, *z = canvas_getcurrent();
-    if (s == &s_)
-    {
-         char  tabname[255];
-         t_symbol *t = gensym("table"); 
-         sprintf(tabname, "%s%d", t->s_name, tabcount++);
-         s = gensym(tabname); 
-    }
-    if (f <= 1)
-        f = 100;
-    SETFLOAT(a, 0);
-    SETFLOAT(a+1, GLIST_DEFCANVASYLOC);
-    SETFLOAT(a+2, 600);
-    SETFLOAT(a+3, 400);
-    SETSYMBOL(a+4, s);
-    SETFLOAT(a+5, 0);
-    x = canvas_new(0, 0, 6, a);
-
-    x->gl_owner = z;
-
-        /* create a graph for the table */
-    gl = glist_addglist((t_glist*)x, &s_, 0, -1, (f > 1 ? f-1 : 1), 1,
-        50, 350, 550, 50);
-
-    graph_array(gl, s, &s_float, f, 0);
-
-    canvas_pop(x, 0); 
-
-    return (x);
-}
-
-    /* return true if the "canvas" object is an abstraction (so we don't
-    save its contents, fogr example.)  */
-int canvas_isabstraction(t_canvas *x)
-{
-    return (x->gl_env != 0);
-}
-
-    /* return true if the "canvas" object is a "table". */
-int canvas_istable(t_canvas *x)
-{
-    t_atom *argv = (x->gl_obj.te_binbuf? binbuf_getvec(x->gl_obj.te_binbuf):0);
-    int argc = (x->gl_obj.te_binbuf? binbuf_getnatom(x->gl_obj.te_binbuf) : 0);
-    int istable = (argc && argv[0].a_type == A_SYMBOL &&
-        argv[0].a_w.w_symbol == gensym("table"));
-    return (istable);
-}
-
-    /* return true if the "canvas" object should be treated as a text
-    object.  This is true for abstractions but also for "table"s... */
-/* JMZ: add a flag to gop-abstractions to hide the title */
-int canvas_showtext(t_canvas *x)
-{
-    t_atom *argv = (x->gl_obj.te_binbuf? binbuf_getvec(x->gl_obj.te_binbuf):0);
-    int argc = (x->gl_obj.te_binbuf? binbuf_getnatom(x->gl_obj.te_binbuf) : 0);
-    int isarray = (argc && argv[0].a_type == A_SYMBOL &&
-        argv[0].a_w.w_symbol == gensym("graph"));
-    if(x->gl_hidetext)
-      return 0;
-    else
-      return (!isarray);
-}
-
-    /* get the document containing this canvas */
-t_canvas *canvas_getrootfor(t_canvas *x)
-{
-    if ((!x->gl_owner) || canvas_isabstraction(x))
-        return (x);
-    else return (canvas_getrootfor(x->gl_owner));
-}
-
-/* ------------------------- DSP chain handling ------------------------- */
-
-EXTERN_STRUCT _dspcontext;
-#define t_dspcontext struct _dspcontext
-
-void ugen_start(void);
-void ugen_stop(void);
-
-t_dspcontext *ugen_start_graph(int toplevel, t_signal **sp,
-    int ninlets, int noutlets);
-void ugen_add(t_dspcontext *dc, t_object *x);
-void ugen_connect(t_dspcontext *dc, t_object *x1, int outno,
-    t_object *x2, int inno);
-void ugen_done_graph(t_dspcontext *dc);
-
-    /* schedule one canvas for DSP.  This is called below for all "root"
-    canvases, but is also called from the "dsp" method for sub-
-    canvases, which are treated almost like any other tilde object.  */
-
-static void canvas_dodsp(t_canvas *x, int toplevel, t_signal **sp)
-{
-    t_linetraverser t;
-    t_outconnect *oc;
-    t_gobj *y;
-    t_object *ob;
-    t_symbol *dspsym = gensym("dsp");
-    t_dspcontext *dc;    
-
-        /* create a new "DSP graph" object to use in sorting this canvas.
-        If we aren't toplevel, there are already other dspcontexts around. */
-
-    dc = ugen_start_graph(toplevel, sp,
-        obj_nsiginlets(&x->gl_obj),
-        obj_nsigoutlets(&x->gl_obj));
-
-        /* find all the "dsp" boxes and add them to the graph */
-
-    ob = &x->gl_magic_glass->x_obj;
-    if (ob && x->gl_magic_glass->x_connectedObj) {
-		//fprintf(stderr,"adding cord inspector to dsp\n");
-		ugen_add(dc, ob);  // this t_canvas could be an array, hence no gl_magic_glass
-	}
-    
-    for (y = x->gl_list; y; y = y->g_next)
-        if ((ob = pd_checkobject(&y->g_pd)) && zgetfn(&y->g_pd, dspsym))
-            ugen_add(dc, ob);
-
-        /* ... and all dsp interconnections */
-    linetraverser_start(&t, x);
-    while (oc = linetraverser_next(&t))
-        if (obj_issignaloutlet(t.tr_ob, t.tr_outno))
-            ugen_connect(dc, t.tr_ob, t.tr_outno, t.tr_ob2, t.tr_inno);
-
-        /* finally, sort them and add them to the DSP chain */
-    ugen_done_graph(dc);
-}
-
-static void canvas_dsp(t_canvas *x, t_signal **sp)
-{
-    canvas_dodsp(x, 0, sp);
-}
-
-    /* this routine starts DSP for all root canvases. */
-static void canvas_start_dsp(void)
-{
-    t_canvas *x;
-    if (canvas_dspstate) ugen_stop();
-    else sys_gui("pdtk_pd_dsp ON\n");
-    ugen_start();
-    
-    for (x = canvas_list; x; x = x->gl_next)
-        canvas_dodsp(x, 1, 0);
-    
-    canvas_dspstate = 1;
-}
-
-static void canvas_stop_dsp(void)
-{
-    if (canvas_dspstate)
-    {
-        ugen_stop();
-        sys_gui("pdtk_pd_dsp OFF\n");
-        canvas_dspstate = 0;
-    }
-}
-
-    /* DSP can be suspended before, and resumed after, operations which
-    might affect the DSP chain.  For example, we suspend before loading and
-    resume afterward, so that DSP doesn't get resorted for every DSP object
-    int the patch. */
-
-int canvas_suspend_dsp(void)
-{
-    int rval = canvas_dspstate;
-    if (rval) canvas_stop_dsp();
-    return (rval);
-}
-
-void canvas_resume_dsp(int oldstate)
-{
-    if (oldstate) canvas_start_dsp();
-}
-
-    /* this is equivalent to suspending and resuming in one step. */
-void canvas_update_dsp(void)
-{
-    if (canvas_dspstate) canvas_start_dsp();
-}
-
-void glob_dsp(void *dummy, t_symbol *s, int argc, t_atom *argv)
-{
-    int newstate;
-    if (argc)
-    {
-        newstate = atom_getintarg(0, argc, argv);
-        if (newstate && !canvas_dspstate)
-        {
-            sys_set_audio_state(1);
-            canvas_start_dsp();
-        }
-        else if (!newstate && canvas_dspstate)
-        {
-            canvas_stop_dsp();
-            sys_set_audio_state(0);
-        }
-    }
-    else post("dsp state %d", canvas_dspstate);
-}
-
-void *canvas_getblock(t_class *blockclass, t_canvas **canvasp)
-{
-    t_canvas *canvas = *canvasp;
-    t_gobj *g;
-    void *ret = 0;
-    for (g = canvas->gl_list; g; g = g->g_next)
-    {
-        if (g->g_pd == blockclass)
-            ret = g;
-    }
-    *canvasp = canvas->gl_owner;
-    return(ret);
-}
-    
-/******************* redrawing  data *********************/
-
-    /* redraw all "scalars" (do this if a drawing command is changed.) 
-    LATER we'll use the "template" information to select which ones we
-    redraw.   Action = 0 for redraw, 1 for draw only, 2 for erase. */
-static void glist_redrawall(t_glist *gl, int action)
-{
-    t_gobj *g;
-    int vis = glist_isvisible(gl);
-    for (g = gl->gl_list; g; g = g->g_next)
-    {
-        t_class *cl;
-        if (vis && g->g_pd == scalar_class)
-        {
-            if (action == 1)
-            {
-                if (glist_isvisible(gl))
-                    gobj_vis(g, gl, 1);
-            }
-            else if (action == 2)
-            {
-                if (glist_isvisible(gl))
-                    gobj_vis(g, gl, 0);
-            }
-            else scalar_redraw((t_scalar *)g, gl);
-        }
-        else if (g->g_pd == canvas_class)
-            glist_redrawall((t_glist *)g, action);
-    }
-}
-
-    /* public interface for above. */
-void canvas_redrawallfortemplate(t_template *template, int action)
-{
-    t_canvas *x;
-        /* find all root canvases */
-    for (x = canvas_list; x; x = x->gl_next)
-        glist_redrawall(x, action);
-}
-
-    /* find the template defined by a canvas, and redraw all elements
-    for that */
-void canvas_redrawallfortemplatecanvas(t_canvas *x, int action)
-{
-    t_gobj *g;
-    t_template *tmpl;
-    t_symbol *s1 = gensym("struct");
-    for (g = x->gl_list; g; g = g->g_next)
-    {
-        t_object *ob = pd_checkobject(&g->g_pd);
-        t_atom *argv;
-        if (!ob || ob->te_type != T_OBJECT ||
-            binbuf_getnatom(ob->te_binbuf) < 2)
-            continue;
-        argv = binbuf_getvec(ob->te_binbuf);
-        if (argv[0].a_type != A_SYMBOL || argv[1].a_type != A_SYMBOL
-            || argv[0].a_w.w_symbol != s1)
-                continue;
-        tmpl = template_findbyname(argv[1].a_w.w_symbol);
-        canvas_redrawallfortemplate(tmpl, action);
-    }
-    canvas_redrawallfortemplate(0, action);
-}
-
-/* ------------------------------- declare ------------------------ */
-
-/* put "declare" objects in a patch to tell it about the environment in
-which objects should be created in this canvas.  This includes directories to
-search ("-path", "-stdpath") and object libraries to load
-("-lib" and "-stdlib").  These must be set before the patch containing
-the "declare" object is filled in with its contents; so when the patch is
-saved,  we throw early messages to the canvas to set the environment
-before any objects are created in it. */
-
-static t_class *declare_class;
-extern t_class *import_class;
-
-typedef struct _declare
-{
-    t_object x_obj;
-    t_canvas *x_canvas;
-    int x_useme;
-} t_declare;
-
-static void *declare_new(t_symbol *s, int argc, t_atom *argv)
-{
-    t_declare *x = (t_declare *)pd_new(declare_class);
-    x->x_useme = 1;
-    x->x_canvas = canvas_getcurrent();
-        /* LATER update environment and/or load libraries */
-    return (x);
-}
-
-static void declare_free(t_declare *x)
-{
-    x->x_useme = 0;
-        /* LATER update environment */
-}
-
-void canvas_savedeclarationsto(t_canvas *x, t_binbuf *b)
-{
-    t_gobj *y;
-
-    for (y = x->gl_list; y; y = y->g_next)
-    {
-        if (pd_class(&y->g_pd) == declare_class)
-        {
-            binbuf_addv(b, "s", gensym("#X"));
-            binbuf_addbinbuf(b, ((t_declare *)y)->x_obj.te_binbuf);
-            binbuf_addv(b, ";");
-        }
-        else if (pd_class(&y->g_pd) == import_class)
-        {
-            int i, argc;
-            t_atom *argv;
-            binbuf_addv(b, "s", gensym("#X"));
-            binbuf_addv(b, "s", gensym("declare"));
-            argc = binbuf_getnatom(((t_object *)y)->te_binbuf) - 1;
-            argv = binbuf_getvec(((t_object *)y)->te_binbuf) + 1;
-            for(i = 0; i < argc; ++i)
-            {
-                binbuf_addv(b, "s", gensym("-lib"));
-                binbuf_add(b, 1, argv + i);
-            }
-            binbuf_addv(b, ";");
-        }
-        else if (pd_class(&y->g_pd) == canvas_class)
-            canvas_savedeclarationsto((t_canvas *)y, b);
-    }
-}
-
-static void canvas_completepath(char *from, char *to, int bufsize)
-{
-    if (sys_isabsolutepath(from))
-    {
-        to[0] = '\0';
-    }
-    else
-    {   // if not absolute path, append Pd lib dir
-        strncpy(to, sys_libdir->s_name, bufsize-4);
-        to[bufsize-3] = '\0';
-        strcat(to, "/");
-    }
-    strncat(to, from, bufsize-strlen(to));
-    to[bufsize-1] = '\0';
-}
-
-static void canvas_declare(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i;
-    t_canvasenvironment *e = canvas_getenv(x);
-#if 0
-    startpost("declare:: %s", s->s_name);
-    postatom(argc, argv);
-    endpost();
-#endif
-    for (i = 0; i < argc; i++)
-    {
-        char strbuf[FILENAME_MAX];
-        char *flag = atom_getsymbolarg(i, argc, argv)->s_name;
-        if ((argc > i+1) && !strcmp(flag, "-path"))
-        {
-            e->ce_path = namelist_append(e->ce_path, 
-                atom_getsymbolarg(i+1, argc, argv)->s_name, 0);
-            i++;
-        }
-        else if ((argc > i+1) && !strcmp(flag, "-stdpath"))
-        {
-            canvas_completepath(atom_getsymbolarg(i+1, argc, argv)->s_name,
-                strbuf, FILENAME_MAX);
-            e->ce_path = namelist_append(e->ce_path, strbuf, 0);
-            i++;
-        }
-        else if ((argc > i+1) && !strcmp(flag, "-lib"))
-        {
-            sys_load_lib(x, atom_getsymbolarg(i+1, argc, argv)->s_name);
-            i++;
-        }
-        else if ((argc > i+1) && !strcmp(flag, "-stdlib"))
-        {
-            canvas_completepath(atom_getsymbolarg(i+1, argc, argv)->s_name,
-                strbuf, FILENAME_MAX);
-            sys_load_lib(0, strbuf);
-            i++;
-        }
-        else post("declare: %s: unknown declaration", flag);
-    }
-}
-
-    /* utility function to read a file, looking first down the canvas's search
-    path (set with "declare" objects in the patch and recursively in calling
-    patches), then down the system one.  The filename is the concatenation of
-    "name" and "ext".  "Name" may be absolute, or may be relative with
-    slashes.  If anything can be opened, the true directory
-    ais put in the buffer dirresult (provided by caller), which should
-    be "size" bytes.  The "nameresult" pointer will be set somewhere in
-    the interior of "dirresult" and will give the file basename (with
-    slashes trimmed).  If "bin" is set a 'binary' open is
-    attempted, otherwise ASCII (this only matters on Microsoft.) 
-    If "x" is zero, the file is sought in the directory "." or in the
-    global path.*/
-
-int canvas_open(t_canvas *x, const char *name, const char *ext,
-    char *dirresult, char **nameresult, unsigned int size, int bin)
-{
-    t_namelist *nl, thislist;
-    int fd = -1;
-    t_canvas *y;
-
-        /* first check if "name" is absolute (and if so, try to open) */
-    if (sys_open_absolute(name, ext, dirresult, nameresult, size, bin, &fd))
-        return (fd);
-    
-        /* otherwise "name" is relative; start trying in directories named
-        in this and parent environments */
-    for (y = x; y; y = y->gl_owner)
-        if (y->gl_env)
-    {
-        t_namelist *nl;
-        t_canvas *x2 = x;
-        char *dir;
-        while (x2 && x2->gl_owner)
-            x2 = x2->gl_owner;
-        dir = (x2 ? canvas_getdir(x2)->s_name : ".");
-        for (nl = y->gl_env->ce_path; nl; nl = nl->nl_next)
-        {
-            char realname[FILENAME_MAX];
-            if (sys_isabsolutepath(nl->nl_string))
-            {
-                realname[0] = '\0';
-            }
-            else
-            {   /* if not absolute path, append Pd lib dir */
-                strncpy(realname, dir, FILENAME_MAX);
-                realname[FILENAME_MAX-3] = 0;
-                strcat(realname, "/");
-            }
-            strncat(realname, nl->nl_string, FILENAME_MAX-strlen(realname));
-            realname[FILENAME_MAX-1] = 0;
-            if ((fd = sys_trytoopenone(realname, name, ext,
-                dirresult, nameresult, size, bin)) >= 0)
-                    return (fd);
-        }
-    }
-    return (open_via_path((x ? canvas_getdir(x)->s_name : "."), name, ext,
-        dirresult, nameresult, size, bin));
-}
-
-/* ------------------------------- setup routine ------------------------ */
-
-    /* why are some of these "glist" and others "canvas"? */
-extern void glist_text(t_glist *x, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_bng(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_toggle(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_vslider(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_hslider(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_vdial(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-    /* old version... */
-extern void canvas_hdial(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_hdial(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-    /* new version: */
-extern void canvas_hradio(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_vradio(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_vumeter(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_mycnv(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_numbox(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_msg(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_floatatom(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void canvas_symbolatom(t_glist *gl, t_symbol *s, int argc, t_atom *argv);
-extern void glist_scalar(t_glist *canvas, t_symbol *s, int argc, t_atom *argv);
-
-void g_graph_setup(void);
-void g_editor_setup(void);
-void g_readwrite_setup(void);
-extern void canvas_properties(t_gobj *z);
-
-void g_canvas_setup(void)
-{
-        /* we prevent the user from typing "canvas" in an object box
-        by sending 0 for a creator function. */
-    canvas_class = class_new(gensym("canvas"), 0,
-        (t_method)canvas_free, sizeof(t_canvas), CLASS_NOINLET, 0);
-            /* here is the real creator function, invoked in patch files
-            by sending the "canvas" message to #N, which is bound
-            to pd_camvasmaker. */
-    class_addmethod(pd_canvasmaker, (t_method)canvas_new, gensym("canvas"),
-        A_GIMME, 0);
-    class_addmethod(canvas_class, (t_method)canvas_restore,
-        gensym("restore"), A_GIMME, 0);
-    class_addmethod(canvas_class, (t_method)canvas_coords,
-        gensym("coords"), A_GIMME, 0);
-
-/* -------------------------- objects ----------------------------- */
-    class_addmethod(canvas_class, (t_method)canvas_obj,
-        gensym("obj"), A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_msg,
-        gensym("msg"), A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_floatatom,
-        gensym("floatatom"), A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_symbolatom,
-        gensym("symbolatom"), A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)glist_text,
-        gensym("text"), A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)glist_glist, gensym("graph"),
-        A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)glist_scalar,
-        gensym("scalar"), A_GIMME, A_NULL);
-
-/* -------------- IEMGUI: button, toggle, slider, etc.  ------------ */
-    class_addmethod(canvas_class, (t_method)canvas_bng, gensym("bng"),
-                    A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_toggle, gensym("toggle"),
-                    A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_vslider, gensym("vslider"),
-                    A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_hslider, gensym("hslider"),
-                    A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_hdial, gensym("hdial"),
-                    A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_vdial, gensym("vdial"),
-                    A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_hradio, gensym("hradio"),
-                    A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_vradio, gensym("vradio"),
-                    A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_vumeter, gensym("vumeter"),
-                    A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_mycnv, gensym("mycnv"),
-                    A_GIMME, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_numbox, gensym("numbox"),
-                    A_GIMME, A_NULL);
-
-/* ------------------------ gui stuff --------------------------- */
-    class_addmethod(canvas_class, (t_method)canvas_pop, gensym("pop"),
-        A_DEFFLOAT, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_loadbang,
-        gensym("loadbang"), A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_relocate,
-        gensym("relocate"), A_SYMBOL, A_SYMBOL, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_vis,
-        gensym("vis"), A_FLOAT, A_NULL);
-    class_addmethod(canvas_class, (t_method)glist_menu_open,
-        gensym("menu-open"), A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_map,
-        gensym("map"), A_FLOAT, A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_dirty,
-        gensym("dirty"), A_FLOAT, A_NULL);
-    class_setpropertiesfn(canvas_class, (t_propertiesfn)canvas_properties);
-
-/* ---------------------- list handling ------------------------ */
-    class_addmethod(canvas_class, (t_method)glist_clear, gensym("clear"),
-        A_NULL);
-
-/* ----- subcanvases, which you get by typing "pd" in a box ---- */
-    class_addcreator((t_newmethod)subcanvas_new, gensym("pd"), A_DEFSYMBOL, 0);
-    class_addcreator((t_newmethod)subcanvas_new, gensym("page"),  A_DEFSYMBOL, 0);
-
-    class_addmethod(canvas_class, (t_method)canvas_click,
-        gensym("click"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
-    class_addmethod(canvas_class, (t_method)canvas_dsp, gensym("dsp"), 0);
-    class_addmethod(canvas_class, (t_method)canvas_rename_method,
-        gensym("rename"), A_GIMME, 0);
-
-/*---------------------------- tables -- GG ------------------- */
-
-    class_addcreator((t_newmethod)table_new, gensym("table"),
-        A_DEFSYM, A_DEFFLOAT, 0);
-
-/*---------------------------- declare ------------------- */
-    declare_class = class_new(gensym("declare"), (t_newmethod)declare_new,
-        (t_method)declare_free, sizeof(t_declare), CLASS_NOINLET, A_GIMME, 0);
-    class_addmethod(canvas_class, (t_method)canvas_declare,
-        gensym("declare"), A_GIMME, 0);
-
-/* -------------- setups from other files for canvas_class ---------------- */
-    g_graph_setup();
-    g_editor_setup();
-    g_readwrite_setup();
-}
diff --git a/src/g_editor.c b/src/g_editor.c
index 59cffcc9cbe7d7be6e5778feeb2cfb89980edb7d..938dc1e702c44cb7357f6b8f9c5ae28b49a6891e 100644
--- a/src/g_editor.c
+++ b/src/g_editor.c
@@ -349,8 +349,10 @@ void glist_noselect(t_glist *x)
 {
     if (x->gl_editor)
     {
-        while (x->gl_editor->e_selection)
-            glist_deselect(x, x->gl_editor->e_selection->sel_what);
+		if (x->gl_editor->e_selection) {
+		    while (x->gl_editor->e_selection)
+		        glist_deselect(x, x->gl_editor->e_selection->sel_what);
+		}
         if (x->gl_editor->e_selectedline)
             glist_deselectline(x);
 		if (c_selection == x)
@@ -431,13 +433,14 @@ static const char *canvas_undo_name;
 void canvas_setundo(t_canvas *x, t_undofn undofn, void *buf,
     const char *name)
 {
-	//fprintf(stderr,"canvas_setundo %lx\n", (t_int)x);
+	//fprintf(stderr,"canvas_setundo %s\n", name);
 
     int hadone = 0;
         /* blow away the old undo information.  In one special case the
         old undo info is re-used; if so we shouldn't free it here. */
     if (canvas_undo_fn && canvas_undo_buf && (buf != canvas_undo_buf))
     {
+		//fprintf(stderr,"hadone canvas_setundo\n");
         (*canvas_undo_fn)(canvas_undo_canvas, canvas_undo_buf, UNDO_FREE);
         hadone = 1;
     }
@@ -608,22 +611,24 @@ static void *canvas_undo_set_cut(t_canvas *x, int mode)
         /* store connections into/out of the selection */
     buf->u_reconnectbuf = binbuf_new();
     linetraverser_start(&t, x);
-    while (oc = linetraverser_next(&t))
-    {
-        int issel1 = glist_isselected(x, &t.tr_ob->ob_g);
-        int issel2 = glist_isselected(x, &t.tr_ob2->ob_g);
-        if (issel1 != issel2)
-        {
-            binbuf_addv(buf->u_reconnectbuf, "ssiiii;",
-                gensym("#X"), gensym("connect"),
-                (issel1 ? nnotsel : 0)
-                    + glist_selectionindex(x, &t.tr_ob->ob_g, issel1),
-                t.tr_outno,
-                (issel2 ? nnotsel : 0) +
-                    glist_selectionindex(x, &t.tr_ob2->ob_g, issel2),
-                t.tr_inno);
-        }
-    }
+	if (linetraverser_next(&t)) {
+		while (oc = linetraverser_next(&t))
+		{
+		    int issel1 = glist_isselected(x, &t.tr_ob->ob_g);
+		    int issel2 = glist_isselected(x, &t.tr_ob2->ob_g);
+		    if (issel1 != issel2)
+		    {
+		        binbuf_addv(buf->u_reconnectbuf, "ssiiii;",
+		            gensym("#X"), gensym("connect"),
+		            (issel1 ? nnotsel : 0)
+		                + glist_selectionindex(x, &t.tr_ob->ob_g, issel1),
+		            t.tr_outno,
+		            (issel2 ? nnotsel : 0) +
+		                glist_selectionindex(x, &t.tr_ob2->ob_g, issel2),
+		            t.tr_inno);
+		    }
+		}
+	}
     if (mode == UCUT_TEXT)
     {
         buf->u_objectbuf = canvas_docopy(x);
@@ -706,7 +711,7 @@ static void canvas_undo_cut(t_canvas *x, void *z, int action)
             binbuf_free(buf->u_reconnectbuf);
         if (buf->u_redotextbuf)
             binbuf_free(buf->u_redotextbuf);
-        t_freebytes(buf, sizeof(*buf));
+        if (buf != NULL) t_freebytes(buf, sizeof(*buf));
     }
 }
 
@@ -1159,7 +1164,7 @@ typedef struct _undo_canvas_properties
     unsigned int gl_hidetext:1;     /* hide object-name + args when doing graph on parent */
 } t_undo_canvas_properties;
 
-t_undo_canvas_properties *global_buf; /* we need this to avoid redundant undo creation when pressing apply and then ok in the canvas properties menu */
+t_undo_canvas_properties global_buf; /* we need this to avoid redundant undo creation when pressing apply and then ok in the canvas properties menu */
 
 static void *canvas_undo_set_canvas(t_canvas *x)
 {
@@ -1169,10 +1174,10 @@ static void *canvas_undo_set_canvas(t_canvas *x)
 	if (!x->gl_edit)
 		canvas_editmode(x, 1);
 
-    if (global_buf == NULL) {
-		global_buf = (t_undo_canvas_properties *)getbytes(sizeof(*global_buf));
+    //if (global_buf == NULL) {
+	//	global_buf = (t_undo_canvas_properties *)getbytes(sizeof(*global_buf));
 		//fprintf(stderr,"creating a new buffer for canvas properties\n");
-	}
+	//}
 
 	/*if (
 		global_buf->gl_pixwidth != x->gl_pixwidth ||
@@ -1192,24 +1197,24 @@ static void *canvas_undo_set_canvas(t_canvas *x)
 		global_buf->gl_hidetext != x->gl_hidetext)
 	{*/
 		//fprintf(stderr,"changing values\n");
-		global_buf->gl_pixwidth = x->gl_pixwidth;
-		global_buf->gl_pixheight = x->gl_pixheight;
-		global_buf->gl_x1 = x->gl_x1;
-		global_buf->gl_y1 = x->gl_y1;
-		global_buf->gl_x2 = x->gl_x2;
-		global_buf->gl_y2 = x->gl_y2;
-		global_buf->gl_screenx1 = x->gl_screenx1;
-		global_buf->gl_screeny1 = x->gl_screeny1;
-		global_buf->gl_screenx2 = x->gl_screenx2;
-		global_buf->gl_screeny2 = x->gl_screeny2;
-		global_buf->gl_xmargin = x->gl_xmargin;
-		global_buf->gl_ymargin = x->gl_ymargin;
-		global_buf->gl_goprect = x->gl_goprect;
-		global_buf->gl_isgraph = x->gl_isgraph;
-		global_buf->gl_hidetext = x->gl_hidetext;
+		global_buf.gl_pixwidth = x->gl_pixwidth;
+		global_buf.gl_pixheight = x->gl_pixheight;
+		global_buf.gl_x1 = x->gl_x1;
+		global_buf.gl_y1 = x->gl_y1;
+		global_buf.gl_x2 = x->gl_x2;
+		global_buf.gl_y2 = x->gl_y2;
+		global_buf.gl_screenx1 = x->gl_screenx1;
+		global_buf.gl_screeny1 = x->gl_screeny1;
+		global_buf.gl_screenx2 = x->gl_screenx2;
+		global_buf.gl_screeny2 = x->gl_screeny2;
+		global_buf.gl_xmargin = x->gl_xmargin;
+		global_buf.gl_ymargin = x->gl_ymargin;
+		global_buf.gl_goprect = x->gl_goprect;
+		global_buf.gl_isgraph = x->gl_isgraph;
+		global_buf.gl_hidetext = x->gl_hidetext;
 	//}
 	
-    return (global_buf);
+    return (&global_buf);
 }
 
 extern int gfxstub_haveproperties(void *key);
@@ -1217,7 +1222,7 @@ extern int gfxstub_haveproperties(void *key);
 static void canvas_undo_canvas_apply(t_canvas *x, void *z, int action)
 {
     t_undo_canvas_properties *buf = z;
-    t_undo_canvas_properties *tmp;
+    t_undo_canvas_properties tmp;
 
 	if (!x->gl_edit)
 		canvas_editmode(x, 1);
@@ -1232,24 +1237,24 @@ static void canvas_undo_canvas_apply(t_canvas *x, void *z, int action)
 		}
 
 		//create a temporary data holder
-		tmp = (t_undo_canvas_properties *)getbytes(sizeof(*tmp));
+		//tmp = (t_undo_canvas_properties *)getbytes(sizeof(*tmp));
 
 		//store current canvas values into temporary data holder
-		tmp->gl_pixwidth = x->gl_pixwidth;
-		tmp->gl_pixheight = x->gl_pixheight;
-		tmp->gl_x1 = x->gl_x1;
-		tmp->gl_y1 = x->gl_y1;
-		tmp->gl_x2 = x->gl_x2;
-		tmp->gl_y2 = x->gl_y2;
-		tmp->gl_screenx1 = x->gl_screenx1;
-		tmp->gl_screeny1 = x->gl_screeny1;
-		tmp->gl_screenx2 = x->gl_screenx2;
-		tmp->gl_screeny2 = x->gl_screeny2;
-		tmp->gl_xmargin = x->gl_xmargin;
-		tmp->gl_ymargin = x->gl_ymargin;
-		tmp->gl_goprect = x->gl_goprect;
-		tmp->gl_isgraph = x->gl_isgraph;
-		tmp->gl_hidetext = x->gl_hidetext;
+		tmp.gl_pixwidth = x->gl_pixwidth;
+		tmp.gl_pixheight = x->gl_pixheight;
+		tmp.gl_x1 = x->gl_x1;
+		tmp.gl_y1 = x->gl_y1;
+		tmp.gl_x2 = x->gl_x2;
+		tmp.gl_y2 = x->gl_y2;
+		tmp.gl_screenx1 = x->gl_screenx1;
+		tmp.gl_screeny1 = x->gl_screeny1;
+		tmp.gl_screenx2 = x->gl_screenx2;
+		tmp.gl_screeny2 = x->gl_screeny2;
+		tmp.gl_xmargin = x->gl_xmargin;
+		tmp.gl_ymargin = x->gl_ymargin;
+		tmp.gl_goprect = x->gl_goprect;
+		tmp.gl_isgraph = x->gl_isgraph;
+		tmp.gl_hidetext = x->gl_hidetext;
 
 		//change canvas values with the ones from the undo buffer
 		x->gl_pixwidth = buf->gl_pixwidth;
@@ -1269,24 +1274,24 @@ static void canvas_undo_canvas_apply(t_canvas *x, void *z, int action)
 		x->gl_hidetext = buf->gl_hidetext;
 
 		//copy data values from the temporary data to the undo buffer
-		buf->gl_pixwidth = tmp->gl_pixwidth;
-		buf->gl_pixheight = tmp->gl_pixheight;
-		buf->gl_x1 = tmp->gl_x1;
-		buf->gl_y1 = tmp->gl_y1;
-		buf->gl_x2 = tmp->gl_x2;
-		buf->gl_y2 = tmp->gl_y2;
-		buf->gl_screenx1 = tmp->gl_screenx1;
-		buf->gl_screeny1 = tmp->gl_screeny1;
-		buf->gl_screenx2 = tmp->gl_screenx2;
-		buf->gl_screeny2 = tmp->gl_screeny2;
-		buf->gl_xmargin = tmp->gl_xmargin;
-		buf->gl_ymargin = tmp->gl_ymargin;
-		buf->gl_goprect = tmp->gl_goprect;
-		buf->gl_isgraph = tmp->gl_isgraph;
-		buf->gl_hidetext = tmp->gl_hidetext;
+		buf->gl_pixwidth = tmp.gl_pixwidth;
+		buf->gl_pixheight = tmp.gl_pixheight;
+		buf->gl_x1 = tmp.gl_x1;
+		buf->gl_y1 = tmp.gl_y1;
+		buf->gl_x2 = tmp.gl_x2;
+		buf->gl_y2 = tmp.gl_y2;
+		buf->gl_screenx1 = tmp.gl_screenx1;
+		buf->gl_screeny1 = tmp.gl_screeny1;
+		buf->gl_screenx2 = tmp.gl_screenx2;
+		buf->gl_screeny2 = tmp.gl_screeny2;
+		buf->gl_xmargin = tmp.gl_xmargin;
+		buf->gl_ymargin = tmp.gl_ymargin;
+		buf->gl_goprect = tmp.gl_goprect;
+		buf->gl_isgraph = tmp.gl_isgraph;
+		buf->gl_hidetext = tmp.gl_hidetext;
 
 		//delete temporary data holder
-		t_freebytes(tmp, sizeof(*tmp));
+		//t_freebytes(tmp, sizeof(*tmp));
 
 		//redraw
 		canvas_setgraph(x, x->gl_isgraph, 0);
@@ -1296,7 +1301,7 @@ static void canvas_undo_canvas_apply(t_canvas *x, void *z, int action)
 		}
 		if (x->gl_owner && glist_isvisible(x->gl_owner))
 		{
-			//fprintf(stderr,"we got gop\n");
+			fprintf(stderr,"we got gop\n");
 			glist_noselect(x);
 		    gobj_vis(&x->gl_gobj, x->gl_owner, 0);
 		    gobj_vis(&x->gl_gobj, x->gl_owner, 1);
@@ -1305,13 +1310,18 @@ static void canvas_undo_canvas_apply(t_canvas *x, void *z, int action)
 		//update scrollbars when GOP potentially exceeds window size
 		t_canvas *canvas=(t_canvas *)glist_getcanvas(x);
 		//if gop is being disabled go one level up
-		if (!x->gl_isgraph) canvas=canvas->gl_owner;
+		if (!x->gl_isgraph && x->gl_owner) {
+			canvas=canvas->gl_owner;
+			canvas_redraw(canvas);
+		}
+		sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)x);
 		sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)canvas);
 	}
 
     else if (action == UNDO_FREE)
     {
-        t_freebytes(buf, sizeof(*buf));
+		//fprintf(stderr,"free...\n");
+        //if (buf != NULL) t_freebytes(buf, sizeof(*buf));
     }
 }
 
@@ -1340,31 +1350,35 @@ void *canvas_undo_set_create(t_canvas *x)
     int nnotsel= glist_selectionindex(x, 0, 0);
 
     buf->u_objectbuf = binbuf_new();
-    for (y = x->gl_list; y; y = y->g_next)
-    {
-        if (glist_isselected(x, y)) {
-			//fprintf(stderr,"saving object\n");
-            gobj_save(y, buf->u_objectbuf);
+	if (x->gl_list) {
+		for (y = x->gl_list; y; y = y->g_next)
+		{
+		    if (glist_isselected(x, y)) {
+				//fprintf(stderr,"saving object\n");
+		        gobj_save(y, buf->u_objectbuf);
+			}
 		}
-    }
+	}
     buf->u_reconnectbuf = binbuf_new();
     linetraverser_start(&t, x);
-    while (oc = linetraverser_next(&t))
-    {
-        int issel1 = glist_isselected(x, &t.tr_ob->ob_g);
-        int issel2 = glist_isselected(x, &t.tr_ob2->ob_g);
-        if (issel1 != issel2)
-        {
-            binbuf_addv(buf->u_reconnectbuf, "ssiiii;",
-                gensym("#X"), gensym("connect"),
-                (issel1 ? nnotsel : 0)
-                    + glist_selectionindex(x, &t.tr_ob->ob_g, issel1),
-                t.tr_outno,
-                (issel2 ? nnotsel : 0) +
-                    glist_selectionindex(x, &t.tr_ob2->ob_g, issel2),
-                t.tr_inno);
-        }
-    }
+	if (linetraverser_next(&t)) {
+		while (oc = linetraverser_next(&t))
+		{
+		    int issel1 = glist_isselected(x, &t.tr_ob->ob_g);
+		    int issel2 = glist_isselected(x, &t.tr_ob2->ob_g);
+		    if (issel1 != issel2)
+		    {
+		        binbuf_addv(buf->u_reconnectbuf, "ssiiii;",
+		            gensym("#X"), gensym("connect"),
+		            (issel1 ? nnotsel : 0)
+		                + glist_selectionindex(x, &t.tr_ob->ob_g, issel1),
+		            t.tr_outno,
+		            (issel2 ? nnotsel : 0) +
+		                glist_selectionindex(x, &t.tr_ob2->ob_g, issel2),
+		            t.tr_inno);
+		    }
+		}
+	}
     return (buf);
 }
 
@@ -1544,10 +1558,10 @@ void canvas_destroy_editor(t_glist *x)
         	    if (ob = pd_checkobject(&y->g_pd))
         	        rtext_free(glist_findrtext(x, ob));
 		}
-		if (x->gl_editor) {
-			editor_free(x->gl_editor, x);
-			x->gl_editor = 0;
-		}
+		//if (x->gl_editor) {
+		editor_free(x->gl_editor, x);
+		x->gl_editor = 0;
+		//}
 	}
 }
 
@@ -1705,11 +1719,14 @@ void canvas_setgraph(t_glist *x, int flag, int nogoprect)
             canvas_destroy_editor(x);
         x->gl_isgraph = 0;
 		x->gl_hidetext = 0;
+		//x->gl_editor = 0;
         if (x->gl_owner && !x->gl_loading && glist_isvisible(x->gl_owner))
         {
             gobj_vis(&x->gl_gobj, x->gl_owner, 1);
             canvas_fixlinesfor(x->gl_owner, &x->gl_obj);
         }
+		//if (x->gl_havewindow && hadeditor)
+		//	canvas_editmode(x, 1);
     }
     else if (flag)
     {
@@ -1850,6 +1867,7 @@ static void canvas_donecanvasdialog(t_glist *x,
     canvas_setgraph(x, graphme, 0);
     canvas_dirty(x, 1);
     if (x->gl_havewindow) {
+		//fprintf(stderr,"donecanvasdialog canvas_redraw\n");
         canvas_redraw(x);
 	}
     else if (x->gl_owner && glist_isvisible(x->gl_owner))
@@ -3343,6 +3361,7 @@ static void canvas_copyfromexternalbuffer(t_canvas *x, t_symbol *s, int ac, t_at
 {
 	if (!x->gl_editor)
 		return;
+	/*
 	if (ac == 0) {
 		//fprintf(stderr,"init\n");
 		copyfromexternalbuffer = 1;
@@ -3358,6 +3377,7 @@ static void canvas_copyfromexternalbuffer(t_canvas *x, t_symbol *s, int ac, t_at
 			//fprintf(stderr,"ignoring canvas\n");
 		}
 	}
+	*/
 }
 
 static void canvas_copy(t_canvas *x)
@@ -3489,7 +3509,7 @@ static void canvas_cut(t_canvas *x)
     if (x->gl_editor && x->gl_editor->e_selectedline)
         canvas_clearline(x);
 	/* if we are cutting text */
-    else if (x->gl_editor->e_textedfor)
+    else if (x->gl_editor && x->gl_editor->e_textedfor)
     {
         char *buf;
         int bufsize;
diff --git a/src/g_editor_patch b/src/g_editor_patch
deleted file mode 100644
index 8011283ac8426be58b64372b8fd1815ee79e106f..0000000000000000000000000000000000000000
--- a/src/g_editor_patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- g_editor.c.old	2011-02-17 20:02:34.000000000 -0500
-+++ g_editor.c	2011-02-18 13:02:41.000000000 -0500
-@@ -240,6 +240,8 @@
- {
-     if (x->gl_editor)
-     {
-+		if (c_selection && c_selection != x)
-+			glist_noselect(c_selection);
-         t_selection *sel = (t_selection *)getbytes(sizeof(*sel));
-         if (x->gl_editor->e_selectedline)
-             glist_deselectline(x);
-@@ -3211,7 +3213,10 @@
-     int dspstate = canvas_suspend_dsp(), nbox, count;
- 
-     canvas_editmode(x, 1.);
--    glist_noselect(x);
-+	if (c_selection && c_selection != x)
-+		glist_noselect(c_selection);
-+	else
-+    	glist_noselect(x);
-     for (g2 = x->gl_list, nbox = 0; g2; g2 = g2->g_next) nbox++;
-     
- 	/* found the end of the queue */
-@@ -3296,7 +3301,6 @@
- 		} else {
- 		    canvas_setundo(x, canvas_undo_paste, canvas_undo_set_paste(x),
- 		        "duplicate");
--			glist_noselect(c_selection);
- 		    canvas_dopaste(x, copy_binbuf);
- 		    //canvas_paste_xyoffset(x);
- 		    canvas_dirty(x, 1);
diff --git a/src/g_graph.c b/src/g_graph.c
index fdf21f25e6f7f24b52a184ab7ca8b159b318432b..b7d1ed8a7e2c304bfb49a3f91284328753c41e4a 100644
--- a/src/g_graph.c
+++ b/src/g_graph.c
@@ -79,74 +79,84 @@ void canvas_closebang(t_canvas *x);
     /* delete an object from a glist and free it */
 void glist_delete(t_glist *x, t_gobj *y)
 {
-    t_gobj *g;
-    t_object *ob;
-    t_gotfn chkdsp = zgetfn(&y->g_pd, gensym("dsp"));
-    t_canvas *canvas = glist_getcanvas(x);
-    int drawcommand = class_isdrawcommand(y->g_pd);
-    int wasdeleting;
-
-    if (pd_class(&y->g_pd) == canvas_class) {
-      /* JMZ: send a closebang to the canvas */
-      canvas_closebang((t_canvas *)y);
-    }
- 
-    wasdeleting = canvas_setdeleting(canvas, 1);
-    if (x->gl_editor)
-    {
-        if (x->gl_editor->e_grab == y) x->gl_editor->e_grab = 0;
-        if (glist_isselected(x, y)) glist_deselect(x, y);
-
-            /* HACK -- we had phantom outlets not getting erased on the
-            screen because the canvas_setdeleting() mechanism is too
-            crude.  LATER carefully set up rules for when the rtexts
-            should exist, so that they stay around until all the
-            steps of becoming invisible are done.  In the meantime, just
-            zap the inlets and outlets here... */
-        if (pd_class(&y->g_pd) == canvas_class)
-        {
-            t_glist *gl = (t_glist *)y;
-            if (gl->gl_isgraph)
-            {
-                char tag[80];
-                //sprintf(tag, "graph%lx", (t_int)gl);
-				//t_glist *yy = (t_glist *)y;
-				sprintf(tag, "%s", rtext_gettag(glist_findrtext(x, &gl->gl_obj)));
-                glist_eraseiofor(x, &gl->gl_obj, tag);
-                text_eraseborder(&gl->gl_obj, x,
-                    rtext_gettag(glist_findrtext(x, &gl->gl_obj)));
-            }
-            else
-            {
-                text_eraseborder(&gl->gl_obj, x,
-                    rtext_gettag(glist_findrtext(x, &gl->gl_obj)));
-            }
-        }
-    }
-        /* if we're a drawing command, erase all scalars now, before deleting
-        it; we'll redraw them once it's deleted below. */
-    if (drawcommand)
-        canvas_redrawallfortemplate(template_findbyname(canvas_makebindsym(
-            glist_getcanvas(x)->gl_name)), 2);
-    if (glist_isvisible(canvas))
-        gobj_vis(y, x, 0);
-    if (x->gl_editor && (ob = pd_checkobject(&y->g_pd)))
-        rtext_new(x, ob);
-    if (x->gl_list == y) x->gl_list = y->g_next;
-    else for (g = x->gl_list; g; g = g->g_next)
-        if (g->g_next == y)
-    {
-        g->g_next = y->g_next;
-        break;
-    }
-    gobj_delete(y, x);
-    pd_free(&y->g_pd);
-    if (chkdsp) canvas_update_dsp();
-    if (drawcommand)
-        canvas_redrawallfortemplate(template_findbyname(canvas_makebindsym(
-            glist_getcanvas(x)->gl_name)), 1);
-    canvas_setdeleting(canvas, wasdeleting);
-    x->gl_valid = ++glist_valid;
+	if (x->gl_list) {
+
+		t_gobj *g;
+		t_object *ob;
+		t_gotfn chkdsp = zgetfn(&y->g_pd, gensym("dsp"));
+		t_canvas *canvas = glist_getcanvas(x);
+		int drawcommand = class_isdrawcommand(y->g_pd);
+		int wasdeleting;
+
+		if (pd_class(&y->g_pd) == canvas_class) {
+		  /* JMZ: send a closebang to the canvas */
+		  canvas_closebang((t_canvas *)y);
+		}
+	 
+		wasdeleting = canvas_setdeleting(canvas, 1);
+		if (x->gl_editor)
+		{
+		    if (x->gl_editor->e_grab == y) x->gl_editor->e_grab = 0;
+		    if (glist_isselected(x, y)) glist_deselect(x, y);
+
+		        /* HACK -- we had phantom outlets not getting erased on the
+		        screen because the canvas_setdeleting() mechanism is too
+		        crude.  LATER carefully set up rules for when the rtexts
+		        should exist, so that they stay around until all the
+		        steps of becoming invisible are done.  In the meantime, just
+		        zap the inlets and outlets here... */
+		    if (pd_class(&y->g_pd) == canvas_class)
+		    {
+		        t_glist *gl = (t_glist *)y;
+		        if (gl->gl_isgraph)
+		        {
+		            char tag[80];
+		            //sprintf(tag, "graph%lx", (t_int)gl);
+					//t_glist *yy = (t_glist *)y;
+					sprintf(tag, "%s", rtext_gettag(glist_findrtext(x, &gl->gl_obj)));
+		            glist_eraseiofor(x, &gl->gl_obj, tag);
+		            text_eraseborder(&gl->gl_obj, x,
+		                rtext_gettag(glist_findrtext(x, &gl->gl_obj)));
+		        }
+		        else
+		        {
+		            text_eraseborder(&gl->gl_obj, x,
+		                rtext_gettag(glist_findrtext(x, &gl->gl_obj)));
+		        }
+		    }
+		}
+		    /* if we're a drawing command, erase all scalars now, before deleting
+		    it; we'll redraw them once it's deleted below. */
+		if (drawcommand)
+		    canvas_redrawallfortemplate(template_findbyname(canvas_makebindsym(
+		        glist_getcanvas(x)->gl_name)), 2);
+		if (glist_isvisible(canvas))
+		    gobj_vis(y, x, 0);
+		if (x->gl_editor && (ob = pd_checkobject(&y->g_pd)))
+		    rtext_new(x, ob);
+		if (x->gl_list == y) {
+			if (y->g_next)		
+				x->gl_list = y->g_next;
+			else
+				x->gl_list = NULL;
+		}
+		else for (g = x->gl_list; g; g = g->g_next)
+		    if (g->g_next == y)
+		{
+			if (y->g_next)
+			    g->g_next = y->g_next;
+			else g->g_next = NULL;
+		    break;
+		}
+		gobj_delete(y, x);
+		pd_free(&y->g_pd);
+		if (chkdsp) canvas_update_dsp();
+		if (drawcommand)
+		    canvas_redrawallfortemplate(template_findbyname(canvas_makebindsym(
+		        glist_getcanvas(x)->gl_name)), 1);
+		canvas_setdeleting(canvas, wasdeleting);
+		x->gl_valid = ++glist_valid;
+	}
 }
 
     /* remove every object from a glist.  Experimental. */
diff --git a/src/g_magicglass.c.orig b/src/g_magicglass.c.orig
deleted file mode 100644
index 2b30e528f0f85fb844431a70fa2810fe10c83c0c..0000000000000000000000000000000000000000
--- a/src/g_magicglass.c.orig
+++ /dev/null
@@ -1,432 +0,0 @@
-#include "m_pd.h"
-#include <stdio.h>
-#include "string.h"
-#include "m_pd.h"
-#include "m_imp.h"
-#include "s_stuff.h"
-#define MG_CLOCK_CLEAR_DELAY 500.5
-#define MG_CLOCK_FLASH_DELAY 50
-#define MG_SAMPLE_COUNT 2205
-
-EXTERN int glist_getfont(t_glist *x);
-
-t_class *magicGlass_class;
-
-typedef struct _magicGlass
-{
-    t_object x_obj;
-    t_object *x_connectedObj;
-    int x_connectedOutno;
-    int x_visible;
-    char x_string[4096];
-    char x_old_string[4096];
-    int x_x;
-    int x_y;
-    int x_c;
-    float x_sigF;
-    int x_dspOn;
-    int x_viewOn;
-    float x_maxSample;
-    int x_sampleCount;
-    t_clock *x_clearClock;
-	t_clock *x_flashClock;
-	unsigned int x_maxSize;
-	unsigned int x_issignal;
-	int x_display_font;
-} t_magicGlass;
-
-void magicGlass_clearText(t_magicGlass *x);
-
-void magicGlass_bind(t_magicGlass *x, t_object *obj, int outno)
-{
-	//fprintf(stderr,"magicglass_bind\n");
-    if (x->x_connectedObj != obj)
-    {
-        if (x->x_connectedObj)
-        {
-            obj_disconnect(x->x_connectedObj,
-                           x->x_connectedOutno,
-                           &x->x_obj,
-                           0);
-        }
-        x->x_connectedObj = obj;
-        x->x_connectedOutno = outno;
-		x->x_maxSize = 1;
-		magicGlass_clearText(x);
-        obj_connect(obj, outno, &x->x_obj, 0);
-    }
-}
-
-void magicGlass_unbind(t_magicGlass *x)
-{
-	//fprintf(stderr,"magicglass_unbind\n");
-    if (x->x_connectedObj)
-    {
-        obj_disconnect(x->x_connectedObj,
-                       x->x_connectedOutno,
-                       &x->x_obj,
-                       0);
-    }
-    x->x_dspOn = 0;
-    x->x_maxSample = -999999;
-    x->x_sampleCount = 0;
-    x->x_connectedObj = NULL;
-    x->x_connectedOutno = 0;
-	x->x_maxSize = 1;
-}
-
-void magicGlass_updateText(t_magicGlass *x, int moved)
-{
-	//fprintf(stderr,"magicglass_updateText\n");
-    int bgSize;
-	/* change second argument (10.0) to provide optimal scaling in the following entry */
-	float font = (float)(sys_hostfontsize(glist_getfont((t_glist *)(x->x_c))))/10.0;
-	if (font <= 1.0) {
-		x->x_display_font = 9;
-		font = 1.0;
-	} else {
-		x->x_display_font = sys_hostfontsize(glist_getfont((t_glist *)(x->x_c)));
-	}
-
-    if (x->x_visible)
-    {
-		if (!moved) {
-			char *color;
-			if (x->x_issignal || strcmp(x->x_old_string, x->x_string)) {
-				color = "#ffffff";
-			}
-			else {
-				color = "#e87216";
-				clock_delay(x->x_flashClock, MG_CLOCK_FLASH_DELAY);
-			}
-		    sys_vgui(".x%x.c itemconfigure magicGlassText -text {%s} -fill %s\n",
-		            x->x_c,
-		            x->x_string,
-					color);
-		} else {
-		    sys_vgui(".x%x.c itemconfigure magicGlassText -text {%s}\n",
-		            x->x_c,
-		            x->x_string);
-		}
-
-        if (strlen(x->x_string) > 0)
-        {
-			if (strlen(x->x_string) > x->x_maxSize) x->x_maxSize = strlen(x->x_string);
-        }
-		bgSize = x->x_x + (int)((30.0 * font) + ((font * 7.0) * (float)x->x_maxSize));
-        sys_vgui(".x%x.c coords magicGlassText %d %d\n",
-                 x->x_c,
-                 x->x_x + 20,
-                 x->x_y);
-        sys_vgui(".x%x.c coords magicGlassLine %d %d %d %d %d %d\n",
-                 x->x_c,
-                 x->x_x + 3,
-                 x->x_y,
-                 x->x_x + 13,
-                 x->x_y + 5,
-                 x->x_x + 13,
-                 x->x_y - 5);
-        sys_vgui(".x%x.c coords magicGlassBg %d %d %d %d\n",
-                 x->x_c,
-                 x->x_x + 13,
-                 x->x_y - (int)(12.0 * font),
-                 bgSize,
-                 x->x_y + (int)(12.0 * font));
-    }
-}
-
-void magicGlass_drawNew(t_magicGlass *x)
-{
-	//fprintf(stderr,"magicglass_drawNew\n");
-    sys_vgui(".x%x.c create rectangle 0 0 0 0 -outline #ffffff -fill #000000 -tags magicGlassBg\n",
-             x->x_c);
-    sys_vgui(".x%x.c create polygon 0 0 0 0 0 0 -fill #000000 -width 4 -tags magicGlassLine\n",
-             x->x_c);
-    sys_vgui(".x%x.c create text 0 0 -text {} -anchor w -fill #e87216 -font {{%s} %d %s} -tags magicGlassText\n",
-             x->x_c, sys_font, x->x_display_font, sys_fontweight);
-    sys_vgui(".x%x.c raise magicGlassBg\n",
-             x->x_c);
-    sys_vgui(".x%x.c raise magicGlassText\n",
-             x->x_c);
-    magicGlass_updateText(x, 0);
-	clock_delay(x->x_flashClock, MG_CLOCK_FLASH_DELAY);
-}
-
-void magicGlass_undraw(t_magicGlass *x)
-{
-	//fprintf(stderr,"magicglass_undraw\n");
-    sys_vgui(".x%x.c delete magicGlassBg\n", x->x_c);
-    sys_vgui(".x%x.c delete magicGlassLine\n", x->x_c);
-    sys_vgui(".x%x.c delete magicGlassText\n", x->x_c);
-}
-
-void magicGlass_flashText(t_magicGlass *x)
-{
-	//fprintf(stderr,"magicglass_flashText\n");
-    sys_vgui(".x%x.c itemconfigure magicGlassText -fill #ffffff\n",
-         x->x_c);
-}
-
-void magicGlass_clearText(t_magicGlass *x)
-{
-	//fprintf(stderr,"magicglass_clearText\n");
-	strcpy(x->x_old_string, x->x_string);
-    x->x_string[0] = 0;
-    magicGlass_updateText(x, 0);
-}
-
-void magicGlass_bang(t_magicGlass *x) 
-{
-	x->x_issignal = 0;
-	strcpy(x->x_old_string, x->x_string);
-    strcpy(x->x_string, "bang");
-    magicGlass_updateText(x, 0);
-    clock_delay(x->x_clearClock, MG_CLOCK_CLEAR_DELAY);
-}
-
-void magicGlass_float(t_magicGlass *x, t_float f) 
-{
-	x->x_issignal = 0;
-	strcpy(x->x_old_string, x->x_string);
-    sprintf(x->x_string, "%g", f);
-    magicGlass_updateText(x, 0);
-    clock_delay(x->x_clearClock, MG_CLOCK_CLEAR_DELAY);
-}
-
-void magicGlass_symbol(t_magicGlass *x, t_symbol *sym)
-{
-	x->x_issignal = 0;
-	strcpy(x->x_old_string, x->x_string);
-    sprintf(x->x_string, "symbol %s", sym->s_name);
-    magicGlass_updateText(x, 0);
-    clock_delay(x->x_clearClock, MG_CLOCK_CLEAR_DELAY);
-}
-
-void magicGlass_anything(t_magicGlass *x, t_symbol *sym, int argc, t_atom *argv)
-{
-    char aString[4096];
-    char valueString[4096];
-    int i;
-
-	x->x_issignal = 0;
-
-	strcpy(x->x_old_string, x->x_string);
-    strcpy(aString, sym->s_name);
-    valueString[0] = 0;
-    for (i = 0; i < argc; i++)
-    {
-        if (argv[i].a_type == A_SYMBOL)
-        {
-            sprintf(valueString, " %s", argv[i].a_w.w_symbol->s_name);
-            strcat(aString, valueString);
-        }
-        else if (argv[i].a_type == A_FLOAT)
-        {
-            sprintf(valueString, " %g", argv[i].a_w.w_float);
-            strcat(aString, valueString);
-        }
-    }
-    strcpy(x->x_string, aString);
-    magicGlass_updateText(x, 0);
-    clock_delay(x->x_clearClock, MG_CLOCK_CLEAR_DELAY);
-}
-
-void magicGlass_list(t_magicGlass *x, t_symbol *sym, int argc, t_atom *argv)
-{
-    char aString[4096];
-    char valueString[4096];
-    int i;
-
-	x->x_issignal = 0;
-
-    aString[0] = 0;
-    valueString[0] = 0;
-
-	strcpy(x->x_old_string, x->x_string);
-	strcpy(aString, sym->s_name);
-    for (i = 0; i < argc; i++)
-    {
-        if (argv[i].a_type == A_SYMBOL)
-        {
-            sprintf(valueString, " %s", argv[i].a_w.w_symbol->s_name);
-            strcat(aString, valueString);
-        }
-        else if (argv[i].a_type == A_FLOAT)
-        {
-            sprintf(valueString, " %g", argv[i].a_w.w_float);
-            strcat(aString, valueString);
-        }
-    }
-    strcpy(x->x_string, aString);
-    magicGlass_updateText(x, 0);
-    clock_delay(x->x_clearClock, MG_CLOCK_CLEAR_DELAY);
-}
-
-void magicGlass_setCanvas(t_magicGlass *x, int c)
-{
-    x->x_c = c;
-}
-
-void magicGlass_show(t_magicGlass *x)
-{
-	//fprintf(stderr,"magicglass_show\n");
-    if (!x->x_visible) {
-		x->x_sampleCount = 0;
-		x->x_maxSample = -999999;
-		x->x_string[0] = 0;
-        x->x_visible = 1;
-        magicGlass_drawNew(x);
-    }
-}
-
-void magicGlass_hide(t_magicGlass *x)
-{
-	//fprintf(stderr,"magicglass_hide\n");
-    if (x->x_visible) {
-        magicGlass_undraw(x);
-		x->x_sampleCount = 0;
-		x->x_maxSample = -999999;
-		x->x_string[0] = 0;
-		x->x_visible = 0;
-	}
-}
-
-void magicGlass_moveText(t_magicGlass *x, int pX, int pY)
-{
-	//fprintf(stderr,"magicglass_moveText\n");
-    int bgSize;
-    
-    x->x_x = pX;
-    x->x_y = pY;
-    magicGlass_updateText(x, 1);
-}
-
-int magicGlass_bound(t_magicGlass *x)
-{
-	//fprintf(stderr,"magicglass_bound\n");
-    if (x->x_connectedObj)
-        return 1;
-    else
-        return 0;
-}
-
-int magicGlass_isOn(t_magicGlass *x)
-{
-	//fprintf(stderr,"magicglass_isOn\n");
-    if (x->x_viewOn)
-        return 1;
-    else
-        return 0;
-}
-
-void magicGlass_setOn(t_magicGlass *x, int i)
-{
-	//fprintf(stderr,"magicglass_setOn\n");
-    if (i)
-    {
-        x->x_viewOn = 1;
-    }
-    else
-    {
-        x->x_viewOn = 0;
-    }
-}
-
-void magicGlass_setDsp(t_magicGlass *x, int i)
-{
-	//fprintf(stderr,"magicglass_setDsp\n");
-	if (i != x->x_dspOn) {
-		if (i)
-		{
-		    x->x_dspOn = 1;
-		    x->x_sampleCount = 0;
-		    x->x_maxSample = -999999;
-		}
-		else
-		{
-		    x->x_dspOn = 0;
-		}
-	}
-}
-
-t_int *magicGlass_perform(t_int *w)
-{
-    t_magicGlass *x = (t_magicGlass *)(w[1]);
-    if (x->x_dspOn && x->x_connectedObj)
-    {
-		//fprintf(stderr,"magicglass_perform\n");
-		float *in = (float *)(w[2]);
-		int N = (int)(w[3]);
-		int i;
-        for (i = 0; i < N; i++)
-        {
-            if (in[i] > x->x_maxSample)
-                x->x_maxSample = in[i];
-            x->x_sampleCount++;
-            if (x->x_sampleCount >= MG_SAMPLE_COUNT)
-            {
-                sprintf(x->x_string, "~ %g", x->x_maxSample);
-                magicGlass_updateText(x, 0);
-                x->x_maxSample = -999999;
-                x->x_sampleCount = 0;
-            }
-        }
-    }
-    return (w + 4);
-}
-
-void magicGlass_dsp(t_magicGlass *x, t_signal **sp)
-{
-	//fprintf(stderr,"magicglass_dsp\n");
-    dsp_add(magicGlass_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
-	x->x_issignal = 1;
-}
-
-void *magicGlass_new(int c)
-{
-	//fprintf(stderr,"magicglass_new\n");
-    t_magicGlass *x = (t_magicGlass *)pd_new(magicGlass_class);
-    x->x_connectedObj= NULL;
-    x->x_connectedOutno = 0;
-    x->x_visible = 0;
-    x->x_c = c;
-    x->x_sigF = 0;
-    x->x_dspOn = 0;
-    x->x_viewOn = 0;
-    x->x_maxSample = -999999;
-    x->x_sampleCount = 0;
-    x->x_clearClock = clock_new(x, (t_method)magicGlass_clearText);
-    x->x_flashClock = clock_new(x, (t_method)magicGlass_flashText);
-	x->x_maxSize = 1;
-	x->x_issignal = 0;
-	x->x_display_font = 9;
-    return x;
-}
-
-void magicGlass_free(t_magicGlass *x)
-{
-	//fprintf(stderr,"magicglass_free\n");
-    x->x_dspOn = 0;
-    clock_free(x->x_clearClock);
-}
-
-void magicGlass_setup(void)
-{
-    magicGlass_class = class_new(gensym("magicGlass"),
-                                 0,
-                                 (t_method)magicGlass_free,
-                                 sizeof(t_magicGlass),
-                                 0,
-                                 A_DEFFLOAT,
-                                 0);
-    CLASS_MAINSIGNALIN(magicGlass_class, t_magicGlass, x_sigF);
-    class_addmethod(magicGlass_class,
-      	            (t_method)magicGlass_dsp,
-	            gensym("dsp"),
-	            0);
-    class_addbang(magicGlass_class, (t_method)magicGlass_bang);
-    class_addfloat(magicGlass_class, (t_method)magicGlass_float);
-    class_addsymbol(magicGlass_class, (t_method)magicGlass_symbol);
-    class_addanything(magicGlass_class, (t_method)magicGlass_anything);
-    class_addlist(magicGlass_class, (t_method)magicGlass_list);
-}
diff --git a/src/g_magicglass.h.orig b/src/g_magicglass.h.orig
deleted file mode 100644
index b6a80fd2a5f7ba47ac203632b3296ab8c54f0ff1..0000000000000000000000000000000000000000
--- a/src/g_magicglass.h.orig
+++ /dev/null
@@ -1,19 +0,0 @@
-EXTERN void magicGlass_bind(t_magicGlass *x, t_object *obj, int outno);
-EXTERN void magicGlass_unbind(t_magicGlass *x);
-EXTERN void magicGlass_bang(t_magicGlass *x); 
-EXTERN void magicGlass_float(t_magicGlass *x, t_float f); 
-EXTERN void magicGlass_symbol(t_magicGlass *x, t_symbol *sym);
-EXTERN void magicGlass_anything(t_magicGlass *x, t_symbol *sym, int argc, t_atom *argv);
-EXTERN void magicGlass_list(t_magicGlass *x, t_symbol *sym, int argc, t_atom *argv);
-EXTERN void magicGlass_setCanvas(t_magicGlass *x, int c);
-EXTERN void magicGlass_show(t_magicGlass *x);
-EXTERN void magicGlass_hide(t_magicGlass *x);
-EXTERN void magicGlass_moveText(t_magicGlass *x, int pX, int pY);
-EXTERN int magicGlass_bound(t_magicGlass *x);
-EXTERN int magicGlass_isOn(t_magicGlass *x);
-EXTERN void magicGlass_setOn(t_magicGlass *x, int i);
-EXTERN void magicGlass_setDsp(t_magicGlass *x, int i);
-EXTERN void *magicGlass_new(int c);
-EXTERN void magicGlass_free(t_magicGlass *x);
-EXTERN void magicGlass_setup(void);
-
diff --git a/src/g_rtext.c b/src/g_rtext.c
index 163615161198b0abf804b53afa4cdf0227a7b73c..a8efb11d29a87490c21769ce3f2bc1876afc9631 100644
--- a/src/g_rtext.c
+++ b/src/g_rtext.c
@@ -358,8 +358,9 @@ t_rtext *glist_findrtext(t_glist *gl, t_text *who)
     t_rtext *x;
     if (!gl->gl_editor)
         canvas_create_editor(gl);
-    for (x = gl->gl_editor->e_rtext; x && x->x_text != who; x = x->x_next)
-        ;
+	if (gl->gl_editor->e_rtext)
+	    for (x = gl->gl_editor->e_rtext; x && x->x_text != who; x = x->x_next)
+    	    ;
     if (!x) bug("glist_findrtext");
     return (x);
 }
diff --git a/src/g_text.c b/src/g_text.c
index b40af744621302c064b06341bd83fbb91cf0939c..104fa3d1cc25598151d0fb3dbb3e5dea4a669415 100644
--- a/src/g_text.c
+++ b/src/g_text.c
@@ -228,7 +228,7 @@ void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
         if (connectme)
             canvas_connect(gl, indx, 0, nobj, 0);
         else canvas_startmotion(glist_getcanvas(gl));
-		canvas_setundo(gl, canvas_undo_create, canvas_undo_set_create(gl), "create");
+		canvas_setundo(glist_getcanvas(gl), canvas_undo_create, canvas_undo_set_create(gl), "create");
     }
 }
 
@@ -270,7 +270,7 @@ void canvas_iemguis(t_glist *gl, t_symbol *guiobjname)
     //glist_getnextxy(gl, &xpix, &ypix);
     //canvas_objtext(gl, xpix, ypix, 1, b);
     else canvas_startmotion(glist_getcanvas(gl));
-	canvas_setundo(gl, canvas_undo_create, canvas_undo_set_create(gl), "create");
+	canvas_setundo(glist_getcanvas(gl), canvas_undo_create, canvas_undo_set_create(gl), "create");
 }
 
 void canvas_bng(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
@@ -541,7 +541,7 @@ void canvas_msg(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
         if (connectme)
             canvas_connect(gl, indx, 0, nobj, 0);
         else canvas_startmotion(glist_getcanvas(gl));
-		canvas_setundo(gl, canvas_undo_create, canvas_undo_set_create(gl), "create");
+		canvas_setundo(glist_getcanvas(gl), canvas_undo_create, canvas_undo_set_create(gl), "create");
     }
 }
 
@@ -1001,7 +1001,7 @@ void canvas_atom(t_glist *gl, t_atomtype type,
         if (connectme)
             canvas_connect(gl, indx, 0, nobj, 0);
         else canvas_startmotion(glist_getcanvas(gl));
-		canvas_setundo(gl, canvas_undo_create, canvas_undo_set_create(gl), "create");
+		canvas_setundo(glist_getcanvas(gl), canvas_undo_create, canvas_undo_set_create(gl), "create");
     }
 }
 
diff --git a/src/git_commit.sh b/src/git_commit.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6a4b06cd43b3a6eb836c43fbd3f5225bb91483ae
--- /dev/null
+++ b/src/git_commit.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+git add *; git commit -a; git push git@github.com:pd-l2ork/pd.git master
diff --git a/src/m_binbuf.c b/src/m_binbuf.c
index d39e18821e5532bab424439f94fb40f5a98e680c..9c377cbd40a0e507b0cac8870f7b69319a0132e1 100644
--- a/src/m_binbuf.c
+++ b/src/m_binbuf.c
@@ -39,6 +39,7 @@ void binbuf_free(t_binbuf *x)
 {
     t_freebytes(x->b_vec, x->b_n * sizeof(*x->b_vec));
     t_freebytes(x,  sizeof(*x));
+	x = NULL;
 }
 
 t_binbuf *binbuf_duplicate(t_binbuf *y)
@@ -59,6 +60,7 @@ void binbuf_clear(t_binbuf *x)
     /* convert text to a binbuf */
 void binbuf_text(t_binbuf *x, char *text, size_t size)
 {
+	//fprintf(stderr, "current text: %s ||| %c %c %d %d\n", text, text[size-1], text[size], strlen(text), (int)size);
     char buf[MAXPDSTRING+1], *bufp, *ebuf = buf+MAXPDSTRING;
     const char *textp = text, *etext = text+size;
     t_atom *ap;
@@ -385,6 +387,7 @@ void binbuf_addsemi(t_binbuf *x)
     t_atom a;
     SETSEMI(&a);
     binbuf_add(x, 1, &a);
+    binbuf_add(x, 1, '\0');
 }
 
 /* Supply atoms to a binbuf from a message, making the opposite changes
diff --git a/src/m_class.c b/src/m_class.c
index abb9561cce6b0ca8f7e416d0cc8fe83867cc78d6..1dd0c9f9e783cba28ea310760c9cfdcf497790e9 100644
--- a/src/m_class.c
+++ b/src/m_class.c
@@ -708,8 +708,8 @@ void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv)
         return;
     }
     for (i = c->c_nmethod, m = c->c_methods; i--; m++)
-        if (m->me_name == s)
-		//if (m && m->me_name == s)
+        //if (m->me_name == s)
+		if (m && m->me_name == s)
     {
 		//fprintf(stderr,"me_name %s\n", m->me_name);
         wp = m->me_arg;
diff --git a/src/m_obj.c b/src/m_obj.c
index 71166aca4a9b18f90915f76de7939ce75f9f751c..393b159628c0e07ee0be3a3d8d576e7d611d4790 100644
--- a/src/m_obj.c
+++ b/src/m_obj.c
@@ -554,10 +554,11 @@ done:
 
 int obj_noutlets(t_object *x)
 {
-    int n;
+    int n = 0;
     t_outlet *o;
-    for (o = x->ob_outlet, n = 0; o; o = o->o_next) n++;
-    return (n);
+	if (x && x->ob_outlet)
+	    for (o = x->ob_outlet, n = 0; o; o = o->o_next) n++;
+   	return (n);
 }
 
 int obj_ninlets(t_object *x)