At long last, I have webclient running on Mac OSX.  I only have a
PowerBook G4, so the only binary I can produce is for the PowerPC.
Perhaps someone lucky enough to own a MacBookPro can produce a binary
for me on that processor architecture.

Many thanks to the generous folks on #developers, in particular,
timeless,
cbarrett, sdwilsh, and jhpedemonte.

Here are the changes.

SECTION: Changes

M dist/build.xml

- propogate clean on mac os x

- On mac os x, there is .jnilib and also .dylib

M dom/build.xml

- propogate make on mac os x

M webclient/build.xml

- new file for javah on mac

- propogate clobber_all on mac

M webclient/classes_spec/org/mozilla/webclient/
BrowserControlCanvas.java

- get the tree lock before calling to native code to get the native
window

A webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/
CocoaAppKitThreadDelegatingNativeEventThread.java

- Allows running arbitrary code on the AppKit thread.  Prevents Thread
  Safety assertions.

M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/
CocoaBrowserControlCanvas.java

- adhere to informal protocol to create NativeEventThread

M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/
ImplObjectNative.java

- use NativeEventThread.instance.isNativeEventThread()

M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/
NativeEventThread.java

- implement isNativeEventThread()

M webclient/src_moz/Makefile.in

- turn on objc-exceptions on mac os x

M webclient/src_moz/NativeBrowserControl.cpp
M webclient/src_moz/NativeBrowserControl.h

- work with cocoa

M webclient/src_moz/NativeEventThread.cpp
M webclient/src_moz/cocoa/CocoaBrowserControlCanvas.h
M webclient/src_moz/cocoa/CocoaBrowserControlCanvasImpl.cpp

- two methods to run arbitrary code on the AppKit thread

M webclient/src_moz/cocoa/CocoaBrowserControlCanvas.mm
M webclient/test/manual/src/classes/org/mozilla/webclient/test/
TestBrowser.java

SECTION: Diffs

Index: dist/build.xml
===================================================================
RCS file: /cvsroot/mozilla/java/dist/build.xml,v
retrieving revision 1.24
diff -u -r1.24 build.xml
--- dist/build.xml      4 Jun 2007 17:10:02 -0000       1.24
+++ dist/build.xml      10 Jun 2007 16:11:31 -0000
@@ -97,6 +97,25 @@
   </target>

   <target name="clean">
+    <condition property="platform" value="win32">
+      <and>
+        <os family="windows" />
+      </and>
+    </condition>
+
+    <condition property="platform" value="macosx-ppc">
+      <and>
+        <os name="Mac OS X" />
+      </and>
+    </condition>
+
+
+    <condition property="platform" value="linux">
+      <and>
+        <os family="unix" />
+      </and>
+    </condition>
+
     <delete file="${objdir}/${name}_${version}_${platform}.zip"  />
     <delete dir="${dist.base}" />
   </target>
@@ -249,7 +268,7 @@
     <copy todir="${dist.home}/bin"
          file="${objdir}/java/dom/jni/${so.prefix}javadomjni.$
{jni.extension}" />
     <copy todir="${dist.home}/bin"
-          file="${objdir}/java/webclient/src_moz/${so.prefix}${name}.$
{so.extension}" />
+          file="${objdir}/java/webclient/src_moz/${so.prefix}${name}.$
{jni.extension}" />

   </target>

Index: dom/build.xml
===================================================================
RCS file: /cvsroot/mozilla/java/dom/build.xml,v
retrieving revision 1.9
diff -u -r1.9 build.xml
--- dom/build.xml       24 May 2007 04:16:58 -0000      1.9
+++ dom/build.xml       10 Jun 2007 16:11:32 -0000
@@ -107,7 +107,7 @@
                      executable="make"/>
     <exec os="Windows 2000" dir="${objdir.native.path}/jni"
executable="make"
                      failonerror="yes"/>
-    <exec os="Mac OS X" dir="${objdir.native.path}/src"
failonerror="yes"
+    <exec os="Mac OS X" dir="${objdir.native.path}/jni"
failonerror="yes"
                      executable="make"/>

   </target>
@@ -176,6 +176,12 @@
       <arg line="clobber_all"/>
     </exec>

+    <exec os="Mac OS X" dir="${objdir.native.path}/jni"
failonerror="yes"
+                     executable="make">
+      <arg line="clobber_all"/>
+    </exec>
+
+
     <delete>
       <fileset dir="" includes="**/*.ilk"/>
     </delete>
Index: webclient/build.xml
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/build.xml,v
retrieving revision 1.34
diff -u -r1.34 build.xml
--- webclient/build.xml 24 May 2007 04:16:58 -0000      1.34
+++ webclient/build.xml 10 Jun 2007 16:11:32 -0000
@@ -194,7 +194,7 @@
     <mkdir dir="${objdir.native.path}/src_moz/cocoa" />

     <javah destdir="${objdir.native.path}/src_moz/cocoa"
