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)