From d6a71adae7c90224e2a49f0edcd4fd52fa0a1b30 Mon Sep 17 00:00:00 2001 From: Miller Puckette Date: Fri, 19 Aug 2005 23:28:03 +0000 Subject: Version 0.39-0test5. Bug fixes and more care about closing dirty windows and quitting. svn path=/trunk/; revision=3434 --- pd/src/d_misc.c | 17 ++++++++++- pd/src/d_soundfile.c | 38 ++++++++++++++++++++--- pd/src/d_ugen.c | 13 ++++++-- pd/src/g_array.c | 19 +++++++----- pd/src/g_canvas.c | 2 +- pd/src/g_canvas.h | 6 ++-- pd/src/g_editor.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++------ pd/src/g_template.c | 4 ++- pd/src/g_text.c | 2 +- pd/src/m_glob.c | 4 ++- pd/src/m_imp.h | 2 +- pd/src/m_pd.h | 1 + pd/src/makefile | 2 +- pd/src/notes.txt | 62 +++++++++++++++---------------------- pd/src/s_inter.c | 20 ++++++++---- pd/src/s_main.c | 2 +- pd/src/s_midi_alsa.c | 4 +-- pd/src/t_tkcmd.c | 2 +- pd/src/u_main.tk | 67 +++++++++++++++++++++++++++------------- pd/src/x_list.c | 5 +++ 20 files changed, 256 insertions(+), 102 deletions(-) (limited to 'pd/src') diff --git a/pd/src/d_misc.c b/pd/src/d_misc.c index ea96c5ac..1056f0cb 100644 --- a/pd/src/d_misc.c +++ b/pd/src/d_misc.c @@ -134,11 +134,24 @@ static t_class *samplerate_tilde_class; typedef struct _samplerate { t_object x_obj; + float x_sr; } t_samplerate; static void samplerate_tilde_bang(t_samplerate *x) { - outlet_float(x->x_obj.ob_outlet, sys_getsr()); + if (!canvas_dspstate) + { + post( + "NB: samplerate~ momentarily started DSP to learn sample rate"); + canvas_resume_dsp(1); + canvas_suspend_dsp(); + } + outlet_float(x->x_obj.ob_outlet, x->x_sr); +} + +static void samplerate_tilde_dsp(t_samplerate *x, t_signal **sp) +{ + x->x_sr = sp[0]->s_sr; } static void *samplerate_tilde_new(t_symbol *s) @@ -153,6 +166,8 @@ static void samplerate_tilde_setup(void) samplerate_tilde_class = class_new(gensym("samplerate~"), (t_newmethod)samplerate_tilde_new, 0, sizeof(t_samplerate), 0, 0); class_addbang(samplerate_tilde_class, samplerate_tilde_bang); + class_addmethod(samplerate_tilde_class, (t_method)samplerate_tilde_dsp, + gensym("dsp"), A_CANT, 0); } /* ------------------------ global setup routine ------------------------- */ diff --git a/pd/src/d_soundfile.c b/pd/src/d_soundfile.c index 07e0635b..0ec2c2af 100644 --- a/pd/src/d_soundfile.c +++ b/pd/src/d_soundfile.c @@ -1976,13 +1976,34 @@ static void *writesf_child_main(void *zz) x->x_requestcode = REQUEST_BUSY; x->x_fileerror = 0; - /* if there's already a file open, close it */ + /* if there's already a file open, close it. This + should never happen since writesf_open() calls stop if + needed and then waits until we're idle. */ if (x->x_fd >= 0) { + int bytesperframe = x->x_bytespersample * x->x_sfchannels; + int bigendian = x->x_bigendian; + char *filename = x->x_filename; + int fd = x->x_fd; + int filetype = x->x_filetype; + int itemswritten = x->x_itemswritten; + int swap = x->x_swap; pthread_mutex_unlock(&x->x_mutex); - close (x->x_fd); + + soundfile_finishwrite(x, filename, fd, + filetype, 0x7fffffff, itemswritten, + bytesperframe, swap); + close (fd); + pthread_mutex_lock(&x->x_mutex); x->x_fd = -1; +#ifdef DEBUG_SOUNDFILE + { + char s[1000]; + sprintf(s, "bug??? ditched %d\n", itemswritten); + pute(s); + } +#endif if (x->x_requestcode != REQUEST_BUSY) continue; } @@ -2087,9 +2108,9 @@ static void *writesf_child_main(void *zz) } x->x_itemswritten += sysrtn / (x->x_bytespersample * x->x_sfchannels); - sprintf(boo, "after: head %d, tail %d\n", - x->x_fifohead, x->x_fifotail); #ifdef DEBUG_SOUNDFILE + sprintf(boo, "after: head %d, tail %d written %d\n", + x->x_fifohead, x->x_fifotail, x->x_itemswritten); pute(boo); #endif /* signal parent in case it's waiting for data */ @@ -2263,6 +2284,10 @@ static void writesf_open(t_writesf *x, t_symbol *s, int argc, t_atom *argv) int filetype, bytespersamp, swap, bigendian, normalize; long onset, nframes; float samplerate; + if (x->x_state != STATE_IDLE) + { + writesf_stop(x); + } if (soundfiler_writeargparse(x, &argc, &argv, &filesym, &filetype, &bytespersamp, &swap, &bigendian, &normalize, &onset, &nframes, &samplerate)) @@ -2276,6 +2301,11 @@ static void writesf_open(t_writesf *x, t_symbol *s, int argc, t_atom *argv) if (argc) pd_error(x, "extra argument(s) to writesf~: ignored"); pthread_mutex_lock(&x->x_mutex); + while (x->x_requestcode != REQUEST_NOTHING) + { + sfread_cond_signal(&x->x_requestcondition); + sfread_cond_wait(&x->x_answercondition, &x->x_mutex); + } x->x_bytespersample = bytespersamp; x->x_swap = swap; x->x_bigendian = bigendian; diff --git a/pd/src/d_ugen.c b/pd/src/d_ugen.c index 124631e6..17a4ecc3 100644 --- a/pd/src/d_ugen.c +++ b/pd/src/d_ugen.c @@ -660,7 +660,7 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u) t_siginlet *uin; t_sigoutconnect *oc, *oc2; t_class *class = pd_class(&u->u_obj->ob_pd); - int i, n; + int i, n, totnsig; /* suppress creating new signals for the outputs of signal inlets and subpatchs; except in the case we're an inlet and "blocking" is set. We don't yet know if a subcanvas will be "blocking" so there @@ -695,7 +695,8 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u) s3->s_refcount = 1; } } - insig = (t_signal **)getbytes((u->u_nin + u->u_nout) * sizeof(t_signal *)); + totnsig = u->u_nin + u->u_nout; + insig = (t_signal **)getbytes((totnsig ? totnsig : 1) * sizeof(t_signal *)); outsig = insig + u->u_nin; for (sig = insig, uin = u->u_in, i = u->u_nin; i--; sig++, uin++) { @@ -730,6 +731,11 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u) *sig = uout->o_signal = signal_new(dc->dc_vecsize, dc->dc_srate); (*sig)->s_refcount = uout->o_nconnect; } + /* if thre are no input or output signals, supply one fake signal so + the object can learn the sample rate and block size. Used by the + samplerate~ object. */ + if (!totnsig) + insig[0] = signal_new(dc->dc_vecsize, dc->dc_srate); /* now call the DSP scheduling routine for the ugen. This routine must fill in "borrowed" signal outputs in case it's either a subcanvas or a signal inlet. */ @@ -744,6 +750,9 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u) if (!(*sig)->s_refcount) signal_makereusable(*sig); } + /* special case: no inputs or outputs: free the fake signal we made */ + if (!totnsig) + signal_makereusable(insig[0]); if (ugen_loud) { if (u->u_nin + u->u_nout == 0) post("put %s %d", diff --git a/pd/src/g_array.c b/pd/src/g_array.c index fb11715b..cf577010 100644 --- a/pd/src/g_array.c +++ b/pd/src/g_array.c @@ -429,6 +429,14 @@ void garray_arraydialog(t_garray *x, t_symbol *name, t_floatarg fsize, pd_unbind(&x->x_gobj.g_pd, x->x_realname); x->x_realname = canvas_realizedollar(x->x_glist, argname); pd_bind(&x->x_gobj.g_pd, x->x_realname); + /* redraw the whole glist, just so the name change shows up */ + if (x->x_glist->gl_havewindow) + canvas_redraw(x->x_glist); + else if (glist_isvisible(x->x_glist->gl_owner)) + { + gobj_vis(&x->x_glist->gl_gobj, x->x_glist->gl_owner, 0); + gobj_vis(&x->x_glist->gl_gobj, x->x_glist->gl_owner, 1); + } } size = fsize; if (size < 1) @@ -448,7 +456,7 @@ void garray_arraydialog(t_garray *x, t_symbol *name, t_floatarg fsize, /* jsarlo { */ void garray_arrayviewlist_new(t_garray *x) { - int i, xonset, yonset, type, elemsize; + int i, xonset=0, yonset=0, type=0, elemsize=0; float yval; char cmdbuf[200]; t_symbol *arraytype; @@ -480,7 +488,7 @@ void garray_arrayviewlist_new(t_garray *x) void garray_arrayviewlist_fillpage(t_garray *x, t_float page) { - int i, xonset, yonset, type, elemsize; + int i, xonset=0, yonset=0, type=0, elemsize=0; float yval; char cmdbuf[200]; t_symbol *arraytype; @@ -751,11 +759,8 @@ int array_doclick(t_array *array, t_glist *glist, t_scalar *sc, t_array *ap, &xonset, &yonset, &wonset)) { float best = 100; - int incr; - /* if it has more than 2000 points, just check 300 of them. */ - if (array->a_n < 2000) - incr = 1; - else incr = array->a_n / 300; + /* if it has more than 2000 points, just check 1000 of them. */ + int incr = (array->a_n <= 2000 ? 1 : array->a_n / 1000); for (i = 0; i < array->a_n; i += incr) { float pxpix, pypix, pwpix, dx, dy; diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index adccb788..4019807f 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -36,7 +36,7 @@ struct _canvasenvironment extern t_pd *newest; t_class *canvas_class; -static int canvas_dspstate; /* whether DSP is on or off */ +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 */ diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h index 857df86d..c8fb9979 100644 --- a/pd/src/g_canvas.h +++ b/pd/src/g_canvas.h @@ -583,7 +583,7 @@ EXTERN void template_setsymbol(t_template *x, t_symbol *fieldname, EXTERN t_template *gtemplate_get(t_gtemplate *x); EXTERN t_template *template_findbyname(t_symbol *s); EXTERN t_canvas *template_findcanvas(t_template *tmpl); -EXTERN void template_notify(t_template *, +EXTERN void template_notify(t_template *template, t_symbol *s, int argc, t_atom *argv); EXTERN t_float template_getfloat(t_template *x, t_symbol *fieldname, @@ -594,9 +594,9 @@ EXTERN t_symbol *template_getsymbol(t_template *x, t_symbol *fieldname, t_word *wp, int loud); EXTERN void template_setsymbol(t_template *x, t_symbol *fieldname, t_word *wp, t_symbol *s, int loud); -EXTERN t_float fielddesc_getcoord(t_fielddesc *f, t_template *, +EXTERN t_float fielddesc_getcoord(t_fielddesc *f, t_template *template, t_word *wp, int loud); -EXTERN void fielddesc_setcoord(t_fielddesc *f, t_template *, +EXTERN void fielddesc_setcoord(t_fielddesc *f, t_template *template, t_word *wp, float pix, int loud); EXTERN t_float fielddesc_cvttocoord(t_fielddesc *f, float val); EXTERN float fielddesc_cvtfromcoord(t_fielddesc *f, float coord); diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c index 932a5413..938842a6 100644 --- a/pd/src/g_editor.c +++ b/pd/src/g_editor.c @@ -1043,7 +1043,7 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which, { t_gobj *y; int shiftmod, runmode, altmod, doublemod = 0, rightclick; - int x1, y1, x2, y2, clickreturned = 0; + int x1=0, y1=0, x2=0, y2=0, clickreturned = 0; if (!x->gl_editor) { @@ -1267,9 +1267,9 @@ int canvas_isconnected (t_canvas *x, t_text *ob1, int n1, void canvas_doconnect(t_canvas *x, int xpos, int ypos, int which, int doit) { - int x11, y11, x12, y12; + int x11=0, y11=0, x12=0, y12=0; t_gobj *y1; - int x21, y21, x22, y22; + int x21=0, y21=0, x22=0, y22=0; t_gobj *y2; int xwas = x->gl_editor->e_xwas, ywas = x->gl_editor->e_ywas; @@ -1628,14 +1628,80 @@ void canvas_print(t_canvas *x, t_symbol *s) else sys_vgui(".x%lx.c postscript -file x.ps\n", x); } -void canvas_menuclose(t_canvas *x, t_floatarg force) + /* find a dirty sub-glist, if any, of this one (including itself) */ +static t_glist *glist_finddirty(t_glist *x) { - if (x->gl_owner) - canvas_vis(x, 0); - else if ((force != 0) || (!x->gl_dirty)) + t_gobj *g; + t_glist *g2; + if (x->gl_env && x->gl_dirty) + return (x); + for (g = x->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd) == canvas_class && + (g2 = glist_finddirty((t_glist *)g))) + return (g2); + return (0); +} + + /* quit, after calling glist_finddirty() on all toplevels and verifying + the user really wants to discard changes */ +void glob_verifyquit(void *dummy, t_floatarg f) +{ + t_glist *g, *g2; + /* find all root canvases */ + for (g = canvas_list; g; g = g->gl_next) + if (g2 = glist_finddirty(g)) + { + canvas_vis(g2, 1); + sys_vgui( +"pdtk_check {Discard changes to this window??} {.x%lx menuclose 3;\n} no\n", + g2); + return; + } + if (f == 0) + sys_vgui("pdtk_check {really quit?} {pd quit;\n} yes\n"); + else glob_quit(0); +} + + /* close a window (or possibly quit Pd), checking for dirty flags. + The "force" parameter is interpreted as follows: + 0 - request from GUI to close, verifying whether clean or dirty + 1 - request from GUI to close, no verification + 2 - verified - mark this one clean, then continue as in 1 + 3 - verified - mark this one clean, then verify-and-quit + */ +void canvas_menuclose(t_canvas *x, t_floatarg fforce) +{ + int force = fforce; + t_glist *g; + if (x->gl_owner && (force == 0 || force == 1)) + canvas_vis(x, 0); /* if subpatch, just invis it */ + else if (force == 0) + { + g = glist_finddirty(x); + if (g) + { + canvas_vis(g, 1); + sys_vgui( +"pdtk_check {Discard changes to this window??} {.x%lx menuclose 2;\n} no\n", + g); + return; + } + else pd_free(&x->gl_pd); + } + else if (force == 1) pd_free(&x->gl_pd); - else sys_vgui("pdtk_check {This window has been modified. Close anyway?}\ - {.x%lx menuclose 1;\n}\n", x); + else if (force == 2) + { + canvas_dirty(x, 0); + while (x->gl_owner) + x = x->gl_owner; + canvas_menuclose(x, 0); + } + else if (force == 3) + { + canvas_dirty(x, 0); + glob_verifyquit(0, 1); + } } /* put up a dialog which may call canvas_font back to do the work */ @@ -1674,7 +1740,7 @@ static int canvas_dofind(t_canvas *x, int *myindex1p) canvas_find_index1 = myindex1; canvas_find_index2 = myindex2; glist_noselect(x); - canvas_vis(x, 1); + vmess(&x->gl_pd, gensym("menu-open"), ""); canvas_editmode(x, 1.); glist_select(x, y); return (1); diff --git a/pd/src/g_template.c b/pd/src/g_template.c index 69f1c864..b1046447 100644 --- a/pd/src/g_template.c +++ b/pd/src/g_template.c @@ -1524,7 +1524,9 @@ static void plot_getrect(t_gobj *z, t_glist *glist, xfielddesc, yfielddesc, wfielddesc, &xonset, &yonset, &wonset)) { - for (i = 0, xsum = 0; i < array->a_n; i++) + /* if it has more than 2000 points, just check 1000 of them. */ + int incr = (array->a_n <= 2000 ? 1 : array->a_n / 1000); + for (i = 0, xsum = 0; i < array->a_n; i += incr) { float usexloc, useyloc; t_gobj *y; diff --git a/pd/src/g_text.c b/pd/src/g_text.c index 54b7ac37..ed37ca40 100644 --- a/pd/src/g_text.c +++ b/pd/src/g_text.c @@ -347,10 +347,10 @@ static void message_addsemi(t_message *x) static void message_adddollar(t_message *x, t_floatarg f) { + t_atom a; int n = f; if (n < 0) n = 0; - t_atom a; SETDOLLAR(&a, n); binbuf_add(x->m_text.te_binbuf, 1, &a); glist_retext(x->m_glist, &x->m_text); diff --git a/pd/src/m_glob.c b/pd/src/m_glob.c index bcd9d6f3..aca3bf24 100644 --- a/pd/src/m_glob.c +++ b/pd/src/m_glob.c @@ -12,7 +12,7 @@ static t_class *maxclass; over. Some others are prototyped in m_imp.h as well. */ void glob_setfilename(void *dummy, t_symbol *name, t_symbol *dir); -void glob_quit(void *dummy); +void glob_verifyquit(void *dummy, t_floatarg f); void glob_dsp(void *dummy, t_symbol *s, int argc, t_atom *argv); void glob_meters(void *dummy, t_floatarg f); void glob_key(void *dummy, t_symbol *s, int ac, t_atom *av); @@ -79,6 +79,8 @@ void glob_init(void) class_addmethod(glob_pdobject, (t_method)glob_evalfile, gensym("open"), A_SYMBOL, A_SYMBOL, 0); class_addmethod(glob_pdobject, (t_method)glob_quit, gensym("quit"), 0); + class_addmethod(glob_pdobject, (t_method)glob_verifyquit, + gensym("verifyquit"), A_DEFFLOAT, 0); class_addmethod(glob_pdobject, (t_method)glob_foo, gensym("foo"), A_GIMME, 0); class_addmethod(glob_pdobject, (t_method)glob_dsp, gensym("dsp"), A_GIMME, 0); class_addmethod(glob_pdobject, (t_method)glob_meters, gensym("meters"), diff --git a/pd/src/m_imp.h b/pd/src/m_imp.h index e82d103a..d129bdbe 100644 --- a/pd/src/m_imp.h +++ b/pd/src/m_imp.h @@ -77,6 +77,6 @@ EXTERN int obj_sigoutletindex(t_object *x, int m); /* misc */ EXTERN void glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir); EXTERN void glob_initfromgui(void *dummy, t_symbol *s, int argc, t_atom *argv); - +EXTERN void glob_quit(void *dummy); #define __m_imp_h_ #endif /* __m_imp_h_ */ diff --git a/pd/src/m_pd.h b/pd/src/m_pd.h index 234ee3d7..41e0ffae 100644 --- a/pd/src/m_pd.h +++ b/pd/src/m_pd.h @@ -515,6 +515,7 @@ EXTERN float *cos_table; EXTERN int canvas_suspend_dsp(void); EXTERN void canvas_resume_dsp(int oldstate); EXTERN void canvas_update_dsp(void); +EXTERN int canvas_dspstate; /* up/downsampling */ typedef struct _resample diff --git a/pd/src/makefile b/pd/src/makefile index 9a560285..433bbb6c 100644 --- a/pd/src/makefile +++ b/pd/src/makefile @@ -24,7 +24,7 @@ WARN_CFLAGS = -Wall -W -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch ARCH_CFLAGS = -DPD -CFLAGS = -Werror $(ARCH_CFLAGS) $(WARN_CFLAGS) $(OPT_CFLAGS) $(MORECFLAGS) +CFLAGS = -Werror -Wdeclaration-after-statement $(ARCH_CFLAGS) $(WARN_CFLAGS) $(OPT_CFLAGS) $(MORECFLAGS) # the sources diff --git a/pd/src/notes.txt b/pd/src/notes.txt index dd9e641c..49f5a90c 100644 --- a/pd/src/notes.txt +++ b/pd/src/notes.txt @@ -20,88 +20,77 @@ Mac to tcl/tk 8.4.5; pd extension added automatically bug fix writing aiff gfiles bug fix (tcl error messages when starting open dialogs) pointer rewind (also check if send-window documented?) - - ------------- 0.39 --------- -problems: -"list" to signal inlet (e.g., "*~") complains -"find" doesn't open GOPs correctly +stop vis-ing subpatches of abstractions save dirty abstractions on close close dirty patches on quit -stop vis-ing subpatches of abstractions -when retyping abstractions, offer to save dirty one -don't filter locked click() through getrect -better hit detection (getrect is too greedy; try just sending it through) +"find" fixed to open GOPs correctly +cheat to speed up mouse motion over arrays +fix samplerate~ to figure out blocking thread-unsafe callbacks from sys_microsleep() +writesf -- "open" without "0" misses closing the previous file. + +------------ 0.39 --------- windows: modal dialogs confuse watchdog check the right-click-on-empty-canvas mac: load libraries first before opening patches on drag-and-drop - writing 3-byte soundfiles distorts??? check: MIDI I/O for windows blechman patch for s_inter.c check what happens when going back and forth between graph-on-parent -array_resize etc., should redraw the array directly? Or should "setsize" - and "garray_resize" do it instead? check it's queued correctly. doc: +object list document env~ second argument (and why is it no less than 1/10 of first???) vibrato example block resampling arguments document tabwrite~_start +"list" to signal inlet (e.g., "*~") or float inlet (f) complains. problems: +don't filter locked click() through getrect +better scalar hit detection (getrect is too greedy) +when retyping abstractions, offer to save dirty one +should linux stop grabbing focus on vis? Is there a way to detect whether + the mouse is in a window when it opens? TK commands to nonexistent windows? (occasionally still happens) -array name changes don't show up on parent arrays that don't fit in bounds don't update (same as red rectangle problem?) look in d_resample.pd to understand inlet~ upsampling... -flag for array to suppress printing name -fix samplerate~ to figure out blocking patcher inlets don't deal with scalars (zbug.pd) check if there's a problem loading libs on startup if superuser -tk errors for large tables? -wierdly small hotspot on lines '[' in numbox label breaks it (Yury Sept. 3) -soundfiles with 3-byte samples buzz for the first readsf buffer (bug/x.pd) read xx.txt in "bad" gives warnings -writesf -- "open" without "0" misses closing the previous file. -Also writesf~ acts differently if DSP is off when "open" is sent? qlist - 'next 1' seems not to work Krzysztof's qlist_next reentrancy bug don't draw in/outlets on gui objects in graph-on-parent reasonable font size default for GUIs moving a bang toward top of window creates problem (invisible label) get rid of messages causing renaming; try to prevent patches closing themselves. -dac~/ adc~/ block~ incompatibility scofo reports error on reading score1.txt loading e-mailed patches without removing headers crashes pd pd $1 bug ($1 is saved as it was evaluated, not as '$1') check if _vsnprintf with zero argument in windows works any better... +detect adc~ and dac~ reblocking features: flag to suppress printing array name above graph +flag to suppress scrollbars in canvases fix copyright notices -IEM guis to use queued updates pixel font sizes pd to find running ones (pd -new to defeat) rename windowname-pd instead of pd-windowname -"enter" into object box to create new one (also, changing borders? forking?) -tab to jump to a connected object (first one?) (shift-tab to back up?) tables: if there's just one array, don't do stringent hit check. array click protection (Krzysztof's suggestion) make graph labels persistent and add to dialog object to get/set table size; random; quantile flag to hide array names -queued graphics updates for IEMGUIs and scalars think of a way to embed abstractions in a patch make watchdog work for MACOSX search path to include both calling patch and abstraction, if different -abstraction reload shouldn't have to vis everyone pasting should look at current mouse location delete-in-rectangle message to Pds put serial object in main dist (see rat@telecoma, Apr. 25; winfried May 22) @@ -109,6 +98,14 @@ open/save panel to take messages to init directory, and to set extent list flags to defeat pre-loading specified classes expr to parse exponential notation pipe to handle symbols&pointers (just takes floats now???) +editing: + "enter" into object box to create new one (also, change border? forking?) + tab to jump to a connected object (first one?) (shift-tab to back up?) + arrow keys to shift connections left and right + menu item to connect selected objects + highlight connections (and I/Os) on mouse motion + select line and hit "insert" to interpolate an object + option-drag an outlet to make a new, connected object data: data copy/paste doesn't check templates aren't changed @@ -146,31 +143,20 @@ look at prctl(2) for FP exception handling ??? have a way to disambiguate externs from different libs??? netsend separate thread netreceive (and netsend?) message to set port number -think about x and y scale preservation when changing between graph and object -show outlines of objects even when graph is "open" graph_vis() to decorate graphs when they're toplevel (parent_glist == 0) -get graphs to expand to hold their contents suita.chopin.edu.pl/~czaja/miXed/externs/xeq.html -- MIDI file reader in glist_delete, consider why this can't be just "vis 0" -- why do we need it? closebang check that -blocksize really reflects in audiobuf calc for Hammerfall makefile to have make install depend on make local. Float method for random -figure out list, message objects put in something for tilde order forcing extensible "toolbar" so people can add external GUI objects -allow spaces in paths variable send and receive -- check how max/MSP does it? number boxes to darken for typing and/or received messages -dialog to change lib flag and path pique~ and fiddle~ unification (notice pique filtering is different!) new message box look figure out what to do when "pd sym" conflicts with window title as in Pluton? - -MAX compatibilty: -trigger 1 (on Pd, outputs 0; on Max?) - -LATER bonk~ file path handling unify arrays and garrays dialog to give values of $1, ... for the canvas diff --git a/pd/src/s_inter.c b/pd/src/s_inter.c index f77b5e84..814e2834 100644 --- a/pd/src/s_inter.c +++ b/pd/src/s_inter.c @@ -174,7 +174,13 @@ static int sys_domicrosleep(int microsec, int pollem) for (i = 0; i < sys_nfdpoll; i++) if (FD_ISSET(sys_fdpoll[i].fdp_fd, &readset)) { +#ifdef THREAD_LOCKING + sys_lock(); +#endif (*sys_fdpoll[i].fdp_fn)(sys_fdpoll[i].fdp_ptr, sys_fdpoll[i].fdp_fd); +#ifdef THREAD_LOCKING + sys_unlock(); +#endif didsomething = 1; } return (didsomething); @@ -280,10 +286,12 @@ void sys_set_priority(int higher) #ifdef _POSIX_MEMLOCK /* tb: force memlock to physical memory { */ - struct rlimit mlock_limit; - mlock_limit.rlim_cur=0; - mlock_limit.rlim_max=0; - setrlimit(RLIMIT_MEMLOCK,&mlock_limit); + { + struct rlimit mlock_limit; + mlock_limit.rlim_cur=0; + mlock_limit.rlim_max=0; + setrlimit(RLIMIT_MEMLOCK,&mlock_limit); + } /* } tb */ if (mlockall(MCL_FUTURE) != -1) fprintf(stderr, "memory locking enabled.\n"); @@ -1087,7 +1095,7 @@ int sys_startgui(const char *guidir) sys_guicmd = cmdbuf; } if (sys_verbose) fprintf(stderr, "%s", sys_guicmd); - execl("/bin/sh", "sh", "-c", sys_guicmd, 0); + execl("/bin/sh", "sh", "-c", sys_guicmd, (char*)0); perror("pd: exec"); _exit(1); } @@ -1171,7 +1179,7 @@ int sys_startgui(const char *guidir) sprintf(cmdbuf, "%s/pd-watchdog\n", guidir); if (sys_verbose) fprintf(stderr, "%s", cmdbuf); - execl("/bin/sh", "sh", "-c", cmdbuf, 0); + execl("/bin/sh", "sh", "-c", cmdbuf, (char*)0); perror("pd: exec"); _exit(1); } diff --git a/pd/src/s_main.c b/pd/src/s_main.c index 098ca115..79e5e153 100644 --- a/pd/src/s_main.c +++ b/pd/src/s_main.c @@ -2,7 +2,7 @@ * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ -char pd_version[] = "Pd version 0.39 TEST 4c\n"; +char pd_version[] = "Pd version 0.39 TEST 5\n"; char pd_compiletime[] = __TIME__; char pd_compiledate[] = __DATE__; diff --git a/pd/src/s_midi_alsa.c b/pd/src/s_midi_alsa.c index 6e9143b3..1d19c111 100644 --- a/pd/src/s_midi_alsa.c +++ b/pd/src/s_midi_alsa.c @@ -46,6 +46,7 @@ void sys_alsa_do_open_midi(int nmidiin, int *midiinvec, int err = 0; int client; int i; + snd_seq_client_info_t *alsainfo; alsa_nmidiin = 0; alsa_nmidiout = 0; if(nmidiin>MAXMIDIINDEV ) @@ -91,7 +92,6 @@ void sys_alsa_do_open_midi(int nmidiin, int *midiinvec, } if (nmidiout == 0 && nmidiin == 0) return; - snd_seq_client_info_t *alsainfo; snd_seq_client_info_malloc(&alsainfo); snd_seq_get_client_info(midi_handle,alsainfo); snd_seq_client_info_set_name(alsainfo,"Pure Data"); @@ -184,7 +184,7 @@ void sys_alsa_putmidibyte(int portno, int byte) /* this version uses the asynchronous "read()" ... */ void sys_alsa_poll_midi(void) { - char buf[20]; + unsigned char buf[20]; int count, alsa_source; int i; snd_seq_event_t *midievent = NULL; diff --git a/pd/src/t_tkcmd.c b/pd/src/t_tkcmd.c index 31c39b52..def4a328 100644 --- a/pd/src/t_tkcmd.c +++ b/pd/src/t_tkcmd.c @@ -432,7 +432,7 @@ static void pd_startfromgui( void) fprintf(debugfd, "%s", cmdbuf); fflush(debugfd); #endif - execl("/bin/sh", "sh", "-c", cmdbuf, 0); + execl("/bin/sh", "sh", "-c", cmdbuf, (char*)0); perror("pd: exec"); _exit(1); } diff --git a/pd/src/u_main.tk b/pd/src/u_main.tk index 26545f98..f0403967 100644 --- a/pd/src/u_main.tk +++ b/pd/src/u_main.tk @@ -42,8 +42,8 @@ if {$pd_nt == 1} { } if {$pd_nt == 2} { -# turn on James Tittle II's fast drawing (wait until I can test this...): -# set tk::mac::useCGDrawing 1 +# turn on James Tittle II's fast drawing + set tk::mac::useCGDrawing 1 # set minimum line size for anti-aliasing. If set to 1 or 0, then every # line will be anti-aliased. While this makes connections and circles in # [bng] and such look really good, it makes boxes and messages look out of @@ -56,18 +56,26 @@ if {$pd_nt == 2} { set pd_guidir $pd_gui2/.. load $pd_guidir/bin/libPdTcl.dylib set pd_tearoff 0 - - # tk::mac::OpenDocument is called with the filenames put into the - # var args whenever docs are either dropped on the Pd.app icon or - # opened from the Finder. - # It uses menu_doc_open so it can handles numerous file types. - proc tk::mac::OpenDocument {args} { - foreach file $args { - pd [concat pd open [pdtk_enquote [file tail $file]] \ - [pdtk_enquote [file dirname $file]] \;] - menu_doc_open [file dirname $file] [file tail $file] - } - } + global pd_macready + set pd_macready 0 + global pd_macdropped + set pd_macdropped "" + # tk::mac::OpenDocument is called with the filenames put into the + # var args whenever docs are either dropped on the Pd.app icon or + # opened from the Finder. + # It uses menu_doc_open so it can handles numerous file types. + proc tk::mac::OpenDocument {args} { + global pd_macready pd_macdropped + foreach file $args { + if {$pd_macready != 0} { + pd [concat pd open [pdtk_enquote [file tail $file]] \ + [pdtk_enquote [file dirname $file]] \;] + menu_doc_open [file dirname $file] [file tail $file] + } else { + set pd_macdropped $args + } + } + } } # hack so you can easily test-run this script in linux... define pd_guidir @@ -233,11 +241,11 @@ proc pdtk_ping {} { pd [concat pd ping \;] } -proc pdtk_check {x message} { - set answer [tk_messageBox \-message $x \-type yesno \-icon question] - switch $answer { - yes {pd $message} } -# no {tk_messageBox \-message "cancelled" \-type ok} +##### routine to ask user if OK and, if so, send a message on to Pd ###### +proc pdtk_check {x message default} { + set answer [tk_messageBox \-message $x \-type yesno -default $default \ + \-icon question] + if {$answer == yes} {pd $message} } set menu_windowlist {} @@ -327,7 +335,7 @@ proc menu_send {} { ################## the "Quit" menu command ######################### proc menu_really_quit {} {pd {pd quit;}} -proc menu_quit {} {pdtk_check {Really quit?} {pd quit;}} +proc menu_quit {} {pd {pd verifyquit;}} ######### the "Pd" menu command, which puts the Pd window on top ######## proc menu_pop_pd {} {raise .} @@ -569,7 +577,12 @@ proc menu_print {name} { proc menu_close {name} { pdtk_canvas_checkgeometry $name - pd [concat $name menuclose \;] + pd [concat $name menuclose 0 \;] +} + +proc menu_really_close {name} { + pdtk_canvas_checkgeometry $name + pd [concat $name menuclose 1 \;] } proc menu_undo {name} { @@ -1553,6 +1566,7 @@ proc pdtk_canvas_ctrlkey {name key shift} { if {$key == "period"} {menu_audio 0} if {$shift == 1} { if {$key == "q" || $key == "Q"} {menu_really_quit} + if {$key == "w" || $key == "W"} {menu_really_close $topname} if {$key == "s" || $key == "S"} {menu_saveas $topname} if {$key == "z" || $key == "Z"} {menu_redo $topname} if {$key == "b" || $key == "B"} {menu_bng $topname 1} @@ -3266,6 +3280,16 @@ proc pdtk_pd_startup {version apilist midiapilist fontname} { # so that we'd know the value of "apilist". menu_addstd .mbar + global pd_nt + if {$pd_nt == 2} { + global pd_macdropped pd_macready + set pd_macready 1 + foreach file $pd_macdropped { + pd [concat pd open [pdtk_enquote [file tail $file]] \ + [pdtk_enquote [file dirname $file]] \;] + menu_doc_open [file dirname $file] [file tail $file] + } + } } ##################### DSP ON/OFF, METERS, DIO ERROR ################### @@ -4186,3 +4210,4 @@ proc pdtk_startup_dialog {id nort flags} { focus $id.f0 } + diff --git a/pd/src/x_list.c b/pd/src/x_list.c index a08fe193..16de0286 100644 --- a/pd/src/x_list.c +++ b/pd/src/x_list.c @@ -4,7 +4,12 @@ #include "m_pd.h" /* #include */ +#ifdef MSW +#include +#else #include +#endif + extern t_pd *newest; #define HAVE_ALLOCA 1 /* LATER this should be set by configure script! */ -- cgit v1.2.1