-
class="org.mozilla.webclient.impl.wrapper_native.CocoaBrowserControlCanvas">
+
class="org.mozilla.webclient.impl.wrapper_native.CocoaBrowserControlCanvas,org.mozilla.webclient.impl.wrapper_native.CocoaAppKitThreadDelegatingNativeEventThread">
       <classpath refid="compile.classpath"/>
     </javah>

@@ -343,6 +343,12 @@
                      failonerror="yes">
       <arg line="clobber_all"/>
     </exec>
+
+    <exec os="Mac OS X" dir="${objdir.native.path}/src_moz"
executable="make"
+                     failonerror="yes">
+      <arg line="clobber_all"/>
+    </exec>
+
     <exec os="Windows 2000" dir="${objdir.native.path}/src_ie"
executable="make"
                      failonerror="yes">
       <arg line="clobber_all"/>
Index: webclient/classes_spec/org/mozilla/webclient/
BrowserControlCanvas.java
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/classes_spec/org/mozilla/
webclient/BrowserControlCanvas.java,v
retrieving revision 1.9
diff -u -r1.9 BrowserControlCanvas.java
--- webclient/classes_spec/org/mozilla/webclient/
BrowserControlCanvas.java       1 Dec 2004 03:21:22 -0000       1.9
+++ webclient/classes_spec/org/mozilla/webclient/
BrowserControlCanvas.java       10 Jun 2007 16:11:32 -0000
@@ -141,25 +141,30 @@
        super.addNotify();

        windowRelativeBounds = new Rectangle();
+        if (0 != nativeWindow) {
+            return;
+        }
+
+        synchronized (getTreeLock()) {
+            //Create the Native gtkWindow and it's container and
+            //get a handle to this widget
+            nativeWindow = getWindow();
+
+            try {
+                Rectangle r = new
Rectangle(getBoundsRelativeToWindow());
+                Assert.assert_it(null != webShell);

-    //Create the Native gtkWindow and it's container and
-    //get a handle to this widget
-       nativeWindow = getWindow();
-
-       try {
-               Rectangle r = new Rectangle(getBoundsRelativeToWindow());
-        Assert.assert_it(null != webShell);
-
-        WindowControl wc = (WindowControl)
-
webShell.queryInterface(BrowserControl.WINDOW_CONTROL_NAME);
-        //This createWindow call sets in motion the creation of the
-        //nativeInitContext and the creation of the Mozilla embedded
-        //webBrowser
-        wc.createWindow(nativeWindow, r);
-       } catch (Exception e) {
-               System.out.println(e.toString());
-               return;
-       }
+                WindowControl wc = (WindowControl)
+
webShell.queryInterface(BrowserControl.WINDOW_CONTROL_NAME);
+                //This createWindow call sets in motion the creation
of the
+                //nativeInitContext and the creation of the Mozilla
embedded
+                //webBrowser
+                wc.createWindow(nativeWindow, r);
+            } catch (Exception e) {
+                System.out.println(e.toString());
+                return;
+            }
+        }

        initializeOK = true;
        webShellCount++;
Index: webclient/classes_spec/org/mozilla/webclient/impl/
wrapper_native/CocoaBrowserControlCanvas.java
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/classes_spec/org/mozilla/
webclient/impl/wrapper_native/CocoaBrowserControlCanvas.java,v
retrieving revision 1.5
diff -u -r1.5 CocoaBrowserControlCanvas.java
--- webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/
CocoaBrowserControlCanvas.java  12 Mar 2007 20:39:22 -0000      1.5
+++ webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/
CocoaBrowserControlCanvas.java  10 Jun 2007 16:11:32 -0000
@@ -28,10 +28,11 @@

 import org.mozilla.webclient.BrowserControlCanvas;

-import org.mozilla.util.ReturnRunnable;
-import org.mozilla.webclient.impl.wrapper_native.NativeEventThread;
-
 import java.awt.*;
