diff options
author | Thomas Deutschmann <whissi@gentoo.org> | 2021-03-30 10:59:39 +0200 |
---|---|---|
committer | Thomas Deutschmann <whissi@gentoo.org> | 2021-04-01 00:04:14 +0200 |
commit | 5ff1d6955496b3cf9a35042c9ac35db43bc336b1 (patch) | |
tree | 6d470f7eb448f59f53e8df1010aec9dad8ce1f72 /demos/java | |
parent | Import Ghostscript 9.53.1 (diff) | |
download | ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.tar.gz ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.tar.bz2 ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.zip |
Import Ghostscript 9.54ghostscript-9.54
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Diffstat (limited to 'demos/java')
87 files changed, 19340 insertions, 0 deletions
diff --git a/demos/java/gsjava/.classpath b/demos/java/gsjava/.classpath new file mode 100644 index 00000000..0cbf9cda --- /dev/null +++ b/demos/java/gsjava/.classpath @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/demos/java/gsjava/.project b/demos/java/gsjava/.project new file mode 100644 index 00000000..45e10ae9 --- /dev/null +++ b/demos/java/gsjava/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>gsjava</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/demos/java/gsjava/README.txt b/demos/java/gsjava/README.txt new file mode 100644 index 00000000..07c55675 --- /dev/null +++ b/demos/java/gsjava/README.txt @@ -0,0 +1,149 @@ +Required libraries for this library: +gpdldll64.dll +gs_jni.dll + +Java Library: + +This library contains direct bindings to Ghostscript as +well as several utility methods to make using the +Ghostscript calls easier. + +The direct Ghostscript calls are found in +com.artifex.gsjava.GSAPI and are named in the same way +in which they are documented on https://www.ghostscript.com/doc/current/API.htm + +The com.artifex.gsjava.callbacks package contains +interfaces which store interfaces and abstract classes +used to implement Ghostscript callbacks in Java. These +can be passed to Ghostscript through the GSAPI class. + +The com.artifex.gsjava.util package contains several +classes to assist in passing parameters and handling +native values. The Reference<T> and ByteArrayReference are +the only classes which need to be used, however the others +are avaliable if needed. The Reference class acts as +a pointer parameter in a C function. An example use of this +is in gsapi_new_instance which takes a Reference<Long> as +a parameter. Calling the method would place the new +Ghoscript instance in the Reference<Long>'s value field. + +The com.artifex.gsjava.GSInstance is a +utility class. The GSInstance class stores an instance +of Ghostscript and a client handle. The methods in this +class are named the same in which they are documented without +the need to pass the "instance" parameter through. + +The com.artifex.gsjava.devices package contains several +classes representing Ghoscript devices. Using the classes +in this package is the greatest amount of separation from +using the raw Ghoscript calls and it requires no direct +calls through the GSAPI class. All device classes in this +package are extensions of Device which provides a way +of setting up a Ghoscript device and setting parameters. +Subclasses have utility methods to set individual parameters +through method calls instead of using a String and parameter +type to specify the parameter name and type, respectively. + +Example code segment to set up an instance of Ghoscript: + +import com.artifex.gsjava.*; +import com.artifex.gsjava.util.*; + +public static void main(String[] args) { + // Stores a reference to the Ghoscript instance + Reference<Long> instanceReference = new Reference<>(); + + // Creates a new Ghoscript instance with a NULL caller handle, + // placing the instance into instanceReference + int code = GSAPI.gsapi_new_instance(instanceReference, GSAPI.GS_NULL); + + if (code != GSAPI.GS_ERROR_OK) { + // An error has occured. + return; + } + + // Returns the value the instanceReference references. + // This value is equivalent to a void * and has the same + // size in bytes. + long instance = instanceReference.getValue(); + + // Deletes the Ghoscript instance + GSAPI.gsapi_delete_instance(instance); +} + +C++ Library: + +This library builds to gs_jni.dll and uses the +Java Native Interface (JNI) to bind the functions in +the GSAPI class to Ghoscript as well as handling callbacks, +exceptions, and references. + +The bindings in GSAPI are in the header com_artifex_gsjava_GSJAVA.h +and the implementations are in com_artifex_gsjava_GSJAVA.cpp. + +Utility methods for throwing exceptions, setting fields, calling +Java methods, and using the Reference<T> class are declared +in jni_util.h. + +Example method explaining the implementation for +gsapi_run_string_begin: + + +/* JNIEnv *env - Provided the JNI. Allows interfacing into calling Java methods, + * setting Java fields, etc. Different threads have different JNIEnv objects. + * + * jclass - Provided by the JNI. It represents the class calling this method. + * + * jlong instance - Instance to be passed to gsapi_run_string_begin + * + * jint userErrors - User errors to be passed to gsapi_run_string_begin + * + * jobject pExitCode - A Reference<Integer> object. This is always the case as the Java + * code will not allow anything else to be passed. The value which Ghostscript returns + * in the pExitCode parameter will be placed into here. + */ +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1begin + (JNIEnv *env, jclass, jlong instance, jint userErrors, jobject pExitCode) +{ + // Declares the exitCode parameter which will be passed as a pointer + // to gsapi_run_string_begin + int exitCode; + + // Different threads have different JNIEnv objects, so each time a JNI method + // is called, this must be set so the Java callback methods can be called. + callbacks::setJNIEnv(env); + + // Calls the Ghoscript call gsapi_run_string_begin + int code = gsapi_run_string_begin((void *)instance, userErrors, &exitCode); + + // If the reference is not NULL, set the value of the reference to the exitCode returned + // from Ghoscript. It must be converted to the wrapper type java.lang.Integer as Java does not support + // primitive generic arguments (i.e. int, float, char, etc.) + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + + // Return the error code returned by Ghostscript + return code; +} + +Viewer: + +There is an eclipse project containing a viewer using the +Java Ghostscript bindings in gsjava. The eclipse project is +set up such that the gsjava eclipse project must be built +to a jar file and used in the gsviewer eclipse project. + +The viewer is designed to load PDF documents, but can also +load other files like PostScript files and distill them into +a PDF document to be opened. + +When the document is first loaded, every page is rendered at +a low resolution. These will be displayed as thumbnails on the +left side. All loadingg is done in the com.artifex.gsjava.Document +class. As the user changes the position of the viewport, the +viewer will dynamically load high resolution images based on +what page the user is viewing. This is done in the +com.artifex.gsviewer.ViewerController.SmartLoader class. This +also handles rendering zoomed images if necessary. Only pages +which need to be loaded at a high resolution are loaded, and +zoomed pages are unloaded when no longer necessary to save memory.
\ No newline at end of file diff --git a/demos/java/gsjava/src/com/artifex/gsjava/GSAPI.java b/demos/java/gsjava/src/com/artifex/gsjava/GSAPI.java new file mode 100644 index 00000000..f275e417 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/GSAPI.java @@ -0,0 +1,284 @@ +package com.artifex.gsjava; + +import java.util.List; + +import com.artifex.gsjava.callbacks.DisplayCallback; +import com.artifex.gsjava.callbacks.ICalloutFunction; +import com.artifex.gsjava.callbacks.IPollFunction; +import com.artifex.gsjava.callbacks.IStdErrFunction; +import com.artifex.gsjava.callbacks.IStdInFunction; +import com.artifex.gsjava.callbacks.IStdOutFunction; +import com.artifex.gsjava.util.Reference; +import com.artifex.gsjava.util.StringUtil; + +/** + * Class which contains native bindings to Ghostscript via the JNI. + * + * @author Ethan Vrhel + * + */ +public class GSAPI { + + static { + registerLibraries(); + } + + /** + * Registers the needed native libraries. + */ + private static void registerLibraries() { + System.loadLibrary("gs_jni"); + } + + /** + * NULL + */ + public static final long GS_NULL = 0L; + + /** + * Error codes + */ + public static final int GS_ERROR_OK = 0, + GS_ERROR_UNKNOWNERROR = -1, + GS_ERROR_DICTFULL = -2, + GS_ERROR_DICTSTACKOVERFLOW = -3, + GS_ERROR_DICTSTACKUNDERFLOW = -4, + GS_ERROR_EXECSTACKOVERFLOW = -5, + GS_ERROR_INTERRUPT = -6, + GS_ERROR_INVALIDACCESS = -7, + GS_ERROR_INVALIDEXIT = -8, + GS_ERROR_INVALIDFILEACCESS = -9, + GS_ERROR_INVALIDFONT = -10, + GS_ERROR_INVALIDRESTORE = -11, + GS_ERROR_IOERROR = -12, + GS_ERROR_LIMITCHECK = -13, + GS_ERROR_NOCURRENTPOINT = -14, + GS_ERROR_RANGECHECK = -15, + GS_ERROR_STACKOVERFLOW = -16, + GS_ERROR_STACKUNDERFLOW = -17, + GS_ERROR_SYNTAXERROR = -18, + GS_ERROR_TIMEOUT = -19, + GS_ERROR_TYPECHECK = -20, + GS_ERROR_UNDEFINED = -21, + GS_ERROR_UNDEFINEDFILENAME = -22, + GS_ERROR_UNDEFINEDRESULT = -23, + GS_ERROR_UNMATCHEDMARK = -24, + GS_ERROR_VMERROR = -25; + + /** + * Error codes + */ + public static final int GS_ERROR_CONFIGURATION_ERROR = -26, + GS_ERROR_UNDEFINEDRESOURCE = -27, + GS_ERROR_UNREGISTERED = -28, + GS_ERROR_INVALIDCONTEXT = -29, + GS_ERROR_INVALID = -30; + + public static final int GS_COLORS_NATIVE = (1 << 0), + GS_COLORS_GRAY = (1 << 1), + GS_COLORS_RGB = (1 << 2), + GS_COLORS_CMYK = (1 << 3), + GS_DISPLAY_COLORS_SEPARATION = (1 << 19); + + public static final long GS_DISPLAY_COLORS_MASK = 0x8000fL; + + public static final int GS_DISPLAY_ALPHA_NONE = (0 << 4), + GS_DISPLAY_ALPHA_FIRST = (1 << 4), + GS_DISPLAY_ALPHA_LAST = (1 << 5), + GS_DISPLAY_UNUSED_FIRST = (1 << 6), + GS_DISPLAY_UNUSED_LAST = (1 << 7); + + public static final long GS_DISPLAY_ALPHA_MASK = 0x00f0L; + + public static final int GS_DISPLAY_DEPTH_1 = (1 << 8), + GS_DISPLAY_DEPTH_2 = (1 << 9), + GS_DISPLAY_DEPTH_4 = (1 << 10), + GS_DISPLAY_DEPTH_8 = (1 << 11), + GS_DISPLAY_DEPTH_12 = (1 << 12), + GS_DISPLAY_DEPTH_16 = (1 << 3); + + public static final long GS_DISPLAY_DEPTH_MASK = 0xff00L; + + public static final int GS_DISPLAY_BIGENDIAN = (0 << 16), + GS_DISPLAY_LITTLEENDIAN = (1 << 16); + + public static final long GS_DISPLAY_ENDIAN_MASK = 0x00010000L; + + public static final int GS_DISPLAY_TOPFIRST = (0 << 17), + GS_DISPLAY_BOTTOMFIRST = (1 << 17); + + public static final long GS_DISPLAY_FIRSTROW_MASK = 0x00020000L; + + public static final int GS_SPT_INVALID = -1, + GS_SPT_NULL = 0, + GS_SPT_BOOL = 1, + GS_SPT_INT = 2, + GS_SPT_FLOAT = 3, + GS_SPT_NAME = 4, + GS_SPT_STRING = 5, + GS_SPT_LONG = 6, + GS_SPT_I64 = 7, + GS_SPT_SIZE_T = 8, + GS_SPT_PARSED = 9, + GS_SPT_MORE_TO_COME = 1 << 31; + + /** + * Class used to store version information about Ghostscript. + * + * @author Ethan Vrhel + * + */ + public static class Revision { + public volatile byte[] product; + public volatile byte[] copyright; + public volatile long revision; + public volatile long revisionDate; + + public Revision() { + this.product = null; + this.copyright = null; + this.revision = 0L; + this.revisionDate = 0L; + } + + /** + * Returns the product information as a String. + * + * @return The product information. + */ + public String getProduct() { + return new String(product); + } + + /** + * Returns the copyright information as a String. + * + * @return The copyright information. + */ + public String getCopyright() { + return new String(copyright); + } + } + + // Don't let this class be instantiated + private GSAPI() { } + + public static native int gsapi_revision(GSAPI.Revision revision, int len); + + public static native int gsapi_new_instance(Reference<Long> instance, long callerHandle); + + public static native void gsapi_delete_instance(long instance); + + public static native int gsapi_set_stdio_with_handle(long instance, IStdInFunction stdin, + IStdOutFunction stdout, IStdErrFunction stderr, long callerHandle); + + public static native int gsapi_set_stdio(long instance, IStdInFunction stdin, IStdOutFunction stdout, + IStdErrFunction stderr); + + public static native int gsapi_set_poll_with_handle(long instance, IPollFunction pollfun, long callerHandle); + + public static native int gsapi_set_poll(long instance, IPollFunction pollfun); + + public static native int gsapi_set_display_callback(long instance, DisplayCallback displayCallback); + + public static native int gsapi_register_callout(long instance, ICalloutFunction callout, long calloutHandle); + + public static native void gsapi_deregister_callout(long instance, ICalloutFunction callout, long calloutHandle); + + public static native int gsapi_set_arg_encoding(long instance, int encoding); + + public static native int gsapi_set_default_device_list(long instance, byte[] list, int listlen); + + public static native int gsapi_get_default_device_list(long instance, Reference<byte[]> list, Reference<Integer> listlen); + + public static native int gsapi_init_with_args(long instance, int argc, byte[][] argv); + + public static native int gsapi_run_string_begin(long instance, int userErrors, Reference<Integer> pExitCode); + + public static native int gsapi_run_string_continue(long instance, byte[] str, int length, int userErrors, + Reference<Integer> pExitCode); + + public static native int gsapi_run_string_end(long instance, int userErrors, Reference<Integer> pExitCode); + + public static native int gsapi_run_string_with_length(long instance, byte[] str, int length, int userErrors, + Reference<Integer> pExitCode); + + public static native int gsapi_run_string(long instance, byte[] str, int userErrors, Reference<Integer> pExitCode); + + public static native int gsapi_run_file(long instance, byte[] fileName, int userErrors, Reference<Integer> pExitCode); + + public static native int gsapi_exit(long instance); + + public static native int gsapi_set_param(long instance, byte[] param, Object value, int paramType); + + public static native int gsapi_get_param(long instance, byte[] param, long value, int paramType); + + public static native int gsapi_get_param_once(long instance, byte[] param, Reference<?> value, int paramType); + + public static native int gsapi_enumerate_params(long instance, Reference<Long> iter, Reference<byte[]> key, Reference<Integer> paramType); + + public static native int gsapi_add_control_path(long instance, int type, byte[] path); + + public static native int gsapi_remove_control_path(long instance, int type, byte[] path); + + public static native void gsapi_purge_control_paths(long instance, int type); + + public static native void gsapi_activate_path_control(long instance, boolean enable); + + public static native boolean gsapi_is_path_control_active(long instance); + + // Utility methods to make calling some native methods easier + + public static int gsapi_init_with_args(long instance, String[] argv) { + return gsapi_init_with_args(instance, argv.length, StringUtil.to2DByteArray(argv)); + } + + public static int gsapi_init_with_args(long instance, List<String> argv) { + return gsapi_init_with_args(instance, argv.toArray(new String[argv.size()])); + } + + public static int gsapi_run_string_continue(long instance, String str, int length, int userErrors, + Reference<Integer> pExitCode) { + return gsapi_run_string_continue(instance, StringUtil.toNullTerminatedByteArray(str.substring(0, length)), + length, userErrors, pExitCode); + } + + public static int gsapi_run_string_with_length(long instance, String str, int length, int userErrors, + Reference<Integer> pExitCode) { + return gsapi_run_string_with_length(instance, StringUtil.toNullTerminatedByteArray(str.substring(0, length)), + length, userErrors, pExitCode); + } + + public static int gsapi_run_string(long instance, String str, int userErrors, Reference<Integer> pExitCode) { + return gsapi_run_string(instance, StringUtil.toNullTerminatedByteArray(str), userErrors, pExitCode); + } + + public static int gsapi_run_file(long instance, String fileName, int userErrors, Reference<Integer> pExitCode) { + return gsapi_run_file(instance, StringUtil.toNullTerminatedByteArray(fileName), userErrors, pExitCode); + } + + public static int gsapi_set_param(long instnace, String param, String value, int paramType) { + return gsapi_set_param(instnace, StringUtil.toNullTerminatedByteArray(param), + StringUtil.toNullTerminatedByteArray(value), paramType); + } + + public static int gsapi_set_param(long instnace, String param, Object value, int paramType) { + return gsapi_set_param(instnace, StringUtil.toNullTerminatedByteArray(param), value, paramType); + } + + public static int gsapi_get_param(long instance, String param, long value, int paramType) { + return gsapi_get_param(instance, StringUtil.toNullTerminatedByteArray(param), value, paramType); + } + + public static int gsapi_get_param_once(long instance, String param, Reference<?> value, int paramType) { + return gsapi_get_param_once(instance, StringUtil.toNullTerminatedByteArray(param), value, paramType); + } + + public static int gsapi_add_control_path(long instance, int type, String path) { + return gsapi_add_control_path(instance, type, StringUtil.toNullTerminatedByteArray(path)); + } + + public static int gsapi_remove_control_path(long instance, int type, String path) { + return gsapi_remove_control_path(instance, type, StringUtil.toNullTerminatedByteArray(path)); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/GSInstance.java b/demos/java/gsjava/src/com/artifex/gsjava/GSInstance.java new file mode 100644 index 00000000..e5e713c7 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/GSInstance.java @@ -0,0 +1,320 @@ +package com.artifex.gsjava; + +import static com.artifex.gsjava.GSAPI.*; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import com.artifex.gsjava.callbacks.DisplayCallback; +import com.artifex.gsjava.callbacks.ICalloutFunction; +import com.artifex.gsjava.callbacks.IPollFunction; +import com.artifex.gsjava.callbacks.IStdErrFunction; +import com.artifex.gsjava.callbacks.IStdInFunction; +import com.artifex.gsjava.callbacks.IStdOutFunction; +import com.artifex.gsjava.util.ByteArrayReference; +import com.artifex.gsjava.util.Reference; + +/** + * Utility class to make Ghostscript calls easier by storing a + * Ghostscript instance and, optionally, a caller handle. + * + * @author Ethan Vrhel + * + */ +public class GSInstance implements Iterable<GSInstance.GSParam<?>> { + + public static class GSParam<V> { + + public final String key; + public final V value; + + public GSParam(String key, V value) { + this.key = key; + this.value = value; + } + + public GSParam(V value) { + this(null, value); + } + + public boolean canConvertToString() { + return value instanceof String || value instanceof byte[]; + } + + public String stringValue() { + if (value instanceof String) + return (String)value; + else if (value instanceof byte[]) + return new String((byte[])value); + throw new IllegalStateException("Value cannot be converted to string"); + } + + @Override + public String toString() { + return key + " -> " + (canConvertToString() ? stringValue() : value); + } + + @Override + public boolean equals(Object o) { + if (o == null) + return false; + if (o == this) + return true; + if (o instanceof GSParam) { + GSParam<?> other = (GSParam<?>)o; + return (key == null ? other.key == null : key.equals(other.key)) && + (value == null ? other.value == null : value.equals(other.value)); + } + return false; + } + + @Override + public int hashCode() { + return key.hashCode() + (value == null ? 0 : value.hashCode()); + } + } + + private static volatile boolean instanceExists = false; + + private long instance; + private long callerHandle; + + public GSInstance(long callerHandle) throws IllegalStateException { + if (instanceExists) + throw new IllegalStateException("An instance already exists"); + Reference<Long> ref = new Reference<>(); + int ret = gsapi_new_instance(ref, callerHandle); + if (ret != GS_ERROR_OK) + throw new IllegalStateException("Failed to create new instance: " + ret); + this.instance = ref.getValue(); + this.callerHandle = callerHandle; + instanceExists = true; + } + + public GSInstance() throws IllegalStateException { + this(GS_NULL); + } + + public void delete_instance() { + if (instance != GS_NULL) + gsapi_delete_instance(instance); + instance = GS_NULL; + instanceExists = false; + } + + public int set_stdio(IStdInFunction stdin, IStdOutFunction stdout, IStdErrFunction stderr) { + return gsapi_set_stdio_with_handle(instance, stdin, stdout, stderr, callerHandle); + } + + public int set_poll(IPollFunction pollfun) { + return gsapi_set_poll_with_handle(instance, pollfun, callerHandle); + } + + public int set_display_callback(DisplayCallback displaycallback) { + return gsapi_set_display_callback(instance, displaycallback); + } + + public int register_callout(ICalloutFunction callout) { + return gsapi_register_callout(instance, callout, callerHandle); + } + + public void deregister_callout(ICalloutFunction callout) { + gsapi_deregister_callout(instance, callout, callerHandle); + } + + public int set_arg_encoding(int encoding) { + return gsapi_set_arg_encoding(instance, encoding); + } + + public int set_default_device_list(byte[] list, int listlen) { + return gsapi_set_default_device_list(instance, list, listlen); + } + + public int get_default_device_list(Reference<byte[]> list, Reference<Integer> listlen) { + return gsapi_get_default_device_list(instance, list, listlen); + } + + public int init_with_args(int argc, byte[][] argv) { + return gsapi_init_with_args(instance, argc, argv); + } + + public int init_with_args(String[] argv) { + return gsapi_init_with_args(instance, argv); + } + + public int init_with_args(List<String> argv) { + return gsapi_init_with_args(instance, argv); + } + + public int run_string_begin(int userErrors, Reference<Integer> pExitCode) { + return gsapi_run_string_begin(instance, userErrors, pExitCode); + } + + public int run_string_continue(byte[] str, int length, int userErrors, Reference<Integer> pExitCode) { + return gsapi_run_string_continue(instance, str, length, userErrors, pExitCode); + } + + public int run_string_continue(String str, int length, int userErrors, Reference<Integer> pExitCode) { + return gsapi_run_string_continue(instance, str, length, userErrors, pExitCode); + } + + public int run_string(byte[] str, int userErrors, Reference<Integer> pExitCode) { + return gsapi_run_string(instance, str, userErrors, pExitCode); + } + + public int run_string(String str, int userErrors, Reference<Integer> pExitCode) { + return gsapi_run_string(instance, str, userErrors, pExitCode); + } + + public int run_file(byte[] fileName, int userErrors, Reference<Integer> pExitCode) { + return gsapi_run_file(instance, fileName, userErrors, pExitCode); + } + + public int run_file(String filename, int userErrors, Reference<Integer> pExitCode) { + return gsapi_run_file(instance, filename, userErrors, pExitCode); + } + + public int exit() { + return gsapi_exit(instance); + } + + public int set_param(byte[] param, Object value, int paramType) { + return gsapi_set_param(instance, param, value, paramType); + } + + public int set_param(String param, String value, int paramType) { + return gsapi_set_param(instance, param, value, paramType); + } + + public int set_param(String param, Object value, int paramType) { + return gsapi_set_param(instance, param, value, paramType); + } + + public int get_param(byte[] param, long value, int paramType) { + return gsapi_get_param(instance, param, value, paramType); + } + + public int get_param(String param, long value, int paramType) { + return gsapi_get_param(instance, param, value, paramType); + } + + public int get_param_once(byte[] param, Reference<?> value, int paramType) { + return gsapi_get_param_once(instance, param, value, paramType); + } + + public int get_param_once(String param, Reference<?> value, int paramType) { + return gsapi_get_param_once(instance, param, value, paramType); + } + + public int enumerate_params(Reference<Long> iter, Reference<byte[]> key, Reference<Integer> paramType) { + return gsapi_enumerate_params(instance, iter, key, paramType); + } + + public int add_control_path(int type, byte[] path) { + return gsapi_add_control_path(instance, type, path); + } + + public int add_control_path(int type, String path) { + return gsapi_add_control_path(instance, type, path); + } + + public int remove_control_path(int type, byte[] path) { + return gsapi_remove_control_path(instance, type, path); + } + + public int remove_control_path(int type, String path) { + return gsapi_remove_control_path(instance, type, path); + } + + public void purge_control_paths(int type) { + gsapi_purge_control_paths(instance, type); + } + + public void activate_path_control(boolean enable) { + gsapi_activate_path_control(instance, enable); + } + + public boolean is_path_control_active() { + return gsapi_is_path_control_active(instance); + } + + public GSParam<?>[] getParamArray() { + List<GSParam<?>> params = new LinkedList<>(); + for (GSParam<?> param : this) { + params.add(param); + } + return params.toArray(new GSParam<?>[params.size()]); + } + + @Override + public void finalize() { + if (instance != GS_NULL) { + exit(); + delete_instance(); + } + } + + @Override + public boolean equals(Object o) { + if (o == null) + return false; + if (o == this) + return true; + if (o instanceof GSInstance) { + GSInstance g = (GSInstance)o; + return g.instance == instance && g.callerHandle == callerHandle; + } + return false; + } + + @Override + public String toString() { + return "GSInstance[instance=0x" + Long.toHexString(instance) + "]"; + } + + @Override + public Iterator<GSParam<?>> iterator() { + return new ParamIterator(); + } + + private class ParamIterator implements Iterator<GSParam<?>> { + + private Reference<Long> iterator; + private ByteArrayReference key; + private Reference<Integer> valueType; + private Reference<?> value; + + private int returnCode; + + private ParamIterator() { + iterator = new Reference<>(0L); + key = new ByteArrayReference(); + valueType = new Reference<>(); + value = new Reference<>(); + } + + @Override + public boolean hasNext() { + long lastValue = iterator.getValue(); + returnCode = enumerate_params(iterator, null, null); + iterator.setValue(lastValue); + return returnCode != 1; + } + + @Override + public GSParam<?> next() { + if (returnCode != 0) + throw new IllegalStateException("Reached end of iterator"); + returnCode = enumerate_params(iterator, key, valueType); + if (returnCode < 0) + throw new IllegalStateException("Failed to enumerate params"); + + int code = get_param_once(key.getValue(), value, valueType.getValue()); + if (code != 0) + throw new IllegalStateException("Failed to get param"); + return new GSParam<>(key.asString(), value.getValue()); + } + + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/DisplayCallback.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/DisplayCallback.java new file mode 100644 index 00000000..f2f7e712 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/DisplayCallback.java @@ -0,0 +1,75 @@ +package com.artifex.gsjava.callbacks; + +import com.artifex.gsjava.util.BytePointer; +import com.artifex.gsjava.util.Reference; + +/** + * Class wrapping a display_callback structure. + * + * @author Ethan Vrhel + * + */ +public abstract class DisplayCallback { + + public volatile int size; + public volatile int versionMajor; + public volatile int versionMinor; + + public int onDisplayOpen(long handle, long device) { + return 0; + } + + public int onDisplayPreclose(long handle, long device) { + return 0; + } + + public int onDisplayClose(long handle, long device) { + return 0; + } + + public int onDisplayPresize(long handle, long device, int width, + int height, int raster, int format) { + return 0; + } + + public int onDisplaySize(long handle, long device, int width, + int height,int raster, int format, BytePointer pimage) { + return 0; + } + + public int onDisplaySync(long handle, long device) { + return 0; + } + + public int onDisplayPage(long handle, long device, int copies, boolean flush) { + return 0; + } + + public int onDisplayUpdate(long handle, long device, int x, int y, int w, int h) { + return 0; + } + + /* + public long onDisplayMemalloc(long handle, long device, long size) { + return GS_NULL; + } + + public int onDisplayMemfree(long handle, long device, long mem) { + return 0; + }*/ + + public int onDisplaySeparation(long handle, long device, int component, byte[] componentName, + short c, short m, short y, short k) { + return 0; + } + + public int onDisplayAdjustBandHeight(long handle, long device, int bandHeight) { + return 0; + } + + public int onDisplayRectangleRequest(long handle, long device, Reference<Long> memory, Reference<Integer> ox, + Reference<Integer> oy, Reference<Integer> raster, Reference<Integer> planeRaster, Reference<Integer> x, + Reference<Integer> y, Reference<Integer> w, Reference<Integer> h) { + return 0; + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/ICalloutFunction.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/ICalloutFunction.java new file mode 100644 index 00000000..9b163717 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/ICalloutFunction.java @@ -0,0 +1,7 @@ +package com.artifex.gsjava.callbacks; + +@FunctionalInterface +public interface ICalloutFunction { + + public int onCallout(long instance, long calloutHandle, byte[] deviceName, int id, int size, long data); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IPollFunction.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IPollFunction.java new file mode 100644 index 00000000..ae0f3b50 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IPollFunction.java @@ -0,0 +1,7 @@ +package com.artifex.gsjava.callbacks; + +@FunctionalInterface +public interface IPollFunction { + + public int onPoll(long callerHandle); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdErrFunction.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdErrFunction.java new file mode 100644 index 00000000..5001b9c5 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdErrFunction.java @@ -0,0 +1,15 @@ +package com.artifex.gsjava.callbacks; + +@FunctionalInterface +public interface IStdErrFunction { + + /** + * Called when something should be written to the standard error stream. + * + * @param callerHandle The caller handle. + * @param str The string to write. + * @param len The length of bytes to be written. + * @return The amount of bytes written, must be <code>len</code>. + */ + public int onStdErr(long callerHandle, byte[] str, int len); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdInFunction.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdInFunction.java new file mode 100644 index 00000000..c6d97e94 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdInFunction.java @@ -0,0 +1,15 @@ +package com.artifex.gsjava.callbacks; + +@FunctionalInterface +public interface IStdInFunction { + + /** + * + * + * @param callerHandle The caller handle. + * @param buf A string. + * @param len The number of bytes to read. + * @return The number of bytes read, must be <code>len</code>/ + */ + public int onStdIn(long callerHandle, byte[] buf, int len); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdOutFunction.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdOutFunction.java new file mode 100644 index 00000000..c3635f54 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdOutFunction.java @@ -0,0 +1,16 @@ +package com.artifex.gsjava.callbacks; + +@FunctionalInterface +public interface IStdOutFunction { + + /** + * Called when something should be written to the standard + * output stream. + * + * @param callerHandle The caller handle. + * @param str The string to write. + * @param len The number of bytes to write. + * @return The number of bytes written, must be <code>len</code>. + */ + public int onStdOut(long callerHandle, byte[] str, int len); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/BMPDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/BMPDevice.java new file mode 100644 index 00000000..2af8e7f1 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/BMPDevice.java @@ -0,0 +1,18 @@ +package com.artifex.gsjava.devices; + +public class BMPDevice extends FileDevice { + + public static final String BMPMONO = "bmpmono"; + public static final String BMPGRAY = "bmpgray"; + public static final String BMPSEP1 = "bmpsep1"; + public static final String BMPSEP8 = "bmpsep8"; + public static final String BMP16 = "bmp16"; + public static final String BMP256 = "bmp256"; + public static final String BMP16M = "bmp16m"; + public static final String BMP32B = "bmp32b"; + + public BMPDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/Device.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/Device.java new file mode 100644 index 00000000..74dc5332 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/Device.java @@ -0,0 +1,308 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +import java.awt.Dimension; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import com.artifex.gsjava.GSInstance; +import com.artifex.gsjava.callbacks.IStdErrFunction; +import com.artifex.gsjava.callbacks.IStdInFunction; +import com.artifex.gsjava.callbacks.IStdOutFunction; +import com.artifex.gsjava.util.Reference; + +/** + * <p>The <code>Device</code> class allows easier rendering to a Ghostscript device. + * The class allows setting different device parameters, running a file, and some + * safety with regard to Ghostcript instances. There can only be one instance of a + * <code>Device</code> at a time.</p> + * + * <p>Full documentation on each device can be found on the + * <a href=https://ghostscript.com/doc/current/Devices.htm>Details of Ghostscript Output Devices</a> + * webpage.</p> + * + * @author Ethan Vrhel + * + */ +public abstract class Device { + + private static Device activeDevice; // The active device, only one device may exist at a time + + private GSInstance instance; + private final String deviceName; + + /** + * Creates a new device with the given device name. When this constructor is called, + * an instance of Ghostscript cannot exist or an exception will be thrown. The check of + * whether an instance already exists does not include instances directly created + * through <code>GSAPI.gsapi_new_instance</code>. + * + * @param deviceName The name of the Ghostscript device. + * @throws DeviceNotSupportedException When <code>deviceName</code> is not a supported + * Ghostscript device. + * @throws DeviceInUseException When a <code>Device</code> object already exists. + * @throws IllegalStateException When an instance of Ghostscript created through <code>GSInstance</code> + * already exists. + */ + public Device(String deviceName) throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + if (activeDevice != null) + throw new DeviceInUseException(activeDevice); + GSInstance instance = new GSInstance(); + this.deviceName = Objects.requireNonNull(deviceName, "device name must be non-null"); + StdIO io = new StdIO(); + instance.set_stdio(io, io, io); + instance.init_with_args(new String[] { + "gs", + "-h", + }); + instance.exit(); + instance.delete_instance(); + if (!io.hasDevice) + throw new DeviceNotSupportedException(deviceName); + } + + /** + * Initializes the device on an instance with the given arguments. The + * given instance must not have had <code>init_with_args</code> called. + * + * @param instance The instance to initialize. + * @param more Arguments which should be passed to Ghostscript through + * <code>gsapi_init_with_args</code>. + */ + public void initWithInstance(GSInstance instance, String... more) { + if (this.instance != null) + throw new IllegalStateException("instance has already been initialized"); + this.instance = Objects.requireNonNull(instance, "Instance must be non-null"); + List<String> args = new ArrayList<>(2 + more.length); + args.add("gs"); + args.add("-sDEVICE=" + deviceName); + for (String s : more) { + args.add(s); + } + instance.init_with_args(args); + } + + /** + * Runs a file. + * + * @param file The file to run. + * @param userErrors The user errors. + * @param pExitCode The exit code. + * @return The result of the <code>run_file</code>. + */ + public int runFile(File file, int userErrors, Reference<Integer> pExitCode) { + return runFile(file.getAbsolutePath(), userErrors, pExitCode); + } + + /** + * Runs a file. + * + * @param file The file to run. + * @param userErrors The user errors. + * @param pExitCode The exit code. + * @return The result of the <code>run_file</code>. + */ + public int runFile(String filename, int userErrors, Reference<Integer> pExitCode) { + return instance.run_file(filename, userErrors, pExitCode); + } + + /** + * Returns the internal device name. This name is the same as the one provided + * by the user in the Device constructor. + * + * @return The internal device name. + */ + public String getInternalName() { + return deviceName; + } + + /** + * Destroys this device. + * + * @throws IllegalStateException When the instance of Ghostscript fails to + * exit. + */ + public void destroyDevice() throws IllegalStateException { + int code = instance.exit(); + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to exit"); + instance.delete_instance(); + activeDevice = null; + } + + /** + * Sets a device parameter. + * + * @param param The name of the device parameter. + * @param value The value to set the device parameter to. + * @param paramType The type of the device parameter. + * @return The result of setting the parameter through + * <code>gsapi_set_param</code>. + */ + public int setParam(String param, Object value, int paramType) { + return instance.set_param(param, value, paramType); + } + + /** + * Sets a string device parameter. + * + * @param param The name of the device parameter. + * @param value The string value to set the device parameter to. + * @param paramType The type of the device parameter. + * @return The result of setting the parameter through + * <code>gsapi_set_param</code>. + */ + public int setParam(String param, String value, int paramType) { + return instance.set_param(param, value, paramType); + } + + public int setResolution(Dimension resolution) { + return setResolution("[" + resolution.width + " " + resolution.height + "]"); + } + + public int setResolution(int resolution) { + return setResolution("[" + resolution + " " + resolution + "]"); + } + + public int setResolution(String resolution) { + return setParam("HWResolution", resolution, GS_SPT_PARSED); + } + + public int setColorScreen(boolean state) { + return setParam("COLORSCREEN", state, GS_SPT_BOOL); + } + + public int setDitherPPI(int lpi) { + return setParam("DITHERPPI", lpi, GS_SPT_INT); + } + + public int setInterpolateControl(int controlValue) { + return setParam("InterpolateControl", controlValue, GS_SPT_INT); + } + + public int setTextAlphaBits(int value) { + return setParam("TextAlphaBits", value, GS_SPT_INT); + } + + public int setGraphicsAlphaBits(int value) { + return setParam("GraphicsAlphaBits", value, GS_SPT_INT); + } + + public int setAlignToPixels(int n) { + return setParam("AlignToPixels", n, GS_SPT_INT); + } + + public int setGridFitTT(int n) { + return setParam("GridFitTT", n, GS_SPT_INT); + } + + public int setFirstPage(int page) { + return setParam("FirstPage", page, GS_SPT_INT); + } + + public int setLastPage(int page) { + return setParam("LastPage", page, GS_SPT_INT); + } + + public int setPageList(String list) { + return setParam("PageList", list, GS_SPT_PARSED); + } + + public int setORIENT1(boolean state) { + return setParam("ORIENT1", state, GS_SPT_BOOL); + } + + public int setDeviceWidthPoints(int w) { + return setParam("DEVICEWIDTHPOINTS", w, GS_SPT_INT); + } + + public int setDeviceHeightPoints(int h) { + return setParam("DEVICEHEIGHTPOINTS", h, GS_SPT_INT); + } + + public int setDefaultPaperSize(String paperSize) { + return setParam("DEFAULTPAPERSIZE", paperSize, GS_SPT_STRING); + } + + public int setFontMap(String files) { + return setParam("FONTMAP", files, GS_SPT_PARSED); + } + + public int setFontPath(String paths) { + return setParam("FONTPATH", paths, GS_SPT_PARSED); + } + + public int setSubstFont(String fontname) { + return setParam("SUBSTFONT", fontname, GS_SPT_STRING); + } + + public int setGenericResourceDir(String path) { + return setParam("FontResourceDir", path, GS_SPT_STRING); + } + + public int setStdout(String filename) { + return setParam("stdout", filename, GS_SPT_STRING); + } + + /** + * Returns the stored Ghostscript instance. + * + * @return The instance. + */ + protected final GSInstance getInstance() { + return instance; + } + + protected final String toArrayParameter(String[] array) { + StringBuilder builder = new StringBuilder(); + if (array.length > 0) { + builder.append(array[0]); + for (int i = 1; i < array.length; i++) { + builder.append(','); + builder.append(array[i]); + } + } + return builder.toString(); + } + + protected final String toArrayParameter(List<String> list) { + return toArrayParameter(list.toArray(new String[list.size()])); + } + + @Override + public String toString() { + return "Device[instance=" + instance + ",deviceName=" + deviceName + "]"; + } + + private class StdIO implements IStdInFunction, IStdOutFunction, IStdErrFunction { + + private boolean hasDevice; + + @Override + public int onStdIn(long callerHandle, byte[] buf, int len) { + return buf.length; + } + + @Override + public int onStdOut(long callerHandle, byte[] str, int len) { + if (!hasDevice) { + String outp = new String(str); + hasDevice = outp.contains(deviceName); + } + return str.length; + } + + @Override + public int onStdErr(long callerHandle, byte[] str, int len) { + if (!hasDevice) { + String outp = new String(str); + hasDevice = outp.contains(deviceName); + } + return str.length; + } + + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceInUseException.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceInUseException.java new file mode 100644 index 00000000..aa5621fc --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceInUseException.java @@ -0,0 +1,17 @@ +package com.artifex.gsjava.devices; + +public class DeviceInUseException extends Exception { + + private static final long serialVersionUID = 1L; + + private Device device; + + public DeviceInUseException(Device device) { + super(device == null ? "null" : device.toString()); + this.device = device; + } + + public Device getDevice() { + return device; + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceNotSupportedException.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceNotSupportedException.java new file mode 100644 index 00000000..453fdead --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceNotSupportedException.java @@ -0,0 +1,28 @@ +package com.artifex.gsjava.devices; + +public class DeviceNotSupportedException extends Exception { + + private static final long serialVersionUID = 1L; + + public DeviceNotSupportedException() { + super(); + } + + public DeviceNotSupportedException(String message) { + super(message); + } + + public DeviceNotSupportedException(Throwable cause) { + super(cause); + } + + public DeviceNotSupportedException(String message, Throwable cause) { + super(message, cause); + } + + protected DeviceNotSupportedException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/DisplayDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/DisplayDevice.java new file mode 100644 index 00000000..959ed4d8 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/DisplayDevice.java @@ -0,0 +1,55 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +import java.util.List; + +public class DisplayDevice extends Device { + + public static final String X11 = "x11"; + public static final String X11ALPHA = "x11alpha"; + public static final String X11CMYK = "x11cmyk"; + public static final String X11MONO = "x11mono"; + public static final String X11GRAY2 = "x11gray2"; + public static final String X11GRAY4 = "x11gray4"; + + public DisplayDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("display"); + } + + public DisplayDevice(String device) throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(device); + } + + public void setDisplayFormat(int format) { + setParam("DisplayFormat", format, GS_SPT_INT); + } + + public void setDisplayResolution(int dpi) { + setParam("DisplayResolution", dpi, GS_SPT_INT); + } + + public void setSeparationColorNames(String nameArray) { + setParam("SeparationColorNames", nameArray, GS_SPT_PARSED); + } + + public void setSeparationColorNames(String[] names) { + setSeparationColorNames(toArrayParameter(names)); + } + + public void setSeparationColorNames(List<String> names) { + setSeparationColorNames(toArrayParameter(names)); + } + + public void setSeparationOrder(String orderArray) { + setParam("SeparationOrder", orderArray, GS_SPT_PARSED); + } + + public void setSeparationOrder(String[] order) { + setSeparationOrder(toArrayParameter(order)); + } + + public void setSeparationOrder(List<String> order) { + setSeparationOrder(toArrayParameter(order)); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/EPSDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/EPSDevice.java new file mode 100644 index 00000000..efa999a1 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/EPSDevice.java @@ -0,0 +1,9 @@ +package com.artifex.gsjava.devices; + +public class EPSDevice extends PostScriptDevice { + + public EPSDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("eps2write"); + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/FAXDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/FAXDevice.java new file mode 100644 index 00000000..5770a8b4 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/FAXDevice.java @@ -0,0 +1,18 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class FAXDevice extends FileDevice { + + public static final String FAXG3 = "faxg3"; + public static final String FAXG32D = "faxg32d"; + public static final String FAXG4 = "faxg4"; + + public FAXDevice(String device) throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(device); + } + + public void setMinFeatureSize(int value) { + setParam("MinFeatureSize", value, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/FileDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/FileDevice.java new file mode 100644 index 00000000..9f3d6ce3 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/FileDevice.java @@ -0,0 +1,36 @@ +package com.artifex.gsjava.devices; + +import java.io.File; + +import com.artifex.gsjava.GSAPI; +import com.artifex.gsjava.GSInstance; + +public abstract class FileDevice extends Device { + + public FileDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + + public void initFileWithInstance(GSInstance instance, File file, String... more) { + initFileWithInstance(instance, file, more); + } + + public void setOutputFile(File file) { + setOutputFile(file.getAbsolutePath()); + } + + public void setOutputFile(String file) { + setParam("OutputFile", file, GSAPI.GS_SPT_STRING); + } + + public void initFileWithInstance(GSInstance instance, String file, String... more) { + String[] args = new String[2 + more.length]; + args[0] = "-o"; + args[1] = file; + for (int i = 0; i < more.length; i++) { + args[i + 2] = more[i]; + } + initWithInstance(instance, args); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/HighLevelDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/HighLevelDevice.java new file mode 100644 index 00000000..4a08d522 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/HighLevelDevice.java @@ -0,0 +1,13 @@ +package com.artifex.gsjava.devices; + +/** + * Interface indicating a device is a high-level device. + * See <a href=https://ghostscript.com/doc/current/VectorDevices.htm>High Level Output Devices</a> + * webpage for full documentation on each device. + * + * @author Ethan Vrhel + * + */ +public interface HighLevelDevice { + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/JPEGDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/JPEGDevice.java new file mode 100644 index 00000000..bf015349 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/JPEGDevice.java @@ -0,0 +1,19 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class JPEGDevice extends FileDevice { + + public JPEGDevice() + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super("jpeg"); + } + + public void setJPEGQuality(int quality) { + setParam("JPEGQ", quality, GSAPI.GS_SPT_INT); + } + + public void setQualityFactor(float scale) { + setParam("QFactor", scale, GSAPI.GS_SPT_FLOAT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/OCRDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/OCRDevice.java new file mode 100644 index 00000000..533714bf --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/OCRDevice.java @@ -0,0 +1,24 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class OCRDevice extends FileDevice { + + public static final int DEFAULT_ENGINE = 0; + public static final int LSTM_ENGINE = 1; + public static final int TESSERACT_ENGINE = 2; + public static final int LSTM_AND_TESSERACT_ENGINE = 3; + + public OCRDevice() + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super("ocr"); + } + + public void setOCRLanguage(String language) { + setParam("OCRLanguage", language, GSAPI.GS_SPT_PARSED); + } + + public void setOCREngine(int engine) { + setParam("OCREngine", engine, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PCXDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PCXDevice.java new file mode 100644 index 00000000..c0323e60 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PCXDevice.java @@ -0,0 +1,17 @@ +package com.artifex.gsjava.devices; + +public class PCXDevice extends FileDevice { + + public static final String PCXMONO = "pcxmono"; + public static final String PCXGRAY = "pcxgray"; + public static final String PCX16 = "pcx16"; + public static final String PCX256 = "pcx256"; + public static final String PCX24B = "pcx24b"; + public static final String PCXCMYK = "pcxcmyk"; + + public PCXDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFDevice.java new file mode 100644 index 00000000..2d084f71 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFDevice.java @@ -0,0 +1,90 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +public class PDFDevice extends PDFPostscriptDeviceFamily { + + public PDFDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("pdfwrite"); + } + + public void setMaxInlineImageSize(int value) { + setParam("MaxInlineImageSize", value, GS_SPT_INT); + } + + public void setDoNumCopies(boolean state) { + setParam("DoNumCopies", state, GS_SPT_BOOL); + } + + public void setDetectDuplicateImages(boolean state) { + setParam("DetectDuplicateImages", state, GS_SPT_BOOL); + } + + public void setFastWebView(boolean state) { + setParam("FastWebView", state, GS_SPT_BOOL); + } + + public void setPreserveAnnots(boolean state) { + setParam("PreserveAnnots", state, GS_SPT_BOOL); + } + + public void setPatternImagemask(boolean state) { + setParam("PatternImagemask", state, GS_SPT_BOOL); + } + + public void setMaxClipPathSize(int value) { + setParam("MaxClipPathSize", value, GS_SPT_INT); + } + + public void setMaxShadingBitmapSize(int value) { + setParam("MaxShadingBitmapSize", value, GS_SPT_INT); + } + + public void setHaveTrueTypes(boolean state) { + setParam("HaveTrueTypes", state, GS_SPT_BOOL); + } + + public void setHaveTransparency(boolean state) { + setParam("HaveTransparency", state, GS_SPT_BOOL); + } + + public void setPDFX(boolean state) { + setParam("PDFX", state, GS_SPT_BOOL); + } + + public void setOwnerPassword(String value) { + setParam("OwnerPassword", value, GS_SPT_STRING); + } + + public void setUserPassword(String value) { + setParam("UserPassword", value, GS_SPT_STRING); + } + + public void setPermissions(int value) { + setParam("Permissions", value, GS_SPT_INT); + } + + public void setEncryptionR(int num) { + setParam("EncryptionR", num, GS_SPT_INT); + } + + public void setKeyLength(int length) { + setParam("KeyLength", length, GS_SPT_INT); + } + + public void setDocumentUUID(String value) { + setParam("DocumentUUID", value, GS_SPT_STRING); + } + + public void setInstanceUUID(String value) { + setParam("InstanceUUID", value, GS_SPT_STRING); + } + + public void setDocumentTimeSeq(int value) { + setParam("DocumentTimeSeq", value, GS_SPT_INT); + } + + public void setDSCEncoding(String encoding) { + setParam("DSCEncoding", encoding, GS_SPT_STRING); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFImageDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFImageDevice.java new file mode 100644 index 00000000..8eedbab9 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFImageDevice.java @@ -0,0 +1,19 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class PDFImageDevice extends FileDevice { + + public static final String PDFIMAGE8 = "pdfimage8"; + public static final String PDFIMAGE24 = "pdfimage24"; + public static final String PDFIMAGE32 = "pdfimage32"; + + public PDFImageDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + + public void setDownScaleFactor(int factor) { + setParam("DownScaleFactor", factor, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFPostscriptDeviceFamily.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFPostscriptDeviceFamily.java new file mode 100644 index 00000000..6afc997c --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFPostscriptDeviceFamily.java @@ -0,0 +1,340 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +/** + * This class is the root device containing methods to set parameters defined + * in section 6.1 in the + * <a href="https://ghostscript.com/doc/current/VectorDevices.htm">Vector Devices</a> + * documentation. + * + * @author Ethan Vrhel + * + */ +public abstract class PDFPostscriptDeviceFamily extends FileDevice implements HighLevelDevice { + + public PDFPostscriptDeviceFamily(String device) + throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(device); + } + + public void setCompressFonts(boolean state) { + setParam("CompressFonts", state, GS_SPT_BOOL); + } + + public void setCompressStreams(boolean state) { + setParam("CompressStreas", state, GS_SPT_BOOL); + } + + public void setAlwaysEmbed(String value) { + setParam("AlwaysEmbed", value, GS_SPT_PARSED); + } + + public void setAntiAliasColorImages(boolean state) { + setParam("AntiAliasColorImages", state, GS_SPT_BOOL); + } + + public void setAntiAliasGrayImages(boolean state) { + setParam("AntiAliasGrayImages", state, GS_SPT_BOOL); + } + + public void setAntiAliasMonoImages(boolean state) { + setParam("AntiAliasMonoImages", state, GS_SPT_BOOL); + } + + public void setASCII85EncodePages(boolean state) { + setParam("ASCII85EncodePages", state, GS_SPT_BOOL); + } + + public void setAutoFilterColorImages(boolean state) { + setParam("AutoFilterColorImages", state, GS_SPT_BOOL); + } + + public void setAutoFilterGrayImages(boolean state) { + setParam("AutoFilterGrayImages", state, GS_SPT_BOOL); + } + + public void setAutoPositionEPSFiles(boolean state) { + setParam("AutoPositionEPSFiles", state, GS_SPT_BOOL); + } + + public void setAutoRotatePages(String mode) { + setParam("AutoRotatePages", mode, GS_SPT_STRING); + } + + public void setBinding(String mode) { + setParam("Binding", mode, GS_SPT_STRING); + } + + public void setCalCMYKProfile(String profile) { + setParam("CalCMYKProfile", profile, GS_SPT_PARSED); + } + + public void setCalGrayProfile(String profile) { + setParam("CalGrayProfile", profile, GS_SPT_PARSED); + } + + public void setCalRGBProfile(String profile) { + setParam("CalRGBProfile", profile, GS_SPT_PARSED); + } + + public void setCannotEmbedFontPolicy(String mode) { + setParam("CannotEmbedFontPolicy", mode, GS_SPT_STRING); + } + + public void setColorACSImageDict(String dict) { + setParam("ColorACSImageDict", dict, GS_SPT_PARSED); + } + + public void setColorConversionStrategy(String strat) { + setParam("ColorConversionSrategy", strat, GS_SPT_STRING); + } + + public void setColorImageDepth(int value) { + setParam("ColorImageDepth", value, GS_SPT_INT); + } + + public void setColorImageDict(String dict) { + setParam("ColorImageDict", dict, GS_SPT_PARSED); + } + + public void setColorImageFilter(String filter) { + setParam("ColorImageFilter", filter, GS_SPT_STRING); + } + + public void setColorImageDownscaleThreshold(float value) { + setParam("ColorImageDownscaleThreshold", value, GS_SPT_FLOAT); + } + + public void setColorImageDownsampleType(String type) { + setParam("ColorImageDownsampleType", type, GS_SPT_STRING); + } + + public void setColorImageResolution(int value) { + setParam("ColorImageResolution", value, GS_SPT_INT); + } + + public void setCompatabilityLevel(String level) { + setParam("CompatabilityLevel", level, GS_SPT_PARSED); + } + + public void setCompressPages(boolean state) { + setParam("CompressPages", state, GS_SPT_BOOL); + } + + public void setConvertCMYKImagesToRGB(boolean state) { + setParam("ConvertCMYKImagesToRGB", state, GS_SPT_BOOL); + } + + public void setConvertColorImagesToIndexed(boolean state) { + setParam("ConvertColorImagesToIndexed", state, GS_SPT_BOOL); + } + + public void setCoreDictVersion(int version) { + setParam("CoreDictVersion", version, GS_SPT_INT); + } + + public void setCreateJobTicket(boolean state) { + setParam("CreateJobTicket", state, GS_SPT_BOOL); + } + + public void setDefaultRenderingIntent(String intent) { + setParam("DefaultRenderingIntent", intent, GS_SPT_STRING); + } + + public void setDetectBlends(boolean state) { + setParam("DetectBlends", state, GS_SPT_BOOL); + } + + public void setDoThumbnails(boolean state) { + setParam("DoThumbnails", state, GS_SPT_BOOL); + } + + public void setDownsampleColorImages(boolean state) { + setParam("DownsampleColorImages", state, GS_SPT_BOOL); + } + + public void setDownsampleGrayImages(boolean state) { + setParam("DownsampleGrayImages", state, GS_SPT_BOOL); + } + + public void setDownsampleMonoImages(boolean state) { + setParam("DownsampleMonoImages", state, GS_SPT_BOOL); + } + + public void setEmbedAllFonts(boolean state) { + setParam("EmbedAllFonts", state, GS_SPT_BOOL); + } + + public void setEmitDSCWarnings(boolean state) { + setParam("EmitDSCWarnings", state, GS_SPT_BOOL); + } + + public void setEncodeColorImages(boolean state) { + setParam("EncodeColorImages", state, GS_SPT_BOOL); + } + + public void setEncodeGrayImages(boolean state) { + setParam("EncodeGrayImages", state, GS_SPT_BOOL); + } + + public void setEncodeMonoImages(boolean state) { + setParam("EncodeMonoImages", state, GS_SPT_BOOL); + } + + public void setEndPage(int page) { + setParam("EndPage", page, GS_SPT_INT); + } + + public void setGrayACSImageDict(String dict) { + setParam("GrayACSImageDict", dict, GS_SPT_PARSED); + } + + public void setGrayImageDepth(int value) { + setParam("GrayImageDepth", value, GS_SPT_INT); + } + + public void setGrayImageDict(String dict) { + setParam("GrayImageDict", dict, GS_SPT_PARSED); + } + + public void setGrayImageDownsampleThreshold(float thresh) { + setParam("GrayImageDownsampleThreshold", thresh, GS_SPT_FLOAT); + } + + public void setGrayImageDownsampleType(String type) { + setParam("GrayImageDownsampleType", type, GS_SPT_STRING); + } + + public void setGrayImageFilter(String filter) { + setParam("GrayImageFilter", filter, GS_SPT_STRING); + } + + public void setGrayImageResolution(int resolution) { + setParam("GrayImageResolution", resolution, GS_SPT_INT); + } + + public void setImageMemory(long memory) { + setParam("ImageMemory", memory, GS_SPT_SIZE_T); + } + + public void setLockDistillerParams(boolean state) { + setParam("LockDistillerParams", state, GS_SPT_BOOL); + } + + public void setLZWEncodePages(boolean state) { + setParam("LZWEncodePages", state, GS_SPT_BOOL); + } + + public void setMaxSubsetPct(int value) { + setParam("MaxSubsetPct", value, GS_SPT_INT); + } + + public void setMonoImageDepth(int depth) { + setParam("MonoImageDepth", depth, GS_SPT_INT); + } + + public void setMonoImageDict(String dict) { + setParam("MonoImageDict", dict, GS_SPT_PARSED); + } + + public void setMonoImageDownsampleThreshold(float thresh) { + setParam("MonoImageDownsampleThreshold", thresh, GS_SPT_FLOAT); + } + + public void setMonoImageDownsampleType(String type) { + setParam("MonoImageDownsampleType", type, GS_SPT_STRING); + } + + public void setMonoImageFilter(String filter) { + setParam("MonoImageFilter", filter, GS_SPT_STRING); + } + + public void setMonoImageResolution(int resolution) { + setParam("MonoImageResolution", resolution, GS_SPT_INT); + } + + public void setNeverEmbed(String value) { + setParam("NeverEmbed", value, GS_SPT_PARSED); + } + + public void setOffOptimizations(int value) { + setParam("OffOptimizations", value, GS_SPT_INT); + } + + public void setOPM(int value) { + setParam("OPM", value, GS_SPT_INT); + } + + public void setOptimize(boolean state) { + setParam("Optimize", state, GS_SPT_BOOL); + } + + public void setParseDSCComments(boolean state) { + setParam("ParseDSCComments", state, GS_SPT_BOOL); + } + + public void setParseDSCCommentsForDocInfo(boolean state) { + setParam("ParseDSCCommentsForDocInfo", state, GS_SPT_BOOL); + } + + public void setPreserveCopyPage(boolean state) { + setParam("PreserveCopyPage", state, GS_SPT_BOOL); + } + + public void setPreserveEPSInfo(boolean state) { + setParam("PreserveEPSInfo", state, GS_SPT_BOOL); + } + + public void setPreserveHalftoneInfo(boolean state) { + setParam("PreserveHalftoneInfo", state, GS_SPT_BOOL); + } + + public void setPreserveOPIComments(boolean state) { + setParam("PreserveOPIComments", state, GS_SPT_BOOL); + } + + public void setPreserveOverprintSettings(boolean state) { + setParam("PreserveOverprintSettings", state, GS_SPT_BOOL); + } + + public void setsRGBProfile(String profile) { + setParam("sRGBProfile", profile, GS_SPT_PARSED); + } + + public void setStartPage(int page) { + setParam("StartPage", page, GS_SPT_INT); + } + + public void setSubsetFonts(boolean state) { + setParam("SubsetFonts", state, GS_SPT_BOOL); + } + + public void setTransferFunctionInfo(String info) { + setParam("TransferFunctionInfo", info, GS_SPT_STRING); + } + + public void setUCRandBGInfo(String info) { + setParam("UCRandBGInfo", info, GS_SPT_STRING); + } + + public void setUseFlateCompression(boolean state) { + setParam("UseFlateCompression", state, GS_SPT_BOOL); + } + + public void setUsePrologue(boolean state) { + setParam("UsePrologue", state, GS_SPT_BOOL); + } + + public void setPassThroughJPEGImages(boolean state) { + setParam("PassThroughJPEGImages", state, GS_SPT_BOOL); + } + + // Specific to PostScript and PDF input + + public void setPDFSETTINGS(String config) { + setParam("PDFSETTINGS", config, GS_SPT_STRING); + } + + // Specific to PCL and PXL input +}
\ No newline at end of file diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PNGDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PNGDevice.java new file mode 100644 index 00000000..8f291851 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PNGDevice.java @@ -0,0 +1,36 @@ +package com.artifex.gsjava.devices; + +import java.awt.Color; + +import com.artifex.gsjava.GSAPI; + +public class PNGDevice extends FileDevice { + + public static final String PNG256 = "png256"; + public static final String PNG16 = "png16"; + public static final String PNGMONO = "pngmono"; + public static final String PNGMONOD = "pngmonod"; + public static final String PNG16M = "png16m"; + public static final String PNGGRAY = "pnggray"; + public static final String PNGALPHA = "pngalpha"; + + public PNGDevice(String format) throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(format); + } + + public void setDownScaleFactor(int value) { + setParam("DownScaleFactor", value, GSAPI.GS_SPT_INT); + } + + public void setMinFeatureSize(int state) { + setParam("MinFeatureSize", state, GSAPI.GS_SPT_INT); + } + + public void setBackgroundColor(Color color) { + setBackgroundColor(color.getRGB()); + } + + public void setBackgroundColor(int color) { + setParam("BackgroundColor", color, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PNMDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PNMDevice.java new file mode 100644 index 00000000..14474906 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PNMDevice.java @@ -0,0 +1,25 @@ +package com.artifex.gsjava.devices; + +public class PNMDevice extends FileDevice { + + public static final String PBM = "pbm"; + public static final String PBMRAW = "pbmraw"; + public static final String PGM = "pbm"; + public static final String PGMRAW = "pgmraw"; + public static final String PGMN = "pgnm"; + public static final String PGMNRAW = "pgnmraw"; + public static final String PNM = "pnm"; + public static final String PNMRAW = "pnmraw"; + public static final String PPM = "ppm"; + public static final String PPMRAW = "ppmraw"; + public static final String PKM = "pkm"; + public static final String PKMRAW = "pkmraw"; + public static final String PKSM = "pksm"; + public static final String PKSMRAW = "pksmraw"; + + public PNMDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PSDDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PSDDevice.java new file mode 100644 index 00000000..312af85d --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PSDDevice.java @@ -0,0 +1,17 @@ +package com.artifex.gsjava.devices; + +public class PSDDevice extends FileDevice { + + public static final String PSDCMYK = "psdcmyk"; + public static final String PSDRGB = "psdrgb"; + public static final String PSDCMYK16 = "psdcmyk16"; + public static final String PSDRGB16 = "psdrgb16"; + public static final String PSDCMYKOG = "psdcmykog"; + + public PSDDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + + // Missing device parameters +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PXLDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PXLDevice.java new file mode 100644 index 00000000..9fb55fd2 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PXLDevice.java @@ -0,0 +1,17 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class PXLDevice extends FileDevice implements HighLevelDevice { + + public static final String PXLMONO = "pxlmono"; + public static final String PXLCOLOR = "pxlcolor"; + + public PXLDevice(String device) throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(device); + } + + public void setCompressMode(int mode) { + setParam("CompressMode", mode, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PostScriptDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PostScriptDevice.java new file mode 100644 index 00000000..3926ebf9 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PostScriptDevice.java @@ -0,0 +1,59 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +public class PostScriptDevice extends PDFPostscriptDeviceFamily { + + public PostScriptDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("ps2write"); + } + + /** + * Intended to be an internal way to override the normal + * ps2write device. + * + * @param override The device override name. + * @throws IllegalStateException {@link Device#Device(String)} + * @throws DeviceNotSupportedException {@link Device#Device(String)} + * @throws DeviceInUseException {@link Device#Device(String)} + */ + protected PostScriptDevice(String override) throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(override); + } + +// public void setPSDocOptions(String options) { +// setParam("PSDocOptions", options, GS_SPT_STRING); +// } +// +// public void setPSPageOptions(String[] options) { +// +// } +// +// public void setPSPageOptions(List<String> options) { +// setPSPageOptions(options.toArray(new String[options.size()])); +// } + + public void setProduceDSC(boolean state) { + setParam("ProduceDSC", state, GS_SPT_BOOL); + } + + public void setCompressEntireFile(boolean state) { + setParam("CompressEntireFile", state, GS_SPT_BOOL); + } + + public void setRotatePages(boolean state) { + setParam("RotatePages", state, GS_SPT_BOOL); + } + + public void setCenterPages(boolean state) { + setParam("CenterPages", state, GS_SPT_BOOL); + } + + public void setSetPageSize(boolean state) { + setParam("SetPageSize", state, GS_SPT_BOOL); + } + + public void setDoNumCopies(boolean state) { + setParam("DoNumCopies", state, GS_SPT_BOOL); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/TIFFDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/TIFFDevice.java new file mode 100644 index 00000000..25b9d335 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/TIFFDevice.java @@ -0,0 +1,80 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class TIFFDevice extends FileDevice { + + public static final String TIFFGRAY = "tiffgray"; + public static final String TIFF12NC = "tiff12nc"; + public static final String TIFF24NC = "tiff24nc"; + public static final String TIFF48NC = "tiff48nc"; + public static final String TIFF32NC = "tiff32nc"; + public static final String TIFF64NC = "tiff64nc"; + public static final String TIFFSEP = "tiffsep"; + + public static final String TIFFSEP1 = "tiffsep1"; + public static final String TIFFSCALED = "tiffscaled"; + public static final String TIFFSCALED4 = "tiffscaled4"; + public static final String TIFFSCALED8 = "tiffscaled8"; + public static final String TIFFSCALED24 = "tiffscaled24"; + public static final String TIFFSCALED32 = "tiffscaled32"; + + public static final String TIFFCRLE = "tiffcrle"; + public static final String TIFFG3 = "tiffg3"; + public static final String TIFFG32D = "tiffg32d"; + public static final String TIFFG4 = "tiffg4"; + public static final String TIFFLZW = "tifflzw"; + public static final String TIFFPACK = "tiffpack"; + + public static final String NONE = "none"; + public static final String CRLE = "crle"; + public static final String G3 = "g3"; + public static final String G4 = "g4"; + public static final String LZW = "lzw"; + public static final String PACK = "pack"; + + public TIFFDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + + public void setMaxStripSize(int size) { + setParam("MaxStripSize", size, GSAPI.GS_SPT_INT); + } + + public void setFillOrder(int order) { + setParam("FillOrder", order, GSAPI.GS_SPT_INT); + } + + public void setUseBigTIFF(boolean state) { + setParam("UseBigTIFF", state, GSAPI.GS_SPT_BOOL); + } + + public void setTIFFDateTime(boolean state) { + setParam("TIFFDateTime", state, GSAPI.GS_SPT_BOOL); + } + + public void setCompression(String compression) { + setParam("Compression", compression, GSAPI.GS_SPT_NAME); + } + + public void setAdjustWith(int state) { + setParam("AdjustWidth", state, GSAPI.GS_SPT_INT); + } + + public void setMinFeatureSize(int state) { + setParam("MinFeatureSize", state, GSAPI.GS_SPT_INT); + } + + public void setDownScaleFactor(int factor) { + setParam("DownScaleFactor", factor, GSAPI.GS_SPT_INT); + } + + public void setPostRenderProfile(String path) { + setParam("PostRenderProfile", path, GSAPI.GS_SPT_NAME); + } + + public void setPrintSpotCMYK(boolean state) { + setParam("PrintSpotCMYK", state, GSAPI.GS_SPT_BOOL); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/TextDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/TextDevice.java new file mode 100644 index 00000000..00f67f5a --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/TextDevice.java @@ -0,0 +1,14 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class TextDevice extends FileDevice implements HighLevelDevice { + + public TextDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("txtwrite"); + } + + public void setTextFormat(int format) { + setParam("TextFormat", format, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/XPSDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/XPSDevice.java new file mode 100644 index 00000000..258dc014 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/XPSDevice.java @@ -0,0 +1,9 @@ +package com.artifex.gsjava.devices; + +public class XPSDevice extends FileDevice implements HighLevelDevice { + + public XPSDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("xpswrite"); + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/AllocationError.java b/demos/java/gsjava/src/com/artifex/gsjava/util/AllocationError.java new file mode 100644 index 00000000..d2f6c99f --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/AllocationError.java @@ -0,0 +1,33 @@ +package com.artifex.gsjava.util; + +/** + * An error thrown when native memory allocation fails. + * + * @author Ethan Vrhel + * + */ +public class AllocationError extends Error { + + private static final long serialVersionUID = 1L; + + public AllocationError() { + super(); + } + + public AllocationError(String message) { + super(message); + } + + public AllocationError(String message, Throwable cause) { + super(message, cause); + } + + public AllocationError(Throwable cause) { + super(cause); + } + + protected AllocationError(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/ByteArrayReference.java b/demos/java/gsjava/src/com/artifex/gsjava/util/ByteArrayReference.java new file mode 100644 index 00000000..1638bb95 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/ByteArrayReference.java @@ -0,0 +1,23 @@ +package com.artifex.gsjava.util; + +/** + * Stores a reference to a byte array. + * + * @author Ethan Vrhel + * + */ +public class ByteArrayReference extends Reference<byte[]> { + + public ByteArrayReference() { + super(); + } + + public ByteArrayReference(final byte[] value) { + super(value); + } + + public String asString() { + byte[] val = getValue(); + return val == null ? "null" : new String(val); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/BytePointer.java b/demos/java/gsjava/src/com/artifex/gsjava/util/BytePointer.java new file mode 100644 index 00000000..8b63254e --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/BytePointer.java @@ -0,0 +1,68 @@ +package com.artifex.gsjava.util; + +/** + * A byte pointer stores a pointer to a memory location containing + * bytes. + * + * @author Ethan Vrhel + * + */ +public class BytePointer extends NativePointer implements NativeArray<Byte> { + + private long length; + + public BytePointer() { + super(); + this.length = 0; + } + + @Override + public void allocate(long length) throws IllegalStateException, AllocationError { + calloc(length, BYTE_SIZE); + this.length = length; + } + + @Override + public void set(long index, Byte value) throws IndexOutOfBoundsException, NullPointerException { + final long address = getAddress(); + if (address == NULL) + throw new NullPointerException("address is null"); + if (index < 0 || index >= length) + throw new IndexOutOfBoundsException(new StringBuilder().append("index: ").append(index).toString()); + setByteNative(address, index, value); + } + + @Override + public Byte at(long index) throws IndexOutOfBoundsException, NullPointerException { + final long address = getAddress(); + if (address == NULL) + throw new NullPointerException("address is null"); + if (index < 0 || index >= length) + throw new IndexOutOfBoundsException(new StringBuilder().append("index: ").append(index).toString()); + return byteAtNative(address, index); + } + + @Override + public Byte[] toArray() throws NullPointerException { + byte[] byteArray = (byte[])toArrayNoConvert(); + Byte[] bArray = new Byte[byteArray.length]; + int i = 0; + for (byte b : byteArray) + bArray[i++] = b; + return bArray; + } + + @Override + public Object toArrayNoConvert() throws NullPointerException { + final long address = getAddress(); + if (address == NULL) + throw new NullPointerException("address is null"); + return byteArrayNative(address, length); + } + + @Override + public long length() { + return length; + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/NativeArray.java b/demos/java/gsjava/src/com/artifex/gsjava/util/NativeArray.java new file mode 100644 index 00000000..0ea059c1 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/NativeArray.java @@ -0,0 +1,67 @@ +package com.artifex.gsjava.util; + +/** + * A NativeArray is an natively allocated array with a set length. + * + * @author Ethan Vrhel + * + * @param <T> The type stored in the array. + */ +public interface NativeArray<T> { + + /** + * Allocates the array of length <code>length</code>. + * + * @param length The length of the array. + * @throws IllegalStateException When the memory has already been allocated. + * @throws AllocationError When the allocation fails. + */ + public void allocate(long length) throws IllegalStateException, AllocationError; + + /** + * Sets the value of an element in the array. + * + * @param index The index to set. + * @param value The value to set to. + * @throws IndexOutOfBoundsException When <code>index</code> is less than 0 or + * greater or equal to the length. + * @throws NullPointerException When the array has not been allocated and is null. + */ + public void set(long index, T value) throws IndexOutOfBoundsException, NullPointerException; + + /** + * Returns the value at an index. + * + * @param index The index to get the value from. + * @return The respective value. + * @throws IndexOutOfBoundsException When <code>index</code> is less than 0 or + * greater or equal to the length. + * @throws NullPointerException When the array has not been allocated and is null. + */ + public T at(long index) throws IndexOutOfBoundsException, NullPointerException; + + /** + * Converts the native array to a Java array. + * + * @return A copy of the native array. + * @throws NullPointerException When the array has not been allocated and is null. + */ + public T[] toArray() throws NullPointerException; + + /** + * Converts the native array to a Java array without creating a new array ensuring + * that an array of <code>T</code>'s are returned. This will generally be faster + * than calling <code>toArray()</code>. + * + * @return A copy of the native array. + * @throws NullPointerException + */ + public Object toArrayNoConvert() throws NullPointerException; + + /** + * Returns the length of the array. + * + * @return The length. + */ + public long length(); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/NativePointer.java b/demos/java/gsjava/src/com/artifex/gsjava/util/NativePointer.java new file mode 100644 index 00000000..222ade80 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/NativePointer.java @@ -0,0 +1,157 @@ +package com.artifex.gsjava.util; + +/** + * <p>The NativePointer class allows for direct non-managed memory + * allocations. The purpose of this class is to provide direct access + * to memory blocks.</p> + * + * <p>An instance of the class is safe in the sense that + * no memory can be accessed that is filled with junk which has been + * freed, and a check is performed so that in the worst case scenario, + * only a Java exception will be thrown. However, an instance of the + * class can cause memory leaks if not used correctly as garbage collecting + * the object will not free the memory natively, so it will need to be + * maintained.</p> + * + * <p>This class also contains several native methods which can be used + * for slightly faster native access to unmanaged memory. These methods + * are considered unsafe, and for read/write access to the memory, + * an implementation <code>NativeArray</code> should be used.</code>. + * + * @author Ethan Vrhel + * + */ +public class NativePointer { + + static { + registerLibraries(); + } + + /** + * Registers the needed native libraries. + */ + private static void registerLibraries() { + System.loadLibrary("gs_jni"); + } + + public static final long NULL = 0x0L; + + public static final long BYTE_SIZE = 1L, + CHAR_SIZE = 2L, + SHORT_SIZE = 2L, + INT_SIZE = 4L, + LONG_SIZE = 8L; + + private long address; + + /** + * Constructs a null native pointer. + */ + public NativePointer() { + address = NULL; + } + + /** + * Allocates a memory block of size <code>size</code>. + * + * @param size The size of the block, in bytes. + * @throws IllegalStateException When this pointer already points to something. + * @throws AllocationError When the native allocation fails. + */ + public final void malloc(long size) throws IllegalStateException, AllocationError { + if (address != NULL) { + throw new IllegalStateException("Memory already allocated."); + } + this.address = mallocNative(size); + } + + /** + * Allocates an block of size <code>count</code> * <code>size</code> with each + * byte initialized to 0. + * + * @param count The number of elements to allocated. + * @param size The size of each element, in bytes. + * @throws IllegalStateException When this pointer already points to something. + * @throws AllocationError When the native allocation fails. + */ + public final void calloc(long count, long size) throws IllegalStateException, AllocationError { + if (address != NULL) { + throw new IllegalStateException("Memory already allocated."); + } + this.address = callocNative(count, size); + } + + /** + * Frees the allocated block, if any has been allocated. + */ + public final void free() { + freeNative(address); + address = NULL; + } + + /** + * Returns the native address of this pointer. + * + * @return The native address. + */ + public final long getAddress() { + return address; + } + + @Override + public boolean equals(Object o) { + if (o == this) + return true; + if (o instanceof NativePointer) { + return address == ((NativePointer)o).address; + } + return false; + } + + @Override + public String toString() { + return new StringBuilder().append("0x").append(Long.toHexString(address)).toString(); + } + + @Override + public int hashCode() { + return (int)address; + } + + private static native long mallocNative(long size) throws AllocationError; + + private static native long callocNative(long count, long size) throws AllocationError; + + private static native void freeNative(long block); + + + public static native byte[] byteArrayNative(long address, long len); + + public static native byte byteAtNative(long address, long index); + + public static native void setByteNative(long address, long index, byte value); + + public static native char[] charArrayNative(long address, long len); + + public static native char charAtNative(long address, long index); + + public static native void setCharNative(long address, long index, char value); + + public static native short[] shortArrayNative(long address, long len); + + public static native short shortAtNative(long address, long index); + + public static native void setShortNative(long address, long index, short value); + + public static native int[] intArrayNative(long address, long len); + + public static native int intAtNative(long address, long index); + + public static native void setIntNative(long address, long index, int value); + + public static native long[] longArrayNative(long address, long len); + + public static native long longAtNative(long address, long index); + + public static native void setLongNative(long address, long index, long value); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/Reference.java b/demos/java/gsjava/src/com/artifex/gsjava/util/Reference.java new file mode 100644 index 00000000..38a34ac1 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/Reference.java @@ -0,0 +1,45 @@ +package com.artifex.gsjava.util; + +public class Reference<T> { + + private volatile T value; + + public Reference() { + this(null); + } + + public Reference(T value) { + this.value = value; + } + + public void setValue(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if (o == null) + return false; + if (o == this) + return true; + if (o instanceof Reference) { + Reference<?> ref = (Reference<?>)o; + return value == null ? ref.value == null : value.equals(ref.value); + } + return false; + } + + @Override + public int hashCode() { + return value == null ? 0 : value.hashCode(); + } + + @Override + public String toString() { + return "Reference<" + (value == null ? "?" : value.getClass().getName()) + "> -> " + value; + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/StringUtil.java b/demos/java/gsjava/src/com/artifex/gsjava/util/StringUtil.java new file mode 100644 index 00000000..0183ad81 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/StringUtil.java @@ -0,0 +1,41 @@ +package com.artifex.gsjava.util; + +/** + * Contains utility methods to work with Strings. + * + * @author Ethan Vrhel + * + */ +public class StringUtil { + + /** + * Converts a Java String to a null-terminated byte array. + * + * @param str The string to convert. + * @return The result byte array. + */ + public static byte[] toNullTerminatedByteArray(final String str) { + final byte[] barray = str.getBytes(); + final byte[] result = new byte[barray.length + 1]; + System.arraycopy(barray, 0, result, 0, barray.length); + return result; + } + + /** + * Converts an array of Strings to a 2D byte array of null-terminated + * strings. + * + * @param strs The strings to convert. + * @return THe result 2D byte array. + */ + public static byte[][] to2DByteArray(final String[] strs){ + final byte[][] array = new byte[strs.length][]; + for (int i = 0; i < strs.length; i++) { + final String str = strs[i]; + array[i] = toNullTerminatedByteArray(str); + } + return array; + } + + private StringUtil() { } +} diff --git a/demos/java/gstest/.classpath b/demos/java/gstest/.classpath new file mode 100644 index 00000000..6d2a9e96 --- /dev/null +++ b/demos/java/gstest/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry combineaccessrules="false" kind="src" path="/gsjava"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/demos/java/gstest/.project b/demos/java/gstest/.project new file mode 100644 index 00000000..b40f0f4f --- /dev/null +++ b/demos/java/gstest/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>gstest</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/demos/java/gstest/src/gstest/Main.java b/demos/java/gstest/src/gstest/Main.java new file mode 100644 index 00000000..ad5b0fb1 --- /dev/null +++ b/demos/java/gstest/src/gstest/Main.java @@ -0,0 +1,41 @@ +package gstest; + +import static com.artifex.gsjava.GSAPI.*; + +import com.artifex.gsjava.GSInstance; +import com.artifex.gsjava.util.NativePointer; +import com.artifex.gsjava.util.Reference; + + +public class Main { + + public static void main(String[] args) throws Exception { + + GSInstance instance = new GSInstance(); + instance.set_arg_encoding(1); + + String[] gsargs = new String[] { + "gs", + "-sDEVICE=pngalpha", + "-r100" + }; + + instance.init_with_args(gsargs); + + Reference<?> aaRef = new Reference<>(); + instance.get_param_once("TextAlphaBits", aaRef, GS_SPT_INT); + System.out.println("TextAlphaBits=" + aaRef.getValue()); + + instance.set_param("TextAlphaBits", 1, GS_SPT_INT); + + NativePointer value = new NativePointer(); + int bytes = instance.get_param("TextAlphaBits", NativePointer.NULL, GS_SPT_INT); + value.malloc(bytes); + instance.get_param("TextAlphaBits", value.getAddress(), GS_SPT_INT); + int val = NativePointer.intAtNative(value.getAddress(), 0); + System.out.println(val); + value.free(); + + instance.delete_instance(); + } +} diff --git a/demos/java/gsviewer/.classpath b/demos/java/gsviewer/.classpath new file mode 100644 index 00000000..3ad142b6 --- /dev/null +++ b/demos/java/gsviewer/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="lib" path="gsjava.jar"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/demos/java/gsviewer/.project b/demos/java/gsviewer/.project new file mode 100644 index 00000000..5b8f7395 --- /dev/null +++ b/demos/java/gsviewer/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>gsviewer</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/demos/java/gsviewer/README.txt b/demos/java/gsviewer/README.txt new file mode 100644 index 00000000..885edf1f --- /dev/null +++ b/demos/java/gsviewer/README.txt @@ -0,0 +1,4 @@ +required libraries in this directory: +gpdldll64.dll +gs_jni.dll +gsjava.jar
\ No newline at end of file diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/DefaultUnhandledExceptionHandler.java b/demos/java/gsviewer/src/com/artifex/gsviewer/DefaultUnhandledExceptionHandler.java new file mode 100644 index 00000000..2074b05b --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/DefaultUnhandledExceptionHandler.java @@ -0,0 +1,107 @@ +package com.artifex.gsviewer; + +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Enumeration; +import java.util.Properties; + +/** + * The default unhandled exception handler. This will handle exceptions which + * are not caught in a try/catch block and print an error message to + * <code>System.err</code> and a log file. + * + * @author Ethan Vrhel + * + */ +public class DefaultUnhandledExceptionHandler implements Thread.UncaughtExceptionHandler { + + /** + * An instance of the exception handler. + */ + public static final DefaultUnhandledExceptionHandler INSTANCE; + + static { + INSTANCE = new DefaultUnhandledExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(INSTANCE); + } + + private DefaultUnhandledExceptionHandler() { } + + @Override + public void uncaughtException(Thread t, Throwable e) { + StringBuilder builder = new StringBuilder(); + + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); + builder.append("Unhandled exception!\n"); + + // Print the time of the error + builder.append("Time: " + dtf.format(LocalDateTime.now()) + "\n\n"); + + // Print all system properties + builder.append("PROPERTIES\n"); + Properties props = System.getProperties(); + for (Enumeration<Object> keys = props.keys(); keys.hasMoreElements();) { + String key = keys.nextElement().toString(); + String prop = props.getProperty(key); + String friendly = "\""; + for (int i = 0; i < prop.length(); i++) { + char c = prop.charAt(i); + switch (c) { + case '\n': + friendly += "\\n"; + break; + case '\r': + friendly += "\\r"; + break; + default: + friendly += c; + break; + } + } + friendly += "\""; + builder.append(key + " = " + friendly + "\n"); + } + builder.append('\n'); + + // Print the stack trace of the error + builder.append("EXCEPTION\n"); + builder.append("Exception: " + e.getClass().getName() + "\n"); + builder.append("Message: " + e.getMessage() + "\n"); + builder.append("Cause: " + (e.getCause() == null ? "[Unknown]" : + e.getCause().getClass().getName()) + "\n"); + builder.append("Thread: " + t.getName() + " (id=" + t.getId() + ")\n"); + builder.append("Stack trace:" + "\n"); + builder.append(stackTraceToString(e)); + + // Write to System.err and a log file + String fullMessage = builder.toString(); + System.err.println(fullMessage); + try { + PrintStream out = new PrintStream(new FileOutputStream("error.log")); + out.println(fullMessage); + out.close(); + } catch (FileNotFoundException e1) { + System.err.println("Failed to write to log file"); + } + + // Close the program + System.exit(1); + } + + /** + * Converts a stack trace to a string. + * + * @param e The <code>Throwable</code> whose stack trace should be converted. + * @return The stack trace as a string. + */ + private String stackTraceToString(Throwable e) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(os); + e.printStackTrace(out); + return new String(os.toByteArray()); + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java new file mode 100644 index 00000000..6000d3e4 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java @@ -0,0 +1,1075 @@ +package com.artifex.gsviewer; + +import static com.artifex.gsjava.GSAPI.*; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Objects; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import com.artifex.gsjava.GSInstance; +import com.artifex.gsjava.callbacks.DisplayCallback; +import com.artifex.gsjava.util.BytePointer; +import com.artifex.gsjava.util.Reference; +import com.artifex.gsviewer.ImageUtil.ImageParams; + +import sun.misc.Unsafe; + +/** + * <p>A Document stores an ordered list of Pages. This class implements + * <code>java.util.List</code>, so it inherits all of a list's capabilities, + * such as the ability to iterate over the document.</p> + * + * <p>The Document class also handles loading of pages through Ghostcript + * and ensuring that two Ghostscript operations are not running at the + * same time.</p> + * + * @author Ethan Vrhel + * + */ +public class Document implements List<Page> { + + private static final DocumentLoader documentLoader = new DocumentLoader(); // The document loader + private static final int format = GS_COLORS_RGB | GS_DISPLAY_DEPTH_8 | GS_DISPLAY_BIGENDIAN; // Format + + private static final ReentrantLock operationLock = new ReentrantLock(); // The operation lock + private static final Condition operationCv = operationLock.newCondition(); // The operation condition variable + private static volatile boolean operationInProgress = false; // Whether an operation is in progress + + private static GSInstance gsInstance = null; + + /** + * Asynchronous execution dispatch returns. + */ + public static final int ASYNC_DISPATCH_OK = 0, ASYNC_DISPATCH_OPERATION_IN_PROGRESS = 1; + + /** + * Operation mode indicating the method should wait until a running operation has finished. + */ + public static final int OPERATION_WAIT = 0; + + /** + * Operation mode indicating the method should immediately return if an operation is already + * running. + */ + public static final int OPERATION_RETURN = 1; + + /** + * Operation mode indicating the method should throw an <code>OperationInProgressException</code> + * if an operation is already running. + */ + public static final int OPERATION_THROW = 2; + + /** + * Loads a document on a separate thread. + * + * @param file The file to load. + * @param cb The callback when loading the document has finished. + * @param dlb The callback signifying when progress has occurred while loading. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be <code>OPERATION_WAIT</code>, meaning the loader should + * wait until a running operation has finished, <code>OPERATION_RETURN</code> meaning + * the loader should immediately return <code>ASYNC_DISPATCH_OPERATION_IN_PROGRESS</code>, or + * <code>OPERATION_THROW</code> meaning the loader should throw an + * <code>OperationInProgressException</code>. + * + * @return The state of the thread dispatching. This is either <code>ASYNC_DISPATCH_OK</code> + * or <code>ASYNC_DISPATCH_OPERATION_IN_PROGRESS</code> which is also dependent on + * <code>operationMode</code>. + * + * @throws NullPointerException When <code>cb</code> is <code>null</code>. + * @throws RuntimeException When the current thread fails to wait until a thread has finished + * completing an operation. + * @throws IllegalArgumentException When <code>operationMode</code> is not + * <code>OPERTAION_WAIT</coded>, <code>OPERATION_RETURN</code>, or <code>OPERATION_THROW</code>. + * @throws OperationInProgressException When an operation is in progress and + * <code>operationMode</codeE> is <code>OPERATION_THROW</code>. + */ + public static int loadDocumentAsync(final File file, final DocAsyncLoadCallback cb, + final DocLoadProgressCallback dlb, final int operationMode) + throws NullPointerException, RuntimeException, IllegalArgumentException, + OperationInProgressException { + if (!handleOperationMode(operationMode)) + return ASYNC_DISPATCH_OPERATION_IN_PROGRESS; + + Objects.requireNonNull(cb, "DocAsyncLoadCallback"); + final Thread t = new Thread(() -> { + Document doc = null; + Exception exception = null; + try { + doc = new Document(file, dlb, operationMode); + } catch (FileNotFoundException | IllegalStateException | NullPointerException e) { + exception = e; + } + cb.onDocumentLoad(doc, exception); + }); + t.setName("Document-Loader-Thread"); + t.setDaemon(true); + t.start(); + return ASYNC_DISPATCH_OK; + } + + /** + * Loads a document on a separate thread. + * + * @param file The file to load. + * @param cb The callback when loading the document has finished. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be <code>OPERATION_WAIT</code>, meaning the loader should + * wait until a running operation has finished, <code>OPERATION_RETURN</code> meaning + * the loader should immediately return <code>ASYNC_DISPATCH_OPERATION_IN_PROGRESS</code>, or + * <code>OPERATION_THROW</code> meaning the loader should throw an + * <code>OperationInProgressException</code>. + * + * @return The state of the thread dispatching. This is either <code>ASYNC_DISPATCH_OK</code> + * or <code>ASYNC_DISPATCH_OPERATION_IN_PROGRESS</code> which is also dependent on + * <code>operationMode</code>. + * + * @throws NullPointerException When <code>cb</code> is <code>null</code>. + * @throws RuntimeException When the current thread fails to wait until a thread has finished + * completing an operation. + * @throws IllegalArgumentException When <code>operationMode</code> is not + * <code>ASYNC_OPERTAION_WAIT</coded> or <code>ASYNC_OPERATION_RETURN</code>. + */ + public static int loadDocumentAsync(final File file, final DocAsyncLoadCallback cb, + final int operationMode) + throws NullPointerException, RuntimeException, IllegalArgumentException { + return loadDocumentAsync(file, cb, null, operationMode); + } + + /** + * Loads a document on a separate thread. + * + * @param filename The name of the file to load. + * @param cb The callback when loading the document has finished. + * @param dlb The callback signifying when progress has occurred while loading. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be <code>OPERATION_WAIT</code>, meaning the loader should + * wait until a running operation has finished, <code>OPERATION_RETURN</code> meaning + * the loader should immediately return <code>ASYNC_DISPATCH_OPERATION_IN_PROGRESS</code>, or + * <code>OPERATION_THROW</code> meaning the loader should throw an + * <code>OperationInProgressException</code>. + * + * @return The state of the thread dispatching. This is either <code>ASYNC_DISPATCH_OK</code> + * or <code>ASYNC_DISPATCH_OPERATION_IN_PROGRESS</code> which is also dependent on + * <code>operationMode</code>. + * + * @throws NullPointerException When <code>cb</code> is <code>null</code>. + * @throws RuntimeException When the current thread fails to wait until a thread has finished + * completing an operation. + * @throws IllegalArgumentException When <code>operationMode</code> is not + * <code>ASYNC_OPERTAION_WAIT</coded> or <code>ASYNC_OPERATION_RETURN</code>. + */ + public static int loadDocumentAsync(final String filename, final DocAsyncLoadCallback cb, + final DocLoadProgressCallback dlb, final int operationMode) + throws NullPointerException, RuntimeException, IllegalArgumentException { + return loadDocumentAsync(new File(filename), cb, dlb, operationMode); + } + + /** + * Loads a document on a separate thread. + * + * @param filename The name of the file to load. + * @param cb The callback when loading the document has finished. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be <code>OPERATION_WAIT</code>, meaning the loader should + * wait until a running operation has finished, <code>OPERATION_RETURN</code> meaning + * the loader should immediately return <code>ASYNC_DISPATCH_OPERATION_IN_PROGRESS</code>, or + * <code>OPERATION_THROW</code> meaning the loader should throw an + * <code>OperationInProgressException</code>. + * + * @return The state of the thread dispatching. This is either <code>ASYNC_DISPATCH_OK</code> + * or <code>ASYNC_DISPATCH_OPERATION_IN_PROGRESS</code> which is also dependent on + * <code>operationMode</code>. + * + * @throws NullPointerException When <code>cb</code> is <code>null</code>. + * @throws RuntimeException When the current thread fails to wait until a thread has finished + * completing an operation. + * @throws IllegalArgumentException When <code>operationMode</code> is not + * <code>ASYNC_OPERTAION_WAIT</coded> or <code>ASYNC_OPERATION_RETURN</code>. + */ + public static int loadDocumentAsync(final String filename, final DocAsyncLoadCallback cb, + final int operationMode) + throws NullPointerException, RuntimeException, IllegalArgumentException { + return loadDocumentAsync(filename, cb, null, operationMode); + } + + /** + * Returns whether a file should being distilled to a PDF before loading. Also tests + * to make sure that the supplied file is a file type that can be loaded into the viewer. + * If the file cannot be loaded into the viewer, an <code>IllegalArgumentException</code> + * is thrown. + * + * @param file The file to test. + * @return <code>true</code> if the file should be distilled or <code>false</code> + * if it should not. + * @throws FileNotFoundException If <code>file</code> does not exist. + * @throws IllegalArgumentException If <code>file</code> is not a document which can + * be loaded into the viewer. + * @throws NullPointerException If <code>file</code> is <code>null</code>. + */ + public static boolean shouldDistill(File file) + throws FileNotFoundException, IllegalArgumentException, NullPointerException { + if (!Objects.requireNonNull(file, "file is null").exists()) + throw new FileNotFoundException("File does not exist."); + String path = file.getAbsolutePath(); + int extensionInd = path.lastIndexOf('.'); + if (extensionInd == -1 || !GSFileFilter.INSTANCE.accept(file)) + throw new IllegalArgumentException("Invalid file type"); + String extension = path.substring(extensionInd); + return !extension.equalsIgnoreCase(".pdf"); + } + + /** + * Distills a document into a PDF. + * + * @param input The input file to distill. + * @param out The output file to write to. If the file does not exist, it will be + * created. If this is <code>null</code>, a temporary file will be created. + * @return The file which was written to. + * @throws IOException When a file fails to be created. + * @throws FileNotFoundException When <code>input</code> does not exist. + * @throws IllegalStateException When the file fails to be distilled. + */ + public static File distillDocument(File input, File out) throws IOException, FileNotFoundException, IllegalStateException { + if (gsInstance != null) + throw new IllegalStateException("gsInstance is non-null"); + + if (!input.exists()) + throw new FileNotFoundException(input.getAbsolutePath()); + + out = out == null ? File.createTempFile(input.getName() + ".pdf", null) : out; + if (!out.exists()) + out.createNewFile(); + + try { + int code = initGSInstance( + "gs", + "-sDEVICE=pdfwrite", + "-dFirstPage=1", + "-dDisplayFormat=" + format, + "-o", out.getAbsolutePath(), + "-f", input.getAbsolutePath() + ); + + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to distill document (code = " + code + ")"); + } finally { + deleteGSInstance(); + } + return out; + } + + /** + * Call, internally, on the start of an operation. + */ + private static void startOperation() { + operationInProgress = true; + } + + /** + * Call, internally, on the start of an operation, before <code>startOperation()</code>. + * + * @param operationMode The operation mode. + * @return Whether the calling function should continue to its operation. + * @throws OperationInProgressException When an operation is in progress and <code>operationMode</code> + * is <code>OPERATION_THROW</code>. This should not be caught by the calling function, who should + * throw it instead. + * @throws IllegalArgumentException When <code>operationMode</code> is not a valid operation mode. + */ + private static boolean handleOperationMode(final int operationMode) + throws OperationInProgressException, IllegalArgumentException { + if (operationInProgress && operationMode == OPERATION_RETURN) + return false; + else if (operationInProgress && operationMode == OPERATION_THROW) { + StackTraceElement[] elems = new Exception().getStackTrace(); + throw new OperationInProgressException(elems[1].getClassName() + "." + elems[1].getMethodName()); + } else if (operationInProgress && operationMode == OPERATION_WAIT) + waitForOperation(); + else if (operationInProgress) + throw new IllegalArgumentException("Unknown operation mode: " + operationMode); + return true; + } + + /** + * Called internally by <code>handleOperationMode()</code>. Waits for an operation + * to finish. + */ + private static void waitForOperation() { + operationLock.lock(); + try { + operationCv.await(); + } catch (InterruptedException e) { + throw new RuntimeException("Thread interrupted", e); + } finally { + operationLock.unlock(); + } + } + + /** + * Call, internally, when an operation is done. + */ + private static void operationDone() { + operationLock.lock(); + operationInProgress = false; + try { + operationCv.signal(); + } finally { + operationLock.unlock(); + } + } + + @FunctionalInterface + public static interface DocAsyncLoadCallback { + + /** + * Called when a document has finished loading on a separate + * thread. + * + * @param doc The document which was loaded. <code>null</code> if the document + * failed to load. + * @param exception An exception that ocurred while loading, <code>null</code> + * if no exception was thrown. + */ + public void onDocumentLoad(Document doc, Exception exception); + } + + @FunctionalInterface + public static interface DocLoadProgressCallback { + + /** + * Called when the document has made progress while loading. + * + * @param progress The amount of progress (from 0 to 100). + */ + public void onDocumentProgress(int progress); + } + + /** + * Exception indicating an operation is already in progress. + * + * @author Ethan Vrhel + * + */ + public static final class OperationInProgressException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public OperationInProgressException(String message) { + super(message); + } + } + + /** + * Initializes a new instance of ghostscript. + * + * @param args The arguments for init_with_args. + * @return The return code of init_with_args. + * @throws IllegalStateException When any return code of a Ghostscript call is + * not <code>GS_ERROR_OK</code>. + */ + private static int initGSInstance(String... args) throws IllegalStateException { + deleteGSInstance(); + + GSInstance instance = new GSInstance(); + + int code; + code = instance.set_arg_encoding(1); + if (code != GS_ERROR_OK) { + instance.delete_instance(); + throw new IllegalStateException("Failed to set arg encoding (code = " + code + ")"); + } + + code = instance.set_display_callback(documentLoader.reset()); + if (code != GS_ERROR_OK) { + instance.delete_instance(); + throw new IllegalStateException("Failed to set display callback (code = " + code + ")"); + } + + code = instance.init_with_args(args); + if (code != GS_ERROR_OK) { + instance.delete_instance(); + throw new IllegalStateException("Failed to init with args (code = " + code + ")"); + } + + gsInstance = instance; + return code; + } + + /** + * Deletes the current instance of Ghostscript. + */ + private static void deleteGSInstance() { + if (gsInstance != null) { + gsInstance.exit(); + gsInstance.delete_instance(); + gsInstance = null; + } + } + + /** + * Sets Ghostscript parameters. + * + * @param dpi The dpi to set. + * @param startPage The start page to set. + * @param lastPage The last page to set. + * @throws NullPointerException When the Ghostscript instance is <code>null</code>. + * @throws IllegalStateException When any Ghostscript call does not return <code>GS_ERROR_OK</code>. + */ + private static void setParams(int dpi, int startPage, int lastPage) throws NullPointerException, IllegalStateException { + if (gsInstance == null) + throw new NullPointerException("gsInstance is null"); + + int code = gsInstance.set_param("HWResolution", Page.toDPIString(dpi), GS_SPT_PARSED); + if (code != GS_ERROR_OK) { + operationDone(); + throw new IllegalStateException("Failed to set HWResolution (code = " + code + ")"); + } + + code = gsInstance.set_param("FirstPage", startPage, GS_SPT_INT); + if (code != GS_ERROR_OK) { + operationDone(); + throw new IllegalStateException("Failed to set dFirstPage (code = " + code + ")"); + } + + code = gsInstance.set_param("LastPage", lastPage, GS_SPT_INT); + if (code != GS_ERROR_OK) { + operationDone(); + throw new IllegalStateException("Failed to set dEndPage (code = " + code + ")"); + } + } + + /** + * Class which handles loading a Document. + * + * @author Ethan Vrhel + * + */ + private static class DocumentLoader extends DisplayCallback { + private int pageWidth, pageHeight, pageRaster; + private BytePointer pimage; + private List<BufferedImage> images; + private int progress; + private DocLoadProgressCallback callback; + + DocumentLoader() { + reset(); + } + + /** + * Resets the DcumentLoader to its default values. + * + * @return <code>this</code>. + */ + DocumentLoader reset() { + this.pageWidth = 0; + this.pageHeight = 0; + this.pageRaster = 0; + this.pimage = null; + this.images = new LinkedList<>(); + this.progress = 0; + this.callback = null; + return this; + } + + @Override + public int onDisplayPresize(long handle, long device, int width, int height, int raster, int format) { + return 0; + } + + @Override + public int onDisplaySize(long handle, long device, int width, int height, int raster, int format, + BytePointer pimage) { + this.pageWidth = width; + this.pageHeight = height; + this.pageRaster = raster; + this.pimage = pimage; + return 0; + } + + @Override + public int onDisplayPage(long handle, long device, int copies, boolean flush) { + byte[] data = (byte[]) pimage.toArrayNoConvert(); + images.add(ImageUtil.createImage(data, new ImageParams(pageWidth, pageHeight, pageRaster, BufferedImage.TYPE_3BYTE_BGR))); + + progress += (100 - progress) / 2; + if (callback != null) + callback.onDocumentProgress(progress); + + return 0; + } + + @Override + public void finalize() { + System.err.println("WARNING: The document loader has been freed by the Java VM"); + } + } + + private File file; + private List<Page> pages; + + /** + * Creates and loads a new document. + * + * @param file The file to load. + * @param loadCallback The callback to indicate when progress has occurred while loading. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be <code>OPERATION_WAIT</code>, meaning the loader should + * wait until a running operation has finished, <code>OPERATION_RETURN</code> meaning + * the loader should immediately return, or <code>OPERATION_THROW</code> meaning the loader + * should throw an <code>OperationInProgressException</code>. + * + * @throws FileNotFoundException When <code>file</code> does not exist. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws NullPointerException When <code>file</code> is <code>null</code>. + * @throws OperationInProgressException When an operation is already in progress + * and <code>operationMode</code> is <code>OPERATION_THROW</code>. + * @throws IllegalArgumentException When <code>operationMode</code> is not + * <code>OPERATION_WAIT</coded>, <code>OPERATION_RETURN</code>, or <code>OPERATION_THROW</code>. + */ + public Document(final File file, final DocLoadProgressCallback loadCallback, int operationMode) + throws FileNotFoundException, IllegalStateException, NullPointerException, + OperationInProgressException, IllegalArgumentException { + this.file = Objects.requireNonNull(file, "file"); + if (!file.exists()) + throw new FileNotFoundException(file.getAbsolutePath()); + + if (!handleOperationMode(operationMode)) + return; + + try { + + startOperation(); + + int code = initGSInstance( + "gs", + "-sDEVICE=display", + "-dFirstPage=1", + "-dDisplayFormat=" + format + ); + + if (gsInstance == null) + throw new IllegalStateException("Failed to initialize Ghostscript"); + + documentLoader.callback = loadCallback; + + + code = gsInstance.set_param("HWResolution", Page.toDPIString(Page.PAGE_LOW_DPI), GS_SPT_PARSED); + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to set HWResolution (code = " + code + ")"); + + Reference<Integer> exitCode = new Reference<>(); + code = gsInstance.run_file(file.getAbsolutePath(), 0, exitCode); + + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to run file (code = " + code + ")"); + + boolean aa = Settings.SETTINGS.getSetting("antialiasing"); + if (aa) { + gsInstance.set_param("TextAlphaBits", 4, GS_SPT_INT); + gsInstance.set_param("GraphicsAlphaBits", 4, GS_SPT_INT); + } else { + gsInstance.set_param("TextAlphaBits", 0, GS_SPT_INT); + gsInstance.set_param("GraphicsAlphaBits", 0, GS_SPT_INT); + } + + this.pages = new ArrayList<>(documentLoader.images.size()); + for (BufferedImage img : documentLoader.images) { + pages.add(new Page(img)); + } + + if (documentLoader.callback != null) + documentLoader.callback.onDocumentProgress(100); + } finally { + operationDone(); + } + } + + /** + * Creates and loads a document from a filename. + * + * @param file The file to load. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be <code>OPERATION_WAIT</code>, meaning the loader should + * wait until a running operation has finished, <code>OPERATION_RETURN</code> meaning + * the loader should immediately return, or <code>OPERATION_THROW</code> meaning the loader + * should throw an <code>OperationInProgressException</code>. + * + * @throws FileNotFoundException When <code>file</code> does not exist. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws NullPointerException When <code>file</code> is <code>null</code>. + * @throws OperationInProgressException When an operation is already in progress + * and <code>operationMode</code> is <code>OPERATION_THROW</code>. + * @throws IllegalArgumentException When <code>operationMode</code> is not + * <code>OPERATION_WAIT</coded>, <code>OPERATION_RETURN</code>, or <code>OPERATION_THROW</code>. + */ + public Document(final File file, final int operationMode) + throws FileNotFoundException, IllegalStateException, NullPointerException, + OperationInProgressException { + this(file, null, operationMode); + } + + /** + * Creates and loads a document from a filename. + * + * @param filename The name of the file to load. + * @param loadCallback The callback to indicate when progress has occurred while loading. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be <code>OPERATION_WAIT</code>, meaning the loader should + * wait until a running operation has finished, <code>OPERATION_RETURN</code> meaning + * the loader should immediately return, or <code>OPERATION_THROW</code> meaning the loader + * should throw an <code>OperationInProgressException</code>. + * + * @throws FileNotFoundException When <code>file</code> does not exist. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws NullPointerException When <code>file</code> is <code>null</code>. + * @throws OperationInProgressException When an operation is already in progress + * and <code>operationMode</code> is <code>OPERATION_THROW</code>. + * @throws IllegalArgumentException When <code>operationMode</code> is not + * <code>OPERATION_WAIT</coded>, <code>OPERATION_RETURN</code>, or <code>OPERATION_THROW</code>. + */ + public Document(final String filename, final DocLoadProgressCallback loadCallback, + final int operationMode) + throws FileNotFoundException, IllegalStateException, NullPointerException, + OperationInProgressException { + this(new File(Objects.requireNonNull(filename, "filename")), loadCallback, operationMode); + } + + /** + * Creates and loads a document from a filename. + * + * @param filename The name of the file to load. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be <code>OPERATION_WAIT</code>, meaning the loader should + * wait until a running operation has finished, <code>OPERATION_RETURN</code> meaning + * the loader should immediately return, or <code>OPERATION_THROW</code> meaning the loader + * should throw an <code>OperationInProgressException</code>. + * + * @throws FileNotFoundException When <code>filename</code> does not exist. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws NullPointerException When <code>filename</code> is <code>null</code>. + * @throws OperationInProgressException When an operation is already in progress + * and <code>operationMode</code> is <code>OPERATION_THROW</code>. + * @throws IllegalArgumentException When <code>operationMode</code> is not + * <code>OPERATION_WAIT</coded>, <code>OPERATION_RETURN</code>, or <code>OPERATION_THROW</code>. + */ + public Document(final String filename, final int operationMode) + throws FileNotFoundException, IllegalStateException, NullPointerException, + OperationInProgressException { + this(filename, null, operationMode); + } + + /** + * Loads the high resolution images in a range of images. + * + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be <code>OPERATION_WAIT</code>, meaning the loader should + * wait until a running operation has finished, <code>OPERATION_RETURN</code> meaning + * the loader should immediately return, or <code>OPERATION_THROW</code> meaning the loader + * should throw an <code>OperationInProgressException</code>. + * @param startPage The first page to load. + * @param endPage The end page to load. + * + * @throws IndexOutOfBoundsException When <code>firstPage</code> or <code>endPage</code> + * are not in the document or <code>endPage</code> is less than <code>firstPage</code>. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + */ + public void loadHighRes(int operationMode, int startPage, int endPage) + throws IndexOutOfBoundsException, IllegalStateException { + checkBounds(startPage, endPage); + + if (!handleOperationMode(operationMode)) + return; + + try { + startOperation(); + + documentLoader.images.clear(); + + setParams(Page.PAGE_HIGH_DPI, startPage, endPage); + + Reference<Integer> exitCode = new Reference<>(); + int code = gsInstance.run_file(file.getAbsolutePath(), 0, exitCode); + + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to run file (code = " + code + ")"); + + if (documentLoader.images.size() != endPage - startPage + 1) { + throw new IllegalStateException("Page range mismatch (expected " + + (endPage - startPage) + ", got " + documentLoader.images.size() + ")"); + } + + int ind = startPage - 1; + for (final BufferedImage img : documentLoader.images) { + this.pages.get(ind++).setHighRes(img); + } + } finally { + operationDone(); + } + } + + /** + * Loads the high resolution image of a singular page. + * + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be <code>OPERATION_WAIT</code>, meaning the loader should + * wait until a running operation has finished, <code>OPERATION_RETURN</code> meaning + * the loader should immediately return, or <code>OPERATION_THROW</code> meaning the loader + * should throw an <code>OperationInProgressException</code>. + * @param page The page to load. + * + * @throws IndexOutOfBoundsException When <code>page</code> is not in the document. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws OperationInProgressException When an operation is already in progress + * and <code>operationMode</code> is <code>OPERATION_THROW</code>. + * @throws IllegalArgumentException When <code>operationMode</code> is not + * <code>OPERATION_WAIT</coded>, <code>OPERATION_RETURN</code>, or <code>OPERATION_THROW</code>. + */ + public void loadHighRes(int operationMode, int page) + throws IndexOutOfBoundsException, IllegalStateException, OperationInProgressException { + loadHighRes(operationMode, page, page); + } + + /** + * Unloads the high resolution images in a range of pages. + * + * @param startPage The start page to unload the high resolution image from. + * @param endPage The end page to unload the high resolution image from. + * + * @throws IndexOutOfBoundsException When <code>startPage</code> and <code>endPage</code> + * are outside document or <code>endPage</code> is less than <code>startPage</code>. + */ + public void unloadHighRes(int startPage, int endPage) throws IndexOutOfBoundsException { + checkBounds(startPage, endPage); + for (int i = startPage - 1; i < endPage; i++) { + pages.get(i).unloadHighRes(); + } + } + + /** + * Unloads a high resolution image at the given page. + * + * @param page The page to unload the high resolution image. + * + * @throws IndexOutOfBoundsException When page is not a page in the document. + */ + public void unloadHighRes(int page) throws IndexOutOfBoundsException { + unloadHighRes(page, page); + } + + /** + * Unloads the zoomed images for a range of pages. + * + * @param startPage The start page to unload. + * @param endPage The end page to unload. + * + * @throws IndexOutOfBoundsException When <code>startPage</code> and <code>endPage</code> + * are outside document or <code>endPage</code> is less than <code>startPage</code>. + */ + public void unloadZoomed(int startPage, int endPage) throws IndexOutOfBoundsException { + checkBounds(startPage, endPage); + for (int i = startPage; i < endPage; i++) { + pages.get(i).unloadZoomed(); + } + } + + /** + * Unloads a zoomed image for a page. + * + * @param page The page to unload. + * + * @throws IndexOutOfBoundsException When <code>page</code> is not in the document. + */ + public void unloadZoomed(int page) throws IndexOutOfBoundsException { + unloadZoomed(page, page); + } + + /** + * Unloads the document's resources. The document will be unusable after this + * call. + */ + public void unload() { + if (pages != null) + deleteGSInstance(); + + for (Page p : pages) { + p.unloadAll(); + } + pages.clear(); + pages = null; + } + + /** + * Returns the name of the document loaded. + * + * @return The name. + */ + public String getName() { + return file.getName(); + } + + /** + * Zooms the area around page <code>page</code>. The area around <code>page</code> + * is <code>page - 1</code> to <code>page + 1</code>. The method will automatically + * handle if <code>page - 1</code> or <code>page + 1</code> are out of range. However, + * it does not handle if <code>page</code> is not in the document. + * + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be <code>OPERATION_WAIT</code>, meaning the loader should + * wait until a running operation has finished, <code>OPERATION_RETURN</code> meaning + * the loader should immediately return, or <code>OPERATION_THROW</code> meaning the loader + * should throw an <code>OperationInProgressException</code>. + * @param page The page to load around. + * @param zoom The zoom of the pages. + * + * @throws IndexOutOfBoundsException When <code>page</code> is not in the document. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws OperationInProgressException When an operation is already in progress + * and <code>operationMode</code> is <code>OPERATION_THROW</code>. + * @throws IllegalArgumentException When <code>operationMode</code> is not + * <code>OPERATION_WAIT</coded>, <code>OPERATION_RETURN</code>, or <code>OPERATION_THROW</code>. + */ + public void zoomArea(final int operationMode, final int page, final double zoom) + throws IndexOutOfBoundsException { + checkBounds(page, page); + + if (!handleOperationMode(operationMode)) + return; + + try { + startOperation(); + + int start = page - 1; + start = start < 1 ? page : start; + int end = page + 1; + end = end > pages.size() ? page : end; + + documentLoader.images.clear(); + + setParams((int)(Page.PAGE_HIGH_DPI * zoom), start, end); + + Reference<Integer> exitCode = new Reference<>(); + int code = gsInstance.run_file(file.getAbsolutePath(), 0, exitCode); + + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to run file (code = " + code + ")"); + + int ind = start - 1; + for (final BufferedImage img : documentLoader.images) { + this.pages.get(ind++).setZoomed(img); + } + } finally { + operationDone(); + } + } + + public void zoomPage(final int operationMode, final int page, final double zoom) + throws IndexOutOfBoundsException { + checkBounds(page, page); + + if (!handleOperationMode(operationMode)) + return; + + try { + startOperation(); + + setParams((int)(Page.PAGE_HIGH_DPI * zoom), page, page); + + Reference<Integer> exitCode = new Reference<>(); + int code = gsInstance.run_file(file.getAbsolutePath(), 0, exitCode); + + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to run file (code = " + code + ")"); + + int ind = page - 1; + for (final BufferedImage img : documentLoader.images) { + this.pages.get(ind++).setZoomed(img); + } + + } finally { + operationDone(); + } + } + + /** + * Checks to make sure the pages <code>start</code> through + * <code>end</code> are in the document, and throws an + * <code>IndexOutOfBoundsException</code> if they are not. + * + * @param start The start page. + * @param end The end page. + * @throws IndexOutOfBoundsException When <code>startPage</code> and <code>endPage</code> + * are outside document or <code>endPage</code> is less than <code>startPage</code>. + */ + private void checkBounds(int start, int end) throws IndexOutOfBoundsException { + if (start < 1 || start > pages.size()) + throw new IndexOutOfBoundsException("start=" + start); + if (end < 1 || end > pages.size()) + throw new IndexOutOfBoundsException("end=" + end); + if (end < start) + throw new IndexOutOfBoundsException("end < start"); + } + + // Implementations of inherited methods from java.util.List. + + @Override + public int size() { + return pages.size(); + } + + @Override + public boolean isEmpty() { + return pages.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return pages.contains(o); + } + + @Override + public Iterator<Page> iterator() { + return pages.iterator(); + } + + @Override + public Object[] toArray() { + return pages.toArray(); + } + + @Override + public <T> T[] toArray(T[] a) { + return pages.toArray(a); + } + + @Override + public boolean add(Page e) { + return pages.add(e); + } + + @Override + public boolean remove(Object o) { + return pages.remove(o); + } + + @Override + public boolean containsAll(Collection<?> c) { + return pages.containsAll(c); + } + + @Override + public boolean addAll(Collection<? extends Page> c) { + return pages.addAll(c); + } + + @Override + public boolean addAll(int index, Collection<? extends Page> c) { + return pages.addAll(index, c); + } + + @Override + public boolean removeAll(Collection<?> c) { + return pages.removeAll(c); + } + + @Override + public boolean retainAll(Collection<?> c) { + return pages.retainAll(c); + } + + @Override + public void clear() { + pages.clear(); + } + + @Override + public Page get(int index) { + return pages.get(index); + } + + @Override + public Page set(int index, Page element) { + return pages.set(index, element); + } + + @Override + public void add(int index, Page element) { + pages.add(index, element); + } + + @Override + public Page remove(int index) { + return pages.remove(index); + } + + @Override + public int indexOf(Object o) { + return pages.indexOf(o); + } + + @Override + public int lastIndexOf(Object o) { + return pages.lastIndexOf(o); + } + + @Override + public ListIterator<Page> listIterator() { + return pages.listIterator(); + } + + @Override + public ListIterator<Page> listIterator(int index) { + return pages.listIterator(index); + } + + @Override + public Document subList(int fromIndex, int toIndex) { + try { + Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + Unsafe unsafe = (Unsafe)unsafeField.get(null); + Document doc = (Document)unsafe.allocateInstance(Document.class); + doc.pages = pages.subList(fromIndex, toIndex); + doc.file = file; + return doc; + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException + | IllegalAccessException | InstantiationException e) { + throw new RuntimeException("Failed to create sublist: " + e); + } + } + + @Override + public String toString() { + return "Document[numPages=" + size() + "]"; + } + + @Override + public boolean equals(Object o) { + if (o == this) + return true; + if (o instanceof Document) { + return pages.equals(((Document)o).pages); + } + return false; + } + + @Override + public int hashCode() { + return pages.hashCode(); + } + + @Override + protected void finalize() { + unload(); + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/GSFileFilter.java b/demos/java/gsviewer/src/com/artifex/gsviewer/GSFileFilter.java new file mode 100644 index 00000000..85033c5a --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/GSFileFilter.java @@ -0,0 +1,50 @@ +package com.artifex.gsviewer; + +import java.io.File; + +import javax.swing.filechooser.FileFilter; + +/** + * <p>A file filter used for the file choose to only accept certain + * file extensions.</p> + * + * <p>This file filter only accepts files of type ".pdf", ".eps", ".ps", + * ".xps", ".oxps", and ".bin"</p> + * + * @author Ethan Vrhel + * + */ +public class GSFileFilter extends FileFilter { + + /** + * An instance of the file filter. + */ + public static final GSFileFilter INSTANCE = new GSFileFilter(); + + @Override + public boolean accept(File f) { + if (f.isDirectory()) + return true; + final String name = f.getName(); + final int ind = name.lastIndexOf('.'); + if (ind < 0) + return false; + final String ext = name.substring(ind); + return + equals(ext, ".pdf") || + equals(ext, ".eps") || + equals(ext, ".ps") || + equals(ext, ".xps") || + equals(ext, ".oxps") || + equals(ext, ".bin"); + } + + @Override + public String getDescription() { + return "Ghostscript Files"; + } + + private boolean equals(String extension, String compare) { + return extension.equalsIgnoreCase(compare); + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/ImageUtil.java b/demos/java/gsviewer/src/com/artifex/gsviewer/ImageUtil.java new file mode 100644 index 00000000..3754d6f7 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/ImageUtil.java @@ -0,0 +1,45 @@ +package com.artifex.gsviewer; + +import java.awt.Point; +import java.awt.color.ColorSpace; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; + +public class ImageUtil { + + public static BufferedImage createImage(final byte[] data, final ImageParams params) { + final DataBuffer dataBuffer = new DataBufferByte(data, data.length); + final WritableRaster wraster = Raster.createInterleavedRaster(dataBuffer, params.width, + params.height, params.raster, 3, new int[] { 0, 1, 2 }, new Point()); + final ColorModel model = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), + new int[] { 8, 8, 8 }, false, false, ColorModel.OPAQUE, DataBuffer.TYPE_BYTE); + + return new BufferedImage(model, wraster, false, null); + } + + public static class ImageParams { + public int width; + public int height; + public int raster; + public int format; + + public ImageParams() { + this(0, 0, 0, 0); + } + + public ImageParams(final int width, final int height, final int raster, final int format) { + this.width = width; + this.height = height; + this.raster = raster; + this.format = format; + } + } + + private ImageUtil() { } + +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Main.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Main.java new file mode 100644 index 00000000..beecdd3b --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Main.java @@ -0,0 +1,42 @@ +package com.artifex.gsviewer; + +import java.io.IOException; + +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +import com.artifex.gsviewer.gui.ViewerWindow; + +public class Main { + + public static void main(String[] args) { + Runtime.getRuntime().addShutdownHook(new Thread(new Shutdown())); + + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException + | UnsupportedLookAndFeelException e) { + System.err.println("Failed to set Look and Feel: " + e); + } + + ViewerWindow win = new ViewerWindow(new ViewerController()); + SwingUtilities.invokeLater(() -> { + win.setVisible(true); + }); + } + + private static class Shutdown implements Runnable { + + @Override + public void run() { + try { + Settings.SETTINGS.save(); + } catch (IOException e) { + System.err.println("Failed to write settings file"); + e.printStackTrace(); + } + } + + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/PDFFileFilter.java b/demos/java/gsviewer/src/com/artifex/gsviewer/PDFFileFilter.java new file mode 100644 index 00000000..e7bd7046 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/PDFFileFilter.java @@ -0,0 +1,28 @@ +package com.artifex.gsviewer; + +import java.io.File; + +import javax.swing.filechooser.FileFilter; + +public class PDFFileFilter extends FileFilter { + + public static final PDFFileFilter INSTANCE = new PDFFileFilter(); + + @Override + public boolean accept(File f) { + if (f.isDirectory()) + return true; + String filename = f.getName(); + int ind = filename.lastIndexOf('.'); + if (ind == -1) + return false; + String ext = filename.substring(ind); + return ext.equalsIgnoreCase(".pdf"); + } + + @Override + public String getDescription() { + return "PDF Files"; + } + +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Page.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Page.java new file mode 100644 index 00000000..a3435f56 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Page.java @@ -0,0 +1,359 @@ +package com.artifex.gsviewer; + +import java.awt.Dimension; +import java.awt.image.BufferedImage; +import java.util.Collection; +import java.util.HashSet; + +import com.artifex.gsviewer.ImageUtil.ImageParams; + +/** + * A Page represents an individual page within a Document. It stores a high resolution image, + * a low resolution preview image, and a zoomed image if the viewer is zoomed. + * + * @author Ethan Vrhel + * + */ +public class Page { + + /** + * The high-resolution DPI to use. + */ + public static final int PAGE_HIGH_DPI = 72; + + /** + * The low-resolution DPI to use. + */ + public static final int PAGE_LOW_DPI = 10; + + /** + * Converts a dpi value to a Ghostscript-friendly string. + * + * @param dpi The dpi to convert. + * @return The respective string. + */ + public static String toDPIString(int dpi) { + return "[" + dpi + " " + dpi + "]"; + } + + private volatile BufferedImage lowRes; // The low resolution image + private volatile BufferedImage highRes; // The high resolution image + private volatile BufferedImage zoomed; // The zoomed image based on the zoom of the viewer + + private Collection<PageUpdateCallback> callbacks; // The page callbacks + + /** + * Creates a new page with now low-resolution or high-resolution image. + */ + public Page() { + this(null, null); + } + + /** + * Creates a new page with a low-resolution image. + * + * @param lowRes The low-resolution image. + */ + public Page(final BufferedImage lowRes) { + this(lowRes, null); + } + + /** + * Creates a new page with a low-resolution image and a high-resolution image. + * + * @param lowRes The low-resolution image. + * @param highRes The high-resolution image. + */ + public Page(final BufferedImage lowRes, final BufferedImage highRes) { + this.lowRes = lowRes; + this.highRes = highRes; + this.callbacks = new HashSet<>(); + } + + /** + * Loads a high resolution image from data. + * + * @param data The raw image data. + * @param width The width of the image. + * @param height The height of the image. + * @param raster The length of one line of the image in bytes. + * @param format The image format. + */ + public void loadHighRes(final byte[] data, final int width, final int height, final int raster, final int format) { + setHighRes(ImageUtil.createImage(data, new ImageParams(width, height, raster, format))); + } + + /** + * Sets the high resolution image + * + * @param highRes An image. + */ + public void setHighRes(final BufferedImage highRes) { + unloadHighRes(); + this.highRes = highRes; + for (PageUpdateCallback cb : callbacks) { + cb.onLoadHighRes(); + cb.onPageUpdate(); + } + } + + /** + * Unloads the high-resolution image. If none is loaded, this method + * does nothing. + */ + public void unloadHighRes() { + if (highRes != null) { + highRes.flush(); + highRes = null; + for (PageUpdateCallback cb : callbacks) { + cb.onUnloadHighRes(); + cb.onPageUpdate(); + } + } + } + + /** + * Loads a low resolution image from data. + * + * @param data The raw image data. + * @param width The width of the image. + * @param height The height of the image. + * @param raster The length of one line of the image in bytes. + * @param format The image format. + */ + public void loadLowRes(final byte[] data, final int width, final int height, final int raster, final int format) { + setLowRes(ImageUtil.createImage(data, new ImageParams(width, height, raster, format))); + } + + /** + * Sets the low resolution image + * + * @param lowRes An image. + */ + public void setLowRes(final BufferedImage lowRes) { + unloadLowRes(); + this.lowRes = lowRes; + for (PageUpdateCallback cb : callbacks) { + cb.onLoadLowRes(); + cb.onPageUpdate(); + } + } + + /** + * Unloads the low-resolution image. If none is loaded, this method + * does nothing. + */ + public void unloadLowRes() { + if (lowRes != null) { + lowRes.flush(); + lowRes = null; + for (PageUpdateCallback cb : callbacks) { + cb.onUnloadLowRes(); + cb.onPageUpdate(); + } + } + } + + /** + * Loads a zoomed image from data. + * + * @param data The raw image data. + * @param width The width of the image. + * @param height The height of the image. + * @param raster The length of one line of the image in bytes. + * @param format The image format. + */ + public void loadZoomed(final byte[] data, final int width, final int height, + final int raster, final int format) { + setZoomed(ImageUtil.createImage(data, new ImageParams(width, height, raster, format))); + } + + /** + * Sets the zoomed image + * + * @param zoomed An image. + */ + public void setZoomed(final BufferedImage zoomed) { + unloadZoomed(); + this.zoomed = zoomed; + for (PageUpdateCallback cb : callbacks) { + cb.onLoadZoomed(); + cb.onPageUpdate(); + } + } + + /** + * Unloads the zoomed image. If none is loaded, this method + * does nothing. + */ + public void unloadZoomed() { + if (zoomed != null) { + zoomed.flush(); + zoomed = null; + for (PageUpdateCallback cb : callbacks) { + cb.onUnloadZoomed(); + cb.onPageUpdate(); + } + } + } + + /** + * Unloads all images. If no images are loaded, this method + * does nothing. + */ + public void unloadAll() { + unloadLowRes(); + unloadHighRes(); + unloadZoomed(); + } + + /** + * Returns the current low-resolution image. + * + * @return The current low-resolution image, or <code>null</code> + * if none is loaded. + */ + public BufferedImage getLowResImage() { + return lowRes; + } + + /** + * Returns the current high-resolution image. + * + * @return The current high-resolution image, or <code>null</code> + * if none is loaded. + */ + public BufferedImage getHighResImage() { + return highRes; + } + + /** + * Returns the current zoomed image. + * + * @return The current zoomed image, or <code>null</code> + * if none is loaded. + */ + public BufferedImage getZoomedImage() { + return zoomed; + } + + /** + * Returns the non-zoomed highest resolution image which can be + * displayed. + * + * @return The highest resolution, non-zoomed image which can be + * displayed. If no non-zoomed images are loaded, <code>null</code> + * is returned. + */ + public BufferedImage getDisplayableImage() { + return highRes == null ? lowRes : highRes; + } + + /** + * Returns the size of the low-resolution image. + * + * @return The size of the low-resolution image, or <code>null</code> + * if it is not loaded. + */ + public Dimension getLowResSize() { + return lowRes == null ? null : new Dimension(lowRes.getWidth(), lowRes.getHeight()); + } + + /** + * Returns the size of the high-resolution image. + * + * @return The size of the high-resolution image, or <code>null</code> + * if it is not loaded. + */ + public Dimension getHighResSize() { + return highRes == null ? null : new Dimension(highRes.getWidth(), highRes.getHeight()); + } + + /** + * Returns the size of the zoomed image. + * + * @return The size of the zoomed image, or <code>null</code> + * if it is not loaded. + */ + public Dimension getZoomedSize() { + return zoomed == null ? null : new Dimension(zoomed.getWidth(), zoomed.getHeight()); + } + + /** + * Returns the size of the non-zoomed highest resolution image which + * can be displayed. + * + * @return The size of the highest resolution, non-zoomed image which + * can be displayed. If no non-zoomed images are loaded, <code>null</code> + * is returned. + */ + public Dimension getDisplayableSize() { + return highRes == null ? getLowResSize() : getHighResSize(); + } + + /** + * Returns the actual size of the image. + * + * @return The size of the page, or <code>null</code> if no images are + * loaded. + */ + public Dimension getSize() { + Dimension size = getHighResSize(); + if (size != null) + return size; + size = getLowResSize(); + if (size == null) + return new Dimension(0, 0); + return new Dimension(size.width * PAGE_HIGH_DPI / PAGE_LOW_DPI, + size.height * PAGE_HIGH_DPI / PAGE_LOW_DPI); + } + + /** + * Adds a <code>PageUpdateCallback</code> to receive callbacks regarding + * page change events. + * + * @param cb The callback to add. + */ + public void addCallback(PageUpdateCallback cb) { + callbacks.add(cb); + cb.onPageUpdate(); + } + + /** + * Removes a callback added through <code>addCallback</code>. If the supplied + * callback was not added, this method does nothing. + * + * @param cb The callback to remove. + */ + public void removeCallback(PageUpdateCallback cb) { + callbacks.remove(cb); + } + + @Override + public String toString() { + return "Page[lowResLoaded=" + (lowRes != null) + ",highResLoaded=" + (highRes != null) + "]"; + } + + @Override + public boolean equals(Object o) { + if (o == this) + return true; + if (o instanceof Page) { + Page p = (Page)o; + boolean first = lowRes == null ? p.lowRes == null : lowRes.equals(p.lowRes); + boolean second = highRes == null ? p.highRes == null : highRes.equals(p.highRes); + return first && second; + } + return false; + } + + @Override + public int hashCode() { + return (lowRes == null ? 0 : lowRes.hashCode()) + (highRes == null ? 0 : highRes.hashCode()); + } + + @Override + public void finalize() { + unloadAll(); + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/PageUpdateCallback.java b/demos/java/gsviewer/src/com/artifex/gsviewer/PageUpdateCallback.java new file mode 100644 index 00000000..6efaf69e --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/PageUpdateCallback.java @@ -0,0 +1,15 @@ +package com.artifex.gsviewer; + +public interface PageUpdateCallback { + + public void onPageUpdate(); + + public void onLoadLowRes(); + public void onUnloadLowRes(); + + public void onLoadHighRes(); + public void onUnloadHighRes(); + + public void onLoadZoomed(); + public void onUnloadZoomed(); +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Settings.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Settings.java new file mode 100644 index 00000000..13f6d6b7 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Settings.java @@ -0,0 +1,142 @@ +package com.artifex.gsviewer; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; + +public class Settings { + + public static final String SETTINGS_FILE = "gsviewer.cfg"; + + public static final Settings SETTINGS; + + static { + SETTINGS = new Settings(SETTINGS_FILE); + } + + private Map<String, Object> settingsMap; + private String filename; + + private Settings(String filename) { + this.filename = filename; + this.settingsMap = new HashMap<>(); + loadDefaultSettings(); + + File f = new File(filename); + if (!f.exists()) + return; + + try { + InputStream in = new FileInputStream(filename); + int b; + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + + while ((b = in.read()) != -1) { + bout.write(b); + } + + in.close(); + bout.close(); + + byte[] array = bout.toByteArray(); + loadFromString(new String(array)); + } catch (IOException e) { + throw new IllegalStateException("Failed to load settings file: " + SETTINGS_FILE, e); + } + } + + private void loadDefaultSettings() { + putSetting("scrollSens", 50); + putSetting("preloadRange", 2); + putSetting("antialiasing", true); + } + + private void loadFromString(String data) { + String[] lines = data.split("\n"); + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + String[] tokens = line.split(" "); + if (tokens.length != 3) + throw new IllegalStateException("Malformed settings file (line " + (i + 1) + ")"); + try { + switch (tokens[0]) { + case "int": + putSetting(tokens[1], Integer.parseInt(tokens[2])); + break; + case "double": + putSetting(tokens[1], Double.parseDouble(tokens[2])); + break; + case "bool": + putSetting(tokens[1], Boolean.parseBoolean(tokens[2])); + break; + default: + throw new IllegalStateException("Invalid type specifier \"" + tokens[0] + "\" (line " + (i + 1) + ")"); + } + } catch (NumberFormatException e) { + throw new IllegalStateException("Invalid value \"" + tokens[2] + "\" for type " + + tokens[0] + " (line " + (i + 1) + ")", e); + } + } + } + + /** + * Returns the value of a setting of type name <code>key</code>. + * + * @param <T> The type of setting stored. + * @param key The name of the setting. + * @return The respective setting, casted to <code>T</code>. + */ + @SuppressWarnings("unchecked") + public <T> T getSetting(String key) { + return (T)settingsMap.get(key); + } + + public void putSetting(String key, Object value) { + settingsMap.put(key, value); + } + + public void setSetting(String key, Object value) throws IllegalArgumentException { + if (settingsMap.get(key) == null) { + putSetting(key, value); + } else if (settingsMap.get(key).getClass() == value.getClass()) { + putSetting(key, value); + } else { + throw new IllegalArgumentException("value is not type " + + settingsMap.get(key).getClass().getName() + " (got " + (value == null ? "null" : value.getClass().getName()) + ")"); + } + } + + public void save() throws IOException { + StringBuilder data = new StringBuilder(); + + for (String setting : settingsMap.keySet()) { + Object value = settingsMap.get(setting); + if (value.getClass() == Integer.class) { + data.append("int "); + } else if (value.getClass() == Double.class) { + data.append("double "); + } else if (value.getClass() == Boolean.class) { + data.append("bool "); + } + data.append(setting); + data.append(' '); + data.append(value); + data.append('\n'); + } + + OutputStream out = new FileOutputStream(filename); + out.write(data.toString().getBytes()); + out.close(); + } + + @Override + public String toString() { + return settingsMap.toString() + " at " + filename; + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/StdIO.java b/demos/java/gsviewer/src/com/artifex/gsviewer/StdIO.java new file mode 100644 index 00000000..4ea1b205 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/StdIO.java @@ -0,0 +1,38 @@ +package com.artifex.gsviewer; + +import com.artifex.gsjava.callbacks.IStdErrFunction; +import com.artifex.gsjava.callbacks.IStdInFunction; +import com.artifex.gsjava.callbacks.IStdOutFunction; + +/** + * Implementation of <code>IStdOutFunction</code>, <code>IStdErrFunction</code>, and + * <code>IStdInFunction</code> to get IO data from Ghostscript. + * + * @author Ethan Vrhel + * + */ +public class StdIO implements IStdOutFunction, IStdErrFunction, IStdInFunction { + + public static final boolean ENABLE_STD_OUT_IO = false; + public static final boolean ENABLE_STD_ERR_IO = true; + + @Override + public int onStdIn(long callerHandle, byte[] buf, int len) { + return len; + } + + @Override + public int onStdErr(long callerHandle, byte[] str, int len) { + if (ENABLE_STD_ERR_IO) + System.err.println(new String(str)); + return len; + } + + @Override + public int onStdOut(long callerHandle, byte[] str, int len) { + if (ENABLE_STD_OUT_IO) + System.out.println(new String(str)); + return len; + } + +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java b/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java new file mode 100644 index 00000000..f2801426 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java @@ -0,0 +1,372 @@ +package com.artifex.gsviewer; + +import java.awt.HeadlessException; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintStream; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import javax.swing.JFileChooser; +import com.artifex.gsviewer.gui.SettingsDialog; +import com.artifex.gsviewer.gui.ViewerGUIListener; +import com.artifex.gsviewer.gui.ViewerWindow; + +/** + * The ViewerController is an implementation of a <code>ViewerGUIListener</code> + * used to control the main logic of the viewer such as determining what pages + * should be loaded. + * + * @author Ethan Vrhel + * + */ +public class ViewerController implements ViewerGUIListener { + + /** + * The lock for the SmartLoader. + */ + private static final Lock lock = new ReentrantLock(); + + /** + * The condition variable for the SmartLoader to signal when an operation + * needs to happen. + */ + private static final Condition cv = lock.newCondition(); + + /** + * The flag for the smart loader to read after completing an operation. If + * this flag is <code>true</code>, the SmartLoader will skip waiting for + * <code>cv</code> to be signaled and will immediately continue to the next + * operation. + */ + private static volatile boolean outOfDate = true; + + private ViewerWindow source; // The viewer window where documents will be displayed + private Document currentDocument; // The current document loaded in the viewer + private SmartLoader smartLoader; // The SmartLoader used to load pages based on scroll and zoom + private boolean loadingDocument; + + /** + * <p>Opens a document from a files asynchronously.</p> + * + * <p>This method handles distilling files if they should be distilled and the user + * chooses to distill them.</p> + * + * @param file The file to load. + * @throws NullPointerException When <code>file</code> is <code>null</code>. + * @throws IllegalArgumentException If <code>file</code> is not a file type which can be loaded + * into the viewer, if distilling occurs and fails. + * @throws FileNotFoundException When <code>file</code> does not exist. + * @throws IOException If distilling occurs and a temporary files to be created. + * @throws HeadlessException If distilling occurs and <code>GraphicsEnvironment.isHeadless()</code> returns + * <code>true</code>. + * @throws RuntimeException When an error occurs while launching the loader thread. + */ + public void open(File file) + throws NullPointerException, IllegalArgumentException, FileNotFoundException, IOException, + HeadlessException, RuntimeException { + if (loadingDocument) { + source.showWarningDialog("Error", "A document is already loading"); + return; + } + if (Document.shouldDistill(file)) { + int ret = source.showConfirmDialog("Distill", "Would you like to distill this document before opening?"); + if (ret == ViewerWindow.CANCEL) + return; + else if (ret == ViewerWindow.YES) { + try { + JFileChooser chooser = new JFileChooser(); + chooser.setCurrentDirectory(new File(".")); + chooser.setFileFilter(PDFFileFilter.INSTANCE); + ret = chooser.showSaveDialog(source); + if (ret != JFileChooser.APPROVE_OPTION) + return; + File out = chooser.getSelectedFile(); + String filepath = out.getAbsolutePath(); + if (filepath.lastIndexOf('.') == -1) + out = new File(filepath + ".pdf"); + if (out.exists()) { + ret = source.showConfirmDialog("Overwrite?", out.getName() + " already exists. Overwrite?"); + if (ret != ViewerWindow.YES) + return; + } + if (currentDocument != null) + close(); + file = Document.distillDocument(file, out); + } catch (IllegalStateException | IOException e) { + System.err.println("Failed to distill: " + e); + } + } + } + + if (currentDocument != null) + close(); + loadingDocument = true; + Document.loadDocumentAsync(file, (final Document doc, final Exception exception) -> { + try { + source.loadDocumentToViewer(doc); + source.setLoadProgress(0); + if (exception != null) { + throw new RuntimeException("Failed to load", exception); + //source.showErrorDialog("Failed to load", exception.toString()); + } else { + this.currentDocument = doc; + dispatchSmartLoader(); + } + source.revalidate(); + } finally { + loadingDocument = false; + } + }, (int progress) -> { + source.setLoadProgress(progress); + }, Document.OPERATION_RETURN); + } + + /** + * Closes the currently loaded document, if one is loaded. If no document + * is loaded, this method does nothing. + */ + public void close() { + if (loadingDocument) { + source.showWarningDialog("Error", "A document is already loading"); + return; + } + + if (smartLoader != null) { + smartLoader.stop(); + smartLoader = null; + } + + if (currentDocument != null) { + source.loadDocumentToViewer(null); + currentDocument.unload(); + currentDocument = null; + } + } + + /** + * Returns the current document being viewed. + * + * @return The current document being viewed or <code>null</code> if + * no document is being viewed. + */ + public Document getCurrentDocument() { + return currentDocument; + } + + @Override + public void onViewerAdd(ViewerWindow source) { + this.source = source; + Thread.setDefaultUncaughtExceptionHandler(new UnhandledExceptionHandler()); + } + + @Override + public void onPageChange(int oldPage, int newPage) { + smartLoader.signalOutOfDate(); + } + + @Override + public void onZoomChange(double oldZoom, double newZoom) { + if (newZoom > 1.0) { + smartLoader.resetZoom(); + smartLoader.signalOutOfDate(); + } + } + + @Override + public void onScrollChange(int newScroll) { + if (smartLoader != null) + smartLoader.signalOutOfDate(); + } + + @Override + public void onOpenFile() { + JFileChooser chooser = new JFileChooser(); + chooser.setFileFilter(GSFileFilter.INSTANCE); + chooser.setCurrentDirectory(new File("").getAbsoluteFile()); + int status = chooser.showOpenDialog(source); + if (status == JFileChooser.APPROVE_OPTION) { + try { + open(chooser.getSelectedFile()); + } catch (IOException | RuntimeException e) { + source.showErrorDialog("Failed to Open", "Failed to open file (" + e + ")"); + } + } + } + + @Override + public void onCloseFile() { + close(); + } + + @Override + public void onClosing() { + source.dispose(); + System.exit(0); + } + + @Override + public void onSettingsOpen() { + SettingsDialog dialog = new SettingsDialog(source, true); + dialog.setVisible(true); + } + + /** + * Starts the SmartLoader on the currently loaded document. If a + * SmartLoader already exists, it will be stopped. + */ + private void dispatchSmartLoader() { + if (smartLoader != null) + smartLoader.stop(); + smartLoader = new SmartLoader(currentDocument); + smartLoader.start(); + } + + /** + * Implementation of <code>Thread.UncaughtExceptionHandler</code> to handle unhandled + * exceptions. This is used to show an error dialog to the user describing the error + * and then routes the error to the instance of the <code>DefaultUnhandledExceptionHandler</code>. + * + * @author Ethan Vrhel + * + */ + private class UnhandledExceptionHandler implements Thread.UncaughtExceptionHandler { + + @Override + public void uncaughtException(Thread t, Throwable e) { + e.printStackTrace(System.err); + if (source != null) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(os); + e.printStackTrace(out); + String errorMessage = new String(os.toByteArray()); + source.showErrorDialog("Unhandled Exception", errorMessage); + } + DefaultUnhandledExceptionHandler.INSTANCE.uncaughtException(t, e); + } + + } + + private class SmartLoader implements Runnable { + + private volatile boolean[] loaded; + private volatile boolean[] zoomLoaded; + private volatile boolean shouldRun; + private Thread thread; + + SmartLoader(Document doc) { + loaded = new boolean[doc.size()]; + zoomLoaded = new boolean[doc.size()]; + shouldRun = true; + } + + void start() { + if (thread != null) + stop(); + shouldRun = true; + thread = new Thread(this); + thread.setDaemon(true); + thread.setName("Document-Smart-Loader-Thread"); + thread.start(); + } + + void stop() { + lock.lock(); + cv.signalAll(); + lock.unlock(); + outOfDate = false; + shouldRun = false; + try { + thread.join(); + } catch (InterruptedException e) { + throw new RuntimeException("Thread join interrupted", e); + } + thread = null; + } + + void resetZoom() { + for (int i = 0; i < zoomLoaded.length; i++) { + zoomLoaded[i] = false; + } + } + + void signalOutOfDate() { + outOfDate = true; + lock.lock(); + try { + cv.signalAll(); + } catch (IllegalMonitorStateException e) { + System.err.println("Exception on signaling: " + e); + } finally { + lock.unlock(); + } + } + + @Override + public void run() { + System.out.println("Smart loader dispatched."); + while (shouldRun) { + int currentPage = source.getCurrentPage(); + int[] toLoad = genToLoad(currentPage); + + if (loaded.length != currentDocument.size()) + throw new IllegalStateException("Array is size " + loaded.length + " while doc size is " + currentDocument.size()); + + int ind = 0; + for (int page : toLoad) { + if (page >= 1 && page <= currentDocument.size()) { + if (source.getZoom() > 1.0) { + + // Load the zoomed page view only if it has not already been loaded. + if (!zoomLoaded[page - 1]) { + currentDocument.zoomArea(Document.OPERATION_WAIT, page, source.getZoom()); + zoomLoaded[page - 1] = true; + } + } else { + + // Unload any zoomed image to save memory consumption + currentDocument.unloadZoomed(page); + + // Load the high-resolution page view only if it has not already been loaded + if (!loaded[page - 1]) { + currentDocument.loadHighRes(Document.OPERATION_WAIT, page); + loaded[page - 1] = true; + } + } + } + ind++; + source.setLoadProgress((int)(((double)ind / toLoad.length) * 100)); + } + source.setLoadProgress(0); + + // First check if the current view is out of date and if so, just immediately continue + // so the thread does not get stuck in the lock until another event has occurred. + if (!outOfDate) { + outOfDate = false; + lock.lock(); + try { + cv.await(); + } catch (InterruptedException e) { + System.err.println("Interrupted in smart loader: " + e); + } finally { + lock.unlock(); + } + } else { + outOfDate = false; + } + } + } + + int[] genToLoad(int page) { + int range = Settings.SETTINGS.getSetting("preloadRange"); + int[] arr = new int[range * 2 + 1]; + for (int i = -range; i <= range; i++) { + arr[i + range] = page + i; + } + return arr; + } + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ScrollMap.java b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ScrollMap.java new file mode 100644 index 00000000..4e0dd5d4 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ScrollMap.java @@ -0,0 +1,142 @@ +package com.artifex.gsviewer.gui; + +import java.awt.Dimension; +import java.util.Arrays; +import java.util.Objects; + +import javax.swing.JComponent; +import javax.swing.JScrollBar; +import javax.swing.JScrollPane; + +import com.artifex.gsviewer.Document; + +/** + * A ScrollMap stores information on how far down a scroll bar + * a certain page is in a viewer. + * + * @author Ethan Vrhel + * + */ +public class ScrollMap { + + private final Document document; // The document which is being viewed + private final ViewerWindow window; // The window containing the scroll pane + private final int gap; // The gap in between each page + private int[] scrollMap; // A map mapping page indices to scroll values + + /** + * Creates and generates a new ScrollMap at zoom 1.0. + * + * @param document The document to generate the map from. + * @param window The viewer window to receive scroll panes from. + * @param gap The gap in between pages. + */ + public ScrollMap(final Document document, final ViewerWindow window, final int gap) { + this.document = Objects.requireNonNull(document, "document"); + this.scrollMap = null; + this.window = Objects.requireNonNull(window, "window"); + this.gap = gap; + genMap(1.0); + } + + /** + * Generates a map at a given zoom amount. + * + * @param zoom The amount that the document is zoomed in. + * @throws IllegalArgumentException If <code>zoom</code> is less than + * 0 or greater than 2. + */ + public synchronized void genMap(final double zoom) throws IllegalArgumentException { + if (zoom < 0.0 || zoom > 2.0) + throw new IllegalArgumentException("0.0 < zoom < 2.0"); + scrollMap = new int[document.size()]; + int currentScroll = 0; + for (int pageNum = 0; pageNum < document.size(); pageNum++) { + final JComponent component = window.getPageComponent(pageNum + 1); + if (component == null) + throw new NullPointerException("component is null!"); + final Dimension cSize = component.getSize(); + + scrollMap[pageNum] = currentScroll; + currentScroll += cSize.height * zoom; + currentScroll += gap; + } + } + + /** + * Returns the amount of scroll on the scroll pane at which page + * <code>page</code> is visible. + * + * @param page The page to get the scroll value for. + * @return The respective value. + * @throws IndexOutOfBoundsException If <code>page</code> is not a page + * in the document. + */ + public synchronized int getScroll(int page) throws IndexOutOfBoundsException { + if (page < 1 || page > scrollMap.length) + throw new IndexOutOfBoundsException("page = " + page); + return scrollMap[page - 1]; + } + + /** + * Returns the current page scrolled to in the scroll pane. + * + * @return The current page scrolled to. + */ + public synchronized int getCurrentPage() { + final JScrollPane scrollPane = window.getViewerScrollPane(); + final JScrollBar vScrollBar = scrollPane.getVerticalScrollBar(); + final int scrollValue = vScrollBar.getValue(); + return getPageFor(scrollValue); + } + + /** + * Returns the page for a given scroll value. + * + * @param scroll The scroll value to get the page for. + * @return The respective page. + */ + public synchronized int getPageFor(int scroll) { + for (int i = 0; i < scrollMap.length; i++) { + if (scroll < scrollMap[i]) + return i; /* Not i + 1! */ + } + return scrollMap.length; + } + + /** + * Automatically scrolls the scroll pane inside the viewer to the + * given page. + * + * @param page The page to srcoll to. + * @throws IndexOutOfBoundsException When <code>page</code> is not in + * the document. + */ + public synchronized void scrollTo(int page) throws IndexOutOfBoundsException { + if (page < 1 || page > scrollMap.length) + throw new IndexOutOfBoundsException("page = " + page); + final int scroll = scrollMap[page - 1]; + final JScrollPane scrollPane = window.getViewerScrollPane(); + final JScrollBar vScrollBar = scrollPane.getVerticalScrollBar(); + vScrollBar.setValue(scroll); + } + + /** + * Returns a copy of the array backing the scroll map, or + * <code>null</code> if none has been generated. + * + * @return A copy of the scroll map's backing array. + */ + public synchronized int[] getMap() { + if (scrollMap == null) + return null; + final int[] copy = new int[this.scrollMap.length]; + System.arraycopy(scrollMap, 0, copy, 0, scrollMap.length); + return copy; + } + + @Override + public String toString() { + return "ScrollMap[map=" + Arrays.toString(scrollMap) + "]"; + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/SettingsDialog.java b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/SettingsDialog.java new file mode 100644 index 00000000..a4ee5d82 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/SettingsDialog.java @@ -0,0 +1,241 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.artifex.gsviewer.gui; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import com.artifex.gsviewer.Settings; + +/** + * The settings dialog + * + * @author Ethan Vrhel + */ +public class SettingsDialog extends javax.swing.JDialog { + + private static final long serialVersionUID = 1L; + + /** + * Creates new form SettingsDialog + */ + public SettingsDialog(java.awt.Frame parent, boolean modal) { + super(parent, modal); + initComponents(); + setLocationRelativeTo(parent); + + scrollSensitivitySlider.addMouseListener(new MouseAdapter() { + + @Override + public void mouseReleased(MouseEvent e) { + scrollSensitvityField + .setText(new StringBuilder().append(scrollSensitivitySlider.getValue()).toString()); + } + }); + + init(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + + // <editor-fold defaultstate="collapsed" desc="Generated Code"> + private void initComponents() { + + scrollSensitivityLabel = new javax.swing.JLabel(); + antialiasingCheckbox = new javax.swing.JCheckBox(); + cancelButton = new javax.swing.JButton(); + applyButton = new javax.swing.JButton(); + okButton = new javax.swing.JButton(); + preloadRangeLabel = new javax.swing.JLabel(); + scrollSensitivitySlider = new javax.swing.JSlider(); + scrollSensitvityField = new javax.swing.JTextField(); + preloadRangeSpinner = new javax.swing.JSpinner(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Settings"); + setModalityType(java.awt.Dialog.ModalityType.APPLICATION_MODAL); + setResizable(false); + + scrollSensitivityLabel.setText("Scroll Sensitivity"); + + antialiasingCheckbox.setText("Antialiasing"); + antialiasingCheckbox.setHideActionText(true); + antialiasingCheckbox.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); + antialiasingCheckbox.setMargin(new java.awt.Insets(0, 0, 0, 0)); + + cancelButton.setText("Cancel"); + cancelButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + cancelButtonActionPerformed(evt); + } + }); + + applyButton.setText("Apply"); + applyButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + applyButtonActionPerformed(evt); + } + }); + + okButton.setText("OK"); + okButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + okButtonActionPerformed(evt); + } + }); + + preloadRangeLabel.setText("Preload Range"); + + scrollSensitivitySlider.setMaximum(200); + scrollSensitivitySlider.setMinimum(1); + scrollSensitivitySlider.setToolTipText("The number of pixels to scroll"); + + scrollSensitvityField.addKeyListener(new java.awt.event.KeyAdapter() { + @Override + public void keyPressed(java.awt.event.KeyEvent evt) { + scrollSensitvityFieldKeyPressed(evt); + } + }); + + preloadRangeSpinner.setToolTipText("The range for loading out of view pages"); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout + .createSequentialGroup().addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout + .createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(scrollSensitivityLabel).addComponent(preloadRangeLabel) + .addComponent(antialiasingCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 79, + javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(43, 43, 43) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(scrollSensitivitySlider, javax.swing.GroupLayout.PREFERRED_SIZE, + 126, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(scrollSensitvityField, javax.swing.GroupLayout.DEFAULT_SIZE, 69, + Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addComponent(preloadRangeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 40, + javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)))) + .addGroup( + layout.createSequentialGroup().addComponent(cancelButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, + javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(applyButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 51, + javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(3, 3, 3))) + .addContainerGap())); + layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout + .createSequentialGroup().addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup().addComponent(scrollSensitivityLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(preloadRangeLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(antialiasingCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cancelButton).addComponent(applyButton).addComponent(okButton))) + .addGroup(layout.createSequentialGroup().addGroup(layout + .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(scrollSensitivitySlider, javax.swing.GroupLayout.PREFERRED_SIZE, + javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(scrollSensitvityField, javax.swing.GroupLayout.Alignment.TRAILING, + javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, + javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(preloadRangeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, + javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))); + + pack(); + }// </editor-fold> + + private void okButtonActionPerformed(java.awt.event.ActionEvent evt) { + apply(); + dispose(); + } + + private void applyButtonActionPerformed(java.awt.event.ActionEvent evt) { + apply(); + } + + private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) { + dispose(); + } + + private void scrollSensitvityFieldKeyPressed(java.awt.event.KeyEvent evt) { + try { + int val = Integer.parseInt(scrollSensitvityField.getText()); + val = Math.max(Math.min(val, 200), 1); + scrollSensitivitySlider.setValue(val); + } catch (NumberFormatException e) { + } + } + + // Variables declaration - do not modify + private javax.swing.JCheckBox antialiasingCheckbox; + private javax.swing.JButton applyButton; + private javax.swing.JButton cancelButton; + private javax.swing.JButton okButton; + private javax.swing.JLabel preloadRangeLabel; + private javax.swing.JSpinner preloadRangeSpinner; + private javax.swing.JLabel scrollSensitivityLabel; + private javax.swing.JSlider scrollSensitivitySlider; + private javax.swing.JTextField scrollSensitvityField; + // End of variables declaration + + private void init() { + Settings settings = Settings.SETTINGS; + int scrollSens = settings.getSetting("scrollSens"); + int preloadRange = settings.getSetting("preloadRange"); + boolean antialiasing = settings.getSetting("antialiasing"); + + scrollSensitvityField.setText(new StringBuilder().append(scrollSens).toString()); + scrollSensitivitySlider.setValue(scrollSens); + + preloadRangeSpinner.setValue(preloadRange); + + antialiasingCheckbox.setSelected(antialiasing); + } + + private void apply() { + Settings settings = Settings.SETTINGS; + Integer scrollSens = settings.getSetting("scrollSens"); + Integer preloadRange = settings.getSetting("preloadRange"); + Boolean antialiasing = settings.getSetting("antialiasing"); + + try { + scrollSens = Integer.parseInt(scrollSensitvityField.getText()); + } catch (NumberFormatException e) { + } + + try { + int set = (Integer) preloadRangeSpinner.getValue(); + preloadRange = set >= 0 ? set : 0; + } catch (ClassCastException e) { + } + + antialiasing = antialiasingCheckbox.isSelected(); + + settings.setSetting("scrollSens", scrollSens); + settings.setSetting("preloadRange", preloadRange); + settings.setSetting("antialiasing", antialiasing); + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerGUIListener.java b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerGUIListener.java new file mode 100644 index 00000000..5a169731 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerGUIListener.java @@ -0,0 +1,61 @@ +package com.artifex.gsviewer.gui; + +/** + * This interface provides several methods which are used to listen + * for events on a <code>ViewerWindow</code>. + * + * @author Ethan Vrhel + * + */ +public interface ViewerGUIListener { + + /** + * Called when this listener is added to a <code>ViewerWindow</code>. + * + * @param source The window added to. + */ + public void onViewerAdd(ViewerWindow source); + + /** + * Called when the user scrolls to a new page. + * + * @param oldPage The old page. + * @param newPage The new page. + */ + public void onPageChange(int oldPage, int newPage); + + /** + * Called when the zoom value changes. + * + * @param oldZoom The old zoom value. + * @param newZoom The new zoom value. + */ + public void onZoomChange(double oldZoom, double newZoom); + + /** + * Called when the user scrolls. + * + * @param newScroll The scroll value which the user scrolls to. + */ + public void onScrollChange(int newScroll); + + /** + * Called when a file is opened. + */ + public void onOpenFile(); + + /** + * Called when a file is closed. + */ + public void onCloseFile(); + + /** + * Called when the window is closing. + */ + public void onClosing(); + + /** + * Called when the settings window opens. + */ + public void onSettingsOpen(); +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java new file mode 100644 index 00000000..48b39953 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java @@ -0,0 +1,1020 @@ +package com.artifex.gsviewer.gui; + +import java.awt.Adjustable; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.HeadlessException; +import java.awt.Image; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +import com.artifex.gsviewer.Document; +import com.artifex.gsviewer.Page; +import com.artifex.gsviewer.PageUpdateCallback; +import com.artifex.gsviewer.Settings; + +/** + * <p>Used to display documents into a window.</p> + * + * <p>Partially a auto-generated form using NetBeans.</p> + */ +public class ViewerWindow extends javax.swing.JFrame { + + private static final long serialVersionUID = 1L; + + /** + * The gap between each page in the main viewer, in pixels. + */ + public static final int VIEWER_PAGE_GAP = 10; + + /** + * The gap between each page in the mini viewer, in pixels. + */ + public static final int MINI_VIEWER_PAGE_GAP = 10; + + /** + * Constant indicating the "Yes" option was clicked in a dialog. + */ + public static final int YES = JOptionPane.YES_OPTION; + + /** + * Constant indicating the "No" option was clicked in a dialog. + */ + public static final int NO = JOptionPane.NO_OPTION; + + /** + * Constant indicating the "Cancel" option was clicked in a ddialog. + */ + public static final int CANCEL = JOptionPane.CANCEL_OPTION; + + private ViewerGUIListener guiListener; // The ViewerGUIListener to receive callbacks + private int currentPage, maxPage; // Current page displayed and the length of the document + private double currentZoom; // The amount the viewer is zoomed + + private Document loadedDocument; // The currently loaded document + private ScrollMap scrollMap; // The ScrollMap mapping scroll values to page numbers + private List<PagePanel> viewerPagePanels; // A list of the page panels in the viewer + private List<PagePanel> miniViewerPagePanels; // A list of the page panels in the mini viewer + + private Dimension min; // The minimum window size + private Dimension max; // The maximum window size + + private boolean gotoPage; // Whether the viewer should jump to currentPage + + private boolean isLoading; + + /** + * Creates new ViewerWindow. + */ + public ViewerWindow() { + this(null); + } + + /** + * Creates a new ViewerWindow with a GUIListener. + * + * @param listener A ViewerGUIListener which will receive callbacks regarding + * different events. + */ + public ViewerWindow(final ViewerGUIListener listener) { + initComponents(); + this.currentPage = 0; + this.maxPage = 0; + this.currentZoom = 1.0; + this.viewerPagePanels = new ArrayList<>(); + this.miniViewerPagePanels = new ArrayList<>(); + + // Adjustment listener looks for any change in the scroll value of the scrollbar + this.viewerScrollPane.getVerticalScrollBar().addAdjustmentListener((AdjustmentEvent evt) -> { + this.viewerScrollPane.getVerticalScrollBar().setUnitIncrement(Settings.SETTINGS.getSetting("scrollSens")); + if (scrollMap != null) { + Adjustable adjustable = evt.getAdjustable(); + int currentPage = scrollMap.getPageFor(adjustable.getValue()); + if (ViewerWindow.this.currentPage != currentPage) { + if (guiListener != null) + guiListener.onPageChange(ViewerWindow.this.currentPage, currentPage); + } + if (guiListener != null) + guiListener.onScrollChange(adjustable.getValue()); + ViewerWindow.this.currentPage = currentPage; + assumePage(currentPage); + } + refreshButtons(); + }); + + setGUIListener(listener); + + zoomSlider.setEnabled(false); + increaseZoomButton.setEnabled(false); + decreaseZoomButton.setEnabled(false); + zoomSlider.setValue(50); + + nextPageButton.setEnabled(false); + lastPageButton.setEnabled(false); + pageNumberField.setEditable(false); + + setLocationRelativeTo(null); + + min = getMinimumSize(); + max = getMaximumSize(); + + gotoPage = false; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + + // <editor-fold defaultstate="collapsed" desc="Generated Code"> + private void initComponents() { + + viewerScrollPane = new javax.swing.JScrollPane(); + viewerContentPane = new javax.swing.JPanel(); + miniViewerScrollPane = new javax.swing.JScrollPane(); + miniViewerContentPane = new javax.swing.JPanel(); + toolbarPanel = new javax.swing.JPanel(); + decreaseZoomButton = new javax.swing.JButton(); + zoomSlider = new javax.swing.JSlider(); + increaseZoomButton = new javax.swing.JButton(); + progressBar = new javax.swing.JProgressBar(); + lastPageButton = new javax.swing.JButton(); + pageNumberField = new javax.swing.JTextField(); + pageSlashLabel = new javax.swing.JLabel(); + maxPagesLabel = new javax.swing.JTextField(); + nextPageButton = new javax.swing.JButton(); + menuBar = new javax.swing.JMenuBar(); + fileMenu = new javax.swing.JMenu(); + openMenu = new javax.swing.JMenuItem(); + closeMenuItem = new javax.swing.JMenuItem(); + fileMenuSeparator = new javax.swing.JPopupMenu.Separator(); + exitMenuItem = new javax.swing.JMenuItem(); + editMenu = new javax.swing.JMenu(); + settingsMenuItem = new javax.swing.JMenuItem(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); + setTitle("Viewer"); + setMinimumSize(new java.awt.Dimension(640, 650)); + addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(java.awt.event.WindowEvent evt) { + formWindowClosing(evt); + } + }); + + viewerScrollPane.setMinimumSize(new java.awt.Dimension(85, 110)); + + javax.swing.GroupLayout viewerContentPaneLayout = new javax.swing.GroupLayout(viewerContentPane); + viewerContentPane.setLayout(viewerContentPaneLayout); + viewerContentPaneLayout.setHorizontalGroup( + viewerContentPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 623, Short.MAX_VALUE) + ); + viewerContentPaneLayout.setVerticalGroup( + viewerContentPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 639, Short.MAX_VALUE) + ); + + viewerScrollPane.setViewportView(viewerContentPane); + + miniViewerScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + + javax.swing.GroupLayout miniViewerContentPaneLayout = new javax.swing.GroupLayout(miniViewerContentPane); + miniViewerContentPane.setLayout(miniViewerContentPaneLayout); + miniViewerContentPaneLayout.setHorizontalGroup( + miniViewerContentPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 118, Short.MAX_VALUE) + ); + miniViewerContentPaneLayout.setVerticalGroup( + miniViewerContentPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 639, Short.MAX_VALUE) + ); + + miniViewerScrollPane.setViewportView(miniViewerContentPane); + + decreaseZoomButton.setText("-"); + decreaseZoomButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + decreaseZoomButtonActionPerformed(evt); + } + }); + + zoomSlider.setMajorTickSpacing(25); + zoomSlider.setMinorTickSpacing(5); + zoomSlider.setPaintTicks(true); + zoomSlider.setSnapToTicks(true); + zoomSlider.addMouseListener(new java.awt.event.MouseAdapter() { + @Override + public void mouseReleased(java.awt.event.MouseEvent evt) { + zoomSliderMouseReleased(evt); + } + }); + + increaseZoomButton.setText("+"); + increaseZoomButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + increaseZoomButtonActionPerformed(evt); + } + }); + + lastPageButton.setText("<"); + lastPageButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + lastPageButtonActionPerformed(evt); + } + }); + + pageNumberField.setText("0"); + pageNumberField.addKeyListener(new java.awt.event.KeyAdapter() { + @Override + public void keyPressed(java.awt.event.KeyEvent evt) { + pageNumberFieldKeyPressed(evt); + } + }); + + pageSlashLabel.setText("/"); + + maxPagesLabel.setEditable(false); + maxPagesLabel.setText("0"); + + nextPageButton.setText(">"); + nextPageButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + nextPageButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout toolbarPanelLayout = new javax.swing.GroupLayout(toolbarPanel); + toolbarPanel.setLayout(toolbarPanelLayout); + toolbarPanelLayout.setHorizontalGroup( + toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(toolbarPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(toolbarPanelLayout.createSequentialGroup() + .addComponent(decreaseZoomButton, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(zoomSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 111, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(increaseZoomButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lastPageButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pageNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pageSlashLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(maxPagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(nextPageButton)) + .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + toolbarPanelLayout.setVerticalGroup( + toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(toolbarPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(increaseZoomButton) + .addComponent(lastPageButton) + .addComponent(pageNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(pageSlashLabel) + .addComponent(maxPagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(nextPageButton)) + .addComponent(zoomSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(decreaseZoomButton)) + .addGap(17, 17, 17) + .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + fileMenu.setText("File"); + + openMenu.setText("Open"); + openMenu.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + openMenuActionPerformed(evt); + } + }); + fileMenu.add(openMenu); + + closeMenuItem.setText("Close"); + closeMenuItem.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + closeMenuItemActionPerformed(evt); + } + }); + fileMenu.add(closeMenuItem); + fileMenu.add(fileMenuSeparator); + + exitMenuItem.setText("Exit"); + exitMenuItem.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + exitMenuItemActionPerformed(evt); + } + }); + fileMenu.add(exitMenuItem); + + menuBar.add(fileMenu); + + editMenu.setText("Edit"); + + settingsMenuItem.setText("Settings"); + settingsMenuItem.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + settingsMenuItemActionPerformed(evt); + } + }); + editMenu.add(settingsMenuItem); + + menuBar.add(editMenu); + + setJMenuBar(menuBar); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(miniViewerScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(toolbarPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(viewerScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 642, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(miniViewerScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 592, Short.MAX_VALUE) + .addComponent(viewerScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 592, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(toolbarPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + pack(); + }// </editor-fold> + + private void lastPageButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_lastPageButtonActionPerformed + if (maxPage > 0) { + tryChangePage(currentPage - 1); + } else { + pageNumberField.setText(new StringBuilder().append(0).toString()); + } + }// GEN-LAST:event_lastPageButtonActionPerformed + + private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_nextPageButtonActionPerformed + if (maxPage > 0) { + tryChangePage(currentPage + 1); + } else { + pageNumberField.setText(new StringBuilder().append(0).toString()); + } + }// GEN-LAST:event_nextPageButtonActionPerformed + + private void formWindowClosing(java.awt.event.WindowEvent evt) {// GEN-FIRST:event_formWindowClosing + if (guiListener != null) + guiListener.onClosing(); + }// GEN-LAST:event_formWindowClosing + + private void pageNumberFieldKeyPressed(java.awt.event.KeyEvent evt) {// GEN-FIRST:event_pageNumberFieldKeyPressed + if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER) { + try { + final String text = pageNumberField.getText(); + tryChangePage(Integer.parseInt(text)); + } catch (NumberFormatException e) { + System.err.println("Invalid page numer."); + } + } + }// GEN-LAST:event_pageNumberFieldKeyPressed + + private void zoomSliderMouseReleased(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_zoomSliderMouseReleased + tryChangeZoom(zoomSlider.getValue() / 50.0); + }// GEN-LAST:event_zoomSliderMouseReleased + + private void increaseZoomButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_increaseZoomButtonActionPerformed + if (tryChangeZoom(Math.min(Math.ceil((currentZoom * 10) + 1) / 10, 2.0))) + zoomSlider.setValue((int)(currentZoom * 50)); + }// GEN-LAST:event_increaseZoomButtonActionPerformed + + private void decreaseZoomButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_decreaseZoomButtonActionPerformed + if (tryChangeZoom(Math.max(Math.floor((currentZoom * 10) - 1) / 10, 0.0))) + zoomSlider.setValue((int)(currentZoom * 50)); + }// GEN-LAST:event_decreaseZoomButtonActionPerformed + + private void openMenuActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_openMenuActionPerformed + if (guiListener != null) + guiListener.onOpenFile(); + }// GEN-LAST:event_openMenuActionPerformed + + private void closeMenuItemActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_closeMenuItemActionPerformed + if (guiListener != null) + guiListener.onCloseFile(); + }// GEN-LAST:event_closeMenuItemActionPerformed + + private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_exitMenuItemActionPerformed + if (guiListener != null) + guiListener.onClosing(); + }// GEN-LAST:event_exitMenuItemActionPerformed + + private void settingsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_settingsMenuItemActionPerformed + if (guiListener != null) + guiListener.onSettingsOpen(); + tryChangeZoom(0.1); + }// GEN-LAST:event_settingsMenuItemActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JMenuItem closeMenuItem; + private javax.swing.JButton decreaseZoomButton; + private javax.swing.JMenu editMenu; + private javax.swing.JMenuItem exitMenuItem; + private javax.swing.JMenu fileMenu; + private javax.swing.JPopupMenu.Separator fileMenuSeparator; + private javax.swing.JButton increaseZoomButton; + private javax.swing.JButton lastPageButton; + private javax.swing.JTextField maxPagesLabel; + private javax.swing.JMenuBar menuBar; + private javax.swing.JPanel miniViewerContentPane; + private javax.swing.JScrollPane miniViewerScrollPane; + private javax.swing.JButton nextPageButton; + private javax.swing.JMenuItem openMenu; + private javax.swing.JTextField pageNumberField; + private javax.swing.JLabel pageSlashLabel; + private javax.swing.JProgressBar progressBar; + private javax.swing.JMenuItem settingsMenuItem; + private javax.swing.JPanel toolbarPanel; + private javax.swing.JPanel viewerContentPane; + private javax.swing.JScrollPane viewerScrollPane; + private javax.swing.JSlider zoomSlider; + // End of variables declaration//GEN-END:variables + + private class PagePanel extends JPanel implements PageUpdateCallback { + + static final long serialVersionUID = 1L; + + Object lock; // A lock to ensure multiple draw calls don't happen + Page page; // The page to display + double size; // The size of the page + + Image toDraw; // The image which should be drawn by the panel + + /** + * Creates a new page panel to display a page of a document. + * + * @param page The page to display. + * @param size The size of the page. + */ + PagePanel(final Page page, double size) { + this.lock = new Object(); + this.page = page; + this.size = size == 0.0 ? 0.01 : size; + + Dimension pageSize = page.getSize(); + + Dimension actualSize = new Dimension((int)(pageSize.width * size), + (int)(pageSize.height * size)); + + toDraw = getImage(); + + setPreferredSize(actualSize); + setMaximumSize(actualSize); + + setBackground(Color.WHITE); + + setDoubleBuffered(false); + //pack(); + + page.addCallback(this); + } + + /** + * Returns the image which should be displayed in the viewer. This will + * change depending on the availability of high resolution images and zoom + * values. + * + * @return The image which should be displayed in the viewer. + */ + Image getImage() { + if (page != null && page.getLowResImage() != null) { + Dimension pageSize = page.getSize(); + Dimension actualSize = new Dimension((int)(pageSize.width * size), + (int)(pageSize.height * size)); + BufferedImage img = page.getDisplayableImage(); + if (page.getZoomedImage() != null && size > 1.0) + img = page.getZoomedImage(); + + Image result = img; + if (img == page.getLowResImage() || currentZoom < 1.0 || + (img == page.getHighResImage() && currentZoom > 1.0 && page.getZoomedImage() == null)) { + result = img.getScaledInstance(actualSize.width, actualSize.height, Image.SCALE_SMOOTH); + } + return result; + } else { + return null; + } + } + + /** + * Cleans up this page panel. + */ + void cleanup() { + if (page != null) { + page.removeCallback(this); + page = null; + } + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + synchronized (lock) { + if (toDraw != null) { + g.drawImage(toDraw, 0, 0, this); + } + } + } + + @Override + public void onPageUpdate() { + toDraw = getImage(); + SwingUtilities.invokeLater(() -> { + repaint(); + }); + } + + @Override + public void onLoadLowRes() { } + + @Override + public void onUnloadLowRes() { } + + @Override + public void onLoadHighRes() { } + + @Override + public void onUnloadHighRes() { } + + @Override + public void onLoadZoomed() { } + + @Override + public void onUnloadZoomed() { } + } + + /** + * The action listener to listen for button clicks in the + * mini viewer. Clicking on a button in the mini viewer will jump + * the user's view to the respective page. + * + * @author evrhe + * + */ + private class MiniViewerActionListener implements ActionListener { + + final int pageNum; // The assigned page number for this listener + + /** + * Creates a new listener with a tied page. + * + * @param pageNum The page number tied to this listener. + */ + MiniViewerActionListener(int pageNum) { + this.pageNum = pageNum; + } + + @Override + public void actionPerformed(ActionEvent e) { + tryChangePage(pageNum); + } + + } + + @Override + public void validate() { + super.validate(); + if (this.scrollMap != null) { + assumePage(this.currentPage = this.scrollMap.getCurrentPage()); + if (gotoPage) + scrollMap.scrollTo(currentPage); + } + unlockSize(); + gotoPage = false; + } + + /** + * Sets the ViewerGUIListener the window should use. + * + * @param listener A listener. + */ + public void setGUIListener(final ViewerGUIListener listener) { + this.guiListener = listener; + listener.onViewerAdd(this); + } + + /** + * Sets the progress of the progress bar in the window. + * + * @param progress The amount of progress (0-100). + */ + public void setLoadProgress(final int progress) { + progressBar.setValue(progress); + } + + /** + * Loads a document into the viewer and unloads the currently loaded document + * if one is loaded. + * + * @param document The document to load into the viewer. + */ + public void loadDocumentToViewer(final Document document) { + isLoading = true; + try { + unloadViewerDocument(); + if (document == null) + return; + lockSize(); + + this.loadedDocument = document; + viewerContentPane.setLayout(new BoxLayout(viewerContentPane, BoxLayout.Y_AXIS)); + + // Generate the viewer page components + /*for (final Page page : document) { + final PagePanel panel = new PagePanel(page, 1.0); + viewerContentPane.add(panel); + viewerContentPane.add(Box.createVerticalStrut(VIEWER_PAGE_GAP)); + + viewerPagePanels.add(panel); + }*/ + + miniViewerContentPane.setLayout(new BoxLayout(miniViewerContentPane, BoxLayout.Y_AXIS)); + + int height = 0; + // Generate the mini viewer icons + int pageNum = 1; + for (final Page page : document) { + + final PagePanel panel = new PagePanel(page, 1.0); + viewerContentPane.add(panel); + viewerContentPane.add(Box.createVerticalStrut(VIEWER_PAGE_GAP)); + + viewerPagePanels.add(panel); + height += page.getSize().height; + height += VIEWER_PAGE_GAP; + + ImageIcon icon = new ImageIcon(page.getLowResImage()); + JButton button = new JButton(icon); + button.setPreferredSize(page.getLowResSize()); + button.addActionListener(new MiniViewerActionListener(pageNum++)); + button.setFocusable(false); + + miniViewerContentPane.add(button); + miniViewerContentPane.add(Box.createVerticalStrut(MINI_VIEWER_PAGE_GAP)); + } + System.out.println(height); + + // Generate the scroll map + invokeAndWait(() -> { + revalidate(); + this.scrollMap = new ScrollMap(document, this, VIEWER_PAGE_GAP); + }); + assumePage(this.currentPage = 1); + assumeMaxPages(this.maxPage = document.size()); + + setTitle("Viewer - " + document.getName()); + + // Enable all widgets + zoomSlider.setEnabled(true); + increaseZoomButton.setEnabled(true); + decreaseZoomButton.setEnabled(true); + zoomSlider.setValue(50); + zoomSlider.setFocusable(true); + + nextPageButton.setEnabled(true); + lastPageButton.setEnabled(true); + pageNumberField.setEditable(true); + + refreshButtons(); + } finally { + isLoading = false; + } + } + + /** + * Unloads the currently loaded document from the viewer. If no document + * is loaded, this method does nothing. + */ + public void unloadViewerDocument() { + if (this.loadedDocument == null) + return; + + lockSize(); + + this.loadedDocument = null; + this.scrollMap = null; + + // Disable all widgets + this.assumePage(0); + this.assumeMaxPages(0); + this.zoomSlider.setValue(50); + this.zoomSlider.setEnabled(false); + this.zoomSlider.setFocusable(false); + this.pageNumberField.setEditable(false); + + setTitle("Viewer"); + + // Remove all pages + for (final PagePanel panel : viewerPagePanels) { + synchronized (panel.lock) { + panel.cleanup(); + } + } + viewerContentPane.removeAll(); + viewerPagePanels.clear(); + + miniViewerContentPane.removeAll(); + miniViewerPagePanels.clear(); + + System.gc(); + + invokeAndWait(() -> { + viewerContentPane.revalidate(); + viewerContentPane.repaint(); + + miniViewerContentPane.revalidate(); + miniViewerContentPane.repaint(); + }); + + } + + /** + * Returns the document currently loaded in the viewer. + * + * @return The currently loaded document, or <code>null</code> if none + * is loaded. + */ + public Document getLoadedDocument() { + return loadedDocument; + } + + /** + * Returns the respective component inside of the viewer for a page. + * + * @param pageNum The page to get the component for. + * @return The respective component. + * @throws IndexOutOfBoundsException If <code>pageNum</code> is not a page in the document. + */ + public JComponent getPageComponent(final int pageNum) throws IndexOutOfBoundsException { + return viewerPagePanels.get(pageNum - 1); + } + + /** + * Returns the scroll pane used by the viewer. + * + * @return The scroll pane. + */ + public JScrollPane getViewerScrollPane() { + return viewerScrollPane; + } + + /** + * Tries to change the page to another page. + * + * @param newPage The page to change to. + * @return <code>true</code> if the page is a valid page and <code>false</code> + * otherwise. + */ + public boolean tryChangePage(final int newPage) { + if (newPage < 1 || newPage > maxPage) + return false; + if (newPage != currentPage) { + final int oldPage = currentPage; + this.currentPage = newPage; + if (guiListener != null) + guiListener.onPageChange(oldPage, currentPage); + if (this.scrollMap != null) { + scrollMap.scrollTo(newPage); + assumePage(newPage); + } + + refreshButtons(); + + pageNumberField.setText(new StringBuilder().append(currentPage).toString()); + } + return true; + } + + /** + * Tries to change the zoom to another zoom value. + * + * @param newZoom The zoom to change to. + * @return <code>true</code> if the zoom is a valid zoom value and + * <code>false</code> otherwise. + */ + public boolean tryChangeZoom(final double newZoom) { + if (newZoom < 0 || newZoom > 2) + return false; + if (newZoom != currentZoom) { + gotoPage = true; + final double oldZoom = currentZoom; + this.currentZoom = newZoom; + if (guiListener != null) + guiListener.onZoomChange(oldZoom, currentZoom); + if (this.scrollMap != null) { + redisplayDocument(); + } + + refreshButtons(); + } + return true; + } + + /** + * Returns the current page the user is scrolled to. + * + * @return The current page. + */ + public int getCurrentPage() { + if (this.scrollMap != null) + return scrollMap.getCurrentPage(); + return 0; + } + + /** + * Shows an error dialog with a title and message. + * + * @param title The title of the dialog. + * @param message The message of the dialog. + * @throws HeadlessException If <code>GraphicsEnvironment.isHeadless</code> returns <code>true</code>. + */ + public void showErrorDialog(String title, String message) throws HeadlessException { + JOptionPane.showMessageDialog(this, message, title, JOptionPane.ERROR_MESSAGE); + } + + /** + * Shows a warning dialog with a title and message. + * + * @param title The title of the dialog. + * @param message The message of the dialog. + * @throws HeadlessException If <code>GraphicsEnvironment.isHeadless</code> returns <code>true</code>. + */ + public void showWarningDialog(String title, String message) throws HeadlessException { + JOptionPane.showMessageDialog(this, message, title, JOptionPane.WARNING_MESSAGE); + } + + /** + * Shows a confirmation dialog with a title and message. + * + * @param title The title of the dialog. + * @param message The message of the dialog. + * @return The button the user clicked (<code>ViewerWindow.YES</code>, <code>ViewerWindow.NO</code>, + * or <code>ViewerWindow.CANCEL</code>). + * @throws HeadlessException If <code>GraphicsEnvironment.isHeadless</code> returns <code>true</code>. + */ + public int showConfirmDialog(String title, String message) throws HeadlessException { + return JOptionPane.showConfirmDialog(this, message, title, JOptionPane.YES_NO_CANCEL_OPTION); + } + + /** + * Returns how much the viewer is zoomed in. + * + * @return The current zoom. + */ + public double getZoom() { + return currentZoom; + } + + /** + * Returns whether the window is loading a document. + * + * @return <code>true</code> if the window is loading a document + * and <code>false</code> otherwise. + */ + public boolean isLoading() { + return isLoading; + } + + public void apply(Settings settings) { + int sens = settings.getSetting("scrollSens"); + this.viewerScrollPane.getVerticalScrollBar().setUnitIncrement(sens); + this.miniViewerScrollPane.getVerticalScrollBar().setUnitIncrement(sens); + } + + /** + * Refresh each button's state. + */ + private void refreshButtons() { + this.lastPageButton.setEnabled(currentPage != 1 && loadedDocument != null); + this.nextPageButton.setEnabled(currentPage != maxPage && loadedDocument != null); + + this.increaseZoomButton.setEnabled(currentZoom != 2.0 && loadedDocument != null); + this.decreaseZoomButton.setEnabled(currentZoom != 0.0 && loadedDocument != null); + } + + /** + * Redisplays the currently loaded document. This will remove all loaded page panels + * and recreate them. + */ + private void redisplayDocument() { + lockSize(); + + for (final PagePanel panel : viewerPagePanels) { + synchronized (panel.lock) { + panel.cleanup(); + } + } + viewerContentPane.removeAll(); + viewerPagePanels.clear(); + + System.gc(); + + for (final Page page : loadedDocument) { + final PagePanel panel = new PagePanel(page, currentZoom); + viewerContentPane.add(panel); + viewerContentPane.add(Box.createVerticalStrut(VIEWER_PAGE_GAP)); + + viewerPagePanels.add(panel); + } + + invokeAndWait(() -> { + gotoPage = true; + revalidate(); + scrollMap.genMap(1.0); + }); + } + + /** + * Prevents the window from being resized. + */ + private void lockSize() { + Dimension size = getSize(); + setMinimumSize(size); + setMaximumSize(size); + //setResizable(false); + } + + /** + * Allows the window to be resized. + */ + private void unlockSize() { + setMinimumSize(min); + setMaximumSize(max); + //setResizable(true); + } + + /** + * Assume that we are on a certain page by setting the page number field. + * + * @param pageNum A page number. + */ + private void assumePage(int pageNum) { + this.pageNumberField.setText(new StringBuilder().append(pageNum).toString()); + } + + /** + * Assume that we have a certain max page count by setting the max pages field. + * + * @param pageCount A page count. + */ + private void assumeMaxPages(int pageCount) { + this.maxPagesLabel.setText(new StringBuilder().append(pageCount).toString()); + } + + private void invokeAndWait(Runnable r) { + if (!SwingUtilities.isEventDispatchThread()) { + try { + SwingUtilities.invokeAndWait(r); + } catch (InvocationTargetException | InterruptedException e) { + r.run(); + } + } else { + r.run(); + } + } +} diff --git a/demos/java/jni/gs_jni/callbacks.cpp b/demos/java/jni/gs_jni/callbacks.cpp new file mode 100644 index 00000000..a8ad2196 --- /dev/null +++ b/demos/java/jni/gs_jni/callbacks.cpp @@ -0,0 +1,368 @@ +#include "callbacks.h" + +#include "jni_util.h" + +#include <string.h> + +#define STDIN_SIG "(J[BI)I" +#define STDOUT_SIG "(J[BI)I" +#define STDERR_SIG "(J[BI)I" + +#define POLL_SIG "(J)I" + +#define DISPLAY_OPEN_SIG "(JJ)I" +#define DISPLAY_PRECLOSE_SIG "(JJ)I" +#define DISPLAY_CLOSE_SIG "(JJ)I" +#define DISPLAY_PRESIZE_SIG "(JJIIII)I" +#define DISPLAY_SIZE_SIG "(JJIIIILcom/artifex/gsjava/util/BytePointer;)I" +#define DISPLAY_SYNC_SIG "(JJ)I" +#define DISPLAY_PAGE_SIG "(JJIZ)I" +#define DISPLAY_UPDATE_SIG "(JJIIII)I" +// display memalloc +// display memfree +#define DISPLAY_SEPARATION_SIG "(JJI[BSSSS)I" +#define DISPLAY_ADJUST_BAND_HEIGHT_SIG "(JJI)I" +#define DISPLAY_RECTANGLE_REQUEST "(JJLcom/artifex/gsjava/LongReference;Lcom/artifex/gsjava/IntReference;\ +Lcom/artifex/gsjava/IntReference;Lcom/artifex/gsjava/IntReference;Lcom/artifex/gsjava/IntReference;\ +Lcom/artifex/gsjava/IntReference;Lcom/artifex/gsjava/IntReference;Lcom/artifex/gsjava/IntReference;\ +Lcom/artifex/gsjava/IntReference;)I" + +#define CHECK_AND_RETURN(E) if (E->ExceptionCheck()) { return -21; } + +using namespace util; + +static JNIEnv *g_env = NULL; + +static jobject g_stdIn = NULL; +static jobject g_stdOut = NULL; +static jobject g_stdErr = NULL; + +static jobject g_poll = NULL; + +static jobject g_displayCallback = NULL; + +static jobject g_callout = NULL; + +void callbacks::setJNIEnv(JNIEnv *env) +{ + g_env = env; +} + +void callbacks::setIOCallbacks(jobject stdIn, jobject stdOut, jobject stdErr) +{ + if (g_env) + { + if (g_stdIn) + g_env->DeleteGlobalRef(g_stdIn); + + if (g_stdOut) + g_env->DeleteGlobalRef(g_stdOut); + + if (g_stdErr) + g_env->DeleteGlobalRef(g_stdErr); + + g_stdIn = g_env->NewGlobalRef(stdIn); + g_stdOut = g_env->NewGlobalRef(stdOut); + g_stdErr = g_env->NewGlobalRef(stdErr); + } +} + +int callbacks::stdInFunction(void *callerHandle, char *buf, int len) +{ + int code = 0; + if (g_env && g_stdIn) + { + jbyteArray byteArray = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(byteArray, 0, len, (jbyte *)buf); + code = callIntMethod(g_env, g_stdIn, "onStdIn", STDIN_SIG, (jlong)callerHandle, byteArray, (jint)len); + } + return code; +} + +int callbacks::stdOutFunction(void *callerHandle, const char *str, int len) +{ + int code = 0; + if (g_env && g_stdOut) + { + jbyteArray byteArray = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(byteArray, 0, len, (const jbyte *)str); + code = callIntMethod(g_env, g_stdOut, "onStdOut", STDOUT_SIG, (jlong)callerHandle, byteArray, (jint)len); + } + return code; +} + +int callbacks::stdErrFunction(void *callerHandle, const char *str, int len) +{ + int code = 0; + if (g_env && g_stdErr) + { + jbyteArray byteArray = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(byteArray, 0, len, (const jbyte *)str); + code = callIntMethod(g_env, g_stdErr, "onStdErr", STDERR_SIG, (jlong)callerHandle, byteArray, (jint)len); + } + return code; +} + +void callbacks::setPollCallback(jobject poll) +{ + if (g_env) + { + if (g_poll) + g_env->DeleteGlobalRef(g_poll); + + g_poll = g_env->NewGlobalRef(poll); + } +} + +int callbacks::pollFunction(void *callerHandle) +{ + int code = 0; + if (g_env && g_poll) + { + code = callIntMethod(g_env, g_poll, "onPoll", POLL_SIG, (jlong)callerHandle); + } + return code; +} + +void callbacks::setDisplayCallback(jobject displayCallback) +{ + if (g_env) + { + if (g_displayCallback) + { + g_env->DeleteGlobalRef(g_displayCallback); + g_displayCallback = NULL; + } + + g_displayCallback = g_env->NewGlobalRef(displayCallback); + //g_displayCallback = displayCallback; + } +} + +void callbacks::setCalloutCallback(jobject callout) +{ + if (g_env) + { + if (g_callout) + g_env->DeleteGlobalRef(g_callout); + + g_callout = g_env->NewGlobalRef(callout); + } +} + +int callbacks::calloutFunction(void *instance, void *handle, const char *deviceName, int id, int size, void *data) +{ + int code = 0; + if (g_env && g_callout) + { + jsize len = strlen(deviceName); + jbyteArray array = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(array, 0, len, (const jbyte *)deviceName); + code = callIntMethod(g_env, g_callout, "onCallout", "(JJ[BIIJ)I", (jlong)instance, (jlong)handle, array, id, size, (jlong)data); + } + return code; +} + +int callbacks::display::displayOpenFunction(void *handle, void *device) +{ + int code = 0; + if (g_env && g_displayCallback) + { + jclass clazz = g_env->GetObjectClass(g_displayCallback); + const char *name = getClassName(g_env, clazz); + freeClassName(name); + code = callIntMethod(g_env, g_displayCallback, "onDisplayOpen", DISPLAY_OPEN_SIG, (jlong)handle, (jlong)device); + CHECK_AND_RETURN(g_env); + } + return 0; +} + +int callbacks::display::displayPrecloseFunction(void *handle, void *device) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayPreclose", DISPLAY_PRECLOSE_SIG, (jlong)handle, (jlong)device); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayCloseFunction(void *handle, void *device) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayClose", DISPLAY_CLOSE_SIG, (jlong)handle, (jlong)device); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayPresizeFunction(void *handle, void *device, int width, int height, int raster, unsigned int format) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayPresize", DISPLAY_PRESIZE_SIG, (jlong)handle, + (jlong)device, width, height, raster, (jint)format); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displaySizeFunction(void *handle, void *device, int width, int height, int raster, + unsigned int format, unsigned char *pimage) +{ + int code = 0; + if (g_env && g_displayCallback) + { + jsize len = height * raster; + jbyteArray byteArray = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(byteArray, 0, len, (signed char *)pimage); + + static const char *const bytePointerClassName = "com/artifex/gsjava/util/BytePointer"; + static const char *const nativePointerClassName = "com/artifex/gsjava/util/NativePointer"; + + jclass bytePointerClass = g_env->FindClass(bytePointerClassName); + if (bytePointerClass == NULL) + { + throwNoClassDefError(g_env, bytePointerClassName); + return -21; + } + + jclass nativePointerClass = g_env->FindClass(nativePointerClassName); + if (nativePointerClass == NULL) + { + throwNoClassDefError(g_env, nativePointerClassName); + return -21; + } + + jmethodID constructor = g_env->GetMethodID(bytePointerClass, "<init>", "()V"); + if (constructor == NULL) + { + throwNoSuchMethodError(g_env, "com.artifex.gsjava.util.BytePointer.<init>()V"); + return -21; + } + jobject bytePointer = g_env->NewObject(bytePointerClass, constructor); + + jfieldID dataPtrID = g_env->GetFieldID(nativePointerClass, "address", "J"); + if (dataPtrID == NULL) + { + throwNoSuchFieldError(g_env, "address"); + return -21; + } + + jfieldID lengthID = g_env->GetFieldID(bytePointerClass, "length", "J"); + if (lengthID == NULL) + { + throwNoSuchFieldError(g_env, "length"); + return -21; + } + + g_env->SetLongField(bytePointer, dataPtrID, (jlong)pimage); + g_env->SetLongField(bytePointer, lengthID, len); + + code = callIntMethod(g_env, g_displayCallback, "onDisplaySize", DISPLAY_SIZE_SIG, (jlong)handle, + (jlong)device, width, height, raster, (jint)format, bytePointer); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displaySyncFunction(void *handle, void *device) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplaySync", DISPLAY_SYNC_SIG, (jlong)handle, (jlong)device); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayPageFunction(void *handle, void *device, int copies, int flush) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayPage", DISPLAY_PAGE_SIG, (jlong)handle, + (jlong)device, copies, flush); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayUpdateFunction(void *handle, void *device, int x, int y, int w, int h) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayUpdate", DISPLAY_UPDATE_SIG, (jlong)handle, + (jlong)device, x, y, w, h); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displaySeparationFunction(void *handle, void *device, int component, const char *componentName, + unsigned short c, unsigned short m, unsigned short y, unsigned short k) +{ + int code = 0; + if (g_env && g_displayCallback) + { + jsize len = strlen(componentName); + jbyteArray byteArray = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(byteArray, 0, len, (const jbyte *)componentName); + code = callIntMethod(g_env, g_displayCallback, "onDisplaySeparation", DISPLAY_SEPARATION_SIG, (jlong)handle, + (jlong)device, component, byteArray, c, m, y, k); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayAdjustBandHeightFunction(void *handle, void *device, int bandHeight) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayAdjustBandHeght", DISPLAY_ADJUST_BAND_HEIGHT_SIG, + (jlong)handle, (jlong)device, bandHeight); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayRectangleRequestFunction(void *handle, void *device, void **memory, int *ox, int *oy, + int *raster, int *plane_raster, int *x, int *y, int *w, int *h) +{ + int code = 0; + if (g_env && g_displayCallback) + { + Reference memoryRef = Reference(g_env, toWrapperType(g_env, (jlong)*memory)); + Reference oxRef = Reference(g_env, toWrapperType(g_env, (jint)*ox)); + Reference oyRef = Reference(g_env, toWrapperType(g_env, (jint)*oy)); + Reference rasterRef = Reference(g_env, toWrapperType(g_env, (jint)*raster)); + Reference planeRasterRef = Reference(g_env, toWrapperType(g_env, (jint)*plane_raster)); + Reference xRef = Reference(g_env, toWrapperType(g_env, (jint)*x)); + Reference yRef = Reference(g_env, toWrapperType(g_env, (jint)*y)); + Reference wRef = Reference(g_env, toWrapperType(g_env, (jint)*w)); + Reference hRef = Reference(g_env, toWrapperType(g_env, (jint)*h)); + + code = callIntMethod(g_env, g_displayCallback, "onDisplayRectangleRequest", DISPLAY_RECTANGLE_REQUEST, + (jlong)handle, (jlong)device, memoryRef, oxRef, oyRef, rasterRef, planeRasterRef, xRef, yRef, wRef, hRef); + + *memory = (void *)memoryRef.longValue(); + *ox = oxRef.intValue(); + *oy = oyRef.intValue(); + *raster = rasterRef.intValue(); + *plane_raster = planeRasterRef.intValue(); + *x = xRef.intValue(); + *y = yRef.intValue(); + *w = wRef.intValue(); + *h = hRef.intValue(); + + CHECK_AND_RETURN(g_env); + } + return code; +} diff --git a/demos/java/jni/gs_jni/callbacks.h b/demos/java/jni/gs_jni/callbacks.h new file mode 100644 index 00000000..55508f2b --- /dev/null +++ b/demos/java/jni/gs_jni/callbacks.h @@ -0,0 +1,54 @@ +#pragma once + +#include <jni.h> + +namespace callbacks +{ + /*! + Sets the JNIEnv which the callbacks should use. Must be set for any Java + callbacks to be called. + + @param env A JNIEnv. + */ + void setJNIEnv(JNIEnv *env); + + void setIOCallbacks(jobject stdIn, jobject stdOut, jobject stdErr); + int stdInFunction(void *callerHandle, char *buf, int len); + int stdOutFunction(void *callerHandle, const char *str, int len); + int stdErrFunction(void *callerHandle, const char *str, int len); + + void setPollCallback(jobject poll); + int pollFunction(void *callerHandle); + + void setDisplayCallback(jobject displayCallback); + + namespace display + { + int displayOpenFunction(void *handle, void *device); + int displayPrecloseFunction(void *handle, void *device); + int displayCloseFunction(void *handle, void *device); + int displayPresizeFunction(void *handle, void *device, int width, + int height, int raster, unsigned int format); + int displaySizeFunction(void *handle, void *device, int width, + int height, int raster, unsigned int format, + unsigned char *pimage); + int displaySyncFunction(void *handle, void *device); + int displayPageFunction(void *handle, void *device, int copies, + int flush); + int displayUpdateFunction(void *handle, void *device, int x, + int y, int w, int h); + // display_memalloc omitted + // display_memfree omitted + int displaySeparationFunction(void *handle, void *device, + int component, const char *componentName, unsigned short c, + unsigned short m, unsigned short y, unsigned short k); + int displayAdjustBandHeightFunction(void *handle, void *device, + int bandHeight); + int displayRectangleRequestFunction(void *handle, void *device, + void **memory, int *ox, int *oy, int *raster, int *plane_raster, + int *x, int *y, int *w, int *h); + } + + void setCalloutCallback(jobject calout); + int calloutFunction(void *instance, void *handle, const char *deviceName, int id, int size, void *data); +}
\ No newline at end of file diff --git a/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp new file mode 100644 index 00000000..7858112e --- /dev/null +++ b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp @@ -0,0 +1,555 @@ +#include "com_artifex_gsjava_GSAPI.h" + +#include <iapi.h> +#include <gdevdsp.h> +#include <string.h> +#include <memory> + +#include "jni_util.h" +#include "callbacks.h" + +using namespace util; + +static void *getAsPointer(JNIEnv *env, jobject object, gs_set_param_type type, bool *success); + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1revision + (JNIEnv *env, jclass, jobject revision, jint len) +{ + if (revision == NULL) + return throwNullPointerException(env, "Revision object is NULL"); + gsapi_revision_t gsrevision; + jint code = gsapi_revision(&gsrevision, sizeof(gsapi_revision_t)); + if (code == 0) + { + setByteArrayField(env, revision, "product", gsrevision.product); + setByteArrayField(env, revision, "copyright", gsrevision.copyright); + setLongField(env, revision, "revision", gsrevision.revision); + setLongField(env, revision, "revisionDate", gsrevision.revisiondate); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1new_1instance + (JNIEnv *env, jclass, jobject instance, jlong callerHandle) +{ + if (instance == NULL) + return throwNullPointerException(env, "LongReference object is NULL"); + + void *gsInstance; + int code = gsapi_new_instance(&gsInstance, (void *)callerHandle); + if (code == 0) + Reference::setValueField(env, instance, toWrapperType(env, (jlong)gsInstance)); + return code; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1delete_1instance + (JNIEnv *env, jclass, jlong instance) +{ + callbacks::setJNIEnv(env); + gsapi_delete_instance((void *)instance); +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio_1with_1handle + (JNIEnv *env, jclass, jlong instance, jobject stdIn, jobject stdOut, jobject stdErr, jlong callerHandle) +{ + int code = gsapi_set_stdio_with_handle((void *)instance, callbacks::stdInFunction, + callbacks::stdOutFunction, callbacks::stdErrFunction, (void *)callerHandle); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setIOCallbacks(stdIn, stdOut, stdErr); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio + (JNIEnv *env, jclass, jlong instance, jobject stdIn, jobject stdOut, jobject stdErr) +{ + int code = gsapi_set_stdio((void *)instance, callbacks::stdInFunction, + callbacks::stdOutFunction, callbacks::stdErrFunction); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setIOCallbacks(stdIn, stdOut, stdErr); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1poll_1with_1handle + (JNIEnv *env, jclass, jlong instance, jobject poll, jlong callerHandle) +{ + int code = gsapi_set_poll_with_handle((void *)instance, callbacks::pollFunction, (void *)callerHandle); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setPollCallback(poll); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1poll + (JNIEnv *env, jclass, jlong instance, jobject poll) +{ + int code = gsapi_set_poll((void *)instance, callbacks::pollFunction); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setPollCallback(poll); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1display_1callback + (JNIEnv *env, jclass, jlong instance, jobject displayCallback) +{ + display_callback *cb = new display_callback; + cb->size = sizeof(display_callback); + cb->version_major = DISPLAY_VERSION_MAJOR; + cb->version_minor = DISPLAY_VERSION_MINOR; + + cb->display_open = callbacks::display::displayOpenFunction; + cb->display_preclose = callbacks::display::displayPrecloseFunction; + cb->display_close = callbacks::display::displayCloseFunction; + cb->display_presize = callbacks::display::displayPresizeFunction; + cb->display_size = callbacks::display::displaySizeFunction; + cb->display_sync = callbacks::display::displaySyncFunction; + cb->display_page = callbacks::display::displayPageFunction; + cb->display_update = callbacks::display::displayUpdateFunction; + cb->display_memalloc = NULL; + cb->display_memfree = NULL; + cb->display_separation = callbacks::display::displaySeparationFunction; + cb->display_adjust_band_height = callbacks::display::displayAdjustBandHeightFunction; + cb->display_rectangle_request = callbacks::display::displayRectangleRequestFunction; + + int code = gsapi_set_display_callback((void *)instance, cb); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setDisplayCallback(displayCallback); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1register_1callout + (JNIEnv *env, jclass, jlong instance, jobject callout, jlong calloutHandle) +{ + int code = gsapi_register_callout((void *)instance, callbacks::calloutFunction, (void *)calloutHandle); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setCalloutCallback(callout); + } + return code; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1deregister_1callout + (JNIEnv *env, jclass, jlong instance, jobject callout, jlong calloutHandle) +{ + gsapi_deregister_callout((void *)instance, callbacks::calloutFunction, (void *)calloutHandle); +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1arg_1encoding + (JNIEnv *env, jclass, jlong instance, jint encoding) +{ + return gsapi_set_arg_encoding((void *)instance, encoding); +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1default_1device_1list + (JNIEnv *env, jclass, jlong instance, jbyteArray list, jint listlen) +{ + if (list == NULL) + return throwNullPointerException(env, "list"); + jboolean isCopy = false; + callbacks::setJNIEnv(env); + int code = gsapi_set_default_device_list((void *)instance, + (const char *)env->GetByteArrayElements(list, &isCopy), listlen); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1default_1device_1list + (JNIEnv *env, jclass, jlong instance, jobject list, jobject listlen) +{ + char *clist = NULL; + int clistlen = 0; + int code = gsapi_get_default_device_list((void *)instance, &clist, &clistlen); + if (code == 0) + { + if (list) + { + jbyteArray arr = env->NewByteArray(clistlen); + env->SetByteArrayRegion(arr, 0, clistlen, (jbyte *)clist); + Reference::setValueField(env, list, arr); + env->DeleteLocalRef(arr); + } + if (listlen) + Reference::setValueField(env, listlen, toWrapperType(env, (jint)clistlen)); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1init_1with_1args + (JNIEnv *env, jclass, jlong instance, jint argc, jobjectArray argv) +{ + if (argv == NULL) + return throwNullPointerException(env, "argv"); + char **cargv = jbyteArray2DToCharArray(env, argv); + callbacks::setJNIEnv(env); + int code = gsapi_init_with_args((void *)instance, argc, cargv); + delete2DByteArray(argc, cargv); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1begin + (JNIEnv *env, jclass, jlong instance, jint userErrors, jobject pExitCode) +{ + int exitCode; + callbacks::setJNIEnv(env); + int code = gsapi_run_string_begin((void *)instance, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1continue + (JNIEnv *env, jclass, jlong instance, jbyteArray str, jint length, jint userErrors, jobject pExitCode) +{ + if (str == NULL) + return throwNullPointerException(env, "str"); + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(str, ©); + callbacks::setJNIEnv(env); + int code = gsapi_run_string_continue((void *)instance, cstring, length, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1end + (JNIEnv *env, jclass, jlong instance, jint userErrors, jobject pExitCode) +{ + int exitCode; + callbacks::setJNIEnv(env); + int code = gsapi_run_string_end((void *)instance, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1with_1length + (JNIEnv *env, jclass, jlong instance, jbyteArray str, jint length, jint userErrors, jobject pExitCode) +{ + if (str == NULL) + return throwNullPointerException(env, "str"); + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(str, ©); + callbacks::setJNIEnv(env); + int code = gsapi_run_string_with_length((void *)instance, cstring, length, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string + (JNIEnv *env, jclass, jlong instance, jbyteArray str, jint userErrors, jobject pExitCode) +{ + if (str == NULL) + return throwNullPointerException(env, "str"); + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(str, ©); + callbacks::setJNIEnv(env); + int code = gsapi_run_string((void *)instance, cstring, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1file + (JNIEnv *env, jclass, jlong instance, jbyteArray fileName, jint userErrors, jobject pExitCode) +{ + if (fileName == NULL) + return throwNullPointerException(env, "fileName"); + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(fileName, ©); + callbacks::setJNIEnv(env); + int code = gsapi_run_file((void *)instance, cstring, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1exit + (JNIEnv *env, jclass, jlong instance) +{ + return gsapi_exit((void *)instance); +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1param + (JNIEnv *env, jclass, jlong instance, jbyteArray param, jobject value, jint paramType) +{ + if (!param) + { + throwNullPointerException(env, "param"); + return -1; + } + + gs_set_param_type type = (gs_set_param_type)paramType; + bool paramSuccess; + void *data = getAsPointer(env, value, type, ¶mSuccess); + if (!paramSuccess) + { + throwIllegalArgumentException(env, "paramType"); + return -1; + } + + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(param, ©); + + callbacks::setJNIEnv(env); + int code = gsapi_set_param((void *)instance, cstring, data, type); + free(data); + + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1param + (JNIEnv *env, jclass, jlong instance, jbyteArray param, jlong value, jint paramType) +{ + if (!param) + { + throwNullPointerException(env, "paramType"); + return -1; + } + + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(param, ©); + + int ret = gsapi_get_param((void *)instance, cstring, (void *)value, (gs_set_param_type)paramType); + + return ret; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1param_1once + (JNIEnv *env, jclass, jlong instance, jbyteArray param, jobject value, jint paramType) +{ + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(param, ©); + + int bytes = gsapi_get_param((void *)instance, cstring, NULL, (gs_set_param_type)paramType); + if (bytes < 0) + return bytes; + + void *data = new char[bytes]; + int code = gsapi_get_param((void *)instance, cstring, data, (gs_set_param_type)paramType); + if (code < 0) + { + delete[] data; + return code; + } + + int stripped = paramType & ~(gs_spt_more_to_come); + Reference ref = Reference(env, value); + + jbyteArray arr = NULL; + const char *str = NULL; + int len = 0; + switch (stripped) + { + case gs_spt_null: + break; + case gs_spt_bool: + ref.set((jboolean)*((int *)data)); + break; + case gs_spt_int: + ref.set(*((jint *)data)); + break; + case gs_spt_float: + ref.set(*((jfloat *)data)); + break; + case gs_spt_long: + ref.set(*((jlong *)data)); + break; + case gs_spt_i64: + ref.set((jlong)*((long long *)data)); + break; + case gs_spt_size_t: + ref.set((jlong)*((size_t *)data)); + break; + case gs_spt_name: + case gs_spt_string: + case gs_spt_parsed: + str = (const char *)data; + len = strlen(str) + 1; + arr = env->NewByteArray(len); + env->SetByteArrayRegion(arr, 0, len, (const jbyte *)str); + ref.set(arr); + break; + case gs_spt_invalid: + default: + throwIllegalArgumentException(env, "paramType"); + delete[] data; + return -1; + break; + } + delete[] data; + return 0; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1enumerate_1params + (JNIEnv *env, jclass, jlong instance, jobject iter, jobject key, jobject paramType) +{ + if (!iter) + { + throwNullPointerException(env, "iterator is NULL"); + return -1; + } + + Reference iterRef = Reference(env, iter); + + Reference keyRef = Reference(env, key); + Reference typeRef = Reference(env, paramType); + + void *citer = (void *)iterRef.longValue(); + + if (env->ExceptionCheck()) + return -1; + + const char *ckey; + gs_set_param_type type; + + int code = gsapi_enumerate_params((void *)instance, &citer, &ckey, &type); + + if (code == 0) + { + iterRef.set((jlong)citer); + + jsize len = strlen(ckey) + 1; + jbyteArray arr = env->NewByteArray(len); + env->SetByteArrayRegion(arr, 0, len, (const jbyte *)ckey); + keyRef.set(arr); + env->DeleteLocalRef(arr); + + typeRef.set((jint)type); + } + + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1add_1control_1path + (JNIEnv *env, jclass, jlong instance, jint type, jbyteArray path) +{ + if (!path) + { + throwNullPointerException(env, "path is NULL"); + return -1; + } + + jboolean copy = false; + const char *cstring = (const char *)env->GetByteArrayElements(path, ©); + + int exitCode = gsapi_add_control_path((void *)instance, type, cstring); + + return exitCode; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1remove_1control_1path +(JNIEnv *env, jclass, jlong instance, jint type, jbyteArray path) +{ + if (!path) + { + throwNullPointerException(env, "path is NULL"); + return -1; + } + + jboolean copy = false; + const char *cstring = (const char *)env->GetByteArrayElements(path, ©); + + int exitCode = gsapi_remove_control_path((void *)instance, type, cstring); + + return exitCode; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1purge_1control_1paths + (JNIEnv *, jclass, jlong instance, jint type) +{ + gsapi_purge_control_paths((void *)instance, type); +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1activate_1path_1control + (JNIEnv *, jclass, jlong instance, jboolean enable) +{ + gsapi_activate_path_control((void *)instance, enable); +} + +JNIEXPORT jboolean JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1is_1path_1control_1active + (JNIEnv *env, jclass, jlong instance) +{ + return gsapi_is_path_control_active((void *)instance); +} + +void *getAsPointer(JNIEnv *env, jobject object, gs_set_param_type type, bool *success) +{ + *success = true; + void *result = NULL; + int stripped = type & ~gs_spt_more_to_come; + + jbyteArray arr = NULL; + jboolean copy = false; + const char *cstring = NULL; + jsize len = 0; + switch (stripped) + { + case gs_spt_null: + return result; + break; + case gs_spt_bool: + result = malloc(sizeof(int)); + *((int *)result) = (bool)toBoolean(env, object); + break; + case gs_spt_int: + result = malloc(sizeof(int)); + *((int *)result) = (int)toInt(env, object); + break; + case gs_spt_float: + result = malloc(sizeof(float)); + *((float *)result) = (float)toFloat(env, object); + break; + case gs_spt_long: + case gs_spt_i64: + result = malloc(sizeof(long long)); + *((long long *)result) = (long long)toLong(env, object); + break; + case gs_spt_size_t: + result = malloc(sizeof(size_t)); + *((size_t *)result) = (size_t)toLong(env, object); + break; + case gs_spt_name: + case gs_spt_string: + case gs_spt_parsed: + arr = (jbyteArray)object; + cstring = (const char *)env->GetByteArrayElements(arr, ©); + len = env->GetArrayLength(arr); + result = malloc(sizeof(char) * len); + //((char *)result)[len - 1] = 0; + memcpy(result, cstring, len); + break; + case gs_spt_invalid: + default: + *success = false; + break; + } + if (env->ExceptionCheck()) + { + if (result) + free(result); + result = NULL; + *success = false; + } + return result; +} diff --git a/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.h b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.h new file mode 100644 index 00000000..68c61e58 --- /dev/null +++ b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.h @@ -0,0 +1,386 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class com_artifex_gsjava_GSAPI */ + +#ifndef _Included_com_artifex_gsjava_GSAPI +#define _Included_com_artifex_gsjava_GSAPI +#ifdef __cplusplus +extern "C" { +#endif +#undef com_artifex_gsjava_GSAPI_GS_NULL +#define com_artifex_gsjava_GSAPI_GS_NULL 0i64 +#undef com_artifex_gsjava_GSAPI_GS_ERROR_OK +#define com_artifex_gsjava_GSAPI_GS_ERROR_OK 0L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNKNOWNERROR +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNKNOWNERROR -1L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_DICTFULL +#define com_artifex_gsjava_GSAPI_GS_ERROR_DICTFULL -2L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_DICTSTACKOVERFLOW +#define com_artifex_gsjava_GSAPI_GS_ERROR_DICTSTACKOVERFLOW -3L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_DICTSTACKUNDERFLOW +#define com_artifex_gsjava_GSAPI_GS_ERROR_DICTSTACKUNDERFLOW -4L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_EXECSTACKOVERFLOW +#define com_artifex_gsjava_GSAPI_GS_ERROR_EXECSTACKOVERFLOW -5L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INTERRUPT +#define com_artifex_gsjava_GSAPI_GS_ERROR_INTERRUPT -6L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDACCESS +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDACCESS -7L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDEXIT +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDEXIT -8L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDFILEACCESS +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDFILEACCESS -9L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDFONT +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDFONT -10L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDRESTORE +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDRESTORE -11L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_IOERROR +#define com_artifex_gsjava_GSAPI_GS_ERROR_IOERROR -12L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_LIMITCHECK +#define com_artifex_gsjava_GSAPI_GS_ERROR_LIMITCHECK -13L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_NOCURRENTPOINT +#define com_artifex_gsjava_GSAPI_GS_ERROR_NOCURRENTPOINT -14L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_RANGECHECK +#define com_artifex_gsjava_GSAPI_GS_ERROR_RANGECHECK -15L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_STACKOVERFLOW +#define com_artifex_gsjava_GSAPI_GS_ERROR_STACKOVERFLOW -16L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_STACKUNDERFLOW +#define com_artifex_gsjava_GSAPI_GS_ERROR_STACKUNDERFLOW -17L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_SYNTAXERROR +#define com_artifex_gsjava_GSAPI_GS_ERROR_SYNTAXERROR -18L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_TIMEOUT +#define com_artifex_gsjava_GSAPI_GS_ERROR_TIMEOUT -19L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_TYPECHECK +#define com_artifex_gsjava_GSAPI_GS_ERROR_TYPECHECK -20L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINED +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINED -21L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDFILENAME +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDFILENAME -22L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDRESULT +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDRESULT -23L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNMATCHEDMARK +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNMATCHEDMARK -24L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_VMERROR +#define com_artifex_gsjava_GSAPI_GS_ERROR_VMERROR -25L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_CONFIGURATION_ERROR +#define com_artifex_gsjava_GSAPI_GS_ERROR_CONFIGURATION_ERROR -26L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDRESOURCE +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDRESOURCE -27L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNREGISTERED +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNREGISTERED -28L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDCONTEXT +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDCONTEXT -29L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALID +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALID -30L +#undef com_artifex_gsjava_GSAPI_GS_COLORS_NATIVE +#define com_artifex_gsjava_GSAPI_GS_COLORS_NATIVE 1L +#undef com_artifex_gsjava_GSAPI_GS_COLORS_GRAY +#define com_artifex_gsjava_GSAPI_GS_COLORS_GRAY 2L +#undef com_artifex_gsjava_GSAPI_GS_COLORS_RGB +#define com_artifex_gsjava_GSAPI_GS_COLORS_RGB 4L +#undef com_artifex_gsjava_GSAPI_GS_COLORS_CMYK +#define com_artifex_gsjava_GSAPI_GS_COLORS_CMYK 8L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_COLORS_SEPARATION +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_COLORS_SEPARATION 524288L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_COLORS_MASK +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_COLORS_MASK 524303i64 +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_NONE +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_NONE 0L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_FIRST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_FIRST 16L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_LAST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_LAST 32L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_UNUSED_FIRST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_UNUSED_FIRST 64L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_UNUSED_LAST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_UNUSED_LAST 128L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_MASK +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_MASK 240i64 +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_1 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_1 256L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_2 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_2 512L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_4 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_4 1024L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_8 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_8 2048L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_12 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_12 4096L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_16 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_16 8L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_MASK +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_MASK 65280i64 +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_BIGENDIAN +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_BIGENDIAN 0L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_LITTLEENDIAN +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_LITTLEENDIAN 65536L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_ENDIAN_MASK +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_ENDIAN_MASK 65536i64 +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_TOPFIRST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_TOPFIRST 0L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_BOTTOMFIRST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_BOTTOMFIRST 131072L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_FIRSTROW_MASK +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_FIRSTROW_MASK 131072i64 +#undef com_artifex_gsjava_GSAPI_GS_SPT_INVALID +#define com_artifex_gsjava_GSAPI_GS_SPT_INVALID -1L +#undef com_artifex_gsjava_GSAPI_GS_SPT_NULL +#define com_artifex_gsjava_GSAPI_GS_SPT_NULL 0L +#undef com_artifex_gsjava_GSAPI_GS_SPT_BOOL +#define com_artifex_gsjava_GSAPI_GS_SPT_BOOL 1L +#undef com_artifex_gsjava_GSAPI_GS_SPT_INT +#define com_artifex_gsjava_GSAPI_GS_SPT_INT 2L +#undef com_artifex_gsjava_GSAPI_GS_SPT_FLOAT +#define com_artifex_gsjava_GSAPI_GS_SPT_FLOAT 3L +#undef com_artifex_gsjava_GSAPI_GS_SPT_NAME +#define com_artifex_gsjava_GSAPI_GS_SPT_NAME 4L +#undef com_artifex_gsjava_GSAPI_GS_SPT_STRING +#define com_artifex_gsjava_GSAPI_GS_SPT_STRING 5L +#undef com_artifex_gsjava_GSAPI_GS_SPT_LONG +#define com_artifex_gsjava_GSAPI_GS_SPT_LONG 6L +#undef com_artifex_gsjava_GSAPI_GS_SPT_I64 +#define com_artifex_gsjava_GSAPI_GS_SPT_I64 7L +#undef com_artifex_gsjava_GSAPI_GS_SPT_SIZE_T +#define com_artifex_gsjava_GSAPI_GS_SPT_SIZE_T 8L +#undef com_artifex_gsjava_GSAPI_GS_SPT_PARSED +#define com_artifex_gsjava_GSAPI_GS_SPT_PARSED 9L +#undef com_artifex_gsjava_GSAPI_GS_SPT_MORE_TO_COME +#define com_artifex_gsjava_GSAPI_GS_SPT_MORE_TO_COME -2147483648L + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_revision + * Signature: (Lcom/artifex/gsjava/GSAPI/Revision;I)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1revision + (JNIEnv *, jclass, jobject, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_new_instance + * Signature: (Lcom/artifex/gsjava/util/Reference;J)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1new_1instance + (JNIEnv *, jclass, jobject, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_delete_instance + * Signature: (J)V + */ + JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1delete_1instance + (JNIEnv *, jclass, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_stdio_with_handle + * Signature: (JLcom/artifex/gsjava/callbacks/IStdInFunction;Lcom/artifex/gsjava/callbacks/IStdOutFunction;Lcom/artifex/gsjava/callbacks/IStdErrFunction;J)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio_1with_1handle + (JNIEnv *, jclass, jlong, jobject, jobject, jobject, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_stdio + * Signature: (JLcom/artifex/gsjava/callbacks/IStdInFunction;Lcom/artifex/gsjava/callbacks/IStdOutFunction;Lcom/artifex/gsjava/callbacks/IStdErrFunction;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio + (JNIEnv *, jclass, jlong, jobject, jobject, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_poll_with_handle + * Signature: (JLcom/artifex/gsjava/callbacks/IPollFunction;J)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1poll_1with_1handle + (JNIEnv *, jclass, jlong, jobject, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_poll + * Signature: (JLcom/artifex/gsjava/callbacks/IPollFunction;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1poll + (JNIEnv *, jclass, jlong, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_display_callback + * Signature: (JLcom/artifex/gsjava/callbacks/DisplayCallback;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1display_1callback + (JNIEnv *, jclass, jlong, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_register_callout + * Signature: (JLcom/artifex/gsjava/callbacks/ICalloutFunction;J)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1register_1callout + (JNIEnv *, jclass, jlong, jobject, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_deregister_callout + * Signature: (JLcom/artifex/gsjava/callbacks/ICalloutFunction;J)V + */ + JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1deregister_1callout + (JNIEnv *, jclass, jlong, jobject, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_arg_encoding + * Signature: (JI)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1arg_1encoding + (JNIEnv *, jclass, jlong, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_default_device_list + * Signature: (J[BI)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1default_1device_1list + (JNIEnv *, jclass, jlong, jbyteArray, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_get_default_device_list + * Signature: (JLcom/artifex/gsjava/util/Reference;Lcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1default_1device_1list + (JNIEnv *, jclass, jlong, jobject, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_init_with_args + * Signature: (JI[[B)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1init_1with_1args + (JNIEnv *, jclass, jlong, jint, jobjectArray); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_string_begin + * Signature: (JILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1begin + (JNIEnv *, jclass, jlong, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_string_continue + * Signature: (J[BIILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1continue + (JNIEnv *, jclass, jlong, jbyteArray, jint, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_string_end + * Signature: (JILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1end + (JNIEnv *, jclass, jlong, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_string_with_length + * Signature: (J[BIILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1with_1length + (JNIEnv *, jclass, jlong, jbyteArray, jint, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_string + * Signature: (J[BILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string + (JNIEnv *, jclass, jlong, jbyteArray, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_file + * Signature: (J[BILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1file + (JNIEnv *, jclass, jlong, jbyteArray, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_exit + * Signature: (J)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1exit + (JNIEnv *, jclass, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_param + * Signature: (J[BLjava/lang/Object;I)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1param + (JNIEnv *, jclass, jlong, jbyteArray, jobject, jint); + + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1param + (JNIEnv *, jclass, jlong, jbyteArray, jlong, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_get_param_once + * Signature: (J[BLcom/artifex/gsjava/util/Reference;I)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1param_1once + (JNIEnv *, jclass, jlong, jbyteArray, jobject, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_enumerate_params + * Signature: (JLcom/artifex/gsjava/util/Reference;Lcom/artifex/gsjava/util/ByteArrayReference;Lcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1enumerate_1params + (JNIEnv *, jclass, jlong, jobject, jobject, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_add_control_path + * Signature: (JI[B)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1add_1control_1path + (JNIEnv *, jclass, jlong, jint, jbyteArray); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_remove_control_path + * Signature: (JI[B)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1remove_1control_1path + (JNIEnv *, jclass, jlong, jint, jbyteArray); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_purge_control_paths + * Signature: (JI)V + */ + JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1purge_1control_1paths + (JNIEnv *, jclass, jlong, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_activate_path_control + * Signature: (JZ)V + */ + JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1activate_1path_1control + (JNIEnv *, jclass, jlong, jboolean); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_is_path_control_active + * Signature: (J)Z + */ + JNIEXPORT jboolean JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1is_1path_1control_1active + (JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.cpp b/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.cpp new file mode 100644 index 00000000..b58c070c --- /dev/null +++ b/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.cpp @@ -0,0 +1,131 @@ +#include "com_artifex_gsjava_util_NativePointer.h" + +#include <memory> + +#include "jni_util.h" + +using namespace util; + +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_mallocNative +(JNIEnv *env, jclass, jlong size) +{ + void *ptr = malloc((size_t)size); + if (ptr == NULL) + return throwAllocationError(env, "malloc"); + return (jlong)ptr; +} + +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_callocNative +(JNIEnv *env, jclass, jlong count, jlong size) +{ + void *ptr = calloc(count, (size_t)size); + if (ptr == NULL) + return throwAllocationError(env, "calloc"); + return (jlong)ptr; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_freeNative +(JNIEnv *, jclass, jlong block) +{ + free((void *)block); +} + +JNIEXPORT jbyteArray JNICALL Java_com_artifex_gsjava_util_NativePointer_byteArrayNative +(JNIEnv *env, jclass, jlong address, jlong len) +{ + jbyteArray array = env->NewByteArray(len); + env->SetByteArrayRegion(array, 0, len, (const jbyte *)address); + return array; +} + +JNIEXPORT jbyte JNICALL Java_com_artifex_gsjava_util_NativePointer_byteAtNative +(JNIEnv *, jclass, jlong address, jlong index) +{ + return ((jbyte *)address)[index]; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setByteNative +(JNIEnv *, jclass, jlong address, jlong index, jbyte value) +{ + ((jbyte *)address)[index]; +} + +JNIEXPORT jcharArray JNICALL Java_com_artifex_gsjava_util_NativePointer_charArrayNative +(JNIEnv *env, jclass, jlong address, jlong len) +{ + jcharArray array = env->NewCharArray(len); + env->SetCharArrayRegion(array, 0, len, (const jchar *)address); + return array; +} + +JNIEXPORT jchar JNICALL Java_com_artifex_gsjava_util_NativePointer_charAtNative +(JNIEnv *, jclass, jlong address, jlong index) +{ + return ((jchar *)address)[index]; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setCharNative +(JNIEnv *, jclass, jlong address, jlong index, jchar value) +{ + ((jchar *)address)[index] = value; +} + +JNIEXPORT jshortArray JNICALL Java_com_artifex_gsjava_util_NativePointer_shortArrayNative +(JNIEnv *env, jclass, jlong address, jlong len) +{ + jshortArray array = env->NewShortArray(len); + env->SetShortArrayRegion(array, 0, len, (const jshort *)address); + return array; +} + +JNIEXPORT jshort JNICALL Java_com_artifex_gsjava_util_NativePointer_shortAtNative +(JNIEnv *, jclass, jlong address, jlong index) +{ + return ((jshort *)address)[index]; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setShortNative +(JNIEnv *, jclass, jlong address, jlong index, jshort value) +{ + ((jshort *)address)[index] = value; +} + +JNIEXPORT jintArray JNICALL Java_com_artifex_gsjava_util_NativePointer_intArrayNative +(JNIEnv *env, jclass, jlong address, jlong len) +{ + jintArray array = env->NewIntArray(len); + env->SetIntArrayRegion(array, 0, len, (const jint *)address); + return array; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_util_NativePointer_intAtNative +(JNIEnv *, jclass, jlong address, jlong index) +{ + return ((jint *)address)[index]; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setIntNative +(JNIEnv *, jclass, jlong address, jlong index, jint value) +{ + ((jint *)address)[index] = value; +} + +JNIEXPORT jlongArray JNICALL Java_com_artifex_gsjava_util_NativePointer_longArrayNative +(JNIEnv *env, jclass, jlong address, jlong len) +{ + jlongArray array = env->NewLongArray(len); + env->SetLongArrayRegion(array, 0, len, (const jlong *)address); + return array; +} + +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_longAtNative +(JNIEnv *, jclass, jlong address, jlong index) +{ + return ((jlong *)address)[index]; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setLongNative +(JNIEnv *, jclass, jlong address, jlong index, jlong value) +{ + ((jlong *)address)[index] = value; +}
\ No newline at end of file diff --git a/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.h b/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.h new file mode 100644 index 00000000..8dd6a30b --- /dev/null +++ b/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.h @@ -0,0 +1,169 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class com_artifex_gsjava_util_NativePointer */ + +#ifndef _Included_com_artifex_gsjava_util_NativePointer +#define _Included_com_artifex_gsjava_util_NativePointer +#ifdef __cplusplus +extern "C" { +#endif +#undef com_artifex_gsjava_util_NativePointer_NULL +#define com_artifex_gsjava_util_NativePointer_NULL 0i64 +#undef com_artifex_gsjava_util_NativePointer_BYTE_SIZE +#define com_artifex_gsjava_util_NativePointer_BYTE_SIZE 1i64 +#undef com_artifex_gsjava_util_NativePointer_CHAR_SIZE +#define com_artifex_gsjava_util_NativePointer_CHAR_SIZE 2i64 +#undef com_artifex_gsjava_util_NativePointer_SHORT_SIZE +#define com_artifex_gsjava_util_NativePointer_SHORT_SIZE 2i64 +#undef com_artifex_gsjava_util_NativePointer_INT_SIZE +#define com_artifex_gsjava_util_NativePointer_INT_SIZE 4i64 +#undef com_artifex_gsjava_util_NativePointer_LONG_SIZE +#define com_artifex_gsjava_util_NativePointer_LONG_SIZE 8i64 +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: mallocNative + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_mallocNative + (JNIEnv *, jclass, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: callocNative + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_callocNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: freeNative + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_freeNative + (JNIEnv *, jclass, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: byteArrayNative + * Signature: (JJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_artifex_gsjava_util_NativePointer_byteArrayNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: byteAtNative + * Signature: (JJ)B + */ +JNIEXPORT jbyte JNICALL Java_com_artifex_gsjava_util_NativePointer_byteAtNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: setByteNative + * Signature: (JJB)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setByteNative + (JNIEnv *, jclass, jlong, jlong, jbyte); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: charArrayNative + * Signature: (JJ)[C + */ +JNIEXPORT jcharArray JNICALL Java_com_artifex_gsjava_util_NativePointer_charArrayNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: charAtNative + * Signature: (JJ)C + */ +JNIEXPORT jchar JNICALL Java_com_artifex_gsjava_util_NativePointer_charAtNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: setCharNative + * Signature: (JJC)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setCharNative + (JNIEnv *, jclass, jlong, jlong, jchar); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: shortArrayNative + * Signature: (JJ)[S + */ +JNIEXPORT jshortArray JNICALL Java_com_artifex_gsjava_util_NativePointer_shortArrayNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: shortAtNative + * Signature: (JJ)S + */ +JNIEXPORT jshort JNICALL Java_com_artifex_gsjava_util_NativePointer_shortAtNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: setShortNative + * Signature: (JJS)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setShortNative + (JNIEnv *, jclass, jlong, jlong, jshort); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: intArrayNative + * Signature: (JJ)[I + */ +JNIEXPORT jintArray JNICALL Java_com_artifex_gsjava_util_NativePointer_intArrayNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: intAtNative + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_util_NativePointer_intAtNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: setIntNative + * Signature: (JJI)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setIntNative + (JNIEnv *, jclass, jlong, jlong, jint); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: longArrayNative + * Signature: (JJ)[J + */ +JNIEXPORT jlongArray JNICALL Java_com_artifex_gsjava_util_NativePointer_longArrayNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: longAtNative + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_longAtNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: setLongNative + * Signature: (JJJ)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setLongNative + (JNIEnv *, jclass, jlong, jlong, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/demos/java/jni/gs_jni/dllmain.cpp b/demos/java/jni/gs_jni/dllmain.cpp new file mode 100644 index 00000000..f6091f3f --- /dev/null +++ b/demos/java/jni/gs_jni/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : Defines the entry point for the DLL application. + +#include <Windows.h> + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +}
\ No newline at end of file diff --git a/demos/java/jni/gs_jni/framework.h b/demos/java/jni/gs_jni/framework.h new file mode 100644 index 00000000..54b83e94 --- /dev/null +++ b/demos/java/jni/gs_jni/framework.h @@ -0,0 +1,5 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include <windows.h> diff --git a/demos/java/jni/gs_jni/gs_jni.sln b/demos/java/jni/gs_jni/gs_jni.sln new file mode 100644 index 00000000..965b2df5 --- /dev/null +++ b/demos/java/jni/gs_jni/gs_jni.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30225.117 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gs_jni", "gs_jni.vcxproj", "{72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Debug|x64.ActiveCfg = Debug|x64 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Debug|x64.Build.0 = Debug|x64 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Debug|x86.ActiveCfg = Debug|Win32 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Debug|x86.Build.0 = Debug|Win32 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Release|x64.ActiveCfg = Release|x64 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Release|x64.Build.0 = Release|x64 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Release|x86.ActiveCfg = Release|Win32 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {70A01221-9F8F-496E-A834-AA2EB06F515A} + EndGlobalSection +EndGlobal diff --git a/demos/java/jni/gs_jni/gs_jni.vcxproj b/demos/java/jni/gs_jni/gs_jni.vcxproj new file mode 100644 index 00000000..eae045e8 --- /dev/null +++ b/demos/java/jni/gs_jni/gs_jni.vcxproj @@ -0,0 +1,184 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>16.0</VCProjectVersion> + <Keyword>Win32Proj</Keyword> + <ProjectGuid>{72caf1b0-7ca6-4044-8705-e0fb2dff01dd}</ProjectGuid> + <RootNamespace>gsjni</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>WIN32;_DEBUG;GSJNI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <PrecompiledHeaderFile> + </PrecompiledHeaderFile> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\..\..\psi;$(SolutionDir)include;$(SolutionDir)..\..\..\..\..\ghostpdl\devices;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableUAC>false</EnableUAC> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)..\..\..\..\debugbin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>WIN32;NDEBUG;GSJNI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <PrecompiledHeaderFile> + </PrecompiledHeaderFile> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\..\..\psi;$(SolutionDir)include;$(SolutionDir)..\..\..\..\..\ghostpdl\devices;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableUAC>false</EnableUAC> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>_DEBUG;GSJNI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <PrecompiledHeaderFile> + </PrecompiledHeaderFile> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\..\..\psi;$(SolutionDir)include;$(SolutionDir)..\..\..\..\..\ghostpdl\devices;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableUAC>false</EnableUAC> + <AdditionalDependencies>gpdldll64.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)..\..\..\..\debugbin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>NDEBUG;GSJNI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <PrecompiledHeaderFile> + </PrecompiledHeaderFile> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\..\..\psi;$(SolutionDir)include;$(SolutionDir)..\..\..\..\..\ghostpdl\devices;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableUAC>false</EnableUAC> + <AdditionalLibraryDirectories>$(SolutionDir)..\..\..\..\bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>gpdldll64.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="callbacks.h" /> + <ClInclude Include="com_artifex_gsjava_GSAPI.h" /> + <ClInclude Include="com_artifex_gsjava_util_NativePointer.h" /> + <ClInclude Include="framework.h" /> + <ClInclude Include="jni_util.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="callbacks.cpp" /> + <ClCompile Include="com_artifex_gsjava_GSAPI.cpp" /> + <ClCompile Include="com_artifex_gsjava_util_NativePointer.cpp" /> + <ClCompile Include="dllmain.cpp" /> + <ClCompile Include="jni_util.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/demos/java/jni/gs_jni/gs_jni.vcxproj.filters b/demos/java/jni/gs_jni/gs_jni.vcxproj.filters new file mode 100644 index 00000000..14063f1b --- /dev/null +++ b/demos/java/jni/gs_jni/gs_jni.vcxproj.filters @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="framework.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="com_artifex_gsjava_GSAPI.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="jni_util.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="callbacks.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="com_artifex_gsjava_util_NativePointer.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="dllmain.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="com_artifex_gsjava_GSAPI.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="jni_util.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="callbacks.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="com_artifex_gsjava_util_NativePointer.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/demos/java/jni/gs_jni/include/classfile_constants.h b/demos/java/jni/gs_jni/include/classfile_constants.h new file mode 100644 index 00000000..e5c20cd9 --- /dev/null +++ b/demos/java/jni/gs_jni/include/classfile_constants.h @@ -0,0 +1,560 @@ +/* + * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef CLASSFILE_CONSTANTS_H +#define CLASSFILE_CONSTANTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Classfile version number for this information */ +#define JVM_CLASSFILE_MAJOR_VERSION 52 +#define JVM_CLASSFILE_MINOR_VERSION 0 + +/* Flags */ + +enum { + JVM_ACC_PUBLIC = 0x0001, + JVM_ACC_PRIVATE = 0x0002, + JVM_ACC_PROTECTED = 0x0004, + JVM_ACC_STATIC = 0x0008, + JVM_ACC_FINAL = 0x0010, + JVM_ACC_SYNCHRONIZED = 0x0020, + JVM_ACC_SUPER = 0x0020, + JVM_ACC_VOLATILE = 0x0040, + JVM_ACC_BRIDGE = 0x0040, + JVM_ACC_TRANSIENT = 0x0080, + JVM_ACC_VARARGS = 0x0080, + JVM_ACC_NATIVE = 0x0100, + JVM_ACC_INTERFACE = 0x0200, + JVM_ACC_ABSTRACT = 0x0400, + JVM_ACC_STRICT = 0x0800, + JVM_ACC_SYNTHETIC = 0x1000, + JVM_ACC_ANNOTATION = 0x2000, + JVM_ACC_ENUM = 0x4000 +}; + +/* Used in newarray instruction. */ + +enum { + JVM_T_BOOLEAN = 4, + JVM_T_CHAR = 5, + JVM_T_FLOAT = 6, + JVM_T_DOUBLE = 7, + JVM_T_BYTE = 8, + JVM_T_SHORT = 9, + JVM_T_INT = 10, + JVM_T_LONG = 11 +}; + +/* Constant Pool Entries */ + +enum { + JVM_CONSTANT_Utf8 = 1, + JVM_CONSTANT_Unicode = 2, /* unused */ + JVM_CONSTANT_Integer = 3, + JVM_CONSTANT_Float = 4, + JVM_CONSTANT_Long = 5, + JVM_CONSTANT_Double = 6, + JVM_CONSTANT_Class = 7, + JVM_CONSTANT_String = 8, + JVM_CONSTANT_Fieldref = 9, + JVM_CONSTANT_Methodref = 10, + JVM_CONSTANT_InterfaceMethodref = 11, + JVM_CONSTANT_NameAndType = 12, + JVM_CONSTANT_MethodHandle = 15, // JSR 292 + JVM_CONSTANT_MethodType = 16, // JSR 292 + JVM_CONSTANT_InvokeDynamic = 18 +}; + +/* JVM_CONSTANT_MethodHandle subtypes */ +enum { + JVM_REF_getField = 1, + JVM_REF_getStatic = 2, + JVM_REF_putField = 3, + JVM_REF_putStatic = 4, + JVM_REF_invokeVirtual = 5, + JVM_REF_invokeStatic = 6, + JVM_REF_invokeSpecial = 7, + JVM_REF_newInvokeSpecial = 8, + JVM_REF_invokeInterface = 9 +}; + +/* StackMapTable type item numbers */ + +enum { + JVM_ITEM_Top = 0, + JVM_ITEM_Integer = 1, + JVM_ITEM_Float = 2, + JVM_ITEM_Double = 3, + JVM_ITEM_Long = 4, + JVM_ITEM_Null = 5, + JVM_ITEM_UninitializedThis = 6, + JVM_ITEM_Object = 7, + JVM_ITEM_Uninitialized = 8 +}; + +/* Type signatures */ + +enum { + JVM_SIGNATURE_ARRAY = '[', + JVM_SIGNATURE_BYTE = 'B', + JVM_SIGNATURE_CHAR = 'C', + JVM_SIGNATURE_CLASS = 'L', + JVM_SIGNATURE_ENDCLASS = ';', + JVM_SIGNATURE_ENUM = 'E', + JVM_SIGNATURE_FLOAT = 'F', + JVM_SIGNATURE_DOUBLE = 'D', + JVM_SIGNATURE_FUNC = '(', + JVM_SIGNATURE_ENDFUNC = ')', + JVM_SIGNATURE_INT = 'I', + JVM_SIGNATURE_LONG = 'J', + JVM_SIGNATURE_SHORT = 'S', + JVM_SIGNATURE_VOID = 'V', + JVM_SIGNATURE_BOOLEAN = 'Z' +}; + +/* Opcodes */ + +enum { + JVM_OPC_nop = 0, + JVM_OPC_aconst_null = 1, + JVM_OPC_iconst_m1 = 2, + JVM_OPC_iconst_0 = 3, + JVM_OPC_iconst_1 = 4, + JVM_OPC_iconst_2 = 5, + JVM_OPC_iconst_3 = 6, + JVM_OPC_iconst_4 = 7, + JVM_OPC_iconst_5 = 8, + JVM_OPC_lconst_0 = 9, + JVM_OPC_lconst_1 = 10, + JVM_OPC_fconst_0 = 11, + JVM_OPC_fconst_1 = 12, + JVM_OPC_fconst_2 = 13, + JVM_OPC_dconst_0 = 14, + JVM_OPC_dconst_1 = 15, + JVM_OPC_bipush = 16, + JVM_OPC_sipush = 17, + JVM_OPC_ldc = 18, + JVM_OPC_ldc_w = 19, + JVM_OPC_ldc2_w = 20, + JVM_OPC_iload = 21, + JVM_OPC_lload = 22, + JVM_OPC_fload = 23, + JVM_OPC_dload = 24, + JVM_OPC_aload = 25, + JVM_OPC_iload_0 = 26, + JVM_OPC_iload_1 = 27, + JVM_OPC_iload_2 = 28, + JVM_OPC_iload_3 = 29, + JVM_OPC_lload_0 = 30, + JVM_OPC_lload_1 = 31, + JVM_OPC_lload_2 = 32, + JVM_OPC_lload_3 = 33, + JVM_OPC_fload_0 = 34, + JVM_OPC_fload_1 = 35, + JVM_OPC_fload_2 = 36, + JVM_OPC_fload_3 = 37, + JVM_OPC_dload_0 = 38, + JVM_OPC_dload_1 = 39, + JVM_OPC_dload_2 = 40, + JVM_OPC_dload_3 = 41, + JVM_OPC_aload_0 = 42, + JVM_OPC_aload_1 = 43, + JVM_OPC_aload_2 = 44, + JVM_OPC_aload_3 = 45, + JVM_OPC_iaload = 46, + JVM_OPC_laload = 47, + JVM_OPC_faload = 48, + JVM_OPC_daload = 49, + JVM_OPC_aaload = 50, + JVM_OPC_baload = 51, + JVM_OPC_caload = 52, + JVM_OPC_saload = 53, + JVM_OPC_istore = 54, + JVM_OPC_lstore = 55, + JVM_OPC_fstore = 56, + JVM_OPC_dstore = 57, + JVM_OPC_astore = 58, + JVM_OPC_istore_0 = 59, + JVM_OPC_istore_1 = 60, + JVM_OPC_istore_2 = 61, + JVM_OPC_istore_3 = 62, + JVM_OPC_lstore_0 = 63, + JVM_OPC_lstore_1 = 64, + JVM_OPC_lstore_2 = 65, + JVM_OPC_lstore_3 = 66, + JVM_OPC_fstore_0 = 67, + JVM_OPC_fstore_1 = 68, + JVM_OPC_fstore_2 = 69, + JVM_OPC_fstore_3 = 70, + JVM_OPC_dstore_0 = 71, + JVM_OPC_dstore_1 = 72, + JVM_OPC_dstore_2 = 73, + JVM_OPC_dstore_3 = 74, + JVM_OPC_astore_0 = 75, + JVM_OPC_astore_1 = 76, + JVM_OPC_astore_2 = 77, + JVM_OPC_astore_3 = 78, + JVM_OPC_iastore = 79, + JVM_OPC_lastore = 80, + JVM_OPC_fastore = 81, + JVM_OPC_dastore = 82, + JVM_OPC_aastore = 83, + JVM_OPC_bastore = 84, + JVM_OPC_castore = 85, + JVM_OPC_sastore = 86, + JVM_OPC_pop = 87, + JVM_OPC_pop2 = 88, + JVM_OPC_dup = 89, + JVM_OPC_dup_x1 = 90, + JVM_OPC_dup_x2 = 91, + JVM_OPC_dup2 = 92, + JVM_OPC_dup2_x1 = 93, + JVM_OPC_dup2_x2 = 94, + JVM_OPC_swap = 95, + JVM_OPC_iadd = 96, + JVM_OPC_ladd = 97, + JVM_OPC_fadd = 98, + JVM_OPC_dadd = 99, + JVM_OPC_isub = 100, + JVM_OPC_lsub = 101, + JVM_OPC_fsub = 102, + JVM_OPC_dsub = 103, + JVM_OPC_imul = 104, + JVM_OPC_lmul = 105, + JVM_OPC_fmul = 106, + JVM_OPC_dmul = 107, + JVM_OPC_idiv = 108, + JVM_OPC_ldiv = 109, + JVM_OPC_fdiv = 110, + JVM_OPC_ddiv = 111, + JVM_OPC_irem = 112, + JVM_OPC_lrem = 113, + JVM_OPC_frem = 114, + JVM_OPC_drem = 115, + JVM_OPC_ineg = 116, + JVM_OPC_lneg = 117, + JVM_OPC_fneg = 118, + JVM_OPC_dneg = 119, + JVM_OPC_ishl = 120, + JVM_OPC_lshl = 121, + JVM_OPC_ishr = 122, + JVM_OPC_lshr = 123, + JVM_OPC_iushr = 124, + JVM_OPC_lushr = 125, + JVM_OPC_iand = 126, + JVM_OPC_land = 127, + JVM_OPC_ior = 128, + JVM_OPC_lor = 129, + JVM_OPC_ixor = 130, + JVM_OPC_lxor = 131, + JVM_OPC_iinc = 132, + JVM_OPC_i2l = 133, + JVM_OPC_i2f = 134, + JVM_OPC_i2d = 135, + JVM_OPC_l2i = 136, + JVM_OPC_l2f = 137, + JVM_OPC_l2d = 138, + JVM_OPC_f2i = 139, + JVM_OPC_f2l = 140, + JVM_OPC_f2d = 141, + JVM_OPC_d2i = 142, + JVM_OPC_d2l = 143, + JVM_OPC_d2f = 144, + JVM_OPC_i2b = 145, + JVM_OPC_i2c = 146, + JVM_OPC_i2s = 147, + JVM_OPC_lcmp = 148, + JVM_OPC_fcmpl = 149, + JVM_OPC_fcmpg = 150, + JVM_OPC_dcmpl = 151, + JVM_OPC_dcmpg = 152, + JVM_OPC_ifeq = 153, + JVM_OPC_ifne = 154, + JVM_OPC_iflt = 155, + JVM_OPC_ifge = 156, + JVM_OPC_ifgt = 157, + JVM_OPC_ifle = 158, + JVM_OPC_if_icmpeq = 159, + JVM_OPC_if_icmpne = 160, + JVM_OPC_if_icmplt = 161, + JVM_OPC_if_icmpge = 162, + JVM_OPC_if_icmpgt = 163, + JVM_OPC_if_icmple = 164, + JVM_OPC_if_acmpeq = 165, + JVM_OPC_if_acmpne = 166, + JVM_OPC_goto = 167, + JVM_OPC_jsr = 168, + JVM_OPC_ret = 169, + JVM_OPC_tableswitch = 170, + JVM_OPC_lookupswitch = 171, + JVM_OPC_ireturn = 172, + JVM_OPC_lreturn = 173, + JVM_OPC_freturn = 174, + JVM_OPC_dreturn = 175, + JVM_OPC_areturn = 176, + JVM_OPC_return = 177, + JVM_OPC_getstatic = 178, + JVM_OPC_putstatic = 179, + JVM_OPC_getfield = 180, + JVM_OPC_putfield = 181, + JVM_OPC_invokevirtual = 182, + JVM_OPC_invokespecial = 183, + JVM_OPC_invokestatic = 184, + JVM_OPC_invokeinterface = 185, + JVM_OPC_invokedynamic = 186, + JVM_OPC_new = 187, + JVM_OPC_newarray = 188, + JVM_OPC_anewarray = 189, + JVM_OPC_arraylength = 190, + JVM_OPC_athrow = 191, + JVM_OPC_checkcast = 192, + JVM_OPC_instanceof = 193, + JVM_OPC_monitorenter = 194, + JVM_OPC_monitorexit = 195, + JVM_OPC_wide = 196, + JVM_OPC_multianewarray = 197, + JVM_OPC_ifnull = 198, + JVM_OPC_ifnonnull = 199, + JVM_OPC_goto_w = 200, + JVM_OPC_jsr_w = 201, + JVM_OPC_MAX = 201 +}; + +/* Opcode length initializer, use with something like: + * unsigned char opcode_length[JVM_OPC_MAX+1] = JVM_OPCODE_LENGTH_INITIALIZER; + */ +#define JVM_OPCODE_LENGTH_INITIALIZER { \ + 1, /* nop */ \ + 1, /* aconst_null */ \ + 1, /* iconst_m1 */ \ + 1, /* iconst_0 */ \ + 1, /* iconst_1 */ \ + 1, /* iconst_2 */ \ + 1, /* iconst_3 */ \ + 1, /* iconst_4 */ \ + 1, /* iconst_5 */ \ + 1, /* lconst_0 */ \ + 1, /* lconst_1 */ \ + 1, /* fconst_0 */ \ + 1, /* fconst_1 */ \ + 1, /* fconst_2 */ \ + 1, /* dconst_0 */ \ + 1, /* dconst_1 */ \ + 2, /* bipush */ \ + 3, /* sipush */ \ + 2, /* ldc */ \ + 3, /* ldc_w */ \ + 3, /* ldc2_w */ \ + 2, /* iload */ \ + 2, /* lload */ \ + 2, /* fload */ \ + 2, /* dload */ \ + 2, /* aload */ \ + 1, /* iload_0 */ \ + 1, /* iload_1 */ \ + 1, /* iload_2 */ \ + 1, /* iload_3 */ \ + 1, /* lload_0 */ \ + 1, /* lload_1 */ \ + 1, /* lload_2 */ \ + 1, /* lload_3 */ \ + 1, /* fload_0 */ \ + 1, /* fload_1 */ \ + 1, /* fload_2 */ \ + 1, /* fload_3 */ \ + 1, /* dload_0 */ \ + 1, /* dload_1 */ \ + 1, /* dload_2 */ \ + 1, /* dload_3 */ \ + 1, /* aload_0 */ \ + 1, /* aload_1 */ \ + 1, /* aload_2 */ \ + 1, /* aload_3 */ \ + 1, /* iaload */ \ + 1, /* laload */ \ + 1, /* faload */ \ + 1, /* daload */ \ + 1, /* aaload */ \ + 1, /* baload */ \ + 1, /* caload */ \ + 1, /* saload */ \ + 2, /* istore */ \ + 2, /* lstore */ \ + 2, /* fstore */ \ + 2, /* dstore */ \ + 2, /* astore */ \ + 1, /* istore_0 */ \ + 1, /* istore_1 */ \ + 1, /* istore_2 */ \ + 1, /* istore_3 */ \ + 1, /* lstore_0 */ \ + 1, /* lstore_1 */ \ + 1, /* lstore_2 */ \ + 1, /* lstore_3 */ \ + 1, /* fstore_0 */ \ + 1, /* fstore_1 */ \ + 1, /* fstore_2 */ \ + 1, /* fstore_3 */ \ + 1, /* dstore_0 */ \ + 1, /* dstore_1 */ \ + 1, /* dstore_2 */ \ + 1, /* dstore_3 */ \ + 1, /* astore_0 */ \ + 1, /* astore_1 */ \ + 1, /* astore_2 */ \ + 1, /* astore_3 */ \ + 1, /* iastore */ \ + 1, /* lastore */ \ + 1, /* fastore */ \ + 1, /* dastore */ \ + 1, /* aastore */ \ + 1, /* bastore */ \ + 1, /* castore */ \ + 1, /* sastore */ \ + 1, /* pop */ \ + 1, /* pop2 */ \ + 1, /* dup */ \ + 1, /* dup_x1 */ \ + 1, /* dup_x2 */ \ + 1, /* dup2 */ \ + 1, /* dup2_x1 */ \ + 1, /* dup2_x2 */ \ + 1, /* swap */ \ + 1, /* iadd */ \ + 1, /* ladd */ \ + 1, /* fadd */ \ + 1, /* dadd */ \ + 1, /* isub */ \ + 1, /* lsub */ \ + 1, /* fsub */ \ + 1, /* dsub */ \ + 1, /* imul */ \ + 1, /* lmul */ \ + 1, /* fmul */ \ + 1, /* dmul */ \ + 1, /* idiv */ \ + 1, /* ldiv */ \ + 1, /* fdiv */ \ + 1, /* ddiv */ \ + 1, /* irem */ \ + 1, /* lrem */ \ + 1, /* frem */ \ + 1, /* drem */ \ + 1, /* ineg */ \ + 1, /* lneg */ \ + 1, /* fneg */ \ + 1, /* dneg */ \ + 1, /* ishl */ \ + 1, /* lshl */ \ + 1, /* ishr */ \ + 1, /* lshr */ \ + 1, /* iushr */ \ + 1, /* lushr */ \ + 1, /* iand */ \ + 1, /* land */ \ + 1, /* ior */ \ + 1, /* lor */ \ + 1, /* ixor */ \ + 1, /* lxor */ \ + 3, /* iinc */ \ + 1, /* i2l */ \ + 1, /* i2f */ \ + 1, /* i2d */ \ + 1, /* l2i */ \ + 1, /* l2f */ \ + 1, /* l2d */ \ + 1, /* f2i */ \ + 1, /* f2l */ \ + 1, /* f2d */ \ + 1, /* d2i */ \ + 1, /* d2l */ \ + 1, /* d2f */ \ + 1, /* i2b */ \ + 1, /* i2c */ \ + 1, /* i2s */ \ + 1, /* lcmp */ \ + 1, /* fcmpl */ \ + 1, /* fcmpg */ \ + 1, /* dcmpl */ \ + 1, /* dcmpg */ \ + 3, /* ifeq */ \ + 3, /* ifne */ \ + 3, /* iflt */ \ + 3, /* ifge */ \ + 3, /* ifgt */ \ + 3, /* ifle */ \ + 3, /* if_icmpeq */ \ + 3, /* if_icmpne */ \ + 3, /* if_icmplt */ \ + 3, /* if_icmpge */ \ + 3, /* if_icmpgt */ \ + 3, /* if_icmple */ \ + 3, /* if_acmpeq */ \ + 3, /* if_acmpne */ \ + 3, /* goto */ \ + 3, /* jsr */ \ + 2, /* ret */ \ + 99, /* tableswitch */ \ + 99, /* lookupswitch */ \ + 1, /* ireturn */ \ + 1, /* lreturn */ \ + 1, /* freturn */ \ + 1, /* dreturn */ \ + 1, /* areturn */ \ + 1, /* return */ \ + 3, /* getstatic */ \ + 3, /* putstatic */ \ + 3, /* getfield */ \ + 3, /* putfield */ \ + 3, /* invokevirtual */ \ + 3, /* invokespecial */ \ + 3, /* invokestatic */ \ + 5, /* invokeinterface */ \ + 5, /* invokedynamic */ \ + 3, /* new */ \ + 2, /* newarray */ \ + 3, /* anewarray */ \ + 1, /* arraylength */ \ + 1, /* athrow */ \ + 3, /* checkcast */ \ + 3, /* instanceof */ \ + 1, /* monitorenter */ \ + 1, /* monitorexit */ \ + 0, /* wide */ \ + 4, /* multianewarray */ \ + 3, /* ifnull */ \ + 3, /* ifnonnull */ \ + 5, /* goto_w */ \ + 5 /* jsr_w */ \ +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* CLASSFILE_CONSTANTS */ diff --git a/demos/java/jni/gs_jni/include/jawt.h b/demos/java/jni/gs_jni/include/jawt.h new file mode 100644 index 00000000..f06e8071 --- /dev/null +++ b/demos/java/jni/gs_jni/include/jawt.h @@ -0,0 +1,299 @@ +/* + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef _JAVASOFT_JAWT_H_ +#define _JAVASOFT_JAWT_H_ + +#include "jni.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * AWT native interface (new in JDK 1.3) + * + * The AWT native interface allows a native C or C++ application a means + * by which to access native structures in AWT. This is to facilitate moving + * legacy C and C++ applications to Java and to target the needs of the + * community who, at present, wish to do their own native rendering to canvases + * for performance reasons. Standard extensions such as Java3D also require a + * means to access the underlying native data structures of AWT. + * + * There may be future extensions to this API depending on demand. + * + * A VM does not have to implement this API in order to pass the JCK. + * It is recommended, however, that this API is implemented on VMs that support + * standard extensions, such as Java3D. + * + * Since this is a native API, any program which uses it cannot be considered + * 100% pure java. + */ + +/* + * AWT Native Drawing Surface (JAWT_DrawingSurface). + * + * For each platform, there is a native drawing surface structure. This + * platform-specific structure can be found in jawt_md.h. It is recommended + * that additional platforms follow the same model. It is also recommended + * that VMs on Win32 and Solaris support the existing structures in jawt_md.h. + * + ******************* + * EXAMPLE OF USAGE: + ******************* + * + * In Win32, a programmer wishes to access the HWND of a canvas to perform + * native rendering into it. The programmer has declared the paint() method + * for their canvas subclass to be native: + * + * + * MyCanvas.java: + * + * import java.awt.*; + * + * public class MyCanvas extends Canvas { + * + * static { + * System.loadLibrary("mylib"); + * } + * + * public native void paint(Graphics g); + * } + * + * + * myfile.c: + * + * #include "jawt_md.h" + * #include <assert.h> + * + * JNIEXPORT void JNICALL + * Java_MyCanvas_paint(JNIEnv* env, jobject canvas, jobject graphics) + * { + * JAWT awt; + * JAWT_DrawingSurface* ds; + * JAWT_DrawingSurfaceInfo* dsi; + * JAWT_Win32DrawingSurfaceInfo* dsi_win; + * jboolean result; + * jint lock; + * + * // Get the AWT + * awt.version = JAWT_VERSION_1_3; + * result = JAWT_GetAWT(env, &awt); + * assert(result != JNI_FALSE); + * + * // Get the drawing surface + * ds = awt.GetDrawingSurface(env, canvas); + * assert(ds != NULL); + * + * // Lock the drawing surface + * lock = ds->Lock(ds); + * assert((lock & JAWT_LOCK_ERROR) == 0); + * + * // Get the drawing surface info + * dsi = ds->GetDrawingSurfaceInfo(ds); + * + * // Get the platform-specific drawing info + * dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo; + * + * ////////////////////////////// + * // !!! DO PAINTING HERE !!! // + * ////////////////////////////// + * + * // Free the drawing surface info + * ds->FreeDrawingSurfaceInfo(dsi); + * + * // Unlock the drawing surface + * ds->Unlock(ds); + * + * // Free the drawing surface + * awt.FreeDrawingSurface(ds); + * } + * + */ + +/* + * JAWT_Rectangle + * Structure for a native rectangle. + */ +typedef struct jawt_Rectangle { + jint x; + jint y; + jint width; + jint height; +} JAWT_Rectangle; + +struct jawt_DrawingSurface; + +/* + * JAWT_DrawingSurfaceInfo + * Structure for containing the underlying drawing information of a component. + */ +typedef struct jawt_DrawingSurfaceInfo { + /* + * Pointer to the platform-specific information. This can be safely + * cast to a JAWT_Win32DrawingSurfaceInfo on Windows or a + * JAWT_X11DrawingSurfaceInfo on Solaris. On Mac OS X this is a + * pointer to a NSObject that conforms to the JAWT_SurfaceLayers + * protocol. See jawt_md.h for details. + */ + void* platformInfo; + /* Cached pointer to the underlying drawing surface */ + struct jawt_DrawingSurface* ds; + /* Bounding rectangle of the drawing surface */ + JAWT_Rectangle bounds; + /* Number of rectangles in the clip */ + jint clipSize; + /* Clip rectangle array */ + JAWT_Rectangle* clip; +} JAWT_DrawingSurfaceInfo; + +#define JAWT_LOCK_ERROR 0x00000001 +#define JAWT_LOCK_CLIP_CHANGED 0x00000002 +#define JAWT_LOCK_BOUNDS_CHANGED 0x00000004 +#define JAWT_LOCK_SURFACE_CHANGED 0x00000008 + +/* + * JAWT_DrawingSurface + * Structure for containing the underlying drawing information of a component. + * All operations on a JAWT_DrawingSurface MUST be performed from the same + * thread as the call to GetDrawingSurface. + */ +typedef struct jawt_DrawingSurface { + /* + * Cached reference to the Java environment of the calling thread. + * If Lock(), Unlock(), GetDrawingSurfaceInfo() or + * FreeDrawingSurfaceInfo() are called from a different thread, + * this data member should be set before calling those functions. + */ + JNIEnv* env; + /* Cached reference to the target object */ + jobject target; + /* + * Lock the surface of the target component for native rendering. + * When finished drawing, the surface must be unlocked with + * Unlock(). This function returns a bitmask with one or more of the + * following values: + * + * JAWT_LOCK_ERROR - When an error has occurred and the surface could not + * be locked. + * + * JAWT_LOCK_CLIP_CHANGED - When the clip region has changed. + * + * JAWT_LOCK_BOUNDS_CHANGED - When the bounds of the surface have changed. + * + * JAWT_LOCK_SURFACE_CHANGED - When the surface itself has changed + */ + jint (JNICALL *Lock) + (struct jawt_DrawingSurface* ds); + /* + * Get the drawing surface info. + * The value returned may be cached, but the values may change if + * additional calls to Lock() or Unlock() are made. + * Lock() must be called before this can return a valid value. + * Returns NULL if an error has occurred. + * When finished with the returned value, FreeDrawingSurfaceInfo must be + * called. + */ + JAWT_DrawingSurfaceInfo* (JNICALL *GetDrawingSurfaceInfo) + (struct jawt_DrawingSurface* ds); + /* + * Free the drawing surface info. + */ + void (JNICALL *FreeDrawingSurfaceInfo) + (JAWT_DrawingSurfaceInfo* dsi); + /* + * Unlock the drawing surface of the target component for native rendering. + */ + void (JNICALL *Unlock) + (struct jawt_DrawingSurface* ds); +} JAWT_DrawingSurface; + +/* + * JAWT + * Structure for containing native AWT functions. + */ +typedef struct jawt { + /* + * Version of this structure. This must always be set before + * calling JAWT_GetAWT() + */ + jint version; + /* + * Return a drawing surface from a target jobject. This value + * may be cached. + * Returns NULL if an error has occurred. + * Target must be a java.awt.Component (should be a Canvas + * or Window for native rendering). + * FreeDrawingSurface() must be called when finished with the + * returned JAWT_DrawingSurface. + */ + JAWT_DrawingSurface* (JNICALL *GetDrawingSurface) + (JNIEnv* env, jobject target); + /* + * Free the drawing surface allocated in GetDrawingSurface. + */ + void (JNICALL *FreeDrawingSurface) + (JAWT_DrawingSurface* ds); + /* + * Since 1.4 + * Locks the entire AWT for synchronization purposes + */ + void (JNICALL *Lock)(JNIEnv* env); + /* + * Since 1.4 + * Unlocks the entire AWT for synchronization purposes + */ + void (JNICALL *Unlock)(JNIEnv* env); + /* + * Since 1.4 + * Returns a reference to a java.awt.Component from a native + * platform handle. On Windows, this corresponds to an HWND; + * on Solaris and Linux, this is a Drawable. For other platforms, + * see the appropriate machine-dependent header file for a description. + * The reference returned by this function is a local + * reference that is only valid in this environment. + * This function returns a NULL reference if no component could be + * found with matching platform information. + */ + jobject (JNICALL *GetComponent)(JNIEnv* env, void* platformInfo); + +} JAWT; + +/* + * Get the AWT native structure. This function returns JNI_FALSE if + * an error occurs. + */ +_JNI_IMPORT_OR_EXPORT_ +jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt); + +#define JAWT_VERSION_1_3 0x00010003 +#define JAWT_VERSION_1_4 0x00010004 +#define JAWT_VERSION_1_7 0x00010007 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* !_JAVASOFT_JAWT_H_ */ diff --git a/demos/java/jni/gs_jni/include/jdwpTransport.h b/demos/java/jni/gs_jni/include/jdwpTransport.h new file mode 100644 index 00000000..4f4b92ed --- /dev/null +++ b/demos/java/jni/gs_jni/include/jdwpTransport.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * Java Debug Wire Protocol Transport Service Provider Interface. + */ + +#ifndef JDWPTRANSPORT_H +#define JDWPTRANSPORT_H + +#include "jni.h" + +enum { + JDWPTRANSPORT_VERSION_1_0 = 0x00010000 +}; + +#ifdef __cplusplus +extern "C" { +#endif + +struct jdwpTransportNativeInterface_; + +struct _jdwpTransportEnv; + +#ifdef __cplusplus +typedef _jdwpTransportEnv jdwpTransportEnv; +#else +typedef const struct jdwpTransportNativeInterface_ *jdwpTransportEnv; +#endif /* __cplusplus */ + +/* + * Errors. Universal errors with JVMTI/JVMDI equivalents keep the + * values the same. + */ +typedef enum { + JDWPTRANSPORT_ERROR_NONE = 0, + JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT = 103, + JDWPTRANSPORT_ERROR_OUT_OF_MEMORY = 110, + JDWPTRANSPORT_ERROR_INTERNAL = 113, + JDWPTRANSPORT_ERROR_ILLEGAL_STATE = 201, + JDWPTRANSPORT_ERROR_IO_ERROR = 202, + JDWPTRANSPORT_ERROR_TIMEOUT = 203, + JDWPTRANSPORT_ERROR_MSG_NOT_AVAILABLE = 204 +} jdwpTransportError; + + +/* + * Structure to define capabilities + */ +typedef struct { + unsigned int can_timeout_attach :1; + unsigned int can_timeout_accept :1; + unsigned int can_timeout_handshake :1; + unsigned int reserved3 :1; + unsigned int reserved4 :1; + unsigned int reserved5 :1; + unsigned int reserved6 :1; + unsigned int reserved7 :1; + unsigned int reserved8 :1; + unsigned int reserved9 :1; + unsigned int reserved10 :1; + unsigned int reserved11 :1; + unsigned int reserved12 :1; + unsigned int reserved13 :1; + unsigned int reserved14 :1; + unsigned int reserved15 :1; +} JDWPTransportCapabilities; + + +/* + * Structures to define packet layout. + * + * See: http://java.sun.com/j2se/1.5/docs/guide/jpda/jdwp-spec.html + */ + +enum { + /* + * If additional flags are added that apply to jdwpCmdPacket, + * then debugLoop.c: reader() will need to be updated to + * accept more than JDWPTRANSPORT_FLAGS_NONE. + */ + JDWPTRANSPORT_FLAGS_NONE = 0x0, + JDWPTRANSPORT_FLAGS_REPLY = 0x80 +}; + +typedef struct { + jint len; + jint id; + jbyte flags; + jbyte cmdSet; + jbyte cmd; + jbyte *data; +} jdwpCmdPacket; + +typedef struct { + jint len; + jint id; + jbyte flags; + jshort errorCode; + jbyte *data; +} jdwpReplyPacket; + +typedef struct { + union { + jdwpCmdPacket cmd; + jdwpReplyPacket reply; + } type; +} jdwpPacket; + +/* + * JDWP functions called by the transport. + */ +typedef struct jdwpTransportCallback { + void *(*alloc)(jint numBytes); /* Call this for all allocations */ + void (*free)(void *buffer); /* Call this for all deallocations */ +} jdwpTransportCallback; + +typedef jint (JNICALL *jdwpTransport_OnLoad_t)(JavaVM *jvm, + jdwpTransportCallback *callback, + jint version, + jdwpTransportEnv** env); + + + +/* Function Interface */ + +struct jdwpTransportNativeInterface_ { + /* 1 : RESERVED */ + void *reserved1; + + /* 2 : Get Capabilities */ + jdwpTransportError (JNICALL *GetCapabilities)(jdwpTransportEnv* env, + JDWPTransportCapabilities *capabilities_ptr); + + /* 3 : Attach */ + jdwpTransportError (JNICALL *Attach)(jdwpTransportEnv* env, + const char* address, + jlong attach_timeout, + jlong handshake_timeout); + + /* 4: StartListening */ + jdwpTransportError (JNICALL *StartListening)(jdwpTransportEnv* env, + const char* address, + char** actual_address); + + /* 5: StopListening */ + jdwpTransportError (JNICALL *StopListening)(jdwpTransportEnv* env); + + /* 6: Accept */ + jdwpTransportError (JNICALL *Accept)(jdwpTransportEnv* env, + jlong accept_timeout, + jlong handshake_timeout); + + /* 7: IsOpen */ + jboolean (JNICALL *IsOpen)(jdwpTransportEnv* env); + + /* 8: Close */ + jdwpTransportError (JNICALL *Close)(jdwpTransportEnv* env); + + /* 9: ReadPacket */ + jdwpTransportError (JNICALL *ReadPacket)(jdwpTransportEnv* env, + jdwpPacket *pkt); + + /* 10: Write Packet */ + jdwpTransportError (JNICALL *WritePacket)(jdwpTransportEnv* env, + const jdwpPacket* pkt); + + /* 11: GetLastError */ + jdwpTransportError (JNICALL *GetLastError)(jdwpTransportEnv* env, + char** error); + +}; + + +/* + * Use inlined functions so that C++ code can use syntax such as + * env->Attach("mymachine:5000", 10*1000, 0); + * + * rather than using C's :- + * + * (*env)->Attach(env, "mymachine:5000", 10*1000, 0); + */ +struct _jdwpTransportEnv { + const struct jdwpTransportNativeInterface_ *functions; +#ifdef __cplusplus + + jdwpTransportError GetCapabilities(JDWPTransportCapabilities *capabilities_ptr) { + return functions->GetCapabilities(this, capabilities_ptr); + } + + jdwpTransportError Attach(const char* address, jlong attach_timeout, + jlong handshake_timeout) { + return functions->Attach(this, address, attach_timeout, handshake_timeout); + } + + jdwpTransportError StartListening(const char* address, + char** actual_address) { + return functions->StartListening(this, address, actual_address); + } + + jdwpTransportError StopListening(void) { + return functions->StopListening(this); + } + + jdwpTransportError Accept(jlong accept_timeout, jlong handshake_timeout) { + return functions->Accept(this, accept_timeout, handshake_timeout); + } + + jboolean IsOpen(void) { + return functions->IsOpen(this); + } + + jdwpTransportError Close(void) { + return functions->Close(this); + } + + jdwpTransportError ReadPacket(jdwpPacket *pkt) { + return functions->ReadPacket(this, pkt); + } + + jdwpTransportError WritePacket(const jdwpPacket* pkt) { + return functions->WritePacket(this, pkt); + } + + jdwpTransportError GetLastError(char** error) { + return functions->GetLastError(this, error); + } + + +#endif /* __cplusplus */ +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* JDWPTRANSPORT_H */ diff --git a/demos/java/jni/gs_jni/include/jni.h b/demos/java/jni/gs_jni/include/jni.h new file mode 100644 index 00000000..97b14d8a --- /dev/null +++ b/demos/java/jni/gs_jni/include/jni.h @@ -0,0 +1,1964 @@ +/* + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * We used part of Netscape's Java Runtime Interface (JRI) as the starting + * point of our design and implementation. + */ + +/****************************************************************************** + * Java Runtime Interface + * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. + *****************************************************************************/ + +#ifndef _JAVASOFT_JNI_H_ +#define _JAVASOFT_JNI_H_ + +#include <stdio.h> +#include <stdarg.h> + +/* jni_md.h contains the machine-dependent typedefs for jbyte, jint + and jlong */ + +#ifdef _WIN32 +#include "win32/jni_md.h" +#else +#include "jni_md.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * JNI Types + */ + +#ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H + +typedef unsigned char jboolean; +typedef unsigned short jchar; +typedef short jshort; +typedef float jfloat; +typedef double jdouble; + +typedef jint jsize; + +#ifdef __cplusplus + +class _jobject {}; +class _jclass : public _jobject {}; +class _jthrowable : public _jobject {}; +class _jstring : public _jobject {}; +class _jarray : public _jobject {}; +class _jbooleanArray : public _jarray {}; +class _jbyteArray : public _jarray {}; +class _jcharArray : public _jarray {}; +class _jshortArray : public _jarray {}; +class _jintArray : public _jarray {}; +class _jlongArray : public _jarray {}; +class _jfloatArray : public _jarray {}; +class _jdoubleArray : public _jarray {}; +class _jobjectArray : public _jarray {}; + +typedef _jobject *jobject; +typedef _jclass *jclass; +typedef _jthrowable *jthrowable; +typedef _jstring *jstring; +typedef _jarray *jarray; +typedef _jbooleanArray *jbooleanArray; +typedef _jbyteArray *jbyteArray; +typedef _jcharArray *jcharArray; +typedef _jshortArray *jshortArray; +typedef _jintArray *jintArray; +typedef _jlongArray *jlongArray; +typedef _jfloatArray *jfloatArray; +typedef _jdoubleArray *jdoubleArray; +typedef _jobjectArray *jobjectArray; + +#else + +struct _jobject; + +typedef struct _jobject *jobject; +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +#endif + +typedef jobject jweak; + +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +struct _jfieldID; +typedef struct _jfieldID *jfieldID; + +struct _jmethodID; +typedef struct _jmethodID *jmethodID; + +/* Return values from jobjectRefType */ +typedef enum _jobjectType { + JNIInvalidRefType = 0, + JNILocalRefType = 1, + JNIGlobalRefType = 2, + JNIWeakGlobalRefType = 3 +} jobjectRefType; + + +#endif /* JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H */ + +/* + * jboolean constants + */ + +#define JNI_FALSE 0 +#define JNI_TRUE 1 + +/* + * possible return values for JNI functions. + */ + +#define JNI_OK 0 /* success */ +#define JNI_ERR (-1) /* unknown error */ +#define JNI_EDETACHED (-2) /* thread detached from the VM */ +#define JNI_EVERSION (-3) /* JNI version error */ +#define JNI_ENOMEM (-4) /* not enough memory */ +#define JNI_EEXIST (-5) /* VM already created */ +#define JNI_EINVAL (-6) /* invalid arguments */ + +/* + * used in ReleaseScalarArrayElements + */ + +#define JNI_COMMIT 1 +#define JNI_ABORT 2 + +/* + * used in RegisterNatives to describe native method name, signature, + * and function pointer. + */ + +typedef struct { + char *name; + char *signature; + void *fnPtr; +} JNINativeMethod; + +/* + * JNI Native Method Interface. + */ + +struct JNINativeInterface_; + +struct JNIEnv_; + +#ifdef __cplusplus +typedef JNIEnv_ JNIEnv; +#else +typedef const struct JNINativeInterface_ *JNIEnv; +#endif + +/* + * JNI Invocation Interface. + */ + +struct JNIInvokeInterface_; + +struct JavaVM_; + +#ifdef __cplusplus +typedef JavaVM_ JavaVM; +#else +typedef const struct JNIInvokeInterface_ *JavaVM; +#endif + +struct JNINativeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + void *reserved3; + jint (JNICALL *GetVersion)(JNIEnv *env); + + jclass (JNICALL *DefineClass) + (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, + jsize len); + jclass (JNICALL *FindClass) + (JNIEnv *env, const char *name); + + jmethodID (JNICALL *FromReflectedMethod) + (JNIEnv *env, jobject method); + jfieldID (JNICALL *FromReflectedField) + (JNIEnv *env, jobject field); + + jobject (JNICALL *ToReflectedMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); + + jclass (JNICALL *GetSuperclass) + (JNIEnv *env, jclass sub); + jboolean (JNICALL *IsAssignableFrom) + (JNIEnv *env, jclass sub, jclass sup); + + jobject (JNICALL *ToReflectedField) + (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); + + jint (JNICALL *Throw) + (JNIEnv *env, jthrowable obj); + jint (JNICALL *ThrowNew) + (JNIEnv *env, jclass clazz, const char *msg); + jthrowable (JNICALL *ExceptionOccurred) + (JNIEnv *env); + void (JNICALL *ExceptionDescribe) + (JNIEnv *env); + void (JNICALL *ExceptionClear) + (JNIEnv *env); + void (JNICALL *FatalError) + (JNIEnv *env, const char *msg); + + jint (JNICALL *PushLocalFrame) + (JNIEnv *env, jint capacity); + jobject (JNICALL *PopLocalFrame) + (JNIEnv *env, jobject result); + + jobject (JNICALL *NewGlobalRef) + (JNIEnv *env, jobject lobj); + void (JNICALL *DeleteGlobalRef) + (JNIEnv *env, jobject gref); + void (JNICALL *DeleteLocalRef) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsSameObject) + (JNIEnv *env, jobject obj1, jobject obj2); + jobject (JNICALL *NewLocalRef) + (JNIEnv *env, jobject ref); + jint (JNICALL *EnsureLocalCapacity) + (JNIEnv *env, jint capacity); + + jobject (JNICALL *AllocObject) + (JNIEnv *env, jclass clazz); + jobject (JNICALL *NewObject) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *NewObjectV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *NewObjectA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jclass (JNICALL *GetObjectClass) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsInstanceOf) + (JNIEnv *env, jobject obj, jclass clazz); + + jmethodID (JNICALL *GetMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallObjectMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jobject (JNICALL *CallObjectMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jobject (JNICALL *CallObjectMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jboolean (JNICALL *CallBooleanMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jboolean (JNICALL *CallBooleanMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jboolean (JNICALL *CallBooleanMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jbyte (JNICALL *CallByteMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jbyte (JNICALL *CallByteMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jbyte (JNICALL *CallByteMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallCharMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jchar (JNICALL *CallCharMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jchar (JNICALL *CallCharMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallShortMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jshort (JNICALL *CallShortMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jshort (JNICALL *CallShortMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallIntMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jint (JNICALL *CallIntMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jint (JNICALL *CallIntMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallLongMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jlong (JNICALL *CallLongMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jlong (JNICALL *CallLongMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallFloatMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jfloat (JNICALL *CallFloatMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jfloat (JNICALL *CallFloatMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallDoubleMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jdouble (JNICALL *CallDoubleMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jdouble (JNICALL *CallDoubleMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallVoidMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + void (JNICALL *CallVoidMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + void (JNICALL *CallVoidMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jobject (JNICALL *CallNonvirtualObjectMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallNonvirtualObjectMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jobject (JNICALL *CallNonvirtualObjectMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jboolean (JNICALL *CallNonvirtualBooleanMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallNonvirtualBooleanMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jboolean (JNICALL *CallNonvirtualBooleanMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jbyte (JNICALL *CallNonvirtualByteMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallNonvirtualByteMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jbyte (JNICALL *CallNonvirtualByteMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jchar (JNICALL *CallNonvirtualCharMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallNonvirtualCharMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jchar (JNICALL *CallNonvirtualCharMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jshort (JNICALL *CallNonvirtualShortMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallNonvirtualShortMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jshort (JNICALL *CallNonvirtualShortMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jint (JNICALL *CallNonvirtualIntMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallNonvirtualIntMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jint (JNICALL *CallNonvirtualIntMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jlong (JNICALL *CallNonvirtualLongMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallNonvirtualLongMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jlong (JNICALL *CallNonvirtualLongMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jfloat (JNICALL *CallNonvirtualFloatMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallNonvirtualFloatMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jfloat (JNICALL *CallNonvirtualFloatMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jdouble (JNICALL *CallNonvirtualDoubleMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallNonvirtualDoubleMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jdouble (JNICALL *CallNonvirtualDoubleMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + void (JNICALL *CallNonvirtualVoidMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + void (JNICALL *CallNonvirtualVoidMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + void (JNICALL *CallNonvirtualVoidMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jfieldID (JNICALL *GetFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *GetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jboolean (JNICALL *GetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jbyte (JNICALL *GetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jchar (JNICALL *GetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jshort (JNICALL *GetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jint (JNICALL *GetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jlong (JNICALL *GetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jfloat (JNICALL *GetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jdouble (JNICALL *GetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + + void (JNICALL *SetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); + void (JNICALL *SetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); + void (JNICALL *SetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); + void (JNICALL *SetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); + void (JNICALL *SetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); + void (JNICALL *SetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); + void (JNICALL *SetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); + void (JNICALL *SetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); + void (JNICALL *SetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); + + jmethodID (JNICALL *GetStaticMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallStaticObjectMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallStaticObjectMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *CallStaticObjectMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jboolean (JNICALL *CallStaticBooleanMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallStaticBooleanMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jboolean (JNICALL *CallStaticBooleanMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jbyte (JNICALL *CallStaticByteMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallStaticByteMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jbyte (JNICALL *CallStaticByteMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallStaticCharMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallStaticCharMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jchar (JNICALL *CallStaticCharMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallStaticShortMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallStaticShortMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jshort (JNICALL *CallStaticShortMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallStaticIntMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallStaticIntMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jint (JNICALL *CallStaticIntMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallStaticLongMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallStaticLongMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jlong (JNICALL *CallStaticLongMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallStaticFloatMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallStaticFloatMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jfloat (JNICALL *CallStaticFloatMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallStaticDoubleMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallStaticDoubleMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jdouble (JNICALL *CallStaticDoubleMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallStaticVoidMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, ...); + void (JNICALL *CallStaticVoidMethodV) + (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); + void (JNICALL *CallStaticVoidMethodA) + (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args); + + jfieldID (JNICALL *GetStaticFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + jobject (JNICALL *GetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jboolean (JNICALL *GetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jbyte (JNICALL *GetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jchar (JNICALL *GetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jshort (JNICALL *GetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jint (JNICALL *GetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jlong (JNICALL *GetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jfloat (JNICALL *GetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jdouble (JNICALL *GetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + + void (JNICALL *SetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); + void (JNICALL *SetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); + void (JNICALL *SetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); + void (JNICALL *SetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); + void (JNICALL *SetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); + void (JNICALL *SetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); + void (JNICALL *SetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); + void (JNICALL *SetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); + void (JNICALL *SetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); + + jstring (JNICALL *NewString) + (JNIEnv *env, const jchar *unicode, jsize len); + jsize (JNICALL *GetStringLength) + (JNIEnv *env, jstring str); + const jchar *(JNICALL *GetStringChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringChars) + (JNIEnv *env, jstring str, const jchar *chars); + + jstring (JNICALL *NewStringUTF) + (JNIEnv *env, const char *utf); + jsize (JNICALL *GetStringUTFLength) + (JNIEnv *env, jstring str); + const char* (JNICALL *GetStringUTFChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringUTFChars) + (JNIEnv *env, jstring str, const char* chars); + + + jsize (JNICALL *GetArrayLength) + (JNIEnv *env, jarray array); + + jobjectArray (JNICALL *NewObjectArray) + (JNIEnv *env, jsize len, jclass clazz, jobject init); + jobject (JNICALL *GetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index); + void (JNICALL *SetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index, jobject val); + + jbooleanArray (JNICALL *NewBooleanArray) + (JNIEnv *env, jsize len); + jbyteArray (JNICALL *NewByteArray) + (JNIEnv *env, jsize len); + jcharArray (JNICALL *NewCharArray) + (JNIEnv *env, jsize len); + jshortArray (JNICALL *NewShortArray) + (JNIEnv *env, jsize len); + jintArray (JNICALL *NewIntArray) + (JNIEnv *env, jsize len); + jlongArray (JNICALL *NewLongArray) + (JNIEnv *env, jsize len); + jfloatArray (JNICALL *NewFloatArray) + (JNIEnv *env, jsize len); + jdoubleArray (JNICALL *NewDoubleArray) + (JNIEnv *env, jsize len); + + jboolean * (JNICALL *GetBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *isCopy); + jbyte * (JNICALL *GetByteArrayElements) + (JNIEnv *env, jbyteArray array, jboolean *isCopy); + jchar * (JNICALL *GetCharArrayElements) + (JNIEnv *env, jcharArray array, jboolean *isCopy); + jshort * (JNICALL *GetShortArrayElements) + (JNIEnv *env, jshortArray array, jboolean *isCopy); + jint * (JNICALL *GetIntArrayElements) + (JNIEnv *env, jintArray array, jboolean *isCopy); + jlong * (JNICALL *GetLongArrayElements) + (JNIEnv *env, jlongArray array, jboolean *isCopy); + jfloat * (JNICALL *GetFloatArrayElements) + (JNIEnv *env, jfloatArray array, jboolean *isCopy); + jdouble * (JNICALL *GetDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jboolean *isCopy); + + void (JNICALL *ReleaseBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); + void (JNICALL *ReleaseByteArrayElements) + (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); + void (JNICALL *ReleaseCharArrayElements) + (JNIEnv *env, jcharArray array, jchar *elems, jint mode); + void (JNICALL *ReleaseShortArrayElements) + (JNIEnv *env, jshortArray array, jshort *elems, jint mode); + void (JNICALL *ReleaseIntArrayElements) + (JNIEnv *env, jintArray array, jint *elems, jint mode); + void (JNICALL *ReleaseLongArrayElements) + (JNIEnv *env, jlongArray array, jlong *elems, jint mode); + void (JNICALL *ReleaseFloatArrayElements) + (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); + void (JNICALL *ReleaseDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); + + void (JNICALL *GetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + void (JNICALL *GetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + void (JNICALL *GetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + void (JNICALL *GetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + void (JNICALL *GetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + void (JNICALL *GetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + void (JNICALL *GetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + void (JNICALL *GetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + void (JNICALL *SetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf); + void (JNICALL *SetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf); + void (JNICALL *SetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf); + void (JNICALL *SetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf); + void (JNICALL *SetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf); + void (JNICALL *SetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf); + void (JNICALL *SetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf); + void (JNICALL *SetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf); + + jint (JNICALL *RegisterNatives) + (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, + jint nMethods); + jint (JNICALL *UnregisterNatives) + (JNIEnv *env, jclass clazz); + + jint (JNICALL *MonitorEnter) + (JNIEnv *env, jobject obj); + jint (JNICALL *MonitorExit) + (JNIEnv *env, jobject obj); + + jint (JNICALL *GetJavaVM) + (JNIEnv *env, JavaVM **vm); + + void (JNICALL *GetStringRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf); + void (JNICALL *GetStringUTFRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, char *buf); + + void * (JNICALL *GetPrimitiveArrayCritical) + (JNIEnv *env, jarray array, jboolean *isCopy); + void (JNICALL *ReleasePrimitiveArrayCritical) + (JNIEnv *env, jarray array, void *carray, jint mode); + + const jchar * (JNICALL *GetStringCritical) + (JNIEnv *env, jstring string, jboolean *isCopy); + void (JNICALL *ReleaseStringCritical) + (JNIEnv *env, jstring string, const jchar *cstring); + + jweak (JNICALL *NewWeakGlobalRef) + (JNIEnv *env, jobject obj); + void (JNICALL *DeleteWeakGlobalRef) + (JNIEnv *env, jweak ref); + + jboolean (JNICALL *ExceptionCheck) + (JNIEnv *env); + + jobject (JNICALL *NewDirectByteBuffer) + (JNIEnv* env, void* address, jlong capacity); + void* (JNICALL *GetDirectBufferAddress) + (JNIEnv* env, jobject buf); + jlong (JNICALL *GetDirectBufferCapacity) + (JNIEnv* env, jobject buf); + + /* New JNI 1.6 Features */ + + jobjectRefType (JNICALL *GetObjectRefType) + (JNIEnv* env, jobject obj); +}; + +/* + * We use inlined functions for C++ so that programmers can write: + * + * env->FindClass("java/lang/String") + * + * in C++ rather than: + * + * (*env)->FindClass(env, "java/lang/String") + * + * in C. + */ + +struct JNIEnv_ { + const struct JNINativeInterface_ *functions; +#ifdef __cplusplus + + jint GetVersion() { + return functions->GetVersion(this); + } + jclass DefineClass(const char *name, jobject loader, const jbyte *buf, + jsize len) { + return functions->DefineClass(this, name, loader, buf, len); + } + jclass FindClass(const char *name) { + return functions->FindClass(this, name); + } + jmethodID FromReflectedMethod(jobject method) { + return functions->FromReflectedMethod(this,method); + } + jfieldID FromReflectedField(jobject field) { + return functions->FromReflectedField(this,field); + } + + jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { + return functions->ToReflectedMethod(this, cls, methodID, isStatic); + } + + jclass GetSuperclass(jclass sub) { + return functions->GetSuperclass(this, sub); + } + jboolean IsAssignableFrom(jclass sub, jclass sup) { + return functions->IsAssignableFrom(this, sub, sup); + } + + jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { + return functions->ToReflectedField(this,cls,fieldID,isStatic); + } + + jint Throw(jthrowable obj) { + return functions->Throw(this, obj); + } + jint ThrowNew(jclass clazz, const char *msg) { + return functions->ThrowNew(this, clazz, msg); + } + jthrowable ExceptionOccurred() { + return functions->ExceptionOccurred(this); + } + void ExceptionDescribe() { + functions->ExceptionDescribe(this); + } + void ExceptionClear() { + functions->ExceptionClear(this); + } + void FatalError(const char *msg) { + functions->FatalError(this, msg); + } + + jint PushLocalFrame(jint capacity) { + return functions->PushLocalFrame(this,capacity); + } + jobject PopLocalFrame(jobject result) { + return functions->PopLocalFrame(this,result); + } + + jobject NewGlobalRef(jobject lobj) { + return functions->NewGlobalRef(this,lobj); + } + void DeleteGlobalRef(jobject gref) { + functions->DeleteGlobalRef(this,gref); + } + void DeleteLocalRef(jobject obj) { + functions->DeleteLocalRef(this, obj); + } + + jboolean IsSameObject(jobject obj1, jobject obj2) { + return functions->IsSameObject(this,obj1,obj2); + } + + jobject NewLocalRef(jobject ref) { + return functions->NewLocalRef(this,ref); + } + jint EnsureLocalCapacity(jint capacity) { + return functions->EnsureLocalCapacity(this,capacity); + } + + jobject AllocObject(jclass clazz) { + return functions->AllocObject(this,clazz); + } + jobject NewObject(jclass clazz, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args, methodID); + result = functions->NewObjectV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject NewObjectV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->NewObjectV(this,clazz,methodID,args); + } + jobject NewObjectA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->NewObjectA(this,clazz,methodID,args); + } + + jclass GetObjectClass(jobject obj) { + return functions->GetObjectClass(this,obj); + } + jboolean IsInstanceOf(jobject obj, jclass clazz) { + return functions->IsInstanceOf(this,obj,clazz); + } + + jmethodID GetMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetMethodID(this,clazz,name,sig); + } + + jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallObjectMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jobject CallObjectMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallObjectMethodV(this,obj,methodID,args); + } + jobject CallObjectMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallObjectMethodA(this,obj,methodID,args); + } + + jboolean CallBooleanMethod(jobject obj, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallBooleanMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallBooleanMethodV(this,obj,methodID,args); + } + jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallBooleanMethodA(this,obj,methodID, args); + } + + jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallByteMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jbyte CallByteMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallByteMethodV(this,obj,methodID,args); + } + jbyte CallByteMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallByteMethodA(this,obj,methodID,args); + } + + jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallCharMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jchar CallCharMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallCharMethodV(this,obj,methodID,args); + } + jchar CallCharMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallCharMethodA(this,obj,methodID,args); + } + + jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallShortMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jshort CallShortMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallShortMethodV(this,obj,methodID,args); + } + jshort CallShortMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallShortMethodA(this,obj,methodID,args); + } + + jint CallIntMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallIntMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jint CallIntMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallIntMethodV(this,obj,methodID,args); + } + jint CallIntMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallIntMethodA(this,obj,methodID,args); + } + + jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallLongMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jlong CallLongMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallLongMethodV(this,obj,methodID,args); + } + jlong CallLongMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallLongMethodA(this,obj,methodID,args); + } + + jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallFloatMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jfloat CallFloatMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallFloatMethodV(this,obj,methodID,args); + } + jfloat CallFloatMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallFloatMethodA(this,obj,methodID,args); + } + + jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallDoubleMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallDoubleMethodV(this,obj,methodID,args); + } + jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallDoubleMethodA(this,obj,methodID,args); + } + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallVoidMethodV(this,obj,methodID,args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, + va_list args) { + functions->CallVoidMethodV(this,obj,methodID,args); + } + void CallVoidMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + functions->CallVoidMethodA(this,obj,methodID,args); + } + + jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + } + jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualObjectMethodA(this,obj,clazz, + methodID,args); + } + + jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + } + jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, + methodID, args); + } + + jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + } + jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualByteMethodA(this,obj,clazz, + methodID,args); + } + + jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + } + jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualCharMethodA(this,obj,clazz, + methodID,args); + } + + jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + } + jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualShortMethodA(this,obj,clazz, + methodID,args); + } + + jint CallNonvirtualIntMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + } + jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualIntMethodA(this,obj,clazz, + methodID,args); + } + + jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + } + jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualLongMethodA(this,obj,clazz, + methodID,args); + } + + jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + } + jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualFloatMethodA(this,obj,clazz, + methodID,args); + } + + jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + } + jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, + methodID,args); + } + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); + } + + jfieldID GetFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetFieldID(this,clazz,name,sig); + } + + jobject GetObjectField(jobject obj, jfieldID fieldID) { + return functions->GetObjectField(this,obj,fieldID); + } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) { + return functions->GetBooleanField(this,obj,fieldID); + } + jbyte GetByteField(jobject obj, jfieldID fieldID) { + return functions->GetByteField(this,obj,fieldID); + } + jchar GetCharField(jobject obj, jfieldID fieldID) { + return functions->GetCharField(this,obj,fieldID); + } + jshort GetShortField(jobject obj, jfieldID fieldID) { + return functions->GetShortField(this,obj,fieldID); + } + jint GetIntField(jobject obj, jfieldID fieldID) { + return functions->GetIntField(this,obj,fieldID); + } + jlong GetLongField(jobject obj, jfieldID fieldID) { + return functions->GetLongField(this,obj,fieldID); + } + jfloat GetFloatField(jobject obj, jfieldID fieldID) { + return functions->GetFloatField(this,obj,fieldID); + } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) { + return functions->GetDoubleField(this,obj,fieldID); + } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { + functions->SetObjectField(this,obj,fieldID,val); + } + void SetBooleanField(jobject obj, jfieldID fieldID, + jboolean val) { + functions->SetBooleanField(this,obj,fieldID,val); + } + void SetByteField(jobject obj, jfieldID fieldID, + jbyte val) { + functions->SetByteField(this,obj,fieldID,val); + } + void SetCharField(jobject obj, jfieldID fieldID, + jchar val) { + functions->SetCharField(this,obj,fieldID,val); + } + void SetShortField(jobject obj, jfieldID fieldID, + jshort val) { + functions->SetShortField(this,obj,fieldID,val); + } + void SetIntField(jobject obj, jfieldID fieldID, + jint val) { + functions->SetIntField(this,obj,fieldID,val); + } + void SetLongField(jobject obj, jfieldID fieldID, + jlong val) { + functions->SetLongField(this,obj,fieldID,val); + } + void SetFloatField(jobject obj, jfieldID fieldID, + jfloat val) { + functions->SetFloatField(this,obj,fieldID,val); + } + void SetDoubleField(jobject obj, jfieldID fieldID, + jdouble val) { + functions->SetDoubleField(this,obj,fieldID,val); + } + + jmethodID GetStaticMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticMethodID(this,clazz,name,sig); + } + + jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, + ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->CallStaticObjectMethodV(this,clazz,methodID,args); + } + jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->CallStaticObjectMethodA(this,clazz,methodID,args); + } + + jboolean CallStaticBooleanMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jboolean CallStaticBooleanMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + } + jboolean CallStaticBooleanMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); + } + + jbyte CallStaticByteMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallStaticByteMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jbyte CallStaticByteMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticByteMethodV(this,clazz,methodID,args); + } + jbyte CallStaticByteMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticByteMethodA(this,clazz,methodID,args); + } + + jchar CallStaticCharMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallStaticCharMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jchar CallStaticCharMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticCharMethodV(this,clazz,methodID,args); + } + jchar CallStaticCharMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticCharMethodA(this,clazz,methodID,args); + } + + jshort CallStaticShortMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallStaticShortMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jshort CallStaticShortMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticShortMethodV(this,clazz,methodID,args); + } + jshort CallStaticShortMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticShortMethodA(this,clazz,methodID,args); + } + + jint CallStaticIntMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallStaticIntMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jint CallStaticIntMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticIntMethodV(this,clazz,methodID,args); + } + jint CallStaticIntMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticIntMethodA(this,clazz,methodID,args); + } + + jlong CallStaticLongMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallStaticLongMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jlong CallStaticLongMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticLongMethodV(this,clazz,methodID,args); + } + jlong CallStaticLongMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticLongMethodA(this,clazz,methodID,args); + } + + jfloat CallStaticFloatMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jfloat CallStaticFloatMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticFloatMethodV(this,clazz,methodID,args); + } + jfloat CallStaticFloatMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticFloatMethodA(this,clazz,methodID,args); + } + + jdouble CallStaticDoubleMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jdouble CallStaticDoubleMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + } + jdouble CallStaticDoubleMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); + } + + void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallStaticVoidMethodV(this,cls,methodID,args); + va_end(args); + } + void CallStaticVoidMethodV(jclass cls, jmethodID methodID, + va_list args) { + functions->CallStaticVoidMethodV(this,cls,methodID,args); + } + void CallStaticVoidMethodA(jclass cls, jmethodID methodID, + const jvalue * args) { + functions->CallStaticVoidMethodA(this,cls,methodID,args); + } + + jfieldID GetStaticFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticFieldID(this,clazz,name,sig); + } + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticObjectField(this,clazz,fieldID); + } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticBooleanField(this,clazz,fieldID); + } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticByteField(this,clazz,fieldID); + } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticCharField(this,clazz,fieldID); + } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticShortField(this,clazz,fieldID); + } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticIntField(this,clazz,fieldID); + } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticLongField(this,clazz,fieldID); + } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticFloatField(this,clazz,fieldID); + } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticDoubleField(this,clazz,fieldID); + } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, + jobject value) { + functions->SetStaticObjectField(this,clazz,fieldID,value); + } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, + jboolean value) { + functions->SetStaticBooleanField(this,clazz,fieldID,value); + } + void SetStaticByteField(jclass clazz, jfieldID fieldID, + jbyte value) { + functions->SetStaticByteField(this,clazz,fieldID,value); + } + void SetStaticCharField(jclass clazz, jfieldID fieldID, + jchar value) { + functions->SetStaticCharField(this,clazz,fieldID,value); + } + void SetStaticShortField(jclass clazz, jfieldID fieldID, + jshort value) { + functions->SetStaticShortField(this,clazz,fieldID,value); + } + void SetStaticIntField(jclass clazz, jfieldID fieldID, + jint value) { + functions->SetStaticIntField(this,clazz,fieldID,value); + } + void SetStaticLongField(jclass clazz, jfieldID fieldID, + jlong value) { + functions->SetStaticLongField(this,clazz,fieldID,value); + } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, + jfloat value) { + functions->SetStaticFloatField(this,clazz,fieldID,value); + } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, + jdouble value) { + functions->SetStaticDoubleField(this,clazz,fieldID,value); + } + + jstring NewString(const jchar *unicode, jsize len) { + return functions->NewString(this,unicode,len); + } + jsize GetStringLength(jstring str) { + return functions->GetStringLength(this,str); + } + const jchar *GetStringChars(jstring str, jboolean *isCopy) { + return functions->GetStringChars(this,str,isCopy); + } + void ReleaseStringChars(jstring str, const jchar *chars) { + functions->ReleaseStringChars(this,str,chars); + } + + jstring NewStringUTF(const char *utf) { + return functions->NewStringUTF(this,utf); + } + jsize GetStringUTFLength(jstring str) { + return functions->GetStringUTFLength(this,str); + } + const char* GetStringUTFChars(jstring str, jboolean *isCopy) { + return functions->GetStringUTFChars(this,str,isCopy); + } + void ReleaseStringUTFChars(jstring str, const char* chars) { + functions->ReleaseStringUTFChars(this,str,chars); + } + + jsize GetArrayLength(jarray array) { + return functions->GetArrayLength(this,array); + } + + jobjectArray NewObjectArray(jsize len, jclass clazz, + jobject init) { + return functions->NewObjectArray(this,len,clazz,init); + } + jobject GetObjectArrayElement(jobjectArray array, jsize index) { + return functions->GetObjectArrayElement(this,array,index); + } + void SetObjectArrayElement(jobjectArray array, jsize index, + jobject val) { + functions->SetObjectArrayElement(this,array,index,val); + } + + jbooleanArray NewBooleanArray(jsize len) { + return functions->NewBooleanArray(this,len); + } + jbyteArray NewByteArray(jsize len) { + return functions->NewByteArray(this,len); + } + jcharArray NewCharArray(jsize len) { + return functions->NewCharArray(this,len); + } + jshortArray NewShortArray(jsize len) { + return functions->NewShortArray(this,len); + } + jintArray NewIntArray(jsize len) { + return functions->NewIntArray(this,len); + } + jlongArray NewLongArray(jsize len) { + return functions->NewLongArray(this,len); + } + jfloatArray NewFloatArray(jsize len) { + return functions->NewFloatArray(this,len); + } + jdoubleArray NewDoubleArray(jsize len) { + return functions->NewDoubleArray(this,len); + } + + jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { + return functions->GetBooleanArrayElements(this,array,isCopy); + } + jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { + return functions->GetByteArrayElements(this,array,isCopy); + } + jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { + return functions->GetCharArrayElements(this,array,isCopy); + } + jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { + return functions->GetShortArrayElements(this,array,isCopy); + } + jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { + return functions->GetIntArrayElements(this,array,isCopy); + } + jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { + return functions->GetLongArrayElements(this,array,isCopy); + } + jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { + return functions->GetFloatArrayElements(this,array,isCopy); + } + jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { + return functions->GetDoubleArrayElements(this,array,isCopy); + } + + void ReleaseBooleanArrayElements(jbooleanArray array, + jboolean *elems, + jint mode) { + functions->ReleaseBooleanArrayElements(this,array,elems,mode); + } + void ReleaseByteArrayElements(jbyteArray array, + jbyte *elems, + jint mode) { + functions->ReleaseByteArrayElements(this,array,elems,mode); + } + void ReleaseCharArrayElements(jcharArray array, + jchar *elems, + jint mode) { + functions->ReleaseCharArrayElements(this,array,elems,mode); + } + void ReleaseShortArrayElements(jshortArray array, + jshort *elems, + jint mode) { + functions->ReleaseShortArrayElements(this,array,elems,mode); + } + void ReleaseIntArrayElements(jintArray array, + jint *elems, + jint mode) { + functions->ReleaseIntArrayElements(this,array,elems,mode); + } + void ReleaseLongArrayElements(jlongArray array, + jlong *elems, + jint mode) { + functions->ReleaseLongArrayElements(this,array,elems,mode); + } + void ReleaseFloatArrayElements(jfloatArray array, + jfloat *elems, + jint mode) { + functions->ReleaseFloatArrayElements(this,array,elems,mode); + } + void ReleaseDoubleArrayElements(jdoubleArray array, + jdouble *elems, + jint mode) { + functions->ReleaseDoubleArrayElements(this,array,elems,mode); + } + + void GetBooleanArrayRegion(jbooleanArray array, + jsize start, jsize len, jboolean *buf) { + functions->GetBooleanArrayRegion(this,array,start,len,buf); + } + void GetByteArrayRegion(jbyteArray array, + jsize start, jsize len, jbyte *buf) { + functions->GetByteArrayRegion(this,array,start,len,buf); + } + void GetCharArrayRegion(jcharArray array, + jsize start, jsize len, jchar *buf) { + functions->GetCharArrayRegion(this,array,start,len,buf); + } + void GetShortArrayRegion(jshortArray array, + jsize start, jsize len, jshort *buf) { + functions->GetShortArrayRegion(this,array,start,len,buf); + } + void GetIntArrayRegion(jintArray array, + jsize start, jsize len, jint *buf) { + functions->GetIntArrayRegion(this,array,start,len,buf); + } + void GetLongArrayRegion(jlongArray array, + jsize start, jsize len, jlong *buf) { + functions->GetLongArrayRegion(this,array,start,len,buf); + } + void GetFloatArrayRegion(jfloatArray array, + jsize start, jsize len, jfloat *buf) { + functions->GetFloatArrayRegion(this,array,start,len,buf); + } + void GetDoubleArrayRegion(jdoubleArray array, + jsize start, jsize len, jdouble *buf) { + functions->GetDoubleArrayRegion(this,array,start,len,buf); + } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + const jboolean *buf) { + functions->SetBooleanArrayRegion(this,array,start,len,buf); + } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + const jbyte *buf) { + functions->SetByteArrayRegion(this,array,start,len,buf); + } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + const jchar *buf) { + functions->SetCharArrayRegion(this,array,start,len,buf); + } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + const jshort *buf) { + functions->SetShortArrayRegion(this,array,start,len,buf); + } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + const jint *buf) { + functions->SetIntArrayRegion(this,array,start,len,buf); + } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + const jlong *buf) { + functions->SetLongArrayRegion(this,array,start,len,buf); + } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + const jfloat *buf) { + functions->SetFloatArrayRegion(this,array,start,len,buf); + } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + const jdouble *buf) { + functions->SetDoubleArrayRegion(this,array,start,len,buf); + } + + jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, + jint nMethods) { + return functions->RegisterNatives(this,clazz,methods,nMethods); + } + jint UnregisterNatives(jclass clazz) { + return functions->UnregisterNatives(this,clazz); + } + + jint MonitorEnter(jobject obj) { + return functions->MonitorEnter(this,obj); + } + jint MonitorExit(jobject obj) { + return functions->MonitorExit(this,obj); + } + + jint GetJavaVM(JavaVM **vm) { + return functions->GetJavaVM(this,vm); + } + + void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) { + functions->GetStringRegion(this,str,start,len,buf); + } + void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) { + functions->GetStringUTFRegion(this,str,start,len,buf); + } + + void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) { + return functions->GetPrimitiveArrayCritical(this,array,isCopy); + } + void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) { + functions->ReleasePrimitiveArrayCritical(this,array,carray,mode); + } + + const jchar * GetStringCritical(jstring string, jboolean *isCopy) { + return functions->GetStringCritical(this,string,isCopy); + } + void ReleaseStringCritical(jstring string, const jchar *cstring) { + functions->ReleaseStringCritical(this,string,cstring); + } + + jweak NewWeakGlobalRef(jobject obj) { + return functions->NewWeakGlobalRef(this,obj); + } + void DeleteWeakGlobalRef(jweak ref) { + functions->DeleteWeakGlobalRef(this,ref); + } + + jboolean ExceptionCheck() { + return functions->ExceptionCheck(this); + } + + jobject NewDirectByteBuffer(void* address, jlong capacity) { + return functions->NewDirectByteBuffer(this, address, capacity); + } + void* GetDirectBufferAddress(jobject buf) { + return functions->GetDirectBufferAddress(this, buf); + } + jlong GetDirectBufferCapacity(jobject buf) { + return functions->GetDirectBufferCapacity(this, buf); + } + jobjectRefType GetObjectRefType(jobject obj) { + return functions->GetObjectRefType(this, obj); + } + +#endif /* __cplusplus */ +}; + +typedef struct JavaVMOption { + char *optionString; + void *extraInfo; +} JavaVMOption; + +typedef struct JavaVMInitArgs { + jint version; + + jint nOptions; + JavaVMOption *options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +typedef struct JavaVMAttachArgs { + jint version; + + char *name; + jobject group; +} JavaVMAttachArgs; + +/* These will be VM-specific. */ + +#define JDK1_2 +#define JDK1_4 + +/* End VM-specific. */ + +struct JNIInvokeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + jint (JNICALL *DestroyJavaVM)(JavaVM *vm); + + jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args); + + jint (JNICALL *DetachCurrentThread)(JavaVM *vm); + + jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version); + + jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args); +}; + +struct JavaVM_ { + const struct JNIInvokeInterface_ *functions; +#ifdef __cplusplus + + jint DestroyJavaVM() { + return functions->DestroyJavaVM(this); + } + jint AttachCurrentThread(void **penv, void *args) { + return functions->AttachCurrentThread(this, penv, args); + } + jint DetachCurrentThread() { + return functions->DetachCurrentThread(this); + } + + jint GetEnv(void **penv, jint version) { + return functions->GetEnv(this, penv, version); + } + jint AttachCurrentThreadAsDaemon(void **penv, void *args) { + return functions->AttachCurrentThreadAsDaemon(this, penv, args); + } +#endif +}; + +#ifdef _JNI_IMPLEMENTATION_ +#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT +#else +#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT +#endif +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetDefaultJavaVMInitArgs(void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *); + +/* Defined by native libraries. */ +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *reserved); + +JNIEXPORT void JNICALL +JNI_OnUnload(JavaVM *vm, void *reserved); + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 +#define JNI_VERSION_1_4 0x00010004 +#define JNI_VERSION_1_6 0x00010006 +#define JNI_VERSION_1_8 0x00010008 + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* !_JAVASOFT_JNI_H_ */ diff --git a/demos/java/jni/gs_jni/include/jvmti.h b/demos/java/jni/gs_jni/include/jvmti.h new file mode 100644 index 00000000..e8de8585 --- /dev/null +++ b/demos/java/jni/gs_jni/include/jvmti.h @@ -0,0 +1,2533 @@ +/* + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + + /* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */ + + + /* Include file for the Java(tm) Virtual Machine Tool Interface */ + +#ifndef _JAVA_JVMTI_H_ +#define _JAVA_JVMTI_H_ + +#include "jni.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + JVMTI_VERSION_1 = 0x30010000, + JVMTI_VERSION_1_0 = 0x30010000, + JVMTI_VERSION_1_1 = 0x30010100, + JVMTI_VERSION_1_2 = 0x30010200, + + JVMTI_VERSION = 0x30000000 + (1 * 0x10000) + (2 * 0x100) + 1 /* version: 1.2.1 */ +}; + +JNIEXPORT jint JNICALL +Agent_OnLoad(JavaVM *vm, char *options, void *reserved); + +JNIEXPORT jint JNICALL +Agent_OnAttach(JavaVM* vm, char* options, void* reserved); + +JNIEXPORT void JNICALL +Agent_OnUnload(JavaVM *vm); + + /* Forward declaration of the environment */ + +struct _jvmtiEnv; + +struct jvmtiInterface_1_; + +#ifdef __cplusplus +typedef _jvmtiEnv jvmtiEnv; +#else +typedef const struct jvmtiInterface_1_ *jvmtiEnv; +#endif /* __cplusplus */ + +/* Derived Base Types */ + +typedef jobject jthread; +typedef jobject jthreadGroup; +typedef jlong jlocation; +struct _jrawMonitorID; +typedef struct _jrawMonitorID *jrawMonitorID; +typedef struct JNINativeInterface_ jniNativeInterface; + + /* Constants */ + + + /* Thread State Flags */ + +enum { + JVMTI_THREAD_STATE_ALIVE = 0x0001, + JVMTI_THREAD_STATE_TERMINATED = 0x0002, + JVMTI_THREAD_STATE_RUNNABLE = 0x0004, + JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400, + JVMTI_THREAD_STATE_WAITING = 0x0080, + JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010, + JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020, + JVMTI_THREAD_STATE_SLEEPING = 0x0040, + JVMTI_THREAD_STATE_IN_OBJECT_WAIT = 0x0100, + JVMTI_THREAD_STATE_PARKED = 0x0200, + JVMTI_THREAD_STATE_SUSPENDED = 0x100000, + JVMTI_THREAD_STATE_INTERRUPTED = 0x200000, + JVMTI_THREAD_STATE_IN_NATIVE = 0x400000, + JVMTI_THREAD_STATE_VENDOR_1 = 0x10000000, + JVMTI_THREAD_STATE_VENDOR_2 = 0x20000000, + JVMTI_THREAD_STATE_VENDOR_3 = 0x40000000 +}; + + /* java.lang.Thread.State Conversion Masks */ + +enum { + JVMTI_JAVA_LANG_THREAD_STATE_MASK = JVMTI_THREAD_STATE_TERMINATED | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT, + JVMTI_JAVA_LANG_THREAD_STATE_NEW = 0, + JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED = JVMTI_THREAD_STATE_TERMINATED, + JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE, + JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER, + JVMTI_JAVA_LANG_THREAD_STATE_WAITING = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY, + JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +}; + + /* Thread Priority Constants */ + +enum { + JVMTI_THREAD_MIN_PRIORITY = 1, + JVMTI_THREAD_NORM_PRIORITY = 5, + JVMTI_THREAD_MAX_PRIORITY = 10 +}; + + /* Heap Filter Flags */ + +enum { + JVMTI_HEAP_FILTER_TAGGED = 0x4, + JVMTI_HEAP_FILTER_UNTAGGED = 0x8, + JVMTI_HEAP_FILTER_CLASS_TAGGED = 0x10, + JVMTI_HEAP_FILTER_CLASS_UNTAGGED = 0x20 +}; + + /* Heap Visit Control Flags */ + +enum { + JVMTI_VISIT_OBJECTS = 0x100, + JVMTI_VISIT_ABORT = 0x8000 +}; + + /* Heap Reference Enumeration */ + +typedef enum { + JVMTI_HEAP_REFERENCE_CLASS = 1, + JVMTI_HEAP_REFERENCE_FIELD = 2, + JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT = 3, + JVMTI_HEAP_REFERENCE_CLASS_LOADER = 4, + JVMTI_HEAP_REFERENCE_SIGNERS = 5, + JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN = 6, + JVMTI_HEAP_REFERENCE_INTERFACE = 7, + JVMTI_HEAP_REFERENCE_STATIC_FIELD = 8, + JVMTI_HEAP_REFERENCE_CONSTANT_POOL = 9, + JVMTI_HEAP_REFERENCE_SUPERCLASS = 10, + JVMTI_HEAP_REFERENCE_JNI_GLOBAL = 21, + JVMTI_HEAP_REFERENCE_SYSTEM_CLASS = 22, + JVMTI_HEAP_REFERENCE_MONITOR = 23, + JVMTI_HEAP_REFERENCE_STACK_LOCAL = 24, + JVMTI_HEAP_REFERENCE_JNI_LOCAL = 25, + JVMTI_HEAP_REFERENCE_THREAD = 26, + JVMTI_HEAP_REFERENCE_OTHER = 27 +} jvmtiHeapReferenceKind; + + /* Primitive Type Enumeration */ + +typedef enum { + JVMTI_PRIMITIVE_TYPE_BOOLEAN = 90, + JVMTI_PRIMITIVE_TYPE_BYTE = 66, + JVMTI_PRIMITIVE_TYPE_CHAR = 67, + JVMTI_PRIMITIVE_TYPE_SHORT = 83, + JVMTI_PRIMITIVE_TYPE_INT = 73, + JVMTI_PRIMITIVE_TYPE_LONG = 74, + JVMTI_PRIMITIVE_TYPE_FLOAT = 70, + JVMTI_PRIMITIVE_TYPE_DOUBLE = 68 +} jvmtiPrimitiveType; + + /* Heap Object Filter Enumeration */ + +typedef enum { + JVMTI_HEAP_OBJECT_TAGGED = 1, + JVMTI_HEAP_OBJECT_UNTAGGED = 2, + JVMTI_HEAP_OBJECT_EITHER = 3 +} jvmtiHeapObjectFilter; + + /* Heap Root Kind Enumeration */ + +typedef enum { + JVMTI_HEAP_ROOT_JNI_GLOBAL = 1, + JVMTI_HEAP_ROOT_SYSTEM_CLASS = 2, + JVMTI_HEAP_ROOT_MONITOR = 3, + JVMTI_HEAP_ROOT_STACK_LOCAL = 4, + JVMTI_HEAP_ROOT_JNI_LOCAL = 5, + JVMTI_HEAP_ROOT_THREAD = 6, + JVMTI_HEAP_ROOT_OTHER = 7 +} jvmtiHeapRootKind; + + /* Object Reference Enumeration */ + +typedef enum { + JVMTI_REFERENCE_CLASS = 1, + JVMTI_REFERENCE_FIELD = 2, + JVMTI_REFERENCE_ARRAY_ELEMENT = 3, + JVMTI_REFERENCE_CLASS_LOADER = 4, + JVMTI_REFERENCE_SIGNERS = 5, + JVMTI_REFERENCE_PROTECTION_DOMAIN = 6, + JVMTI_REFERENCE_INTERFACE = 7, + JVMTI_REFERENCE_STATIC_FIELD = 8, + JVMTI_REFERENCE_CONSTANT_POOL = 9 +} jvmtiObjectReferenceKind; + + /* Iteration Control Enumeration */ + +typedef enum { + JVMTI_ITERATION_CONTINUE = 1, + JVMTI_ITERATION_IGNORE = 2, + JVMTI_ITERATION_ABORT = 0 +} jvmtiIterationControl; + + /* Class Status Flags */ + +enum { + JVMTI_CLASS_STATUS_VERIFIED = 1, + JVMTI_CLASS_STATUS_PREPARED = 2, + JVMTI_CLASS_STATUS_INITIALIZED = 4, + JVMTI_CLASS_STATUS_ERROR = 8, + JVMTI_CLASS_STATUS_ARRAY = 16, + JVMTI_CLASS_STATUS_PRIMITIVE = 32 +}; + + /* Event Enable/Disable */ + +typedef enum { + JVMTI_ENABLE = 1, + JVMTI_DISABLE = 0 +} jvmtiEventMode; + + /* Extension Function/Event Parameter Types */ + +typedef enum { + JVMTI_TYPE_JBYTE = 101, + JVMTI_TYPE_JCHAR = 102, + JVMTI_TYPE_JSHORT = 103, + JVMTI_TYPE_JINT = 104, + JVMTI_TYPE_JLONG = 105, + JVMTI_TYPE_JFLOAT = 106, + JVMTI_TYPE_JDOUBLE = 107, + JVMTI_TYPE_JBOOLEAN = 108, + JVMTI_TYPE_JOBJECT = 109, + JVMTI_TYPE_JTHREAD = 110, + JVMTI_TYPE_JCLASS = 111, + JVMTI_TYPE_JVALUE = 112, + JVMTI_TYPE_JFIELDID = 113, + JVMTI_TYPE_JMETHODID = 114, + JVMTI_TYPE_CCHAR = 115, + JVMTI_TYPE_CVOID = 116, + JVMTI_TYPE_JNIENV = 117 +} jvmtiParamTypes; + + /* Extension Function/Event Parameter Kinds */ + +typedef enum { + JVMTI_KIND_IN = 91, + JVMTI_KIND_IN_PTR = 92, + JVMTI_KIND_IN_BUF = 93, + JVMTI_KIND_ALLOC_BUF = 94, + JVMTI_KIND_ALLOC_ALLOC_BUF = 95, + JVMTI_KIND_OUT = 96, + JVMTI_KIND_OUT_BUF = 97 +} jvmtiParamKind; + + /* Timer Kinds */ + +typedef enum { + JVMTI_TIMER_USER_CPU = 30, + JVMTI_TIMER_TOTAL_CPU = 31, + JVMTI_TIMER_ELAPSED = 32 +} jvmtiTimerKind; + + /* Phases of execution */ + +typedef enum { + JVMTI_PHASE_ONLOAD = 1, + JVMTI_PHASE_PRIMORDIAL = 2, + JVMTI_PHASE_START = 6, + JVMTI_PHASE_LIVE = 4, + JVMTI_PHASE_DEAD = 8 +} jvmtiPhase; + + /* Version Interface Types */ + +enum { + JVMTI_VERSION_INTERFACE_JNI = 0x00000000, + JVMTI_VERSION_INTERFACE_JVMTI = 0x30000000 +}; + + /* Version Masks */ + +enum { + JVMTI_VERSION_MASK_INTERFACE_TYPE = 0x70000000, + JVMTI_VERSION_MASK_MAJOR = 0x0FFF0000, + JVMTI_VERSION_MASK_MINOR = 0x0000FF00, + JVMTI_VERSION_MASK_MICRO = 0x000000FF +}; + + /* Version Shifts */ + +enum { + JVMTI_VERSION_SHIFT_MAJOR = 16, + JVMTI_VERSION_SHIFT_MINOR = 8, + JVMTI_VERSION_SHIFT_MICRO = 0 +}; + + /* Verbose Flag Enumeration */ + +typedef enum { + JVMTI_VERBOSE_OTHER = 0, + JVMTI_VERBOSE_GC = 1, + JVMTI_VERBOSE_CLASS = 2, + JVMTI_VERBOSE_JNI = 4 +} jvmtiVerboseFlag; + + /* JLocation Format Enumeration */ + +typedef enum { + JVMTI_JLOCATION_JVMBCI = 1, + JVMTI_JLOCATION_MACHINEPC = 2, + JVMTI_JLOCATION_OTHER = 0 +} jvmtiJlocationFormat; + + /* Resource Exhaustion Flags */ + +enum { + JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR = 0x0001, + JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP = 0x0002, + JVMTI_RESOURCE_EXHAUSTED_THREADS = 0x0004 +}; + + /* Errors */ + +typedef enum { + JVMTI_ERROR_NONE = 0, + JVMTI_ERROR_INVALID_THREAD = 10, + JVMTI_ERROR_INVALID_THREAD_GROUP = 11, + JVMTI_ERROR_INVALID_PRIORITY = 12, + JVMTI_ERROR_THREAD_NOT_SUSPENDED = 13, + JVMTI_ERROR_THREAD_SUSPENDED = 14, + JVMTI_ERROR_THREAD_NOT_ALIVE = 15, + JVMTI_ERROR_INVALID_OBJECT = 20, + JVMTI_ERROR_INVALID_CLASS = 21, + JVMTI_ERROR_CLASS_NOT_PREPARED = 22, + JVMTI_ERROR_INVALID_METHODID = 23, + JVMTI_ERROR_INVALID_LOCATION = 24, + JVMTI_ERROR_INVALID_FIELDID = 25, + JVMTI_ERROR_NO_MORE_FRAMES = 31, + JVMTI_ERROR_OPAQUE_FRAME = 32, + JVMTI_ERROR_TYPE_MISMATCH = 34, + JVMTI_ERROR_INVALID_SLOT = 35, + JVMTI_ERROR_DUPLICATE = 40, + JVMTI_ERROR_NOT_FOUND = 41, + JVMTI_ERROR_INVALID_MONITOR = 50, + JVMTI_ERROR_NOT_MONITOR_OWNER = 51, + JVMTI_ERROR_INTERRUPT = 52, + JVMTI_ERROR_INVALID_CLASS_FORMAT = 60, + JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION = 61, + JVMTI_ERROR_FAILS_VERIFICATION = 62, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED = 63, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED = 64, + JVMTI_ERROR_INVALID_TYPESTATE = 65, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED = 66, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED = 67, + JVMTI_ERROR_UNSUPPORTED_VERSION = 68, + JVMTI_ERROR_NAMES_DONT_MATCH = 69, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED = 70, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED = 71, + JVMTI_ERROR_UNMODIFIABLE_CLASS = 79, + JVMTI_ERROR_NOT_AVAILABLE = 98, + JVMTI_ERROR_MUST_POSSESS_CAPABILITY = 99, + JVMTI_ERROR_NULL_POINTER = 100, + JVMTI_ERROR_ABSENT_INFORMATION = 101, + JVMTI_ERROR_INVALID_EVENT_TYPE = 102, + JVMTI_ERROR_ILLEGAL_ARGUMENT = 103, + JVMTI_ERROR_NATIVE_METHOD = 104, + JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED = 106, + JVMTI_ERROR_OUT_OF_MEMORY = 110, + JVMTI_ERROR_ACCESS_DENIED = 111, + JVMTI_ERROR_WRONG_PHASE = 112, + JVMTI_ERROR_INTERNAL = 113, + JVMTI_ERROR_UNATTACHED_THREAD = 115, + JVMTI_ERROR_INVALID_ENVIRONMENT = 116, + JVMTI_ERROR_MAX = 116 +} jvmtiError; + + /* Event IDs */ + +typedef enum { + JVMTI_MIN_EVENT_TYPE_VAL = 50, + JVMTI_EVENT_VM_INIT = 50, + JVMTI_EVENT_VM_DEATH = 51, + JVMTI_EVENT_THREAD_START = 52, + JVMTI_EVENT_THREAD_END = 53, + JVMTI_EVENT_CLASS_FILE_LOAD_HOOK = 54, + JVMTI_EVENT_CLASS_LOAD = 55, + JVMTI_EVENT_CLASS_PREPARE = 56, + JVMTI_EVENT_VM_START = 57, + JVMTI_EVENT_EXCEPTION = 58, + JVMTI_EVENT_EXCEPTION_CATCH = 59, + JVMTI_EVENT_SINGLE_STEP = 60, + JVMTI_EVENT_FRAME_POP = 61, + JVMTI_EVENT_BREAKPOINT = 62, + JVMTI_EVENT_FIELD_ACCESS = 63, + JVMTI_EVENT_FIELD_MODIFICATION = 64, + JVMTI_EVENT_METHOD_ENTRY = 65, + JVMTI_EVENT_METHOD_EXIT = 66, + JVMTI_EVENT_NATIVE_METHOD_BIND = 67, + JVMTI_EVENT_COMPILED_METHOD_LOAD = 68, + JVMTI_EVENT_COMPILED_METHOD_UNLOAD = 69, + JVMTI_EVENT_DYNAMIC_CODE_GENERATED = 70, + JVMTI_EVENT_DATA_DUMP_REQUEST = 71, + JVMTI_EVENT_MONITOR_WAIT = 73, + JVMTI_EVENT_MONITOR_WAITED = 74, + JVMTI_EVENT_MONITOR_CONTENDED_ENTER = 75, + JVMTI_EVENT_MONITOR_CONTENDED_ENTERED = 76, + JVMTI_EVENT_RESOURCE_EXHAUSTED = 80, + JVMTI_EVENT_GARBAGE_COLLECTION_START = 81, + JVMTI_EVENT_GARBAGE_COLLECTION_FINISH = 82, + JVMTI_EVENT_OBJECT_FREE = 83, + JVMTI_EVENT_VM_OBJECT_ALLOC = 84, + JVMTI_MAX_EVENT_TYPE_VAL = 84 +} jvmtiEvent; + + + /* Pre-Declarations */ +struct _jvmtiThreadInfo; +typedef struct _jvmtiThreadInfo jvmtiThreadInfo; +struct _jvmtiMonitorStackDepthInfo; +typedef struct _jvmtiMonitorStackDepthInfo jvmtiMonitorStackDepthInfo; +struct _jvmtiThreadGroupInfo; +typedef struct _jvmtiThreadGroupInfo jvmtiThreadGroupInfo; +struct _jvmtiFrameInfo; +typedef struct _jvmtiFrameInfo jvmtiFrameInfo; +struct _jvmtiStackInfo; +typedef struct _jvmtiStackInfo jvmtiStackInfo; +struct _jvmtiHeapReferenceInfoField; +typedef struct _jvmtiHeapReferenceInfoField jvmtiHeapReferenceInfoField; +struct _jvmtiHeapReferenceInfoArray; +typedef struct _jvmtiHeapReferenceInfoArray jvmtiHeapReferenceInfoArray; +struct _jvmtiHeapReferenceInfoConstantPool; +typedef struct _jvmtiHeapReferenceInfoConstantPool jvmtiHeapReferenceInfoConstantPool; +struct _jvmtiHeapReferenceInfoStackLocal; +typedef struct _jvmtiHeapReferenceInfoStackLocal jvmtiHeapReferenceInfoStackLocal; +struct _jvmtiHeapReferenceInfoJniLocal; +typedef struct _jvmtiHeapReferenceInfoJniLocal jvmtiHeapReferenceInfoJniLocal; +struct _jvmtiHeapReferenceInfoReserved; +typedef struct _jvmtiHeapReferenceInfoReserved jvmtiHeapReferenceInfoReserved; +union _jvmtiHeapReferenceInfo; +typedef union _jvmtiHeapReferenceInfo jvmtiHeapReferenceInfo; +struct _jvmtiHeapCallbacks; +typedef struct _jvmtiHeapCallbacks jvmtiHeapCallbacks; +struct _jvmtiClassDefinition; +typedef struct _jvmtiClassDefinition jvmtiClassDefinition; +struct _jvmtiMonitorUsage; +typedef struct _jvmtiMonitorUsage jvmtiMonitorUsage; +struct _jvmtiLineNumberEntry; +typedef struct _jvmtiLineNumberEntry jvmtiLineNumberEntry; +struct _jvmtiLocalVariableEntry; +typedef struct _jvmtiLocalVariableEntry jvmtiLocalVariableEntry; +struct _jvmtiParamInfo; +typedef struct _jvmtiParamInfo jvmtiParamInfo; +struct _jvmtiExtensionFunctionInfo; +typedef struct _jvmtiExtensionFunctionInfo jvmtiExtensionFunctionInfo; +struct _jvmtiExtensionEventInfo; +typedef struct _jvmtiExtensionEventInfo jvmtiExtensionEventInfo; +struct _jvmtiTimerInfo; +typedef struct _jvmtiTimerInfo jvmtiTimerInfo; +struct _jvmtiAddrLocationMap; +typedef struct _jvmtiAddrLocationMap jvmtiAddrLocationMap; + + /* Function Types */ + +typedef void (JNICALL *jvmtiStartFunction) + (jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg); + +typedef jint (JNICALL *jvmtiHeapIterationCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, jint length, void* user_data); + +typedef jint (JNICALL *jvmtiHeapReferenceCallback) + (jvmtiHeapReferenceKind reference_kind, const jvmtiHeapReferenceInfo* reference_info, jlong class_tag, jlong referrer_class_tag, jlong size, jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data); + +typedef jint (JNICALL *jvmtiPrimitiveFieldCallback) + (jvmtiHeapReferenceKind kind, const jvmtiHeapReferenceInfo* info, jlong object_class_tag, jlong* object_tag_ptr, jvalue value, jvmtiPrimitiveType value_type, void* user_data); + +typedef jint (JNICALL *jvmtiArrayPrimitiveValueCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, jint element_count, jvmtiPrimitiveType element_type, const void* elements, void* user_data); + +typedef jint (JNICALL *jvmtiStringPrimitiveValueCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, const jchar* value, jint value_length, void* user_data); + +typedef jint (JNICALL *jvmtiReservedCallback) + (); + +typedef jvmtiIterationControl (JNICALL *jvmtiHeapObjectCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, void* user_data); + +typedef jvmtiIterationControl (JNICALL *jvmtiHeapRootCallback) + (jvmtiHeapRootKind root_kind, jlong class_tag, jlong size, jlong* tag_ptr, void* user_data); + +typedef jvmtiIterationControl (JNICALL *jvmtiStackReferenceCallback) + (jvmtiHeapRootKind root_kind, jlong class_tag, jlong size, jlong* tag_ptr, jlong thread_tag, jint depth, jmethodID method, jint slot, void* user_data); + +typedef jvmtiIterationControl (JNICALL *jvmtiObjectReferenceCallback) + (jvmtiObjectReferenceKind reference_kind, jlong class_tag, jlong size, jlong* tag_ptr, jlong referrer_tag, jint referrer_index, void* user_data); + +typedef jvmtiError (JNICALL *jvmtiExtensionFunction) + (jvmtiEnv* jvmti_env, ...); + +typedef void (JNICALL *jvmtiExtensionEvent) + (jvmtiEnv* jvmti_env, ...); + + + /* Structure Types */ +struct _jvmtiThreadInfo { + char* name; + jint priority; + jboolean is_daemon; + jthreadGroup thread_group; + jobject context_class_loader; +}; +struct _jvmtiMonitorStackDepthInfo { + jobject monitor; + jint stack_depth; +}; +struct _jvmtiThreadGroupInfo { + jthreadGroup parent; + char* name; + jint max_priority; + jboolean is_daemon; +}; +struct _jvmtiFrameInfo { + jmethodID method; + jlocation location; +}; +struct _jvmtiStackInfo { + jthread thread; + jint state; + jvmtiFrameInfo* frame_buffer; + jint frame_count; +}; +struct _jvmtiHeapReferenceInfoField { + jint index; +}; +struct _jvmtiHeapReferenceInfoArray { + jint index; +}; +struct _jvmtiHeapReferenceInfoConstantPool { + jint index; +}; +struct _jvmtiHeapReferenceInfoStackLocal { + jlong thread_tag; + jlong thread_id; + jint depth; + jmethodID method; + jlocation location; + jint slot; +}; +struct _jvmtiHeapReferenceInfoJniLocal { + jlong thread_tag; + jlong thread_id; + jint depth; + jmethodID method; +}; +struct _jvmtiHeapReferenceInfoReserved { + jlong reserved1; + jlong reserved2; + jlong reserved3; + jlong reserved4; + jlong reserved5; + jlong reserved6; + jlong reserved7; + jlong reserved8; +}; +union _jvmtiHeapReferenceInfo { + jvmtiHeapReferenceInfoField field; + jvmtiHeapReferenceInfoArray array; + jvmtiHeapReferenceInfoConstantPool constant_pool; + jvmtiHeapReferenceInfoStackLocal stack_local; + jvmtiHeapReferenceInfoJniLocal jni_local; + jvmtiHeapReferenceInfoReserved other; +}; +struct _jvmtiHeapCallbacks { + jvmtiHeapIterationCallback heap_iteration_callback; + jvmtiHeapReferenceCallback heap_reference_callback; + jvmtiPrimitiveFieldCallback primitive_field_callback; + jvmtiArrayPrimitiveValueCallback array_primitive_value_callback; + jvmtiStringPrimitiveValueCallback string_primitive_value_callback; + jvmtiReservedCallback reserved5; + jvmtiReservedCallback reserved6; + jvmtiReservedCallback reserved7; + jvmtiReservedCallback reserved8; + jvmtiReservedCallback reserved9; + jvmtiReservedCallback reserved10; + jvmtiReservedCallback reserved11; + jvmtiReservedCallback reserved12; + jvmtiReservedCallback reserved13; + jvmtiReservedCallback reserved14; + jvmtiReservedCallback reserved15; +}; +struct _jvmtiClassDefinition { + jclass klass; + jint class_byte_count; + const unsigned char* class_bytes; +}; +struct _jvmtiMonitorUsage { + jthread owner; + jint entry_count; + jint waiter_count; + jthread* waiters; + jint notify_waiter_count; + jthread* notify_waiters; +}; +struct _jvmtiLineNumberEntry { + jlocation start_location; + jint line_number; +}; +struct _jvmtiLocalVariableEntry { + jlocation start_location; + jint length; + char* name; + char* signature; + char* generic_signature; + jint slot; +}; +struct _jvmtiParamInfo { + char* name; + jvmtiParamKind kind; + jvmtiParamTypes base_type; + jboolean null_ok; +}; +struct _jvmtiExtensionFunctionInfo { + jvmtiExtensionFunction func; + char* id; + char* short_description; + jint param_count; + jvmtiParamInfo* params; + jint error_count; + jvmtiError* errors; +}; +struct _jvmtiExtensionEventInfo { + jint extension_event_index; + char* id; + char* short_description; + jint param_count; + jvmtiParamInfo* params; +}; +struct _jvmtiTimerInfo { + jlong max_value; + jboolean may_skip_forward; + jboolean may_skip_backward; + jvmtiTimerKind kind; + jlong reserved1; + jlong reserved2; +}; +struct _jvmtiAddrLocationMap { + const void* start_address; + jlocation location; +}; + +typedef struct { + unsigned int can_tag_objects : 1; + unsigned int can_generate_field_modification_events : 1; + unsigned int can_generate_field_access_events : 1; + unsigned int can_get_bytecodes : 1; + unsigned int can_get_synthetic_attribute : 1; + unsigned int can_get_owned_monitor_info : 1; + unsigned int can_get_current_contended_monitor : 1; + unsigned int can_get_monitor_info : 1; + unsigned int can_pop_frame : 1; + unsigned int can_redefine_classes : 1; + unsigned int can_signal_thread : 1; + unsigned int can_get_source_file_name : 1; + unsigned int can_get_line_numbers : 1; + unsigned int can_get_source_debug_extension : 1; + unsigned int can_access_local_variables : 1; + unsigned int can_maintain_original_method_order : 1; + unsigned int can_generate_single_step_events : 1; + unsigned int can_generate_exception_events : 1; + unsigned int can_generate_frame_pop_events : 1; + unsigned int can_generate_breakpoint_events : 1; + unsigned int can_suspend : 1; + unsigned int can_redefine_any_class : 1; + unsigned int can_get_current_thread_cpu_time : 1; + unsigned int can_get_thread_cpu_time : 1; + unsigned int can_generate_method_entry_events : 1; + unsigned int can_generate_method_exit_events : 1; + unsigned int can_generate_all_class_hook_events : 1; + unsigned int can_generate_compiled_method_load_events : 1; + unsigned int can_generate_monitor_events : 1; + unsigned int can_generate_vm_object_alloc_events : 1; + unsigned int can_generate_native_method_bind_events : 1; + unsigned int can_generate_garbage_collection_events : 1; + unsigned int can_generate_object_free_events : 1; + unsigned int can_force_early_return : 1; + unsigned int can_get_owned_monitor_stack_depth_info : 1; + unsigned int can_get_constant_pool : 1; + unsigned int can_set_native_method_prefix : 1; + unsigned int can_retransform_classes : 1; + unsigned int can_retransform_any_class : 1; + unsigned int can_generate_resource_exhaustion_heap_events : 1; + unsigned int can_generate_resource_exhaustion_threads_events : 1; + unsigned int : 7; + unsigned int : 16; + unsigned int : 16; + unsigned int : 16; + unsigned int : 16; + unsigned int : 16; +} jvmtiCapabilities; + + + /* Event Definitions */ + +typedef void (JNICALL *jvmtiEventReserved)(void); + + +typedef void (JNICALL *jvmtiEventBreakpoint) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location); + +typedef void (JNICALL *jvmtiEventClassFileLoadHook) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jclass class_being_redefined, + jobject loader, + const char* name, + jobject protection_domain, + jint class_data_len, + const unsigned char* class_data, + jint* new_class_data_len, + unsigned char** new_class_data); + +typedef void (JNICALL *jvmtiEventClassLoad) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jclass klass); + +typedef void (JNICALL *jvmtiEventClassPrepare) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jclass klass); + +typedef void (JNICALL *jvmtiEventCompiledMethodLoad) + (jvmtiEnv *jvmti_env, + jmethodID method, + jint code_size, + const void* code_addr, + jint map_length, + const jvmtiAddrLocationMap* map, + const void* compile_info); + +typedef void (JNICALL *jvmtiEventCompiledMethodUnload) + (jvmtiEnv *jvmti_env, + jmethodID method, + const void* code_addr); + +typedef void (JNICALL *jvmtiEventDataDumpRequest) + (jvmtiEnv *jvmti_env); + +typedef void (JNICALL *jvmtiEventDynamicCodeGenerated) + (jvmtiEnv *jvmti_env, + const char* name, + const void* address, + jint length); + +typedef void (JNICALL *jvmtiEventException) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jobject exception, + jmethodID catch_method, + jlocation catch_location); + +typedef void (JNICALL *jvmtiEventExceptionCatch) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jobject exception); + +typedef void (JNICALL *jvmtiEventFieldAccess) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jclass field_klass, + jobject object, + jfieldID field); + +typedef void (JNICALL *jvmtiEventFieldModification) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jclass field_klass, + jobject object, + jfieldID field, + char signature_type, + jvalue new_value); + +typedef void (JNICALL *jvmtiEventFramePop) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jboolean was_popped_by_exception); + +typedef void (JNICALL *jvmtiEventGarbageCollectionFinish) + (jvmtiEnv *jvmti_env); + +typedef void (JNICALL *jvmtiEventGarbageCollectionStart) + (jvmtiEnv *jvmti_env); + +typedef void (JNICALL *jvmtiEventMethodEntry) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method); + +typedef void (JNICALL *jvmtiEventMethodExit) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jboolean was_popped_by_exception, + jvalue return_value); + +typedef void (JNICALL *jvmtiEventMonitorContendedEnter) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object); + +typedef void (JNICALL *jvmtiEventMonitorContendedEntered) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object); + +typedef void (JNICALL *jvmtiEventMonitorWait) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object, + jlong timeout); + +typedef void (JNICALL *jvmtiEventMonitorWaited) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object, + jboolean timed_out); + +typedef void (JNICALL *jvmtiEventNativeMethodBind) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + void* address, + void** new_address_ptr); + +typedef void (JNICALL *jvmtiEventObjectFree) + (jvmtiEnv *jvmti_env, + jlong tag); + +typedef void (JNICALL *jvmtiEventResourceExhausted) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jint flags, + const void* reserved, + const char* description); + +typedef void (JNICALL *jvmtiEventSingleStep) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location); + +typedef void (JNICALL *jvmtiEventThreadEnd) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread); + +typedef void (JNICALL *jvmtiEventThreadStart) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread); + +typedef void (JNICALL *jvmtiEventVMDeath) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env); + +typedef void (JNICALL *jvmtiEventVMInit) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread); + +typedef void (JNICALL *jvmtiEventVMObjectAlloc) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object, + jclass object_klass, + jlong size); + +typedef void (JNICALL *jvmtiEventVMStart) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env); + + /* Event Callback Structure */ + +typedef struct { + /* 50 : VM Initialization Event */ + jvmtiEventVMInit VMInit; + /* 51 : VM Death Event */ + jvmtiEventVMDeath VMDeath; + /* 52 : Thread Start */ + jvmtiEventThreadStart ThreadStart; + /* 53 : Thread End */ + jvmtiEventThreadEnd ThreadEnd; + /* 54 : Class File Load Hook */ + jvmtiEventClassFileLoadHook ClassFileLoadHook; + /* 55 : Class Load */ + jvmtiEventClassLoad ClassLoad; + /* 56 : Class Prepare */ + jvmtiEventClassPrepare ClassPrepare; + /* 57 : VM Start Event */ + jvmtiEventVMStart VMStart; + /* 58 : Exception */ + jvmtiEventException Exception; + /* 59 : Exception Catch */ + jvmtiEventExceptionCatch ExceptionCatch; + /* 60 : Single Step */ + jvmtiEventSingleStep SingleStep; + /* 61 : Frame Pop */ + jvmtiEventFramePop FramePop; + /* 62 : Breakpoint */ + jvmtiEventBreakpoint Breakpoint; + /* 63 : Field Access */ + jvmtiEventFieldAccess FieldAccess; + /* 64 : Field Modification */ + jvmtiEventFieldModification FieldModification; + /* 65 : Method Entry */ + jvmtiEventMethodEntry MethodEntry; + /* 66 : Method Exit */ + jvmtiEventMethodExit MethodExit; + /* 67 : Native Method Bind */ + jvmtiEventNativeMethodBind NativeMethodBind; + /* 68 : Compiled Method Load */ + jvmtiEventCompiledMethodLoad CompiledMethodLoad; + /* 69 : Compiled Method Unload */ + jvmtiEventCompiledMethodUnload CompiledMethodUnload; + /* 70 : Dynamic Code Generated */ + jvmtiEventDynamicCodeGenerated DynamicCodeGenerated; + /* 71 : Data Dump Request */ + jvmtiEventDataDumpRequest DataDumpRequest; + /* 72 */ + jvmtiEventReserved reserved72; + /* 73 : Monitor Wait */ + jvmtiEventMonitorWait MonitorWait; + /* 74 : Monitor Waited */ + jvmtiEventMonitorWaited MonitorWaited; + /* 75 : Monitor Contended Enter */ + jvmtiEventMonitorContendedEnter MonitorContendedEnter; + /* 76 : Monitor Contended Entered */ + jvmtiEventMonitorContendedEntered MonitorContendedEntered; + /* 77 */ + jvmtiEventReserved reserved77; + /* 78 */ + jvmtiEventReserved reserved78; + /* 79 */ + jvmtiEventReserved reserved79; + /* 80 : Resource Exhausted */ + jvmtiEventResourceExhausted ResourceExhausted; + /* 81 : Garbage Collection Start */ + jvmtiEventGarbageCollectionStart GarbageCollectionStart; + /* 82 : Garbage Collection Finish */ + jvmtiEventGarbageCollectionFinish GarbageCollectionFinish; + /* 83 : Object Free */ + jvmtiEventObjectFree ObjectFree; + /* 84 : VM Object Allocation */ + jvmtiEventVMObjectAlloc VMObjectAlloc; +} jvmtiEventCallbacks; + + + /* Function Interface */ + +typedef struct jvmtiInterface_1_ { + + /* 1 : RESERVED */ + void *reserved1; + + /* 2 : Set Event Notification Mode */ + jvmtiError (JNICALL *SetEventNotificationMode) (jvmtiEnv* env, + jvmtiEventMode mode, + jvmtiEvent event_type, + jthread event_thread, + ...); + + /* 3 : RESERVED */ + void *reserved3; + + /* 4 : Get All Threads */ + jvmtiError (JNICALL *GetAllThreads) (jvmtiEnv* env, + jint* threads_count_ptr, + jthread** threads_ptr); + + /* 5 : Suspend Thread */ + jvmtiError (JNICALL *SuspendThread) (jvmtiEnv* env, + jthread thread); + + /* 6 : Resume Thread */ + jvmtiError (JNICALL *ResumeThread) (jvmtiEnv* env, + jthread thread); + + /* 7 : Stop Thread */ + jvmtiError (JNICALL *StopThread) (jvmtiEnv* env, + jthread thread, + jobject exception); + + /* 8 : Interrupt Thread */ + jvmtiError (JNICALL *InterruptThread) (jvmtiEnv* env, + jthread thread); + + /* 9 : Get Thread Info */ + jvmtiError (JNICALL *GetThreadInfo) (jvmtiEnv* env, + jthread thread, + jvmtiThreadInfo* info_ptr); + + /* 10 : Get Owned Monitor Info */ + jvmtiError (JNICALL *GetOwnedMonitorInfo) (jvmtiEnv* env, + jthread thread, + jint* owned_monitor_count_ptr, + jobject** owned_monitors_ptr); + + /* 11 : Get Current Contended Monitor */ + jvmtiError (JNICALL *GetCurrentContendedMonitor) (jvmtiEnv* env, + jthread thread, + jobject* monitor_ptr); + + /* 12 : Run Agent Thread */ + jvmtiError (JNICALL *RunAgentThread) (jvmtiEnv* env, + jthread thread, + jvmtiStartFunction proc, + const void* arg, + jint priority); + + /* 13 : Get Top Thread Groups */ + jvmtiError (JNICALL *GetTopThreadGroups) (jvmtiEnv* env, + jint* group_count_ptr, + jthreadGroup** groups_ptr); + + /* 14 : Get Thread Group Info */ + jvmtiError (JNICALL *GetThreadGroupInfo) (jvmtiEnv* env, + jthreadGroup group, + jvmtiThreadGroupInfo* info_ptr); + + /* 15 : Get Thread Group Children */ + jvmtiError (JNICALL *GetThreadGroupChildren) (jvmtiEnv* env, + jthreadGroup group, + jint* thread_count_ptr, + jthread** threads_ptr, + jint* group_count_ptr, + jthreadGroup** groups_ptr); + + /* 16 : Get Frame Count */ + jvmtiError (JNICALL *GetFrameCount) (jvmtiEnv* env, + jthread thread, + jint* count_ptr); + + /* 17 : Get Thread State */ + jvmtiError (JNICALL *GetThreadState) (jvmtiEnv* env, + jthread thread, + jint* thread_state_ptr); + + /* 18 : Get Current Thread */ + jvmtiError (JNICALL *GetCurrentThread) (jvmtiEnv* env, + jthread* thread_ptr); + + /* 19 : Get Frame Location */ + jvmtiError (JNICALL *GetFrameLocation) (jvmtiEnv* env, + jthread thread, + jint depth, + jmethodID* method_ptr, + jlocation* location_ptr); + + /* 20 : Notify Frame Pop */ + jvmtiError (JNICALL *NotifyFramePop) (jvmtiEnv* env, + jthread thread, + jint depth); + + /* 21 : Get Local Variable - Object */ + jvmtiError (JNICALL *GetLocalObject) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jobject* value_ptr); + + /* 22 : Get Local Variable - Int */ + jvmtiError (JNICALL *GetLocalInt) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jint* value_ptr); + + /* 23 : Get Local Variable - Long */ + jvmtiError (JNICALL *GetLocalLong) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jlong* value_ptr); + + /* 24 : Get Local Variable - Float */ + jvmtiError (JNICALL *GetLocalFloat) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jfloat* value_ptr); + + /* 25 : Get Local Variable - Double */ + jvmtiError (JNICALL *GetLocalDouble) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jdouble* value_ptr); + + /* 26 : Set Local Variable - Object */ + jvmtiError (JNICALL *SetLocalObject) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jobject value); + + /* 27 : Set Local Variable - Int */ + jvmtiError (JNICALL *SetLocalInt) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jint value); + + /* 28 : Set Local Variable - Long */ + jvmtiError (JNICALL *SetLocalLong) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jlong value); + + /* 29 : Set Local Variable - Float */ + jvmtiError (JNICALL *SetLocalFloat) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jfloat value); + + /* 30 : Set Local Variable - Double */ + jvmtiError (JNICALL *SetLocalDouble) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jdouble value); + + /* 31 : Create Raw Monitor */ + jvmtiError (JNICALL *CreateRawMonitor) (jvmtiEnv* env, + const char* name, + jrawMonitorID* monitor_ptr); + + /* 32 : Destroy Raw Monitor */ + jvmtiError (JNICALL *DestroyRawMonitor) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 33 : Raw Monitor Enter */ + jvmtiError (JNICALL *RawMonitorEnter) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 34 : Raw Monitor Exit */ + jvmtiError (JNICALL *RawMonitorExit) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 35 : Raw Monitor Wait */ + jvmtiError (JNICALL *RawMonitorWait) (jvmtiEnv* env, + jrawMonitorID monitor, + jlong millis); + + /* 36 : Raw Monitor Notify */ + jvmtiError (JNICALL *RawMonitorNotify) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 37 : Raw Monitor Notify All */ + jvmtiError (JNICALL *RawMonitorNotifyAll) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 38 : Set Breakpoint */ + jvmtiError (JNICALL *SetBreakpoint) (jvmtiEnv* env, + jmethodID method, + jlocation location); + + /* 39 : Clear Breakpoint */ + jvmtiError (JNICALL *ClearBreakpoint) (jvmtiEnv* env, + jmethodID method, + jlocation location); + + /* 40 : RESERVED */ + void *reserved40; + + /* 41 : Set Field Access Watch */ + jvmtiError (JNICALL *SetFieldAccessWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 42 : Clear Field Access Watch */ + jvmtiError (JNICALL *ClearFieldAccessWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 43 : Set Field Modification Watch */ + jvmtiError (JNICALL *SetFieldModificationWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 44 : Clear Field Modification Watch */ + jvmtiError (JNICALL *ClearFieldModificationWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 45 : Is Modifiable Class */ + jvmtiError (JNICALL *IsModifiableClass) (jvmtiEnv* env, + jclass klass, + jboolean* is_modifiable_class_ptr); + + /* 46 : Allocate */ + jvmtiError (JNICALL *Allocate) (jvmtiEnv* env, + jlong size, + unsigned char** mem_ptr); + + /* 47 : Deallocate */ + jvmtiError (JNICALL *Deallocate) (jvmtiEnv* env, + unsigned char* mem); + + /* 48 : Get Class Signature */ + jvmtiError (JNICALL *GetClassSignature) (jvmtiEnv* env, + jclass klass, + char** signature_ptr, + char** generic_ptr); + + /* 49 : Get Class Status */ + jvmtiError (JNICALL *GetClassStatus) (jvmtiEnv* env, + jclass klass, + jint* status_ptr); + + /* 50 : Get Source File Name */ + jvmtiError (JNICALL *GetSourceFileName) (jvmtiEnv* env, + jclass klass, + char** source_name_ptr); + + /* 51 : Get Class Modifiers */ + jvmtiError (JNICALL *GetClassModifiers) (jvmtiEnv* env, + jclass klass, + jint* modifiers_ptr); + + /* 52 : Get Class Methods */ + jvmtiError (JNICALL *GetClassMethods) (jvmtiEnv* env, + jclass klass, + jint* method_count_ptr, + jmethodID** methods_ptr); + + /* 53 : Get Class Fields */ + jvmtiError (JNICALL *GetClassFields) (jvmtiEnv* env, + jclass klass, + jint* field_count_ptr, + jfieldID** fields_ptr); + + /* 54 : Get Implemented Interfaces */ + jvmtiError (JNICALL *GetImplementedInterfaces) (jvmtiEnv* env, + jclass klass, + jint* interface_count_ptr, + jclass** interfaces_ptr); + + /* 55 : Is Interface */ + jvmtiError (JNICALL *IsInterface) (jvmtiEnv* env, + jclass klass, + jboolean* is_interface_ptr); + + /* 56 : Is Array Class */ + jvmtiError (JNICALL *IsArrayClass) (jvmtiEnv* env, + jclass klass, + jboolean* is_array_class_ptr); + + /* 57 : Get Class Loader */ + jvmtiError (JNICALL *GetClassLoader) (jvmtiEnv* env, + jclass klass, + jobject* classloader_ptr); + + /* 58 : Get Object Hash Code */ + jvmtiError (JNICALL *GetObjectHashCode) (jvmtiEnv* env, + jobject object, + jint* hash_code_ptr); + + /* 59 : Get Object Monitor Usage */ + jvmtiError (JNICALL *GetObjectMonitorUsage) (jvmtiEnv* env, + jobject object, + jvmtiMonitorUsage* info_ptr); + + /* 60 : Get Field Name (and Signature) */ + jvmtiError (JNICALL *GetFieldName) (jvmtiEnv* env, + jclass klass, + jfieldID field, + char** name_ptr, + char** signature_ptr, + char** generic_ptr); + + /* 61 : Get Field Declaring Class */ + jvmtiError (JNICALL *GetFieldDeclaringClass) (jvmtiEnv* env, + jclass klass, + jfieldID field, + jclass* declaring_class_ptr); + + /* 62 : Get Field Modifiers */ + jvmtiError (JNICALL *GetFieldModifiers) (jvmtiEnv* env, + jclass klass, + jfieldID field, + jint* modifiers_ptr); + + /* 63 : Is Field Synthetic */ + jvmtiError (JNICALL *IsFieldSynthetic) (jvmtiEnv* env, + jclass klass, + jfieldID field, + jboolean* is_synthetic_ptr); + + /* 64 : Get Method Name (and Signature) */ + jvmtiError (JNICALL *GetMethodName) (jvmtiEnv* env, + jmethodID method, + char** name_ptr, + char** signature_ptr, + char** generic_ptr); + + /* 65 : Get Method Declaring Class */ + jvmtiError (JNICALL *GetMethodDeclaringClass) (jvmtiEnv* env, + jmethodID method, + jclass* declaring_class_ptr); + + /* 66 : Get Method Modifiers */ + jvmtiError (JNICALL *GetMethodModifiers) (jvmtiEnv* env, + jmethodID method, + jint* modifiers_ptr); + + /* 67 : RESERVED */ + void *reserved67; + + /* 68 : Get Max Locals */ + jvmtiError (JNICALL *GetMaxLocals) (jvmtiEnv* env, + jmethodID method, + jint* max_ptr); + + /* 69 : Get Arguments Size */ + jvmtiError (JNICALL *GetArgumentsSize) (jvmtiEnv* env, + jmethodID method, + jint* size_ptr); + + /* 70 : Get Line Number Table */ + jvmtiError (JNICALL *GetLineNumberTable) (jvmtiEnv* env, + jmethodID method, + jint* entry_count_ptr, + jvmtiLineNumberEntry** table_ptr); + + /* 71 : Get Method Location */ + jvmtiError (JNICALL *GetMethodLocation) (jvmtiEnv* env, + jmethodID method, + jlocation* start_location_ptr, + jlocation* end_location_ptr); + + /* 72 : Get Local Variable Table */ + jvmtiError (JNICALL *GetLocalVariableTable) (jvmtiEnv* env, + jmethodID method, + jint* entry_count_ptr, + jvmtiLocalVariableEntry** table_ptr); + + /* 73 : Set Native Method Prefix */ + jvmtiError (JNICALL *SetNativeMethodPrefix) (jvmtiEnv* env, + const char* prefix); + + /* 74 : Set Native Method Prefixes */ + jvmtiError (JNICALL *SetNativeMethodPrefixes) (jvmtiEnv* env, + jint prefix_count, + char** prefixes); + + /* 75 : Get Bytecodes */ + jvmtiError (JNICALL *GetBytecodes) (jvmtiEnv* env, + jmethodID method, + jint* bytecode_count_ptr, + unsigned char** bytecodes_ptr); + + /* 76 : Is Method Native */ + jvmtiError (JNICALL *IsMethodNative) (jvmtiEnv* env, + jmethodID method, + jboolean* is_native_ptr); + + /* 77 : Is Method Synthetic */ + jvmtiError (JNICALL *IsMethodSynthetic) (jvmtiEnv* env, + jmethodID method, + jboolean* is_synthetic_ptr); + + /* 78 : Get Loaded Classes */ + jvmtiError (JNICALL *GetLoadedClasses) (jvmtiEnv* env, + jint* class_count_ptr, + jclass** classes_ptr); + + /* 79 : Get Classloader Classes */ + jvmtiError (JNICALL *GetClassLoaderClasses) (jvmtiEnv* env, + jobject initiating_loader, + jint* class_count_ptr, + jclass** classes_ptr); + + /* 80 : Pop Frame */ + jvmtiError (JNICALL *PopFrame) (jvmtiEnv* env, + jthread thread); + + /* 81 : Force Early Return - Object */ + jvmtiError (JNICALL *ForceEarlyReturnObject) (jvmtiEnv* env, + jthread thread, + jobject value); + + /* 82 : Force Early Return - Int */ + jvmtiError (JNICALL *ForceEarlyReturnInt) (jvmtiEnv* env, + jthread thread, + jint value); + + /* 83 : Force Early Return - Long */ + jvmtiError (JNICALL *ForceEarlyReturnLong) (jvmtiEnv* env, + jthread thread, + jlong value); + + /* 84 : Force Early Return - Float */ + jvmtiError (JNICALL *ForceEarlyReturnFloat) (jvmtiEnv* env, + jthread thread, + jfloat value); + + /* 85 : Force Early Return - Double */ + jvmtiError (JNICALL *ForceEarlyReturnDouble) (jvmtiEnv* env, + jthread thread, + jdouble value); + + /* 86 : Force Early Return - Void */ + jvmtiError (JNICALL *ForceEarlyReturnVoid) (jvmtiEnv* env, + jthread thread); + + /* 87 : Redefine Classes */ + jvmtiError (JNICALL *RedefineClasses) (jvmtiEnv* env, + jint class_count, + const jvmtiClassDefinition* class_definitions); + + /* 88 : Get Version Number */ + jvmtiError (JNICALL *GetVersionNumber) (jvmtiEnv* env, + jint* version_ptr); + + /* 89 : Get Capabilities */ + jvmtiError (JNICALL *GetCapabilities) (jvmtiEnv* env, + jvmtiCapabilities* capabilities_ptr); + + /* 90 : Get Source Debug Extension */ + jvmtiError (JNICALL *GetSourceDebugExtension) (jvmtiEnv* env, + jclass klass, + char** source_debug_extension_ptr); + + /* 91 : Is Method Obsolete */ + jvmtiError (JNICALL *IsMethodObsolete) (jvmtiEnv* env, + jmethodID method, + jboolean* is_obsolete_ptr); + + /* 92 : Suspend Thread List */ + jvmtiError (JNICALL *SuspendThreadList) (jvmtiEnv* env, + jint request_count, + const jthread* request_list, + jvmtiError* results); + + /* 93 : Resume Thread List */ + jvmtiError (JNICALL *ResumeThreadList) (jvmtiEnv* env, + jint request_count, + const jthread* request_list, + jvmtiError* results); + + /* 94 : RESERVED */ + void *reserved94; + + /* 95 : RESERVED */ + void *reserved95; + + /* 96 : RESERVED */ + void *reserved96; + + /* 97 : RESERVED */ + void *reserved97; + + /* 98 : RESERVED */ + void *reserved98; + + /* 99 : RESERVED */ + void *reserved99; + + /* 100 : Get All Stack Traces */ + jvmtiError (JNICALL *GetAllStackTraces) (jvmtiEnv* env, + jint max_frame_count, + jvmtiStackInfo** stack_info_ptr, + jint* thread_count_ptr); + + /* 101 : Get Thread List Stack Traces */ + jvmtiError (JNICALL *GetThreadListStackTraces) (jvmtiEnv* env, + jint thread_count, + const jthread* thread_list, + jint max_frame_count, + jvmtiStackInfo** stack_info_ptr); + + /* 102 : Get Thread Local Storage */ + jvmtiError (JNICALL *GetThreadLocalStorage) (jvmtiEnv* env, + jthread thread, + void** data_ptr); + + /* 103 : Set Thread Local Storage */ + jvmtiError (JNICALL *SetThreadLocalStorage) (jvmtiEnv* env, + jthread thread, + const void* data); + + /* 104 : Get Stack Trace */ + jvmtiError (JNICALL *GetStackTrace) (jvmtiEnv* env, + jthread thread, + jint start_depth, + jint max_frame_count, + jvmtiFrameInfo* frame_buffer, + jint* count_ptr); + + /* 105 : RESERVED */ + void *reserved105; + + /* 106 : Get Tag */ + jvmtiError (JNICALL *GetTag) (jvmtiEnv* env, + jobject object, + jlong* tag_ptr); + + /* 107 : Set Tag */ + jvmtiError (JNICALL *SetTag) (jvmtiEnv* env, + jobject object, + jlong tag); + + /* 108 : Force Garbage Collection */ + jvmtiError (JNICALL *ForceGarbageCollection) (jvmtiEnv* env); + + /* 109 : Iterate Over Objects Reachable From Object */ + jvmtiError (JNICALL *IterateOverObjectsReachableFromObject) (jvmtiEnv* env, + jobject object, + jvmtiObjectReferenceCallback object_reference_callback, + const void* user_data); + + /* 110 : Iterate Over Reachable Objects */ + jvmtiError (JNICALL *IterateOverReachableObjects) (jvmtiEnv* env, + jvmtiHeapRootCallback heap_root_callback, + jvmtiStackReferenceCallback stack_ref_callback, + jvmtiObjectReferenceCallback object_ref_callback, + const void* user_data); + + /* 111 : Iterate Over Heap */ + jvmtiError (JNICALL *IterateOverHeap) (jvmtiEnv* env, + jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data); + + /* 112 : Iterate Over Instances Of Class */ + jvmtiError (JNICALL *IterateOverInstancesOfClass) (jvmtiEnv* env, + jclass klass, + jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data); + + /* 113 : RESERVED */ + void *reserved113; + + /* 114 : Get Objects With Tags */ + jvmtiError (JNICALL *GetObjectsWithTags) (jvmtiEnv* env, + jint tag_count, + const jlong* tags, + jint* count_ptr, + jobject** object_result_ptr, + jlong** tag_result_ptr); + + /* 115 : Follow References */ + jvmtiError (JNICALL *FollowReferences) (jvmtiEnv* env, + jint heap_filter, + jclass klass, + jobject initial_object, + const jvmtiHeapCallbacks* callbacks, + const void* user_data); + + /* 116 : Iterate Through Heap */ + jvmtiError (JNICALL *IterateThroughHeap) (jvmtiEnv* env, + jint heap_filter, + jclass klass, + const jvmtiHeapCallbacks* callbacks, + const void* user_data); + + /* 117 : RESERVED */ + void *reserved117; + + /* 118 : RESERVED */ + void *reserved118; + + /* 119 : RESERVED */ + void *reserved119; + + /* 120 : Set JNI Function Table */ + jvmtiError (JNICALL *SetJNIFunctionTable) (jvmtiEnv* env, + const jniNativeInterface* function_table); + + /* 121 : Get JNI Function Table */ + jvmtiError (JNICALL *GetJNIFunctionTable) (jvmtiEnv* env, + jniNativeInterface** function_table); + + /* 122 : Set Event Callbacks */ + jvmtiError (JNICALL *SetEventCallbacks) (jvmtiEnv* env, + const jvmtiEventCallbacks* callbacks, + jint size_of_callbacks); + + /* 123 : Generate Events */ + jvmtiError (JNICALL *GenerateEvents) (jvmtiEnv* env, + jvmtiEvent event_type); + + /* 124 : Get Extension Functions */ + jvmtiError (JNICALL *GetExtensionFunctions) (jvmtiEnv* env, + jint* extension_count_ptr, + jvmtiExtensionFunctionInfo** extensions); + + /* 125 : Get Extension Events */ + jvmtiError (JNICALL *GetExtensionEvents) (jvmtiEnv* env, + jint* extension_count_ptr, + jvmtiExtensionEventInfo** extensions); + + /* 126 : Set Extension Event Callback */ + jvmtiError (JNICALL *SetExtensionEventCallback) (jvmtiEnv* env, + jint extension_event_index, + jvmtiExtensionEvent callback); + + /* 127 : Dispose Environment */ + jvmtiError (JNICALL *DisposeEnvironment) (jvmtiEnv* env); + + /* 128 : Get Error Name */ + jvmtiError (JNICALL *GetErrorName) (jvmtiEnv* env, + jvmtiError error, + char** name_ptr); + + /* 129 : Get JLocation Format */ + jvmtiError (JNICALL *GetJLocationFormat) (jvmtiEnv* env, + jvmtiJlocationFormat* format_ptr); + + /* 130 : Get System Properties */ + jvmtiError (JNICALL *GetSystemProperties) (jvmtiEnv* env, + jint* count_ptr, + char*** property_ptr); + + /* 131 : Get System Property */ + jvmtiError (JNICALL *GetSystemProperty) (jvmtiEnv* env, + const char* property, + char** value_ptr); + + /* 132 : Set System Property */ + jvmtiError (JNICALL *SetSystemProperty) (jvmtiEnv* env, + const char* property, + const char* value); + + /* 133 : Get Phase */ + jvmtiError (JNICALL *GetPhase) (jvmtiEnv* env, + jvmtiPhase* phase_ptr); + + /* 134 : Get Current Thread CPU Timer Information */ + jvmtiError (JNICALL *GetCurrentThreadCpuTimerInfo) (jvmtiEnv* env, + jvmtiTimerInfo* info_ptr); + + /* 135 : Get Current Thread CPU Time */ + jvmtiError (JNICALL *GetCurrentThreadCpuTime) (jvmtiEnv* env, + jlong* nanos_ptr); + + /* 136 : Get Thread CPU Timer Information */ + jvmtiError (JNICALL *GetThreadCpuTimerInfo) (jvmtiEnv* env, + jvmtiTimerInfo* info_ptr); + + /* 137 : Get Thread CPU Time */ + jvmtiError (JNICALL *GetThreadCpuTime) (jvmtiEnv* env, + jthread thread, + jlong* nanos_ptr); + + /* 138 : Get Timer Information */ + jvmtiError (JNICALL *GetTimerInfo) (jvmtiEnv* env, + jvmtiTimerInfo* info_ptr); + + /* 139 : Get Time */ + jvmtiError (JNICALL *GetTime) (jvmtiEnv* env, + jlong* nanos_ptr); + + /* 140 : Get Potential Capabilities */ + jvmtiError (JNICALL *GetPotentialCapabilities) (jvmtiEnv* env, + jvmtiCapabilities* capabilities_ptr); + + /* 141 : RESERVED */ + void *reserved141; + + /* 142 : Add Capabilities */ + jvmtiError (JNICALL *AddCapabilities) (jvmtiEnv* env, + const jvmtiCapabilities* capabilities_ptr); + + /* 143 : Relinquish Capabilities */ + jvmtiError (JNICALL *RelinquishCapabilities) (jvmtiEnv* env, + const jvmtiCapabilities* capabilities_ptr); + + /* 144 : Get Available Processors */ + jvmtiError (JNICALL *GetAvailableProcessors) (jvmtiEnv* env, + jint* processor_count_ptr); + + /* 145 : Get Class Version Numbers */ + jvmtiError (JNICALL *GetClassVersionNumbers) (jvmtiEnv* env, + jclass klass, + jint* minor_version_ptr, + jint* major_version_ptr); + + /* 146 : Get Constant Pool */ + jvmtiError (JNICALL *GetConstantPool) (jvmtiEnv* env, + jclass klass, + jint* constant_pool_count_ptr, + jint* constant_pool_byte_count_ptr, + unsigned char** constant_pool_bytes_ptr); + + /* 147 : Get Environment Local Storage */ + jvmtiError (JNICALL *GetEnvironmentLocalStorage) (jvmtiEnv* env, + void** data_ptr); + + /* 148 : Set Environment Local Storage */ + jvmtiError (JNICALL *SetEnvironmentLocalStorage) (jvmtiEnv* env, + const void* data); + + /* 149 : Add To Bootstrap Class Loader Search */ + jvmtiError (JNICALL *AddToBootstrapClassLoaderSearch) (jvmtiEnv* env, + const char* segment); + + /* 150 : Set Verbose Flag */ + jvmtiError (JNICALL *SetVerboseFlag) (jvmtiEnv* env, + jvmtiVerboseFlag flag, + jboolean value); + + /* 151 : Add To System Class Loader Search */ + jvmtiError (JNICALL *AddToSystemClassLoaderSearch) (jvmtiEnv* env, + const char* segment); + + /* 152 : Retransform Classes */ + jvmtiError (JNICALL *RetransformClasses) (jvmtiEnv* env, + jint class_count, + const jclass* classes); + + /* 153 : Get Owned Monitor Stack Depth Info */ + jvmtiError (JNICALL *GetOwnedMonitorStackDepthInfo) (jvmtiEnv* env, + jthread thread, + jint* monitor_info_count_ptr, + jvmtiMonitorStackDepthInfo** monitor_info_ptr); + + /* 154 : Get Object Size */ + jvmtiError (JNICALL *GetObjectSize) (jvmtiEnv* env, + jobject object, + jlong* size_ptr); + + /* 155 : Get Local Instance */ + jvmtiError (JNICALL *GetLocalInstance) (jvmtiEnv* env, + jthread thread, + jint depth, + jobject* value_ptr); + +} jvmtiInterface_1; + +struct _jvmtiEnv { + const struct jvmtiInterface_1_ *functions; +#ifdef __cplusplus + + + jvmtiError Allocate(jlong size, + unsigned char** mem_ptr) { + return functions->Allocate(this, size, mem_ptr); + } + + jvmtiError Deallocate(unsigned char* mem) { + return functions->Deallocate(this, mem); + } + + jvmtiError GetThreadState(jthread thread, + jint* thread_state_ptr) { + return functions->GetThreadState(this, thread, thread_state_ptr); + } + + jvmtiError GetCurrentThread(jthread* thread_ptr) { + return functions->GetCurrentThread(this, thread_ptr); + } + + jvmtiError GetAllThreads(jint* threads_count_ptr, + jthread** threads_ptr) { + return functions->GetAllThreads(this, threads_count_ptr, threads_ptr); + } + + jvmtiError SuspendThread(jthread thread) { + return functions->SuspendThread(this, thread); + } + + jvmtiError SuspendThreadList(jint request_count, + const jthread* request_list, + jvmtiError* results) { + return functions->SuspendThreadList(this, request_count, request_list, results); + } + + jvmtiError ResumeThread(jthread thread) { + return functions->ResumeThread(this, thread); + } + + jvmtiError ResumeThreadList(jint request_count, + const jthread* request_list, + jvmtiError* results) { + return functions->ResumeThreadList(this, request_count, request_list, results); + } + + jvmtiError StopThread(jthread thread, + jobject exception) { + return functions->StopThread(this, thread, exception); + } + + jvmtiError InterruptThread(jthread thread) { + return functions->InterruptThread(this, thread); + } + + jvmtiError GetThreadInfo(jthread thread, + jvmtiThreadInfo* info_ptr) { + return functions->GetThreadInfo(this, thread, info_ptr); + } + + jvmtiError GetOwnedMonitorInfo(jthread thread, + jint* owned_monitor_count_ptr, + jobject** owned_monitors_ptr) { + return functions->GetOwnedMonitorInfo(this, thread, owned_monitor_count_ptr, owned_monitors_ptr); + } + + jvmtiError GetOwnedMonitorStackDepthInfo(jthread thread, + jint* monitor_info_count_ptr, + jvmtiMonitorStackDepthInfo** monitor_info_ptr) { + return functions->GetOwnedMonitorStackDepthInfo(this, thread, monitor_info_count_ptr, monitor_info_ptr); + } + + jvmtiError GetCurrentContendedMonitor(jthread thread, + jobject* monitor_ptr) { + return functions->GetCurrentContendedMonitor(this, thread, monitor_ptr); + } + + jvmtiError RunAgentThread(jthread thread, + jvmtiStartFunction proc, + const void* arg, + jint priority) { + return functions->RunAgentThread(this, thread, proc, arg, priority); + } + + jvmtiError SetThreadLocalStorage(jthread thread, + const void* data) { + return functions->SetThreadLocalStorage(this, thread, data); + } + + jvmtiError GetThreadLocalStorage(jthread thread, + void** data_ptr) { + return functions->GetThreadLocalStorage(this, thread, data_ptr); + } + + jvmtiError GetTopThreadGroups(jint* group_count_ptr, + jthreadGroup** groups_ptr) { + return functions->GetTopThreadGroups(this, group_count_ptr, groups_ptr); + } + + jvmtiError GetThreadGroupInfo(jthreadGroup group, + jvmtiThreadGroupInfo* info_ptr) { + return functions->GetThreadGroupInfo(this, group, info_ptr); + } + + jvmtiError GetThreadGroupChildren(jthreadGroup group, + jint* thread_count_ptr, + jthread** threads_ptr, + jint* group_count_ptr, + jthreadGroup** groups_ptr) { + return functions->GetThreadGroupChildren(this, group, thread_count_ptr, threads_ptr, group_count_ptr, groups_ptr); + } + + jvmtiError GetStackTrace(jthread thread, + jint start_depth, + jint max_frame_count, + jvmtiFrameInfo* frame_buffer, + jint* count_ptr) { + return functions->GetStackTrace(this, thread, start_depth, max_frame_count, frame_buffer, count_ptr); + } + + jvmtiError GetAllStackTraces(jint max_frame_count, + jvmtiStackInfo** stack_info_ptr, + jint* thread_count_ptr) { + return functions->GetAllStackTraces(this, max_frame_count, stack_info_ptr, thread_count_ptr); + } + + jvmtiError GetThreadListStackTraces(jint thread_count, + const jthread* thread_list, + jint max_frame_count, + jvmtiStackInfo** stack_info_ptr) { + return functions->GetThreadListStackTraces(this, thread_count, thread_list, max_frame_count, stack_info_ptr); + } + + jvmtiError GetFrameCount(jthread thread, + jint* count_ptr) { + return functions->GetFrameCount(this, thread, count_ptr); + } + + jvmtiError PopFrame(jthread thread) { + return functions->PopFrame(this, thread); + } + + jvmtiError GetFrameLocation(jthread thread, + jint depth, + jmethodID* method_ptr, + jlocation* location_ptr) { + return functions->GetFrameLocation(this, thread, depth, method_ptr, location_ptr); + } + + jvmtiError NotifyFramePop(jthread thread, + jint depth) { + return functions->NotifyFramePop(this, thread, depth); + } + + jvmtiError ForceEarlyReturnObject(jthread thread, + jobject value) { + return functions->ForceEarlyReturnObject(this, thread, value); + } + + jvmtiError ForceEarlyReturnInt(jthread thread, + jint value) { + return functions->ForceEarlyReturnInt(this, thread, value); + } + + jvmtiError ForceEarlyReturnLong(jthread thread, + jlong value) { + return functions->ForceEarlyReturnLong(this, thread, value); + } + + jvmtiError ForceEarlyReturnFloat(jthread thread, + jfloat value) { + return functions->ForceEarlyReturnFloat(this, thread, value); + } + + jvmtiError ForceEarlyReturnDouble(jthread thread, + jdouble value) { + return functions->ForceEarlyReturnDouble(this, thread, value); + } + + jvmtiError ForceEarlyReturnVoid(jthread thread) { + return functions->ForceEarlyReturnVoid(this, thread); + } + + jvmtiError FollowReferences(jint heap_filter, + jclass klass, + jobject initial_object, + const jvmtiHeapCallbacks* callbacks, + const void* user_data) { + return functions->FollowReferences(this, heap_filter, klass, initial_object, callbacks, user_data); + } + + jvmtiError IterateThroughHeap(jint heap_filter, + jclass klass, + const jvmtiHeapCallbacks* callbacks, + const void* user_data) { + return functions->IterateThroughHeap(this, heap_filter, klass, callbacks, user_data); + } + + jvmtiError GetTag(jobject object, + jlong* tag_ptr) { + return functions->GetTag(this, object, tag_ptr); + } + + jvmtiError SetTag(jobject object, + jlong tag) { + return functions->SetTag(this, object, tag); + } + + jvmtiError GetObjectsWithTags(jint tag_count, + const jlong* tags, + jint* count_ptr, + jobject** object_result_ptr, + jlong** tag_result_ptr) { + return functions->GetObjectsWithTags(this, tag_count, tags, count_ptr, object_result_ptr, tag_result_ptr); + } + + jvmtiError ForceGarbageCollection() { + return functions->ForceGarbageCollection(this); + } + + jvmtiError IterateOverObjectsReachableFromObject(jobject object, + jvmtiObjectReferenceCallback object_reference_callback, + const void* user_data) { + return functions->IterateOverObjectsReachableFromObject(this, object, object_reference_callback, user_data); + } + + jvmtiError IterateOverReachableObjects(jvmtiHeapRootCallback heap_root_callback, + jvmtiStackReferenceCallback stack_ref_callback, + jvmtiObjectReferenceCallback object_ref_callback, + const void* user_data) { + return functions->IterateOverReachableObjects(this, heap_root_callback, stack_ref_callback, object_ref_callback, user_data); + } + + jvmtiError IterateOverHeap(jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data) { + return functions->IterateOverHeap(this, object_filter, heap_object_callback, user_data); + } + + jvmtiError IterateOverInstancesOfClass(jclass klass, + jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data) { + return functions->IterateOverInstancesOfClass(this, klass, object_filter, heap_object_callback, user_data); + } + + jvmtiError GetLocalObject(jthread thread, + jint depth, + jint slot, + jobject* value_ptr) { + return functions->GetLocalObject(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalInstance(jthread thread, + jint depth, + jobject* value_ptr) { + return functions->GetLocalInstance(this, thread, depth, value_ptr); + } + + jvmtiError GetLocalInt(jthread thread, + jint depth, + jint slot, + jint* value_ptr) { + return functions->GetLocalInt(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalLong(jthread thread, + jint depth, + jint slot, + jlong* value_ptr) { + return functions->GetLocalLong(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalFloat(jthread thread, + jint depth, + jint slot, + jfloat* value_ptr) { + return functions->GetLocalFloat(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalDouble(jthread thread, + jint depth, + jint slot, + jdouble* value_ptr) { + return functions->GetLocalDouble(this, thread, depth, slot, value_ptr); + } + + jvmtiError SetLocalObject(jthread thread, + jint depth, + jint slot, + jobject value) { + return functions->SetLocalObject(this, thread, depth, slot, value); + } + + jvmtiError SetLocalInt(jthread thread, + jint depth, + jint slot, + jint value) { + return functions->SetLocalInt(this, thread, depth, slot, value); + } + + jvmtiError SetLocalLong(jthread thread, + jint depth, + jint slot, + jlong value) { + return functions->SetLocalLong(this, thread, depth, slot, value); + } + + jvmtiError SetLocalFloat(jthread thread, + jint depth, + jint slot, + jfloat value) { + return functions->SetLocalFloat(this, thread, depth, slot, value); + } + + jvmtiError SetLocalDouble(jthread thread, + jint depth, + jint slot, + jdouble value) { + return functions->SetLocalDouble(this, thread, depth, slot, value); + } + + jvmtiError SetBreakpoint(jmethodID method, + jlocation location) { + return functions->SetBreakpoint(this, method, location); + } + + jvmtiError ClearBreakpoint(jmethodID method, + jlocation location) { + return functions->ClearBreakpoint(this, method, location); + } + + jvmtiError SetFieldAccessWatch(jclass klass, + jfieldID field) { + return functions->SetFieldAccessWatch(this, klass, field); + } + + jvmtiError ClearFieldAccessWatch(jclass klass, + jfieldID field) { + return functions->ClearFieldAccessWatch(this, klass, field); + } + + jvmtiError SetFieldModificationWatch(jclass klass, + jfieldID field) { + return functions->SetFieldModificationWatch(this, klass, field); + } + + jvmtiError ClearFieldModificationWatch(jclass klass, + jfieldID field) { + return functions->ClearFieldModificationWatch(this, klass, field); + } + + jvmtiError GetLoadedClasses(jint* class_count_ptr, + jclass** classes_ptr) { + return functions->GetLoadedClasses(this, class_count_ptr, classes_ptr); + } + + jvmtiError GetClassLoaderClasses(jobject initiating_loader, + jint* class_count_ptr, + jclass** classes_ptr) { + return functions->GetClassLoaderClasses(this, initiating_loader, class_count_ptr, classes_ptr); + } + + jvmtiError GetClassSignature(jclass klass, + char** signature_ptr, + char** generic_ptr) { + return functions->GetClassSignature(this, klass, signature_ptr, generic_ptr); + } + + jvmtiError GetClassStatus(jclass klass, + jint* status_ptr) { + return functions->GetClassStatus(this, klass, status_ptr); + } + + jvmtiError GetSourceFileName(jclass klass, + char** source_name_ptr) { + return functions->GetSourceFileName(this, klass, source_name_ptr); + } + + jvmtiError GetClassModifiers(jclass klass, + jint* modifiers_ptr) { + return functions->GetClassModifiers(this, klass, modifiers_ptr); + } + + jvmtiError GetClassMethods(jclass klass, + jint* method_count_ptr, + jmethodID** methods_ptr) { + return functions->GetClassMethods(this, klass, method_count_ptr, methods_ptr); + } + + jvmtiError GetClassFields(jclass klass, + jint* field_count_ptr, + jfieldID** fields_ptr) { + return functions->GetClassFields(this, klass, field_count_ptr, fields_ptr); + } + + jvmtiError GetImplementedInterfaces(jclass klass, + jint* interface_count_ptr, + jclass** interfaces_ptr) { + return functions->GetImplementedInterfaces(this, klass, interface_count_ptr, interfaces_ptr); + } + + jvmtiError GetClassVersionNumbers(jclass klass, + jint* minor_version_ptr, + jint* major_version_ptr) { + return functions->GetClassVersionNumbers(this, klass, minor_version_ptr, major_version_ptr); + } + + jvmtiError GetConstantPool(jclass klass, + jint* constant_pool_count_ptr, + jint* constant_pool_byte_count_ptr, + unsigned char** constant_pool_bytes_ptr) { + return functions->GetConstantPool(this, klass, constant_pool_count_ptr, constant_pool_byte_count_ptr, constant_pool_bytes_ptr); + } + + jvmtiError IsInterface(jclass klass, + jboolean* is_interface_ptr) { + return functions->IsInterface(this, klass, is_interface_ptr); + } + + jvmtiError IsArrayClass(jclass klass, + jboolean* is_array_class_ptr) { + return functions->IsArrayClass(this, klass, is_array_class_ptr); + } + + jvmtiError IsModifiableClass(jclass klass, + jboolean* is_modifiable_class_ptr) { + return functions->IsModifiableClass(this, klass, is_modifiable_class_ptr); + } + + jvmtiError GetClassLoader(jclass klass, + jobject* classloader_ptr) { + return functions->GetClassLoader(this, klass, classloader_ptr); + } + + jvmtiError GetSourceDebugExtension(jclass klass, + char** source_debug_extension_ptr) { + return functions->GetSourceDebugExtension(this, klass, source_debug_extension_ptr); + } + + jvmtiError RetransformClasses(jint class_count, + const jclass* classes) { + return functions->RetransformClasses(this, class_count, classes); + } + + jvmtiError RedefineClasses(jint class_count, + const jvmtiClassDefinition* class_definitions) { + return functions->RedefineClasses(this, class_count, class_definitions); + } + + jvmtiError GetObjectSize(jobject object, + jlong* size_ptr) { + return functions->GetObjectSize(this, object, size_ptr); + } + + jvmtiError GetObjectHashCode(jobject object, + jint* hash_code_ptr) { + return functions->GetObjectHashCode(this, object, hash_code_ptr); + } + + jvmtiError GetObjectMonitorUsage(jobject object, + jvmtiMonitorUsage* info_ptr) { + return functions->GetObjectMonitorUsage(this, object, info_ptr); + } + + jvmtiError GetFieldName(jclass klass, + jfieldID field, + char** name_ptr, + char** signature_ptr, + char** generic_ptr) { + return functions->GetFieldName(this, klass, field, name_ptr, signature_ptr, generic_ptr); + } + + jvmtiError GetFieldDeclaringClass(jclass klass, + jfieldID field, + jclass* declaring_class_ptr) { + return functions->GetFieldDeclaringClass(this, klass, field, declaring_class_ptr); + } + + jvmtiError GetFieldModifiers(jclass klass, + jfieldID field, + jint* modifiers_ptr) { + return functions->GetFieldModifiers(this, klass, field, modifiers_ptr); + } + + jvmtiError IsFieldSynthetic(jclass klass, + jfieldID field, + jboolean* is_synthetic_ptr) { + return functions->IsFieldSynthetic(this, klass, field, is_synthetic_ptr); + } + + jvmtiError GetMethodName(jmethodID method, + char** name_ptr, + char** signature_ptr, + char** generic_ptr) { + return functions->GetMethodName(this, method, name_ptr, signature_ptr, generic_ptr); + } + + jvmtiError GetMethodDeclaringClass(jmethodID method, + jclass* declaring_class_ptr) { + return functions->GetMethodDeclaringClass(this, method, declaring_class_ptr); + } + + jvmtiError GetMethodModifiers(jmethodID method, + jint* modifiers_ptr) { + return functions->GetMethodModifiers(this, method, modifiers_ptr); + } + + jvmtiError GetMaxLocals(jmethodID method, + jint* max_ptr) { + return functions->GetMaxLocals(this, method, max_ptr); + } + + jvmtiError GetArgumentsSize(jmethodID method, + jint* size_ptr) { + return functions->GetArgumentsSize(this, method, size_ptr); + } + + jvmtiError GetLineNumberTable(jmethodID method, + jint* entry_count_ptr, + jvmtiLineNumberEntry** table_ptr) { + return functions->GetLineNumberTable(this, method, entry_count_ptr, table_ptr); + } + + jvmtiError GetMethodLocation(jmethodID method, + jlocation* start_location_ptr, + jlocation* end_location_ptr) { + return functions->GetMethodLocation(this, method, start_location_ptr, end_location_ptr); + } + + jvmtiError GetLocalVariableTable(jmethodID method, + jint* entry_count_ptr, + jvmtiLocalVariableEntry** table_ptr) { + return functions->GetLocalVariableTable(this, method, entry_count_ptr, table_ptr); + } + + jvmtiError GetBytecodes(jmethodID method, + jint* bytecode_count_ptr, + unsigned char** bytecodes_ptr) { + return functions->GetBytecodes(this, method, bytecode_count_ptr, bytecodes_ptr); + } + + jvmtiError IsMethodNative(jmethodID method, + jboolean* is_native_ptr) { + return functions->IsMethodNative(this, method, is_native_ptr); + } + + jvmtiError IsMethodSynthetic(jmethodID method, + jboolean* is_synthetic_ptr) { + return functions->IsMethodSynthetic(this, method, is_synthetic_ptr); + } + + jvmtiError IsMethodObsolete(jmethodID method, + jboolean* is_obsolete_ptr) { + return functions->IsMethodObsolete(this, method, is_obsolete_ptr); + } + + jvmtiError SetNativeMethodPrefix(const char* prefix) { + return functions->SetNativeMethodPrefix(this, prefix); + } + + jvmtiError SetNativeMethodPrefixes(jint prefix_count, + char** prefixes) { + return functions->SetNativeMethodPrefixes(this, prefix_count, prefixes); + } + + jvmtiError CreateRawMonitor(const char* name, + jrawMonitorID* monitor_ptr) { + return functions->CreateRawMonitor(this, name, monitor_ptr); + } + + jvmtiError DestroyRawMonitor(jrawMonitorID monitor) { + return functions->DestroyRawMonitor(this, monitor); + } + + jvmtiError RawMonitorEnter(jrawMonitorID monitor) { + return functions->RawMonitorEnter(this, monitor); + } + + jvmtiError RawMonitorExit(jrawMonitorID monitor) { + return functions->RawMonitorExit(this, monitor); + } + + jvmtiError RawMonitorWait(jrawMonitorID monitor, + jlong millis) { + return functions->RawMonitorWait(this, monitor, millis); + } + + jvmtiError RawMonitorNotify(jrawMonitorID monitor) { + return functions->RawMonitorNotify(this, monitor); + } + + jvmtiError RawMonitorNotifyAll(jrawMonitorID monitor) { + return functions->RawMonitorNotifyAll(this, monitor); + } + + jvmtiError SetJNIFunctionTable(const jniNativeInterface* function_table) { + return functions->SetJNIFunctionTable(this, function_table); + } + + jvmtiError GetJNIFunctionTable(jniNativeInterface** function_table) { + return functions->GetJNIFunctionTable(this, function_table); + } + + jvmtiError SetEventCallbacks(const jvmtiEventCallbacks* callbacks, + jint size_of_callbacks) { + return functions->SetEventCallbacks(this, callbacks, size_of_callbacks); + } + + jvmtiError SetEventNotificationMode(jvmtiEventMode mode, + jvmtiEvent event_type, + jthread event_thread, + ...) { + return functions->SetEventNotificationMode(this, mode, event_type, event_thread); + } + + jvmtiError GenerateEvents(jvmtiEvent event_type) { + return functions->GenerateEvents(this, event_type); + } + + jvmtiError GetExtensionFunctions(jint* extension_count_ptr, + jvmtiExtensionFunctionInfo** extensions) { + return functions->GetExtensionFunctions(this, extension_count_ptr, extensions); + } + + jvmtiError GetExtensionEvents(jint* extension_count_ptr, + jvmtiExtensionEventInfo** extensions) { + return functions->GetExtensionEvents(this, extension_count_ptr, extensions); + } + + jvmtiError SetExtensionEventCallback(jint extension_event_index, + jvmtiExtensionEvent callback) { + return functions->SetExtensionEventCallback(this, extension_event_index, callback); + } + + jvmtiError GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) { + return functions->GetPotentialCapabilities(this, capabilities_ptr); + } + + jvmtiError AddCapabilities(const jvmtiCapabilities* capabilities_ptr) { + return functions->AddCapabilities(this, capabilities_ptr); + } + + jvmtiError RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) { + return functions->RelinquishCapabilities(this, capabilities_ptr); + } + + jvmtiError GetCapabilities(jvmtiCapabilities* capabilities_ptr) { + return functions->GetCapabilities(this, capabilities_ptr); + } + + jvmtiError GetCurrentThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) { + return functions->GetCurrentThreadCpuTimerInfo(this, info_ptr); + } + + jvmtiError GetCurrentThreadCpuTime(jlong* nanos_ptr) { + return functions->GetCurrentThreadCpuTime(this, nanos_ptr); + } + + jvmtiError GetThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) { + return functions->GetThreadCpuTimerInfo(this, info_ptr); + } + + jvmtiError GetThreadCpuTime(jthread thread, + jlong* nanos_ptr) { + return functions->GetThreadCpuTime(this, thread, nanos_ptr); + } + + jvmtiError GetTimerInfo(jvmtiTimerInfo* info_ptr) { + return functions->GetTimerInfo(this, info_ptr); + } + + jvmtiError GetTime(jlong* nanos_ptr) { + return functions->GetTime(this, nanos_ptr); + } + + jvmtiError GetAvailableProcessors(jint* processor_count_ptr) { + return functions->GetAvailableProcessors(this, processor_count_ptr); + } + + jvmtiError AddToBootstrapClassLoaderSearch(const char* segment) { + return functions->AddToBootstrapClassLoaderSearch(this, segment); + } + + jvmtiError AddToSystemClassLoaderSearch(const char* segment) { + return functions->AddToSystemClassLoaderSearch(this, segment); + } + + jvmtiError GetSystemProperties(jint* count_ptr, + char*** property_ptr) { + return functions->GetSystemProperties(this, count_ptr, property_ptr); + } + + jvmtiError GetSystemProperty(const char* property, + char** value_ptr) { + return functions->GetSystemProperty(this, property, value_ptr); + } + + jvmtiError SetSystemProperty(const char* property, + const char* value) { + return functions->SetSystemProperty(this, property, value); + } + + jvmtiError GetPhase(jvmtiPhase* phase_ptr) { + return functions->GetPhase(this, phase_ptr); + } + + jvmtiError DisposeEnvironment() { + return functions->DisposeEnvironment(this); + } + + jvmtiError SetEnvironmentLocalStorage(const void* data) { + return functions->SetEnvironmentLocalStorage(this, data); + } + + jvmtiError GetEnvironmentLocalStorage(void** data_ptr) { + return functions->GetEnvironmentLocalStorage(this, data_ptr); + } + + jvmtiError GetVersionNumber(jint* version_ptr) { + return functions->GetVersionNumber(this, version_ptr); + } + + jvmtiError GetErrorName(jvmtiError error, + char** name_ptr) { + return functions->GetErrorName(this, error, name_ptr); + } + + jvmtiError SetVerboseFlag(jvmtiVerboseFlag flag, + jboolean value) { + return functions->SetVerboseFlag(this, flag, value); + } + + jvmtiError GetJLocationFormat(jvmtiJlocationFormat* format_ptr) { + return functions->GetJLocationFormat(this, format_ptr); + } + +#endif /* __cplusplus */ +}; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* !_JAVA_JVMTI_H_ */
\ No newline at end of file diff --git a/demos/java/jni/gs_jni/include/jvmticmlr.h b/demos/java/jni/gs_jni/include/jvmticmlr.h new file mode 100644 index 00000000..a9c88f36 --- /dev/null +++ b/demos/java/jni/gs_jni/include/jvmticmlr.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * This header file defines the data structures sent by the VM + * through the JVMTI CompiledMethodLoad callback function via the + * "void * compile_info" parameter. The memory pointed to by the + * compile_info parameter may not be referenced after returning from + * the CompiledMethodLoad callback. These are VM implementation + * specific data structures that may evolve in future releases. A + * JVMTI agent should interpret a non-NULL compile_info as a pointer + * to a region of memory containing a list of records. In a typical + * usage scenario, a JVMTI agent would cast each record to a + * jvmtiCompiledMethodLoadRecordHeader, a struct that represents + * arbitrary information. This struct contains a kind field to indicate + * the kind of information being passed, and a pointer to the next + * record. If the kind field indicates inlining information, then the + * agent would cast the record to a jvmtiCompiledMethodLoadInlineRecord. + * This record contains an array of PCStackInfo structs, which indicate + * for every pc address what are the methods on the invocation stack. + * The "methods" and "bcis" fields in each PCStackInfo struct specify a + * 1-1 mapping between these inlined methods and their bytecode indices. + * This can be used to derive the proper source lines of the inlined + * methods. + */ + +#ifndef _JVMTI_CMLR_H_ +#define _JVMTI_CMLR_H_ + +enum { + JVMTI_CMLR_MAJOR_VERSION_1 = 0x00000001, + JVMTI_CMLR_MINOR_VERSION_0 = 0x00000000, + + JVMTI_CMLR_MAJOR_VERSION = 0x00000001, + JVMTI_CMLR_MINOR_VERSION = 0x00000000 + + /* + * This comment is for the "JDK import from HotSpot" sanity check: + * version: 1.0.0 + */ +}; + +typedef enum { + JVMTI_CMLR_DUMMY = 1, + JVMTI_CMLR_INLINE_INFO = 2 +} jvmtiCMLRKind; + +/* + * Record that represents arbitrary information passed through JVMTI + * CompiledMethodLoadEvent void pointer. + */ +typedef struct _jvmtiCompiledMethodLoadRecordHeader { + jvmtiCMLRKind kind; /* id for the kind of info passed in the record */ + jint majorinfoversion; /* major and minor info version values. Init'ed */ + jint minorinfoversion; /* to current version value in jvmtiExport.cpp. */ + + struct _jvmtiCompiledMethodLoadRecordHeader* next; +} jvmtiCompiledMethodLoadRecordHeader; + +/* + * Record that gives information about the methods on the compile-time + * stack at a specific pc address of a compiled method. Each element in + * the methods array maps to same element in the bcis array. + */ +typedef struct _PCStackInfo { + void* pc; /* the pc address for this compiled method */ + jint numstackframes; /* number of methods on the stack */ + jmethodID* methods; /* array of numstackframes method ids */ + jint* bcis; /* array of numstackframes bytecode indices */ +} PCStackInfo; + +/* + * Record that contains inlining information for each pc address of + * an nmethod. + */ +typedef struct _jvmtiCompiledMethodLoadInlineRecord { + jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */ + jint numpcs; /* number of pc descriptors in this nmethod */ + PCStackInfo* pcinfo; /* array of numpcs pc descriptors */ +} jvmtiCompiledMethodLoadInlineRecord; + +/* + * Dummy record used to test that we can pass records with different + * information through the void pointer provided that they can be cast + * to a jvmtiCompiledMethodLoadRecordHeader. + */ + +typedef struct _jvmtiCompiledMethodLoadDummyRecord { + jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */ + char message[50]; +} jvmtiCompiledMethodLoadDummyRecord; + +#endif diff --git a/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCallbacks.h b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCallbacks.h new file mode 100644 index 00000000..df5035b8 --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCallbacks.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * AccessBridgeCallbacks.h 1.17 05/03/21 + */ + +/* + * Header file defining callback typedefs for Windows routines + * which are called from Java (responding to events, etc.). + */ + +#ifndef __AccessBridgeCallbacks_H__ +#define __AccessBridgeCallbacks_H__ + +#include <jni.h> +#include "AccessBridgePackages.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*AccessBridge_PropertyChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *property, wchar_t *oldValue, wchar_t *newValue); + +typedef void (*AccessBridge_JavaShutdownFP) (long vmID); +typedef void (*AccessBridge_JavaShutdownFP) (long vmID); + +typedef void (*AccessBridge_FocusGainedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_FocusLostFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_CaretUpdateFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_MouseClickedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseEnteredFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseExitedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MousePressedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseReleasedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_MenuCanceledFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MenuDeselectedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MenuSelectedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuCanceledFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuWillBecomeInvisibleFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuWillBecomeVisibleFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_PropertyNameChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldName, wchar_t *newName); +typedef void (*AccessBridge_PropertyDescriptionChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldDescription, wchar_t *newDescription); +typedef void (*AccessBridge_PropertyStateChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldState, wchar_t *newState); +typedef void (*AccessBridge_PropertyValueChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldValue, wchar_t *newValue); +typedef void (*AccessBridge_PropertySelectionChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyTextChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyCaretChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + int oldPosition, int newPosition); +typedef void (*AccessBridge_PropertyVisibleDataChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyChildChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + JOBJECT64 oldChild, JOBJECT64 newChild); +typedef void (*AccessBridge_PropertyActiveDescendentChangeFP) (long vmID, JOBJECT64 event, + JOBJECT64 source, + JOBJECT64 oldActiveDescendent, + JOBJECT64 newActiveDescendent); + +typedef void (*AccessBridge_PropertyTableModelChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 src, + wchar_t *oldValue, wchar_t *newValue); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.c b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.c new file mode 100644 index 00000000..36866481 --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.c @@ -0,0 +1,1131 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * @(#)AccessBridgeCalls.c 1.25 05/08/22 + */ + +/* + * Wrapper functions around calls to the AccessBridge DLL + */ + + +#include <windows.h> +#include <jni.h> + + +//#define ACCESSBRIDGE_32 +//#define ACCESSBRIDGE_64 + +#include "AccessBridgeCalls.h" +#include "AccessBridgeDebug.h" + +#ifdef __cplusplus +extern "C" { +#endif + + HINSTANCE theAccessBridgeInstance; + AccessBridgeFPs theAccessBridge; + + BOOL theAccessBridgeInitializedFlag = FALSE; + +#define LOAD_FP(result, type, name) \ + PrintDebugString("LOAD_FP loading: %s ...", name); \ + if ((theAccessBridge.result = \ + (type) GetProcAddress(theAccessBridgeInstance, name)) == (type) 0) { \ + PrintDebugString("LOAD_FP failed: %s", name); \ + return FALSE; \ + } + + BOOL initializeAccessBridge() { + +#ifdef ACCESSBRIDGE_ARCH_32 // For 32bit AT new bridge + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE-32"); +#else +#ifdef ACCESSBRIDGE_ARCH_64 // For 64bit AT new bridge + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE-64"); +#else // legacy + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE"); +#endif +#endif + if (theAccessBridgeInstance != 0) { + LOAD_FP(Windows_run, Windows_runFP, "Windows_run"); + + LOAD_FP(SetJavaShutdown, SetJavaShutdownFP, "setJavaShutdownFP"); + LOAD_FP(SetFocusGained, SetFocusGainedFP, "setFocusGainedFP"); + LOAD_FP(SetFocusLost, SetFocusLostFP, "setFocusLostFP"); + + LOAD_FP(SetCaretUpdate, SetCaretUpdateFP, "setCaretUpdateFP"); + + LOAD_FP(SetMouseClicked, SetMouseClickedFP, "setMouseClickedFP"); + LOAD_FP(SetMouseEntered, SetMouseEnteredFP, "setMouseEnteredFP"); + LOAD_FP(SetMouseExited, SetMouseExitedFP, "setMouseExitedFP"); + LOAD_FP(SetMousePressed, SetMousePressedFP, "setMousePressedFP"); + LOAD_FP(SetMouseReleased, SetMouseReleasedFP, "setMouseReleasedFP"); + + LOAD_FP(SetMenuCanceled, SetMenuCanceledFP, "setMenuCanceledFP"); + LOAD_FP(SetMenuDeselected, SetMenuDeselectedFP, "setMenuDeselectedFP"); + LOAD_FP(SetMenuSelected, SetMenuSelectedFP, "setMenuSelectedFP"); + LOAD_FP(SetPopupMenuCanceled, SetPopupMenuCanceledFP, "setPopupMenuCanceledFP"); + LOAD_FP(SetPopupMenuWillBecomeInvisible, SetPopupMenuWillBecomeInvisibleFP, "setPopupMenuWillBecomeInvisibleFP"); + LOAD_FP(SetPopupMenuWillBecomeVisible, SetPopupMenuWillBecomeVisibleFP, "setPopupMenuWillBecomeVisibleFP"); + + LOAD_FP(SetPropertyNameChange, SetPropertyNameChangeFP, "setPropertyNameChangeFP"); + LOAD_FP(SetPropertyDescriptionChange, SetPropertyDescriptionChangeFP, "setPropertyDescriptionChangeFP"); + LOAD_FP(SetPropertyStateChange, SetPropertyStateChangeFP, "setPropertyStateChangeFP"); + LOAD_FP(SetPropertyValueChange, SetPropertyValueChangeFP, "setPropertyValueChangeFP"); + LOAD_FP(SetPropertySelectionChange, SetPropertySelectionChangeFP, "setPropertySelectionChangeFP"); + LOAD_FP(SetPropertyTextChange, SetPropertyTextChangeFP, "setPropertyTextChangeFP"); + LOAD_FP(SetPropertyCaretChange, SetPropertyCaretChangeFP, "setPropertyCaretChangeFP"); + LOAD_FP(SetPropertyVisibleDataChange, SetPropertyVisibleDataChangeFP, "setPropertyVisibleDataChangeFP"); + LOAD_FP(SetPropertyChildChange, SetPropertyChildChangeFP, "setPropertyChildChangeFP"); + LOAD_FP(SetPropertyActiveDescendentChange, SetPropertyActiveDescendentChangeFP, "setPropertyActiveDescendentChangeFP"); + + LOAD_FP(SetPropertyTableModelChange, SetPropertyTableModelChangeFP, "setPropertyTableModelChangeFP"); + + LOAD_FP(ReleaseJavaObject, ReleaseJavaObjectFP, "releaseJavaObject"); + LOAD_FP(GetVersionInfo, GetVersionInfoFP, "getVersionInfo"); + + LOAD_FP(IsJavaWindow, IsJavaWindowFP, "isJavaWindow"); + LOAD_FP(IsSameObject, IsSameObjectFP, "isSameObject"); + LOAD_FP(GetAccessibleContextFromHWND, GetAccessibleContextFromHWNDFP, "getAccessibleContextFromHWND"); + LOAD_FP(getHWNDFromAccessibleContext, getHWNDFromAccessibleContextFP, "getHWNDFromAccessibleContext"); + + LOAD_FP(GetAccessibleContextAt, GetAccessibleContextAtFP, "getAccessibleContextAt"); + LOAD_FP(GetAccessibleContextWithFocus, GetAccessibleContextWithFocusFP, "getAccessibleContextWithFocus"); + LOAD_FP(GetAccessibleContextInfo, GetAccessibleContextInfoFP, "getAccessibleContextInfo"); + LOAD_FP(GetAccessibleChildFromContext, GetAccessibleChildFromContextFP, "getAccessibleChildFromContext"); + LOAD_FP(GetAccessibleParentFromContext, GetAccessibleParentFromContextFP, "getAccessibleParentFromContext"); + + /* begin AccessibleTable */ + LOAD_FP(getAccessibleTableInfo, getAccessibleTableInfoFP, "getAccessibleTableInfo"); + LOAD_FP(getAccessibleTableCellInfo, getAccessibleTableCellInfoFP, "getAccessibleTableCellInfo"); + + LOAD_FP(getAccessibleTableRowHeader, getAccessibleTableRowHeaderFP, "getAccessibleTableRowHeader"); + LOAD_FP(getAccessibleTableColumnHeader, getAccessibleTableColumnHeaderFP, "getAccessibleTableColumnHeader"); + + LOAD_FP(getAccessibleTableRowDescription, getAccessibleTableRowDescriptionFP, "getAccessibleTableRowDescription"); + LOAD_FP(getAccessibleTableColumnDescription, getAccessibleTableColumnDescriptionFP, "getAccessibleTableColumnDescription"); + + LOAD_FP(getAccessibleTableRowSelectionCount, getAccessibleTableRowSelectionCountFP, + "getAccessibleTableRowSelectionCount"); + LOAD_FP(isAccessibleTableRowSelected, isAccessibleTableRowSelectedFP, + "isAccessibleTableRowSelected"); + LOAD_FP(getAccessibleTableRowSelections, getAccessibleTableRowSelectionsFP, + "getAccessibleTableRowSelections"); + + LOAD_FP(getAccessibleTableColumnSelectionCount, getAccessibleTableColumnSelectionCountFP, + "getAccessibleTableColumnSelectionCount"); + LOAD_FP(isAccessibleTableColumnSelected, isAccessibleTableColumnSelectedFP, + "isAccessibleTableColumnSelected"); + LOAD_FP(getAccessibleTableColumnSelections, getAccessibleTableColumnSelectionsFP, + "getAccessibleTableColumnSelections"); + + LOAD_FP(getAccessibleTableRow, getAccessibleTableRowFP, + "getAccessibleTableRow"); + LOAD_FP(getAccessibleTableColumn, getAccessibleTableColumnFP, + "getAccessibleTableColumn"); + LOAD_FP(getAccessibleTableIndex, getAccessibleTableIndexFP, + "getAccessibleTableIndex"); + + /* end AccessibleTable */ + + /* AccessibleRelationSet */ + LOAD_FP(getAccessibleRelationSet, getAccessibleRelationSetFP, "getAccessibleRelationSet"); + + /* AccessibleHypertext */ + LOAD_FP(getAccessibleHypertext, getAccessibleHypertextFP, "getAccessibleHypertext"); + LOAD_FP(activateAccessibleHyperlink, activateAccessibleHyperlinkFP, "activateAccessibleHyperlink"); + LOAD_FP(getAccessibleHyperlinkCount, getAccessibleHyperlinkCountFP, "getAccessibleHyperlinkCount"); + LOAD_FP(getAccessibleHypertextExt, getAccessibleHypertextExtFP, "getAccessibleHypertextExt"); + LOAD_FP(getAccessibleHypertextLinkIndex, getAccessibleHypertextLinkIndexFP, "getAccessibleHypertextLinkIndex"); + LOAD_FP(getAccessibleHyperlink, getAccessibleHyperlinkFP, "getAccessibleHyperlink"); + + /* Accessible KeyBinding, Icon and Action */ + LOAD_FP(getAccessibleKeyBindings, getAccessibleKeyBindingsFP, "getAccessibleKeyBindings"); + LOAD_FP(getAccessibleIcons, getAccessibleIconsFP, "getAccessibleIcons"); + LOAD_FP(getAccessibleActions, getAccessibleActionsFP, "getAccessibleActions"); + LOAD_FP(doAccessibleActions, doAccessibleActionsFP, "doAccessibleActions"); + + /* AccessibleText */ + LOAD_FP(GetAccessibleTextInfo, GetAccessibleTextInfoFP, "getAccessibleTextInfo"); + LOAD_FP(GetAccessibleTextItems, GetAccessibleTextItemsFP, "getAccessibleTextItems"); + LOAD_FP(GetAccessibleTextSelectionInfo, GetAccessibleTextSelectionInfoFP, "getAccessibleTextSelectionInfo"); + LOAD_FP(GetAccessibleTextAttributes, GetAccessibleTextAttributesFP, "getAccessibleTextAttributes"); + LOAD_FP(GetAccessibleTextRect, GetAccessibleTextRectFP, "getAccessibleTextRect"); + LOAD_FP(GetAccessibleTextLineBounds, GetAccessibleTextLineBoundsFP, "getAccessibleTextLineBounds"); + LOAD_FP(GetAccessibleTextRange, GetAccessibleTextRangeFP, "getAccessibleTextRange"); + + LOAD_FP(GetCurrentAccessibleValueFromContext, GetCurrentAccessibleValueFromContextFP, "getCurrentAccessibleValueFromContext"); + LOAD_FP(GetMaximumAccessibleValueFromContext, GetMaximumAccessibleValueFromContextFP, "getMaximumAccessibleValueFromContext"); + LOAD_FP(GetMinimumAccessibleValueFromContext, GetMinimumAccessibleValueFromContextFP, "getMinimumAccessibleValueFromContext"); + + LOAD_FP(AddAccessibleSelectionFromContext, AddAccessibleSelectionFromContextFP, "addAccessibleSelectionFromContext"); + LOAD_FP(ClearAccessibleSelectionFromContext, ClearAccessibleSelectionFromContextFP, "clearAccessibleSelectionFromContext"); + LOAD_FP(GetAccessibleSelectionFromContext, GetAccessibleSelectionFromContextFP, "getAccessibleSelectionFromContext"); + LOAD_FP(GetAccessibleSelectionCountFromContext, GetAccessibleSelectionCountFromContextFP, "getAccessibleSelectionCountFromContext"); + LOAD_FP(IsAccessibleChildSelectedFromContext, IsAccessibleChildSelectedFromContextFP, "isAccessibleChildSelectedFromContext"); + LOAD_FP(RemoveAccessibleSelectionFromContext, RemoveAccessibleSelectionFromContextFP, "removeAccessibleSelectionFromContext"); + LOAD_FP(SelectAllAccessibleSelectionFromContext, SelectAllAccessibleSelectionFromContextFP, "selectAllAccessibleSelectionFromContext"); + + LOAD_FP(setTextContents, setTextContentsFP, "setTextContents"); + LOAD_FP(getParentWithRole, getParentWithRoleFP, "getParentWithRole"); + LOAD_FP(getTopLevelObject, getTopLevelObjectFP, "getTopLevelObject"); + LOAD_FP(getParentWithRoleElseRoot, getParentWithRoleElseRootFP, "getParentWithRoleElseRoot"); + LOAD_FP(getObjectDepth, getObjectDepthFP, "getObjectDepth"); + LOAD_FP(getActiveDescendent, getActiveDescendentFP, "getActiveDescendent"); + + // additional methods for Teton + LOAD_FP(getVirtualAccessibleName, getVirtualAccessibleNameFP, "getVirtualAccessibleName"); + LOAD_FP(requestFocus, requestFocusFP, "requestFocus"); + LOAD_FP(selectTextRange, selectTextRangeFP, "selectTextRange"); + LOAD_FP(getTextAttributesInRange, getTextAttributesInRangeFP, "getTextAttributesInRange"); + LOAD_FP(getVisibleChildrenCount, getVisibleChildrenCountFP, "getVisibleChildrenCount"); + LOAD_FP(getVisibleChildren, getVisibleChildrenFP, "getVisibleChildren"); + LOAD_FP(setCaretPosition, setCaretPositionFP, "setCaretPosition"); + LOAD_FP(getCaretLocation, getCaretLocationFP, "getCaretLocation"); + + LOAD_FP(getEventsWaiting, getEventsWaitingFP, "getEventsWaiting"); + + theAccessBridge.Windows_run(); + + theAccessBridgeInitializedFlag = TRUE; + PrintDebugString("theAccessBridgeInitializedFlag = TRUE"); + return TRUE; + } else { + return FALSE; + } + } + + + BOOL shutdownAccessBridge() { + BOOL result; + DWORD error; + theAccessBridgeInitializedFlag = FALSE; + if (theAccessBridgeInstance != (HANDLE) 0) { + result = FreeLibrary(theAccessBridgeInstance); + if (result != TRUE) { + error = GetLastError(); + } + return TRUE; + } + return FALSE; + } + + + void SetJavaShutdown(AccessBridge_JavaShutdownFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetJavaShutdown(fp); + } + } + + void SetFocusGained(AccessBridge_FocusGainedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetFocusGained(fp); + } + } + + void SetFocusLost(AccessBridge_FocusLostFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetFocusLost(fp); + } + } + + + void SetCaretUpdate(AccessBridge_CaretUpdateFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetCaretUpdate(fp); + } + } + + + void SetMouseClicked(AccessBridge_MouseClickedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseClicked(fp); + } + } + + void SetMouseEntered(AccessBridge_MouseEnteredFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseEntered(fp); + } + } + + void SetMouseExited(AccessBridge_MouseExitedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseExited(fp); + } + } + + void SetMousePressed(AccessBridge_MousePressedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMousePressed(fp); + } + } + + void SetMouseReleased(AccessBridge_MouseReleasedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseReleased(fp); + } + } + + + void SetMenuCanceled(AccessBridge_MenuCanceledFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuCanceled(fp); + } + } + + void SetMenuDeselected(AccessBridge_MenuDeselectedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuDeselected(fp); + } + } + + void SetMenuSelected(AccessBridge_MenuSelectedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuSelected(fp); + } + } + + void SetPopupMenuCanceled(AccessBridge_PopupMenuCanceledFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuCanceled(fp); + } + } + + void SetPopupMenuWillBecomeInvisible(AccessBridge_PopupMenuWillBecomeInvisibleFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuWillBecomeInvisible(fp); + } + } + + void SetPopupMenuWillBecomeVisible(AccessBridge_PopupMenuWillBecomeVisibleFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuWillBecomeVisible(fp); + } + } + + + void SetPropertyNameChange(AccessBridge_PropertyNameChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyNameChange(fp); + } + } + + void SetPropertyDescriptionChange(AccessBridge_PropertyDescriptionChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyDescriptionChange(fp); + } + } + + void SetPropertyStateChange(AccessBridge_PropertyStateChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyStateChange(fp); + } + } + + void SetPropertyValueChange(AccessBridge_PropertyValueChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyValueChange(fp); + } + } + + void SetPropertySelectionChange(AccessBridge_PropertySelectionChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertySelectionChange(fp); + } + } + + void SetPropertyTextChange(AccessBridge_PropertyTextChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyTextChange(fp); + } + } + + void SetPropertyCaretChange(AccessBridge_PropertyCaretChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyCaretChange(fp); + } + } + + void SetPropertyVisibleDataChange(AccessBridge_PropertyVisibleDataChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyVisibleDataChange(fp); + } + } + + void SetPropertyChildChange(AccessBridge_PropertyChildChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyChildChange(fp); + } + } + + void SetPropertyActiveDescendentChange(AccessBridge_PropertyActiveDescendentChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyActiveDescendentChange(fp); + } + } + + void SetPropertyTableModelChange(AccessBridge_PropertyTableModelChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyTableModelChange(fp); + } + } + + /** + * General routines + */ + void ReleaseJavaObject(long vmID, Java_Object object) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.ReleaseJavaObject(vmID, object); + } + } + + BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetVersionInfo(vmID, info); + } + return FALSE; + } + + + /** + * Window routines + */ + BOOL IsJavaWindow(HWND window) { + if (theAccessBridgeInitializedFlag == TRUE) { + BOOL ret ; + ret = theAccessBridge.IsJavaWindow(window); + return ret ; + + } + return FALSE; + } + + + /** + * Returns the virtual machine ID and AccessibleContext for a top-level window + */ + BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextFromHWND(target, vmID, ac); + } + return FALSE; + } + + /** + * Returns the HWND from the AccessibleContext of a top-level window. Returns 0 + * on error or if the AccessibleContext does not refer to a top-level window. + */ + HWND getHWNDFromAccessibleContext(long vmID, JOBJECT64 accesibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getHWNDFromAccessibleContext(vmID, accesibleContext); + } + return (HWND)0; + } + + /** + * returns whether two objects are the same + */ + BOOL IsSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.IsSameObject(vmID, obj1, obj2); + } + return FALSE; + } + + /** + * Sets editable text contents. The AccessibleContext must implement AccessibleEditableText and + * be editable. The maximum text length is MAX_STRING_SIZE - 1. + * Returns whether successful + */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.setTextContents(vmID, accessibleContext, text); + } + return FALSE; + } + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h + * If there is no ancestor object that has the specified role, + * returns (AccessibleContext)0. + */ + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getParentWithRole(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h. If an object with the specified + * role does not exist, returns the top level object for the Java Window. + * Returns (AccessibleContext)0 on error. + */ + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getParentWithRoleElseRoot(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getTopLevelObject(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getObjectDepth(vmID, accessibleContext); + } + return -1; + } + + /** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * This method assumes the ActiveDescendent is the component that is currently + * selected in a container object. + * Returns (AccessibleContext)0 on error or if there is no selection. + */ + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getActiveDescendent(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + + /** + * Accessible Context routines + */ + BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextAt(vmID, acParent, x, y, ac); + } + return FALSE; + } + + BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextWithFocus(window, vmID, ac); + } + return FALSE; + } + + BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextInfo(vmID, ac, info); + } + return FALSE; + } + + AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleChildFromContext(vmID, ac, index); + } + return (AccessibleContext) 0; + } + + AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleParentFromContext(vmID, ac); + } + return (AccessibleContext) 0; + } + + /* begin AccessibleTable routines */ + + /* + * get information about an AccessibleTable + */ + BOOL getAccessibleTableInfo(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableInfo(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable cell + */ + BOOL getAccessibleTableCellInfo(long vmID, AccessibleTable accessibleTable, + jint row, jint column, AccessibleTableCellInfo *tableCellInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableCellInfo(vmID, accessibleTable, row, column, tableCellInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable row header + */ + BOOL getAccessibleTableRowHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowHeader(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable column header + */ + BOOL getAccessibleTableColumnHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnHeader(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * return a description of an AccessibleTable row header + */ + AccessibleContext getAccessibleTableRowDescription(long vmID, AccessibleContext acParent, jint row) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowDescription(vmID, acParent, row); + } + return (AccessibleContext)0; + } + + /* + * return a description of an AccessibleTable column header + */ + AccessibleContext getAccessibleTableColumnDescription(long vmID, AccessibleContext acParent, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnDescription(vmID, acParent, column); + } + return (AccessibleContext)0; + } + + /* + * return the number of rows selected in an AccessibleTable + */ + jint getAccessibleTableRowSelectionCount(long vmID, AccessibleTable table) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowSelectionCount(vmID, table); + } + return -1; + } + + /* + * return whether a row is selected in an AccessibleTable + */ + BOOL isAccessibleTableRowSelected(long vmID, AccessibleTable table, jint row) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.isAccessibleTableRowSelected(vmID, table, row); + } + return FALSE; + } + + /* + * get an array of selected rows in an AccessibleTable + */ + BOOL getAccessibleTableRowSelections(long vmID, AccessibleTable table, jint count, jint *selections) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowSelections(vmID, table, count, selections); + } + return FALSE; + } + + /* + * return the number of columns selected in an AccessibleTable + */ + jint getAccessibleTableColumnSelectionCount(long vmID, AccessibleTable table) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnSelectionCount(vmID, table); + } + return -1; + } + + /* + * return whether a column is selected in an AccessibleTable + */ + BOOL isAccessibleTableColumnSelected(long vmID, AccessibleTable table, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.isAccessibleTableColumnSelected(vmID, table, column); + } + return FALSE; + } + + /* + * get an array of columns selected in an AccessibleTable + */ + BOOL getAccessibleTableColumnSelections(long vmID, AccessibleTable table, jint count, jint *selections) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnSelections(vmID, table, count, selections); + } + return FALSE; + } + + /* + * return the row number for a cell at a given index + */ + jint + getAccessibleTableRow(long vmID, AccessibleTable table, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRow(vmID, table, index); + } + return -1; + } + + /* + * return the column number for a cell at a given index + */ + jint + getAccessibleTableColumn(long vmID, AccessibleTable table, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumn(vmID, table, index); + } + return -1; + } + + /* + * return the index of a cell at a given row and column + */ + jint + getAccessibleTableIndex(long vmID, AccessibleTable table, jint row, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableIndex(vmID, table, row, column); + } + return -1; + } + + /* end AccessibleTable routines */ + + + /** + * Accessible Text routines + */ + BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextInfo(vmID, at, textInfo, x, y); + } + return FALSE; + } + + BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextItems(vmID, at, textItems, index); + } + return FALSE; + } + + BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextSelectionInfo(vmID, at, textSelection); + } + return FALSE; + } + + BOOL GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextAttributes(vmID, at, index, attributes); + } + return FALSE; + } + + BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextRect(vmID, at, rectInfo, index); + } + return FALSE; + } + + BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextLineBounds(vmID, at, index, startIndex, endIndex); + } + return FALSE; + } + + BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextRange(vmID, at, start, end, text, len); + } + return FALSE; + } + + /** + * AccessibleRelationSet routines + */ + BOOL getAccessibleRelationSet(long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleRelationSet(vmID, accessibleContext, relationSetInfo); + } + return FALSE; + } + + /** + * AccessibleHypertext routines + */ + + // Gets AccessibleHypertext for an AccessibleContext + BOOL getAccessibleHypertext(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertext(vmID, accessibleContext, hypertextInfo); + } + return FALSE; + } + + // Activates an AccessibleHyperlink for an AccessibleContext + BOOL activateAccessibleHyperlink(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.activateAccessibleHyperlink(vmID, accessibleContext, accessibleHyperlink); + } + return FALSE; + } + + /* + * Returns the number of hyperlinks in a component + * Maps to AccessibleHypertext.getLinkCount. + * Returns -1 on error. + */ + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHyperlinkCount(vmID, accessibleContext); + } + return -1; + } + + /* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * returns FALSE on error. + */ + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertextExt(vmID, + accessibleContext, + nStartIndex, + hypertextInfo); + } + return FALSE; + } + + /* + * Returns the index into an array of hyperlinks that is associated with + * a character index in document; + * Maps to AccessibleHypertext.getLinkIndex. + * Returns -1 on error. + */ + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertextLinkIndex(vmID, + hypertext, + nIndex); + } + return -1; + } + + /* + * Returns the nth hyperlink in a document. + * Maps to AccessibleHypertext.getLink. + * Returns -1 on error + */ + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHyperlink(vmID, + hypertext, + nIndex, + hyperlinkInfo); + } + return FALSE; + } + + + /* Accessible KeyBindings, Icons and Actions */ + BOOL getAccessibleKeyBindings(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleKeyBindings(vmID, accessibleContext, keyBindings); + } + return FALSE; + } + + BOOL getAccessibleIcons(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleIcons(vmID, accessibleContext, icons); + } + return FALSE; + } + + BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleActions(vmID, accessibleContext, actions); + } + return FALSE; + } + + BOOL doAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.doAccessibleActions(vmID, accessibleContext, actionsToDo, failure); + } + return FALSE; + } + + /** + * Accessible Value routines + */ + BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetCurrentAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetMaximumAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetMinimumAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + + /** + * Accessible Selection routines + */ + void addAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.AddAccessibleSelectionFromContext(vmID, as, i); + } + } + + void clearAccessibleSelectionFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.ClearAccessibleSelectionFromContext(vmID, as); + } + } + + JOBJECT64 GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleSelectionFromContext(vmID, as, i); + } + return (JOBJECT64) 0; + } + + int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleSelectionCountFromContext(vmID, as); + } + return -1; + } + + BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.IsAccessibleChildSelectedFromContext(vmID, as, i); + } + return FALSE; + } + + void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.RemoveAccessibleSelectionFromContext(vmID, as, i); + } + } + + void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SelectAllAccessibleSelectionFromContext(vmID, as); + } + } + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVirtualAccessibleName(vmID, accessibleContext, name, len); + } + return FALSE; + } + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(const long vmID, const AccessibleContext accessibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.requestFocus(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.selectTextRange(vmID, accessibleContext, startIndex, endIndex); + } + return FALSE; + } + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getTextAttributesInRange(vmID, accessibleContext, startIndex, + endIndex, attributes, len); + } + return FALSE; + } + + /** + * Returns the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVisibleChildrenCount(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, VisibleChildrenInfo *visibleChildrenInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVisibleChildren(vmID, accessibleContext, startIndex, + visibleChildrenInfo); + } + return FALSE; + } + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const long vmID, const AccessibleContext accessibleContext, + const int position) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.setCaretPosition(vmID, accessibleContext, position); + } + return FALSE; + } + + /** + * Gets the text caret location + */ + BOOL getCaretLocation(long vmID, AccessibleContext ac, AccessibleTextRectInfo *rectInfo, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getCaretLocation(vmID, ac, rectInfo, index); + } + return FALSE; + } + + /** + * Gets the number of events waiting to fire + */ + int getEventsWaiting() { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getEventsWaiting(); + } + return FALSE; + } + +#ifdef __cplusplus +} +#endif diff --git a/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.h b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.h new file mode 100644 index 00000000..ad007400 --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.h @@ -0,0 +1,706 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * Wrapper functions around calls to the AccessBridge DLL + */ + +#include <windows.h> +#include <jni.h> +#include "AccessBridgeCallbacks.h" +#include "AccessBridgePackages.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define null NULL + + typedef JOBJECT64 AccessibleContext; + typedef JOBJECT64 AccessibleText; + typedef JOBJECT64 AccessibleValue; + typedef JOBJECT64 AccessibleSelection; + typedef JOBJECT64 Java_Object; + typedef JOBJECT64 PropertyChangeEvent; + typedef JOBJECT64 FocusEvent; + typedef JOBJECT64 CaretEvent; + typedef JOBJECT64 MouseEvent; + typedef JOBJECT64 MenuEvent; + typedef JOBJECT64 AccessibleTable; + typedef JOBJECT64 AccessibleHyperlink; + typedef JOBJECT64 AccessibleHypertext; + + + typedef void (*Windows_runFP) (); + + typedef void (*SetPropertyChangeFP) (AccessBridge_PropertyChangeFP fp); + + typedef void (*SetJavaShutdownFP) (AccessBridge_JavaShutdownFP fp); + typedef void (*SetFocusGainedFP) (AccessBridge_FocusGainedFP fp); + typedef void (*SetFocusLostFP) (AccessBridge_FocusLostFP fp); + + typedef void (*SetCaretUpdateFP) (AccessBridge_CaretUpdateFP fp); + + typedef void (*SetMouseClickedFP) (AccessBridge_MouseClickedFP fp); + typedef void (*SetMouseEnteredFP) (AccessBridge_MouseEnteredFP fp); + typedef void (*SetMouseExitedFP) (AccessBridge_MouseExitedFP fp); + typedef void (*SetMousePressedFP) (AccessBridge_MousePressedFP fp); + typedef void (*SetMouseReleasedFP) (AccessBridge_MouseReleasedFP fp); + + typedef void (*SetMenuCanceledFP) (AccessBridge_MenuCanceledFP fp); + typedef void (*SetMenuDeselectedFP) (AccessBridge_MenuDeselectedFP fp); + typedef void (*SetMenuSelectedFP) (AccessBridge_MenuSelectedFP fp); + typedef void (*SetPopupMenuCanceledFP) (AccessBridge_PopupMenuCanceledFP fp); + typedef void (*SetPopupMenuWillBecomeInvisibleFP) (AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + typedef void (*SetPopupMenuWillBecomeVisibleFP) (AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + typedef void (*SetPropertyNameChangeFP) (AccessBridge_PropertyNameChangeFP fp); + typedef void (*SetPropertyDescriptionChangeFP) (AccessBridge_PropertyDescriptionChangeFP fp); + typedef void (*SetPropertyStateChangeFP) (AccessBridge_PropertyStateChangeFP fp); + typedef void (*SetPropertyValueChangeFP) (AccessBridge_PropertyValueChangeFP fp); + typedef void (*SetPropertySelectionChangeFP) (AccessBridge_PropertySelectionChangeFP fp); + typedef void (*SetPropertyTextChangeFP) (AccessBridge_PropertyTextChangeFP fp); + typedef void (*SetPropertyCaretChangeFP) (AccessBridge_PropertyCaretChangeFP fp); + typedef void (*SetPropertyVisibleDataChangeFP) (AccessBridge_PropertyVisibleDataChangeFP fp); + typedef void (*SetPropertyChildChangeFP) (AccessBridge_PropertyChildChangeFP fp); + typedef void (*SetPropertyActiveDescendentChangeFP) (AccessBridge_PropertyActiveDescendentChangeFP fp); + + typedef void (*SetPropertyTableModelChangeFP) (AccessBridge_PropertyTableModelChangeFP fp); + + typedef void (*ReleaseJavaObjectFP) (long vmID, Java_Object object); + + typedef BOOL (*GetVersionInfoFP) (long vmID, AccessBridgeVersionInfo *info); + + typedef BOOL (*IsJavaWindowFP) (HWND window); + typedef BOOL (*IsSameObjectFP) (long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + typedef BOOL (*GetAccessibleContextFromHWNDFP) (HWND window, long *vmID, AccessibleContext *ac); + typedef HWND (*getHWNDFromAccessibleContextFP) (long vmID, AccessibleContext ac); + + typedef BOOL (*GetAccessibleContextAtFP) (long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac); + typedef BOOL (*GetAccessibleContextWithFocusFP) (HWND window, long *vmID, AccessibleContext *ac); + typedef BOOL (*GetAccessibleContextInfoFP) (long vmID, AccessibleContext ac, AccessibleContextInfo *info); + typedef AccessibleContext (*GetAccessibleChildFromContextFP) (long vmID, AccessibleContext ac, jint i); + typedef AccessibleContext (*GetAccessibleParentFromContextFP) (long vmID, AccessibleContext ac); + + /* begin AccessibleTable */ + typedef BOOL (*getAccessibleTableInfoFP) (long vmID, AccessibleContext ac, AccessibleTableInfo *tableInfo); + typedef BOOL (*getAccessibleTableCellInfoFP) (long vmID, AccessibleTable accessibleTable, + jint row, jint column, AccessibleTableCellInfo *tableCellInfo); + + typedef BOOL (*getAccessibleTableRowHeaderFP) (long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + typedef BOOL (*getAccessibleTableColumnHeaderFP) (long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + typedef AccessibleContext (*getAccessibleTableRowDescriptionFP) (long vmID, AccessibleContext acParent, jint row); + typedef AccessibleContext (*getAccessibleTableColumnDescriptionFP) (long vmID, AccessibleContext acParent, jint column); + + typedef jint (*getAccessibleTableRowSelectionCountFP) (long vmID, AccessibleTable table); + typedef BOOL (*isAccessibleTableRowSelectedFP) (long vmID, AccessibleTable table, jint row); + typedef BOOL (*getAccessibleTableRowSelectionsFP) (long vmID, AccessibleTable table, jint count, + jint *selections); + + typedef jint (*getAccessibleTableColumnSelectionCountFP) (long vmID, AccessibleTable table); + typedef BOOL (*isAccessibleTableColumnSelectedFP) (long vmID, AccessibleTable table, jint column); + typedef BOOL (*getAccessibleTableColumnSelectionsFP) (long vmID, AccessibleTable table, jint count, + jint *selections); + + typedef jint (*getAccessibleTableRowFP) (long vmID, AccessibleTable table, jint index); + typedef jint (*getAccessibleTableColumnFP) (long vmID, AccessibleTable table, jint index); + typedef jint (*getAccessibleTableIndexFP) (long vmID, AccessibleTable table, jint row, jint column); + /* end AccessibleTable */ + + /* AccessibleRelationSet */ + typedef BOOL (*getAccessibleRelationSetFP) (long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo); + + /* AccessibleHypertext */ + typedef BOOL (*getAccessibleHypertextFP)(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo); + + typedef BOOL (*activateAccessibleHyperlinkFP)(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink); + + typedef jint (*getAccessibleHyperlinkCountFP)(const long vmID, + const AccessibleContext accessibleContext); + + typedef BOOL (*getAccessibleHypertextExtFP) (const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + AccessibleHypertextInfo *hypertextInfo); + + typedef jint (*getAccessibleHypertextLinkIndexFP)(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + typedef BOOL (*getAccessibleHyperlinkFP)(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + AccessibleHyperlinkInfo *hyperlinkInfo); + + + /* Accessible KeyBindings, Icons and Actions */ + typedef BOOL (*getAccessibleKeyBindingsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings); + + typedef BOOL (*getAccessibleIconsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons); + + typedef BOOL (*getAccessibleActionsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions); + + typedef BOOL (*doAccessibleActionsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + + /* AccessibleText */ + + typedef BOOL (*GetAccessibleTextInfoFP) (long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y); + typedef BOOL (*GetAccessibleTextItemsFP) (long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index); + typedef BOOL (*GetAccessibleTextSelectionInfoFP) (long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection); + typedef BOOL (*GetAccessibleTextAttributesFP) (long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes); + typedef BOOL (*GetAccessibleTextRectFP) (long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index); + typedef BOOL (*GetAccessibleTextLineBoundsFP) (long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex); + typedef BOOL (*GetAccessibleTextRangeFP) (long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len); + + typedef BOOL (*GetCurrentAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + typedef BOOL (*GetMaximumAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + typedef BOOL (*GetMinimumAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + + typedef void (*AddAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*ClearAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as); + typedef JOBJECT64 (*GetAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef int (*GetAccessibleSelectionCountFromContextFP) (long vmID, AccessibleSelection as); + typedef BOOL (*IsAccessibleChildSelectedFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*RemoveAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*SelectAllAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as); + + /* Utility methods */ + + typedef BOOL (*setTextContentsFP) (const long vmID, const AccessibleContext ac, const wchar_t *text); + typedef AccessibleContext (*getParentWithRoleFP) (const long vmID, const AccessibleContext ac, const wchar_t *role); + typedef AccessibleContext (*getParentWithRoleElseRootFP) (const long vmID, const AccessibleContext ac, const wchar_t *role); + typedef AccessibleContext (*getTopLevelObjectFP) (const long vmID, const AccessibleContext ac); + typedef int (*getObjectDepthFP) (const long vmID, const AccessibleContext ac); + typedef AccessibleContext (*getActiveDescendentFP) (const long vmID, const AccessibleContext ac); + + + typedef BOOL (*getVirtualAccessibleNameFP) (const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len); + + typedef BOOL (*requestFocusFP) (const long vmID, const AccessibleContext accessibleContext); + + typedef BOOL (*selectTextRangeFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex); + + typedef BOOL (*getTextAttributesInRangeFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + typedef int (*getVisibleChildrenCountFP) (const long vmID, const AccessibleContext accessibleContext); + + typedef BOOL (*getVisibleChildrenFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, VisibleChildrenInfo *children); + + typedef BOOL (*setCaretPositionFP) (const long vmID, const AccessibleContext accessibleContext, const int position); + + typedef BOOL (*getCaretLocationFP) (long vmID, AccessibleContext ac, AccessibleTextRectInfo *rectInfo, jint index); + + typedef int (*getEventsWaitingFP) (); + + typedef struct AccessBridgeFPsTag { + Windows_runFP Windows_run; + + SetPropertyChangeFP SetPropertyChange; + + SetJavaShutdownFP SetJavaShutdown; + SetFocusGainedFP SetFocusGained; + SetFocusLostFP SetFocusLost; + + SetCaretUpdateFP SetCaretUpdate; + + SetMouseClickedFP SetMouseClicked; + SetMouseEnteredFP SetMouseEntered; + SetMouseExitedFP SetMouseExited; + SetMousePressedFP SetMousePressed; + SetMouseReleasedFP SetMouseReleased; + + SetMenuCanceledFP SetMenuCanceled; + SetMenuDeselectedFP SetMenuDeselected; + SetMenuSelectedFP SetMenuSelected; + SetPopupMenuCanceledFP SetPopupMenuCanceled; + SetPopupMenuWillBecomeInvisibleFP SetPopupMenuWillBecomeInvisible; + SetPopupMenuWillBecomeVisibleFP SetPopupMenuWillBecomeVisible; + + SetPropertyNameChangeFP SetPropertyNameChange; + SetPropertyDescriptionChangeFP SetPropertyDescriptionChange; + SetPropertyStateChangeFP SetPropertyStateChange; + SetPropertyValueChangeFP SetPropertyValueChange; + SetPropertySelectionChangeFP SetPropertySelectionChange; + SetPropertyTextChangeFP SetPropertyTextChange; + SetPropertyCaretChangeFP SetPropertyCaretChange; + SetPropertyVisibleDataChangeFP SetPropertyVisibleDataChange; + SetPropertyChildChangeFP SetPropertyChildChange; + SetPropertyActiveDescendentChangeFP SetPropertyActiveDescendentChange; + + SetPropertyTableModelChangeFP SetPropertyTableModelChange; + + ReleaseJavaObjectFP ReleaseJavaObject; + GetVersionInfoFP GetVersionInfo; + + IsJavaWindowFP IsJavaWindow; + IsSameObjectFP IsSameObject; + GetAccessibleContextFromHWNDFP GetAccessibleContextFromHWND; + getHWNDFromAccessibleContextFP getHWNDFromAccessibleContext; + + GetAccessibleContextAtFP GetAccessibleContextAt; + GetAccessibleContextWithFocusFP GetAccessibleContextWithFocus; + GetAccessibleContextInfoFP GetAccessibleContextInfo; + GetAccessibleChildFromContextFP GetAccessibleChildFromContext; + GetAccessibleParentFromContextFP GetAccessibleParentFromContext; + + getAccessibleTableInfoFP getAccessibleTableInfo; + getAccessibleTableCellInfoFP getAccessibleTableCellInfo; + + getAccessibleTableRowHeaderFP getAccessibleTableRowHeader; + getAccessibleTableColumnHeaderFP getAccessibleTableColumnHeader; + + getAccessibleTableRowDescriptionFP getAccessibleTableRowDescription; + getAccessibleTableColumnDescriptionFP getAccessibleTableColumnDescription; + + getAccessibleTableRowSelectionCountFP getAccessibleTableRowSelectionCount; + isAccessibleTableRowSelectedFP isAccessibleTableRowSelected; + getAccessibleTableRowSelectionsFP getAccessibleTableRowSelections; + + getAccessibleTableColumnSelectionCountFP getAccessibleTableColumnSelectionCount; + isAccessibleTableColumnSelectedFP isAccessibleTableColumnSelected; + getAccessibleTableColumnSelectionsFP getAccessibleTableColumnSelections; + + getAccessibleTableRowFP getAccessibleTableRow; + getAccessibleTableColumnFP getAccessibleTableColumn; + getAccessibleTableIndexFP getAccessibleTableIndex; + + getAccessibleRelationSetFP getAccessibleRelationSet; + + getAccessibleHypertextFP getAccessibleHypertext; + activateAccessibleHyperlinkFP activateAccessibleHyperlink; + getAccessibleHyperlinkCountFP getAccessibleHyperlinkCount; + getAccessibleHypertextExtFP getAccessibleHypertextExt; + getAccessibleHypertextLinkIndexFP getAccessibleHypertextLinkIndex; + getAccessibleHyperlinkFP getAccessibleHyperlink; + + getAccessibleKeyBindingsFP getAccessibleKeyBindings; + getAccessibleIconsFP getAccessibleIcons; + getAccessibleActionsFP getAccessibleActions; + doAccessibleActionsFP doAccessibleActions; + + GetAccessibleTextInfoFP GetAccessibleTextInfo; + GetAccessibleTextItemsFP GetAccessibleTextItems; + GetAccessibleTextSelectionInfoFP GetAccessibleTextSelectionInfo; + GetAccessibleTextAttributesFP GetAccessibleTextAttributes; + GetAccessibleTextRectFP GetAccessibleTextRect; + GetAccessibleTextLineBoundsFP GetAccessibleTextLineBounds; + GetAccessibleTextRangeFP GetAccessibleTextRange; + + GetCurrentAccessibleValueFromContextFP GetCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextFP GetMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextFP GetMinimumAccessibleValueFromContext; + + AddAccessibleSelectionFromContextFP AddAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextFP ClearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextFP GetAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextFP GetAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextFP IsAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextFP RemoveAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextFP SelectAllAccessibleSelectionFromContext; + + setTextContentsFP setTextContents; + getParentWithRoleFP getParentWithRole; + getTopLevelObjectFP getTopLevelObject; + getParentWithRoleElseRootFP getParentWithRoleElseRoot; + getObjectDepthFP getObjectDepth; + getActiveDescendentFP getActiveDescendent; + + getVirtualAccessibleNameFP getVirtualAccessibleName; + requestFocusFP requestFocus; + selectTextRangeFP selectTextRange; + getTextAttributesInRangeFP getTextAttributesInRange; + getVisibleChildrenCountFP getVisibleChildrenCount; + getVisibleChildrenFP getVisibleChildren; + setCaretPositionFP setCaretPosition; + getCaretLocationFP getCaretLocation; + + getEventsWaitingFP getEventsWaiting; + + } AccessBridgeFPs; + + + /** + * Initialize the world + */ + BOOL initializeAccessBridge(); + BOOL shutdownAccessBridge(); + + /** + * Window routines + */ + BOOL IsJavaWindow(HWND window); + + // Returns the virtual machine ID and AccessibleContext for a top-level window + BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac); + + // Returns the HWND from the AccessibleContext of a top-level window + HWND getHWNDFromAccessibleContext(long vmID, AccessibleContext ac); + + + /** + * Event handling routines + */ + void SetJavaShutdown(AccessBridge_JavaShutdownFP fp); + void SetFocusGained(AccessBridge_FocusGainedFP fp); + void SetFocusLost(AccessBridge_FocusLostFP fp); + + void SetCaretUpdate(AccessBridge_CaretUpdateFP fp); + + void SetMouseClicked(AccessBridge_MouseClickedFP fp); + void SetMouseEntered(AccessBridge_MouseEnteredFP fp); + void SetMouseExited(AccessBridge_MouseExitedFP fp); + void SetMousePressed(AccessBridge_MousePressedFP fp); + void SetMouseReleased(AccessBridge_MouseReleasedFP fp); + + void SetMenuCanceled(AccessBridge_MenuCanceledFP fp); + void SetMenuDeselected(AccessBridge_MenuDeselectedFP fp); + void SetMenuSelected(AccessBridge_MenuSelectedFP fp); + void SetPopupMenuCanceled(AccessBridge_PopupMenuCanceledFP fp); + void SetPopupMenuWillBecomeInvisible(AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + void SetPopupMenuWillBecomeVisible(AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + void SetPropertyNameChange(AccessBridge_PropertyNameChangeFP fp); + void SetPropertyDescriptionChange(AccessBridge_PropertyDescriptionChangeFP fp); + void SetPropertyStateChange(AccessBridge_PropertyStateChangeFP fp); + void SetPropertyValueChange(AccessBridge_PropertyValueChangeFP fp); + void SetPropertySelectionChange(AccessBridge_PropertySelectionChangeFP fp); + void SetPropertyTextChange(AccessBridge_PropertyTextChangeFP fp); + void SetPropertyCaretChange(AccessBridge_PropertyCaretChangeFP fp); + void SetPropertyVisibleDataChange(AccessBridge_PropertyVisibleDataChangeFP fp); + void SetPropertyChildChange(AccessBridge_PropertyChildChangeFP fp); + void SetPropertyActiveDescendentChange(AccessBridge_PropertyActiveDescendentChangeFP fp); + + void SetPropertyTableModelChange(AccessBridge_PropertyTableModelChangeFP fp); + + + /** + * General routines + */ + void ReleaseJavaObject(long vmID, Java_Object object); + BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info); + HWND GetHWNDFromAccessibleContext(long vmID, JOBJECT64 accesibleContext); + + /** + * Accessible Context routines + */ + BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac); + BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac); + BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info); + AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index); + AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac); + + /** + * Accessible Text routines + */ + BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y); + BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index); + BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection); + BOOL GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes); + BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index); + BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex); + BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len); + + /* begin AccessibleTable routines */ + BOOL getAccessibleTableInfo(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + BOOL getAccessibleTableCellInfo(long vmID, AccessibleTable accessibleTable, jint row, jint column, + AccessibleTableCellInfo *tableCellInfo); + + BOOL getAccessibleTableRowHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableColumnHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + AccessibleContext getAccessibleTableRowDescription(long vmID, AccessibleContext acParent, jint row); + AccessibleContext getAccessibleTableColumnDescription(long vmID, AccessibleContext acParent, jint column); + + jint getAccessibleTableRowSelectionCount(long vmID, AccessibleTable table); + BOOL isAccessibleTableRowSelected(long vmID, AccessibleTable table, jint row); + BOOL getAccessibleTableRowSelections(long vmID, AccessibleTable table, jint count, jint *selections); + + jint getAccessibleTableColumnSelectionCount(long vmID, AccessibleTable table); + BOOL isAccessibleTableColumnSelected(long vmID, AccessibleTable table, jint column); + BOOL getAccessibleTableColumnSelections(long vmID, AccessibleTable table, jint count, jint *selections); + + jint getAccessibleTableRow(long vmID, AccessibleTable table, jint index); + jint getAccessibleTableColumn(long vmID, AccessibleTable table, jint index); + jint getAccessibleTableIndex(long vmID, AccessibleTable table, jint row, jint column); + /* end AccessibleTable */ + + /* ----- AccessibleRelationSet routines */ + BOOL getAccessibleRelationSet(long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo); + + /* ----- AccessibleHypertext routines */ + + /* + * Returns hypertext information associated with a component. + */ + BOOL getAccessibleHypertext(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo); + + /* + * Requests that a hyperlink be activated. + */ + BOOL activateAccessibleHyperlink(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink); + + /* + * Returns the number of hyperlinks in a component + * Maps to AccessibleHypertext.getLinkCount. + * Returns -1 on error. + */ + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleHypertext hypertext); + + /* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * Returns FALSE on error. + */ + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo); + + /* + * Returns the index into an array of hyperlinks that is associated with + * a character index in document; maps to AccessibleHypertext.getLinkIndex + * Returns -1 on error. + */ + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + /* + * Returns the nth hyperlink in a document + * Maps to AccessibleHypertext.getLink. + * Returns FALSE on error + */ + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + /* Accessible KeyBindings, Icons and Actions */ + + /* + * Returns a list of key bindings associated with a component. + */ + BOOL getAccessibleKeyBindings(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings); + + /* + * Returns a list of icons associate with a component. + */ + BOOL getAccessibleIcons(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons); + + /* + * Returns a list of actions that a component can perform. + */ + BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions); + + /* + * Request that a list of AccessibleActions be performed by a component. + * Returns TRUE if all actions are performed. Returns FALSE + * when the first requested action fails in which case "failure" + * contains the index of the action that failed. + */ + BOOL doAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + + + /* Additional utility methods */ + + /* + * Returns whether two object references refer to the same object. + */ + BOOL IsSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + + /** + * Sets editable text contents. The AccessibleContext must implement AccessibleEditableText and + * be editable. The maximum text length that can be set is MAX_STRING_SIZE - 1. + * Returns whether successful + */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text); + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h + * If there is no ancestor object that has the specified role, + * returns (AccessibleContext)0. + */ + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h. If an object with the specified + * role does not exist, returns the top level object for the Java Window. + * Returns (AccessibleContext)0 on error. + */ + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext); + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext); + + /** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * This method assumes the ActiveDescendent is the component that is currently + * selected in a container object. + * Returns (AccessibleContext)0 on error or if there is no selection. + */ + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext); + + /** + /** + * Accessible Value routines + */ + BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + + /** + * Accessible Selection routines + */ + void AddAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + void ClearAccessibleSelectionFromContext(long vmID, AccessibleSelection as); + JOBJECT64 GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as); + BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i); + void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as); + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len); + + /** + * Request focus for a component. Returns whether successful. + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(const long vmID, const AccessibleContext accessibleContext); + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful. + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(const long vmID, const AccessibleContext accessibleContext, const int startIndex, + const int endIndex); + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + /** + * Returns the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext); + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, + VisibleChildrenInfo *visibleChildrenInfo); + + /** + * Set the caret to a text position. Returns whether successful. + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const long vmID, const AccessibleContext accessibleContext, + const int position); + + /** + * Gets the text caret location + */ + BOOL getCaretLocation(long vmID, AccessibleContext ac, + AccessibleTextRectInfo *rectInfo, jint index); + + /** + * Gets the number of events waiting to fire + */ + int getEventsWaiting(); + +#ifdef __cplusplus +} +#endif diff --git a/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgePackages.h b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgePackages.h new file mode 100644 index 00000000..478f7c63 --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgePackages.h @@ -0,0 +1,2215 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * Header file for packages of paramaters passed between Java Accessibility + * and native Assistive Technologies + */ + +#ifndef __AccessBridgePackages_H__ +#define __AccessBridgePackages_H__ + +#include <jni.h> +#include <windows.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef ACCESSBRIDGE_ARCH_LEGACY +typedef jobject JOBJECT64; +typedef HWND ABHWND64; +#define ABHandleToLong +#define ABLongToHandle +#else +typedef jlong JOBJECT64; +typedef long ABHWND64; +#define ABHandleToLong HandleToLong +#define ABLongToHandle LongToHandle +#endif + +#define MAX_BUFFER_SIZE 10240 +#define MAX_STRING_SIZE 1024 +#define SHORT_STRING_SIZE 256 + + // object types + typedef JOBJECT64 AccessibleContext; + typedef JOBJECT64 AccessibleText; + typedef JOBJECT64 AccessibleValue; + typedef JOBJECT64 AccessibleSelection; + typedef JOBJECT64 Java_Object; + typedef JOBJECT64 PropertyChangeEvent; + typedef JOBJECT64 FocusEvent; + typedef JOBJECT64 CaretEvent; + typedef JOBJECT64 MouseEvent; + typedef JOBJECT64 MenuEvent; + typedef JOBJECT64 AccessibleTable; + typedef JOBJECT64 AccessibleHyperlink; + typedef JOBJECT64 AccessibleHypertext; + + /** + ****************************************************** + * Java event types + ****************************************************** + */ + +#define cPropertyChangeEvent (jlong) 1 // 1 +#define cFocusGainedEvent (jlong) 2 // 2 +#define cFocusLostEvent (jlong) 4 // 4 +#define cCaretUpdateEvent (jlong) 8 // 8 +#define cMouseClickedEvent (jlong) 16 // 10 +#define cMouseEnteredEvent (jlong) 32 // 20 +#define cMouseExitedEvent (jlong) 64 // 40 +#define cMousePressedEvent (jlong) 128 // 80 +#define cMouseReleasedEvent (jlong) 256 // 100 +#define cMenuCanceledEvent (jlong) 512 // 200 +#define cMenuDeselectedEvent (jlong) 1024 // 400 +#define cMenuSelectedEvent (jlong) 2048 // 800 +#define cPopupMenuCanceledEvent (jlong) 4096 // 1000 +#define cPopupMenuWillBecomeInvisibleEvent (jlong) 8192 // 2000 +#define cPopupMenuWillBecomeVisibleEvent (jlong) 16384 // 4000 +#define cJavaShutdownEvent (jlong) 32768 // 8000 + + /** + ****************************************************** + * Accessible Roles + * Defines all AccessibleRoles in Local.US + ****************************************************** + */ + + /** + * Object is used to alert the user about something. + */ +#define ACCESSIBLE_ALERT L"alert" + + /** + * The header for a column of data. + */ +#define ACCESSIBLE_COLUMN_HEADER L"column header" + + /** + * Object that can be drawn into and is used to trap + * events. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_CANVAS L"canvas" + + /** + * A list of choices the user can select from. Also optionally + * allows the user to enter a choice of their own. + */ +#define ACCESSIBLE_COMBO_BOX L"combo box" + + /** + * An iconified internal frame in a DESKTOP_PANE. + * see ACCESSIBLE_DESKTOP_PANE + * see ACCESSIBLE_INTERNAL_FRAME + */ +#define ACCESSIBLE_DESKTOP_ICON L"desktop icon" + + /** + * A frame-like object that is clipped by a desktop pane. The + * desktop pane, internal frame, and desktop icon objects are + * often used to create multiple document interfaces within an + * application. + * see ACCESSIBLE_DESKTOP_ICON + * see ACCESSIBLE_DESKTOP_PANE + * see ACCESSIBLE_FRAME + */ +#define ACCESSIBLE_INTERNAL_FRAME L"internal frame" + + /** + * A pane that supports internal frames and + * iconified versions of those internal frames. + * see ACCESSIBLE_DESKTOP_ICON + * see ACCESSIBLE_INTERNAL_FRAME + */ +#define ACCESSIBLE_DESKTOP_PANE L"desktop pane" + + /** + * A specialized pane whose primary use is inside a DIALOG + * see ACCESSIBLE_DIALOG + */ +#define ACCESSIBLE_OPTION_PANE L"option pane" + + /** + * A top level window with no title or border. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_DIALOG + */ +#define ACCESSIBLE_WINDOW L"window" + + /** + * A top level window with a title bar, border, menu bar, etc. It is + * often used as the primary window for an application. + * see ACCESSIBLE_DIALOG + * see ACCESSIBLE_CANVAS + * see ACCESSIBLE_WINDOW + */ +#define ACCESSIBLE_FRAME L"frame" + + /** + * A top level window with title bar and a border. A dialog is similar + * to a frame, but it has fewer properties and is often used as a + * secondary window for an application. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_WINDOW + */ +#define ACCESSIBLE_DIALOG L"dialog" + + /** + * A specialized dialog that lets the user choose a color. + */ +#define ACCESSIBLE_COLOR_CHOOSER L"color chooser" + + + /** + * A pane that allows the user to navigate through + * and select the contents of a directory. May be used + * by a file chooser. + * see ACCESSIBLE_FILE_CHOOSER + */ +#define ACCESSIBLE_DIRECTORY_PANE L"directory pane" + + /** + * A specialized dialog that displays the files in the directory + * and lets the user select a file, browse a different directory, + * or specify a filename. May use the directory pane to show the + * contents of a directory. + * see ACCESSIBLE_DIRECTORY_PANE + */ +#define ACCESSIBLE_FILE_CHOOSER L"file chooser" + + /** + * An object that fills up space in a user interface. It is often + * used in interfaces to tweak the spacing between components, + * but serves no other purpose. + */ +#define ACCESSIBLE_FILLER L"filler" + + /** + * A hypertext anchor + */ +#define ACCESSIBLE_HYPERLINK L"hyperlink" + + /** + * A small fixed size picture, typically used to decorate components. + */ +#define ACCESSIBLE_ICON L"icon" + + /** + * An object used to present an icon or short string in an interface. + */ +#define ACCESSIBLE_LABEL L"label" + + /** + * A specialized pane that has a glass pane and a layered pane as its + * children. + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_ROOT_PANE L"root pane" + + /** + * A pane that is guaranteed to be painted on top + * of all panes beneath it. + * see ACCESSIBLE_ROOT_PANE + * see ACCESSIBLE_CANVAS + */ +#define ACCESSIBLE_GLASS_PANE L"glass pane" + + /** + * A specialized pane that allows its children to be drawn in layers, + * providing a form of stacking order. This is usually the pane that + * holds the menu bar as well as the pane that contains most of the + * visual components in a window. + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_ROOT_PANE + */ +#define ACCESSIBLE_LAYERED_PANE L"layered pane" + + /** + * An object that presents a list of objects to the user and allows the + * user to select one or more of them. A list is usually contained + * within a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + * see ACCESSIBLE_LIST_ITEM + */ +#define ACCESSIBLE_LIST L"list" + + /** + * An object that presents an element in a list. A list is usually + * contained within a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + * see ACCESSIBLE_LIST + */ +#define ACCESSIBLE_LIST_ITEM L"list item" + + /** + * An object usually drawn at the top of the primary dialog box of + * an application that contains a list of menus the user can choose + * from. For example, a menu bar might contain menus for "File," + * "Edit," and "Help." + * see ACCESSIBLE_MENU + * see ACCESSIBLE_POPUP_MENU + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_MENU_BAR L"menu bar" + + /** + * A temporary window that is usually used to offer the user a + * list of choices, and then hides when the user selects one of + * those choices. + * see ACCESSIBLE_MENU + * see ACCESSIBLE_MENU_ITEM + */ +#define ACCESSIBLE_POPUP_MENU L"popup menu" + + /** + * An object usually found inside a menu bar that contains a list + * of actions the user can choose from. A menu can have any object + * as its children, but most often they are menu items, other menus, + * or rudimentary objects such as radio buttons, check boxes, or + * separators. For example, an application may have an "Edit" menu + * that contains menu items for "Cut" and "Paste." + * see ACCESSIBLE_MENU_BAR + * see ACCESSIBLE_MENU_ITEM + * see ACCESSIBLE_SEPARATOR + * see ACCESSIBLE_RADIO_BUTTON + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_POPUP_MENU + */ +#define ACCESSIBLE_MENU L"menu" + + /** + * An object usually contained in a menu that presents an action + * the user can choose. For example, the "Cut" menu item in an + * "Edit" menu would be an action the user can select to cut the + * selected area of text in a document. + * see ACCESSIBLE_MENU_BAR + * see ACCESSIBLE_SEPARATOR + * see ACCESSIBLE_POPUP_MENU + */ +#define ACCESSIBLE_MENU_ITEM L"menu item" + + /** + * An object usually contained in a menu to provide a visual + * and logical separation of the contents in a menu. For example, + * the "File" menu of an application might contain menu items for + * "Open," "Close," and "Exit," and will place a separator between + * "Close" and "Exit" menu items. + * see ACCESSIBLE_MENU + * see ACCESSIBLE_MENU_ITEM + */ +#define ACCESSIBLE_SEPARATOR L"separator" + + /** + * An object that presents a series of panels (or page tabs), one at a + * time, through some mechanism provided by the object. The most common + * mechanism is a list of tabs at the top of the panel. The children of + * a page tab list are all page tabs. + * see ACCESSIBLE_PAGE_TAB + */ +#define ACCESSIBLE_PAGE_TAB_LIST L"page tab list" + + /** + * An object that is a child of a page tab list. Its sole child is + * the panel that is to be presented to the user when the user + * selects the page tab from the list of tabs in the page tab list. + * see ACCESSIBLE_PAGE_TAB_LIST + */ +#define ACCESSIBLE_PAGE_TAB L"page tab" + + /** + * A generic container that is often used to group objects. + */ +#define ACCESSIBLE_PANEL L"panel" + + /** + * An object used to indicate how much of a task has been completed. + */ +#define ACCESSIBLE_PROGRESS_BAR L"progress bar" + + /** + * A text object used for passwords, or other places where the + * text contents is not shown visibly to the user + */ +#define ACCESSIBLE_PASSWORD_TEXT L"password text" + + /** + * An object the user can manipulate to tell the application to do + * something. + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_PUSH_BUTTON L"push button" + + /** + * A specialized push button that can be checked or unchecked, but + * does not provide a separate indicator for the current state. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_TOGGLE_BUTTON L"toggle button" + + /** + * A choice that can be checked or unchecked and provides a + * separate indicator for the current state. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_CHECK_BOX L"check box" + + /** + * A specialized check box that will cause other radio buttons in the + * same group to become unchecked when this one is checked. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_CHECK_BOX + */ +#define ACCESSIBLE_RADIO_BUTTON L"radio button" + + /** + * The header for a row of data. + */ +#define ACCESSIBLE_ROW_HEADER L"row header" + + /** + * An object that allows a user to incrementally view a large amount + * of information. Its children can include scroll bars and a viewport. + * see ACCESSIBLE_SCROLL_BAR + * see ACCESSIBLE_VIEWPORT + */ +#define ACCESSIBLE_SCROLL_PANE L"scroll pane" + + /** + * An object usually used to allow a user to incrementally view a + * large amount of data. Usually used only by a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + */ +#define ACCESSIBLE_SCROLL_BAR L"scroll bar" + + /** + * An object usually used in a scroll pane. It represents the portion + * of the entire data that the user can see. As the user manipulates + * the scroll bars, the contents of the viewport can change. + * see ACCESSIBLE_SCROLL_PANE + */ +#define ACCESSIBLE_VIEWPORT L"viewport" + + /** + * An object that allows the user to select from a bounded range. For + * example, a slider might be used to select a number between 0 and 100. + */ +#define ACCESSIBLE_SLIDER L"slider" + + /** + * A specialized panel that presents two other panels at the same time. + * Between the two panels is a divider the user can manipulate to make + * one panel larger and the other panel smaller. + */ +#define ACCESSIBLE_SPLIT_PANE L"split pane" + + /** + * An object used to present information in terms of rows and columns. + * An example might include a spreadsheet application. + */ +#define ACCESSIBLE_TABLE L"table" + + /** + * An object that presents text to the user. The text is usually + * editable by the user as opposed to a label. + * see ACCESSIBLE_LABEL + */ +#define ACCESSIBLE_TEXT L"text" + + /** + * An object used to present hierarchical information to the user. + * The individual nodes in the tree can be collapsed and expanded + * to provide selective disclosure of the tree's contents. + */ +#define ACCESSIBLE_TREE L"tree" + + /** + * A bar or palette usually composed of push buttons or toggle buttons. + * It is often used to provide the most frequently used functions for an + * application. + */ +#define ACCESSIBLE_TOOL_BAR L"tool bar" + + /** + * An object that provides information about another object. The + * accessibleDescription property of the tool tip is often displayed + * to the user in a small L"help bubble" when the user causes the + * mouse to hover over the object associated with the tool tip. + */ +#define ACCESSIBLE_TOOL_TIP L"tool tip" + + /** + * An AWT component, but nothing else is known about it. + * see ACCESSIBLE_SWING_COMPONENT + * see ACCESSIBLE_UNKNOWN + */ +#define ACCESSIBLE_AWT_COMPONENT L"awt component" + + /** + * A Swing component, but nothing else is known about it. + * see ACCESSIBLE_AWT_COMPONENT + * see ACCESSIBLE_UNKNOWN + */ +#define ACCESSIBLE_SWING_COMPONENT L"swing component" + + /** + * The object contains some Accessible information, but its role is + * not known. + * see ACCESSIBLE_AWT_COMPONENT + * see ACCESSIBLE_SWING_COMPONENT + */ +#define ACCESSIBLE_UNKNOWN L"unknown" + + /** + * A STATUS_BAR is an simple component that can contain + * multiple labels of status information to the user. + */ +#define ACCESSIBLE_STATUS_BAR L"status bar" + + /** + * A DATE_EDITOR is a component that allows users to edit + * java.util.Date and java.util.Time objects + */ +#define ACCESSIBLE_DATE_EDITOR L"date editor" + + /** + * A SPIN_BOX is a simple spinner component and its main use + * is for simple numbers. + */ +#define ACCESSIBLE_SPIN_BOX L"spin box" + + /** + * A FONT_CHOOSER is a component that lets the user pick various + * attributes for fonts. + */ +#define ACCESSIBLE_FONT_CHOOSER L"font chooser" + + /** + * A GROUP_BOX is a simple container that contains a border + * around it and contains components inside it. + */ +#define ACCESSIBLE_GROUP_BOX L"group box" + + /** + * A text header + */ +#define ACCESSIBLE_HEADER L"header" + + /** + * A text footer + */ +#define ACCESSIBLE_FOOTER L"footer" + + /** + * A text paragraph + */ +#define ACCESSIBLE_PARAGRAPH L"paragraph" + + /** + * A ruler is an object used to measure distance + */ +#define ACCESSIBLE_RULER L"ruler" + + /** + * A role indicating the object acts as a formula for + * calculating a value. An example is a formula in + * a spreadsheet cell. + */ +#define ACCESSIBLE_EDITBAR L"editbar" + + /** + * A role indicating the object monitors the progress + * of some operation. + */ +#define PROGRESS_MONITOR L"progress monitor" + + + /** + ****************************************************** + * Accessibility event types + ****************************************************** + */ + +#define cPropertyNameChangeEvent (jlong) 1 // 1 +#define cPropertyDescriptionChangeEvent (jlong) 2 // 2 +#define cPropertyStateChangeEvent (jlong) 4 // 4 +#define cPropertyValueChangeEvent (jlong) 8 // 8 +#define cPropertySelectionChangeEvent (jlong) 16 // 10 +#define cPropertyTextChangeEvent (jlong) 32 // 20 +#define cPropertyCaretChangeEvent (jlong) 64 // 40 +#define cPropertyVisibleDataChangeEvent (jlong) 128 // 80 +#define cPropertyChildChangeEvent (jlong) 256 // 100 +#define cPropertyActiveDescendentChangeEvent (jlong) 512 // 200 +#define cPropertyTableModelChangeEvent (jlong) 1024 // 400 + + /** + ****************************************************** + * optional AccessibleContext interfaces + * + * This version of the bridge reuses the accessibleValue + * field in the AccessibleContextInfo struct to represent + * additional optional interfaces that are supported by + * the Java AccessibleContext. This is backwardly compatable + * because the old accessibleValue was set to the BOOL + * value TRUE (i.e., 1) if the AccessibleValue interface is + * supported. + ****************************************************** + */ + +#define cAccessibleValueInterface (jlong) 1 // 1 << 1 (TRUE) +#define cAccessibleActionInterface (jlong) 2 // 1 << 2 +#define cAccessibleComponentInterface (jlong) 4 // 1 << 3 +#define cAccessibleSelectionInterface (jlong) 8 // 1 << 4 +#define cAccessibleTableInterface (jlong) 16 // 1 << 5 +#define cAccessibleTextInterface (jlong) 32 // 1 << 6 +#define cAccessibleHypertextInterface (jlong) 64 // 1 << 7 + + + /** + ****************************************************** + * Accessibility information bundles + ****************************************************** + */ + + typedef struct AccessBridgeVersionInfoTag { + wchar_t VMversion[SHORT_STRING_SIZE]; // output of "java -version" + wchar_t bridgeJavaClassVersion[SHORT_STRING_SIZE]; // version of the AccessBridge.class + wchar_t bridgeJavaDLLVersion[SHORT_STRING_SIZE]; // version of JavaAccessBridge.dll + wchar_t bridgeWinDLLVersion[SHORT_STRING_SIZE]; // version of WindowsAccessBridge.dll + } AccessBridgeVersionInfo; + + + typedef struct AccessibleContextInfoTag { + wchar_t name[MAX_STRING_SIZE]; // the AccessibleName of the object + wchar_t description[MAX_STRING_SIZE]; // the AccessibleDescription of the object + + wchar_t role[SHORT_STRING_SIZE]; // localized AccesibleRole string + wchar_t role_en_US[SHORT_STRING_SIZE]; // AccesibleRole string in the en_US locale + wchar_t states[SHORT_STRING_SIZE]; // localized AccesibleStateSet string (comma separated) + wchar_t states_en_US[SHORT_STRING_SIZE]; // AccesibleStateSet string in the en_US locale (comma separated) + + jint indexInParent; // index of object in parent + jint childrenCount; // # of children, if any + + jint x; // screen coords in pixels + jint y; // " + jint width; // pixel width of object + jint height; // pixel height of object + + BOOL accessibleComponent; // flags for various additional + BOOL accessibleAction; // Java Accessibility interfaces + BOOL accessibleSelection; // FALSE if this object doesn't + BOOL accessibleText; // implement the additional interface + // in question + + // BOOL accessibleValue; // old BOOL indicating whether AccessibleValue is supported + BOOL accessibleInterfaces; // new bitfield containing additional interface flags + + } AccessibleContextInfo; + + + + // AccessibleText packages + typedef struct AccessibleTextInfoTag { + jint charCount; // # of characters in this text object + jint caretIndex; // index of caret + jint indexAtPoint; // index at the passsed in point + } AccessibleTextInfo; + + typedef struct AccessibleTextItemsInfoTag { + wchar_t letter; + wchar_t word[SHORT_STRING_SIZE]; + wchar_t sentence[MAX_STRING_SIZE]; + } AccessibleTextItemsInfo; + + typedef struct AccessibleTextSelectionInfoTag { + jint selectionStartIndex; + jint selectionEndIndex; + wchar_t selectedText[MAX_STRING_SIZE]; + } AccessibleTextSelectionInfo; + + typedef struct AccessibleTextRectInfoTag { + jint x; // bounding rect of char at index + jint y; // " + jint width; // " + jint height; // " + } AccessibleTextRectInfo; + + // standard attributes for text; note: tabstops are not supported + typedef struct AccessibleTextAttributesInfoTag { + BOOL bold; + BOOL italic; + BOOL underline; + BOOL strikethrough; + BOOL superscript; + BOOL subscript; + + wchar_t backgroundColor[SHORT_STRING_SIZE]; + wchar_t foregroundColor[SHORT_STRING_SIZE]; + wchar_t fontFamily[SHORT_STRING_SIZE]; + jint fontSize; + + jint alignment; + jint bidiLevel; + + jfloat firstLineIndent; + jfloat leftIndent; + jfloat rightIndent; + jfloat lineSpacing; + jfloat spaceAbove; + jfloat spaceBelow; + + wchar_t fullAttributesString[MAX_STRING_SIZE]; + } AccessibleTextAttributesInfo; + + /** + ****************************************************** + * IPC management typedefs + ****************************************************** + */ + +#define cMemoryMappedNameSize 255 + + /** + * sent by the WindowsDLL -> the memory-mapped file is setup + * + */ + typedef struct MemoryMappedFileCreatedPackageTag { +// HWND bridgeWindow; // redundant, but easier to get to here... + ABHWND64 bridgeWindow; // redundant, but easier to get to here... + char filename[cMemoryMappedNameSize]; + } MemoryMappedFileCreatedPackage; + + + + + /** + * sent when a new JavaVM attaches to the Bridge + * + */ + typedef struct JavaVMCreatedPackageTag { + ABHWND64 bridgeWindow; + long vmID; + } JavaVMCreatedPackage; + + /** + * sent when a JavaVM detatches from the Bridge + * + */ + typedef struct JavaVMDestroyedPackageTag { + ABHWND64 bridgeWindow; + } JavaVMDestroyedPackage; + + /** + * sent when a new AT attaches to the Bridge + * + */ + typedef struct WindowsATCreatedPackageTag { + ABHWND64 bridgeWindow; + } WindowsATCreatedPackage; + + /** + * sent when an AT detatches from the Bridge + * + */ + typedef struct WindowsATDestroyedPackageTag { + ABHWND64 bridgeWindow; + } WindowsATDestroyedPackage; + + + /** + * sent by JVM Bridges in response to a WindowsATCreate + * message; saying "howdy, welcome to the neighborhood" + * + */ + typedef struct JavaVMPresentNotificationPackageTag { + ABHWND64 bridgeWindow; + long vmID; + } JavaVMPresentNotificationPackage; + + /** + * sent by AT Bridges in response to a JavaVMCreate + * message; saying "howdy, welcome to the neighborhood" + * + */ + typedef struct WindowsATPresentNotificationPackageTag { + ABHWND64 bridgeWindow; + } WindowsATPresentNotificationPackage; + + + /** + ****************************************************** + * Core packages + ****************************************************** + */ + + typedef struct ReleaseJavaObjectPackageTag { + long vmID; + JOBJECT64 object; + } ReleaseJavaObjectPackage; + + typedef struct GetAccessBridgeVersionPackageTag { + long vmID; // can't get VM info w/out a VM! + AccessBridgeVersionInfo rVersionInfo; + } GetAccessBridgeVersionPackage; + + typedef struct IsSameObjectPackageTag { + long vmID; + JOBJECT64 obj1; + JOBJECT64 obj2; + jboolean rResult; + } IsSameObjectPackage; + + /** + ****************************************************** + * Windows packages + ****************************************************** + */ + + typedef struct IsJavaWindowPackageTag { + jint window; + jboolean rResult; + } IsJavaWindowPackage; + + typedef struct GetAccessibleContextFromHWNDPackageTag { + jint window; + long rVMID; + JOBJECT64 rAccessibleContext; + } GetAccessibleContextFromHWNDPackage; + + typedef struct GetHWNDFromAccessibleContextPackageTag { + JOBJECT64 accessibleContext; + ABHWND64 rHWND; + } GetHWNDFromAccessibleContextPackage; + + /** +****************************************************** +* AccessibleContext packages +****************************************************** +*/ + + typedef struct GetAccessibleContextAtPackageTag { + jint x; + jint y; + long vmID; + JOBJECT64 AccessibleContext; // look within this AC + JOBJECT64 rAccessibleContext; + } GetAccessibleContextAtPackage; + + typedef struct GetAccessibleContextWithFocusPackageTag { + long rVMID; + JOBJECT64 rAccessibleContext; + } GetAccessibleContextWithFocusPackage; + + typedef struct GetAccessibleContextInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + AccessibleContextInfo rAccessibleContextInfo; + } GetAccessibleContextInfoPackage; + + typedef struct GetAccessibleChildFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint childIndex; + JOBJECT64 rAccessibleContext; + } GetAccessibleChildFromContextPackage; + + typedef struct GetAccessibleParentFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + JOBJECT64 rAccessibleContext; + } GetAccessibleParentFromContextPackage; + + /** +****************************************************** +* AccessibleTable packages +****************************************************** +*/ + +#define MAX_TABLE_SELECTIONS 64 + + // table information + typedef struct AccessibleTableInfoTag { + JOBJECT64 caption; // AccesibleContext + JOBJECT64 summary; // AccessibleContext + jint rowCount; + jint columnCount; + JOBJECT64 accessibleContext; + JOBJECT64 accessibleTable; + } AccessibleTableInfo; + + typedef struct GetAccessibleTableInfoPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableInfoPackage; + + // table cell information + typedef struct AccessibleTableCellInfoTag { + JOBJECT64 accessibleContext; + jint index; + jint row; + jint column; + jint rowExtent; + jint columnExtent; + jboolean isSelected; + } AccessibleTableCellInfo; + + typedef struct GetAccessibleTableCellInfoPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jint column; + AccessibleTableCellInfo rTableCellInfo; + } GetAccessibleTableCellInfoPackage; + + typedef struct GetAccessibleTableRowHeaderPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableRowHeaderPackage; + + typedef struct GetAccessibleTableColumnHeaderPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableColumnHeaderPackage; + + typedef struct GetAccessibleTableRowDescriptionPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint row; + JOBJECT64 rAccessibleContext; + } GetAccessibleTableRowDescriptionPackage; + + typedef struct GetAccessibleTableColumnDescriptionPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint column; + JOBJECT64 rAccessibleContext; + } GetAccessibleTableColumnDescriptionPackage; + + typedef struct GetAccessibleTableRowSelectionCountPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint rCount; + } GetAccessibleTableRowSelectionCountPackage; + + typedef struct IsAccessibleTableRowSelectedPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jboolean rResult; + } IsAccessibleTableRowSelectedPackage; + + typedef struct GetAccessibleTableRowSelectionsPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint count; + jint rSelections[MAX_TABLE_SELECTIONS]; + } GetAccessibleTableRowSelectionsPackage; + + typedef struct GetAccessibleTableColumnSelectionCountPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint rCount; + } GetAccessibleTableColumnSelectionCountPackage; + + typedef struct IsAccessibleTableColumnSelectedPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint column; + jboolean rResult; + } IsAccessibleTableColumnSelectedPackage; + + typedef struct GetAccessibleTableColumnSelectionsPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint count; + jint rSelections[MAX_TABLE_SELECTIONS]; + } GetAccessibleTableColumnSelectionsPackage; + + + typedef struct GetAccessibleTableRowPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint index; + jint rRow; + } GetAccessibleTableRowPackage; + + typedef struct GetAccessibleTableColumnPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint index; + jint rColumn; + } GetAccessibleTableColumnPackage; + + typedef struct GetAccessibleTableIndexPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jint column; + jint rIndex; + } GetAccessibleTableIndexPackage; + + + /** + ****************************************************** + * AccessibleRelationSet packages + ****************************************************** + */ + +#define MAX_RELATION_TARGETS 25 +#define MAX_RELATIONS 5 + + typedef struct AccessibleRelationInfoTag { + wchar_t key[SHORT_STRING_SIZE]; + jint targetCount; + JOBJECT64 targets[MAX_RELATION_TARGETS]; // AccessibleContexts + } AccessibleRelationInfo; + + typedef struct AccessibleRelationSetInfoTag { + jint relationCount; + AccessibleRelationInfo relations[MAX_RELATIONS]; + } AccessibleRelationSetInfo; + + typedef struct GetAccessibleRelationSetPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleRelationSetInfo rAccessibleRelationSetInfo; + } GetAccessibleRelationSetPackage; + + /** + ****************************************************** + * AccessibleHypertext packagess + ****************************************************** + */ + +#define MAX_HYPERLINKS 64 // maximum number of hyperlinks returned + + // hyperlink information + typedef struct AccessibleHyperlinkInfoTag { + wchar_t text[SHORT_STRING_SIZE]; // the hyperlink text + jint startIndex; //index in the hypertext document where the link begins + jint endIndex; //index in the hypertext document where the link ends + JOBJECT64 accessibleHyperlink; // AccessibleHyperlink object + } AccessibleHyperlinkInfo; + + // hypertext information + typedef struct AccessibleHypertextInfoTag { + jint linkCount; // number of hyperlinks + AccessibleHyperlinkInfo links[MAX_HYPERLINKS]; // the hyperlinks + JOBJECT64 accessibleHypertext; // AccessibleHypertext object + } AccessibleHypertextInfo; + + // struct for sending a message to get the hypertext for an AccessibleContext + typedef struct GetAccessibleHypertextPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext with hypertext + AccessibleHypertextInfo rAccessibleHypertextInfo; // returned hypertext + } GetAccessibleHypertextPackage; + + // struct for sending an message to activate a hyperlink + typedef struct ActivateAccessibleHyperlinkPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext containing the link + JOBJECT64 accessibleHyperlink; // the link to activate + BOOL rResult; // hyperlink activation return value + } ActivateAccessibleHyperlinkPackage; + + // struct for sending a message to get the number of hyperlinks in a component + typedef struct GetAccessibleHyperlinkCountPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext containing AccessibleHypertext + jint rLinkCount; // link count return value + } GetAccessibleHyperlinkCountPackage; + + // struct for sending a message to get the hypertext for an AccessibleContext + // starting at a specified index in the document + typedef struct GetAccessibleHypertextExtPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext with hypertext + jint startIndex; // start index in document + AccessibleHypertextInfo rAccessibleHypertextInfo; // returned hypertext + BOOL rSuccess; // whether call succeeded + } GetAccessibleHypertextExtPackage; + + // struct for sending a message to get the nth hyperlink in a document; + // maps to AccessibleHypertext.getLink + typedef struct GetAccessibleHyperlinkPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 hypertext; // AccessibleHypertext + jint linkIndex; // hyperlink index + AccessibleHyperlinkInfo rAccessibleHyperlinkInfo; // returned hyperlink + } GetAccessibleHyperlinkPackage; + + // struct for sending a message to get the index into an array + // of hyperlinks that is associated with a character index in a + // document; maps to AccessibleHypertext.getLinkIndex + typedef struct GetAccessibleHypertextLinkIndexPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 hypertext; // AccessibleHypertext + jint charIndex; // character index in document + jint rLinkIndex; // returned hyperlink index + } GetAccessibleHypertextLinkIndexPackage; + + /** + ****************************************************** + * Accessible Key Bindings packages + ****************************************************** + */ + +#define MAX_KEY_BINDINGS 10 + + // keyboard character modifiers +#define ACCESSIBLE_SHIFT_KEYSTROKE 1 +#define ACCESSIBLE_CONTROL_KEYSTROKE 2 +#define ACCESSIBLE_META_KEYSTROKE 4 +#define ACCESSIBLE_ALT_KEYSTROKE 8 +#define ACCESSIBLE_ALT_GRAPH_KEYSTROKE 16 +#define ACCESSIBLE_BUTTON1_KEYSTROKE 32 +#define ACCESSIBLE_BUTTON2_KEYSTROKE 64 +#define ACCESSIBLE_BUTTON3_KEYSTROKE 128 +#define ACCESSIBLE_FKEY_KEYSTROKE 256 // F key pressed, character contains 1-24 +#define ACCESSIBLE_CONTROLCODE_KEYSTROKE 512 // Control code key pressed, character contains control code. + +// The supported control code keys are: +#define ACCESSIBLE_VK_BACK_SPACE 8 +#define ACCESSIBLE_VK_DELETE 127 +#define ACCESSIBLE_VK_DOWN 40 +#define ACCESSIBLE_VK_END 35 +#define ACCESSIBLE_VK_HOME 36 +#define ACCESSIBLE_VK_INSERT 155 +#define ACCESSIBLE_VK_KP_DOWN 225 +#define ACCESSIBLE_VK_KP_LEFT 226 +#define ACCESSIBLE_VK_KP_RIGHT 227 +#define ACCESSIBLE_VK_KP_UP 224 +#define ACCESSIBLE_VK_LEFT 37 +#define ACCESSIBLE_VK_PAGE_DOWN 34 +#define ACCESSIBLE_VK_PAGE_UP 33 +#define ACCESSIBLE_VK_RIGHT 39 +#define ACCESSIBLE_VK_UP 38 + + // a key binding associates with a component + typedef struct AccessibleKeyBindingInfoTag { + jchar character; // the key character + jint modifiers; // the key modifiers + } AccessibleKeyBindingInfo; + + // all of the key bindings associated with a component + typedef struct AccessibleKeyBindingsTag { + int keyBindingsCount; // number of key bindings + AccessibleKeyBindingInfo keyBindingInfo[MAX_KEY_BINDINGS]; + } AccessibleKeyBindings; + + // struct to get the key bindings associated with a component + typedef struct GetAccessibleKeyBindingsPackageTag { + long vmID; // the virtual machine id + JOBJECT64 accessibleContext; // the component + AccessibleKeyBindings rAccessibleKeyBindings; // the key bindings + } GetAccessibleKeyBindingsPackage; + + /** +****************************************************** +* AccessibleIcon packages +****************************************************** +*/ +#define MAX_ICON_INFO 8 + + // an icon assocated with a component + typedef struct AccessibleIconInfoTag { + wchar_t description[SHORT_STRING_SIZE]; // icon description + jint height; // icon height + jint width; // icon width + } AccessibleIconInfo; + + // all of the icons associated with a component + typedef struct AccessibleIconsTag { + jint iconsCount; // number of icons + AccessibleIconInfo iconInfo[MAX_ICON_INFO]; // the icons + } AccessibleIcons; + + // struct to get the icons associated with a component + typedef struct GetAccessibleIconsPackageTag { + long vmID; // the virtual machine id + JOBJECT64 accessibleContext; // the component + AccessibleIcons rAccessibleIcons; // the icons + } GetAccessibleIconsPackage; + + + /** +****************************************************** +* AccessibleAction packages +****************************************************** +*/ +#define MAX_ACTION_INFO 256 +#define MAX_ACTIONS_TO_DO 32 + + // an action assocated with a component + typedef struct AccessibleActionInfoTag { + wchar_t name[SHORT_STRING_SIZE]; // action name + } AccessibleActionInfo; + + // all of the actions associated with a component + typedef struct AccessibleActionsTag { + jint actionsCount; // number of actions + AccessibleActionInfo actionInfo[MAX_ACTION_INFO]; // the action information + } AccessibleActions; + + // struct for requesting the actions associated with a component + typedef struct GetAccessibleActionsPackageTag { + long vmID; + JOBJECT64 accessibleContext; // the component + AccessibleActions rAccessibleActions; // the actions + } GetAccessibleActionsPackage; + + // list of AccessibleActions to do + typedef struct AccessibleActionsToDoTag { + jint actionsCount; // number of actions to do + AccessibleActionInfo actions[MAX_ACTIONS_TO_DO];// the accessible actions to do + } AccessibleActionsToDo; + + // struct for sending an message to do one or more actions + typedef struct DoAccessibleActionsPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // component to do the action + AccessibleActionsToDo actionsToDo; // the accessible actions to do + BOOL rResult; // action return value + jint failure; // index of action that failed if rResult is FALSE + } DoAccessibleActionsPackage; + + /** +****************************************************** +* AccessibleText packages +****************************************************** +*/ + + typedef struct GetAccessibleTextInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint x; + jint y; + AccessibleTextInfo rTextInfo; + } GetAccessibleTextInfoPackage; + + typedef struct GetAccessibleTextItemsPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextItemsInfo rTextItemsInfo; + } GetAccessibleTextItemsPackage; + + typedef struct GetAccessibleTextSelectionInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + AccessibleTextSelectionInfo rTextSelectionItemsInfo; + } GetAccessibleTextSelectionInfoPackage; + + typedef struct GetAccessibleTextAttributeInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextAttributesInfo rAttributeInfo; + } GetAccessibleTextAttributeInfoPackage; + + typedef struct GetAccessibleTextRectInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextRectInfo rTextRectInfo; + } GetAccessibleTextRectInfoPackage; + + typedef struct GetCaretLocationPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextRectInfo rTextRectInfo; + } GetCaretLocationPackage; + + typedef struct GetAccessibleTextLineBoundsPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + jint rLineStart; + jint rLineEnd; + } GetAccessibleTextLineBoundsPackage; + + typedef struct GetAccessibleTextRangePackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint start; + jint end; + wchar_t rText[MAX_BUFFER_SIZE]; + } GetAccessibleTextRangePackage; + + /** +****************************************************** +* +* Utility method packages +****************************************************** +*/ + + typedef struct SetTextContentsPackageTag { + long vmID; + JOBJECT64 accessibleContext; // the text field + wchar_t text[MAX_STRING_SIZE]; // the text + BOOL rResult; + } SetTextContentsPackage; + + typedef struct GetParentWithRolePackageTag { + long vmID; + JOBJECT64 accessibleContext; + wchar_t role[SHORT_STRING_SIZE]; // one of Accessible Roles above + JOBJECT64 rAccessibleContext; + } GetParentWithRolePackage; + + typedef struct GetTopLevelObjectPackageTag { + long vmID; + JOBJECT64 accessibleContext; + JOBJECT64 rAccessibleContext; + } GetTopLevelObjectPackage; + + typedef struct GetParentWithRoleElseRootPackageTag { + long vmID; + JOBJECT64 accessibleContext; + wchar_t role[SHORT_STRING_SIZE]; // one of Accessible Roles above + JOBJECT64 rAccessibleContext; + } GetParentWithRoleElseRootPackage; + + typedef struct GetObjectDepthPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint rResult; + } GetObjectDepthPackage; + + typedef struct GetActiveDescendentPackageTag { + long vmID; + JOBJECT64 accessibleContext; + JOBJECT64 rAccessibleContext; + } GetActiveDescendentPackage; + + /** +****************************************************** +* AccessibleValue packages +****************************************************** +*/ + + typedef struct GetCurrentAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetCurrentAccessibleValueFromContextPackage; + + typedef struct GetMaximumAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetMaximumAccessibleValueFromContextPackage; + + typedef struct GetMinimumAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetMinimumAccessibleValueFromContextPackage; + + + /** +****************************************************** +* AccessibleSelection packages +****************************************************** +*/ + + typedef struct AddAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + } AddAccessibleSelectionFromContextPackage; + + typedef struct ClearAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + } ClearAccessibleSelectionFromContextPackage; + + typedef struct GetAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + JOBJECT64 rAccessibleContext; + } GetAccessibleSelectionFromContextPackage; + + typedef struct GetAccessibleSelectionCountFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint rCount; + } GetAccessibleSelectionCountFromContextPackage; + + typedef struct IsAccessibleChildSelectedFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + jboolean rResult; + } IsAccessibleChildSelectedFromContextPackage; + + typedef struct RemoveAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + } RemoveAccessibleSelectionFromContextPackage; + + typedef struct SelectAllAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + } SelectAllAccessibleSelectionFromContextPackage; + + + /** +****************************************************** +* Java Event Notification Registration packages +****************************************************** +*/ + + typedef struct AddJavaEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } AddJavaEventNotificationPackage; + + typedef struct RemoveJavaEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } RemoveJavaEventNotificationPackage; + + + /** +****************************************************** +* Accessibility Event Notification Registration packages +****************************************************** +*/ + + typedef struct AddAccessibilityEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } AddAccessibilityEventNotificationPackage; + + typedef struct RemoveAccessibilityEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } RemoveAccessibilityEventNotificationPackage; + + + /** +****************************************************** +* Accessibility Property Change Event packages +****************************************************** +*/ + + typedef struct PropertyCaretChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + jint oldPosition; + jint newPosition; + } PropertyCaretChangePackage; + + typedef struct PropertyDescriptionChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldDescription[SHORT_STRING_SIZE]; + wchar_t newDescription[SHORT_STRING_SIZE]; + } PropertyDescriptionChangePackage; + + typedef struct PropertyNameChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldName[SHORT_STRING_SIZE]; + wchar_t newName[SHORT_STRING_SIZE]; + } PropertyNameChangePackage; + + typedef struct PropertySelectionChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertySelectionChangePackage; + + typedef struct PropertyStateChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldState[SHORT_STRING_SIZE]; + wchar_t newState[SHORT_STRING_SIZE]; + } PropertyStateChangePackage; + + typedef struct PropertyTextChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertyTextChangePackage; + + typedef struct PropertyValueChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldValue[SHORT_STRING_SIZE]; + wchar_t newValue[SHORT_STRING_SIZE]; + } PropertyValueChangePackage; + + typedef struct PropertyVisibleDataChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertyVisibleDataChangePackage; + + typedef struct PropertyChildChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + JOBJECT64 oldChildAccessibleContext; + JOBJECT64 newChildAccessibleContext; + } PropertyChildChangePackage; + + typedef struct PropertyActiveDescendentChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + JOBJECT64 oldActiveDescendentAccessibleContext; + JOBJECT64 newActiveDescendentAccessibleContext; + } PropertyActiveDescendentChangePackage; + + + // String format for newValue is: + // "type" one of "INSERT", "UPDATE" or "DELETE" + // "firstRow" + // "lastRow" + // "firstColumn" + // "lastColumn" + // + // oldValue is currently unused + // + typedef struct PropertyTableModelChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldValue[SHORT_STRING_SIZE]; + wchar_t newValue[SHORT_STRING_SIZE]; + } PropertyTableModelChangePackage; + + + /** +****************************************************** +* Property Change Event packages +****************************************************** +*/ + + /* + typedef struct PropertyChangePackageTag { + long vmID; + jobject Event; + jobject AccessibleContextSource; + char propertyName[SHORT_STRING_SIZE]; + char oldValue[SHORT_STRING_SIZE]; // PropertyChangeEvent().getOldValue().toString() + char newValue[SHORT_STRING_SIZE]; // PropertyChangeEvent().getNewValue().toString() + } PropertyChangePackage; + */ + + /* + * Java shutdown event package + */ + typedef struct JavaShutdownPackageTag { + long vmID; + } JavaShutdownPackage; + + + /** +****************************************************** +* Focus Event packages +****************************************************** +*/ + + typedef struct FocusGainedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } FocusGainedPackage; + + typedef struct FocusLostPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } FocusLostPackage; + + + /** +****************************************************** +* Caret Event packages +****************************************************** +*/ + + typedef struct CaretUpdatePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } CaretUpdatePackage; + + + /** +****************************************************** +* Mouse Event packages +****************************************************** +*/ + + typedef struct MouseClickedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseClickedPackage; + + typedef struct MouseEnteredPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseEnteredPackage; + + typedef struct MouseExitedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseExitedPackage; + + typedef struct MousePressedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MousePressedPackage; + + typedef struct MouseReleasedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseReleasedPackage; + + + /** +****************************************************** +* Menu/PopupMenu Event packages +****************************************************** +*/ + + typedef struct MenuCanceledPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuCanceledPackage; + + typedef struct MenuDeselectedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuDeselectedPackage; + + typedef struct MenuSelectedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuSelectedPackage; + + + typedef struct PopupMenuCanceledPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuCanceledPackage; + + typedef struct PopupMenuWillBecomeInvisiblePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuWillBecomeInvisiblePackage; + + typedef struct PopupMenuWillBecomeVisiblePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuWillBecomeVisiblePackage; + + /** +****************************************************** +* Additional methods for Teton +****************************************************** +*/ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + typedef struct GetVirtualAccessibleNamePackageTag { + long vmID; + AccessibleContext accessibleContext; + wchar_t rName[MAX_STRING_SIZE]; + int len; + } GetVirtualAccessibleNamePackage; + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + typedef struct RequestFocusPackageTag { + long vmID; + AccessibleContext accessibleContext; + } RequestFocusPackage; + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + typedef struct SelectTextRangePackageTag { + long vmID; + AccessibleContext accessibleContext; + jint startIndex; + jint endIndex; + } SelectTextRangePackage; + + /** + * Gets the number of contiguous characters with the same attributes. + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + typedef struct GetTextAttributesInRangePackageTag { + long vmID; + AccessibleContext accessibleContext; + jint startIndex; // start index (inclusive) + jint endIndex; // end index (inclusive) + AccessibleTextAttributesInfo attributes; // character attributes to match + short rLength; // number of contiguous characters with matching attributes + } GetTextAttributesInRangePackage; + +#define MAX_VISIBLE_CHILDREN 256 + + // visible children information + typedef struct VisibleChildenInfoTag { + int returnedChildrenCount; // number of children returned + AccessibleContext children[MAX_VISIBLE_CHILDREN]; // the visible children + } VisibleChildrenInfo; + + // struct for sending a message to get the number of visible children + typedef struct GetVisibleChildrenCountPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext of parent component + jint rChildrenCount; // visible children count return value + } GetVisibleChildrenCountPackage; + + // struct for sending a message to get the hypertext for an AccessibleContext + // starting at a specified index in the document + typedef struct GetVisibleChildrenPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext of parent component + jint startIndex; // start index for retrieving children + VisibleChildrenInfo rVisibleChildrenInfo; // returned info + BOOL rSuccess; // whether call succeeded + } GetVisibleChildrenPackage; + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + typedef struct SetCaretPositionPackageTag { + long vmID; + AccessibleContext accessibleContext; + jint position; + } SetCaretPositionPackage; + + + /** + ****************************************************** + * Wrapping up all of the packages + ****************************************************** + */ + + /** + * What is the type of this package + */ + typedef enum PackageType { + + cMemoryMappedFileCreatedPackage = 0x11000, + + // many of these will go away... + cJavaVMCreatedPackage = 0x10000, + cJavaVMDestroyedPackage, + cWindowsATCreatedPackage, + cWindowsATDestroyedPackage, + cJavaVMPresentNotificationPackage, + cWindowsATPresentNotificationPackage, + + cReleaseJavaObjectPackage = 1, + cGetAccessBridgeVersionPackage = 2, + + cGetAccessibleContextFromHWNDPackage = 0x10, + cIsJavaWindowPackage, + cGetHWNDFromAccessibleContextPackage, + + cGetAccessibleContextAtPackage = 0x100, + cGetAccessibleContextWithFocusPackage, + cGetAccessibleContextInfoPackage, + cGetAccessibleChildFromContextPackage, + cGetAccessibleParentFromContextPackage, + cIsSameObjectPackage, + + cGetAccessibleTextInfoPackage = 0x200, + cGetAccessibleTextItemsPackage, + cGetAccessibleTextSelectionInfoPackage, + cGetAccessibleTextAttributeInfoPackage, + cGetAccessibleTextRectInfoPackage, + cGetAccessibleTextLineBoundsPackage, + cGetAccessibleTextRangePackage, + + cGetCurrentAccessibleValueFromContextPackage = 0x300, + cGetMaximumAccessibleValueFromContextPackage, + cGetMinimumAccessibleValueFromContextPackage, + + cAddAccessibleSelectionFromContextPackage = 0x400, + cClearAccessibleSelectionFromContextPackage, + cGetAccessibleSelectionFromContextPackage, + cGetAccessibleSelectionCountFromContextPackage, + cIsAccessibleChildSelectedFromContextPackage, + cRemoveAccessibleSelectionFromContextPackage, + cSelectAllAccessibleSelectionFromContextPackage, + + cAddJavaEventNotificationPackage = 0x900, + cRemoveJavaEventNotificationPackage, + cAddAccessibilityEventNotificationPackage, + cRemoveAccessibilityEventNotificationPackage, + + cPropertyChangePackage = 0x1000, + + cJavaShutdownPackage = 0x1010, + cFocusGainedPackage, + cFocusLostPackage, + + cCaretUpdatePackage = 0x1020, + + cMouseClickedPackage = 0x1030, + cMouseEnteredPackage, + cMouseExitedPackage, + cMousePressedPackage, + cMouseReleasedPackage, + + cMenuCanceledPackage = 0x1040, + cMenuDeselectedPackage, + cMenuSelectedPackage, + cPopupMenuCanceledPackage, + cPopupMenuWillBecomeInvisiblePackage, + cPopupMenuWillBecomeVisiblePackage, + + cPropertyCaretChangePackage = 0x1100, + cPropertyDescriptionChangePackage, + cPropertyNameChangePackage, + cPropertySelectionChangePackage, + cPropertyStateChangePackage, + cPropertyTextChangePackage, + cPropertyValueChangePackage, + cPropertyVisibleDataChangePackage, + cPropertyChildChangePackage, + cPropertyActiveDescendentChangePackage, + + + // AccessibleTable + cGetAccessibleTableInfoPackage = 0x1200, + cGetAccessibleTableCellInfoPackage, + + cGetAccessibleTableRowHeaderPackage, + cGetAccessibleTableColumnHeaderPackage, + + cGetAccessibleTableRowDescriptionPackage, + cGetAccessibleTableColumnDescriptionPackage, + + cGetAccessibleTableRowSelectionCountPackage, + cIsAccessibleTableRowSelectedPackage, + cGetAccessibleTableRowSelectionsPackage, + + cGetAccessibleTableColumnSelectionCountPackage, + cIsAccessibleTableColumnSelectedPackage, + cGetAccessibleTableColumnSelectionsPackage, + + cGetAccessibleTableRowPackage, + cGetAccessibleTableColumnPackage, + cGetAccessibleTableIndexPackage, + + cPropertyTableModelChangePackage, + + + // AccessibleRelationSet + cGetAccessibleRelationSetPackage = 0x1300, + + // AccessibleHypertext + cGetAccessibleHypertextPackage = 0x1400, + cActivateAccessibleHyperlinkPackage, + cGetAccessibleHyperlinkCountPackage, + cGetAccessibleHypertextExtPackage, + cGetAccessibleHypertextLinkIndexPackage, + cGetAccessibleHyperlinkPackage, + + // Accessible KeyBinding, Icon and Action + cGetAccessibleKeyBindingsPackage = 0x1500, + cGetAccessibleIconsPackage, + cGetAccessibleActionsPackage, + cDoAccessibleActionsPackage, + + // Utility methods + cSetTextContentsPackage = 0x1600, + cGetParentWithRolePackage, + cGetTopLevelObjectPackage, + cGetParentWithRoleElseRootPackage, + cGetObjectDepthPackage, + cGetActiveDescendentPackage, + + // Additional methods for Teton + cGetVirtualAccessibleNamePackage = 0x1700, + cRequestFocusPackage, + cSelectTextRangePackage, + cGetTextAttributesInRangePackage, + cGetSameTextAttributesInRangePackage, + cGetVisibleChildrenCountPackage, + cGetVisibleChildrenPackage, + cSetCaretPositionPackage, + cGetCaretLocationPackage + + + } PackageType; + + + /** + * Union of all package contents + */ + typedef union AllPackagesTag { + + // Initial Rendezvous packages + MemoryMappedFileCreatedPackage memoryMappedFileCreatedPackage; + + JavaVMCreatedPackage javaVMCreatedPackage; + JavaVMDestroyedPackage javaVMDestroyedPackage; + WindowsATCreatedPackage windowsATCreatedPackage; + WindowsATDestroyedPackage windowsATDestroyedPackage; + JavaVMPresentNotificationPackage javaVMPresentNotificationPackage; + WindowsATPresentNotificationPackage windowsATPresentNotificationPackage; + + // Core packages + ReleaseJavaObjectPackage releaseJavaObject; + GetAccessBridgeVersionPackage getAccessBridgeVersion; + + // Window packages + GetAccessibleContextFromHWNDPackage getAccessibleContextFromHWND; + GetHWNDFromAccessibleContextPackage getHWNDFromAccessibleContext; + + // AccessibleContext packages + GetAccessibleContextAtPackage getAccessibleContextAt; + GetAccessibleContextWithFocusPackage getAccessibleContextWithFocus; + GetAccessibleContextInfoPackage getAccessibleContextInfo; + GetAccessibleChildFromContextPackage getAccessibleChildFromContext; + GetAccessibleParentFromContextPackage getAccessibleParentFromContext; + + // AccessibleText packages + GetAccessibleTextInfoPackage getAccessibleTextInfo; + GetAccessibleTextItemsPackage getAccessibleTextItems; + GetAccessibleTextSelectionInfoPackage getAccessibleTextSelectionInfo; + GetAccessibleTextAttributeInfoPackage getAccessibleTextAttributeInfo; + GetAccessibleTextRectInfoPackage getAccessibleTextRectInfo; + GetAccessibleTextLineBoundsPackage getAccessibleTextLineBounds; + GetAccessibleTextRangePackage getAccessibleTextRange; + + // AccessibleValue packages + GetCurrentAccessibleValueFromContextPackage getCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextPackage getMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextPackage getMinimumAccessibleValueFromContext; + + // AccessibleSelection packages + AddAccessibleSelectionFromContextPackage addAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextPackage clearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextPackage getAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextPackage getAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextPackage isAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextPackage removeAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextPackage selectAllAccessibleSelectionFromContext; + + // Event Notification Registration packages + AddJavaEventNotificationPackage addJavaEventNotification; + RemoveJavaEventNotificationPackage removeJavaEventNotification; + AddAccessibilityEventNotificationPackage addAccessibilityEventNotification; + RemoveAccessibilityEventNotificationPackage removeAccessibilityEventNotification; + + // Event contents packages + // PropertyChangePackage propertyChange; + PropertyCaretChangePackage propertyCaretChangePackage; + PropertyDescriptionChangePackage propertyDescriptionChangePackage; + PropertyNameChangePackage propertyNameChangePackage; + PropertySelectionChangePackage propertySelectionChangePackage; + PropertyStateChangePackage propertyStateChangePackage; + PropertyTextChangePackage propertyTextChangePackage; + PropertyValueChangePackage propertyValueChangePackage; + PropertyVisibleDataChangePackage propertyVisibleDataChangePackage; + PropertyChildChangePackage propertyChildChangePackage; + PropertyActiveDescendentChangePackage propertyActiveDescendentChangePackage; + + PropertyTableModelChangePackage propertyTableModelChangePackage; + + JavaShutdownPackage JavaShutdown; + FocusGainedPackage focusGained; + FocusLostPackage focusLost; + + CaretUpdatePackage caretUpdate; + + MouseClickedPackage mouseClicked; + MouseEnteredPackage mouseEntered; + MouseExitedPackage mouseExited; + MousePressedPackage mousePressed; + MouseReleasedPackage mouseReleased; + + MenuCanceledPackage menuCanceled; + MenuDeselectedPackage menuDeselected; + MenuSelectedPackage menuSelected; + PopupMenuCanceledPackage popupMenuCanceled; + PopupMenuWillBecomeInvisiblePackage popupMenuWillBecomeInvisible; + PopupMenuWillBecomeVisiblePackage popupMenuWillBecomeVisible; + + // AccessibleRelationSet + GetAccessibleRelationSetPackage getAccessibleRelationSet; + + // AccessibleHypertext + GetAccessibleHypertextPackage _getAccessibleHypertext; + ActivateAccessibleHyperlinkPackage _activateAccessibleHyperlink; + GetAccessibleHyperlinkCountPackage _getAccessibleHyperlinkCount; + GetAccessibleHypertextExtPackage _getAccessibleHypertextExt; + GetAccessibleHypertextLinkIndexPackage _getAccessibleHypertextLinkIndex; + GetAccessibleHyperlinkPackage _getAccessibleHyperlink; + + // Accessible KeyBinding, Icon and Action + GetAccessibleKeyBindingsPackage getAccessibleKeyBindings; + GetAccessibleIconsPackage getAccessibleIcons; + GetAccessibleActionsPackage getAccessibleActions; + DoAccessibleActionsPackage doAccessibleActions; + + // utility methods + SetTextContentsPackage _setTextContents; + GetParentWithRolePackage _getParentWithRole; + GetTopLevelObjectPackage _getTopLevelObject; + GetParentWithRoleElseRootPackage _getParentWithRoleElseRoot; + GetObjectDepthPackage _getObjectDepth; + GetActiveDescendentPackage _getActiveDescendent; + + // Additional methods for Teton + GetVirtualAccessibleNamePackage _getVirtualAccessibleName; + RequestFocusPackage _requestFocus; + SelectTextRangePackage _selectTextRange; + GetTextAttributesInRangePackage _getTextAttributesInRange; + GetVisibleChildrenCountPackage _getVisibleChildrenCount; + GetVisibleChildrenPackage _getVisibleChildren; + SetCaretPositionPackage _setCaretPosition; + + } AllPackages; + + + /** + * Union of all Java-initiated package contents + */ + typedef union JavaInitiatedPackagesTag { + + // Initial Rendezvous packages + JavaVMCreatedPackage javaVMCreatedPackage; + JavaVMDestroyedPackage javaVMDestroyedPackage; + JavaVMPresentNotificationPackage javaVMPresentNotificationPackage; + + // Event contents packages + PropertyCaretChangePackage propertyCaretChangePackage; + PropertyDescriptionChangePackage propertyDescriptionChangePackage; + PropertyNameChangePackage propertyNameChangePackage; + PropertySelectionChangePackage propertySelectionChangePackage; + PropertyStateChangePackage propertyStateChangePackage; + PropertyTextChangePackage propertyTextChangePackage; + PropertyValueChangePackage propertyValueChangePackage; + PropertyVisibleDataChangePackage propertyVisibleDataChangePackage; + PropertyChildChangePackage propertyChildChangePackage; + PropertyActiveDescendentChangePackage propertyActiveDescendentChangePackage; + + PropertyTableModelChangePackage propertyTableModelChangePackage; + + JavaShutdownPackage JavaShutdown; + FocusGainedPackage focusGained; + FocusLostPackage focusLost; + + CaretUpdatePackage caretUpdate; + + MouseClickedPackage mouseClicked; + MouseEnteredPackage mouseEntered; + MouseExitedPackage mouseExited; + MousePressedPackage mousePressed; + MouseReleasedPackage mouseReleased; + + MenuCanceledPackage menuCanceled; + MenuDeselectedPackage menuDeselected; + MenuSelectedPackage menuSelected; + PopupMenuCanceledPackage popupMenuCanceled; + PopupMenuWillBecomeInvisiblePackage popupMenuWillBecomeInvisible; + PopupMenuWillBecomeVisiblePackage popupMenuWillBecomeVisible; + + } JavaInitiatedPackages; + + + /** + * Union of all Windows-initiated package contents + */ + typedef union WindowsInitiatedPackagesTag { + + // Initial Rendezvous packages + MemoryMappedFileCreatedPackage memoryMappedFileCreatedPackage; + + WindowsATCreatedPackage windowsATCreatedPackage; + WindowsATDestroyedPackage windowsATDestroyedPackage; + WindowsATPresentNotificationPackage windowsATPresentNotificationPackage; + + // Core packages + ReleaseJavaObjectPackage releaseJavaObject; + GetAccessBridgeVersionPackage getAccessBridgeVersion; + + // Window packages + GetAccessibleContextFromHWNDPackage getAccessibleContextFromHWND; + GetHWNDFromAccessibleContextPackage getHWNDFromAccessibleContext; + + // AccessibleContext packages + GetAccessibleContextAtPackage getAccessibleContextAt; + GetAccessibleContextWithFocusPackage getAccessibleContextWithFocus; + GetAccessibleContextInfoPackage getAccessibleContextInfo; + GetAccessibleChildFromContextPackage getAccessibleChildFromContext; + GetAccessibleParentFromContextPackage getAccessibleParentFromContext; + + // AccessibleText packages + GetAccessibleTextInfoPackage getAccessibleTextInfo; + GetAccessibleTextItemsPackage getAccessibleTextItems; + GetAccessibleTextSelectionInfoPackage getAccessibleTextSelectionInfo; + GetAccessibleTextAttributeInfoPackage getAccessibleTextAttributeInfo; + GetAccessibleTextRectInfoPackage getAccessibleTextRectInfo; + GetAccessibleTextLineBoundsPackage getAccessibleTextLineBounds; + GetAccessibleTextRangePackage getAccessibleTextRange; + + // AccessibleValue packages + GetCurrentAccessibleValueFromContextPackage getCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextPackage getMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextPackage getMinimumAccessibleValueFromContext; + + // AccessibleSelection packages + AddAccessibleSelectionFromContextPackage addAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextPackage clearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextPackage getAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextPackage getAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextPackage isAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextPackage removeAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextPackage selectAllAccessibleSelectionFromContext; + + // Event Notification Registration packages + AddJavaEventNotificationPackage addJavaEventNotification; + RemoveJavaEventNotificationPackage removeJavaEventNotification; + AddAccessibilityEventNotificationPackage addAccessibilityEventNotification; + RemoveAccessibilityEventNotificationPackage removeAccessibilityEventNotification; + + // AccessibleTable + GetAccessibleTableInfoPackage _getAccessibleTableInfo; + GetAccessibleTableCellInfoPackage _getAccessibleTableCellInfo; + + GetAccessibleTableRowHeaderPackage _getAccessibleTableRowHeader; + GetAccessibleTableColumnHeaderPackage _getAccessibleTableColumnHeader; + + GetAccessibleTableRowDescriptionPackage _getAccessibleTableRowDescription; + GetAccessibleTableColumnDescriptionPackage _getAccessibleTableColumnDescription; + + GetAccessibleTableRowSelectionCountPackage _getAccessibleTableRowSelectionCount; + IsAccessibleTableRowSelectedPackage _isAccessibleTableRowSelected; + GetAccessibleTableRowSelectionsPackage _getAccessibleTableRowSelections; + + GetAccessibleTableColumnSelectionCountPackage _getAccessibleTableColumnSelectionCount; + IsAccessibleTableColumnSelectedPackage _isAccessibleTableColumnSelected; + GetAccessibleTableColumnSelectionsPackage _getAccessibleTableColumnSelections; + + GetAccessibleTableRowPackage _getAccessibleTableRow; + GetAccessibleTableColumnPackage _getAccessibleTableColumn; + GetAccessibleTableIndexPackage _getAccessibleTableIndex; + + // AccessibleRelationSet + GetAccessibleRelationSetPackage _getAccessibleRelationSet; + + // Accessible KeyBindings, Icons and Actions + GetAccessibleKeyBindingsPackage _getAccessibleKeyBindings; + GetAccessibleIconsPackage _getAccessibleIcons; + GetAccessibleActionsPackage _getAccessibleActions; + DoAccessibleActionsPackage _doAccessibleActions; + + + IsSameObjectPackage _isSameObject; + + // utility methods + SetTextContentsPackage _setTextContents; + GetParentWithRolePackage _getParentWithRole; + GetTopLevelObjectPackage _getTopLevelObject; + GetParentWithRoleElseRootPackage _getParentWithRoleElseRoot; + GetObjectDepthPackage _getObjectDepth; + GetActiveDescendentPackage _getActiveDescendent; + + // Additional methods for Teton + GetVirtualAccessibleNamePackage _getVirtualAccessibleName; + RequestFocusPackage _requestFocus; + SelectTextRangePackage _selectTextRange; + GetTextAttributesInRangePackage _getTextAttributesInRange; + GetVisibleChildrenCountPackage _getVisibleChildrenCount; + GetVisibleChildrenPackage _getVisibleChildren; + SetCaretPositionPackage _setCaretPosition; + + + } WindowsInitiatedPackages; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/demos/java/jni/gs_jni/include/win32/jawt_md.h b/demos/java/jni/gs_jni/include/win32/jawt_md.h new file mode 100644 index 00000000..66e7256a --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/jawt_md.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef _JAVASOFT_JAWT_MD_H_ +#define _JAVASOFT_JAWT_MD_H_ + +#include <windows.h> +#include "jawt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Win32-specific declarations for AWT native interface. + * See notes in jawt.h for an example of use. + */ +typedef struct jawt_Win32DrawingSurfaceInfo { + /* Native window, DDB, or DIB handle */ + union { + HWND hwnd; + HBITMAP hbitmap; + void* pbits; + }; + /* + * This HDC should always be used instead of the HDC returned from + * BeginPaint() or any calls to GetDC(). + */ + HDC hdc; + HPALETTE hpalette; +} JAWT_Win32DrawingSurfaceInfo; + +#ifdef __cplusplus +} +#endif + +#endif /* !_JAVASOFT_JAWT_MD_H_ */ diff --git a/demos/java/jni/gs_jni/include/win32/jni_md.h b/demos/java/jni/gs_jni/include/win32/jni_md.h new file mode 100644 index 00000000..38080013 --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/jni_md.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef _JAVASOFT_JNI_MD_H_ +#define _JAVASOFT_JNI_MD_H_ + +#define JNIEXPORT __declspec(dllexport) +#define JNIIMPORT __declspec(dllimport) +#define JNICALL __stdcall + +typedef long jint; +typedef __int64 jlong; +typedef signed char jbyte; + +#endif /* !_JAVASOFT_JNI_MD_H_ */ diff --git a/demos/java/jni/gs_jni/jni_util.cpp b/demos/java/jni/gs_jni/jni_util.cpp new file mode 100644 index 00000000..0a99f8bc --- /dev/null +++ b/demos/java/jni/gs_jni/jni_util.cpp @@ -0,0 +1,593 @@ +#include "jni_util.h" + +#include <exception> +#include <string.h> +#include <varargs.h> +#include <string> + +using namespace util; + +jfieldID util::getFieldID(JNIEnv *env, jobject object, const char *field, const char *sig) +{ + if (env == NULL || object == NULL || field == NULL || sig == NULL) + return NULL; + + jclass clazz = env->GetObjectClass(object); + jfieldID fieldID = env->GetFieldID(clazz, field, sig); + if (fieldID == NULL) + { + const char *className = getClassName(env, clazz); + + const std::string full = std::string(className) + "." + field; + throwNoSuchFieldError(env, full.c_str()); + + freeClassName(className); + + return NULL; + } + + return fieldID; +} + +jmethodID util::getMethodID(JNIEnv *env, jobject object, const char *method, const char *sig) +{ + if (env == NULL || object == NULL || method == NULL || sig == NULL) + return NULL; + + jclass clazz = env->GetObjectClass(object); + + jmethodID methodID = env->GetMethodID(clazz, method, sig); + if (methodID == NULL) + { + const char *className = getClassName(env, clazz); + + const std::string full = std::string(className) + "." + method + sig; + throwNoSuchMethodError(env, full.c_str()); + + freeClassName(className); + + env->DeleteLocalRef(clazz); + return NULL; + } + + env->DeleteLocalRef(clazz); + return methodID; +} + + +void util::setByteArrayField(JNIEnv *env, jobject object, const char *field, jbyteArray value) +{ + jfieldID fieldID = getFieldID(env, object, field, "[B"); + if (fieldID == NULL) + return; + + env->SetObjectField(object, fieldID, value); +} + +void util::setByteArrayField(JNIEnv *env, jobject object, const char *field, const char *string) +{ + jsize len = (jsize)strlen(string); + jbyteArray byteArray = env->NewByteArray(len); + env->SetByteArrayRegion(byteArray, 0, len, (const signed char *)string); + setByteArrayField(env, object, field, byteArray); +} + +jbyteArray util::getByteArrayField(JNIEnv *env, jobject object, const char *field) +{ + jfieldID fieldID = getFieldID(env, object, field, "[B"); + if (fieldID == NULL) + return NULL; + + return (jbyteArray)env->GetObjectField(object, fieldID); +} + +char **util::jbyteArray2DToCharArray(JNIEnv *env, jobjectArray array) +{ + jboolean copy = false; + jsize len = env->GetArrayLength(array); + char **result = new char*[len]; + for (jsize i = 0; i < len; i++) + { + jbyteArray byteArrayObject = (jbyteArray)env->GetObjectArrayElement(array, i); + char *elem = (char *)env->GetByteArrayElements(byteArrayObject, ©); + jsize slen = strlen(elem); + char *nstring = new char[slen + 1LL]; + nstring[slen] = 0; + memcpy(nstring, elem, slen); + result[i] = nstring; + } + return result; +} + +void util::delete2DByteArray(int count, char **array) +{ + for (int i = 0; i < count; i++) + { + delete[] array[i]; + array[i] = NULL; + } + delete[] array; +} + +void util::setLongField(JNIEnv *env, jobject object, const char *field, jlong value) +{ + jfieldID fieldID = getFieldID(env, object, field, "J"); + if (fieldID == NULL) + return; + + env->SetLongField(object, fieldID, value); +} + +jlong util::getLongField(JNIEnv *env, jobject object, const char *field) +{ + jfieldID fieldID = getFieldID(env, object, field, "J"); + if (fieldID == NULL) + return 0LL; + + return env->GetLongField(object, fieldID); +} + +void util::setIntField(JNIEnv *env, jobject object, const char *field, jint value) +{ + jfieldID fieldID = getFieldID(env, object, field, "I"); + if (fieldID == NULL) + return; + + env->SetIntField(object, fieldID, value); +} + +jint util::getIntField(JNIEnv *env, jobject object, const char *field) +{ + jfieldID fieldID = getFieldID(env, object, field, "I"); + if (fieldID == NULL) + return 0; + + return env->GetIntField(object, fieldID); +} + +int util::callIntMethod(JNIEnv *env, jobject object, const char *method, const char *sig, ...) +{ + jmethodID methodID = getMethodID(env, object, method, sig); + if (methodID == NULL) + return 0; + + va_list args; + int result; + va_start(args, sig); + result = env->CallIntMethodV(object, methodID, args); + va_end(args); + + return result; +} + +void util::setObjectField(JNIEnv *env, jobject object, const char *field, jobject value) +{ + jfieldID fieldID = getFieldID(env, object, field, "Ljava/lang/Object;"); + if (fieldID == NULL) + return; + + env->SetObjectField(object, fieldID, value); +} + +jobject util::getObjectField(JNIEnv *env, jobject object, const char *field) +{ + + jfieldID fieldID = getFieldID(env, object, field, "Ljava/lang/Object;"); + if (fieldID == NULL) + return 0; + + return env->GetObjectField(object, fieldID); +} + +jobject util::toWrapperType(JNIEnv *env, jboolean value) +{ + jclass clazz; + static const char *const className = "java/lang/Boolean"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "<init>", "(Z)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jbyte value) +{ + jclass clazz; + static const char *const className = "java/lang/Byte"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "<init>", "(Z)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jchar value) +{ + jclass clazz; + static const char *const className = "java/lang/Character"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "<init>", "(C)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jshort value) +{ + jclass clazz; + static const char *const className = "java/lang/Short"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "<init>", "(S)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jint value) +{ + jclass clazz; + static const char *const className = "java/lang/Integer"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "<init>", "(I)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jlong value) +{ + jclass clazz; + static const char *const className = "java/lang/Long"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "<init>", "(J)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jfloat value) +{ + jclass clazz; + static const char *const className = "java/lang/Float"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "<init>", "(F)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jdouble value) +{ + jclass clazz; + static const char *const className = "java/lang/Double"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "<init>", "(D)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jboolean util::toBoolean(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jboolean on NULL jobject"); + return JNI_FALSE; + } + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "Z"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetBooleanField(wrapped, fieldID); +} + +jbyte util::toByte(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jbyte on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "B"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetByteField(wrapped, fieldID); +} + +jchar util::toChar(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jchar on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "C"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetCharField(wrapped, fieldID); +} + +jshort util::toShort(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jshort on NULL jobject"); + return 0; + } + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "S"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetShortField(wrapped, fieldID); +} + +jint util::toInt(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jint on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "I"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetIntField(wrapped, fieldID); +} + +jlong util::toLong(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jlong on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "J"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetLongField(wrapped, fieldID); +} + +jfloat util::toFloat(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jfloat on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "F"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetFloatField(wrapped, fieldID); +} + +jdouble util::toDouble(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jdouble on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "D"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetDoubleField(wrapped, fieldID); +} + +jint util::throwNoClassDefError(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "java/lang/NoClassDefFoundError"; + + exClass = env->FindClass(className); + if (exClass == NULL) + throw std::exception("Failed to find java.lang.NoClassDefFoundError"); + + return env->ThrowNew(exClass, message); +} + +jint util::throwNullPointerException(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "java/lang/NullPointerException"; + + exClass = env->FindClass(className); + if (exClass == NULL) + return throwNoClassDefError(env, className); + + return env->ThrowNew(exClass, message); +} + +jint util::throwNoSuchMethodError(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "java/lang/NoSuchMethodError"; + + exClass = env->FindClass(className); + if (exClass == NULL) + return throwNoClassDefError(env, className); + + return env->ThrowNew(exClass, message); +} + +jint util::throwNoSuchFieldError(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "java/lang/NoSuchFieldError"; + + exClass = env->FindClass(className); + if (exClass == NULL) + return throwNoClassDefError(env, className); + + return env->ThrowNew(exClass, message); +} + +jint util::throwAllocationError(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "com/artifex/gsjava/util/AllocationError"; + + exClass = env->FindClass(className); + if (exClass == NULL) + return throwNoClassDefError(env, className); + + return env->ThrowNew(exClass, message); +} + +jint util::throwIllegalArgumentException(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "java/lang/IllegalArgumentException"; + + exClass = env->FindClass(className); + if (exClass == NULL) + return throwNoClassDefError(env, className); + + return env->ThrowNew(exClass, message); +} + +const char *util::getClassName(JNIEnv *env, jclass clazz) +{ + jclass clsClazz = env->GetObjectClass(clazz); + + jmethodID methodId = env->GetMethodID(clsClazz, "getName", "()Ljava/lang/String;"); + jstring className = (jstring)env->CallObjectMethod(clazz, methodId); + const char *chars = env->GetStringUTFChars(className, NULL); + jsize len = env->GetStringLength(className); + char *cstr = new char[len + 1LL]; + if (cstr == NULL) + { + env->ReleaseStringUTFChars(className, chars); + env->DeleteLocalRef(className); + return NULL; + } + cstr[len] = 0; + memcpy(cstr, chars, len); + env->ReleaseStringUTFChars(className, chars); + env->DeleteLocalRef(className); + return cstr; +} + +void util::freeClassName(const char *className) +{ + delete[] className; +} + +util::Reference::Reference(JNIEnv *env) : Reference(m_env, NULL) +{ +} + +util::Reference::Reference(JNIEnv *env, jobject object) : m_env(env), m_object(NULL) +{ + if (!object) + { + static const char *const CLASS_NAME = "com/artifex/gsjava/util/Reference"; + jclass refClass = env->FindClass(CLASS_NAME); + if (refClass == NULL) + { + throwNoClassDefError(env, CLASS_NAME); + return; + } + jmethodID constructor = env->GetMethodID(refClass, "<init>", "()V"); + if (constructor == NULL) + { + throwNoSuchMethodError(env, "com/artifex/gsjava/util/Reference.<init>()V"); + return; + } + object = m_env->NewObject(refClass, constructor); + if (object == NULL) + return; + } + m_object = m_env->NewGlobalRef(object); +} + +util::Reference::~Reference() +{ + if (m_object) + m_env->DeleteGlobalRef(m_object); +} diff --git a/demos/java/jni/gs_jni/jni_util.h b/demos/java/jni/gs_jni/jni_util.h new file mode 100644 index 00000000..6439712e --- /dev/null +++ b/demos/java/jni/gs_jni/jni_util.h @@ -0,0 +1,377 @@ +#pragma once + +#include <jni.h> + +#define REFERENCE_VALUE_FILED_NAME "value" + +namespace util +{ + + typedef class Reference Reference; + typedef class LongReference LongReference; + typedef class IntReference IntReference; + typedef class ByteArrayReference ByteArrayReference; + + /*! + Returns the field ID of a field inside an object, checking if it exists and ensuring + all arguments are non-null. If the field is not found, the Java exception NoSuchFieldError + will be thrown and NULL will be returned. + + @param env A JNIEnv. + @param object The object to find the field in. + @param field The name of the field. + @param sig The field's signature. + + @return The field ID, or NULL if the field is not found, or any argument is NULL. + */ + jfieldID getFieldID(JNIEnv *env, jobject object, const char *field, const char *sig); + + /*! + Returns the method ID of a method inside an object, checking if it exists and ensuring + all arguments are non-null. If the method is not found, the Java exception NoSuchMethodError + will be thrown and NULL will be returned. + + @param env A JNIEnv. + @param object The object to find the method in. + @param method The name of the method. + @param sig The method's signature. + + @return The method ID, or NULL if the method is not found, or any argument is NULL. + */ + jmethodID getMethodID(JNIEnv *env, jobject object, const char *method, const char *sig); + + /*! + Sets a byte array field of an object. + + @param env A JNIEnv. + @param object The object containing a byte array field. + @param field The name of the field to set. + @param value The value to set the field to. + */ + void setByteArrayField(JNIEnv *env, jobject object, const char *field, jbyteArray value); + + /*! + Sets a byte array field of an object. + + @param env A JNIEnv. + @param object The object containing a byte array field. + @param field The name of the field to set. + @param string The value to set the field to. + */ + void setByteArrayField(JNIEnv *env, jobject object, const char *field, const char *string); + + /*! + Returns the value of a byte array field in an object. + + @param env A JNIEnv. + @param object The object to get the byte array field from. + @param field The name of the field. + + @return The value of the field. + */ + jbyteArray getByteArrayField(JNIEnv *env, jobject object, const char *field); + + /*! + Converts a 2D Java byte array to a 2D C++ char array. The returned + value should be used in delete2DByteArray() when finished. + + @param env A JNIEnv. + @param array The array to convert. + + @return The 2D C++ char array. + */ + char **jbyteArray2DToCharArray(JNIEnv *env, jobjectArray array); + + /*! + Deletes a 2D C++ char array allocated from jbyteArray2DToCharArray(). + + @param count The size of the array. + @param array The array to delete. + */ + void delete2DByteArray(int count, char **array); + + /*! + Sets a long field of an object. + + @param env A JNIEnv. + @param object The object containing a long field. + @param field The name of the field to set. + @param value The value to set the field to. + */ + void setLongField(JNIEnv *env, jobject object, const char *field, jlong value); + + /*! + Returns the value of a long field in an object. + + @param env A JNIEnv. + @param object The object to get the long field from. + @param field The name of the long field. + + @return The value of the long field. + */ + jlong getLongField(JNIEnv *env, jobject object, const char *field); + + /*! + Sets a int field of an object. + + @param env A JNIEnv. + @param object The object containing a int field. + @param field The name of the field to set. + @param value The value to set the field to. + */ + void setIntField(JNIEnv *env, jobject object, const char *field, jint value); + + /*! + Returns the value of a int field in an object. + + @param env A JNIEnv. + @param object The object to get the int field from. + @param field The name of the int field. + + @return The value of the int field. + */ + jint getIntField(JNIEnv *env, jobject object, const char *field); + + /*! + Calls a Java method returning an int. + + @param env A JNIEnv. + @param object The object containing the int method. + @param name The name of the method. + @param sig The method's signature. + @param ... The varargs representing the object's arguments in their respective order. + */ + int callIntMethod(JNIEnv *env, jobject object, const char *name, const char *sig, ...); + + void setObjectField(JNIEnv *env, jobject object, const char *field, jobject value); + + jobject getObjectField(JNIEnv *env, jobject object, const char *field); + + jobject toWrapperType(JNIEnv *env, jboolean value); + jobject toWrapperType(JNIEnv *env, jbyte value); + jobject toWrapperType(JNIEnv *env, jchar value); + jobject toWrapperType(JNIEnv *env, jshort value); + jobject toWrapperType(JNIEnv *env, jint value); + jobject toWrapperType(JNIEnv *env, jlong value); + jobject toWrapperType(JNIEnv *env, jfloat value); + jobject toWrapperType(JNIEnv *env, jdouble value); + + jboolean toBoolean(JNIEnv *env, jobject wrapped); + jbyte toByte(JNIEnv *env, jobject wrapped); + jchar toChar(JNIEnv *env, jobject wrapped); + jshort toShort(JNIEnv *env, jobject wrapped); + jint toInt(JNIEnv *env, jobject wrapped); + jlong toLong(JNIEnv *env, jobject wrapped); + jfloat toFloat(JNIEnv *env, jobject wrapped); + jdouble toDouble(JNIEnv *env, jobject wrapped); + + /*! + Throws the Java exception java.lang.NoClassDefFoundError with a message. The function + calling this function should immediately return after calling this function. + + @param env A JNIEnv. + @param message The message of the error. + + @return The result of throwing the error. + */ + jint throwNoClassDefError(JNIEnv *env, const char *message); + + /*! + Throws the Java exception java.lang.NullPointerException with a message. The function + calling this function should immediately return after calling this function. + + @param env A JNIEnv. + @param message The message of the exception. + + @return The result of throwing the exception. + */ + jint throwNullPointerException(JNIEnv *env, const char *message); + + /*! + Throws the Java exception java.lang.NoSuchMethodError with a message. The function + calling this function should immediately return after calling this function. + + @param env A JNIEnv. + @param message The message of the exception. + + @return The result of throwing the exception. + */ + jint throwNoSuchMethodError(JNIEnv *env, const char *message); + + /*! + Throws the Java exception java.lang.NoSuchFieldError with a message. The function + calling this function should immediately return after calling this function. + + @param env A JNIEnv. + @param message The message of the exception. + + @return The result of throwing the exception. + */ + jint throwNoSuchFieldError(JNIEnv *env, const char *message); + + /*! + Throws the Java exception com.artifex.gsjava.util.AllocationError with a message. + The function calling this function should immediately return after calling this function. + + @param env A JNIEnv. + @param message The message of the exception. + + @return The result of throwing the exception. + */ + jint throwAllocationError(JNIEnv *env, const char *message); + + jint throwIllegalArgumentException(JNIEnv *env, const char *message); + + /*! + Returns the name of a jclass. The name is dynamically allocated and after usage, + freeClassName() should be called. + + @param env A JNIEnv. + @param clazz A jclass. + + @return The name of the class, or NULL if env or clazz are NULL. + */ + const char *getClassName(JNIEnv *env, jclass clazz); + + /*! + Frees a class name generated from getClassName(). + + @param className The className generated from getClassName(). + */ + void freeClassName(const char *className); + + class Reference + { + public: + + static inline void setValueField(JNIEnv *env, jobject object, jobject value) + { + setObjectField(env, object, "value", value); + } + + static inline jobject getValueField(JNIEnv *env, jobject object) + { + return getObjectField(env, object, "value"); + } + + private: + JNIEnv *m_env; + jobject m_object; + public: + /*! + Creates a new reference. + + @param env A JNIEnv. + */ + Reference(JNIEnv *env); + + /*! + Creates a new reference. + + @param env A JNIEnv. + @param object A com.artifex.gsjava.util.Reference or NULL if one + should be created. + */ + Reference(JNIEnv *env, jobject object); + ~Reference(); + + inline jobject object() + { + return m_object; + } + + inline jobject value() + { + return getValueField(m_env, m_object); + } + + inline jboolean booleanValue() + { + jobject val = value(); + return val ? toBoolean(m_env, val) : JNI_FALSE; + } + + inline jbyte byteValue() + { + jobject val = value(); + return val ? toByte(m_env, val) : 0; + } + + inline jchar charValue() + { + jobject val = value(); + return val ? toChar(m_env, val) : 0; + } + + inline jshort shortValue() + { + jobject val = value(); + return val ? toShort(m_env, val) : 0; + } + + inline jint intValue() + { + jobject val = value(); + return val ? toInt(m_env, val) : 0; + } + + inline jlong longValue() + { + jobject val = value(); + return val ? toLong(m_env, val) : 0LL; + } + + inline jfloat floatValue() + { + jobject val = value(); + return val ? toFloat(m_env, val) : 0.0f; + } + + inline jdouble doubleValue() + { + jobject val = value(); + return val ? toDouble(m_env, val) : 0.0; + } + + inline void set(jobject value) + { + setValueField(m_env, m_object, value); + } + + inline void set(jboolean value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jbyte value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jshort value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jint value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jlong value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jfloat value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jdouble value) + { + set(toWrapperType(m_env, value)); + } + }; + +} |