Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Rashbrook2014-11-18 11:30:57 -0500
committerlshanmugam2014-12-11 06:34:41 -0500
commitf6e8d7c3b98020ef2b8fbc5fc5f9dd3dbbba612e (patch)
tree06a0e386201dc19f8af03fe797b9a1cb946eea1f
parente31bc0cb3b632b6f3f11bd1e3d2b18904e6671ab (diff)
downloadeclipse.platform.swt-xulrunner-31.tar.gz
eclipse.platform.swt-xulrunner-31.tar.xz
eclipse.platform.swt-xulrunner-31.zip
Bug 452138 - Reduce number of error-prone manual steps needed to supportxulrunner-31
new versions of XULRunner Provide an overload of VtblCall which can generically call the majority of methods used by SWT. Provide a way for interfaces to invoke VtblCall without having to manually provide vtbl offsets. Change-Id: Ide35e0e258d0903319ca4e3e9789362148480ce6 Signed-off-by: Neil Rashbrook <neil@parkwaycc.co.uk> Signed-off-by: Lakshmi Shanmugam <lshanmug@in.ibm.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/library/xpcom.cpp141
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/XPCOM.java11
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIInterfaceInfo.java50
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIInterfaceInfoManager.java51
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsISupports.java53
5 files changed, 305 insertions, 1 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/library/xpcom.cpp b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/library/xpcom.cpp
index a8ee3cc01f..89c9d19169 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/library/xpcom.cpp
+++ b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/library/xpcom.cpp
@@ -12,6 +12,10 @@
#include "swt.h"
#include "xpcom_structs.h"
#include "xpcom_stats.h"
+#include "nsCOMPtr.h"
+#include "nsIServiceManager.h"
+#include "xptinfo.h"
+#include "xptcall.h"
#ifndef XPCOM_NATIVE
#define XPCOM_NATIVE(func) Java_org_eclipse_swt_internal_mozilla_XPCOM_##func
@@ -6813,6 +6817,142 @@ fail:
}
#endif
+#if (!defined(NO__1VtblCall__II_3Ljava_lang_Object_2) && !defined(JNI64)) || (!defined(NO__1VtblCall__IJ_3Ljava_lang_Object_2) && defined(JNI64))
+#ifndef JNI64
+extern "C" JNIEXPORT jint JNICALL XPCOM_NATIVE(_1VtblCall__II_3Ljava_lang_Object_2)(JNIEnv *env, jclass that, jint fnNumber, jintLong supports, jobjectArray args);
+JNIEXPORT jint JNICALL XPCOM_NATIVE(_1VtblCall__II_3Ljava_lang_Object_2)(JNIEnv *env, jclass that, jint fnNumber, jintLong supports, jobjectArray args)
+#else
+extern "C" JNIEXPORT jint JNICALL XPCOM_NATIVE(_1VtblCall__IJ_3Ljava_lang_Object_2)(JNIEnv *env, jclass that, jint fnNumber, jintLong supports, jobjectArray args);
+JNIEXPORT jint JNICALL XPCOM_NATIVE(_1VtblCall__IJ_3Ljava_lang_Object_2)(JNIEnv *env, jclass that, jint fnNumber, jintLong supports, jobjectArray args)
+#endif
+{
+#ifndef JNI64
+ XPCOM_NATIVE_ENTER(env, that, _1VtblCall__II_3Ljava_lang_Object_2_FUNC);
+#else
+ XPCOM_NATIVE_ENTER(env, that, _1VtblCall__IJ_3Ljava_lang_Object_2_FUNC);
+#endif
+
+ jsize count = env->GetArrayLength(args);
+ nsXPTCVariant *variants = new nsXPTCVariant[count];
+ memset(variants, 0, count * sizeof(nsXPTCVariant));
+
+ for (jsize index = 0; index < count; index++) {
+ jobject arg = env->GetObjectArrayElement(args, index);
+ jclass clazz = env->GetObjectClass(arg);
+ jmethodID methodID = env->GetMethodID(env->GetObjectClass(clazz), "getName", "()Ljava/lang/String;");
+ jstring nameStr = (jstring)env->CallObjectMethod(clazz, methodID);
+ char name[20];
+ env->GetStringUTFRegion(nameStr, 0, env->GetStringLength(nameStr), name);
+
+ if (name[0] == '[') {
+ variants[index].SetPtrIsData();
+ switch (name[1]) {
+ case 'B':
+ variants[index].ptr = env->GetByteArrayElements((jbyteArray)arg, NULL);
+ variants[index].type = TD_INT8;
+ break;
+ case 'C':
+ variants[index].ptr = env->GetCharArrayElements((jcharArray)arg, NULL);
+ variants[index].type = TD_WCHAR;
+ break;
+ case 'D':
+ variants[index].ptr = env->GetDoubleArrayElements((jdoubleArray)arg, NULL);
+ variants[index].type = TD_DOUBLE;
+ break;
+ case 'F':
+ variants[index].ptr = env->GetFloatArrayElements((jfloatArray)arg, NULL);
+ variants[index].type = TD_FLOAT;
+ break;
+ case 'I':
+ variants[index].ptr = env->GetIntArrayElements((jintArray)arg, NULL);
+ variants[index].type = TD_INT32;
+ break;
+ case 'L':
+ variants[index].ptr = env->GetLongArrayElements((jlongArray)arg, NULL);
+ variants[index].type = TD_INT64;
+ break;
+ case 'S':
+ variants[index].ptr = env->GetShortArrayElements((jshortArray)arg, NULL);
+ variants[index].type = TD_INT16;
+ break;
+ }
+ } else if (strncmp(name, "java.lang.", 10) == 0) {
+ switch (name[10]) {
+ case 'B':
+ variants[index].val.i8 = env->CallByteMethod(arg, env->GetMethodID(clazz, "byteValue", "()B"));
+ variants[index].type = TD_INT8;
+ break;
+ case 'C':
+ variants[index].val.wc = env->CallCharMethod(arg, env->GetMethodID(clazz, "charValue", "()C"));
+ variants[index].type = TD_WCHAR;
+ break;
+ case 'D':
+ variants[index].val.d = env->CallDoubleMethod(arg, env->GetMethodID(clazz, "doubleValue", "()D"));
+ variants[index].type = TD_DOUBLE;
+ break;
+ case 'F':
+ variants[index].val.f = env->CallFloatMethod(arg, env->GetMethodID(clazz, "floatValue", "()F"));
+ variants[index].type = TD_FLOAT;
+ break;
+ case 'I':
+ variants[index].val.i32 = env->CallIntMethod(arg, env->GetMethodID(clazz, "intValue", "()I"));
+ variants[index].type = TD_INT32;
+ break;
+ case 'L':
+ variants[index].val.i64 = env->CallLongMethod(arg, env->GetMethodID(clazz, "longValue", "()L"));
+ variants[index].type = TD_INT64;
+ break;
+ case 'S':
+ variants[index].val.i16 = env->CallShortMethod(arg, env->GetMethodID(clazz, "shortValue", "()S"));
+ variants[index].type = TD_INT16;
+ break;
+ }
+ }
+ }
+
+ jint rc = NS_InvokeByIndex((nsISupports*)supports, fnNumber, count, variants);
+
+ for (jsize index = 0; index < count; index++) {
+ if (variants[index].IsPtrData()) {
+ jobject arg = env->GetObjectArrayElement(args, index);
+ void *ptr = variants[index].ptr;
+
+ switch (variants[index].type) {
+ case TD_INT8:
+ env->ReleaseByteArrayElements((jbyteArray)arg, (jbyte*)ptr, 0);
+ break;
+ case TD_WCHAR:
+ env->ReleaseCharArrayElements((jcharArray)arg, (jchar*)ptr, 0);
+ break;
+ case TD_DOUBLE:
+ env->ReleaseDoubleArrayElements((jdoubleArray)arg, (jdouble*)ptr, 0);
+ break;
+ case TD_FLOAT:
+ env->ReleaseFloatArrayElements((jfloatArray)arg, (jfloat*)ptr, 0);
+ break;
+ case TD_INT32:
+ env->ReleaseIntArrayElements((jintArray)arg, (jint*)ptr, 0);
+ break;
+ case TD_INT64:
+ env->ReleaseLongArrayElements((jlongArray)arg, (jlong*)ptr, 0);
+ break;
+ case TD_INT16:
+ env->ReleaseShortArrayElements((jshortArray)arg, (jshort*)ptr, 0);
+ break;
+ }
+ }
+ }
+ delete[] variants;
+
+#ifndef JNI64
+ XPCOM_NATIVE_EXIT(env, that, _1VtblCall__II_3Ljava_lang_Object_2_FUNC);
+#else
+ XPCOM_NATIVE_EXIT(env, that, _1VtblCall__IJ_3Ljava_lang_Object_2_FUNC);
+#endif
+ return rc;
+}
+#endif
+
#ifndef NO__1XPCOMGlueLoadXULFunctions
extern "C" JNIEXPORT jint JNICALL XPCOM_NATIVE(_1XPCOMGlueLoadXULFunctions)(JNIEnv *env, jclass that, jintLong arg0);
JNIEXPORT jint JNICALL XPCOM_NATIVE(_1XPCOMGlueLoadXULFunctions)
@@ -7209,4 +7349,3 @@ JNIEXPORT jint JNICALL XPCOM_NATIVE(nsDynamicFunctionLoad_1sizeof)
return rc;
}
#endif
-
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/XPCOM.java b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/XPCOM.java
index 77d3a4f21c..00e19a9900 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/XPCOM.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/XPCOM.java
@@ -106,6 +106,7 @@ public class XPCOM extends C {
public static final String NS_FILEPICKER_CONTRACTID = "@mozilla.org/filepicker;1"; //$NON-NLS-1$
public static final String NS_FOCUSMANAGER_CONTRACTID = "@mozilla.org/focus-manager;1"; //$NON-NLS-1$
public static final String NS_HELPERAPPLAUNCHERDIALOG_CONTRACTID = "@mozilla.org/helperapplauncherdialog;1"; //$NON-NLS-1$
+ public static final String NS_INTERFACEINFOMANAGER_CONTRACTID = "@mozilla.org/xpti/interfaceinfomanager-service;1";
public static final String NS_MEMORY_CONTRACTID = "@mozilla.org/xpcom/memory-service;1"; //$NON-NLS-1$
public static final String NS_MIMEINPUTSTREAM_CONTRACTID = "@mozilla.org/network/mime-input-stream;1"; //$NON-NLS-1$
public static final String NS_SCRIPTSECURITYMANAGER_CONTRACTID = "@mozilla.org/scriptsecuritymanager;1"; //$NON-NLS-1$
@@ -2659,4 +2660,14 @@ static final int VtblCall(int fnNumber, long /*int*/ ppVtbl, long arg0, int arg1
}
}
+static final native int _VtblCall(int fnNumber, long /*int*/ ppVtbl, Object[] args);
+static final int VtblCall(int fnNumber, long /*int*/ ppVtbl, Object[] args) {
+ lock.lock();
+ try {
+ return _VtblCall(fnNumber, ppVtbl, args);
+ } finally {
+ lock.unlock();
+ }
+}
+
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIInterfaceInfo.java b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIInterfaceInfo.java
new file mode 100644
index 0000000000..955b05e9a6
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIInterfaceInfo.java
@@ -0,0 +1,50 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by Netscape are Copyright (C) 1998-1999
+ * Netscape Communications Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * IBM
+ * - Binding to permit interfacing between Mozilla and SWT
+ * - Copyright (C) 2003, 2012 IBM Corp. All Rights Reserved.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.eclipse.swt.internal.mozilla;
+
+
+public class nsIInterfaceInfo extends nsISupports {
+
+ static final int LAST_METHOD_ID = nsISupports.LAST_METHOD_ID + ((IsXULRVersionOrLater (MozillaVersion.VERSION_XR10)) ? 21 : 20);
+
+ static final String NS_IINTERFACEINFO_IID_STR = "215dbe04-94a7-11d2-ba58-00805f8a5dd7";
+ static final String NS_IINTERFACEINFO_10_IID_STR = "1affa260-8965-4612-869a-78af4ccfb287";
+
+ static {
+ IIDStore.RegisterIID(nsIDocShell.class, MozillaVersion.VERSION_BASE, new nsID(NS_IINTERFACEINFO_IID_STR));
+ IIDStore.RegisterIID(nsIDocShell.class, MozillaVersion.VERSION_XR10, new nsID(NS_IINTERFACEINFO_10_IID_STR));
+ }
+
+ public nsIInterfaceInfo(long /*int*/ address) {
+ super(address);
+ }
+
+ public int GetMethodInfoForName(byte[] methodName, int [] index, long /*int*/[] result) {
+ return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + ((IsXULRVersionOrLater (MozillaVersion.VERSION_XR10)) ? 9 : 8), getAddress(), methodName, index, result);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIInterfaceInfoManager.java b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIInterfaceInfoManager.java
new file mode 100644
index 0000000000..b74b174075
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIInterfaceInfoManager.java
@@ -0,0 +1,51 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by Netscape are Copyright (C) 1998-1999
+ * Netscape Communications Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * IBM
+ * - Binding to permit interfacing between Mozilla and SWT
+ * - Copyright (C) 2003, 2012 IBM Corp. All Rights Reserved.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.eclipse.swt.internal.mozilla;
+
+
+public class nsIInterfaceInfoManager extends nsISupports {
+
+ static final int LAST_METHOD_ID = nsISupports.LAST_METHOD_ID + 6;
+ static final String NS_IINTERFACEINFOMANAGER_IID_STR = "1d53d8d9-1d92-428f-b5cc-198b55e897d7";
+
+ static {
+ IIDStore.RegisterIID(nsIInterfaceInfoManager.class, MozillaVersion.VERSION_BASE, new nsID(NS_IINTERFACEINFOMANAGER_IID_STR));
+ }
+
+ public nsIInterfaceInfoManager(long /*int*/ address) {
+ super(address);
+ }
+
+ public int GetInfoForIID(nsID iid, long /*int*/[] result) {
+ return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 1, getAddress(), iid, result);
+ }
+
+ public int GetInfoForName(byte[] aName, long /*int*/[] result) {
+ return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 2, getAddress(), aName, result);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsISupports.java b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsISupports.java
index a7482f0239..07f6f0b0f5 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsISupports.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsISupports.java
@@ -50,6 +50,10 @@ public class nsISupports {
protected static boolean IsXULRunner31 () {
return MozillaVersion.CheckVersion (MozillaVersion.VERSION_XR31, true);
}
+
+ protected static boolean IsXULRVersionOrLater (int version) {
+ return MozillaVersion.CheckVersion (version, false);
+ }
public static final String NS_ISUPPORTS_IID_STR = "00000000-0000-0000-c000-000000000046";
@@ -57,6 +61,55 @@ public class nsISupports {
IIDStore.RegisterIID (nsISupports.class, MozillaVersion.VERSION_BASE, new nsID (NS_ISUPPORTS_IID_STR));
}
+ private static byte[] toByteArray (String str) {
+ byte[] bytes = new byte[str.length() + 1];
+ for (int i = str.length (); i-- > 0; )
+ bytes[i] = (byte)str.charAt (i);
+ return bytes;
+ }
+
+ protected int callFunction (String methodString, boolean setter, Object[] args) {
+ int index = getMethodIndex (methodString);
+ if (setter) index++;
+ return XPCOM.VtblCall(index, getAddress(), args);
+ }
+
+ protected int getGetterIndex (String attribute) {
+ return getMethodIndex (attribute);
+ }
+
+ protected int getSetterIndex (String attribute) {
+ return getMethodIndex (attribute) + 1;
+ }
+
+ protected int getMethodIndex (String methodString) {
+ long /*int*/[] result = new long /*int*/[1];
+ result[0] = 0;
+ int rc = XPCOM.NS_GetServiceManager (result);
+ if (rc != XPCOM.NS_OK) return -1;
+
+ nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
+ result[0] = 0;
+ rc = serviceManager.GetServiceByContractID (toByteArray (XPCOM.NS_INTERFACEINFOMANAGER_CONTRACTID), IIDStore.GetIID (nsIInterfaceInfoManager.class), result);
+ serviceManager.Release ();
+ if (rc != XPCOM.NS_OK) return -1;
+
+ nsIInterfaceInfoManager iim = new nsIInterfaceInfoManager (result[0]);
+ result[0] = 0;
+ rc = iim.GetInfoForName (toByteArray (getClass ().getSimpleName ()), result);
+ iim.Release ();
+ if (rc != XPCOM.NS_OK) return -1;
+
+ nsIInterfaceInfo info = new nsIInterfaceInfo (result[0]);
+ int[] index = new int [1];
+ long /*int*/[] dummy = new long /*int*/[1];
+ rc = info.GetMethodInfoForName (toByteArray (methodString), index, dummy);
+ info.Release ();
+ if (rc != XPCOM.NS_OK) return -1;
+
+ return index[0];
+ }
+
long /*int*/ address;
public nsISupports(long /*int*/ address) {

Back to the top