aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2008-03-22 02:28:22 +0000
committerHans-Christoph Steiner <eighthave@users.sourceforge.net>2008-03-22 02:28:22 +0000
commit0f770551cebca90c92b7a39b0e0135a445af51f9 (patch)
treec1fc0b535133c7d292808c8cee22817e5cdec0e3 /src
parenta764e59e1d3a8e330f0d484fdb26b35ca3f0b2e4 (diff)
merging in pdj-0.8.4.tar.gz from http://www.le-son666.com/software/pdj/
svn path=/trunk/externals/loaders/pdj/; revision=9624
Diffstat (limited to 'src')
-rw-r--r--src/MaxClock.c2
-rw-r--r--src/MaxObject.c13
-rw-r--r--src/MaxSystem.c2
-rw-r--r--src/init.c16
-rw-r--r--src/java/com/cycling74/max/MaxObject.java4
-rw-r--r--src/java/com/cycling74/max/MaxRuntimeException.java8
-rw-r--r--src/java/com/cycling74/max/MaxSystem.java2
-rw-r--r--src/java/com/cycling74/msp/AudioFileBuffer.java2
-rw-r--r--src/java/com/cycling74/net/TcpReceiver.java89
-rw-r--r--src/java/com/cycling74/net/TcpSender.java103
-rw-r--r--src/java/com/cycling74/net/UdpReceiver.java84
-rw-r--r--src/java/com/cycling74/net/UdpSender.java84
-rw-r--r--src/java/com/e1/pdj/JikesCompiler.java1
-rw-r--r--src/java/com/e1/pdj/PDJSystem.java20
-rw-r--r--src/java/pdj_test_class.java3
-rw-r--r--src/pd_patch/osx_extsched_fix.patch29
-rw-r--r--src/pdj-linux.c27
-rw-r--r--src/pdj-osx.c165
-rw-r--r--src/pdj.h9
-rw-r--r--src/pdj~.c8
-rw-r--r--src/type_handler.c4
21 files changed, 622 insertions, 53 deletions
diff --git a/src/MaxClock.c b/src/MaxClock.c
index e7e5886..c5694fd 100644
--- a/src/MaxClock.c
+++ b/src/MaxClock.c
@@ -11,7 +11,7 @@ typedef struct _clockCtnr {
static t_clockCtnr *getClock(JNIEnv *env, jobject obj) {
- return (t_clockCtnr *) (*env)->GetLongField(env, obj, pdjCaching.FIDMaxClock_clock_ptr);
+ return (t_clockCtnr *) JPOINTER_CAST (*env)->GetLongField(env, obj, pdjCaching.FIDMaxClock_clock_ptr);
}
diff --git a/src/MaxObject.c b/src/MaxObject.c
index 3c77f49..cffbd76 100644
--- a/src/MaxObject.c
+++ b/src/MaxObject.c
@@ -4,7 +4,7 @@
static t_pdj *getMaxObject(JNIEnv *env, jobject obj) {
- t_pdj *ret = (t_pdj *) (*env)->GetLongField(env, obj,
+ t_pdj *ret = (t_pdj *) JPOINTER_CAST (*env)->GetLongField(env, obj,
pdjCaching.FIDMaxObject_pdobj_ptr);
if ( ret == NULL )
@@ -27,8 +27,7 @@ JNIEXPORT jlong JNICALL Java_com_cycling74_max_MaxObject_newInlet
}
proxy = (t_inlet_proxy *) pd_new(inlet_proxy);
- pdj->nb_inlet++;
- proxy->idx = pdj->nb_inlet;
+ proxy->idx = pdj->nb_inlet++;
proxy->peer = pdj;
return (jlong) inlet_new(&pdj->x_obj, &proxy->x_obj.ob_pd, 0, 0);
@@ -53,28 +52,28 @@ JNIEXPORT jlong JNICALL Java_com_cycling74_max_MaxObject_newOutlet
JNIEXPORT void JNICALL Java_com_cycling74_max_MaxObject_doOutletBang
(JNIEnv *env, jobject obj, jlong outlet) {
- t_outlet *x = (t_outlet *) ((unsigned int) outlet);
+ t_outlet *x = (t_outlet *) (JPOINTER_CAST outlet);
outlet_bang(x);
}
JNIEXPORT void JNICALL Java_com_cycling74_max_MaxObject_doOutletFloat
(JNIEnv *env, jobject obj, jlong outlet , jfloat value) {
- t_outlet *x = (t_outlet *) ((unsigned int) outlet);
+ t_outlet *x = (t_outlet *) (JPOINTER_CAST outlet);
outlet_float(x, value);
}
JNIEXPORT void JNICALL Java_com_cycling74_max_MaxObject_doOutletSymbol
(JNIEnv *env, jobject obj, jlong outlet, jstring value) {
- t_outlet *x = (t_outlet *) ((unsigned int) outlet);
+ t_outlet *x = (t_outlet *) (JPOINTER_CAST outlet);
outlet_symbol(x, jstring2symbol(env, value));
}
JNIEXPORT void JNICALL Java_com_cycling74_max_MaxObject_doOutletAnything
(JNIEnv *env, jobject obj, jlong outlet, jstring str, jobjectArray value) {
- t_outlet *x = (t_outlet *) ((unsigned int) outlet);
+ t_outlet *x = (t_outlet *) (JPOINTER_CAST outlet);
t_atom args[MAX_ATOMS_STACK];
int argc;
diff --git a/src/MaxSystem.c b/src/MaxSystem.c
index c506fa2..ea48ab2 100644
--- a/src/MaxSystem.c
+++ b/src/MaxSystem.c
@@ -158,7 +158,7 @@ JNIEXPORT jboolean JNICALL Java_com_cycling74_max_MaxSystem_sendMessageToBoundOb
JNIEXPORT jstring JNICALL Java_com_cycling74_max_MaxSystem_locateFile
(JNIEnv *env, jclass cls, jstring filename) {
- const jbyte *file = (*env)->GetStringUTFChars(env, filename, NULL);
+ const char *file = (*env)->GetStringUTFChars(env, filename, NULL);
char fullpath[MAXPDSTRING], *pfullpath;
FILE *fd;
diff --git a/src/init.c b/src/init.c
index 4666367..b147db4 100644
--- a/src/init.c
+++ b/src/init.c
@@ -1,5 +1,5 @@
/**
- * This code is very ugly and needs rewrite. PERIOD.
+ * initialization
*/
#include <stdio.h>
@@ -97,7 +97,7 @@ static void load_properties() {
}
-static void copyToJavaSystemProperties(JNIEnv *env) {
+void copyToJavaSystemProperties(JNIEnv *env) {
jclass system = (*env)->FindClass(env, "java/lang/System");
jmethodID id = (*env)->GetStaticMethodID(env, system, "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
int i;
@@ -232,8 +232,8 @@ static int linkClasses(JNIEnv *env) {
}
-void buildVMOptions(jint *nb, JavaVMOption *options) {
- static char cp[BUFFER_SIZE], pdj_cp[BUFFER_SIZE];
+static void buildVMOptions(jint *nb, JavaVMOption *options) {
+ static char cp[BUFFER_SIZE];
char installPath[BUFFER_SIZE];
char *prop;
char *token, *work;
@@ -316,7 +316,7 @@ JNIEnv *init_jvm(void) {
vm_args.options = opt;
vm_args.version = JNI_VERSION_1_4;
vm_args.ignoreUnrecognized = JNI_FALSE;
-
+
vm_type = pdj_getProperty("pdj.vm_type");
if ( vm_type == NULL ) {
error("pdj: unknown vm_type, using client");
@@ -332,12 +332,12 @@ JNIEnv *init_jvm(void) {
error("pdj: unable to create JVM: JNI_CreateJavaVM = %d", rc);
return NULL;
}
-
- copyToJavaSystemProperties(jni_env);
- if ( initIDCaching(jni_env) != 0) {
+
+ if ( initIDCaching(jni_env) != 0 ) {
return NULL;
}
+ copyToJavaSystemProperties(jni_env);
if ( linkClasses(jni_env) != 0 ) {
return NULL;
}
diff --git a/src/java/com/cycling74/max/MaxObject.java b/src/java/com/cycling74/max/MaxObject.java
index 3d07d49..15f2a16 100644
--- a/src/java/com/cycling74/max/MaxObject.java
+++ b/src/java/com/cycling74/max/MaxObject.java
@@ -806,7 +806,7 @@ public class MaxObject {
}
/**
- * Tries to instanciate a MaxObject.
+ * Tries to instantiate a MaxObject.
* @param name fq java name
* @param _pdobj_ptr C pointer to pd object
* @param args objects arguments
@@ -844,7 +844,7 @@ public class MaxObject {
pushPdjPointer(_pdobj_ptr);
- // instanciate the object
+ // instantiate the object
if ( args.length > 0 ) {
try {
Object argValue[] = new Object[1];
diff --git a/src/java/com/cycling74/max/MaxRuntimeException.java b/src/java/com/cycling74/max/MaxRuntimeException.java
index 9909a5c..8043aa9 100644
--- a/src/java/com/cycling74/max/MaxRuntimeException.java
+++ b/src/java/com/cycling74/max/MaxRuntimeException.java
@@ -5,11 +5,15 @@ package com.cycling74.max;
*/
public class MaxRuntimeException extends RuntimeException {
+ public MaxRuntimeException() {
+ }
+
public MaxRuntimeException(String msg) {
super(msg);
}
- public MaxRuntimeException() {
- }
+ public MaxRuntimeException(Exception e) {
+ super(e);
+ }
}
diff --git a/src/java/com/cycling74/max/MaxSystem.java b/src/java/com/cycling74/max/MaxSystem.java
index 3a29540..dd8fe48 100644
--- a/src/java/com/cycling74/max/MaxSystem.java
+++ b/src/java/com/cycling74/max/MaxSystem.java
@@ -171,7 +171,7 @@ public class MaxSystem {
}
// constants
- public static String MXJ_VERSION = "pdj 0.8.3";
+ public static String MXJ_VERSION = "pdj 0.8.4";
public static final int PATH_STYLE_COLON = 2;
public static final int PATH_STYLE_MAX = 0;
diff --git a/src/java/com/cycling74/msp/AudioFileBuffer.java b/src/java/com/cycling74/msp/AudioFileBuffer.java
index b2e76f3..eebffa1 100644
--- a/src/java/com/cycling74/msp/AudioFileBuffer.java
+++ b/src/java/com/cycling74/msp/AudioFileBuffer.java
@@ -12,7 +12,7 @@ import javax.sound.sampled.UnsupportedAudioFileException;
import com.cycling74.max.MessageReceiver;
/**
- * Work in progress, target: 0.8.4
+ * Work in progress, target: 0.8.5
*/
class AudioFileBuffer {
diff --git a/src/java/com/cycling74/net/TcpReceiver.java b/src/java/com/cycling74/net/TcpReceiver.java
new file mode 100644
index 0000000..f449517
--- /dev/null
+++ b/src/java/com/cycling74/net/TcpReceiver.java
@@ -0,0 +1,89 @@
+package com.cycling74.net;
+
+import java.lang.reflect.Method;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+
+import com.cycling74.max.Atom;
+import com.cycling74.max.MaxRuntimeException;
+import com.cycling74.max.MaxSystem;
+
+/**
+ * This portion of code is scheduled for pdj-0.8.5
+ * IT IS NOT FUNCTIONAL
+ */
+public class TcpReceiver implements Runnable {
+ DatagramSocket receiver;
+ DatagramPacket packet;
+
+ Method callback = null;
+ Object instance;
+
+ String debugString = null;
+ int port;
+ boolean runnable = true;
+
+ public void close() {
+ if ( receiver == null )
+ return;
+ runnable = false;
+ receiver.close();
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setActive(boolean active) {
+ if ( active == false ) {
+ runnable = true;
+ new Thread(this).start();
+ } else {
+ close();
+ }
+
+ }
+
+ public void setCallback(Object caller, String methodName) {
+ try {
+ callback = caller.getClass().getDeclaredMethod(methodName, new Class[] { Atom.class });
+ instance = caller;
+ } catch (Exception e) {
+ throw new MaxRuntimeException(e);
+ }
+ }
+
+ public void setPort(int port) {
+ setActive(false);
+ this.port = port;
+ }
+
+ public void setDebugString(String debugString) {
+ this.debugString = debugString;
+ }
+
+ public void run() {
+ DatagramPacket packet = new DatagramPacket(new byte[4096], 4096);
+ Object callerArgs[] = new Object[1];
+
+ try {
+ while(runnable) {
+ receiver.receive(packet);
+ String msg = new String(packet.getData(), 0, packet.getLength());
+ if ( debugString != null )
+ MaxSystem.post(debugString + " " + msg);
+ callerArgs[0] = Atom.parse(msg);
+ try {
+ callback.invoke(instance, callerArgs);
+ } catch( Exception e ) {
+ e.printStackTrace();
+ }
+ }
+ } catch (Exception e) {
+ if ( runnable != false) {
+ runnable = false;
+ throw new MaxRuntimeException(e);
+ }
+ }
+ }
+}
diff --git a/src/java/com/cycling74/net/TcpSender.java b/src/java/com/cycling74/net/TcpSender.java
new file mode 100644
index 0000000..2ba0f67
--- /dev/null
+++ b/src/java/com/cycling74/net/TcpSender.java
@@ -0,0 +1,103 @@
+package com.cycling74.net;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetSocketAddress;
+
+import com.cycling74.max.Atom;
+import com.cycling74.max.MaxRuntimeException;
+
+/**
+ * This portion of code is scheduled for pdj-0.8.5
+ * IT IS NOT FUNCTIONAL
+ */
+public class TcpSender {
+ DatagramSocket sender;
+ DatagramPacket packet;
+ String address = null;
+ int port = -1;
+
+ public TcpSender() {
+ }
+
+ public TcpSender(String address, int port) {
+ this.address= address;
+ this.port = port;
+ }
+
+ public void send(Atom args[]) {
+ if ( sender == null )
+ initsocket();
+
+ byte buff[] = Atom.toOneString(args).getBytes();
+ packet.setData(buff, 0, buff.length);
+ try {
+ sender.send(packet);
+ } catch (IOException e) {
+ throw new MaxRuntimeException(e);
+ }
+ }
+
+ public void send(int i) {
+ if ( sender == null )
+ initsocket();
+
+ byte buff[] = Integer.toString(i).getBytes();
+ packet.setData(buff, 0, buff.length);
+ try {
+ sender.send(packet);
+ } catch (IOException e) {
+ throw new MaxRuntimeException(e);
+ }
+ }
+
+ public void send(float f) {
+ if ( sender == null )
+ initsocket();
+
+ byte buff[] = Float.toString(f).getBytes();
+ packet.setData(buff, 0, buff.length);
+ try {
+ sender.send(packet);
+ } catch (IOException e) {
+ throw new MaxRuntimeException(e);
+ }
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ if ( sender != null ) {
+ sender = null;
+ sender.close();
+ }
+ this.address = address;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ if ( sender != null ) {
+ sender = null;
+ sender.close();
+ }
+ this.port = port;
+ }
+
+ private synchronized void initsocket() {
+ if ( sender != null )
+ return;
+ try {
+ sender = new DatagramSocket();
+ sender.connect(new InetSocketAddress(address, port));
+ packet = new DatagramPacket(new byte[0], 0);
+ } catch (Exception e) {
+ throw new MaxRuntimeException(e);
+ }
+ }
+}
diff --git a/src/java/com/cycling74/net/UdpReceiver.java b/src/java/com/cycling74/net/UdpReceiver.java
new file mode 100644
index 0000000..fd47e25
--- /dev/null
+++ b/src/java/com/cycling74/net/UdpReceiver.java
@@ -0,0 +1,84 @@
+package com.cycling74.net;
+
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+
+import com.cycling74.max.Atom;
+import com.cycling74.max.MaxRuntimeException;
+import com.cycling74.max.MaxSystem;
+import com.cycling74.max.Callback;
+
+/**
+ * This portion of code is scheduled for pdj-0.8.5
+ * IT IS NOT FUNCTIONAL
+ */
+public class UdpReceiver implements Runnable {
+ DatagramSocket receiver;
+ DatagramPacket packet;
+
+ Callback callback;
+
+ String debugString = null;
+ int port;
+ boolean runnable = true;
+
+ public void close() {
+ if ( receiver == null )
+ return;
+ runnable = false;
+ receiver.close();
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setActive(boolean active) {
+ if ( active == false ) {
+ runnable = true;
+ new Thread(this).start();
+ } else {
+ close();
+ }
+
+ }
+
+ public void setCallback(Object caller, String methodName) {
+ callback = new Callback(caller, methodName);
+ }
+
+ public void setPort(int port) {
+ setActive(false);
+ this.port = port;
+ }
+
+ public void setDebugString(String debugString) {
+ this.debugString = debugString;
+ }
+
+ public void run() {
+ DatagramPacket packet = new DatagramPacket(new byte[4096], 4096);
+ Object callerArgs[] = new Object[1];
+
+ try {
+ while(runnable) {
+ receiver.receive(packet);
+ String msg = new String(packet.getData(), 0, packet.getLength());
+ if ( debugString != null )
+ MaxSystem.post(debugString + " " + msg);
+ callerArgs[0] = Atom.parse(msg);
+
+ /* try {
+ callback.invoke(instance, callerArgs);
+ } catch( Exception e ) {
+ e.printStackTrace();
+ } */
+ }
+ } catch (Exception e) {
+ if ( runnable != false) {
+ runnable = false;
+ throw new MaxRuntimeException(e);
+ }
+ }
+ }
+}
diff --git a/src/java/com/cycling74/net/UdpSender.java b/src/java/com/cycling74/net/UdpSender.java
new file mode 100644
index 0000000..6ef7e34
--- /dev/null
+++ b/src/java/com/cycling74/net/UdpSender.java
@@ -0,0 +1,84 @@
+package com.cycling74.net;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+
+import com.cycling74.max.Atom;
+import com.cycling74.max.MaxRuntimeException;
+
+/**
+ * This portion of code is scheduled for pdj-0.8.5
+ * IT IS NOT FUNCTIONAL
+ */
+public class UdpSender {
+ InetAddress inetAddress;
+ DatagramSocket sender;
+ boolean init;
+
+ String address = null;
+ int port = -1;
+
+ public UdpSender() {
+ }
+
+ public UdpSender(String address, int port) {
+ this.address = address;
+ this.port = port;
+ initsocket();
+ }
+
+ public void send(Atom args[]) {
+ send(Atom.toOneString(args).getBytes());
+ }
+
+ public void send(int i) {
+ send(Integer.toString(i).getBytes());
+ }
+
+ public void send(float f) {
+ send(Float.toString(f).getBytes());
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ initsocket();
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ initsocket();
+ }
+
+ synchronized void initsocket() {
+ try {
+ sender = null;
+ inetAddress = InetAddress.getByName(address);
+ sender = new DatagramSocket();
+ } catch (Exception e) {
+ throw new MaxRuntimeException(e);
+ }
+ }
+
+ void send(byte buff[]) {
+ if ( sender == null )
+ throw new MaxRuntimeException("UdpSender is not initialized");
+
+ try {
+ DatagramPacket packet = new DatagramPacket(buff, buff.length, inetAddress, port);
+ sender.send(packet);
+ } catch (IOException e) {
+ throw new MaxRuntimeException(e);
+ }
+
+ }
+}
diff --git a/src/java/com/e1/pdj/JikesCompiler.java b/src/java/com/e1/pdj/JikesCompiler.java
index f9337b2..041a4f7 100644
--- a/src/java/com/e1/pdj/JikesCompiler.java
+++ b/src/java/com/e1/pdj/JikesCompiler.java
@@ -1,6 +1,5 @@
package com.e1.pdj;
-import java.io.*;
import com.cycling74.max.MaxSystem;
public class JikesCompiler extends GenericCompiler {
diff --git a/src/java/com/e1/pdj/PDJSystem.java b/src/java/com/e1/pdj/PDJSystem.java
index 3d30a53..1fd50d2 100644
--- a/src/java/com/e1/pdj/PDJSystem.java
+++ b/src/java/com/e1/pdj/PDJSystem.java
@@ -7,6 +7,7 @@ import java.awt.Frame;
import java.awt.Toolkit;
import java.io.*;
+import java.awt.GraphicsEnvironment;
/**
* Startup class for pdj.
*/
@@ -50,7 +51,7 @@ public class PDJSystem {
// this is a hack to be sure that statics of MaxSystem are loaded
// before everything
Class cls = MaxSystem.class;
-
+
String osname = System.getProperty("os.name");
if ( osname.indexOf("Linux") != -1 ) {
@@ -71,20 +72,13 @@ public class PDJSystem {
if ( osname.indexOf("OS X") != -1 ) {
// maps PD object as a JVM native library
- try {
- Runtime.getRuntime().load(pdjHome + "/pdj.pd_darwin");
- } catch (UnsatisfiedLinkError e ) {
- Runtime.getRuntime().load(pdjHome + "/pdj.pd_imac");
- }
+ Runtime.getRuntime().load(pdjHome + "/pdj.d_fat");
loaded = 1;
-
- // this will initialize the AWT component in another thread
- new Thread(new Runnable() {
- public void run() {
- Class clz = Component.class;
- }
- }).start();
+ if ( System.getenv("PDJ_USE_AWT") != null ) {
+ GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
+ Toolkit.getDefaultToolkit();
+ }
GenericCompiler.rtJar = "/System/Library/Frameworks/JavaVM.framework/Classes/classes.jar:";
return;
diff --git a/src/java/pdj_test_class.java b/src/java/pdj_test_class.java
index ff6f756..61cf804 100644
--- a/src/java/pdj_test_class.java
+++ b/src/java/pdj_test_class.java
@@ -9,6 +9,7 @@ public class pdj_test_class extends MaxObject implements Executable {
clock = new MaxClock(this);
declareAttribute("patate");
+ declareIO(2,2);
}
public pdj_test_class(Atom args[]) {
@@ -49,7 +50,7 @@ public class pdj_test_class extends MaxObject implements Executable {
}
protected void inlet(float f) {
- post("le float " + f);
+ post("le float " + f + "inlet " + getInlet());
}
void wer(Atom[] atom) {
diff --git a/src/pd_patch/osx_extsched_fix.patch b/src/pd_patch/osx_extsched_fix.patch
new file mode 100644
index 0000000..29195e4
--- /dev/null
+++ b/src/pd_patch/osx_extsched_fix.patch
@@ -0,0 +1,29 @@
+--- s_loader.orig 2008-03-12 11:19:15.000000000 -0400
++++ s_loader.c 2008-03-12 11:18:09.000000000 -0400
+@@ -247,7 +247,7 @@
+ typedef int (*t_externalschedlibmain)(const char *);
+ t_externalschedlibmain externalmainfunc;
+ char filename[MAXPDSTRING];
+- snprintf(filename, sizeof(filename), "%s.%s", externalschedlibname,
++ snprintf(filename, sizeof(filename), "%s%s", externalschedlibname,
+ sys_dllextent);
+ sys_bashfilename(filename, filename);
+ #ifdef MSW
+@@ -255,7 +255,7 @@
+ HINSTANCE ntdll = LoadLibrary(filename);
+ if (!ntdll)
+ {
+- post("%s: couldn't load external scheduler lib ", filename);
++ fprintf(stderr, "%s: couldn't load external scheduler lib ", filename);
+ return (0);
+ }
+ externalmainfunc =
+@@ -266,7 +266,7 @@
+ void *dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
+ if (!dlobj)
+ {
+- post("%s: %s", filename, dlerror());
++ fprintf(stderr, "%s: %s\n", filename, dlerror());
+ return (0);
+ }
+ externalmainfunc = (t_externalschedlibmain)dlsym(dlobj,
diff --git a/src/pdj-linux.c b/src/pdj-linux.c
index 63bb015..5af919f 100644
--- a/src/pdj-linux.c
+++ b/src/pdj-linux.c
@@ -4,6 +4,19 @@
#include <dlfcn.h>
#include "pdj.h"
+// test if this system is amd64
+#ifdef __LP64__
+ #define ARCH "amd64"
+ #define MAPPOS 73
+#else
+ #define ARCH "i386"
+ #define MAPPOS 49
+#endif
+
+/*
+ * This is why it is called getuglylibpath... getting the info from /proc...
+ * if you have a better idea; well I would like to be informed
+ */
int getuglylibpath(char *path) {
char buffer[BUFFER_SIZE];
FILE *f;
@@ -20,7 +33,7 @@ int getuglylibpath(char *path) {
fgets(buffer, BUFFER_SIZE-1, f);
if ( strstr(buffer, "pdj.pd_linux") != NULL ) {
buffer[strlen(buffer) - 14] = 0;
- strcpy(path, buffer+49);
+ strcpy(path, buffer + MAPPOS);
fclose(f);
return 0;
}
@@ -43,7 +56,7 @@ JNI_CreateJavaVM_func *linkjvm(char *vm_type) {
if ( javahome == NULL ) {
javahome = getenv("JAVA_HOME");
} else {
- sprintf(work, "%s/jre/lib/i386/%s/libjvm.so", javahome, vm_type);
+ sprintf(work, "%s/jre/lib/" ARCH "/%s/libjvm.so", javahome, vm_type);
libVM = dlopen(work, RTLD_LAZY);
if ( libVM == NULL ) {
@@ -60,20 +73,20 @@ JNI_CreateJavaVM_func *linkjvm(char *vm_type) {
/* using LD_LIBRARY_PATH + putenv doesn't work, load std jvm libs
* with absolute path. order is important.
*/
- sprintf(work, "%s/jre/lib/i386/%s/libjvm.so", javahome, vm_type);
+ sprintf(work, "%s/jre/lib/" ARCH "/%s/libjvm.so", javahome, vm_type);
dlopen(work, RTLD_LAZY);
- sprintf(work, "%s/jre/lib/i386/libverify.so", javahome);
+ sprintf(work, "%s/jre/lib/" ARCH "/libverify.so", javahome);
dlopen(work, RTLD_LAZY);
- sprintf(work, "%s/jre/lib/i386/libjava.so", javahome);
+ sprintf(work, "%s/jre/lib/" ARCH "/libjava.so", javahome);
dlopen(work, RTLD_LAZY);
- sprintf(work, "%s/jre/lib/i386/libmlib_image.so", javahome);
+ sprintf(work, "%s/jre/lib/" ARCH "/libmlib_image.so", javahome);
dlopen(work, RTLD_LAZY);
/* ELF should support dynamic LD_LIBRARY_PATH :( :( :( */
- sprintf(work, "%s/jre/lib/i386/libjava.so", javahome);
+ sprintf(work, "%s/jre/lib/" ARCH "/libjava.so", javahome);
libVM = dlopen(work, RTLD_LAZY);
}
diff --git a/src/pdj-osx.c b/src/pdj-osx.c
index bd2be18..7c5b281 100644
--- a/src/pdj-osx.c
+++ b/src/pdj-osx.c
@@ -2,12 +2,170 @@
#include <string.h>
#include <pthread.h>
#include <CoreFoundation/CoreFoundation.h>
+#include <mach-o/dyld.h>
+#include <mach-o/ldsyms.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
#include "pdj.h"
+/**
+ * === USING AWT WITH OS X
+ *
+ * Unlike Linux or Windows, you cannot just simply fire-up a AWT form on OS X. This is
+ * because the event GUI mecanism has these limitation :
+ *
+ * --> A CFRunLoopRun must be park in the main thread.
+ * --> Java must be run in a secondary thread.
+ *
+ * Since this prerequisite need a pure-data patch, we will write our own pd scheduler.
+ * This scheduler will simple fire-up another thread that will run the real pd
+ * scheduler (m_mainloop) and park the main thread with a CFRunLoopRun.
+ *
+ * To be able to use the pdj scheduler, you need to apply a patch to pd. (Yes there
+ * is a bug with the -schedlib option). The patch is available in the directory
+ * src/pd_patch/osx_extsched_fix.patch. This patch has been made on a miller's 41.2
+ * pd version.
+ *
+ * Once the patch is applied and compiled, you must configure your pure-data environement
+ * to add the option : -schedlib [fullpath of the pdj external without the extension]. Use
+ * the menu Pd -> Preference -> Startup to do this. Don't forget to click on [Save All
+ * Settings].
+ *
+ * Be carfull when you configure this switch since it can crash PD on startup. If you do
+ * have the problem; you will have to delete all pd-preference by deleting file:
+ * ~/Library/Preferences/org.puredata.pd.plist
+ *
+ * If the scheduler is loaded, you should have this pd message :
+ * 'pdj: using pdj scheduler for Java AWT.'
+ */
+
+int rc_pd = 0xFF;
+CFRunLoopRef cfrunloop;
+
+
+/* setting the environment varible APP_NAME_<pid> to the applications name */
+/* sets it for the application menu */
+void setAppName(const char * name) {
+ char a[32];
+ pid_t id = getpid();
+ sprintf(a,"APP_NAME_%ld",(long)id);
+ setenv(a, name, 1);
+}
+
+
+/**
+ * The main pd thread, will become a secondary thread to AWT.
+ */
+void *pdj_pdloop(void *notused) {
+ post("pdj: using pdj scheduler for Java AWT.");
+ rc_pd = 0;
+
+ // this will tell the java init code to initialize AWT before anything
+ setenv("PDJ_USE_AWT", "true", 1);
+
+ // we create the JVM now
+ init_jvm();
+
+ /* open audio and MIDI */
+ sys_reopen_midi();
+ sys_reopen_audio();
+
+ rc_pd = m_mainloop();
+
+ exit(rc_pd);
+}
+
+
+/* call back for dummy source used to make sure the CFRunLoop doesn't exit right away */
+/* This callback is called when the source has fired. */
+void sourceCallBack ( void *info ) {
+}
+
+
+/**
+ * This function is called when pdj is considered a scheduler on pd
+ */
+int pd_extern_sched(void *notused) {
+ CFRunLoopSourceContext sourceContext;
+
+ /* Start the thread that runs the pure-data main thread and the VM. */
+ pthread_t vmthread;
+
+ setAppName("pdj");
+
+ /* create a new pthread copying the stack size of the primordial pthread */
+ struct rlimit limit;
+ size_t stack_size = 0;
+ int rc = getrlimit(RLIMIT_STACK, &limit);
+ if (rc == 0) {
+ if (limit.rlim_cur != 0LL) {
+ stack_size = (size_t)limit.rlim_cur;
+ }
+ }
+
+ pthread_attr_t thread_attr;
+ pthread_attr_init(&thread_attr);
+ pthread_attr_setscope(&thread_attr, PTHREAD_SCOPE_SYSTEM);
+ pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
+ if (stack_size > 0) {
+ pthread_attr_setstacksize(&thread_attr, stack_size);
+ }
+
+ /* Start the thread that we will start the pd main thread */
+ pthread_create(&vmthread, &thread_attr, pdj_pdloop, NULL);
+ pthread_attr_destroy(&thread_attr);
+
+ /* Create a a sourceContext to be used by our source that makes */
+ /* sure the CFRunLoop doesn't exit right away */
+ sourceContext.version = 0;
+ sourceContext.info = NULL;
+ sourceContext.retain = NULL;
+ sourceContext.release = NULL;
+ sourceContext.copyDescription = NULL;
+ sourceContext.equal = NULL;
+ sourceContext.hash = NULL;
+ sourceContext.schedule = NULL;
+ sourceContext.cancel = NULL;
+ sourceContext.perform = &sourceCallBack;
+
+ /* Create the Source from the sourceContext */
+ CFRunLoopSourceRef sourceRef = CFRunLoopSourceCreate(NULL, 0, &sourceContext);
+
+ /* Use the constant kCFRunLoopCommonModes to add the source to the set of objects */
+ /* monitored by all the common modes */
+ CFRunLoopAddSource (CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes);
+
+ /* Park this thread in the runloop for Java */
+ CFRunLoopRun();
+
+ return rc_pd;
+}
+
+
int getuglylibpath(char *path) {
char fullpath[MAXPDSTRING], *pfullpath;
+ int cnt = _dyld_image_count();
+ char *imagename = NULL;
FILE *fd;
+ int i;
+
+ // we get the bundle header, that contains the dyld header too...
+ struct mach_header* header = (struct mach_header*) &_mh_bundle_header;
+
+ for(i=1;i<cnt;i++) {
+ if (_dyld_get_image_header(i) == header)
+ imagename = (char *) _dyld_get_image_name(i);
+ }
+
+ if ( imagename != NULL ) {
+ strncpy(path, imagename, MAXPDSTRING);
+ // remove the pdj.pd_fat text
+ path[strlen(imagename) - 10] = 0;
+ return 0;
+ }
+
+ error("unable to find pdj directory, looking into the user PD path");
fd = (FILE *) open_via_path("", "pdj.properties", "", fullpath, &pfullpath, MAXPDSTRING, 0);
if ( fd != NULL ) {
@@ -26,6 +184,7 @@ int getuglylibpath(char *path) {
return 1;
}
+
JNI_CreateJavaVM_func *linkjvm(char *vmtype) {
char *jvmVersion = pdj_getProperty("pdj.osx.JAVA_JVM_VERSION");
@@ -33,5 +192,9 @@ JNI_CreateJavaVM_func *linkjvm(char *vmtype) {
setenv("JAVA_JVM_VERSION", jvmVersion, 1);
}
+ if ( rc_pd == 0xFF ) {
+ post("pdj: warning: Java is initialized from main thread. AWT can lock pure-data environment. See pdj/pd scheduler to cover this problem.");
+ }
+
return (JNI_CreateJavaVM_func *) &JNI_CreateJavaVM;
-} \ No newline at end of file
+}
diff --git a/src/pdj.h b/src/pdj.h
index d318ded..f8755e8 100644
--- a/src/pdj.h
+++ b/src/pdj.h
@@ -3,11 +3,12 @@
#ifdef DEBUG
#define ASSERT(v) { if ( v == NULL ) {bug("ouch, assertion failed %s:%d\n", __FILE__, __LINE__);}}
- #define JASSERT(v) { if ( v == NULL ){(*env)->ExceptionDescribe(env);bug("ouch, assertion failed %s:%d\n", __FILE__, __LINE__);}}
+ #define JASSERT(v) { if ( v == NULL ) {(*env)->ExceptionDescribe(env);bug("ouch, jni assertion failed %s:%d\n", __FILE__, __LINE__);}}
#undef DEBUG
#define DEBUG(X) {X};
#else
#define ASSERT(v)
+ #undef DEBUG
#define DEBUG(X)
#define JASSERT(v)
#endif
@@ -28,6 +29,12 @@
#define PATH_SEP ":"
#endif
+#ifdef __LP64__
+ #define JPOINTER_CAST (unsigned long)
+#else
+ #define JPOINTER_CAST (unsigned int)
+#endif
+
// the JVM takes 50M; I don't care taking 4K...
#define BUFFER_SIZE 4096
diff --git a/src/pdj~.c b/src/pdj~.c
index d2f2a36..8ecdb5d 100644
--- a/src/pdj~.c
+++ b/src/pdj~.c
@@ -20,12 +20,13 @@ t_int *pdj_tilde_perform(t_int *w) {
/* call the performer */
(*env)->CallVoidMethod(env, pdjt->pdj.obj, pdjt->performer,
pdjt->_used_inputs, pdjt->_used_outputs);
-
+
+ /* set work to output outlets */
+ work = i + 3;
+
/* if an exception occured, stop the dsp processing for this object */
if ( (*env)->ExceptionOccurred(env) ) {
int tmp;
-
- work = i + 3;
/* insert silence */
for (tmp=0;tmp<pdjt->outs_count;tmp++) {
@@ -41,7 +42,6 @@ t_int *pdj_tilde_perform(t_int *w) {
}
/* copy buffer out */
- work = i + 3;
for (i=0;i<pdjt->outs_count;i++) {
t_sample *out = (t_sample *)(w[work+i]);
(*env)->GetFloatArrayRegion(env, pdjt->outs[i], 0, sz, out);
diff --git a/src/type_handler.c b/src/type_handler.c
index 7089a31..0c7bc67 100644
--- a/src/type_handler.c
+++ b/src/type_handler.c
@@ -4,7 +4,7 @@
int jatom2atom(JNIEnv *env, jobject jatom, t_atom *atom) {
int type = (*env)->GetIntField(env, jatom, pdjCaching.FIDAtom_type);
- const jbyte *symbolValue;
+ const char *symbolValue;
jstring value;
switch(type) {
@@ -121,7 +121,7 @@ jobjectArray atoms2jatoms(JNIEnv *env, int argc, t_atom *argv) {
t_symbol *jstring2symbol(JNIEnv *env, jstring strvalue) {
- const jbyte *tmp = (*env)->GetStringUTFChars(env, strvalue, NULL);
+ const char *tmp = (*env)->GetStringUTFChars(env, strvalue, NULL);
t_symbol *value;
JASSERT(tmp);