+import java.util.logging.Logger;
+import org.mozilla.util.Log;
+import org.mozilla.util.ReturnRunnable;
+import org.mozilla.webclient.impl.WrapperFactory;

 /**
  *
@@ -39,13 +40,20 @@
  */
 public class CocoaBrowserControlCanvas extends BrowserControlCanvas {

+    public static final String LOG =
"org.mozilla.webclient.impl.wrapper_native.CocoaBrowserControlCanvas";
+
+    public static final Logger LOGGER = Log.getLogger(LOG);
+
+
     /** Creates a new instance of CocoaBrowserControlCanvas */
     public CocoaBrowserControlCanvas() {
     }

     //New method for obtaining access to the Native Peer handle
     private native int getHandleToPeer();
-    private native void paintMe(Graphics g);
+
+    private boolean didGetWindow = false;
+    private int nativeView = 0;

        /**
         * Obtain the native window handle for this
@@ -54,40 +62,29 @@
         * @returns The native window handle.
         */
     protected int getWindow() {
-       Integer result = (Integer)
-           NativeEventThread.instance.pushBlockingReturnRunnable(new
ReturnRunnable(){
-                   public Object run() {
-                       Integer result =
-                           new 
Integer(CocoaBrowserControlCanvas.this.getHandleToPeer());
-                       return result;
-                   }
-                    public String toString() {
-                        return "WCRunnable.getHandleToPeer";
-                    }
+        if (!didGetWindow) {
+            Integer result = (Integer)
+            NativeEventThread.instance.pushBlockingReturnRunnable(new
ReturnRunnable(){
+                public Object run() {
+                    Integer result =
+                            new
Integer(CocoaBrowserControlCanvas.this.getHandleToPeer());
+                    return result;
+                }
+                public String toString() {
+                    return "WCRunnable.getHandleToPeer";
+                }

-               });
-       return result.intValue();
-    }
-
-    public void paint(Graphics g) {
-        g.setColor(Color.green);
-        g.fillRect(0, 0, 100, 100);
+            });
+            nativeView = result.intValue();
+        }
+       return nativeView;

-        g.setColor(Color.blue);
-        g.fillRect(5, 5, 90, 90);
-
-        // flush any outstanding graphics operations
-        Toolkit.getDefaultToolkit().sync();
-        // Call native code to render third (red) rect
-        paintMe(g);
-
-        g.setColor(Color.yellow);
-        g.fillRect(25, 25, 50, 50);
-
-        g.setColor(Color.black);
-        g.fillRect(40, 40, 20, 20);
     }
-

+    public static NativeEventThread
newNativeEventThread(WrapperFactory owner) {
+        NativeEventThread result = new
CocoaAppKitThreadDelegatingNativeEventThread("WebclientEventThread",
+                owner);
+        return result;
+    }

 }
Index: webclient/classes_spec/org/mozilla/webclient/impl/
wrapper_native/ImplObjectNative.java
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/classes_spec/org/mozilla/
webclient/impl/wrapper_native/ImplObjectNative.java,v
retrieving revision 1.5
diff -u -r1.5 ImplObjectNative.java
--- webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/
ImplObjectNative.java   17 Apr 2004 21:25:11 -0000      1.5
+++ webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/
ImplObjectNative.java   10 Jun 2007 16:11:32 -0000
@@ -100,7 +100,7 @@
 }

 protected boolean isNativeEventThread() {
-    return (Thread.currentThread() == NativeEventThread.instance);
+    return (NativeEventThread.instance.isNativeEventThread());
 }


Index: webclient/classes_spec/org/mozilla/webclient/impl/
wrapper_native/NativeEventThread.java
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/classes_spec/org/mozilla/
webclient/impl/wrapper_native/NativeEventThread.java,v
retrieving revision 1.15
diff -u -r1.15 NativeEventThread.java
--- webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/
NativeEventThread.java  13 Mar 2007 06:21:45 -0000      1.15
+++ webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/
NativeEventThread.java  10 Jun 2007 16:11:32 -0000
@@ -93,6 +93,10 @@
        runnables = new ConcurrentLinkedQueue<Runnable>();
     }

