Skip to content
Snippets Groups Projects
Commit cb9dd051 authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

Merge branch 'fix-unique-flag-revised'

parents aaf525e0 a147dfbb
No related branches found
No related tags found
No related merge requests found
## Makefile.am -- Process this file with automake to produce Makefile.in #########################################
##### Defaults & Paths #####
NAME=pd~ NAME=pd~
PATCHES = pd~-help.pd pd~-subprocess.pd external_LTLIBRARIES = pd~.la pdsched.la
PATCHES = pd~-help.pd pd~-subprocess.pd
OTHERDATA = OTHERDATA =
pd__la_SOURCES = pd~.c pd__la_SOURCES = pd~.c
pdsched_la_SOURCES = pdsched.c pdsched_la_SOURCES = pdsched.c
external_LTLIBRARIES = pd~.la pdsched.la EXTRA_DIST = makefile notes.txt binarymsg.c
dist_external_DATA = $(PATCHES) $(OTHERDATA)
#########################################
##### Files, Binaries, & Libs #####
# you shouldn't need to add anything below here
dist_external_DATA = $(PATCHES) $(OTHERDATA)
AUTOMAKE_OPTIONS = foreign AUTOMAKE_OPTIONS = foreign
AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @EXTERNAL_CFLAGS@
AM_CFLAGS = @ARCH_CFLAGS@ AM_CPPFLAGS += -I$(top_srcdir)/src -DPD
AM_LIBS = $(LIBM) AM_LIBS = $(LIBM)
AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src AM_LDFLAGS = -module -avoid-version -shared @EXTERNAL_LDFLAGS@ \
-shrext .@EXTERNAL_EXTENSION@ -L$(top_builddir)/src
externaldir = $(pkglibdir)/extra/$(NAME) externaldir = $(pkglibdir)/extra/$(NAME)
#########################################
if MINGW ##### Targets #####
AM_LIBS += -lpd
endif
libtool: $(LIBTOOL_DEPS) libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck $(SHELL) ./config.status --recheck
# create convenience link for running locally
all-local:
rm -f *.@EXTERNAL_EXTENSION@
-$(LN_S) $(wildcard .libs/*.@EXTERNAL_EXTENSION@) ./
clean-local:
rm -f *.@EXTERNAL_EXTENSION@
#include <stdio.h>
#include "m_pd.h"
static void pd_tilde_putfloat(float f, FILE *fd)
{
putc(A_FLOAT, fd);
fwrite(&f, sizeof(f), 1, fd);
}
static void pd_tilde_putsymbol(t_symbol *s, FILE *fd)
{
char *sp = s->s_name;
putc(A_SYMBOL, fd);
do
putc(*sp, fd);
while (*sp++);
}
static int pd_tilde_getatom(t_atom *ap, FILE *fd)
{
char buf[MAXPDSTRING];
while (1)
{
int type = getc(fd), fill;
float f;
switch (type)
{
case EOF:
return (0);
case A_SEMI:
SETSEMI(ap);
return (1);
case A_FLOAT:
if (fread(&f, sizeof(f), 1, fd) >= 1)
{
SETFLOAT(ap, f);
return (1);
}
else return (0);
case A_SYMBOL:
for (fill = 0; fill < MAXPDSTRING; fill++)
{
int c = getc(fd);
if (c == EOF)
return (0);
else buf[fill] = c;
if (!c)
{
SETSYMBOL(ap, gensym(buf));
return (1);
}
}
return (0);
}
}
}
...@@ -4,6 +4,7 @@ CSYM=pd_tilde ...@@ -4,6 +4,7 @@ CSYM=pd_tilde
include ../makefile.subdir include ../makefile.subdir
pd_linux: pdsched.pd_linux pd_linux: pdsched.pd_linux
pd_nt: pdsched.dll
d_fat: pdsched.d_fat d_fat: pdsched.d_fat
d_ppc: pdsched.d_ppc d_ppc: pdsched.d_ppc
...@@ -12,3 +13,8 @@ pdsched.pd_linux: pdsched.c ...@@ -12,3 +13,8 @@ pdsched.pd_linux: pdsched.c
$(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
$(CC) -shared -o $*.pd_linux $*.o -lc -lm $(CC) -shared -o $*.pd_linux $*.o -lc -lm
rm -f $*.o rm -f $*.o
pdsched.dll: pdsched.c
$(MSCC) $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
$(MSLN) /nologo /dll /export:pd_extern_sched $*.obj $(PDNTLIB)
rm -f $*.obj
...@@ -12,19 +12,25 @@ outputs audio and messages. */ ...@@ -12,19 +12,25 @@ outputs audio and messages. */
*/ */
#include "m_pd.h" #include "m_pd.h"
#include "s_stuff.h" #include "s_stuff.h"
#include "m_imp.h"
#include <stdio.h> #include <stdio.h>
#ifdef _WIN32
#include <io.h>
#include <fcntl.h>
#endif
#define BUFSIZE 65536 #include "binarymsg.c"
static char inbuf[BUFSIZE];
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__) #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\
|| defined(__GNU__)
void glob_watchdog(t_pd *dummy); void glob_watchdog(t_pd *dummy);
static void pollwatchdog( void) static void pollwatchdog( void)
{ {
static int sched_diddsp, sched_nextpingtime; static int sched_diddsp, sched_nextpingtime;
sched_diddsp++; sched_diddsp++;
if (sys_nogui && sys_hipriority && (sched_diddsp - sched_nextpingtime > 0)) if (sys_nogui && sys_hipriority &&
(sched_diddsp - sched_nextpingtime > 0))
{ {
glob_watchdog(0); glob_watchdog(0);
/* ping every 2 seconds */ /* ping every 2 seconds */
...@@ -34,11 +40,53 @@ static void pollwatchdog( void) ...@@ -34,11 +40,53 @@ static void pollwatchdog( void)
} }
#endif #endif
static t_class *pd_ambinary_class;
#define BUFSIZE 65536
static char *ascii_inbuf;
static int readasciimessage(t_binbuf *b)
{
int fill = 0, c;
binbuf_clear(b);
while ((c = getchar()) != EOF)
{
if (c == ';')
{
binbuf_text(b, ascii_inbuf, fill);
return (1);
}
else if (fill < BUFSIZE)
ascii_inbuf[fill++] = c;
else if (fill == BUFSIZE)
fprintf(stderr, "pd-extern: input buffer overflow\n");
}
return (0);
}
static int readbinmessage(t_binbuf *b)
{
binbuf_clear(b);
while (1)
{
t_atom at;
if (!pd_tilde_getatom(&at, stdin))
{
fprintf(stderr, "pd-extern: EOF on input\n");
return (0);
}
else if (at.a_type == A_SEMI)
return (1);
else binbuf_add(b, 1, &at);
}
}
int pd_extern_sched(char *flags) int pd_extern_sched(char *flags)
{ {
int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
int i, j, rate, advance, callback, chin, chout, fill = 0, c, blocksize; int i, j, rate, advance, callback, chin, chout, fill = 0, c, blocksize,
useascii = 0;
t_binbuf *b = binbuf_new(); t_binbuf *b = binbuf_new();
sys_get_audio_params(&naudioindev, audioindev, chindev, sys_get_audio_params(&naudioindev, audioindev, chindev,
...@@ -47,60 +95,76 @@ int pd_extern_sched(char *flags) ...@@ -47,60 +95,76 @@ int pd_extern_sched(char *flags)
chin = (naudioindev < 1 ? 0 : chindev[0]); chin = (naudioindev < 1 ? 0 : chindev[0]);
chout = (naudiooutdev < 1 ? 0 : choutdev[0]); chout = (naudiooutdev < 1 ? 0 : choutdev[0]);
if (!flags || flags[0] != 'a')
fprintf(stderr, "Pd plug-in scheduler called, chans %d %d, sr %d\n", {
chin, chout, (int)rate); /* signal to stdout object to do binary by attaching an object
to an obscure symbol name */
pd_ambinary_class = class_new(gensym("pd~"), 0, 0, sizeof(t_pd),
CLASS_PD, 0);
pd_bind(&pd_ambinary_class, gensym("#pd_binary_stdio"));
/* On Windows, set stdin and out to "binary" mode */
#ifdef _WIN32
setmode(fileno(stdout),O_BINARY);
setmode(fileno(stdin),O_BINARY);
#endif
}
else
{
if (!(ascii_inbuf = getbytes(BUFSIZE)))
return (1);
useascii = 1;
}
/* fprintf(stderr, "Pd plug-in scheduler called, chans %d %d, sr %d\n",
chin, chout, (int)rate); */
sys_setchsr(chin, chout, rate); sys_setchsr(chin, chout, rate);
sys_audioapi = API_NONE; sys_audioapi = API_NONE;
while ((c = getchar()) != EOF) while (useascii ? readasciimessage(b) : readbinmessage(b) )
{ {
if (c == ';') t_atom *ap = binbuf_getvec(b);
int n = binbuf_getnatom(b);
if (n > 0 && ap[0].a_type == A_FLOAT)
{ {
int n; /* a list -- take it as incoming signals. */
t_atom *ap; int chan, nchan = n/DEFDACBLKSIZE;
binbuf_text(b, inbuf, fill); t_sample *fp;
n = binbuf_getnatom(b); for (i = chan = 0, fp = sys_soundin; chan < nchan; chan++)
ap = binbuf_getvec(b); for (j = 0; j < DEFDACBLKSIZE; j++)
fill = 0; *fp++ = atom_getfloat(ap++);
if (n > 0 && ap[0].a_type == A_FLOAT) for (; chan < chin; chan++)
{ for (j = 0; j < DEFDACBLKSIZE; j++)
/* a list -- take it as incoming signals. */ *fp++ = 0;
int chan, nchan = n/DEFDACBLKSIZE; sched_tick();
t_sample *fp; sys_pollgui();
for (i = chan = 0, fp = sys_soundin; chan < nchan; chan++) #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\
for (j = 0; j < DEFDACBLKSIZE; j++) || defined(__GNU__)
*fp++ = atom_getfloat(ap++); pollwatchdog();
for (; chan < chin; chan++)
for (j = 0; j < DEFDACBLKSIZE; j++)
*fp++ = 0;
sched_tick();
sys_pollgui();
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
pollwatchdog();
#endif #endif
if (useascii)
printf(";\n"); printf(";\n");
for (i = chout*DEFDACBLKSIZE, fp = sys_soundout; i--; fp++) else putchar(A_SEMI);
{ for (i = chout*DEFDACBLKSIZE, fp = sys_soundout; i--;
printf("%g\n", *fp); fp++)
*fp = 0;
}
printf(";\n");
fflush(stdout);
}
else if (n > 1 && ap[0].a_type == A_SYMBOL)
{ {
t_pd *whom = ap[0].a_w.w_symbol->s_thing; if (useascii)
if (!whom) printf("%g\n", *fp);
error("%s: no such object", ap[0].a_w.w_symbol->s_name); else pd_tilde_putfloat(*fp, stdout);
else if (ap[1].a_type == A_SYMBOL) *fp = 0;
typedmess(whom, ap[1].a_w.w_symbol, n-2, ap+2);
else pd_list(whom, 0, n-1, ap+1);
} }
if (useascii)
printf(";\n");
else putchar(A_SEMI);
fflush(stdout);
}
else if (n > 1 && ap[0].a_type == A_SYMBOL)
{
t_pd *whom = ap[0].a_w.w_symbol->s_thing;
if (!whom)
error("%s: no such object", ap[0].a_w.w_symbol->s_name);
else if (ap[1].a_type == A_SYMBOL)
typedmess(whom, ap[1].a_w.w_symbol, n-2, ap+2);
else pd_list(whom, 0, n-1, ap+1);
} }
else if (fill < BUFSIZE)
inbuf[fill++] = c;
else if (fill == BUFSIZE)
fprintf(stderr, "pd-extern: input buffer overflow\n");
} }
binbuf_free(b);
return (0); return (0);
} }
#N canvas 12 0 566 872 12; #N canvas 113 52 638 844 12;
#X msg 31 406 foo bar baz; #X msg 31 406 foo bar baz;
#X obj 189 466 osc~ 440; #X obj 189 466 osc~ 440;
#X obj 127 645 env~ 8192; #X obj 114 614 env~ 8192;
#X floatatom 127 694 5 0 0 0 - - -; #X floatatom 114 663 5 0 0 0 - - -, f 5;
#X msg 434 807 \; pd dsp 1; #X msg 535 750 \; pd dsp 1;
#X msg 24 332 pd~ stop; #X msg 24 332 pd~ stop;
#X obj 127 670 i; #X obj 114 639 i;
#X obj 241 643 env~ 8192; #X obj 228 612 env~ 8192;
#X floatatom 241 693 5 0 0 0 - - -; #X floatatom 228 662 5 0 0 0 - - -, f 5;
#X obj 241 669 i; #X obj 228 638 i;
#X obj 123 489 *~; #X obj 123 489 *~;
#X obj 158 490 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 #X obj 158 490 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1; 1;
#X obj 189 490 *~; #X obj 189 490 *~;
#X obj 224 491 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 #X obj 224 491 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1; 1;
#X obj 434 781 loadbang; #X obj 535 724 loadbang;
#X obj 14 691 print x; #X obj 12 643 print x;
#X msg 15 309 pd~ start pd~-subprocess.pd; #X msg 15 309 pd~ start pd~-subprocess.pd;
#X obj 14 532 pd~ -ninsig 2 -noutsig 2 -fifo 20; #X obj 14 532 pd~ -ninsig 2 -noutsig 2 -fifo 20;
#X obj 37 20 pd~; #X obj 37 20 pd~;
#X text 69 22 - run a pd sub-process; #X text 69 22 - run a pd sub-process;
#X text 27 57 The pd~ object starts and manages a Pd sub-process that #X text 27 52 The pd~ object starts and manages a Pd sub-process that
can communicate with the super-process (this one) via audio channels can communicate with the super-process (this one) via audio channels
and/or Pd messages. In this way you can take advantage of multi-core and/or Pd messages. In this way you can take advantage of multi-core
CPUs \, and/or use Pd features from within Max (if you're using the CPUs \, and/or use Pd features from within Max (if you're using the
Max version of pd~).; Max version of pd~).;
#X text 24 251 Sending a new "start" message will stop the sub-process #X text 24 246 Sending a new "start" message will stop the sub-process
and start a new one. If you just want to stop the sub-process \, send and start a new one. If you just want to stop the sub-process \, send
"stop".; "stop".;
#X text 33 353 Any message besides "pd~" is sent to the sub-process. #X text 33 353 Any message besides "pd~" is sent to the sub-process.
...@@ -34,23 +34,23 @@ For instance \, the message below sends "bar baz" to any object in ...@@ -34,23 +34,23 @@ For instance \, the message below sends "bar baz" to any object in
the sub-process named "foo" \, such as a "receive" object.; the sub-process named "foo" \, such as a "receive" object.;
#X text 43 430 Audio signals appear in adc~ objects in the sub-process. #X text 43 430 Audio signals appear in adc~ objects in the sub-process.
The sub-process doesn't open real audio devices.; The sub-process doesn't open real audio devices.;
#X text 281 473 Creation args:; #X text 302 469 Creation args:;
#X text 265 490 -insig <n> sets input audio channels; #X text 286 486 -insig <n> sets input audio channels;
#X text 266 508 -outsig <n> sets output channels; #X text 287 504 -outsig <n> sets output channels;
#X text 269 542 -fifo <n> sets round-trip delay in blocks; #X text 290 538 -fifo <n> sets round-trip delay in blocks;
#X text 272 559 -pddir <s> sets Pd directory \, e.g. \,; #X text 293 555 -pddir <s> sets Pd directory \, e.g. \,;
#X text 299 574 .../Pd-0.42.app/Contents/Resources; #X text 320 570 .../Pd-0.42.app/Contents/Resources;
#X text 272 590 -scheddir <s> sets scheduler dir \, e.g. \,; #X text 293 586 -scheddir <s> sets scheduler dir \, e.g. \,;
#X text 297 607 .../.../Resources/extra/pd~; #X text 318 603 .../.../Resources/extra/pd~;
#X text 267 524 -sr <n> sets sample rate; #X text 288 520 -sr <n> sets sample rate;
#X text 20 716 The first outlet reports messages the sub-process sends #X text 28 699 The first outlet reports messages the sub-process sends
us via "stdout" objects. Any other outlets are signals corresponding us via "stdout" objects. Any other outlets are signals corresponding
to "dac~" objects in the sub-process.; to "dac~" objects in the sub-process.;
#X text 10 784 ATTENTION: DSP must be running in this process for the #X text 21 756 ATTENTION: DSP must be running in this process for the
sub-process to run. This is because its clock is slaved to audio I/O sub-process to run. This is because its clock is slaved to audio I/O
it gets from us!; it gets from us!;
#X text 359 849 Updated for Pd version 0.42.; #X text 393 802 Updated for Pd version 0.42.;
#X text 24 138 Messages with "pd~" selector control the sub-process. #X text 24 132 Messages with "pd~" selector control the sub-process.
"pd~ start" takes as arguments any startup arguments you wish to send "pd~ start" takes as arguments any startup arguments you wish to send
the sub-process. For example \, specify "-nogui" to stop the sub-process's the sub-process. For example \, specify "-nogui" to stop the sub-process's
GUI from appearing. You don't have to specify the number of channels GUI from appearing. You don't have to specify the number of channels
......
#N canvas 577 21 563 559 12; #N canvas 600 66 646 598 12;
#X obj 202 395 r foo; #X obj 202 395 r foo;
#X obj 202 423 print foo; #X obj 202 423 print foo;
#X obj 87 174 adc~; #X obj 87 174 adc~;
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
#X msg 72 364 a b c; #X msg 72 364 a b c;
#X msg 455 441 \; pd dsp 1; #X msg 455 441 \; pd dsp 1;
#X obj 87 201 env~ 8192; #X obj 87 201 env~ 8192;
#X floatatom 87 250 5 0 0 0 - - -; #X floatatom 87 250 5 0 0 0 - - -, f 5;
#X obj 87 226 i; #X obj 87 226 i;
#X obj 263 253 dac~; #X obj 263 253 dac~;
#X obj 262 185 osc~ 440; #X obj 262 185 osc~ 440;
#X obj 262 219 *~; #X obj 262 219 *~;
#X obj 297 220 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 #X obj 297 220 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
1; 1;
#X obj 332 186 osc~ 440; #X obj 332 186 osc~ 440;
#X obj 332 220 *~; #X obj 332 220 *~;
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#X msg 86 411 bang; #X msg 86 411 bang;
#X obj 455 417 loadbang; #X obj 455 417 loadbang;
#X obj 160 201 env~ 8192; #X obj 160 201 env~ 8192;
#X floatatom 160 250 5 0 0 0 - - -; #X floatatom 160 250 5 0 0 0 - - -, f 5;
#X obj 160 226 i; #X obj 160 226 i;
#X msg 86 388 4; #X msg 86 388 4;
#X text 62 8 This is a test patch to demonstrate the Pd~ object. It's #X text 62 8 This is a test patch to demonstrate the Pd~ object. It's
...@@ -29,7 +29,7 @@ is a separate instance of Pd) can be called from a Max or Pd super-process. ...@@ -29,7 +29,7 @@ is a separate instance of Pd) can be called from a Max or Pd super-process.
; ;
#X text 63 73 Audio inlets and outlets on the Pd~ object (in the super-process) #X text 63 73 Audio inlets and outlets on the Pd~ object (in the super-process)
talk to adc~ and dac~ objects here - so \, for instance \, the first talk to adc~ and dac~ objects here - so \, for instance \, the first
adc~ here is the first inlet of the pd~ object \, and the first chanel adc~ here is the first inlet of the pd~ object \, and the first channel
of dac~ goes to the second outlet of pd~ (because the first one is of dac~ goes to the second outlet of pd~ (because the first one is
for messages \, as shown further below.); for messages \, as shown further below.);
#X text 58 283 Any message sent to a stdout object in this sub-process #X text 58 283 Any message sent to a stdout object in this sub-process
......
This diff is collapsed.
...@@ -31,14 +31,19 @@ function have_args() { ...@@ -31,14 +31,19 @@ function have_args() {
} }
function set_vars(win) { function set_vars(win) {
var port_no, font_engine_sanity, pd_engine_id; var port_no, font_engine_sanity, pd_engine_id, argv_offset;
// If the GUI was started by Pd, our port number is going to be // If the GUI was started by Pd, our port number is going to be
// the first argument. If the GUI is supposed to start Pd, we won't // the first argument. If the GUI is supposed to start Pd, we won't
// have any arguments and need to set it here. // have any arguments and need to set it here.
if (have_args() && gui.App.argv.length > 1) { if (have_args() && gui.App.argv.length > 1) {
port_no = gui.App.argv[0]; // fed to us by the Pd process // Unfortunately there's a bug in nw.js where the argument that
// specifies the package.json path doesn't get included in the
// argv array. This happens under Windows and Linux but apparently
// not under OSX. That means we need an offset hack
argv_offset = process.platform === "darwin" ? 1 : 0;
port_no = gui.App.argv[1 + argv_offset]; // fed to us by the Pd process
// address unique to the pd_engine // address unique to the pd_engine
pd_engine_id = gui.App.argv[4]; pd_engine_id = gui.App.argv[5 + argv_offset];
} else { } else {
// If we're starting Pd, this is the first port number to try. (We'll // If we're starting Pd, this is the first port number to try. (We'll
// increment it if that port happens to be taken.) // increment it if that port happens to be taken.)
......
...@@ -224,7 +224,7 @@ pd.res: pd.rc ...@@ -224,7 +224,7 @@ pd.res: pd.rc
# for making objects included with Pd, [expr] is whacky, so its built # for making objects included with Pd, [expr] is whacky, so its built
# separately, and pd~ doesn't build on Windows yet # separately, and pd~ doesn't build on Windows yet
EXTERNALS_SRC := $(wildcard $(pd_src)/extra/[a-df-oq-z]*/*.c) EXTERNALS_SRC := $(wildcard $(pd_src)/extra/[a-z]*/*.c)
#EXPR_SRC = vexp.c vexp_fun.c vexp_if.c #EXPR_SRC = vexp.c vexp_fun.c vexp_if.c
#EXPR_OBJ = $(patsubst %.c, $(pd_src)/extra/expr~/%.o, $(EXPR_SRC)) #EXPR_OBJ = $(patsubst %.c, $(pd_src)/extra/expr~/%.o, $(EXPR_SRC))
#expr_src = $(pd_src)/extra/expr~ #expr_src = $(pd_src)/extra/expr~
......
...@@ -1135,6 +1135,57 @@ static int defaultfontshit[MAXFONTS] = { ...@@ -1135,6 +1135,57 @@ static int defaultfontshit[MAXFONTS] = {
24, 15, 28}; 24, 15, 28};
#define NDEFAULTFONT (sizeof(defaultfontshit)/sizeof(*defaultfontshit)) #define NDEFAULTFONT (sizeof(defaultfontshit)/sizeof(*defaultfontshit))
extern t_symbol *pd_getplatform(void);
extern void sys_expandpath(const char *from, char *to);
/* set the datadir for nwjs. We use the published nw.js
defaults if there's only one instance of the GUI set to
run. Otherwise, we append the port number so that
nw.js will spawn a new instance for us.
Currently, users can give a command line arg to force Pd
to start with a new GUI instance. A new GUI must also get
created when a user turns on audio and there is a [pd~] object
on the canvas. The latter would actually be more usable within
a single GUI instance, but that would require some way to
visually distinguish patches that are associated with different Pd
engine processes.
*/
static void set_datadir(char *buf, int new_gui_instance, int portno)
{
char dir[FILENAME_MAX];
t_symbol *platform = pd_getplatform();
strcpy(buf, "--user-data-dir=");
/* Let's go ahead and quote the string to handle spaces in
paths, etc. */
strcat(buf, "\"");
if (platform == gensym("darwin"))
sys_expandpath("~/Library/Application Support/", dir);
else if (platform != gensym("win32"))/* bsd and linux */
sys_expandpath("~/.config/", dir);
#ifdef _WIN32
/* win32 has a more robust API for getting the
value of %LOCALAPPDATA%, but this works on
Windows 7 and is straightforward... */
char *env = getenv("LOCALAPPDATA");
strcpy(dir, env);
strcat(dir, "\\");
#endif
strcat(dir, "purr-data");
if (new_gui_instance)
{
char portbuf[10];
sprintf(portbuf, "-%d", portno);
strcat(dir, portbuf);
}
strcat(buf, dir);
/* Finally, close quote... */
strcat(buf, "\"");
}
extern int sys_unique;
int sys_startgui(const char *guidir) int sys_startgui(const char *guidir)
{ {
pid_t childpid; pid_t childpid;
...@@ -1146,13 +1197,12 @@ int sys_startgui(const char *guidir) ...@@ -1146,13 +1197,12 @@ int sys_startgui(const char *guidir)
int xsock = -1; int xsock = -1;
stderr_isatty = isatty(2); stderr_isatty = isatty(2);
#ifdef MSW #ifdef MSW
if (GetCurrentDirectory(FILENAME_MAX, cwd) == 0) if (GetCurrentDirectory(FILENAME_MAX, cwd) == 0)
strcpy(cwd, "."); strcpy(cwd, ".");
#endif #endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
if (!getcwd(cwd, FILENAME_MAX)) if (!getcwd(cwd, FILENAME_MAX))
strcpy(cwd, "."); strcpy(cwd, ".");
#endif #endif
#ifdef MSW #ifdef MSW
short version = MAKEWORD(2, 0); short version = MAKEWORD(2, 0);
...@@ -1272,7 +1322,6 @@ int sys_startgui(const char *guidir) ...@@ -1272,7 +1322,6 @@ int sys_startgui(const char *guidir)
/* assign server port number */ /* assign server port number */
server.sin_port = htons((unsigned short)portno); server.sin_port = htons((unsigned short)portno);
/* name the socket */ /* name the socket */
while (bind(xsock, (struct sockaddr *)&server, sizeof(server)) < 0) while (bind(xsock, (struct sockaddr *)&server, sizeof(server)) < 0)
{ {
...@@ -1325,7 +1374,8 @@ int sys_startgui(const char *guidir) ...@@ -1325,7 +1374,8 @@ int sys_startgui(const char *guidir)
/* this glob is needed so the Wish executable can have the same /* this glob is needed so the Wish executable can have the same
* filename as the Pd.app, i.e. 'Pd-0.42-3.app' should have a Wish * filename as the Pd.app, i.e. 'Pd-0.42-3.app' should have a Wish
* executable called 'Pd-0.42-3.app/Contents/MacOS/Pd-0.42-3' */ * executable called 'Pd-0.42-3.app/Contents/MacOS/Pd-0.42-3' */
sprintf(embed_glob, "%s/../../MacOS/Pd*", guidir); // sprintf(embed_glob, "%s/../../MacOS/Pd*", guidir);
sprintf(embed_glob, "%s/../../MacOS/nwjs", guidir);
glob_buffer.gl_matchc = 1; /* we only need one match */ glob_buffer.gl_matchc = 1; /* we only need one match */
glob(embed_glob, GLOB_LIMIT, NULL, &glob_buffer); glob(embed_glob, GLOB_LIMIT, NULL, &glob_buffer);
if (glob_buffer.gl_pathc > 0) { if (glob_buffer.gl_pathc > 0) {
...@@ -1342,37 +1392,74 @@ int sys_startgui(const char *guidir) ...@@ -1342,37 +1392,74 @@ int sys_startgui(const char *guidir)
break; break;
} }
sprintf(cmdbuf,"\"%s\" %s/pd.tk %d\n",wish_paths[i],guidir,portno); sprintf(cmdbuf,"\"%s\" %s/pd.tk %d\n",wish_paths[i],guidir,portno);
char data_dir_flag[MAXPDSTRING];
set_datadir(data_dir_flag, sys_unique, portno);
/* Make a copy in case the user wants to change to the repo
dir while developing... */
char guidir2[MAXPDSTRING];
/* Let's go ahead and quote the path in case there are spaces
in it. This won't happen on a sane Linux/BSD setup. But it
will happen under Windows, so we quote here, too, for
the sake of consistency. */
strcpy(guidir2, "\"");
strcat(guidir2, guidir);
strcat(guidir2, "\"");
/* Uncomment the following line if you want to
use the nw binary and GUI code from your local
copy of the Purr Data repo. (Make sure to run
tar_em_up.sh first to fetch the nw binary.) */
//strcpy(guidir2, "\"/home/grieg/purr-data/pd/nw\"");
sprintf(cmdbuf,
"\"%s\" %s %s "
"%d localhost %s %s " X_SPECIFIER,
wish_paths[i],
data_dir_flag,
guidir2,
portno,
(sys_k12_mode ? "pd-l2ork-k12" : "pd-l2ork"),
guidir2,
(long unsigned int)pd_this);
#else #else
sprintf(cmdbuf, sprintf(cmdbuf,
"TCL_LIBRARY=\"%s/tcl/library\" TK_LIBRARY=\"%s/tk/library\" \ "TCL_LIBRARY=\"%s/tcl/library\" TK_LIBRARY=\"%s/tk/library\" \
\"%s/pd-gui\" %d localhost %s\n", \"%s/pd-gui\" %d localhost %s\n",
sys_libdir->s_name, sys_libdir->s_name, guidir, portno, (sys_k12_mode ? "pd-l2ork-k12" : "pd-l2ork")); sys_libdir->s_name, sys_libdir->s_name, guidir, portno, (sys_k12_mode ? "pd-l2ork-k12" : "pd-l2ork"));
/* SUPERHACK - let's just load node-webkit and see what happens */ fprintf(stderr, "guidir is %s\n", guidir);
// sprintf(cmdbuf,
// "/home/user/Downloads/nwjs-v0.12.2-linux-ia32/nw "
// "/home/nu/Downloads/nwjs-v0.12.0-alpha2-linux-ia32/nw "
// "/home/user/pd-nw/pd/nw/ %d localhost %s\n",
// portno,
// (sys_k12_mode ? "pd-l2ork-k12" : "pd-l2ork"));
fprintf(stderr, "guidir is %s\n", guidir);
/* For some reason, the nw binary doesn't give you access to /* For some reason, the nw binary doesn't give you access to
the first argument-- this is the path to the directory where the first argument-- this is the path to the directory where
package.json lives (or the zip file if it's compressed). So package.json lives (or the zip file if it's compressed). So
we add it again as the last argument to make sure we can fetch we add it again as the last argument to make sure we can fetch
it on the GUI side. */ it on the GUI side. */
char data_dir_flag[MAXPDSTRING];
set_datadir(data_dir_flag, sys_unique, portno);
/* Make a copy in case the user wants to change to the repo
dir while developing... */
char guidir2[MAXPDSTRING];
/* Let's go ahead and quote the path in case there are spaces
in it. This won't happen on a sane Linux/BSD setup. But it
will happen under Windows, so we quote here, too, for
the sake of consistency. */
strcpy(guidir2, "\"");
strcat(guidir2, guidir);
strcat(guidir2, "\"");
/* Uncomment the following line if you want to
use the nw binary and GUI code from your local
copy of the Purr Data repo. (Make sure to run
tar_em_up.sh first to fetch the nw binary.) */
//strcpy(guidir2, "\"/home/grieg/purr-data/pd/nw\"");
sprintf(cmdbuf, sprintf(cmdbuf,
"%s/nw/nw %s %d localhost %s %s " X_SPECIFIER, "%s/nw/nw %s %s "
guidir, "%d localhost %s %s " X_SPECIFIER,
guidir, guidir2,
// "/home/user/purr-data/pd/nw", data_dir_flag,
guidir2,
portno, portno,
(sys_k12_mode ? "pd-l2ork-k12" : "pd-l2ork"), (sys_k12_mode ? "pd-l2ork-k12" : "pd-l2ork"),
guidir, guidir2,
(long unsigned int)pd_this); (long unsigned int)pd_this);
#endif #endif
sys_guicmd = cmdbuf; sys_guicmd = cmdbuf;
} }
...@@ -1406,6 +1493,7 @@ fprintf(stderr, "guidir is %s\n", guidir); ...@@ -1406,6 +1493,7 @@ fprintf(stderr, "guidir is %s\n", guidir);
close(stdinpipe[0]); close(stdinpipe[0]);
} }
} }
#endif #endif
execl("/bin/sh", "sh", "-c", sys_guicmd, (char*)0); execl("/bin/sh", "sh", "-c", sys_guicmd, (char*)0);
perror("pd: exec"); perror("pd: exec");
...@@ -1441,7 +1529,11 @@ fprintf(stderr, "guidir is %s\n", guidir); ...@@ -1441,7 +1529,11 @@ fprintf(stderr, "guidir is %s\n", guidir);
strcat(wishbuf, "/" PDBINDIR "nw/nw"); strcat(wishbuf, "/" PDBINDIR "nw/nw");
sys_bashfilename(wishbuf, wishbuf); sys_bashfilename(wishbuf, wishbuf);
spawnret = _spawnl(P_NOWAIT, wishbuf, "pd-nw", scriptbuf, char data_dir_flag[MAXPDSTRING];
set_datadir(data_dir_flag, sys_unique, portno);
spawnret = _spawnl(P_NOWAIT, wishbuf, "pd-nw",
data_dir_flag,
scriptbuf,
portbuf, portbuf,
"localhost", "localhost",
(sys_k12_mode ? "pd-l2ork-k12" : "pd-l2ork"), (sys_k12_mode ? "pd-l2ork-k12" : "pd-l2ork"),
......
...@@ -485,7 +485,7 @@ static int sys_getmultidevchannels(int n, int *devlist) ...@@ -485,7 +485,7 @@ static int sys_getmultidevchannels(int n, int *devlist)
void sys_findprogdir(char *progname) void sys_findprogdir(char *progname)
{ {
char *execdir = pd_getdirname()->s_name, *lastslash; char *execdir = pd_getdirname()->s_name, *lastslash;
char sbuf[FILENAME_MAX], sbuf2[FILENAME_MAX]; char sbuf[FILENAME_MAX], sbuf2[FILENAME_MAX], appbuf[FILENAME_MAX];
strncpy(sbuf, execdir, FILENAME_MAX-1); strncpy(sbuf, execdir, FILENAME_MAX-1);
#ifndef MSW #ifndef MSW
struct stat statbuf; struct stat statbuf;
...@@ -551,12 +551,20 @@ void sys_findprogdir(char *progname) ...@@ -551,12 +551,20 @@ void sys_findprogdir(char *progname)
else else
{ {
/* simple layout: lib dir is the parent */ /* simple layout: lib dir is the parent */
sys_libdir = gensym(sbuf);
/* gui lives in .../bin */ /* gui lives in .../bin */
strncpy(sbuf2, sbuf, FILENAME_MAX-30); strncpy(sbuf2, sbuf, FILENAME_MAX-30);
strncpy(appbuf, sbuf, FILENAME_MAX-30);
sbuf[FILENAME_MAX-30] = 0; sbuf[FILENAME_MAX-30] = 0;
sys_libdir = gensym(sbuf);
strcat(sbuf2, "/bin"); strcat(sbuf2, "/bin");
sys_guidir = gensym(sbuf2); /* special case-- with the OSX app bundle the guidir is actually
in app.nw instead of app.nw/bin. So we check for a package.json
there and then set it accordingly. */
strcat(appbuf, "/package.json");
if (stat(appbuf, &statbuf) >= 0)
sys_guidir = gensym(sbuf);
else
sys_guidir = gensym(sbuf2);
} }
#endif #endif
} }
......
...@@ -121,7 +121,7 @@ static void sys_path_replace( ...@@ -121,7 +121,7 @@ static void sys_path_replace(
} }
/* expand env vars and ~ at the beginning of a path and make a copy to return */ /* expand env vars and ~ at the beginning of a path and make a copy to return */
static void sys_expandpath(const char *from, char *to) void sys_expandpath(const char *from, char *to)
{ {
if ((strlen(from) == 1 && from[0] == '~') || (strncmp(from,"~/", 2) == 0)) if ((strlen(from) == 1 && from[0] == '~') || (strncmp(from,"~/", 2) == 0))
{ {
......
...@@ -843,23 +843,28 @@ void pdinfo_libdir(t_pdinfo *x, t_symbol *s, int argc, t_atom *argv) ...@@ -843,23 +843,28 @@ void pdinfo_libdir(t_pdinfo *x, t_symbol *s, int argc, t_atom *argv)
info_out((t_text *)x, s, 1, at); info_out((t_text *)x, s, 1, at);
} }
void pdinfo_platform(t_pdinfo *x, t_symbol *s, int argc, t_atom *argv) t_symbol* pd_getplatform(void)
{ {
t_atom at[1];
t_symbol *p = gensym("unknown");
#ifdef __APPLE__ #ifdef __APPLE__
p = gensym("darwin"); return gensym("darwin");
#endif #endif
#ifdef __FreeBSD__ #ifdef __FreeBSD__
p = gensym("freebsd"); return gensym("freebsd");
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
p = gensym("win32"); return gensym("win32");
#endif #endif
#ifdef __linux__ #ifdef __linux__
p = gensym("linux"); return gensym("linux");
#endif #endif
SETSYMBOL(at, p); /* don't know the platform... */
return gensym("unknown");
}
void pdinfo_platform(t_pdinfo *x, t_symbol *s, int argc, t_atom *argv)
{
t_atom at[1];
SETSYMBOL(at, pd_getplatform());
info_out((t_text *)x, s, 1, at); info_out((t_text *)x, s, 1, at);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment