Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT PI/common_j2se/org/eclipse/swt/internal/Library.java eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT PI/common_j2se/org/eclipse/swt/internal/Library.java
Sami Wagiaalla 75f9fa
index 780a82c..c3bedd0 100644
Sami Wagiaalla 75f9fa
--- eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT PI/common_j2se/org/eclipse/swt/internal/Library.java	
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT PI/common_j2se/org/eclipse/swt/internal/Library.java	
Sami Wagiaalla 75f9fa
@@ -10,9 +10,15 @@
Sami Wagiaalla 75f9fa
  *******************************************************************************/
Sami Wagiaalla 75f9fa
 package org.eclipse.swt.internal;
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
-import java.io.*;
Sami Wagiaalla 75f9fa
-import java.net.*;
Sami Wagiaalla 75f9fa
-import java.util.jar.*;
Sami Wagiaalla 75f9fa
+import java.io.File;
Sami Wagiaalla 75f9fa
+import java.io.FileOutputStream;
Sami Wagiaalla 75f9fa
+import java.io.IOException;
Sami Wagiaalla 75f9fa
+import java.io.InputStream;
Sami Wagiaalla 75f9fa
+import java.lang.reflect.Method;
Sami Wagiaalla 75f9fa
+import java.net.JarURLConnection;
Sami Wagiaalla 75f9fa
+import java.net.URL;
Sami Wagiaalla 75f9fa
+import java.net.URLConnection;
Sami Wagiaalla 75f9fa
+import java.util.jar.Attributes;
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 public class Library {
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
@@ -263,19 +269,7 @@ public static void loadLibrary (String name, boolean mapName) {
Sami Wagiaalla 75f9fa
 	/* Compute the library name and mapped name */
Sami Wagiaalla 75f9fa
 	String libName1, libName2, mappedName1, mappedName2;
Sami Wagiaalla 75f9fa
 	if (mapName) {
Sami Wagiaalla 75f9fa
-		String version = System.getProperty ("swt.version"); //$NON-NLS-1$
Sami Wagiaalla 75f9fa
-		if (version == null) {
Sami Wagiaalla 75f9fa
-			version = "" + MAJOR_VERSION; //$NON-NLS-1$
Sami Wagiaalla 75f9fa
-			/* Force 3 digits in minor version number */
Sami Wagiaalla 75f9fa
-			if (MINOR_VERSION < 10) {
Sami Wagiaalla 75f9fa
-				version += "00"; //$NON-NLS-1$
Sami Wagiaalla 75f9fa
-			} else {
Sami Wagiaalla 75f9fa
-				if (MINOR_VERSION < 100) version += "0"; //$NON-NLS-1$
Sami Wagiaalla 75f9fa
-			}
Sami Wagiaalla 75f9fa
-			version += MINOR_VERSION;		
Sami Wagiaalla 75f9fa
-			/* No "r" until first revision */
Sami Wagiaalla 75f9fa
-			if (REVISION > 0) version += "r" + REVISION; //$NON-NLS-1$
Sami Wagiaalla 75f9fa
-		}
Sami Wagiaalla 75f9fa
+		String version = getVersionString();
Sami Wagiaalla 75f9fa
 		libName1 = name + "-" + Platform.PLATFORM + "-" + version;  //$NON-NLS-1$ //$NON-NLS-2$
Sami Wagiaalla 75f9fa
 		libName2 = name + "-" + Platform.PLATFORM;  //$NON-NLS-1$
Sami Wagiaalla 75f9fa
 		mappedName1 = mapLibraryName (libName1);
Sami Wagiaalla 75f9fa
@@ -337,4 +331,60 @@ static String mapLibraryName (String libName) {
Sami Wagiaalla 75f9fa
 	return libName;
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+private static String getVersionString(){
Sami Wagiaalla 75f9fa
+	String version = System.getProperty ("swt.version"); //$NON-NLS-1$
Sami Wagiaalla 75f9fa
+	if (version == null) {
Sami Wagiaalla 75f9fa
+		version = "" + MAJOR_VERSION; //$NON-NLS-1$
Sami Wagiaalla 75f9fa
+		/* Force 3 digits in minor version number */
Sami Wagiaalla 75f9fa
+		if (MINOR_VERSION < 10) {
Sami Wagiaalla 75f9fa
+			version += "00"; //$NON-NLS-1$
Sami Wagiaalla 75f9fa
+		} else {
Sami Wagiaalla 75f9fa
+			if (MINOR_VERSION < 100) version += "0"; //$NON-NLS-1$
Sami Wagiaalla 75f9fa
+		}
Sami Wagiaalla 75f9fa
+		version += MINOR_VERSION;
Sami Wagiaalla 75f9fa
+		/* No "r" until first revision */
Sami Wagiaalla 75f9fa
+		if (REVISION > 0) version += "r" + REVISION; //$NON-NLS-1$
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+	return version;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+public static File findResource(String resourceName, boolean mapName){
Sami Wagiaalla 75f9fa
+	if (mapName){
Sami Wagiaalla 75f9fa
+		resourceName = resourceName + "-"+ getVersionString();
Sami Wagiaalla 75f9fa
+		resourceName = mapLibraryName(resourceName);
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+	// Look for the resource in the swt library path
Sami Wagiaalla 75f9fa
+	String classpath = System.getProperty("java.library.path");
Sami Wagiaalla 75f9fa
+	if (classpath != null){
Sami Wagiaalla 75f9fa
+		File file = new File(classpath + SEPARATOR + resourceName);
Sami Wagiaalla 75f9fa
+		if (file.exists()){
Sami Wagiaalla 75f9fa
+			return file;
Sami Wagiaalla 75f9fa
+		}
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	// If this is an OSGI bundle look for the resource using getResource
Sami Wagiaalla 75f9fa
+	URL url = Library.class.getClassLoader().getResource(resourceName);
Sami Wagiaalla 75f9fa
+	URLConnection connection;
Sami Wagiaalla 75f9fa
+	try {
Sami Wagiaalla 75f9fa
+		connection = url.openConnection();
Sami Wagiaalla 75f9fa
+		Method getFileURLMethod = connection.getClass().getMethod("getFileURL");
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (getFileURLMethod != null){
Sami Wagiaalla 75f9fa
+		URL result = (URL) getFileURLMethod.invoke(connection);
Sami Wagiaalla 75f9fa
+		return new File(result.toURI());
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+	} catch (Exception e) {
Sami Wagiaalla 75f9fa
+		// If any exceptions are thrown the resource cannot be located this way.
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	// Look for the resource in the user's home directory
Sami Wagiaalla 75f9fa
+	String homeDir = System.getProperty ("user.home"); //$NON-NLS-1$
Sami Wagiaalla 75f9fa
+	File file = new File (homeDir + SWT_LIB_DIR, resourceName);
Sami Wagiaalla 75f9fa
+	if (file.exists()){
Sami Wagiaalla 75f9fa
+		return file;
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	return null;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak
Sami Wagiaalla d15395
index 6bce587..fea2a5b 100644
Sami Wagiaalla 75f9fa
--- eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak	
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak	
Sami Wagiaalla 75f9fa
@@ -48,6 +48,7 @@ XULRUNNER_LIB = lib$(XULRUNNER_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
Sami Wagiaalla 75f9fa
 XULRUNNER24_LIB = lib$(XULRUNNER24_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
Sami Wagiaalla 75f9fa
 XPCOMINIT_LIB = lib$(XPCOMINIT_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
Sami Wagiaalla 75f9fa
 WEBKIT_LIB = lib$(WEBKIT_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
Sami Wagiaalla 75f9fa
+WEBKIT_EXTENSION = lib$(WEBKIT_PREFIX)-extension-$(SWT_VERSION).so
Sami Wagiaalla 75f9fa
 GLX_LIB = lib$(GLX_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 CAIROCFLAGS = `pkg-config --cflags cairo`
25f005
@@ -292,7 +293,7 @@ xpcominit_stats.o: xpcominit_stats.cpp
Sami Wagiaalla 75f9fa
 #
Sami Wagiaalla 75f9fa
 # WebKit lib
Sami Wagiaalla 75f9fa
 #
Sami Wagiaalla 75f9fa
-make_webkit: $(WEBKIT_LIB)
Sami Wagiaalla 75f9fa
+make_webkit: $(WEBKIT_LIB) $(WEBKIT_EXTENSION)
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 $(WEBKIT_LIB): $(WEBKIT_OBJECTS)
Sami Wagiaalla 75f9fa
 	$(CC) $(LFLAGS) -o $(WEBKIT_LIB) $(WEBKIT_OBJECTS)
25f005
@@ -306,6 +307,13 @@ webkit_structs.o: webkitgtk_structs.c
Sami Wagiaalla 75f9fa
 webkit_stats.o: webkitgtk_stats.c webkitgtk_stats.h
Sami Wagiaalla 75f9fa
 	$(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk_stats.c -o webkit_stats.o
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+webkit_extension.o: webkit_extension.c webkit_extension.h
Sami Wagiaalla d15395
+	$(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkit_extension.c -o webkit_extension.o `pkg-config --cflags --libs webkit2gtk-4.0`
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+$(WEBKIT_EXTENSION): webkit_extension.o
Sami Wagiaalla 75f9fa
+	$(CC) -g -shared -Wl,-no-undefined,-soname,$(WEBKIT_EXTENSION) \
74681a
+        `pkg-config --cflags --libs webkit2gtk-4.0` -o $(WEBKIT_EXTENSION) webkit_extension.o -lc
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 #
Sami Wagiaalla 75f9fa
 # GLX lib
Sami Wagiaalla 75f9fa
 #
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkit_extension.c eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkit_extension.c
Sami Wagiaalla 75f9fa
new file mode 100644
Sami Wagiaalla 75f9fa
index 0000000..b6288de
Sami Wagiaalla 75f9fa
--- /dev/null
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkit_extension.c	
Sami Wagiaalla 75f9fa
@@ -0,0 +1,394 @@
Sami Wagiaalla 75f9fa
+/*******************************************************************************
Sami Wagiaalla 75f9fa
+ * Copyright (c) 2014 Red Hat and others. All rights reserved.
Sami Wagiaalla 75f9fa
+ * The contents of this file are made available under the terms
Sami Wagiaalla 75f9fa
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
Sami Wagiaalla 75f9fa
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
Sami Wagiaalla 75f9fa
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
Sami Wagiaalla 75f9fa
+ * of the LGPL at http://www.gnu.org is different to the version of
Sami Wagiaalla 75f9fa
+ * the LGPL accompanying this distribution and there is any conflict
Sami Wagiaalla 75f9fa
+ * between the two license versions, the terms of the LGPL accompanying
Sami Wagiaalla 75f9fa
+ * this distribution shall govern.
Sami Wagiaalla 75f9fa
+ *
Sami Wagiaalla 75f9fa
+ * Contributors:
Sami Wagiaalla 75f9fa
+ *     Red Hat - initial API and implementation
Sami Wagiaalla 75f9fa
+ *******************************************************************************/
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#include "webkit_extension.h"
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * This function will get called when JavaScript calls external.callJava
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+static JSValueRef
Sami Wagiaalla 75f9fa
+webkit_extension_external_object_callJava(JSContextRef context,
Sami Wagiaalla 75f9fa
+    JSObjectRef object,
Sami Wagiaalla 75f9fa
+    JSObjectRef thisObject,
Sami Wagiaalla 75f9fa
+    size_t argumentCount,
Sami Wagiaalla 75f9fa
+    const JSValueRef arguments[],
Sami Wagiaalla 75f9fa
+    JSValueRef* exception)
Sami Wagiaalla 75f9fa
+{
Sami Wagiaalla 75f9fa
+   JSStringRef propertyName =JSStringCreateWithUTF8CString ("pageId");
Sami Wagiaalla 75f9fa
+   JSValueRef value = JSObjectGetProperty (context, thisObject, propertyName, NULL);
Sami Wagiaalla 75f9fa
+   JSStringRelease (propertyName);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+   // Forward the java call to Java
Sami Wagiaalla 75f9fa
+   g_assert (argumentCount == 3);
Sami Wagiaalla 75f9fa
+   GVariant *result = g_dbus_proxy_call_sync (main_process_proxy,
Sami Wagiaalla 75f9fa
+                      "webkit_extension_external_object_callJava",
Sami Wagiaalla 75f9fa
+                      g_variant_new ("(t@d@s@r)", (guint64)JSValueToNumber (context, value, NULL),
Sami Wagiaalla 75f9fa
+                          webkit_extension_convert_js_to_gvariant(context, arguments[0]),
Sami Wagiaalla 75f9fa
+                          webkit_extension_convert_js_to_gvariant(context, arguments[1]),
Sami Wagiaalla 75f9fa
+                          webkit_extension_convert_js_to_gvariant(context, arguments[2])),
Sami Wagiaalla 75f9fa
+                      G_DBUS_CALL_FLAGS_NONE,
Sami Wagiaalla 75f9fa
+                      -1,
Sami Wagiaalla 75f9fa
+                      NULL,
Sami Wagiaalla 75f9fa
+                      NULL);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+   return webkit_extension_convert_gvariant_to_js(context, result);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static JSValueRef webkit_extension_convert_gvariant_to_js (JSContextRef context, GVariant * value){
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (g_variant_is_of_type(value, G_VARIANT_TYPE_BYTE) && g_variant_get_byte(value) == 0x00){
Sami Wagiaalla 75f9fa
+      return JSValueMakeUndefined (context);
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)){
Sami Wagiaalla 75f9fa
+      return JSValueMakeBoolean (context, g_variant_get_boolean(value));
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (g_variant_is_of_type(value, G_VARIANT_TYPE_DOUBLE)){
Sami Wagiaalla 75f9fa
+      return JSValueMakeNumber (context, g_variant_get_double(value));
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)){
Sami Wagiaalla 75f9fa
+      JSStringRef stringRef = JSStringCreateWithUTF8CString (g_variant_get_string(value, NULL));
Sami Wagiaalla 75f9fa
+      JSValueRef result = JSValueMakeString (context, stringRef);
Sami Wagiaalla 75f9fa
+      JSStringRelease (stringRef);
Sami Wagiaalla 75f9fa
+      return result;
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (g_variant_is_of_type(value, G_VARIANT_TYPE_UINT64)){
Sami Wagiaalla 75f9fa
+      return JSValueMakeNumber (context, g_variant_get_uint64(value));
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (g_variant_is_of_type(value, G_VARIANT_TYPE_TUPLE)){
Sami Wagiaalla 75f9fa
+      gsize length = (int)g_variant_n_children (value);
Sami Wagiaalla 75f9fa
+      JSValueRef *children = g_new (JSValueRef, length);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+      int i = 0;
Sami Wagiaalla 75f9fa
+      for (i = 0; i < length; i++) {
Sami Wagiaalla 75f9fa
+          children[i] = webkit_extension_convert_gvariant_to_js (context, g_variant_get_child_value(value, i));
Sami Wagiaalla 75f9fa
+      }
Sami Wagiaalla 75f9fa
+      JSValueRef result = JSObjectMakeArray (context, length, children, NULL);
Sami Wagiaalla 75f9fa
+      g_free (children);
Sami Wagiaalla 75f9fa
+      return result;
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  g_error("Unhandled type %s \n", g_variant_get_type_string (value));
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  return NULL;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static GVariant * webkit_extension_convert_js_to_gvariant (JSContextRef context, JSValueRef value){
Sami Wagiaalla 75f9fa
+  JSType type = JSValueGetType (context, value);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (type == kJSTypeBoolean){
Sami Wagiaalla 75f9fa
+      gboolean result = JSValueToNumber (context, value, NULL) != 0;
Sami Wagiaalla 75f9fa
+      return g_variant_new_boolean(result);
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (type == kJSTypeNumber){
Sami Wagiaalla 75f9fa
+      double result = JSValueToNumber (context, value, NULL);
Sami Wagiaalla 75f9fa
+      return g_variant_new_double (result);
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (type == kJSTypeString){
Sami Wagiaalla 75f9fa
+      JSStringRef stringRef = JSValueToStringCopy(context, value, NULL);
Sami Wagiaalla 75f9fa
+      size_t length = JSStringGetMaximumUTF8CStringSize (stringRef);
Sami Wagiaalla 75f9fa
+      char* string = (char*)malloc(length);
Sami Wagiaalla 75f9fa
+      JSStringGetUTF8CString(stringRef, string, length);
Sami Wagiaalla 75f9fa
+      GVariant *variant = g_variant_new_string(string);
Sami Wagiaalla 75f9fa
+      free(string);
Sami Wagiaalla 75f9fa
+      return variant;
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (type == kJSTypeNull || type == kJSTypeUndefined){
Sami Wagiaalla 75f9fa
+      return NULL;
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (type == kJSTypeObject){
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+      JSStringRef propertyName =JSStringCreateWithUTF8CString ("length");
Sami Wagiaalla 75f9fa
+      JSObjectRef object =  JSValueToObject(context, value, NULL);
Sami Wagiaalla 75f9fa
+      JSValueRef valuePtr = JSObjectGetProperty (context, object, propertyName, NULL);
Sami Wagiaalla 75f9fa
+      JSStringRelease (propertyName);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+      if (JSValueGetType (context, valuePtr) == kJSTypeNumber) {
Sami Wagiaalla 75f9fa
+          int length = (int)JSValueToNumber (context, valuePtr, NULL);
Sami Wagiaalla 75f9fa
+          GVariant **children = g_new (GVariant *, length);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+          int i = 0;
Sami Wagiaalla 75f9fa
+          for (i = 0; i < length; i++) {
Sami Wagiaalla 75f9fa
+              const JSValueRef child = JSObjectGetPropertyAtIndex (context, object, i, NULL);
Sami Wagiaalla 75f9fa
+              children[i] = webkit_extension_convert_js_to_gvariant(context, child);
Sami Wagiaalla 75f9fa
+          }
Sami Wagiaalla 75f9fa
+          GVariant* variant = g_variant_new_tuple (children, length);
Sami Wagiaalla 75f9fa
+          g_free (children);
Sami Wagiaalla 75f9fa
+          return variant;
Sami Wagiaalla 75f9fa
+      }
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  // Get type value string
Sami Wagiaalla 75f9fa
+  JSStringRef valueIString = JSValueToStringCopy(context, value, NULL);
Sami Wagiaalla 75f9fa
+  size_t valueUTF8Size = JSStringGetMaximumUTF8CStringSize(valueIString);
Sami Wagiaalla 75f9fa
+  char* valueUTF8 = (char*)malloc(valueUTF8Size);
Sami Wagiaalla 75f9fa
+  JSStringGetUTF8CString(valueIString, valueUTF8, valueUTF8Size);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  g_error("Unhandled type %d value: %s \n", type, valueUTF8);
Sami Wagiaalla 75f9fa
+  free(valueUTF8);
Sami Wagiaalla 75f9fa
+  JSStringRelease(valueIString);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  return NULL;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Returns the main frame of the WebPage with the given id
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+static WebKitFrame *webkit_extension_get_main_frame (const guint64 id){
Sami Wagiaalla 75f9fa
+  WebKitWebPage *web_page = webkit_web_extension_get_page (this_extension, id);
Sami Wagiaalla 75f9fa
+  return webkit_web_page_get_main_frame (web_page);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * The 'external' object's hasProperty function. This function will confirm
Sami Wagiaalla 75f9fa
+ * that 'external.callJava' exist
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+static bool external_object_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName){
Sami Wagiaalla 75f9fa
+  return JSStringIsEqualToUTF8CString(propertyName, "callJava");
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * For the 'callJava' property of the 'external' object create a JavaScript
Sami Wagiaalla 75f9fa
+ * function which will call back webkit_extension_external_object_callJava
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+static JSValueRef external_object_getProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception){
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (JSStringIsEqualToUTF8CString(propertyName, "callJava")) {
Sami Wagiaalla 75f9fa
+      return JSObjectMakeFunctionWithCallback (context, propertyName, webkit_extension_external_object_callJava);
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  return NULL;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+JSClassDefinition external_object_definition = {
Sami Wagiaalla 75f9fa
+    0,
Sami Wagiaalla 75f9fa
+    kJSClassAttributeNone,
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+    "external",
Sami Wagiaalla 75f9fa
+    NULL,
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+    NULL,
Sami Wagiaalla 75f9fa
+    NULL,
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+    NULL,
Sami Wagiaalla 75f9fa
+    NULL,
Sami Wagiaalla 75f9fa
+    external_object_hasProperty,
Sami Wagiaalla 75f9fa
+    external_object_getProperty,
Sami Wagiaalla 75f9fa
+    NULL,
Sami Wagiaalla 75f9fa
+    NULL,
Sami Wagiaalla 75f9fa
+    NULL,
Sami Wagiaalla 75f9fa
+    NULL,
Sami Wagiaalla 75f9fa
+    NULL,
Sami Wagiaalla 75f9fa
+    NULL,
Sami Wagiaalla 75f9fa
+    NULL
Sami Wagiaalla 75f9fa
+};
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Set window.external to the "external" object we created in C.
Sami Wagiaalla 75f9fa
+ * That way external.callJava calls our C function.
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+static void webkit_extension_install_external_object(WebKitScriptWorld *world, WebKitFrame *frame, guint64 page_id){
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  // Create the 'external' object.
Sami Wagiaalla 75f9fa
+  JSGlobalContextRef context = webkit_frame_get_javascript_context_for_script_world (frame, world);
Sami Wagiaalla 75f9fa
+  JSObjectRef globalObject = JSContextGetGlobalObject (context);
Sami Wagiaalla 75f9fa
+  JSObjectRef externalObject = JSObjectMake (context, JSClassCreate(&external_object_definition), NULL);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  // Add the pageId to the 'external' object.
Sami Wagiaalla 75f9fa
+  JSStringRef name = JSStringCreateWithUTF8CString ("pageId");
Sami Wagiaalla 75f9fa
+  JSValueRef number = JSValueMakeNumber (context, page_id);
Sami Wagiaalla 75f9fa
+  JSObjectSetProperty (context, externalObject, name, number, 0, NULL);
Sami Wagiaalla 75f9fa
+  JSStringRelease (name);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  // Set the global variable external to the external object
Sami Wagiaalla 75f9fa
+  name = JSStringCreateWithUTF8CString ("external");
Sami Wagiaalla 75f9fa
+  JSObjectSetProperty (context, globalObject, name, externalObject, 0, NULL);
Sami Wagiaalla 75f9fa
+  JSStringRelease (name);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static void
Sami Wagiaalla 75f9fa
+window_object_cleared_callback (WebKitScriptWorld *world,
Sami Wagiaalla 75f9fa
+                                WebKitWebPage     *web_page,
Sami Wagiaalla 75f9fa
+                                WebKitFrame       *frame,
Sami Wagiaalla 75f9fa
+                                gpointer           user_data)
Sami Wagiaalla 75f9fa
+{
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  guint64 page_id = webkit_web_page_get_id (web_page);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  // Install the "external" object.
Sami Wagiaalla 75f9fa
+  webkit_extension_install_external_object(world, frame, page_id);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  // Notify the main process
Sami Wagiaalla 75f9fa
+  g_dbus_proxy_call (main_process_proxy,
Sami Wagiaalla 75f9fa
+                     "webkit_extension_window_object_cleared",
Sami Wagiaalla 75f9fa
+                     g_variant_new ("(tb)", page_id, webkit_frame_is_main_frame (frame)),
Sami Wagiaalla 75f9fa
+                     G_DBUS_CALL_FLAGS_NONE,
Sami Wagiaalla 75f9fa
+                     -1,
Sami Wagiaalla 75f9fa
+                     NULL,
Sami Wagiaalla 75f9fa
+                     NULL,
Sami Wagiaalla 75f9fa
+                     NULL);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static gboolean webkit_extension_execute_script (const guint64 page_id, const gchar* script, const gchar* url){
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  WebKitFrame *main_frame = webkit_extension_get_main_frame (page_id);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  JSStringRef url_string = JSStringCreateWithUTF8CString (url);
Sami Wagiaalla 75f9fa
+  JSStringRef script_string = JSStringCreateWithUTF8CString (script);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  JSGlobalContextRef context = webkit_frame_get_javascript_global_context (main_frame);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  JSValueRef exception;
Sami Wagiaalla 75f9fa
+  JSValueRef result = JSEvaluateScript(context, script_string, NULL, url_string, 0,  &exception);
Sami Wagiaalla 75f9fa
+  if (!result){
Sami Wagiaalla 75f9fa
+      JSStringRef exceptionIString = JSValueToStringCopy(context, exception, NULL);
Sami Wagiaalla 75f9fa
+      size_t exceptionUTF8Size = JSStringGetMaximumUTF8CStringSize(exceptionIString);
Sami Wagiaalla 75f9fa
+      char* exceptionUTF8 = (char*)malloc(exceptionUTF8Size);
Sami Wagiaalla 75f9fa
+      JSStringGetUTF8CString(exceptionIString, exceptionUTF8, exceptionUTF8Size);
Sami Wagiaalla 75f9fa
+      g_error("Failed to execute script exception: %s\n", exceptionUTF8);
Sami Wagiaalla 75f9fa
+      free(exceptionUTF8);
Sami Wagiaalla 75f9fa
+      JSStringRelease(exceptionIString);
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  JSStringRelease (url_string);
Sami Wagiaalla 75f9fa
+  JSStringRelease (script_string);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  return result != NULL;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static void
Sami Wagiaalla 75f9fa
+webkit_extension_handle_method_call (GDBusConnection       *connection,
Sami Wagiaalla 75f9fa
+                    const gchar           *sender,
Sami Wagiaalla 75f9fa
+                    const gchar           *object_path,
Sami Wagiaalla 75f9fa
+                    const gchar           *interface_name,
Sami Wagiaalla 75f9fa
+                    const gchar           *method_name,
Sami Wagiaalla 75f9fa
+                    GVariant              *parameters,
Sami Wagiaalla 75f9fa
+                    GDBusMethodInvocation *invocation,
Sami Wagiaalla 75f9fa
+                    gpointer               user_data)
Sami Wagiaalla 75f9fa
+{
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  if (g_strcmp0(method_name, "webkit_extension_execute_script") == 0){
Sami Wagiaalla 75f9fa
+      const gchar *script;
Sami Wagiaalla 75f9fa
+      const gchar *url;
Sami Wagiaalla 75f9fa
+      guint64 page_id;
Sami Wagiaalla 75f9fa
+      g_variant_get(parameters, "(t&s&s)", &page_id, &script, &url);
Sami Wagiaalla 75f9fa
+      gboolean result = webkit_extension_execute_script (page_id, script, url);
Sami Wagiaalla 75f9fa
+      g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", result));
Sami Wagiaalla 75f9fa
+      return;
Sami Wagiaalla 75f9fa
+  }
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  g_error ("UNKNOWN method %s\n", method_name);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static void setup_dbus_connection(){
Sami Wagiaalla 75f9fa
+  GDBusConnection *bcon = g_bus_get_sync  (G_BUS_TYPE_SESSION, NULL,  NULL);
Sami Wagiaalla 75f9fa
+  main_process_proxy = g_dbus_proxy_new_sync (bcon,
Sami Wagiaalla 75f9fa
+      G_DBUS_PROXY_FLAGS_NONE,
Sami Wagiaalla 75f9fa
+      NULL,
Sami Wagiaalla 75f9fa
+      webkit_main_process_dbus_name,
Sami Wagiaalla 75f9fa
+      webkit_main_process_dbus_path,
Sami Wagiaalla 75f9fa
+      webkit_main_process_dbus_name,
Sami Wagiaalla 75f9fa
+      NULL,
Sami Wagiaalla 75f9fa
+      NULL);
Sami Wagiaalla 75f9fa
+  g_assert (main_process_proxy != NULL);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static void notify_main_process_ready(){
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  // Notify the server that extension bus is ready.
Sami Wagiaalla 75f9fa
+  g_dbus_proxy_call (main_process_proxy,
Sami Wagiaalla 75f9fa
+                     "webkit_extension_ready",
Sami Wagiaalla 75f9fa
+                     g_variant_new ("(ss)", webkit_extension_dbus_name, webkit_extension_dbus_path),
Sami Wagiaalla 75f9fa
+                     G_DBUS_CALL_FLAGS_NONE,
Sami Wagiaalla 75f9fa
+                     -1,
Sami Wagiaalla 75f9fa
+                     NULL,
Sami Wagiaalla 75f9fa
+                     NULL,
Sami Wagiaalla 75f9fa
+                     NULL);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static const GDBusInterfaceVTable interface_vtable =
Sami Wagiaalla 75f9fa
+  { webkit_extension_handle_method_call, NULL, NULL };
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static void
Sami Wagiaalla 75f9fa
+on_bus_acquired (GDBusConnection *connection,
Sami Wagiaalla 75f9fa
+                 const gchar     *name,
Sami Wagiaalla 75f9fa
+                 gpointer         user_data)
Sami Wagiaalla 75f9fa
+{
Sami Wagiaalla 75f9fa
+  guint registration_id = g_dbus_connection_register_object(connection,
Sami Wagiaalla 75f9fa
+      webkit_extension_dbus_path,
Sami Wagiaalla 75f9fa
+      introspection_data->interfaces[0],
Sami Wagiaalla 75f9fa
+      &interface_vtable, NULL, /* user_data */
Sami Wagiaalla 75f9fa
+      NULL, /* user_data_free_func */
Sami Wagiaalla 75f9fa
+      NULL); /* GError** */
Sami Wagiaalla 75f9fa
+  g_assert(registration_id > 0);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  setup_dbus_connection();
Sami Wagiaalla 75f9fa
+  notify_main_process_ready();
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+G_MODULE_EXPORT void
Sami Wagiaalla 75f9fa
+webkit_web_extension_initialize_with_user_data (WebKitWebExtension *extension, GVariant *user_data)
Sami Wagiaalla 75f9fa
+{
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  this_extension = extension;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  const gchar *unique_id = g_variant_get_string(user_data, NULL);
Sami Wagiaalla 75f9fa
+  int id_length = strlen(unique_id);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  //FIXME: free these pointers when the extension is being unloaded.
Sami Wagiaalla 75f9fa
+  webkit_main_process_dbus_name = g_new (gchar, strlen(WEBKIT_MAIN_PROCESS_DBUS_NAME_PREFIX) + id_length + 1);
Sami Wagiaalla 75f9fa
+  webkit_main_process_dbus_path = g_new (gchar, strlen(WEBKIT_MAIN_PROCESS_DBUS_PATH_PREFIX) + id_length + 1);
Sami Wagiaalla 75f9fa
+  webkit_extension_dbus_name = g_new (gchar, strlen(WEBKIT_EXTENSION_DBUS_NAME_PREFIX) + id_length + 1);
Sami Wagiaalla 75f9fa
+  webkit_extension_dbus_path = g_new (gchar, strlen(WEBKIT_EXTENSION_DBUS_PATH_PREFIX) + id_length + 1);
Sami Wagiaalla 75f9fa
+  introspection_xml = g_new (gchar, strlen(introspection_xml_template) + strlen(WEBKIT_EXTENSION_DBUS_NAME_PREFIX) + id_length + 1);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  g_sprintf (webkit_main_process_dbus_name, WEBKIT_MAIN_PROCESS_DBUS_NAME_PREFIX, unique_id);
Sami Wagiaalla 75f9fa
+  g_sprintf (webkit_main_process_dbus_path, WEBKIT_MAIN_PROCESS_DBUS_PATH_PREFIX, unique_id);
Sami Wagiaalla 75f9fa
+  g_sprintf (webkit_extension_dbus_name, WEBKIT_EXTENSION_DBUS_NAME_PREFIX, unique_id);
Sami Wagiaalla 75f9fa
+  g_sprintf (webkit_extension_dbus_path, WEBKIT_EXTENSION_DBUS_PATH_PREFIX, unique_id);
Sami Wagiaalla 75f9fa
+  g_sprintf (introspection_xml, introspection_xml_template, webkit_extension_dbus_name);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  g_signal_connect (webkit_script_world_get_default (),
Sami Wagiaalla 75f9fa
+                    "window-object-cleared",
Sami Wagiaalla 75f9fa
+                    G_CALLBACK (window_object_cleared_callback),
Sami Wagiaalla 75f9fa
+                    NULL);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  // Setup DBus connection
Sami Wagiaalla 75f9fa
+  guint owner_id;
Sami Wagiaalla 75f9fa
+  introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
Sami Wagiaalla 75f9fa
+  g_assert (introspection_data != NULL);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
Sami Wagiaalla 75f9fa
+                             webkit_extension_dbus_name,
Sami Wagiaalla 75f9fa
+                             G_BUS_NAME_OWNER_FLAGS_REPLACE | G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
Sami Wagiaalla 75f9fa
+                             on_bus_acquired,
Sami Wagiaalla 75f9fa
+                             NULL, /* on_name_acquired */
Sami Wagiaalla 75f9fa
+                             NULL, /* on_name_lost */
Sami Wagiaalla 75f9fa
+                             NULL,
Sami Wagiaalla 75f9fa
+                             NULL);
Sami Wagiaalla 75f9fa
+  g_assert (owner_id != 0);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  // TODO: clean up on extension unload.
Sami Wagiaalla 75f9fa
+  //  g_bus_unown_name (owner_id);
Sami Wagiaalla 75f9fa
+  //  g_dbus_node_info_unref (introspection_data);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkit_extension.h eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkit_extension.h
Sami Wagiaalla 75f9fa
new file mode 100644
Sami Wagiaalla 75f9fa
index 0000000..d127f9c
Sami Wagiaalla 75f9fa
--- /dev/null
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkit_extension.h	
Sami Wagiaalla 75f9fa
@@ -0,0 +1,73 @@
Sami Wagiaalla 75f9fa
+/*******************************************************************************
Sami Wagiaalla 75f9fa
+ * Copyright (c) 2014 Red Hat and others. All rights reserved.
Sami Wagiaalla 75f9fa
+ * The contents of this file are made available under the terms
Sami Wagiaalla 75f9fa
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
Sami Wagiaalla 75f9fa
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
Sami Wagiaalla 75f9fa
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
Sami Wagiaalla 75f9fa
+ * of the LGPL at http://www.gnu.org is different to the version of
Sami Wagiaalla 75f9fa
+ * the LGPL accompanying this distribution and there is any conflict
Sami Wagiaalla 75f9fa
+ * between the two license versions, the terms of the LGPL accompanying
Sami Wagiaalla 75f9fa
+ * this distribution shall govern.
Sami Wagiaalla 75f9fa
+ *
Sami Wagiaalla 75f9fa
+ * Contributors:
Sami Wagiaalla 75f9fa
+ *     Red Hat - initial API and implementation
Sami Wagiaalla 75f9fa
+ *******************************************************************************/
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#ifndef INC_webkit_extension_H
Sami Wagiaalla 75f9fa
+#define INC_webkit_extension_H
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#include <string.h>
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#include <glib.h>
Sami Wagiaalla 75f9fa
+#include <glib gprintf.h="">
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#include <gio gio.h="">
Sami Wagiaalla 75f9fa
+#include <stdlib.h>
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#include <unistd.h>
Sami Wagiaalla 75f9fa
+#include <stdio.h>
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#include <webkit2 webkit-web-extension.h="">
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#include <javascriptcore jscontextref.h="">
Sami Wagiaalla 75f9fa
+#include <javascriptcore jsobjectref.h="">
Sami Wagiaalla 75f9fa
+#include <javascriptcore jsstringref.h="">
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#define WEBKIT_MAIN_PROCESS_DBUS_NAME_PREFIX "org.eclipse.webkit_main.%s"
Sami Wagiaalla 75f9fa
+#define WEBKIT_MAIN_PROCESS_DBUS_PATH_PREFIX "/org/eclipse/webkit_main/%s"
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#define WEBKIT_EXTENSION_DBUS_NAME_PREFIX "org.eclipse.webkit_extension.%s"
Sami Wagiaalla 75f9fa
+#define WEBKIT_EXTENSION_DBUS_PATH_PREFIX "/org/eclipse/webkit_extension/%s"
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static gchar* webkit_main_process_dbus_name;
Sami Wagiaalla 75f9fa
+static gchar* webkit_main_process_dbus_path;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static gchar* webkit_extension_dbus_name;
Sami Wagiaalla 75f9fa
+static gchar* webkit_extension_dbus_path;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static GDBusProxy *main_process_proxy;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static GDBusNodeInfo *introspection_data = NULL;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static gchar* introspection_xml;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static gchar* introspection_xml_template =
Sami Wagiaalla 75f9fa
+"<node>"
Sami Wagiaalla 75f9fa
+  "<interface name="%s">"
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+    "<method name="webkit_extension_execute_script">"
Sami Wagiaalla 75f9fa
+      "<arg type="t" name="page_id" direction="in"/>"
Sami Wagiaalla 75f9fa
+      "<arg type="s" name="script" direction="in"/>"
Sami Wagiaalla 75f9fa
+      "<arg type="s" name="url" direction="in"/>"
Sami Wagiaalla 75f9fa
+      "<arg type="b" name="result" direction="out"/>"
Sami Wagiaalla 75f9fa
+    "</method>"
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+  "</interface>"
Sami Wagiaalla 75f9fa
+"</node>";
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+WebKitWebExtension *this_extension;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static GVariant * webkit_extension_convert_js_to_gvariant (JSContextRef context, JSValueRef value);
Sami Wagiaalla 75f9fa
+static JSValueRef webkit_extension_convert_gvariant_to_js (JSContextRef context, GVariant * value);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#endif /*INC_webkit_extension_H*/
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
Sami Wagiaalla 75f9fa
index 15b7761..3994f37 100644
Sami Wagiaalla 75f9fa
--- eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c	
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c	
Sami Wagiaalla 75f9fa
@@ -2103,6 +2103,46 @@ JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1context_1set_1favicon
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 #endif
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+#ifndef NO__1webkit_1web_1context_1set_1web_1extensions_1directory
Sami Wagiaalla 75f9fa
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1web_1context_1set_1web_1extensions_1directory)
Sami Wagiaalla 75f9fa
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1)
Sami Wagiaalla 75f9fa
+{
Sami Wagiaalla 75f9fa
+	jbyte *lparg1=NULL;
Sami Wagiaalla 75f9fa
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1context_1set_1web_1extensions_1directory_FUNC);
Sami Wagiaalla 75f9fa
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
Sami Wagiaalla 75f9fa
+/*
Sami Wagiaalla 75f9fa
+	webkit_web_context_set_web_extensions_directory(arg0, lparg1);
Sami Wagiaalla 75f9fa
+*/
Sami Wagiaalla 75f9fa
+	{
Sami Wagiaalla 75f9fa
+		WebKitGTK_LOAD_FUNCTION(fp, webkit_web_context_set_web_extensions_directory)
Sami Wagiaalla 75f9fa
+		if (fp) {
Sami Wagiaalla 75f9fa
+			((void (CALLING_CONVENTION*)(jintLong, jbyte *))fp)(arg0, lparg1);
Sami Wagiaalla 75f9fa
+		}
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+fail:
Sami Wagiaalla 75f9fa
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
Sami Wagiaalla 75f9fa
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1context_1set_1web_1extensions_1directory_FUNC);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+#endif
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+#ifndef NO__1webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data
Sami Wagiaalla 75f9fa
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data)
Sami Wagiaalla 75f9fa
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
Sami Wagiaalla 75f9fa
+{
Sami Wagiaalla 75f9fa
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data_FUNC);
Sami Wagiaalla 75f9fa
+/*
Sami Wagiaalla 75f9fa
+	webkit_web_context_set_web_extensions_initialization_user_data(arg0, arg1);
Sami Wagiaalla 75f9fa
+*/
Sami Wagiaalla 75f9fa
+	{
Sami Wagiaalla 75f9fa
+		WebKitGTK_LOAD_FUNCTION(fp, webkit_web_context_set_web_extensions_initialization_user_data)
Sami Wagiaalla 75f9fa
+		if (fp) {
Sami Wagiaalla 75f9fa
+			((void (CALLING_CONVENTION*)(jintLong, jintLong))fp)(arg0, arg1);
Sami Wagiaalla 75f9fa
+		}
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data_FUNC);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+#endif
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 #ifndef NO__1webkit_1web_1data_1source_1get_1data
Sami Wagiaalla 75f9fa
 JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1data_1source_1get_1data)
Sami Wagiaalla 75f9fa
 	(JNIEnv *env, jclass that, jintLong arg0)
Sami Wagiaalla 75f9fa
@@ -2501,6 +2541,26 @@ JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1get_1main_1fram
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 #endif
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+#ifndef NO__1webkit_1web_1view_1get_1page_1id
Sami Wagiaalla 75f9fa
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1get_1page_1id)
Sami Wagiaalla 75f9fa
+	(JNIEnv *env, jclass that, jintLong arg0)
Sami Wagiaalla 75f9fa
+{
Sami Wagiaalla 75f9fa
+	jintLong rc = 0;
Sami Wagiaalla 75f9fa
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1get_1page_1id_FUNC);
Sami Wagiaalla 75f9fa
+/*
Sami Wagiaalla 75f9fa
+	rc = (jintLong)webkit_web_view_get_page_id(arg0);
Sami Wagiaalla 75f9fa
+*/
Sami Wagiaalla 75f9fa
+	{
Sami Wagiaalla 75f9fa
+		WebKitGTK_LOAD_FUNCTION(fp, webkit_web_view_get_page_id)
Sami Wagiaalla 75f9fa
+		if (fp) {
Sami Wagiaalla 75f9fa
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
Sami Wagiaalla 75f9fa
+		}
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1get_1page_1id_FUNC);
Sami Wagiaalla 75f9fa
+	return rc;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+#endif
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 #ifndef NO__1webkit_1web_1view_1get_1progress
Sami Wagiaalla 75f9fa
 JNIEXPORT jdouble JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1get_1progress)
Sami Wagiaalla 75f9fa
 	(JNIEnv *env, jclass that, jintLong arg0)
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
Sami Wagiaalla 75f9fa
index c3cf9ee..b0e6650 100644
Sami Wagiaalla 75f9fa
--- eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c	
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c	
Sami Wagiaalla 75f9fa
@@ -123,6 +123,8 @@ char * WebKitGTK_nativeFunctionNames[] = {
Sami Wagiaalla 75f9fa
 	"_1webkit_1uri_1response_1get_1mime_1type",
Sami Wagiaalla 75f9fa
 	"_1webkit_1web_1context_1get_1default",
Sami Wagiaalla 75f9fa
 	"_1webkit_1web_1context_1set_1favicon_1database_1directory",
Sami Wagiaalla 75f9fa
+	"_1webkit_1web_1context_1set_1web_1extensions_1directory",
Sami Wagiaalla 75f9fa
+	"_1webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data",
Sami Wagiaalla 75f9fa
 	"_1webkit_1web_1data_1source_1get_1data",
Sami Wagiaalla 75f9fa
 	"_1webkit_1web_1data_1source_1get_1encoding",
Sami Wagiaalla 75f9fa
 	"_1webkit_1web_1frame_1get_1data_1source",
Sami Wagiaalla 75f9fa
@@ -143,6 +145,7 @@ char * WebKitGTK_nativeFunctionNames[] = {
Sami Wagiaalla 75f9fa
 	"_1webkit_1web_1view_1get_1estimated_1load_1progress",
Sami Wagiaalla 75f9fa
 	"_1webkit_1web_1view_1get_1load_1status",
Sami Wagiaalla 75f9fa
 	"_1webkit_1web_1view_1get_1main_1frame",
Sami Wagiaalla 75f9fa
+	"_1webkit_1web_1view_1get_1page_1id",
Sami Wagiaalla 75f9fa
 	"_1webkit_1web_1view_1get_1progress",
Sami Wagiaalla 75f9fa
 	"_1webkit_1web_1view_1get_1settings",
Sami Wagiaalla 75f9fa
 	"_1webkit_1web_1view_1get_1title",
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
Sami Wagiaalla 75f9fa
index e14e8f6..7b939e9 100644
Sami Wagiaalla 75f9fa
--- eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h	
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h	
Sami Wagiaalla 75f9fa
@@ -133,6 +133,8 @@ typedef enum {
Sami Wagiaalla 75f9fa
 	_1webkit_1uri_1response_1get_1mime_1type_FUNC,
Sami Wagiaalla 75f9fa
 	_1webkit_1web_1context_1get_1default_FUNC,
Sami Wagiaalla 75f9fa
 	_1webkit_1web_1context_1set_1favicon_1database_1directory_FUNC,
Sami Wagiaalla 75f9fa
+	_1webkit_1web_1context_1set_1web_1extensions_1directory_FUNC,
Sami Wagiaalla 75f9fa
+	_1webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data_FUNC,
Sami Wagiaalla 75f9fa
 	_1webkit_1web_1data_1source_1get_1data_FUNC,
Sami Wagiaalla 75f9fa
 	_1webkit_1web_1data_1source_1get_1encoding_FUNC,
Sami Wagiaalla 75f9fa
 	_1webkit_1web_1frame_1get_1data_1source_FUNC,
Sami Wagiaalla 75f9fa
@@ -153,6 +155,7 @@ typedef enum {
Sami Wagiaalla 75f9fa
 	_1webkit_1web_1view_1get_1estimated_1load_1progress_FUNC,
Sami Wagiaalla 75f9fa
 	_1webkit_1web_1view_1get_1load_1status_FUNC,
Sami Wagiaalla 75f9fa
 	_1webkit_1web_1view_1get_1main_1frame_FUNC,
Sami Wagiaalla 75f9fa
+	_1webkit_1web_1view_1get_1page_1id_FUNC,
Sami Wagiaalla 75f9fa
 	_1webkit_1web_1view_1get_1progress_FUNC,
Sami Wagiaalla 75f9fa
 	_1webkit_1web_1view_1get_1settings_FUNC,
Sami Wagiaalla 75f9fa
 	_1webkit_1web_1view_1get_1title_FUNC,
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_structs.c eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_structs.c
Sami Wagiaalla 75f9fa
index 5324bd8..8ad1c78 100644
Sami Wagiaalla 75f9fa
--- eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_structs.c	
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_structs.c	
Sami Wagiaalla 75f9fa
@@ -1,5 +1,5 @@
Sami Wagiaalla 75f9fa
 /*******************************************************************************
Sami Wagiaalla 75f9fa
- * Copyright (c) 2009, 2011 IBM Corporation and others. All rights reserved.
Sami Wagiaalla 75f9fa
+ * Copyright (c) 2009, 2014 IBM Corporation and others. All rights reserved.
Sami Wagiaalla 75f9fa
  * The contents of this file are made available under the terms
Sami Wagiaalla 75f9fa
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
Sami Wagiaalla 75f9fa
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
Sami Wagiaalla 75f9fa
index 7ef6236..0e00c09 100644
Sami Wagiaalla 75f9fa
--- eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java	
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java	
1a78a8
@@ -12,12 +12,15 @@
Sami Wagiaalla 75f9fa
 package org.eclipse.swt.browser;
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+import java.io.File;
Sami Wagiaalla 75f9fa
 import java.io.UnsupportedEncodingException;
Sami Wagiaalla 75f9fa
 import java.net.MalformedURLException;
Sami Wagiaalla 75f9fa
 import java.net.URL;
Sami Wagiaalla 75f9fa
 import java.util.Enumeration;
Sami Wagiaalla 75f9fa
+import java.util.HashMap;
Sami Wagiaalla 75f9fa
 import java.util.Hashtable;
Sami Wagiaalla 75f9fa
 import java.util.StringTokenizer;
Sami Wagiaalla 75f9fa
+import java.util.UUID;
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 import org.eclipse.swt.SWT;
Sami Wagiaalla 75f9fa
 import org.eclipse.swt.SWTException;
Sami Wagiaalla 75f9fa
@@ -27,6 +30,7 @@ import org.eclipse.swt.internal.C;
Sami Wagiaalla 75f9fa
 import org.eclipse.swt.internal.Callback;
Sami Wagiaalla 75f9fa
 import org.eclipse.swt.internal.Compatibility;
Sami Wagiaalla 75f9fa
 import org.eclipse.swt.internal.Converter;
Sami Wagiaalla 75f9fa
+import org.eclipse.swt.internal.GVariantConverter;
Sami Wagiaalla 75f9fa
 import org.eclipse.swt.internal.LONG;
Sami Wagiaalla 75f9fa
 import org.eclipse.swt.internal.Library;
Sami Wagiaalla 75f9fa
 import org.eclipse.swt.internal.gtk.GdkEventKey;
25f005
@@ -48,6 +52,8 @@ import org.eclipse.swt.widgets.Shell;
25f005
 
Sami Wagiaalla 75f9fa
 class WebKit extends WebBrowser {
Sami Wagiaalla 75f9fa
 	long /*int*/ webView, webViewData, scrolledWindow;
Sami Wagiaalla 75f9fa
+	long pageId;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 	int failureCount, lastKeyCode, lastCharCode;
Sami Wagiaalla 75f9fa
 	String postData;
Sami Wagiaalla 75f9fa
 	String[] headers;
25f005
@@ -55,10 +61,61 @@ class WebKit extends WebBrowser {
Sami Wagiaalla 75f9fa
 	byte[] htmlBytes;
Sami Wagiaalla 75f9fa
 	BrowserFunction eventFunction;
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+	/**
Sami Wagiaalla 75f9fa
+	 * A hash map to keep the results of Java Script executions. The result is
Sami Wagiaalla 75f9fa
+	 * mapped to the value of jsCounter at the time of execution so that the
Sami Wagiaalla 75f9fa
+	 * polling loop can find the correct result
Sami Wagiaalla 75f9fa
+	 */
Sami Wagiaalla 75f9fa
+	private static HashMap<integer, long=""> jsResults = new HashMap<integer, long="">();
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	/**
Sami Wagiaalla 75f9fa
+	 * A counter that is incremented each time @link
Sami Wagiaalla 75f9fa
+	 * {@link WebKit#webkit_extension_execute_script(String, String)} is called
Sami Wagiaalla 75f9fa
+	 * and as a unique reference to that script run.
Sami Wagiaalla 75f9fa
+	 */
Sami Wagiaalla 75f9fa
+	private static int jsCounter = 0;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	private static long /*int*/ dbus_proxy = 0;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 	static int DisabledJSCount;
Sami Wagiaalla 75f9fa
 	static long /*int*/ ExternalClass, PostString, WebViewType;
Sami Wagiaalla 75f9fa
 	static boolean IsWebKit14orNewer, LibraryLoaded;
25f005
 	static Hashtable<long, long=""> WindowMappings = new Hashtable<long, long=""> ();
Sami Wagiaalla 75f9fa
+	static HashMap<long, webkit=""> browserIdMappings = new HashMap<long, webkit="">();
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	private static final String WEBKIT_MAIN_PROCESS_DBUS_NAME_PREFIX = "org.eclipse.webkit_main.";
Sami Wagiaalla 75f9fa
+	private static final String WEBKIT_MAIN_PROCESS_DBUS_PATH_PREFIX = "/org/eclipse/webkit_main/";
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	private static String uniqueDBusID;
Sami Wagiaalla 75f9fa
+	private static String mainProcessDBusName;
Sami Wagiaalla 75f9fa
+	private static String mainProcessDBusPath;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	/* Introspection data out main WebKit process. This specifies the
Sami Wagiaalla 75f9fa
+	 * interface that the extension will expect to see. */
Sami Wagiaalla 75f9fa
+	private static String dbusIntrospectionXml =
Sami Wagiaalla 75f9fa
+	"<node>" +
Sami Wagiaalla 75f9fa
+	  "<interface name="%s">" +
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	    "<method name="webkit_extension_ready">" +
Sami Wagiaalla 75f9fa
+	      "<arg type="s" name="extension_dbus_name" direction="in"/>" +
Sami Wagiaalla 75f9fa
+	      "<arg type="s" name="extension_dbus_path" direction="in"/>" +
Sami Wagiaalla 75f9fa
+	    "</method>" +
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	    "<method name="webkit_extension_window_object_cleared">" +
Sami Wagiaalla 75f9fa
+	      "<arg type="t" name="pageId" direction="in"/>" +
Sami Wagiaalla 75f9fa
+	      "<arg type="b" name="isMainFrame" direction="in"/>" +
Sami Wagiaalla 75f9fa
+	    "</method>" +
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	    "<method name="webkit_extension_external_object_callJava">" +
Sami Wagiaalla 75f9fa
+	      "<arg type="t" name="pageId" direction="in"/>" +
Sami Wagiaalla 75f9fa
+	      "<arg type="d" name="id" direction="in"/>" +
Sami Wagiaalla 75f9fa
+	      "<arg type="s" name="token" direction="in"/>" +
Sami Wagiaalla 75f9fa
+	      "<arg type="r" name="arguments" direction="in"/>" +
Sami Wagiaalla 75f9fa
+	      "<arg type="*" name="result" direction="out"/>" +
Sami Wagiaalla 75f9fa
+	    "</method>" +
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	"</interface>" +
Sami Wagiaalla 75f9fa
+	"</node>";
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 	static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$
Sami Wagiaalla 75f9fa
 	static final String CHARSET_UTF8 = "UTF-8"; //$NON-NLS-1$
Sami Wagiaalla 75f9fa
@@ -122,6 +179,12 @@ class WebKit extends WebBrowser {
Sami Wagiaalla 75f9fa
 	static Callback JSObjectHasPropertyProc, JSObjectGetPropertyProc, JSObjectCallAsFunctionProc;
Sami Wagiaalla 75f9fa
 	static Callback JSDOMEventProc;
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+	private static Callback connectedToExtensionCallback;
Sami Wagiaalla 75f9fa
+	private static Callback busAcquiredCallback;
Sami Wagiaalla 75f9fa
+	private static Callback handleDbusFunctionCallCallbackObject;
Sami Wagiaalla 75f9fa
+	private static Callback executeJavaScriptFinishedCallback;
Sami Wagiaalla 75f9fa
+	private static Callback webkit_initialize_web_extensions_callback;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 	static boolean WEBKIT2;
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 	static {
Sami Wagiaalla 75f9fa
@@ -137,6 +200,22 @@ class WebKit extends WebBrowser {
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 			WebViewType = WebKitGTK.webkit_web_view_get_type ();
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+			if (WEBKIT2){
Sami Wagiaalla 75f9fa
+				long /*int*/ webContext = WebKitGTK.webkit_web_context_get_default();
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+				webkit_initialize_web_extensions_callback = new Callback(WebKit.class, "webkit_initialize_web_extensions", 2);
Sami Wagiaalla 75f9fa
+				OS.g_signal_connect (webContext, WebKitGTK.initialize_web_extensions, webkit_initialize_web_extensions_callback.getAddress(), 0);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+				setUpExtensionConnection();
Sami Wagiaalla 75f9fa
+				//TODO: Perhaps a directory can be created inside SWT_LIBRARY_PATH for the extension.
Sami Wagiaalla 75f9fa
+				//      That way webkit wouldn't attempt to load unrelated .so's as extensions
Sami Wagiaalla 75f9fa
+				File extension = Library.findResource("swt-webkit-extension", true);  //$NON-NLS-1$
Sami Wagiaalla 75f9fa
+				String extensionsPath = extension.getParent();
Sami Wagiaalla 75f9fa
+				byte[] extensionsPathBytes = Converter.wcsToMbcs (null, extensionsPath, true);
Sami Wagiaalla 75f9fa
+				WebKitGTK.webkit_web_context_set_web_extensions_directory(webContext, extensionsPathBytes);
Sami Wagiaalla 75f9fa
+				executeJavaScriptFinishedCallback = new Callback(WebKit.class, "executeJavaScriptFinishedCallback", 3);
Sami Wagiaalla 75f9fa
+			}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 			Proc2 = new Callback (WebKit.class, "Proc", 2); //$NON-NLS-1$
Sami Wagiaalla 75f9fa
 			if (Proc2.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
Sami Wagiaalla 75f9fa
 			Proc3 = new Callback (WebKit.class, "Proc", 3); //$NON-NLS-1$
Sami Wagiaalla 75f9fa
@@ -247,11 +326,24 @@ class WebKit extends WebBrowser {
Sami Wagiaalla 75f9fa
 		}
Sami Wagiaalla 75f9fa
 	}
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
-static String getString (long /*int*/ strPtr) {
Sami Wagiaalla 75f9fa
-	int length = OS.strlen (strPtr);
Sami Wagiaalla 75f9fa
-	byte [] buffer = new byte [length];
Sami Wagiaalla 75f9fa
-	OS.memmove (buffer, strPtr, length);
Sami Wagiaalla 75f9fa
-	return new String (Converter.mbcsToWcs (null, buffer));
Sami Wagiaalla 75f9fa
+@SuppressWarnings("unused")
Sami Wagiaalla 75f9fa
+private static long /*int*/ webkit_initialize_web_extensions (long /*int*/ context, long /*int*/ user_data){
Sami Wagiaalla 75f9fa
+	 WebKitGTK.webkit_web_context_set_web_extensions_initialization_user_data (
Sami Wagiaalla 75f9fa
+		      context,
Sami Wagiaalla 75f9fa
+		      GVariantConverter.convertJavaToGVariant(uniqueDBusID));
Sami Wagiaalla 75f9fa
+	return 0;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * In WebKit2 each WebPage/WebView pair is assigned an ID. This is used to
Sami Wagiaalla 75f9fa
+ * coordinate operations between a WebView in the main process and its
Sami Wagiaalla 75f9fa
+ * corresponding WebPage in the extension process.
Sami Wagiaalla 75f9fa
+ *
Sami Wagiaalla 75f9fa
+ * @param id the id of the WebView
Sami Wagiaalla 75f9fa
+ * @return an instance of WebKit which has the corresponding id
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+private static WebKit findBrowserById (long id) {
Sami Wagiaalla 75f9fa
+	return browserIdMappings.get(id);
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 static Browser FindBrowser (long /*int*/ webView) {
Sami Wagiaalla 75f9fa
@@ -286,6 +378,55 @@ static boolean IsInstalled () {
Sami Wagiaalla 75f9fa
 		(major == MIN_VERSION[0] && minor == MIN_VERSION[1] && micro >= MIN_VERSION[2]);
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Set up this process to be ready to receive DBus connections from the extension.
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+private static void setUpExtensionConnection(){
Sami Wagiaalla 75f9fa
+	UUID uuid = UUID.randomUUID();
Sami Wagiaalla 75f9fa
+	// A valid dbus name must not contain '-' and must
Sami Wagiaalla 75f9fa
+	// not begin with a digit.
Sami Wagiaalla 75f9fa
+	uniqueDBusID = "a" + uuid.toString().replace('-', '_');
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	mainProcessDBusName = WEBKIT_MAIN_PROCESS_DBUS_NAME_PREFIX + uniqueDBusID;
Sami Wagiaalla 75f9fa
+	mainProcessDBusPath = WEBKIT_MAIN_PROCESS_DBUS_PATH_PREFIX + uniqueDBusID;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	busAcquiredCallback = new Callback(WebKit.class, "busAcquiredCallback", 3);
Sami Wagiaalla 75f9fa
+	int owner_id = OS.g_bus_own_name (OS.G_BUS_TYPE_SESSION,
Sami Wagiaalla 75f9fa
+			Converter.wcsToMbcs(null, mainProcessDBusName, true),
Sami Wagiaalla 75f9fa
+			OS.G_BUS_NAME_OWNER_FLAGS_REPLACE | OS.G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
Sami Wagiaalla 75f9fa
+			busAcquiredCallback.getAddress(),
Sami Wagiaalla 75f9fa
+			0,
Sami Wagiaalla 75f9fa
+			0,
Sami Wagiaalla 75f9fa
+			0,
Sami Wagiaalla 75f9fa
+			0);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	assert(owner_id > 0);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+static long /*int*/ busAcquiredCallback (long /*int*/ connection, long /*int*/ name, long /*int*/ user_data){
Sami Wagiaalla 75f9fa
+	dbusIntrospectionXml = String.format(dbusIntrospectionXml, mainProcessDBusName);
Sami Wagiaalla 75f9fa
+	byte[] dbusIntrospectionXmlBytes = Converter.wcsToMbcs(null, dbusIntrospectionXml, true);
Sami Wagiaalla 75f9fa
+	long /*int*/ [] error = new long /*int*/ [1];
Sami Wagiaalla 75f9fa
+	long /*int*/ introspection_data = OS.g_dbus_node_info_new_for_xml (dbusIntrospectionXmlBytes, error);
Sami Wagiaalla 75f9fa
+	if (introspection_data == 0 || error[0] != 0){
Sami Wagiaalla 75f9fa
+		return 0;
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+	handleDbusFunctionCallCallbackObject = new Callback(WebKit.class, "webkit_extension_handle_dbus_function_call", 8);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	long /*int*/ interface_info = OS.g_dbus_node_info_lookup_interface(introspection_data, Converter.wcsToMbcs(null, mainProcessDBusName, true));
Sami Wagiaalla 75f9fa
+	long /*int*/[] vtable = {handleDbusFunctionCallCallbackObject.getAddress(),0,0};
Sami Wagiaalla 75f9fa
+	long /*int*/ registration_id = OS.g_dbus_connection_register_object (connection,
Sami Wagiaalla 75f9fa
+			Converter.wcsToMbcs(null, mainProcessDBusPath, true),
Sami Wagiaalla 75f9fa
+			interface_info,
Sami Wagiaalla 75f9fa
+            vtable,
Sami Wagiaalla 75f9fa
+            0,
Sami Wagiaalla 75f9fa
+            0,
Sami Wagiaalla 75f9fa
+            error);
Sami Wagiaalla 75f9fa
+	assert (registration_id != 0);
Sami Wagiaalla 75f9fa
+	return 0;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 static long /*int*/ JSObjectCallAsFunctionProc (long /*int*/ ctx, long /*int*/ function, long /*int*/ thisObject, long /*int*/ argumentCount, long /*int*/ arguments, long /*int*/ exception) {
Sami Wagiaalla 75f9fa
 	if (WebKitGTK.JSValueIsObjectOfClass (ctx, thisObject, ExternalClass) == 0) {
Sami Wagiaalla 75f9fa
 		return WebKitGTK.JSValueMakeUndefined (ctx);
Sami Wagiaalla 75f9fa
@@ -406,10 +547,11 @@ static long /*int*/ Proc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ u
Sami Wagiaalla 75f9fa
 	} else if (OS.G_TYPE_CHECK_INSTANCE_TYPE (handle, WebKitGTK.webkit_web_frame_get_type ())) {
Sami Wagiaalla 75f9fa
 		webView = WebKitGTK.webkit_web_frame_get_web_view (handle);
Sami Wagiaalla 75f9fa
 	} else {
Sami Wagiaalla 75f9fa
+		SWT.error(SWT.ERROR_INVALID_ARGUMENT, new Throwable("UNHANDLED type " + Converter.getString(OS.G_OBJECT_TYPE_NAME(handle))));
Sami Wagiaalla 75f9fa
 		return 0;
Sami Wagiaalla 75f9fa
 	}
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
-	Browser browser = FindBrowser (webView); 
Sami Wagiaalla 75f9fa
+	Browser browser = FindBrowser (webView);
Sami Wagiaalla 75f9fa
 	if (browser == null) return 0;
Sami Wagiaalla 75f9fa
 	WebKit webkit = (WebKit)browser.webBrowser;
Sami Wagiaalla 75f9fa
 	if (webView == handle) {
Sami Wagiaalla 75f9fa
@@ -526,6 +668,7 @@ long /*int*/ webFrameProc (long /*int*/ handle, long /*int*/ arg0, long /*int*/
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 long /*int*/ webViewProc (long /*int*/ handle, long /*int*/ user_data) {
Sami Wagiaalla 75f9fa
 	switch ((int)/*64*/user_data) {
Sami Wagiaalla 75f9fa
+		case CREATE_WEB_VIEW: return webkit_create_web_view (handle, 0);
Sami Wagiaalla 75f9fa
 		case CLOSE_WEB_VIEW: return webkit_close_web_view (handle);
Sami Wagiaalla 75f9fa
 		case WEB_VIEW_READY: return webkit_web_view_ready (handle);
Sami Wagiaalla 75f9fa
 		default: return 0;
Sami Wagiaalla 75f9fa
@@ -574,8 +717,98 @@ long /*int*/ webViewProc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ a
Sami Wagiaalla 75f9fa
 	}
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Handles function calls from the extension through DBus.
Sami Wagiaalla 75f9fa
+ *
Sami Wagiaalla 75f9fa
+ * @param connection
Sami Wagiaalla 75f9fa
+ * @param sender
Sami Wagiaalla 75f9fa
+ * @param object_path
Sami Wagiaalla 75f9fa
+ * @param interface_name
Sami Wagiaalla 75f9fa
+ * @param method_name
Sami Wagiaalla 75f9fa
+ * @param parameters
Sami Wagiaalla 75f9fa
+ * @param invocation
Sami Wagiaalla 75f9fa
+ * @param user_data
Sami Wagiaalla 75f9fa
+ * @return
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+@SuppressWarnings("unused")
Sami Wagiaalla 75f9fa
+private static long /*int*/ webkit_extension_handle_dbus_function_call(
Sami Wagiaalla 75f9fa
+		long /*int*/ connection, long /*int*/ sender,
Sami Wagiaalla 75f9fa
+		long /*int*/ object_path, long /*int*/ interface_name,
Sami Wagiaalla 75f9fa
+		long /*int*/ method_name, long /*int*/ parameters,
Sami Wagiaalla 75f9fa
+		long /*int*/ invocation, long /*int*/ user_data) {
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	String methodName = Converter.getString(method_name);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (methodName.equals("webkit_extension_ready")) {
Sami Wagiaalla 75f9fa
+		webkit_extension_ready(parameters);
Sami Wagiaalla 75f9fa
+		return 0;
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (methodName.equals("webkit_extension_window_object_cleared")) {
Sami Wagiaalla 75f9fa
+		webkit_extension_window_object_cleared(parameters);
Sami Wagiaalla 75f9fa
+		return 0;
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (methodName.equals("webkit_extension_external_object_callJava")) {
Sami Wagiaalla 75f9fa
+		Object result = webkit_extension_external_object_callJava(parameters);
Sami Wagiaalla 75f9fa
+		OS.g_dbus_method_invocation_return_value(invocation, GVariantConverter.convertJavaToGVariant(new Object[]{result}));
Sami Wagiaalla 75f9fa
+		return 0;
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	SWT.error(SWT.ERROR_INVALID_ARGUMENT, new Throwable("Unknow DBus method name " + methodName));
Sami Wagiaalla 75f9fa
+	return 0;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Called by the extension through DBus to notify the main process that
Sami Wagiaalla 75f9fa
+ * extension ready for connection through DBus
Sami Wagiaalla 75f9fa
+ *
Sami Wagiaalla 75f9fa
+ * @param args_variant a GVariant containing the call arguments.
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+private static void webkit_extension_ready (long /*int*/ args_variant){
Sami Wagiaalla 75f9fa
+	Object[] args = (Object[]) GVariantConverter.convertGVariantToJava(args_variant);
Sami Wagiaalla 75f9fa
+	String extensionDbusName = (String) args[0];
Sami Wagiaalla 75f9fa
+	String extensionDbusPath = (String) args[1];
Sami Wagiaalla 75f9fa
+	connectToExtension(extensionDbusName, extensionDbusPath);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Connect to the WebKit extension via dbus
Sami Wagiaalla 75f9fa
+ * @param name dbus name
Sami Wagiaalla 75f9fa
+ * @param path dbus path
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+private static void connectToExtension(String name, String path){
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	connectedToExtensionCallback = new Callback(WebKit.class, "connectedToExtensionCallback", 3);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	long /*int*/ bcon = OS.g_bus_get_sync (OS.G_BUS_TYPE_SESSION, 0,  0);
Sami Wagiaalla 75f9fa
+	OS.g_dbus_proxy_new (bcon,
Sami Wagiaalla 75f9fa
+			OS.G_DBUS_PROXY_FLAGS_NONE,
Sami Wagiaalla 75f9fa
+			0,
Sami Wagiaalla 75f9fa
+			Converter.wcsToMbcs(null, name, true),
Sami Wagiaalla 75f9fa
+			Converter.wcsToMbcs(null, path, true),
Sami Wagiaalla 75f9fa
+			Converter.wcsToMbcs(null, name, true),
Sami Wagiaalla 75f9fa
+			0,
Sami Wagiaalla 75f9fa
+			connectedToExtensionCallback.getAddress(),
Sami Wagiaalla 75f9fa
+			0);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Called by DBus when the connection to the extension has been established.
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+@SuppressWarnings("unused")
Sami Wagiaalla 75f9fa
+private static long /*int*/ connectedToExtensionCallback (long /*int*/ source_object, long /*int*/ res, long /*int*/ user_data){
Sami Wagiaalla 75f9fa
+	long /*int*/[] error = new long /*int*/[1];
Sami Wagiaalla 75f9fa
+	dbus_proxy = OS.g_dbus_proxy_new_finish (res, error);
Sami Wagiaalla 75f9fa
+	if (error[0] != 0){
Sami Wagiaalla 75f9fa
+		SWT.error(SWT.ERROR_IO, new Throwable(Converter.getString(OS.g_error_get_message(error[0]))));
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+	return 0;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 @Override
Sami Wagiaalla 75f9fa
 public void create (Composite parent, int style) {
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 	if (ExternalClass == 0) {
Sami Wagiaalla 75f9fa
 		if (Device.DEBUG) {
Sami Wagiaalla 75f9fa
 			int major, minor, micro;
Sami Wagiaalla 75f9fa
@@ -651,10 +884,15 @@ public void create (Composite parent, int style) {
Sami Wagiaalla 75f9fa
 		OS.g_signal_connect (webView, WebKitGTK.window_object_cleared, Proc5.getAddress (), WINDOW_OBJECT_CLEARED);
Sami Wagiaalla 75f9fa
 		OS.g_signal_connect (webView, WebKitGTK.status_bar_text_changed, Proc3.getAddress (), STATUS_BAR_TEXT_CHANGED);
Sami Wagiaalla 75f9fa
 	} else {
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+		// Set the page Id
Sami Wagiaalla 75f9fa
+		this.pageId = WebKitGTK.webkit_web_view_get_page_id (webView);
Sami Wagiaalla 75f9fa
+		browserIdMappings.put(pageId, this);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 		OS.gtk_container_add (browser.handle, webView);
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 		OS.g_signal_connect (webView, WebKitGTK.close, Proc2.getAddress (), CLOSE_WEB_VIEW);
Sami Wagiaalla 75f9fa
-		OS.g_signal_connect (webView, WebKitGTK.create, Proc3.getAddress (), CREATE_WEB_VIEW);
Sami Wagiaalla 75f9fa
+		OS.g_signal_connect (webView, WebKitGTK.create, Proc2.getAddress (), CREATE_WEB_VIEW);
Sami Wagiaalla 75f9fa
 		OS.g_signal_connect (webView, WebKitGTK.load_changed, Proc3.getAddress (), LOAD_CHANGED);
Sami Wagiaalla 75f9fa
 		OS.g_signal_connect (webView, WebKitGTK.ready_to_show, Proc2.getAddress (), WEB_VIEW_READY);
Sami Wagiaalla 75f9fa
 		OS.g_signal_connect (webView, WebKitGTK.decide_policy, Proc4.getAddress (), DECIDE_POLICY);
Sami Wagiaalla 75f9fa
@@ -663,6 +901,22 @@ public void create (Composite parent, int style) {
Sami Wagiaalla 75f9fa
 		OS.g_signal_connect (webView, WebKitGTK.context_menu, Proc5.getAddress (), CONTEXT_MENU);
Sami Wagiaalla 75f9fa
 		OS.g_signal_connect (webView, WebKitGTK.notify_estimated_load_progress, Proc3.getAddress (), NOTIFY_PROGRESS);
Sami Wagiaalla 75f9fa
 		OS.g_signal_connect (webView, WebKitGTK.authenticate, Proc3.getAddress (), AUTHENTICATE);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+		// Wait for extension initialization.
Sami Wagiaalla 75f9fa
+		// The extension and the DBus connection to it is performed asyncrounously
Sami Wagiaalla 75f9fa
+		// This creates a race condition; if functions requiring the extension are
Sami Wagiaalla 75f9fa
+		// called right after this function returns crashes can occure.
Sami Wagiaalla 75f9fa
+		Display display = browser.getDisplay();
Sami Wagiaalla 75f9fa
+		long time = System.currentTimeMillis();
Sami Wagiaalla 75f9fa
+		long timeOut = time+2000;
Sami Wagiaalla 75f9fa
+		while (!display.isDisposed() && dbus_proxy == 0 && time < timeOut) {
Sami Wagiaalla 75f9fa
+			if (!display.readAndDispatch()) display.sleep();
Sami Wagiaalla 75f9fa
+			time = System.currentTimeMillis();
Sami Wagiaalla 75f9fa
+		}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+		if (dbus_proxy == 0){
Sami Wagiaalla 75f9fa
+			SWT.error(SWT.ERROR_IO, new Throwable("Failed to initialize DBus connection to extension"));
Sami Wagiaalla 75f9fa
+		}
Sami Wagiaalla 75f9fa
 	}
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 	OS.gtk_widget_show (webView);
Sami Wagiaalla 75f9fa
@@ -679,9 +933,9 @@ public void create (Composite parent, int style) {
Sami Wagiaalla 75f9fa
 	OS.g_signal_connect (webView, OS.motion_notify_event, JSDOMEventProc.getAddress (), 0);
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 	/*
Sami Wagiaalla 75f9fa
-	* Callbacks to get the events not consumed by WebKit, and to block 
Sami Wagiaalla 75f9fa
-	* them so that they don't get propagated to the parent handle twice.  
Sami Wagiaalla 75f9fa
-	* This hook is set after WebKit and is therefore called after WebKit's 
Sami Wagiaalla 75f9fa
+	* Callbacks to get the events not consumed by WebKit, and to block
Sami Wagiaalla 75f9fa
+	* them so that they don't get propagated to the parent handle twice.
Sami Wagiaalla 75f9fa
+	* This hook is set after WebKit and is therefore called after WebKit's
Sami Wagiaalla 75f9fa
 	* handler because GTK dispatches events in their order of registration.
Sami Wagiaalla 75f9fa
 	*/
Sami Wagiaalla 75f9fa
 	if (!WEBKIT2){
Sami Wagiaalla 75f9fa
@@ -781,12 +1035,20 @@ public void create (Composite parent, int style) {
Sami Wagiaalla 75f9fa
 		}
Sami Wagiaalla 75f9fa
 	}
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
-	eventFunction = new BrowserFunction (browser, "HandleWebKitEvent") { //$NON-NLS-1$
Sami Wagiaalla 75f9fa
-		@Override
Sami Wagiaalla 75f9fa
-		public Object function(Object[] arguments) {
Sami Wagiaalla 75f9fa
-			return handleEventFromFunction (arguments) ? Boolean.TRUE : Boolean.FALSE;
Sami Wagiaalla 75f9fa
-		}
Sami Wagiaalla 75f9fa
-	};
Sami Wagiaalla 75f9fa
+	if (WEBKIT2){
Sami Wagiaalla 75f9fa
+		/* In WebKit2 if the create function is called from a signal handler
Sami Wagiaalla 75f9fa
+		 * which blocks the core process such as "create" signal the following call
Sami Wagiaalla 75f9fa
+		 * will cause a deadlock as the core process is blocked and unable to
Sami Wagiaalla 75f9fa
+		 * execute JavaScript.
Sami Wagiaalla 75f9fa
+		 */
Sami Wagiaalla 75f9fa
+		this.browser.getDisplay().asyncExec(new Runnable() {
Sami Wagiaalla 75f9fa
+			public void run() {
Sami Wagiaalla 75f9fa
+				initializeEventFunction();
Sami Wagiaalla 75f9fa
+			}
Sami Wagiaalla 75f9fa
+		});
Sami Wagiaalla 75f9fa
+	}else {
Sami Wagiaalla 75f9fa
+		initializeEventFunction();
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 	/*
Sami Wagiaalla 75f9fa
 	* Bug in WebKitGTK.  MouseOver/MouseLeave events are not consistently sent from
Sami Wagiaalla 75f9fa
@@ -822,6 +1084,15 @@ public void create (Composite parent, int style) {
Sami Wagiaalla 75f9fa
 	}
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+private void initializeEventFunction(){
Sami Wagiaalla 75f9fa
+	eventFunction = new BrowserFunction (browser, "HandleWebKitEvent") { //$NON-NLS-1$
Sami Wagiaalla 75f9fa
+		@Override
Sami Wagiaalla 75f9fa
+		public Object function(Object[] arguments) {
Sami Wagiaalla 75f9fa
+			return handleEventFromFunction (arguments) ? Boolean.TRUE : Boolean.FALSE;
Sami Wagiaalla 75f9fa
+		}
Sami Wagiaalla 75f9fa
+	};
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 void addEventHandlers (long /*int*/ web_view, boolean top) {
Sami Wagiaalla 75f9fa
 	/*
Sami Wagiaalla 75f9fa
 	* If JS is disabled (causes DOM events to not be delivered) then do not add event
Sami Wagiaalla 75f9fa
@@ -829,7 +1100,7 @@ void addEventHandlers (long /*int*/ web_view, boolean top) {
Sami Wagiaalla 75f9fa
 	*/
Sami Wagiaalla 75f9fa
 	if (!jsEnabled) return;
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
-	if (top && IsWebKit14orNewer) {
Sami Wagiaalla 75f9fa
+	if (top && IsWebKit14orNewer && !WEBKIT2) {
Sami Wagiaalla 75f9fa
 		long /*int*/ domDocument = WebKitGTK.webkit_web_view_get_dom_document (web_view);
Sami Wagiaalla 75f9fa
 		if (domDocument != 0) {
Sami Wagiaalla 75f9fa
 			WindowMappings.put (new LONG (domDocument), new LONG (web_view));
Sami Wagiaalla 75f9fa
@@ -886,6 +1157,9 @@ void addEventHandlers (long /*int*/ web_view, boolean top) {
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 	/* add JS event listener in frames */
Sami Wagiaalla 75f9fa
 	buffer = new StringBuffer ("for (var i = 0; i < frames.length; i++) {"); //$NON-NLS-1$
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	buffer.append ("if (frames[i].document == undefined) { continue; } "); //$NON-NLS-1$
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 	buffer.append ("frames[i].document.addEventListener('keydown', window.SWTkeyhandler, true);"); //$NON-NLS-1$
Sami Wagiaalla 75f9fa
 	buffer.append ("frames[i].document.addEventListener('keypress', window.SWTkeyhandler, true);"); //$NON-NLS-1$
Sami Wagiaalla 75f9fa
 	buffer.append ("frames[i].document.addEventListener('keyup', window.SWTkeyhandler, true);"); //$NON-NLS-1$
Sami Wagiaalla 75f9fa
@@ -915,6 +1189,8 @@ public boolean close () {
Sami Wagiaalla 75f9fa
 boolean close (boolean showPrompters) {
Sami Wagiaalla 75f9fa
 	if (!jsEnabled) return true;
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+	// If the current window or any of its frames have an onbeforeunload
Sami Wagiaalla 75f9fa
+	// function, execute that function.
Sami Wagiaalla 75f9fa
 	String message1 = Compatibility.getMessage("SWT_OnBeforeUnload_Message1"); // $NON-NLS-1$
Sami Wagiaalla 75f9fa
 	String message2 = Compatibility.getMessage("SWT_OnBeforeUnload_Message2"); // $NON-NLS-1$
Sami Wagiaalla 75f9fa
 	String functionName = EXECUTE_ID + "CLOSE"; // $NON-NLS-1$
Sami Wagiaalla 75f9fa
@@ -945,6 +1221,11 @@ boolean close (boolean showPrompters) {
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 @Override
Sami Wagiaalla 75f9fa
 public boolean execute (String script) {
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (WEBKIT2){
Sami Wagiaalla 75f9fa
+		return webkit_extension_execute_script(this.pageId, script, getUrl());
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 	byte[] bytes = null;
Sami Wagiaalla 75f9fa
 	try {
Sami Wagiaalla 75f9fa
 		bytes = (script + '\0').getBytes (CHARSET_UTF8); //$NON-NLS-1$
Sami Wagiaalla 75f9fa
@@ -960,22 +1241,67 @@ public boolean execute (String script) {
Sami Wagiaalla 75f9fa
 	}
Sami Wagiaalla 75f9fa
 	long /*int*/ result = 0;
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
-	if (WEBKIT2){
Sami Wagiaalla 75f9fa
-		WebKitGTK.webkit_web_view_run_javascript (webView, scriptString, 0, 0, 0);
Sami Wagiaalla 75f9fa
-	} else {
Sami Wagiaalla 75f9fa
-		long /*int*/ urlString = WebKitGTK.JSStringCreateWithUTF8CString (bytes);
Sami Wagiaalla 75f9fa
+	long /*int*/ urlString = WebKitGTK.JSStringCreateWithUTF8CString (bytes);
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
-		long /*int*/ frame = WebKitGTK.webkit_web_view_get_main_frame (webView);
Sami Wagiaalla 75f9fa
-		long /*int*/ context = WebKitGTK.webkit_web_frame_get_global_context (frame);
Sami Wagiaalla 75f9fa
-		result = WebKitGTK.JSEvaluateScript (context, scriptString, 0, urlString, 0, null);
Sami Wagiaalla 75f9fa
+	long /*int*/ frame = WebKitGTK.webkit_web_view_get_main_frame (webView);
Sami Wagiaalla 75f9fa
+	long /*int*/ context = WebKitGTK.webkit_web_frame_get_global_context (frame);
Sami Wagiaalla 75f9fa
+	result = WebKitGTK.JSEvaluateScript (context, scriptString, 0, urlString, 0, null);
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
-		WebKitGTK.JSStringRelease (urlString);
Sami Wagiaalla 75f9fa
-	}
Sami Wagiaalla 75f9fa
+	WebKitGTK.JSStringRelease (urlString);
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 	WebKitGTK.JSStringRelease (scriptString);
Sami Wagiaalla 75f9fa
 	return result != 0;
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Execute the given script by sending it through DBus to the webkit extension.
Sami Wagiaalla 75f9fa
+ * @param pageId
Sami Wagiaalla 75f9fa
+ * @param script
Sami Wagiaalla 75f9fa
+ * @param url
Sami Wagiaalla 75f9fa
+ * @return true if execution is successful, false otherwise.
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+private boolean webkit_extension_execute_script (long pageId, String script, String url){
Sami Wagiaalla 75f9fa
+	long /*int*/ args[] = { OS.g_variant_new_uint64(pageId),
Sami Wagiaalla 75f9fa
+			OS.g_variant_new_string (Converter.wcsToMbcs(null, script, true)),
Sami Wagiaalla 75f9fa
+			OS.g_variant_new_string (Converter.wcsToMbcs(null, url, true))};
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	final long /*int*/ argsTuple = OS.g_variant_new_tuple(args, args.length);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	int currentCounter = jsCounter++;
Sami Wagiaalla 75f9fa
+	OS.g_dbus_proxy_call (dbus_proxy,
Sami Wagiaalla 75f9fa
+			Converter.wcsToMbcs(null,"webkit_extension_execute_script", true),
Sami Wagiaalla 75f9fa
+			argsTuple, OS.G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, 0, executeJavaScriptFinishedCallback.getAddress(),currentCounter);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	// The following is a workaround for the fact that g_dbus_proxy_call_sync
Sami Wagiaalla 75f9fa
+	// blocks until it is timed-out and returns a failure.
Sami Wagiaalla 75f9fa
+	// Keep iterating through the event loop until our JavaScript call has finished
Sami Wagiaalla 75f9fa
+	// executing, failed, or timed-out.
Sami Wagiaalla 75f9fa
+	Display display = this.browser.getDisplay();
Sami Wagiaalla 75f9fa
+	while (!display.isDisposed() && jsResults.get(currentCounter) == null) {
Sami Wagiaalla 75f9fa
+		if (!display.readAndDispatch()) display.sleep();
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	long result = jsResults.remove(currentCounter);
Sami Wagiaalla 75f9fa
+	if (result == 0){
Sami Wagiaalla 75f9fa
+		return false;
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	return (Boolean) ((Object[])GVariantConverter.convertGVariantToJava((long /*int*/ )result))[0];
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+@SuppressWarnings("unused")
Sami Wagiaalla 75f9fa
+private static long /*int*/ executeJavaScriptFinishedCallback (long /*int*/ source_object, long /*int*/ res, long /*int*/ user_data){
Sami Wagiaalla 75f9fa
+	long /*int*/[] error = new long /*int*/[1];
Sami Wagiaalla 75f9fa
+	long /*int*/ result = OS.g_dbus_proxy_call_finish (dbus_proxy, res, error);
Sami Wagiaalla 75f9fa
+	int counter = (int) user_data;
Sami Wagiaalla 75f9fa
+	if (error[0] != 0){
Sami Wagiaalla 75f9fa
+		SWT.error(SWT.ERROR_IO, new Throwable(Converter.getString(OS.g_error_get_message(error[0]))));
Sami Wagiaalla 75f9fa
+		result = 0;
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+	jsResults.put(counter, (long)result);
Sami Wagiaalla 75f9fa
+	return 0;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 @Override
Sami Wagiaalla 75f9fa
 public boolean forward () {
Sami Wagiaalla 75f9fa
 	if (WebKitGTK.webkit_web_view_can_go_forward (webView) == 0) return false;
Sami Wagiaalla 75f9fa
@@ -1996,7 +2322,7 @@ long /*int*/ webkit_decide_policy (long /*int*/ web_view, long /*int*/ decision,
Sami Wagiaalla 75f9fa
           return 0;
Sami Wagiaalla 75f9fa
        }
Sami Wagiaalla 75f9fa
        long /*int*/ uri = WebKitGTK.webkit_uri_request_get_uri (request);
Sami Wagiaalla 75f9fa
-       String url = getString(uri);
Sami Wagiaalla 75f9fa
+       String url = Converter.getString(uri);
Sami Wagiaalla 75f9fa
        /*
Sami Wagiaalla 75f9fa
         * If the URI indicates that the page is being rendered from memory
Sami Wagiaalla 75f9fa
         * (via setText()) then set it to about:blank to be consistent with IE.
Sami Wagiaalla 75f9fa
@@ -2075,7 +2401,7 @@ long /*int*/ webkit_load_changed (long /*int*/ web_view, int status, long user_d
Sami Wagiaalla 75f9fa
 			long /*int*/ title = WebKitGTK.webkit_web_view_get_title (webView);
Sami Wagiaalla 75f9fa
 			if (title == 0) {
Sami Wagiaalla 75f9fa
 				long /*int*/ uri = WebKitGTK.webkit_web_view_get_uri (webView);
Sami Wagiaalla 75f9fa
-				fireNewTitleEvent(getString(uri));
Sami Wagiaalla 75f9fa
+				fireNewTitleEvent(Converter.getString(uri));
Sami Wagiaalla 75f9fa
 			}
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 			fireProgressCompletedEvent();
Sami Wagiaalla 75f9fa
@@ -2215,9 +2541,11 @@ long /*int*/ webkit_resource_request_starting (long /*int*/ web_view, long /*int
Sami Wagiaalla 75f9fa
 				// Set the message method type to POST
Sami Wagiaalla 75f9fa
 				WebKitGTK.SoupMessage_method (message, PostString);
Sami Wagiaalla 75f9fa
 				long /*int*/ body = WebKitGTK.SoupMessage_request_body (message);
Sami Wagiaalla 75f9fa
+				// convert custom postData to bytes
Sami Wagiaalla 75f9fa
 				byte[] bytes = Converter.wcsToMbcs (null, postData, false);
Sami Wagiaalla 75f9fa
 				long /*int*/ data = C.malloc (bytes.length);
Sami Wagiaalla 75f9fa
 				C.memmove (data, bytes, bytes.length);
Sami Wagiaalla 75f9fa
+				// Append custom POST data to soup message
Sami Wagiaalla 75f9fa
 				WebKitGTK.soup_message_body_append (body, WebKitGTK.SOUP_MEMORY_TAKE, data, bytes.length);
Sami Wagiaalla 75f9fa
 				WebKitGTK.soup_message_body_flatten (body);
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
@@ -2309,6 +2637,27 @@ long /*int*/ webkit_web_view_ready (long /*int*/ web_view) {
Sami Wagiaalla 75f9fa
 	return 0;
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Called by the extension through DBus to notify the main process that the
Sami Wagiaalla 75f9fa
+ * JavaScript 'window' object has been cleared. This means that window functions
Sami Wagiaalla 75f9fa
+ * such as 'window.external.callJava' has been cleared and should be reinstalled.
Sami Wagiaalla 75f9fa
+ *
Sami Wagiaalla 75f9fa
+ * @param args_variant
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+private static void webkit_extension_window_object_cleared (long /*int*/ args_variant) {
Sami Wagiaalla 75f9fa
+	Object[] args = (Object[]) GVariantConverter.convertGVariantToJava(args_variant);
Sami Wagiaalla 75f9fa
+	long pageId = (Long) args[0];
Sami Wagiaalla 75f9fa
+	boolean isMainFrame = (Boolean) args[1];
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	WebKit instance = findBrowserById(pageId);
Sami Wagiaalla 75f9fa
+	Enumeration elements = instance.functions.elements ();
Sami Wagiaalla 75f9fa
+	while (elements.hasMoreElements ()) {
Sami Wagiaalla 75f9fa
+		BrowserFunction current = (BrowserFunction)elements.nextElement ();
Sami Wagiaalla 75f9fa
+		instance.execute (current.functionString);
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+	instance.addEventHandlers (instance.webView, isMainFrame);
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 long /*int*/ webkit_window_object_cleared (long /*int*/ web_view, long /*int*/ frame, long /*int*/ context, long /*int*/ window_object) {
Sami Wagiaalla 75f9fa
 	long /*int*/ globalObject = WebKitGTK.JSContextGetGlobalObject (context);
Sami Wagiaalla 75f9fa
 	long /*int*/ externalObject = WebKitGTK.JSObjectMake (context, ExternalClass, webViewData);
Sami Wagiaalla 75f9fa
@@ -2332,6 +2681,56 @@ long /*int*/ webkit_window_object_cleared (long /*int*/ web_view, long /*int*/ f
Sami Wagiaalla 75f9fa
 	return 0;
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Called by the extension to forward a call to Java from JavaScript
Sami Wagiaalla 75f9fa
+ * @param args_variant a GVariant containing the arguments passed along from JavaScript
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+private static Object  webkit_extension_external_object_callJava (long /*int*/ args_variant){
Sami Wagiaalla 75f9fa
+	Object[] args = (Object[]) GVariantConverter.convertGVariantToJava(args_variant);
Sami Wagiaalla 75f9fa
+	Object returnValue = null;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (args.length == 4) {
Sami Wagiaalla 75f9fa
+		// The first argument is the pageId
Sami Wagiaalla 75f9fa
+		int i = 0;
Sami Wagiaalla 75f9fa
+		long pageId = (Long) args[i++];
Sami Wagiaalla 75f9fa
+		WebKit browser = findBrowserById(pageId);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+		// The f argument is the function key which is the same as the function index.
Sami Wagiaalla 75f9fa
+		int index = ((Double)args[i++]).intValue();
Sami Wagiaalla 75f9fa
+		Object key = new Integer (index);
Sami Wagiaalla 75f9fa
+		BrowserFunction function = (BrowserFunction)browser.functions.get (key);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+		// The second argument is a String that is equal to the token of the function.
Sami Wagiaalla 75f9fa
+		String token = args[i++].toString();
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+		if (function != null && token.equals (function.token)) {
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+			// The third argument is an array of arguments to the Java function.
Sami Wagiaalla 75f9fa
+			args = (Object[]) args[i++];
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+			if (function != null && token.equals (function.token)) {
Sami Wagiaalla 75f9fa
+				try {
Sami Wagiaalla 75f9fa
+					try {
Sami Wagiaalla 75f9fa
+						returnValue = function.function (args);
Sami Wagiaalla 75f9fa
+					} catch (Exception e) {
Sami Wagiaalla 75f9fa
+						/* exception during function invocation */
Sami Wagiaalla 75f9fa
+						returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
Sami Wagiaalla 75f9fa
+					}
Sami Wagiaalla 75f9fa
+				} catch (IllegalArgumentException e) {
Sami Wagiaalla 75f9fa
+					/* invalid argument value type */
Sami Wagiaalla 75f9fa
+					if (function.isEvaluate) {
Sami Wagiaalla 75f9fa
+						/* notify the function so that a java exception can be thrown */
Sami Wagiaalla 75f9fa
+						function.function (new String[] {WebBrowser.CreateErrorString (new SWTException (SWT.ERROR_INVALID_RETURN_VALUE).getLocalizedMessage ())});
Sami Wagiaalla 75f9fa
+					}
Sami Wagiaalla 75f9fa
+					returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
Sami Wagiaalla 75f9fa
+				}
Sami Wagiaalla 75f9fa
+			}
Sami Wagiaalla 75f9fa
+		}
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	return returnValue;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 long /*int*/ callJava (long /*int*/ ctx, long /*int*/ func, long /*int*/ thisObject, long /*int*/ argumentCount, long /*int*/ arguments, long /*int*/ exception) {
Sami Wagiaalla 75f9fa
 	Object returnValue = null;
Sami Wagiaalla 75f9fa
 	if (argumentCount == 3) {
Sami Wagiaalla 75f9fa
@@ -2339,9 +2738,15 @@ long /*int*/ callJava (long /*int*/ ctx, long /*int*/ func, long /*int*/ thisObj
Sami Wagiaalla 75f9fa
 		C.memmove (result, arguments, C.PTR_SIZEOF);
Sami Wagiaalla 75f9fa
 		int type = WebKitGTK.JSValueGetType (ctx, result[0]);
Sami Wagiaalla 75f9fa
 		if (type == WebKitGTK.kJSTypeNumber) {
Sami Wagiaalla 75f9fa
+			// The arguments are an array of pointers
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+			// The first argument is the function key which is the same as the function index.
Sami Wagiaalla 75f9fa
+			// Extract it.
Sami Wagiaalla 75f9fa
 			int index = ((Double)convertToJava (ctx, result[0])).intValue ();
Sami Wagiaalla 75f9fa
 			result[0] = 0;
1a78a8
 			Integer key = new Integer (index);
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+			// The second argument is a String that is equal to the token of the function.
Sami Wagiaalla 75f9fa
 			C.memmove (result, arguments + C.PTR_SIZEOF, C.PTR_SIZEOF);
Sami Wagiaalla 75f9fa
 			type = WebKitGTK.JSValueGetType (ctx, result[0]);
Sami Wagiaalla 75f9fa
 			if (type == WebKitGTK.kJSTypeString) {
Sami Wagiaalla 75f9fa
@@ -2349,6 +2754,7 @@ long /*int*/ callJava (long /*int*/ ctx, long /*int*/ func, long /*int*/ thisObj
25f005
 				BrowserFunction function = functions.get (key);
Sami Wagiaalla 75f9fa
 				if (function != null && token.equals (function.token)) {
Sami Wagiaalla 75f9fa
 					try {
Sami Wagiaalla 75f9fa
+						// The third argument is an array of arguments to the Java function.
Sami Wagiaalla 75f9fa
 						C.memmove (result, arguments + 2 * C.PTR_SIZEOF, C.PTR_SIZEOF);
Sami Wagiaalla 75f9fa
 						Object temp = convertToJava (ctx, result[0]);
Sami Wagiaalla 75f9fa
 						if (temp instanceof Object[]) {
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java
Sami Wagiaalla 75f9fa
index f7505ba..71876c0 100644
Sami Wagiaalla 75f9fa
--- eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java	
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java	
Sami Wagiaalla 75f9fa
@@ -57,6 +57,7 @@ public class WebKitGTK extends C {
Sami Wagiaalla 75f9fa
 	public static final byte[] decide_policy = ascii ("decide-policy"); // $NON-NLS-1$
Sami Wagiaalla 75f9fa
 	public static final byte[] download_requested = ascii ("download-requested"); // $NON-NLS-1$
Sami Wagiaalla 75f9fa
 	public static final byte[] download_started = ascii ("download-started"); // $NON-NLS-1$
Sami Wagiaalla 75f9fa
+	public static final byte[] initialize_web_extensions = ascii("initialize-web-extensions"); // $NON-NLS-1$
Sami Wagiaalla 75f9fa
 	public static final byte[] hovering_over_link = ascii ("hovering-over-link"); // $NON-NLS-1$
Sami Wagiaalla 75f9fa
 	public static final byte[] load_changed = ascii ("load-changed"); // $NON-NLS-1$
Sami Wagiaalla 75f9fa
 	public static final byte[] mime_type_policy_decision_requested = ascii ("mime-type-policy-decision-requested"); // $NON-NLS-1$
Sami Wagiaalla 75f9fa
@@ -1132,6 +1133,29 @@ public static final long /*int*/ webkit_web_context_get_default () {
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 /** @method flags=dynamic */
Sami Wagiaalla 75f9fa
+public static final native void _webkit_web_context_set_web_extensions_initialization_user_data (long /*int*/ context, long /*int*/ user_data);
Sami Wagiaalla 75f9fa
+public static final void webkit_web_context_set_web_extensions_initialization_user_data (long /*int*/ context,  long /*int*/ user_data) {
Sami Wagiaalla 75f9fa
+	lock.lock();
Sami Wagiaalla 75f9fa
+	try {
Sami Wagiaalla 75f9fa
+		_webkit_web_context_set_web_extensions_initialization_user_data (context, user_data);
Sami Wagiaalla 75f9fa
+	} finally {
Sami Wagiaalla 75f9fa
+		lock.unlock();
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/** @method flags=dynamic */
Sami Wagiaalla 75f9fa
+public static final native void _webkit_web_context_set_web_extensions_directory (long /*int*/ context, byte[] directory);
Sami Wagiaalla 75f9fa
+public static final void webkit_web_context_set_web_extensions_directory (long /*int*/ context, byte[] directory) {
Sami Wagiaalla 75f9fa
+	lock.lock();
Sami Wagiaalla 75f9fa
+	try {
Sami Wagiaalla 75f9fa
+		_webkit_web_context_set_web_extensions_directory (context, directory);
Sami Wagiaalla 75f9fa
+	} finally {
Sami Wagiaalla 75f9fa
+		lock.unlock();
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/** @method flags=dynamic */
Sami Wagiaalla 75f9fa
 public static final native long /*int*/ _webkit_web_context_set_favicon_database_directory (long /*int*/ context, long /*int*/ path);
Sami Wagiaalla 75f9fa
 public static final long /*int*/ webkit_web_context_set_favicon_database_directory (long /*int*/ context, long /*int*/ path) {
Sami Wagiaalla 75f9fa
 	lock.lock();
Sami Wagiaalla 75f9fa
@@ -1364,6 +1388,17 @@ public static final long /*int*/ webkit_web_view_get_main_frame (long /*int*/ we
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 /** @method flags=dynamic */
Sami Wagiaalla 75f9fa
+public static final native long /*int*/ _webkit_web_view_get_page_id (long /*int*/ web_view);
Sami Wagiaalla 75f9fa
+public static final long /*int*/ webkit_web_view_get_page_id (long /*int*/ web_view) {
Sami Wagiaalla 75f9fa
+	lock.lock();
Sami Wagiaalla 75f9fa
+	try {
Sami Wagiaalla 75f9fa
+		return _webkit_web_view_get_page_id (web_view);
Sami Wagiaalla 75f9fa
+	} finally {
Sami Wagiaalla 75f9fa
+		lock.unlock();
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/** @method flags=dynamic */
Sami Wagiaalla 75f9fa
 public static final native double _webkit_web_view_get_progress (long /*int*/ web_view);
Sami Wagiaalla 75f9fa
 public static final double webkit_web_view_get_progress (long /*int*/ web_view) {
Sami Wagiaalla 75f9fa
 	lock.lock();
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/Converter.java eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/Converter.java
Sami Wagiaalla 75f9fa
index 4b8c089..176b44f 100644
Sami Wagiaalla 75f9fa
--- eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/Converter.java	
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/Converter.java	
Sami Wagiaalla 75f9fa
@@ -36,6 +36,13 @@ public static String defaultCodePage () {
Sami Wagiaalla 75f9fa
 	return "UTF8";
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
+public static String getString (long /*int*/ strPtr) {
Sami Wagiaalla 75f9fa
+	int length = OS.strlen (strPtr);
Sami Wagiaalla 75f9fa
+	byte [] buffer = new byte [length];
Sami Wagiaalla 75f9fa
+	OS.memmove (buffer, strPtr, length);
Sami Wagiaalla 75f9fa
+	return new String (Converter.mbcsToWcs (null, buffer));
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
 public static char [] mbcsToWcs (String codePage, byte [] buffer) {
Sami Wagiaalla 75f9fa
 	long /*int*/ [] items_written = new long /*int*/ [1];
Sami Wagiaalla 75f9fa
 	long /*int*/ ptr = OS.g_utf8_to_utf16 (buffer, buffer.length, null, items_written, null);
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/GVariantConverter.java eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/GVariantConverter.java
Sami Wagiaalla 75f9fa
new file mode 100644
Sami Wagiaalla 75f9fa
index 0000000..dc19b0f
Sami Wagiaalla 75f9fa
--- /dev/null
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/GVariantConverter.java	
Sami Wagiaalla 75f9fa
@@ -0,0 +1,98 @@
Sami Wagiaalla 75f9fa
+/*******************************************************************************
Sami Wagiaalla 75f9fa
+ * Copyright (c) 2014 Red Hat and others.
Sami Wagiaalla 75f9fa
+ * All rights reserved. This program and the accompanying materials
Sami Wagiaalla 75f9fa
+ * are made available under the terms of the Eclipse Public License v1.0
Sami Wagiaalla 75f9fa
+ * which accompanies this distribution, and is available at
Sami Wagiaalla 75f9fa
+ * http://www.eclipse.org/legal/epl-v10.html
Sami Wagiaalla 75f9fa
+ *
Sami Wagiaalla 75f9fa
+ * Contributors:
Sami Wagiaalla 75f9fa
+ *     Red Hat - initial API and implementation
Sami Wagiaalla 75f9fa
+ *******************************************************************************/
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+package org.eclipse.swt.internal;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+import org.eclipse.swt.SWT;
Sami Wagiaalla 75f9fa
+import org.eclipse.swt.internal.gtk.OS;
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+public class GVariantConverter {
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Converts the given GVariant to a Java object
Sami Wagiaalla 75f9fa
+ * @param value a pointer to the native GVariant
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+public static Object convertGVariantToJava(long /*int*/ value){
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (OS.g_variant_is_of_type(value, OS.G_VARIANT_TYPE_BOOLEAN)){
Sami Wagiaalla 75f9fa
+		return new Boolean(OS.g_variant_get_boolean(value));
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (OS.g_variant_is_of_type(value, OS.G_VARIANT_TYPE_DOUBLE)){
Sami Wagiaalla 75f9fa
+		return new Double(OS.g_variant_get_double(value));
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (OS.g_variant_is_of_type(value, OS.G_VARIANT_TYPE_STRING)){
Sami Wagiaalla 75f9fa
+		return Converter.getString(OS.g_variant_get_string(value, null));
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (OS.g_variant_is_of_type(value, OS.G_VARIANT_TYPE_UINT64)){
Sami Wagiaalla 75f9fa
+		return new Long(OS.g_variant_get_uint64(value));
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (OS.g_variant_is_of_type(value, OS.G_VARIANT_TYPE_TUPLE)){
Sami Wagiaalla 75f9fa
+		int length = (int)OS.g_variant_n_children (value);
Sami Wagiaalla 75f9fa
+		Object[] result = new Object[length];
Sami Wagiaalla 75f9fa
+		for (int i = 0; i < length; i++) {
Sami Wagiaalla 75f9fa
+			result[i] = convertGVariantToJava (OS.g_variant_get_child_value(value, i));
Sami Wagiaalla 75f9fa
+		}
Sami Wagiaalla 75f9fa
+		return result;
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	String typeString = Converter.getString(OS.g_variant_get_type_string(value));
Sami Wagiaalla 75f9fa
+	SWT.error (SWT.ERROR_INVALID_ARGUMENT, new Throwable("Unhandled variant type " + typeString ));
Sami Wagiaalla 75f9fa
+	return null;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+/**
Sami Wagiaalla 75f9fa
+ * Converts the given Java Object to a GVariant representation
Sami Wagiaalla 75f9fa
+ * @param value a pointer to the native GVariant
Sami Wagiaalla 75f9fa
+ */
Sami Wagiaalla 75f9fa
+public static long /*int*/ convertJavaToGVariant(Object value){
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (value == null) {
Sami Wagiaalla 75f9fa
+		return OS.g_variant_new_byte((byte) 0x00);
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (value instanceof String) {
Sami Wagiaalla 75f9fa
+		return OS.g_variant_new_string (Converter.wcsToMbcs(null, (String) value, true));
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (value instanceof Boolean) {
Sami Wagiaalla 75f9fa
+		return OS.g_variant_new_boolean((Boolean) value);
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (value instanceof Double) {
Sami Wagiaalla 75f9fa
+		return OS.g_variant_new_double (((Double) value).doubleValue());
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (value instanceof Long) {
Sami Wagiaalla 75f9fa
+		return OS.g_variant_new_int64((Long) value);
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	if (value instanceof Object[]) {
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+		Object[] arrayValue = (Object[]) value;
Sami Wagiaalla 75f9fa
+		int length = arrayValue.length;
Sami Wagiaalla 75f9fa
+		long /*int*/ variants[] = new long /*int*/[length];
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+		for (int i = 0; i < length; i++) {
Sami Wagiaalla 75f9fa
+			variants[i] = convertJavaToGVariant(arrayValue[i]);
Sami Wagiaalla 75f9fa
+		}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+		return OS.g_variant_new_tuple(variants, length);
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+	SWT.error (SWT.ERROR_INVALID_RETURN_VALUE, new Throwable("Unhandled type " + value.getClass()));
Sami Wagiaalla 75f9fa
+	return 0;
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
+
Sami Wagiaalla 75f9fa
+}
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/browser/Browser4.java eclipse.platform.swt/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/browser/Browser4.java
Sami Wagiaalla 75f9fa
index f254c91..c33e138 100644
Sami Wagiaalla 75f9fa
--- eclipse.platform.swt/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/browser/Browser4.java	
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/browser/Browser4.java	
Sami Wagiaalla 75f9fa
@@ -84,8 +84,8 @@ public class Browser4 {
Sami Wagiaalla 75f9fa
 					shell.close();
Sami Wagiaalla 75f9fa
 					return;					
Sami Wagiaalla 75f9fa
 				}
Sami Wagiaalla 75f9fa
-				shell2.open();
Sami Wagiaalla 75f9fa
 				visibilityShow = true;
Sami Wagiaalla 75f9fa
+				shell2.open();
Sami Wagiaalla 75f9fa
 			}
Sami Wagiaalla 75f9fa
 		});
Sami Wagiaalla 75f9fa
 		browser2.addProgressListener(new ProgressListener() {
Sami Wagiaalla 75f9fa
diff --git eclipse.platform.swt/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/browser/Test_BrowserSuite.java eclipse.platform.swt/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/browser/Test_BrowserSuite.java
Sami Wagiaalla 75f9fa
index 763c1fe..b7fbb02 100644
Sami Wagiaalla 75f9fa
--- eclipse.platform.swt/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/browser/Test_BrowserSuite.java	
Sami Wagiaalla 75f9fa
+++ eclipse.platform.swt/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/browser/Test_BrowserSuite.java	
Sami Wagiaalla 75f9fa
@@ -54,6 +54,15 @@ public void testBrowser8() {
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa
 
Sami Wagiaalla 75f9fa
 public void testBrowser9() {
Sami Wagiaalla 75f9fa
+	String webkit2 = System.getenv("SWT_WEBKIT2"); // $NON-NLS-1$
Sami Wagiaalla 75f9fa
+	boolean WEBKIT2 = webkit2 != null && webkit2.equals("1"); // $NON-NLS-1$
Sami Wagiaalla 75f9fa
+	/* WebKit2GTK+ does not support the "status-bar-text-changed" signal
Sami Wagiaalla 75f9fa
+	 * which this test is testing.
Sami Wagiaalla 75f9fa
+	 * RFE: https://bugs.webkit.org/show_bug.cgi?id=128604
Sami Wagiaalla 75f9fa
+	 */
Sami Wagiaalla 75f9fa
+	if(WEBKIT2){
Sami Wagiaalla 75f9fa
+		return;
Sami Wagiaalla 75f9fa
+	}
Sami Wagiaalla 75f9fa
 	assertTrue(Browser9.test());
Sami Wagiaalla 75f9fa
 }
Sami Wagiaalla 75f9fa