diff --git a/mozilla/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.cpp b/mozilla/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.cpp index 7ffb2184a0f..23dfba55a93 100644 --- a/mozilla/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.cpp +++ b/mozilla/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.cpp @@ -346,6 +346,14 @@ static void CreateNativeThread(CSecureEnv* secureEnv) NS_IMETHODIMP CSecureEnv::Run() { jboolean isRunning = true; + +#if TARGET_RT_MAC_MACHO + // we need to attach this thread to a Java thread + JavaVM* jvm = mSession->getJavaVM(); + JNIEnv* env; + jvm->AttachCurrentThread((void**)&env, NULL); +#endif + NativeMonitor requestMonitor(mSession, mThreadManager); MRJMonitor replyMonitor(mSession); JavaMessageQueue requests(&requestMonitor), replies(&replyMonitor); @@ -359,9 +367,9 @@ NS_IMETHODIMP CSecureEnv::Run() mNativeQueue = &requests; mJavaQueue = &replies; - // when this thread is running, no other thread can enter the request queue monitor. + // when this thread is running, no other thread can enter the request queue monitor. requests.enter(); - + while (isRunning) { // the protocol for now is dead simple: get a message from the // requests message queue, process it, and then put it back in @@ -382,6 +390,10 @@ NS_IMETHODIMP CSecureEnv::Run() requests.exit(); +#if TARGET_RT_MAC_MACHO + jvm->DetachCurrentThread(); +#endif + return NS_OK; } diff --git a/mozilla/plugin/oji/MRJCarbon/plugin/Source/EmbeddedFramePluginInstance.cpp b/mozilla/plugin/oji/MRJCarbon/plugin/Source/EmbeddedFramePluginInstance.cpp index 3b814f558f3..606e201337f 100644 --- a/mozilla/plugin/oji/MRJCarbon/plugin/Source/EmbeddedFramePluginInstance.cpp +++ b/mozilla/plugin/oji/MRJCarbon/plugin/Source/EmbeddedFramePluginInstance.cpp @@ -50,7 +50,7 @@ EmbeddedFramePluginInstance::EmbeddedFramePluginInstance() : mPeer(NULL), mFrame(NULL) { - NS_INIT_REFCNT(); + NS_INIT_ISUPPORTS(); } EmbeddedFramePluginInstance::~EmbeddedFramePluginInstance() diff --git a/mozilla/plugin/oji/MRJCarbon/plugin/Source/JavaVMFramework.cpp b/mozilla/plugin/oji/MRJCarbon/plugin/Source/JavaVMFramework.cpp index c324737b43c..d7eab2218c0 100644 --- a/mozilla/plugin/oji/MRJCarbon/plugin/Source/JavaVMFramework.cpp +++ b/mozilla/plugin/oji/MRJCarbon/plugin/Source/JavaVMFramework.cpp @@ -116,3 +116,14 @@ JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args) if (_JNI_CreateJavaVM) return _JNI_CreateJavaVM(pvm, penv, args); return -1; } + +extern void * _NSLoadJavaVirtualMachine(const char *jvm_name, const char *jvm_version); + +typedef void* (*_NSLoadJavaVirtualMachine_proc_ptr) (const char *jvm_name, const char *jvm_version); +static _NSLoadJavaVirtualMachine_proc_ptr __NSLoadJavaVirtualMachine = (_NSLoadJavaVirtualMachine_proc_ptr) getJavaVMFunction(CFSTR("_NSLoadJavaVirtualMachine")); + +void * _NSLoadJavaVirtualMachine(const char *jvm_name, const char *jvm_version) +{ + if (__NSLoadJavaVirtualMachine) return __NSLoadJavaVirtualMachine(jvm_name, jvm_version); + return reinterpret_cast(-1); +} diff --git a/mozilla/plugin/oji/MRJCarbon/plugin/Source/LiveConnectNativeMethods.cpp b/mozilla/plugin/oji/MRJCarbon/plugin/Source/LiveConnectNativeMethods.cpp index 3fc967009f8..971d0b6a8e7 100644 --- a/mozilla/plugin/oji/MRJCarbon/plugin/Source/LiveConnectNativeMethods.cpp +++ b/mozilla/plugin/oji/MRJCarbon/plugin/Source/LiveConnectNativeMethods.cpp @@ -107,7 +107,7 @@ nsresult InitLiveConnectSupport(MRJPlugin* jvmPlugin) "eval", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_eval, "toString", "()Ljava/lang/String;", (void*)&Java_netscape_javascript_JSObject_toString, "getWindow", "(Ljava/applet/Applet;)Lnetscape/javascript/JSObject;", (void*)&Java_netscape_javascript_JSObject_getWindow, - "finalize", "()V", (void*)&Java_netscape_javascript_JSObject_finalize, + "finalize", "()V", (void*)&Java_netscape_javascript_JSObject_finalize }; MRJSession* session = jvmPlugin->getSession(); @@ -207,7 +207,7 @@ static jobject GetCurrentThread(JNIEnv* env) MRJSecurityContext::MRJSecurityContext(const char* location) : mLocation(nsnull), mConnection(nsnull) { - NS_INIT_REFCNT(); + NS_INIT_ISUPPORTS(); mLocation = ::strdup(location); if (mLocation) { diff --git a/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJContext.cp b/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJContext.cp index 5fbc71736bc..d87b5cd8d78 100644 --- a/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJContext.cp +++ b/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJContext.cp @@ -36,10 +36,12 @@ #include #include + #include #include #include +#if TARGET_CARBON #include #include #include @@ -66,6 +68,8 @@ private: // cfref(const cfref& other) {} }; +#endif + #include "MRJSession.h" #include "MRJContext.h" #include "MRJPlugin.h" @@ -75,6 +79,10 @@ private: #include "LocalPort.h" #include "StringUtils.h" #include "TimedMessage.h" +#if !TARGET_CARBON +#include "TopLevelFrame.h" +#include "EmbeddedFrame.h" +#endif #include "nsIPluginManager2.h" #include "nsIPluginInstancePeer.h" @@ -1130,12 +1138,15 @@ Boolean MRJContext::loadApplet() status = ::RegisterStatusCallback(env, mAppletFrame, &setStatusCallback, this); status = ::RegisterShowDocumentCallback(env, mAppletFrame, &showDocumentCallback, this); + WindowRef window = ::GetWindowFromPort(mPluginPort); + // wrap applet in a control. Rect bounds = { 0, 0, 100, 100 }; - status = ::CreateJavaControl(env, GetWindowFromPort(mPluginPort), &bounds, mAppletFrame, true, &mAppletControl); + status = ::CreateJavaControl(env, window, &bounds, mAppletFrame, true, &mAppletControl); if (status == noErr) { status = ::SetJavaAppletState(env, mAppletFrame, kAppletStart); } + } } #else @@ -1213,29 +1224,41 @@ jobject MRJContext::getApplet() { #if TARGET_CARBON if (appletLoaded() && mAppletObject == NULL) { - // mAppletFrame implements the interface java.applet.AppletContext, as of Mac OS X 10.1. - // This code simply looks for the getApplet(String) accessor method of whatever class the object happens - // to be. Hopefully Apple will maintain this level of compatibility. + // mAppletFrame is an instance of javap com.apple.mrj.JavaEmbedding.JE_AppletViewer, as of Mac OS X 10.1. + // In Mac OS X 10.1, it implemented the java.applet.AppletContext interface, but this is no longer true + // in Mac OS X 10.2 (Jaguar). However both versions of JE_AppletViewer have a public field panel, which + // is an instance of com.apple.mrj.JavaEmbedding.JE_AppletViewerPanel, which extends sun.applet.AppletPanel, + // which contains the method public java.applet.Applet getApplet(). Apple needs to provide us with an API + // that we can use, but for now this is the best that we can do. JNIEnv* env = mSession->getCurrentEnv(); jclass frameClass = env->GetObjectClass(mAppletFrame); if (frameClass) { - jmethodID getAppletMethod = env->GetMethodID(frameClass, "getApplet", "(Ljava/lang/String;)Ljava/applet/Applet;"); - if (getAppletMethod) { - jstring name = env->NewStringUTF(getAttribute(mPeer, "name")); - if (name) { - jobject applet = env->CallObjectMethod(mAppletFrame, getAppletMethod, name); - env->DeleteLocalRef(name); - if (applet) { - mAppletObject = env->NewGlobalRef(applet); - env->DeleteLocalRef(applet); + jfieldID panelID = env->GetFieldID(frameClass, "panel", "Lcom/apple/mrj/JavaEmbedding/JE_AppletViewerPanel;"); + if (panelID) { + jobject appletPanel = env->GetObjectField(mAppletFrame, panelID); + if (appletPanel) { + jclass panelClass = env->GetObjectClass(appletPanel); + jmethodID getAppletMethod = env->GetMethodID(panelClass, "getApplet", "()Ljava/applet/Applet;"); + if (getAppletMethod) { + jobject applet = env->CallObjectMethod(appletPanel, getAppletMethod); + if (applet) { + mAppletObject = env->NewGlobalRef(applet); + env->DeleteLocalRef(applet); + } + } else { + env->ExceptionClear(); } + env->DeleteLocalRef(panelClass); + env->DeleteLocalRef(appletPanel); } else { - // FIXME: use the getApplets() call when we don't have the name of the apple in question. + env->ExceptionClear(); } } else { env->ExceptionClear(); } env->DeleteLocalRef(frameClass); + } else { + env->ExceptionClear(); } } return mAppletObject; @@ -1420,11 +1443,10 @@ void MRJContext::mouseClick(const EventRecord* event) SInt32 contentOffset = 0; #endif - ::HandleControlClick(mAppletControl, localWhere, event->modifiers, NULL); + ControlPartCode clickedPart = ::HandleControlClick(mAppletControl, localWhere, event->modifiers, NULL); - localWhere = event->where; - // To fix some major browser problems, just handle tracking right here. + // XXX this does not work MouseTrackingResult trackingResult; do { UInt32 modifiers; @@ -1463,7 +1485,7 @@ void MRJContext::mouseClick(const EventRecord* event) } } } while (trackingResult != kMouseTrackingMouseUp); - + // the Java control seems to focus itself automatically when clicked in. mIsFocused = true; @@ -1507,38 +1529,53 @@ void MRJContext::mouseRelease(const EventRecord* event) } } -static OSStatus createRawKeyboardEvent(const EventRecord* event, UInt32 kind, EventRef* outEvent) +static OSStatus CreateRawKeyboardEvent(const EventRecord* event, UInt32 kind, EventRef* outEvent) { OSStatus err = CreateEvent(NULL, kEventClassKeyboard, kind, - event->when, kEventAttributeNone, outEvent); + event->when, kEventAttributeUserEvent, outEvent); if (err == noErr) { char keyChar = (event->message & charCodeMask); - SetEventParameter(*outEvent, kEventParamKeyMacCharCodes, typeChar, - sizeof(keyChar), &keyChar); + err = SetEventParameter(*outEvent, kEventParamKeyMacCharCodes, typeChar, sizeof(keyChar), &keyChar); // --> kEventParamKeyCode typeUInt32 UInt32 keyCode = (event->message & keyCodeMask) >> 8; - SetEventParameter(*outEvent, kEventParamKeyCode, typeUInt32, - sizeof(keyCode), &keyCode); + err = SetEventParameter(*outEvent, kEventParamKeyCode, typeUInt32, sizeof(keyCode), &keyCode); // --> kEventParamKeyModifiers typeUInt32 UInt32 modifiers = event->modifiers; - SetEventParameter(*outEvent, kEventParamKeyModifiers, typeUInt32, - sizeof(modifiers), &modifiers); + err = SetEventParameter(*outEvent, kEventParamKeyModifiers, typeUInt32, sizeof(modifiers), &modifiers); // --> kEventParamKeyboardType typeUInt32 - UInt32 keyboardType = KBGetLayoutType(LMGetKbdType()); // XXX is this correct? - SetEventParameter(*outEvent, kEventParamKeyboardType, typeUInt32, - sizeof(keyboardType), &keyboardType); + UInt32 keyboardType = 0; // KBGetLayoutType(LMGetKbdType()); // XXX is this correct? + err = SetEventParameter(*outEvent, kEventParamKeyboardType, typeUInt32, sizeof(keyboardType), &keyboardType); } + return err; } +/* + The Java control current reports that it supports these features: + + kControlSupportsEmbedding + kControlWantsIdle + kControlHandlesTracking + kControlSupportsDataAccess + kControlGetsFocusOnClick + kControlSupportsCalcBestRect + kControlSupportsDragAndDrop + kControlAutoToggles + 16 ?? + kControlSupportsGetRegion + +*/ + + Boolean MRJContext::keyPress(const EventRecord* event) { // won't Carbon events just take care of everything? // Evidently not. If we are inside a Cocoa application, we have // to generate all of the Carbon events ourselves. EventRef carbonEvent; - OSStatus err = createRawKeyboardEvent(event, kEventRawKeyDown, &carbonEvent); - if (err == noErr) { + OSStatus err = CreateRawKeyboardEvent(event, kEventRawKeyDown, &carbonEvent); + if (err == noErr) + { err = SendEventToControl(carbonEvent, mAppletControl); ReleaseEvent(carbonEvent); return (err == noErr); @@ -1550,7 +1587,7 @@ Boolean MRJContext::keyRelease(const EventRecord* event) { // won't Carbon events just take care of everything? EventRef carbonEvent; - OSStatus err = createRawKeyboardEvent(event, kEventRawKeyUp, &carbonEvent); + OSStatus err = CreateRawKeyboardEvent(event, kEventRawKeyUp, &carbonEvent); if (err == noErr) { err = SendEventToControl(carbonEvent, mAppletControl); ReleaseEvent(carbonEvent); @@ -1585,7 +1622,12 @@ Boolean MRJContext::handleEvent(EventRecord* event) Boolean eventHandled = false; if (mAppletControl) { eventHandled = true; - switch (event->what) { + + switch (event->what) + { + case activateEvt: + break; + case updateEvt: drawApplet(); break; @@ -1595,7 +1637,7 @@ Boolean MRJContext::handleEvent(EventRecord* event) #if TARGET_RT_MAC_MACHO eventHandled = keyPress(event); #else - ::HandleControlKey(mAppletControl, + ControlPartCode partCode = ::HandleControlKey(mAppletControl, (event->message & keyCodeMask) >> 8, (event->message & charCodeMask), event->modifiers); @@ -1609,6 +1651,10 @@ Boolean MRJContext::handleEvent(EventRecord* event) eventHandled = keyRelease(event); break; + case autoKey: + // XXX write me + break; + case mouseDown: mouseClick(event); eventHandled = mIsFocused; @@ -1618,9 +1664,19 @@ Boolean MRJContext::handleEvent(EventRecord* event) mouseRelease(event); break; + case nullEvent: + // handle mouse motion + + + break; + case nsPluginEventType_GetFocusEvent: - if (!mIsFocused) { - ::SetKeyboardFocus(::GetWindowFromPort(mPluginPort), mAppletControl, kControlFocusNextPart); + if (!mIsFocused) + { + WindowRef nativeWindow = ::GetWindowFromPort(mPluginPort); + // this doesn't seem to work with the Java control, probably because + // it doesn't report kControlSupportsFocus in its control features. + ::SetKeyboardFocus(nativeWindow, mAppletControl, kControlFocusNextPart); mIsFocused = true; } break; @@ -1681,6 +1737,7 @@ OSStatus MRJContext::installEventHandlers(WindowRef window) { // install mouseDown/mouseUp handlers for this window, so we can disable // async updates during mouse tracking. + // also install window resize handlers, to turn off drawing during resize return noErr; } diff --git a/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJMonitor.h b/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJMonitor.h index 90fea27904c..de89f32ff78 100644 --- a/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJMonitor.h +++ b/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJMonitor.h @@ -53,7 +53,7 @@ class MRJSession; class MRJMonitor : public Monitor { public: MRJMonitor(MRJSession* session, jobject monitor = NULL); - ~MRJMonitor(); + virtual ~MRJMonitor(); virtual void enter(); virtual void exit(); diff --git a/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJSecurityContext.h b/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJSecurityContext.h index 34a993e0a70..ac91b59b3dd 100644 --- a/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJSecurityContext.h +++ b/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJSecurityContext.h @@ -43,7 +43,7 @@ class nsILiveconnect; class MRJSecurityContext : public nsISecurityContext { public: MRJSecurityContext(const char* location); - ~MRJSecurityContext(); + virtual ~MRJSecurityContext(); NS_DECL_ISUPPORTS diff --git a/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJSession.cpp b/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJSession.cpp index d18c09fc05b..fe1f1f8a35e 100644 --- a/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJSession.cpp +++ b/mozilla/plugin/oji/MRJCarbon/plugin/Source/MRJSession.cpp @@ -218,6 +218,9 @@ MRJSession::~MRJSession() close(); } +// see http://bugzilla.mozilla.org/show_bug.cgi?id=178329 for more info. +extern "C" void * _NSLoadJavaVirtualMachine(const char *jvm_name, const char *jvm_version); + OSStatus MRJSession::open(const char* consolePath) { // Use vanilla JNI invocation API to fire up a fresh JVM. @@ -238,11 +241,14 @@ OSStatus MRJSession::open(const char* consolePath) JNI_TRUE }; - mStatus = ::JNI_CreateJavaVM(&mJavaVM, (void**) &mMainEnv, &theInitArgs); - + if (::_NSLoadJavaVirtualMachine("hotspot", "1.3.1")) + mStatus = ::JNI_CreateJavaVM(&mJavaVM, (void**) &mMainEnv, &theInitArgs); + else + mStatus = unimpErr; + if (mStatus == noErr) { // create a monitor for the message queue to unblock Java threads. - mMessageMonitor = new MRJMonitor(this); + mMessageMonitor = new MRJMonitor(this); } JNIEnv* env = mMainEnv; @@ -317,7 +323,7 @@ JNIEnv* MRJSession::getCurrentEnv() JNIEnv* env; if (mJavaVM->GetEnv((void**)&env, JNI_VERSION_1_2) == JNI_OK) return env; - return NULL; + return NULL; } JNIEnv* MRJSession::getMainEnv() diff --git a/mozilla/plugin/oji/MRJCarbon/plugin/Source/SupportsMixin.cpp b/mozilla/plugin/oji/MRJCarbon/plugin/Source/SupportsMixin.cpp index 4f0e8f9cec4..cf6c8298c7b 100644 --- a/mozilla/plugin/oji/MRJCarbon/plugin/Source/SupportsMixin.cpp +++ b/mozilla/plugin/oji/MRJCarbon/plugin/Source/SupportsMixin.cpp @@ -60,7 +60,7 @@ SupportsMixin::SupportsMixin(void* instance, const InterfaceInfo interfaces[], U SupportsMixin::~SupportsMixin() { if (mRefCount > 0) { - ::DebugStr("\pmRefCount > 0!"); + // ::DebugStr("\pmRefCount > 0!"); } if (mInner != NULL) delete mInner; @@ -116,7 +116,7 @@ SupportsMixin::SupportsMixin(void* instance, const InterfaceInfo interfaces[], U SupportsMixin::~SupportsMixin() { if (mRefCount > 0) { - ::DebugStr("\pmRefCount > 0!"); + //::DebugStr("\pmRefCount > 0!"); } }