зеркало из https://github.com/mozilla/pjs.git
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
This commit is contained in:
Родитель
9274778899
Коммит
ec2c4cca97
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 @@ ${myenv.MOZ_JDKHOME}/bin/java ${debug.options} org.mozilla.webclient.test.Embedd
|
|||
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"/>
|
||||
|
|
|
@ -53,7 +53,7 @@ import java.awt.event.*;
|
|||
|
||||
* See concrete subclasses for scope info.
|
||||
|
||||
* @version $Id: BrowserControlCanvas.java,v 1.9 2004-12-01 03:21:22 edburns%acm.org Exp $
|
||||
* @version $Id: BrowserControlCanvas.java,v 1.10 2007-06-10 16:24:11 edburns%acm.org Exp $
|
||||
|
||||
* @see org.mozilla.webclient.win32.Win32BrowserControlCanvas
|
||||
|
||||
|
@ -141,25 +141,30 @@ public void addNotify ()
|
|||
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();
|
||||
|
||||
//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);
|
||||
|
||||
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++;
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is RaptorCanvas.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Kirk Baker and
|
||||
* Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are
|
||||
* Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Ed Burns <edburns@acm.org>
|
||||
* Ashutosh Kulkarni <ashuk@eng.sun.com>
|
||||
* Jason Mawdsley <jason@macadamian.com>
|
||||
* Louis-Philippe Gagnon <louisphilippe@macadamian.com>
|
||||
*/
|
||||
|
||||
package org.mozilla.webclient.impl.wrapper_native;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.mozilla.util.Log;
|
||||
import org.mozilla.util.ReturnRunnable;
|
||||
import org.mozilla.webclient.impl.WrapperFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author edburns
|
||||
*/
|
||||
public class CocoaAppKitThreadDelegatingNativeEventThread extends NativeEventThread {
|
||||
public static final String LOG = "org.mozilla.webclient.impl.wrapper_native.CocoaAppKitThreadDelegatingNativeEventThread";
|
||||
|
||||
public static final Logger LOGGER = Log.getLogger(LOG);
|
||||
|
||||
Thread appKitThread = null;
|
||||
|
||||
/** Creates a new instance of CocoaAppKitThreadDelegatingNativeEventThread */
|
||||
public CocoaAppKitThreadDelegatingNativeEventThread(String threadName,
|
||||
WrapperFactory yourFactory) {
|
||||
super(threadName, yourFactory);
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public boolean isNativeEventThread() {
|
||||
return (Thread.currentThread() == appKitThread);
|
||||
}
|
||||
|
||||
|
||||
public Object pushBlockingReturnRunnable(ReturnRunnable toInvoke) throws RuntimeException {
|
||||
Object result = null;
|
||||
|
||||
if (isNativeEventThread()){
|
||||
toInvoke.setResult(toInvoke.run());
|
||||
result = toInvoke.getResult();
|
||||
if (result instanceof RuntimeException) {
|
||||
throw ((RuntimeException) result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
final ReturnRunnable finalToInvoke = toInvoke;
|
||||
ReturnRunnable appKitToInvoke = new ReturnRunnable() {
|
||||
public Object run() {
|
||||
if (LOGGER.isLoggable(Level.FINEST)) {
|
||||
LOGGER.finest("On NativeEventThread, blocking, about to call " +
|
||||
finalToInvoke.toString() + " on AppKit Thread.");
|
||||
}
|
||||
|
||||
Object result = CocoaAppKitThreadDelegatingNativeEventThread.this.
|
||||
runReturnRunnableOnAppKitThread(finalToInvoke);
|
||||
|
||||
if (LOGGER.isLoggable(Level.FINEST)) {
|
||||
LOGGER.finest("On NativeEventThread, blocking, returned from calling " +
|
||||
finalToInvoke.toString() + " on AppKit Thread.");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public String toString() {
|
||||
return finalToInvoke.toString();
|
||||
}
|
||||
};
|
||||
result = super.pushBlockingReturnRunnable(appKitToInvoke);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void pushRunnable(Runnable toInvoke) {
|
||||
final Runnable finalToInvoke = toInvoke;
|
||||
Runnable appKitToInvoke = new Runnable() {
|
||||
public void run() {
|
||||
if (LOGGER.isLoggable(Level.FINEST)) {
|
||||
LOGGER.finest("On NativeEventThread, non-blocking, about to call " +
|
||||
finalToInvoke.toString() + " on AppKit Thread.");
|
||||
}
|
||||
CocoaAppKitThreadDelegatingNativeEventThread.this.
|
||||
runRunnableOnAppKitThread(finalToInvoke);
|
||||
if (LOGGER.isLoggable(Level.FINEST)) {
|
||||
LOGGER.finest("On NativeEventThread, non-blocking, returned from calling " +
|
||||
finalToInvoke.toString() + " on AppKit Thread.");
|
||||
}
|
||||
}
|
||||
public String toString() {
|
||||
return finalToInvoke.toString();
|
||||
}
|
||||
};
|
||||
super.pushRunnable(appKitToInvoke);
|
||||
}
|
||||
|
||||
private Object doRunReturnRunnableOnAppKitThread(ReturnRunnable toInvoke) {
|
||||
assert(-1 != Thread.currentThread().getName().indexOf("AppKit"));
|
||||
if (null == appKitThread) {
|
||||
appKitThread = Thread.currentThread();
|
||||
}
|
||||
if (LOGGER.isLoggable(Level.FINEST)) {
|
||||
LOGGER.finest("On AppKitThread, blocking, about to call " +
|
||||
toInvoke.toString() + ".");
|
||||
}
|
||||
|
||||
Object result = toInvoke.run();
|
||||
|
||||
if (LOGGER.isLoggable(Level.FINEST)) {
|
||||
LOGGER.finest("On AppKitThread, returned from calling " +
|
||||
toInvoke.toString() + ".");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void doRunRunnableOnAppKitThread(Runnable toInvoke) {
|
||||
assert(-1 != Thread.currentThread().getName().indexOf("AppKit"));
|
||||
if (null == appKitThread) {
|
||||
appKitThread = Thread.currentThread();
|
||||
}
|
||||
if (LOGGER.isLoggable(Level.FINEST)) {
|
||||
LOGGER.finest("On AppKitThread, non-blocking, about to call " +
|
||||
toInvoke.toString() + ".");
|
||||
}
|
||||
|
||||
toInvoke.run();
|
||||
|
||||
if (LOGGER.isLoggable(Level.FINEST)) {
|
||||
LOGGER.finest("On AppKitThread, non-blocking, returned from calling " +
|
||||
toInvoke.toString() + ".");
|
||||
}
|
||||
}
|
||||
|
||||
private native Object runReturnRunnableOnAppKitThread(ReturnRunnable toInvoke);
|
||||
private native void runRunnableOnAppKitThread(Runnable toInvoke);
|
||||
|
||||
}
|
|
@ -28,10 +28,11 @@ package org.mozilla.webclient.impl.wrapper_native;
|
|||
|
||||
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 @@ import java.awt.*;
|
|||
*/
|
||||
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 @@ public class CocoaBrowserControlCanvas extends BrowserControlCanvas {
|
|||
* @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();
|
||||
});
|
||||
nativeView = result.intValue();
|
||||
}
|
||||
return nativeView;
|
||||
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
g.setColor(Color.green);
|
||||
g.fillRect(0, 0, 100, 100);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ protected int getNativeBrowserControl() {
|
|||
}
|
||||
|
||||
protected boolean isNativeEventThread() {
|
||||
return (Thread.currentThread() == NativeEventThread.instance);
|
||||
return (NativeEventThread.instance.isNativeEventThread());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -93,6 +93,10 @@ public class NativeEventThread extends Thread implements RunnableRunner {
|
|||
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 class NativeEventThread extends Thread implements RunnableRunner {
|
|||
|
||||
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
|
||||
|
|
|
@ -142,9 +142,9 @@ else
|
|||
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 @@ INCLUDES := -I$(MOZ_JDKHOME)/include -I$(MOZ_JDKHOME)/include/win32 $(INCLUDES)
|
|||
-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
|
||||
|
|
|
@ -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 @@ NativeBrowserControl::Realize(jobject javaBrowserControl,
|
|||
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 @@ NativeBrowserControl::Realize(jobject javaBrowserControl,
|
|||
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
|
||||
|
|
|
@ -108,9 +108,9 @@ public:
|
|||
|
||||
#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
|
||||
|
||||
|
|
|
@ -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 @@ nsresult InitMozillaStuff (NativeBrowserControl * nativeBrowserControl)
|
|||
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
|
||||
|
|
|
@ -31,8 +31,11 @@ class CocoaBrowserControlCanvas {
|
|||
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
|
||||
|
|
|
@ -31,11 +31,85 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
// #include <MacWindows.h>
|
||||
|
||||
#include "CocoaBrowserControlCanvas.h"
|
||||
|
||||
#include "jni_util.h" //for throwing Exceptions to Java
|
||||
#include "nsIWidget.h"
|
||||
#include "nsWidgetSupport.h"
|
||||
|
||||
jint CocoaBrowserControlCanvas::cocoaGetHandleToPeer(JNIEnv *env, jobject canvas) {
|
||||
#include "jni_util.h" //for throwing Exceptions to Java
|
||||
#include "ns_globals.h"
|
||||
|
||||
// #include "nsRect.h"
|
||||
|
||||
@interface RunOnAppKitThread : NSObject
|
||||
|
||||
-(void)runReturnRunnableOnAppKitThread:(NSMutableArray *) args;
|
||||
|
||||
-(void)doRunReturnRunnableOnAppKitThread:(NSMutableArray *) args;
|
||||
|
||||
-(void)runRunnableOnAppKitThread:(NSMutableArray *) args;
|
||||
|
||||
-(void)doRunRunnableOnAppKitThread:(NSMutableArray *) args;
|
||||
|
||||
@end
|
||||
|
||||
@implementation 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;
|
||||
}
|
||||
|
||||
-(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;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
jint CocoaBrowserControlCanvas::cocoaGetHandleToPeer(JNIEnv *env, jobject canvas)
|
||||
{
|
||||
JAWT awt;
|
||||
JAWT_DrawingSurface* ds = NULL;
|
||||
JAWT_DrawingSurfaceInfo* dsi = NULL;
|
||||
|
@ -43,14 +117,17 @@ jint CocoaBrowserControlCanvas::cocoaGetHandleToPeer(JNIEnv *env, jobject canvas
|
|||
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 @@ jint CocoaBrowserControlCanvas::cocoaGetHandleToPeer(JNIEnv *env, jobject canvas
|
|||
// 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 @@ jint CocoaBrowserControlCanvas::cocoaGetHandleToPeer(JNIEnv *env, jobject canvas
|
|||
// 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;
|
||||
}
|
||||
|
||||
jobject CocoaBrowserControlCanvas::runReturnRunnableOnAppKitThread(JNIEnv *env, jobject javaThis, jobject toInvoke)
|
||||
{
|
||||
PR_ASSERT(javaThis);
|
||||
PR_ASSERT(toInvoke);
|
||||
|
||||
void CocoaBrowserControlCanvas::paintMe(JNIEnv *env, jobject canvas, jobject graphics) {
|
||||
jobject result = 0;
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
// Free the drawing surface (if not caching it)
|
||||
awt.FreeDrawingSurface(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);
|
||||
}
|
||||
|
||||
[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];
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,3 @@ JNIEXPORT jint JNICALL Java_org_mozilla_webclient_impl_wrapper_1native_CocoaBrow
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -371,25 +371,29 @@ public class TestBrowser extends JPanel {
|
|||
//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 @@ public class TestBrowser extends JPanel {
|
|||
// 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.")) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче