summaryrefslogtreecommitdiff
path: root/demos
diff options
context:
space:
mode:
authorEthan Vrhel <ethanvrhel@gmail.com>2021-11-12 15:45:55 -0800
committerEthan Vrhel <ethanvrhel@gmail.com>2021-11-12 15:47:52 -0800
commit7db1ae4245a2ec37ae256f11b96e50ebb2dc9f45 (patch)
tree52af9fabff87d529eb6afa3528abce158c8aa076 /demos
parente5197d3ae65e6b16012c4509000ff7efbb9e9d89 (diff)
downloadghostpdl-7db1ae4245a2ec37ae256f11b96e50ebb2dc9f45.tar.gz
Fixed an assertion failure in display callbacks
Diffstat (limited to 'demos')
-rw-r--r--demos/java/README.txt9
-rw-r--r--demos/java/jni/gs_jni/build_darwin.sh11
-rw-r--r--demos/java/jni/gs_jni/callbacks.cpp24
-rw-r--r--demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp54
-rw-r--r--demos/java/jni/gs_jni/instance_data.h3
5 files changed, 89 insertions, 12 deletions
diff --git a/demos/java/README.txt b/demos/java/README.txt
index 4781bb099..3e94a920c 100644
--- a/demos/java/README.txt
+++ b/demos/java/README.txt
@@ -6,3 +6,12 @@ variable. This exposes command line programs to build Java
applications.
On Linux and Mac, OpenJDK 8 is used.
+
+What's in this directory:
+
+./gsjava The Java project which provides the bindings to Ghostscript.
+./gstest An old project used for testing gsjava
+./gsviewer A demo Java PDF viewer made using the Java bindings
+./jni Contains the C++ project which backs the Java bindings to Ghostscript
+./mtdemo A demo project used to demonstrate how multithreading can be used with
+ the Java bindings \ No newline at end of file
diff --git a/demos/java/jni/gs_jni/build_darwin.sh b/demos/java/jni/gs_jni/build_darwin.sh
index 81b10c019..18e12caeb 100644
--- a/demos/java/jni/gs_jni/build_darwin.sh
+++ b/demos/java/jni/gs_jni/build_darwin.sh
@@ -46,6 +46,16 @@ g++ -c -Wall -O3 -fPIC \
"jni_util.cpp" \
-o "obin/jni_util.o"
+echo "Compile instance_data.cpp"
+g++ -c -Wall -O3 -fPIC \
+ -std=c++14 \
+ -I./include \
+ -I./include/darwin \
+ -I./../../../../psi \
+ -I./../../../../devices \
+ "instance_data.cpp" \
+ -o "obin/instance_data.o"
+
echo "Link"
g++ -dynamiclib -fPIC \
-Wl \
@@ -54,4 +64,5 @@ g++ -dynamiclib -fPIC \
"obin/com_artifex_gsjava_GSAPI.o" \
"obin/com_artifex_gsjava_util_NativePointer.o" \
"obin/jni_util.o" \
+ "obin/instance_data.o" \
"../../../../sobin/libgpdl.dylib" \ No newline at end of file
diff --git a/demos/java/jni/gs_jni/callbacks.cpp b/demos/java/jni/gs_jni/callbacks.cpp
index fa2f54b75..2d0da54ed 100644
--- a/demos/java/jni/gs_jni/callbacks.cpp
+++ b/demos/java/jni/gs_jni/callbacks.cpp
@@ -175,6 +175,8 @@ int callbacks::calloutFunction(void *instance, void *handle, const char *deviceN
jsize len = (jsize)strlen(deviceName);
jbyteArray array = gsdata->env->NewByteArray(len);
gsdata->env->SetByteArrayRegion(array, 0, len, (const jbyte *)deviceName);
+
+ // TODO: gsdata->callerHandle is not consistent with the specification for a callout
code = callIntMethod(gsdata->env, gsdata->callout, "onCallout", "(JJ[BIIJ)I", (jlong)instance, (jlong)gsdata->callerHandle, array, id, size, (jlong)data);
}
return code;
@@ -192,7 +194,7 @@ int callbacks::display::displayOpenFunction(void *handle, void *device)
jclass clazz = gsdata->env->GetObjectClass(gsdata->displayCallback);
const char *name = getClassName(gsdata->env, clazz);
freeClassName(name);
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayOpen", DISPLAY_OPEN_SIG, (jlong)gsdata->callerHandle, (jlong)device);
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayOpen", DISPLAY_OPEN_SIG, (jlong)gsdata->displayHandle, (jlong)device);
CHECK_AND_RETURN(gsdata->env);
}
return code;
@@ -207,7 +209,7 @@ int callbacks::display::displayPrecloseFunction(void *handle, void *device)
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPreclose", DISPLAY_PRECLOSE_SIG, (jlong)gsdata->callerHandle, (jlong)device);
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPreclose", DISPLAY_PRECLOSE_SIG, (jlong)gsdata->displayHandle, (jlong)device);
CHECK_AND_RETURN(gsdata->env);
}
return code;
@@ -222,7 +224,7 @@ int callbacks::display::displayCloseFunction(void *handle, void *device)
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayClose", DISPLAY_CLOSE_SIG, (jlong)gsdata->callerHandle, (jlong)device);
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayClose", DISPLAY_CLOSE_SIG, (jlong)gsdata->displayHandle, (jlong)device);
CHECK_AND_RETURN(gsdata->env);
}
return code;
@@ -237,7 +239,7 @@ int callbacks::display::displayPresizeFunction(void *handle, void *device, int w
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPresize", DISPLAY_PRESIZE_SIG, (jlong)gsdata->callerHandle,
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPresize", DISPLAY_PRESIZE_SIG, (jlong)gsdata->displayHandle,
(jlong)device, width, height, raster, (jint)format);
CHECK_AND_RETURN(gsdata->env);
}
@@ -300,7 +302,7 @@ int callbacks::display::displaySizeFunction(void *handle, void *device, int widt
gsdata->env->SetLongField(bytePointer, dataPtrID, (jlong)pimage);
gsdata->env->SetLongField(bytePointer, lengthID, len);
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySize", DISPLAY_SIZE_SIG, (jlong)gsdata->callerHandle,
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySize", DISPLAY_SIZE_SIG, (jlong)gsdata->displayHandle,
(jlong)device, width, height, raster, (jint)format, bytePointer);
CHECK_AND_RETURN(gsdata->env);
}
@@ -316,7 +318,7 @@ int callbacks::display::displaySyncFunction(void *handle, void *device)
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySync", DISPLAY_SYNC_SIG, (jlong)gsdata->callerHandle, (jlong)device);
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySync", DISPLAY_SYNC_SIG, (jlong)gsdata->displayHandle, (jlong)device);
CHECK_AND_RETURN(gsdata->env);
}
return code;
@@ -331,7 +333,7 @@ int callbacks::display::displayPageFunction(void *handle, void *device, int copi
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPage", DISPLAY_PAGE_SIG, (jlong)gsdata->callerHandle,
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPage", DISPLAY_PAGE_SIG, (jlong)gsdata->displayHandle,
(jlong)device, copies, flush);
CHECK_AND_RETURN(gsdata->env);
}
@@ -347,7 +349,7 @@ int callbacks::display::displayUpdateFunction(void *handle, void *device, int x,
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayUpdate", DISPLAY_UPDATE_SIG, (jlong)gsdata->callerHandle,
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayUpdate", DISPLAY_UPDATE_SIG, (jlong)gsdata->displayHandle,
(jlong)device, x, y, w, h);
CHECK_AND_RETURN(gsdata->env);
}
@@ -367,7 +369,7 @@ int callbacks::display::displaySeparationFunction(void *handle, void *device, in
jsize len = (jsize)strlen(componentName);
jbyteArray byteArray = gsdata->env->NewByteArray(len);
gsdata->env->SetByteArrayRegion(byteArray, 0, len, (const jbyte *)componentName);
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySeparation", DISPLAY_SEPARATION_SIG, (jlong)gsdata->callerHandle,
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySeparation", DISPLAY_SEPARATION_SIG, (jlong)gsdata->displayHandle,
(jlong)device, component, byteArray, c, m, y, k);
CHECK_AND_RETURN(gsdata->env);
}
@@ -384,7 +386,7 @@ int callbacks::display::displayAdjustBandHeightFunction(void *handle, void *devi
if (gsdata->env && gsdata->displayCallback)
{
code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayAdjustBandHeght", DISPLAY_ADJUST_BAND_HEIGHT_SIG,
- (jlong)gsdata->callerHandle, (jlong)device, bandHeight);
+ (jlong)gsdata->displayHandle, (jlong)device, bandHeight);
CHECK_AND_RETURN(gsdata->env);
}
return code;
@@ -411,7 +413,7 @@ int callbacks::display::displayRectangleRequestFunction(void *handle, void *devi
Reference hRef = Reference(gsdata->env, toWrapperType(gsdata->env, (jint)*h));
code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayRectangleRequest", DISPLAY_RECTANGLE_REQUEST,
- (jlong)gsdata->callerHandle,
+ (jlong)gsdata->displayHandle,
(jlong)device,
memoryRef.object(),
oxRef.object(),
diff --git a/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp
index c5b809481..1a045b948 100644
--- a/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp
+++ b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp
@@ -5,6 +5,7 @@
#include <string.h>
#include <memory>
#include <assert.h>
+#include <string>
#include "jni_util.h"
#include "callbacks.h"
@@ -14,6 +15,8 @@ using namespace util;
static void *getAsPointer(JNIEnv *env, jobject object, gs_set_param_type type, bool *success);
+static void storeDispalyHandle(GSInstanceData *idata);
+
JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1revision
(JNIEnv *env, jclass, jobject revision, jint len)
{
@@ -40,7 +43,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1new_1instance
GSInstanceData *idata = new GSInstanceData();
idata->callerHandle = (void *)callerHandle;
- void *gsInstance;
+ void *gsInstance = NULL;
int code = gsapi_new_instance(&gsInstance, idata);
if (code == 0)
Reference::setValueField(env, instance, toWrapperType(env, (jlong)gsInstance));
@@ -79,6 +82,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio_1with_1ha
callbacks::setJNIEnv(idata, env);
callbacks::setIOCallbacks(idata, stdIn, stdOut, stdErr);
}
+
return code;
}
@@ -97,6 +101,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio
callbacks::setJNIEnv(idata, env);
callbacks::setIOCallbacks(idata, stdIn, stdOut, stdErr);
}
+
return code;
}
@@ -136,6 +141,9 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1display_1callba
GSInstanceData *idata = findDataFromInstance((void *)instance);
assert(idata);
+ if (idata->hasinit && idata->displayCallback)
+ storeDispalyHandle(idata);
+
display_callback *cb = new display_callback;
cb->size = sizeof(display_callback);
cb->version_major = DISPLAY_VERSION_MAJOR;
@@ -241,6 +249,9 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1init_1with_1args
callbacks::setJNIEnv(idata, env);
int code = gsapi_init_with_args((void *)instance, argc, cargv);
delete2DByteArray(argc, cargv);
+
+ idata->hasinit = true;
+ storeDispalyHandle(idata);
return code;
}
@@ -654,3 +665,44 @@ void *getAsPointer(JNIEnv *env, jobject object, gs_set_param_type type, bool *su
}
return result;
}
+
+void storeDispalyHandle(GSInstanceData *idata)
+{
+ static const char PARAM_NAME[] = "DisplayHandle";
+
+ char *param = NULL;
+ int bytes = gsapi_get_param(idata->instance, PARAM_NAME, NULL, gs_spt_string);
+ if (bytes == com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINED)
+ idata->displayCallback = NULL;
+ else
+ {
+ // Parse the DisplayHandle string again
+
+ param = new char[bytes];
+ gsapi_get_param(idata->instance, PARAM_NAME, param, gs_spt_string);
+
+ char *toparse = param;
+
+ int radix = 10; // default base 10
+
+ // If there is a # character, we need to change the radix
+ char *rend = strchr(param, '#');
+ if (rend)
+ {
+ *rend = 0;
+ radix = atoi(param);
+ toparse = rend + 1;
+ }
+
+ char *end;
+ long long val = std::strtoll(toparse, &end, radix);
+
+ idata->displayHandle = (void *)val;
+
+ delete[] param;
+ }
+
+ char buf[20]; // 16#[16 hex digits][null terminator]
+ sprintf_s(buf, "16#%llx", (long long)idata);
+ gsapi_set_param(idata->instance, PARAM_NAME, buf, gs_spt_string);
+}
diff --git a/demos/java/jni/gs_jni/instance_data.h b/demos/java/jni/gs_jni/instance_data.h
index 94422a672..2b2afe2e6 100644
--- a/demos/java/jni/gs_jni/instance_data.h
+++ b/demos/java/jni/gs_jni/instance_data.h
@@ -13,6 +13,7 @@ public:
void *instance = NULL; // The Ghostscript instance
void *callerHandle = NULL; // The caller handle passed to gsapi_new_instance
void *stdioHandle = NULL; // The caller handle passed to gsapi_set_stdio_with_handle
+ void *displayHandle = NULL; // The handle passed to display callbacks
JNIEnv *env = NULL; // The JNIEnv which should be used for JNI API calls
@@ -25,6 +26,8 @@ public:
jobject displayCallback = NULL; // The user DisplayCallback class
jobject callout = NULL; // The user ICalloutFunction class
+
+ bool hasinit = false; // Whether the user has called init_with_args
};
GSInstanceData *putInstanceData(GSInstanceData *data);