+    public boolean isNativeEventThread() {
+        return (Thread.currentThread() ==
NativeEventThread.instance);
+    }
+
     /**
      *
      * This is a very delicate method, and possibly subject to race
@@ -146,6 +150,11 @@

 public void run()
 {
+    // PENDING(edburns): On Mac OS X, the loading of native libraries
+    // should happen on the AppKit thread, at least in the case of
embedding
+    // mozilla.  To do this, you need to put the runOnAppKitThread
functionality
+    // into its own native library, load that first, *then* on the
AppKitThread
+    // load the other native libraries.
     nativeWrapperFactory =
wrapperFactory.loadNativeLibrariesIfNecessary();

     // our owner must have put an event in the queue
Index: webclient/src_moz/Makefile.in
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/src_moz/Makefile.in,v
retrieving revision 1.58
diff -u -r1.58 Makefile.in
--- webclient/src_moz/Makefile.in       24 May 2007 04:16:59 -0000      1.58
+++ webclient/src_moz/Makefile.in       10 Jun 2007 16:11:32 -0000
@@ -142,9 +142,9 @@
 ifeq ($(OS_ARCH),Darwin)
 CMMSRCS = cocoa/CocoaBrowserControlCanvas.mm
 CPPSRCS += cocoa/CocoaBrowserControlCanvasImpl.cpp
-DLL_SUFFIX = .dylib
+DLL_SUFFIX = .jnilib
 #DSO_LDOPTS += -L/System/Library/Frameworks/JavaVM.Framework/
Libraries -ljawt
-DSO_LDOPTS += -framework JavaVM -framework AppKit -lobjc -L$
(srcdir)/../src_share
+DSO_LDOPTS += -framework JavaVM -framework AppKit -lobjc -L$
(srcdir)/../src_share -framework Carbon
 else
 ifeq ($(OS_ARCH),WINNT)
 CPPSRCS += \
@@ -215,7 +215,8 @@
        -I$(srcdir)/../src_share -I../src_share -I. -I./win32
 else
 ifeq ($(OS_ARCH),Darwin)
-INCLUDES := -I$(MOZ_JDKHOME)/include $(INCLUDES) -I$(srcdir)/../
src_share -I../src_share -I. -I$(srcdir) -I$(srcdir)/cocoa -I./cocoa
+INCLUDES := -I$(MOZ_JDKHOME)/include $(INCLUDES) -I$(srcdir)/../
src_share -I../src_share -I. -I$(srcdir) -I$(srcdir)/cocoa -I./cocoa -I
$(DIST)/include/plugin
+CXXFLAGS += -fobjc-exceptions
 else
 INCLUDES := -I$(MOZ_JDKHOME)/include -I$(MOZ_JDKHOME)/include/solaris
$(INCLUDES) \
        -I$(DEPTH)/widget/src/gtk -I$(srcdir)/../src_share -I../src_share
Index: webclient/src_moz/NativeBrowserControl.cpp
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/src_moz/
NativeBrowserControl.cpp,v
retrieving revision 1.17
diff -u -r1.17 NativeBrowserControl.cpp
--- webclient/src_moz/NativeBrowserControl.cpp  9 Mar 2007 04:34:24
-0000   1.17
+++ webclient/src_moz/NativeBrowserControl.cpp  10 Jun 2007 16:11:33
-0000
@@ -37,6 +37,7 @@
 #include "EmbedEventListener.h"
 #include "NativeBrowserControl.h"
 #include "ns_util.h"
+#include "ns_globals.h"

 // all of the crap that we need for event listeners
 // and when chrome windows finish loading
@@ -132,6 +133,10 @@
                               void *parentWinPtr, PRBool
*aAlreadyRealized,
                               PRUint32 width, PRUint32 height)
 {
+
+    // parentWinPtr is whatever was returned from
+    // <platform>BrowserControlCanvas.getWindow().
+
     nsresult rv = NS_OK;
     mJavaBrowserControl = javaBrowserControl;

@@ -147,10 +152,10 @@
     parentHWnd = ownerAsWidget;
     width = ownerAsWidget->allocation.width;
     height = ownerAsWidget->allocation.height;
-#elif !defined(XP_MACOSX)
+#elif defined(XP_PC)
     parentHWnd = (HWND) parentWinPtr;
-#else
-    parentHWnd = parentWinPtr;
+#elif (defined(XP_MAC) || defined(XP_MACOSX)) &&
defined(MOZ_WIDGET_COCOA)
+    parentHWnd = (void *) parentWinPtr;
 #endif

     // create the window
Index: webclient/src_moz/NativeBrowserControl.h
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/src_moz/
NativeBrowserControl.h,v
retrieving revision 1.11
diff -u -r1.11 NativeBrowserControl.h
--- webclient/src_moz/NativeBrowserControl.h    13 May 2005 06:40:11
-0000   1.11
+++ webclient/src_moz/NativeBrowserControl.h    10 Jun 2007 16:11:33
-0000
@@ -108,9 +108,9 @@

 #if defined(XP_UNIX) &&!defined(XP_MACOSX)
     GtkWidget *                    parentHWnd;
-#elif defined(XP_MAC) || defined(XP_MACOSX)
+#elif (defined(XP_MAC) || defined(XP_MACOSX))
     void *                         parentHWnd;
-#else !defined(XP_MACOSX)
+#else
     HWND                           parentHWnd;
 #endif

Index: webclient/src_moz/NativeEventThread.cpp
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/src_moz/
NativeEventThread.cpp,v
retrieving revision 1.47
diff -u -r1.47 NativeEventThread.cpp
--- webclient/src_moz/NativeEventThread.cpp     5 Mar 2006 03:53:08 -0000
1.47
+++ webclient/src_moz/NativeEventThread.cpp     10 Jun 2007 16:11:33 -0000
@@ -41,6 +41,11 @@
 #include <windows.h>
 #endif

+#if (defined(XP_MAC) || defined(XP_MACOSX)) &&
defined(MOZ_WIDGET_COCOA)
+#include "CocoaBrowserControlCanvas.h"
+#include
"org_mozilla_webclient_impl_wrapper_0005fnative_CocoaAppKitThreadDelegatingNativeEventThread.h"
+#endif
+
 //#include "nsAppShellCIDs.h" // for NS_SESSIONHISTORY_CID
 #include "nsCOMPtr.h" // to get nsIBaseWindow from webshell
 //nsIDocShell is included in ns_util.h
@@ -428,5 +433,43 @@
     return rv;
 }

+#if (defined(XP_MAC) || defined(XP_MACOSX)) &&
defined(MOZ_WIDGET_COCOA)
+
+JNIEXPORT jobject JNICALL
+Java_org_mozilla_webclient_impl_wrapper_1native_CocoaAppKitThreadDelegatingNativeEventThread_runReturnRunnableOnAppKitThread
+(JNIEnv *env, jobject javaThis, jobject toInvoke)
+{
+    jobject result = nsnull;
+
+    if (nsnull == javaThis || nsnull == toInvoke) {
+        ::util_ThrowExceptionToJava(env,
"CocoaAppKitThreadDelegatingNativeEventThread.runReturnRunnableOnAppKitThread:
null arguments");
+        return;
+    }
+
+    result =
CocoaBrowserControlCanvas::runReturnRunnableOnAppKitThread(env,
+
javaThis,
+
toInvoke);
+
+    return result;
+}
+
+JNIEXPORT void JNICALL
+Java_org_mozilla_webclient_impl_wrapper_1native_CocoaAppKitThreadDelegatingNativeEventThread_runRunnableOnAppKitThread
+(JNIEnv *env, jobject javaThis, jobject toInvoke)
+{
+    // Store our pointer to the global vm
+    if (nsnull == gVm) { // declared in ../src_share/jni_util.h
+        ::util_GetJavaVM(env, &gVm);  // save this vm reference
+    }
+
+    if (nsnull == javaThis || nsnull == toInvoke) {
+        ::util_ThrowExceptionToJava(env,
"CocoaAppKitThreadDelegatingNativeEventThread.runReturnRunnableOnAppKitThread:
null arguments");
+        return;
+    }
+
+    CocoaBrowserControlCanvas::runRunnableOnAppKitThread(env,
javaThis,
+                                                         toInvoke);
+}


+#endif
Index: webclient/src_moz/cocoa/CocoaBrowserControlCanvas.h
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/src_moz/cocoa/
CocoaBrowserControlCanvas.h,v
retrieving revision 1.3
diff -u -r1.3 CocoaBrowserControlCanvas.h
--- webclient/src_moz/cocoa/CocoaBrowserControlCanvas.h 23 May 2005
01:10:22 -0000  1.3
+++ webclient/src_moz/cocoa/CocoaBrowserControlCanvas.h 10 Jun 2007
16:11:33 -0000
@@ -31,8 +31,11 @@
 public:

   static jint cocoaGetHandleToPeer(JNIEnv *env, jobject canvas);
-  static void paintMe(JNIEnv *env, jobject canvas, jobject graphics);
-
+  static void cocoaPaint(JNIEnv *env, jobject canvas, jobject
graphics);
+  static jobject runReturnRunnableOnAppKitThread(JNIEnv *env, jobject
javaThis,
+                                                 jobject toInvoke);
+  static void runRunnableOnAppKitThread(JNIEnv *env, jobject
javaThis,
+                                        jobject toInvoke);
 };

 #endif
Index: webclient/src_moz/cocoa/CocoaBrowserControlCanvas.mm
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/src_moz/cocoa/
CocoaBrowserControlCanvas.mm,v
retrieving revision 1.5
diff -u -r1.5 CocoaBrowserControlCanvas.mm
--- webclient/src_moz/cocoa/CocoaBrowserControlCanvas.mm        23 May 2005
01:10:22 -0000  1.5
+++ webclient/src_moz/cocoa/CocoaBrowserControlCanvas.mm        10 Jun 2007
16:11:33 -0000
@@ -31,11 +31,85 @@

 #import <Cocoa/Cocoa.h>

+// #include <MacWindows.h>
+
 #include "CocoaBrowserControlCanvas.h"

+#include "nsIWidget.h"
+#include "nsWidgetSupport.h"
+
 #include "jni_util.h" //for throwing Exceptions to Java
+#include "ns_globals.h"
+
+// #include "nsRect.h"
+
[EMAIL PROTECTED] RunOnAppKitThread : NSObject
+
+-(void)runReturnRunnableOnAppKitThread:(NSMutableArray *) args;
+
+-(void)doRunReturnRunnableOnAppKitThread:(NSMutableArray *) args;
+
+-(void)runRunnableOnAppKitThread:(NSMutableArray *) args;
+
+-(void)doRunRunnableOnAppKitThread:(NSMutableArray *) args;
+
[EMAIL PROTECTED]
+
[EMAIL PROTECTED] RunOnAppKitThread
+
+-(void)runReturnRunnableOnAppKitThread:(NSMutableArray *)args {
+
+    [self performSelectorOnMainThread:
@selector(doRunReturnRunnableOnAppKitThread:)
+         withObject: args
+         waitUntilDone: YES];
+}
+
+-(void)doRunReturnRunnableOnAppKitThread:(NSMutableArray *) args {
+    JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
+    jobject
+       javaThis = (jobject) [[args objectAtIndex:0] pointerValue],
+       toInvoke = (jobject) [[args objectAtIndex:1] pointerValue],
+       result = nsnull;
+    NSValue *nsValue = nsnull;
+    jclass clazz = env->GetObjectClass(javaThis);
+    jmethodID mid = env->GetMethodID(clazz,
"doRunReturnRunnableOnAppKitThread",
+                                     "(Lorg/mozilla/util/
ReturnRunnable;)Ljava/lang/Object;");
+    result = env->CallObjectMethod(javaThis, mid, toInvoke);
+    if (env->ExceptionOccurred()) {
+        ::util_ThrowExceptionToJava(env, "Cannot call back into
Java");
+    }
+    nsValue = [NSValue value:&result withObjCType:@encode(jobject)];
+    [args addObject: nsValue];
+
+    return;
+}

-jint CocoaBrowserControlCanvas::cocoaGetHandleToPeer(JNIEnv *env,
jobject canvas) {
+-(void)runRunnableOnAppKitThread:(NSMutableArray *)args {
+
+    [self performSelectorOnMainThread:
@selector(doRunRunnableOnAppKitThread:)
+         withObject: args
+         waitUntilDone: YES];
+}
+
+-(void)doRunRunnableOnAppKitThread:(NSMutableArray *) args {
+    JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
+    jobject
+        javaThis = (jobject) [[args objectAtIndex:0] pointerValue],
+        toInvoke = (jobject) [[args objectAtIndex:1] pointerValue];
+    jclass clazz = env->GetObjectClass(javaThis);
+    jmethodID mid = env->GetMethodID(clazz,
"doRunRunnableOnAppKitThread",
+                                     "(Ljava/lang/Runnable;)V");
+    env->CallVoidMethod(javaThis, mid, toInvoke);
+    if (env->ExceptionOccurred()) {
+        ::util_ThrowExceptionToJava(env, "Cannot call back into
Java");
+    }
+    return;
+}
+
[EMAIL PROTECTED]
+
+jint CocoaBrowserControlCanvas::cocoaGetHandleToPeer(JNIEnv *env,
jobject canvas)
+{
     JAWT awt;
     JAWT_DrawingSurface* ds = NULL;
     JAWT_DrawingSurfaceInfo* dsi = NULL;
@@ -43,14 +117,17 @@
     jboolean result = JNI_FALSE;
     jint lock = 0;
     NSView *view = NULL;
-    NSWindow *win = NULL;
-    void * windowPtr = NULL;

     // get the AWT
     awt.version = JAWT_VERSION_1_4;

     result = JAWT_GetAWT(env, &awt);

+    if (JNI_FALSE == result) {
+        util_ThrowExceptionToJava(env, "CocoaBrowserControlCanvas:
can't get JAWT");
+    }
+
+
     // Get the drawing surface.  This can be safely cached.
     // Anything below the DS (DSI, contexts, etc)
     // can possibly change/go away and should not be cached.
@@ -78,18 +155,23 @@
         // Get the platform-specific drawing info
         // We will use this to get at Cocoa and CoreGraphics
         // See <JavaVM/jawt_md.h>
+
         dsi_mac = (JAWT_MacOSXDrawingSurfaceInfo*)dsi->platformInfo;
         if (NULL == dsi_mac) {
-            util_ThrowExceptionToJava(env,
"CocoaBrowserControlCanvas: can't get DrawingSurfaceInfo");
+            util_ThrowExceptionToJava(env,
"CocoaBrowserControlCanvas: can't get mac DrawingSurfaceInfo");
         }

         // Get the corresponding peer from the caller canvas
         view = dsi_mac->cocoaViewRef;
-        win = [view window];
-        windowPtr = [win windowRef];
+
         // Free the DrawingSurfaceInfo
         ds->FreeDrawingSurfaceInfo(dsi);
     }
+    else {
+        PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
+               ("CocoaBrowserControlCanvas::cocoaGetHandleToPeer:
can't get drawing surface info"));
+
+    }

     // Unlock the drawing surface
     // You must unlock EACH TIME when done drawing
@@ -98,98 +180,71 @@
     // Free the drawing surface (if not caching it)
     awt.FreeDrawingSurface(ds);

-printf("debug: edburns: CocoaBC: winPtr: %p\n", windowPtr);
-fflush(stdout);
-
-    return (jint) windowPtr;
+    return (jint) view;
 }

-
-void CocoaBrowserControlCanvas::paintMe(JNIEnv *env, jobject canvas,
jobject graphics) {
-
-    JAWT awt;
-    JAWT_DrawingSurface* ds = NULL;
-    JAWT_DrawingSurfaceInfo* dsi = NULL;
-    JAWT_MacOSXDrawingSurfaceInfo* dsi_mac = NULL;
-    jboolean result = JNI_FALSE;
-    jint lock = 0;
-       jclass bcClass;
-       jmethodID mid;
-
-    // get the AWT
-    awt.version = JAWT_VERSION_1_4;
-    result = JAWT_GetAWT(env, &awt);
-    if (env->ExceptionOccurred()) {
-        env->ExceptionDescribe();
-    }
-    assert(result != JNI_FALSE);
-
-    // Get the drawing surface.  This can be safely cached.
-    // Anything below the DS (DSI, contexts, etc)
-    // can possibly change/go away and should not be cached.
-    ds = awt.GetDrawingSurface(env, canvas);
-    if (env->ExceptionOccurred()) {
-        env->ExceptionDescribe();
-    }
-    assert(ds != NULL);
-
-    // Lock the drawing surface
-    // You must lock EACH TIME before drawing
-    lock = ds->Lock(ds);
-    if (env->ExceptionOccurred()) {
-        env->ExceptionDescribe();
-    }
-    assert((lock & JAWT_LOCK_ERROR) == 0);
-
-    // Get the drawing surface info
-    dsi = ds->GetDrawingSurfaceInfo(ds);
-
-    // Check DrawingSurfaceInfo.  This can be NULL on Mac OS X
-    // if the windowing system is not ready
-    if (dsi != NULL) {
-
-        // Get the platform-specific drawing info
-        // We will use this to get at Cocoa and CoreGraphics
-        // See <JavaVM/jawt_md.h>
-        dsi_mac = (JAWT_MacOSXDrawingSurfaceInfo*)dsi->platformInfo;
-        if (env->ExceptionOccurred()) {
-            env->ExceptionDescribe();
-        }
-
-        // Get the corresponding peer from the caller canvas
-        NSView *view = dsi_mac->cocoaViewRef;
-
-        // Get the CoreGraphics context from the parent window.
-        // DO NOT CACHE NSGraphicsContexts -- they may go away.
-        NSWindow *window = [view window];
-        NSGraphicsContext *ctxt = [NSGraphicsContext
graphicsContextWithWindow:window];
-        CGContextRef cg = [ctxt graphicsPort];
-
-        // Match Java's ctm
-        NSRect windowRect = [window frame];
-        CGContextConcatCTM(cg, CGAffineTransformMake(1, 0, 0, -1, dsi-
>bounds.x, windowRect.size.height-dsi->bounds.y));
-
-        // Draw a pattern using CoreGraphics
-        CGContextSetRGBFillColor(cg, 1.0f, 0.0f, 0.0f, 1.0f);
-        CGContextFillRect(cg, CGRectMake(15, 15, dsi-
>bounds.width-30, dsi->bounds.height-30));
-
-        // Free the DrawingSurfaceInfo
-        ds->FreeDrawingSurfaceInfo(dsi);
-        if (env->ExceptionOccurred()){
-            env->ExceptionDescribe();
+jobject
CocoaBrowserControlCanvas::runReturnRunnableOnAppKitThread(JNIEnv
*env, jobject javaThis, jobject toInvoke)
+{
+    PR_ASSERT(javaThis);
+    PR_ASSERT(toInvoke);
+
+    jobject result = 0;
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+    RunOnAppKitThread *appKitThreadRunner = [[RunOnAppKitThread
alloc] init];
+    NSMutableArray *args = [NSMutableArray arrayWithCapacity: 10];
+    NSValue
+       *inArg0 = [NSValue value:&javaThis withObjCType:@encode(jobject)],
+       *inArg1 = [NSValue value:&toInvoke withObjCType:@encode(jobject)],
+       *outArg0;
+    [args addObject: inArg0];
+    [args addObject: inArg1];
+    @try {
+        [appKitThreadRunner runReturnRunnableOnAppKitThread: args];
+        outArg0 = [args objectAtIndex:2];
+        if (outArg0) {
+            result = (jobject) [outArg0 pointerValue];
         }
     }
-
-    // Unlock the drawing surface
-    // You must unlock EACH TIME when done drawing
-    ds->Unlock(ds);
-    if (env->ExceptionOccurred()) {
-        env->ExceptionDescribe();
+    @catch (NSException *e) {
+        NSString *reason = [e reason];
+        const char *cStringReason = [reason cStringUsingEncoding:
+                                     NSUTF8StringEncoding];
+        JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
+        ::util_ThrowExceptionToJava(env, cStringReason);
     }
-
-    // Free the drawing surface (if not caching it)
-    awt.FreeDrawingSurface(ds);
-    if (env->ExceptionOccurred()) {
-        env->ExceptionDescribe();
+
+    [pool release];
+    return result;
+}
+
+void CocoaBrowserControlCanvas::runRunnableOnAppKitThread(JNIEnv
*env, jobject javaThis, jobject toInvoke)
+{
+    PR_ASSERT(javaThis);
+    PR_ASSERT(toInvoke);
+
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+    RunOnAppKitThread *appKitThreadRunner = [[RunOnAppKitThread
alloc] init];
+    NSMutableArray *args = [NSMutableArray arrayWithCapacity: 10];
+    NSValue
+       *inArg0 = [NSValue value:&javaThis withObjCType:@encode(jobject)],
+       *inArg1 = [NSValue value:&toInvoke withObjCType:@encode(jobject)];
+    [args addObject: inArg0];
+    [args addObject: inArg1];
+    @try {
+        [appKitThreadRunner runRunnableOnAppKitThread: args];
+    }
+    @catch (NSException *e) {
+        NSString *reason = [e reason];
+        const char *cStringReason = [reason cStringUsingEncoding:
+                                     NSUTF8StringEncoding];
+        PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
+
("CocoaBrowserControlCanvas::runRunnableOnAppKitThread: Native Cocoa
Exception occurred: %s", cStringReason));
+        JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
+        ::util_ThrowExceptionToJava(env, cStringReason);
     }
+
+    [pool release];
 }
+
Index: webclient/src_moz/cocoa/CocoaBrowserControlCanvasImpl.cpp
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/src_moz/cocoa/
CocoaBrowserControlCanvasImpl.cpp,v
retrieving revision 1.4
diff -u -r1.4 CocoaBrowserControlCanvasImpl.cpp
--- webclient/src_moz/cocoa/CocoaBrowserControlCanvasImpl.cpp   23 May
2005 01:10:22 -0000     1.4
+++ webclient/src_moz/cocoa/CocoaBrowserControlCanvasImpl.cpp   10 Jun
2007 16:11:33 -0000
@@ -44,7 +44,3 @@
     result = CocoaBrowserControlCanvas::cocoaGetHandleToPeer(env,
canvas);
     return result;
 }
-
-JNIEXPORT void JNICALL
Java_org_mozilla_webclient_impl_wrapper_1native_CocoaBrowserControlCanvas_paintMe(JNIEnv
*env, jobject canvas, jobject graphics) {
-    CocoaBrowserControlCanvas::paintMe(env, canvas, graphics);
-}
Index: webclient/test/manual/src/classes/org/mozilla/webclient/test/
TestBrowser.java
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/test/manual/src/classes/org/
mozilla/webclient/test/TestBrowser.java,v
retrieving revision 1.14
diff -u -r1.14 TestBrowser.java
--- webclient/test/manual/src/classes/org/mozilla/webclient/test/
TestBrowser.java        9 Mar 2007 14:17:04 -0000       1.14
+++ webclient/test/manual/src/classes/org/mozilla/webclient/test/
TestBrowser.java        10 Jun 2007 16:11:34 -0000
@@ -371,25 +371,29 @@
                             //System.out.println("Meta ");
                         }

-                        Node domNode = (Node)
-                        wcMouseEvent.getWebclientEvent().getSource();
-                        Element element = (Element) domNode;
-                        String
-                                href = (String)
eventProps.get("href"),
-                                id = element.getAttribute("id"),
-                                name = element.getAttribute("name"),
-                                nodeName = domNode.getNodeName(),
-                                value = domNode.getNodeValue(),
-                                status = "";
-                        if (null != href) {
-                            // PENDING(edburns): take care of
relative URL
-                            status = href;
-                        }
-                        if (null != id || null != name || null !=
nodeName
-                                || null != value) {
-                            status = status + " domNode: " + nodeName
+ " id: " + id
-                                    + " name: " + name + " value: " +
value;
-                            updateStatusInfo(status);
+                        Object source =
wcMouseEvent.getWebclientEvent().getSource();
+
+                        if (source instanceof Node) {
+                            Node domNode = (Node) source;
+
+                            Element element = (Element) domNode;
+                            String
+                                    href = (String)
eventProps.get("href"),
+                                    id = element.getAttribute("id"),
+                                    name =
element.getAttribute("name"),
+                                    nodeName = domNode.getNodeName(),
+                                    value = domNode.getNodeValue(),
+                                    status = "";
+                            if (null != href) {
+                                // PENDING(edburns): take care of
relative URL
+                                status = href;
+                            }
+                            if (null != id || null != name || null !=
nodeName
+                                    || null != value) {
+                                status = status + " domNode: " +
nodeName + " id: " + id
+                                        + " name: " + name + " value:
" + value;
+                                updateStatusInfo(status);
+                            }
                         }
                     }
                 }
@@ -440,7 +444,8 @@
                     // Check if the text value starts with known
protocols.
                     if
(inputValue.toLowerCase().startsWith("http://";)
                             ||
inputValue.toLowerCase().startsWith("ftp://";)
-                            ||
inputValue.toLowerCase().startsWith("gopher://";)) {
+                            ||
inputValue.toLowerCase().startsWith("gopher://";)
+                            ||
inputValue.toLowerCase().startsWith("file://")) {
                         curUrl = new URL(inputValue);
                     } else {
                         if
(inputValue.toLowerCase().startsWith("ftp.")) {

_______________________________________________
dev-embedding mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-embedding

Reply via email to