From 44e6bf391768c9b52e11caaed1d5b823dfeac8b8 Mon Sep 17 00:00:00 2001 From: "sfraser%netscape.com" Date: Thu, 5 Dec 2002 09:08:50 +0000 Subject: [PATCH] Moving patches from bug 164712 (LiveConnect on 10.2) onto the Chimera branch. Checking in the patch in bug 178329 onto the Chimera branch (make sure we load the correct JavaVM). Sundry other warning fixes and code cleanup. git-svn-id: svn://10.0.0.236/branches/CHIMERA_M1_0_1_BRANCH@134840 18797224-902f-48f8-a5cc-f745e15eee43 --- .../MRJCarbon/plugin/Source/CSecureEnv.cpp | 16 ++- .../Source/EmbeddedFramePluginInstance.cpp | 2 +- .../plugin/Source/JavaVMFramework.cpp | 11 ++ .../Source/LiveConnectNativeMethods.cpp | 4 +- .../oji/MRJCarbon/plugin/Source/MRJContext.cp | 129 +++++++++++++----- .../oji/MRJCarbon/plugin/Source/MRJMonitor.h | 2 +- .../plugin/Source/MRJSecurityContext.h | 2 +- .../MRJCarbon/plugin/Source/MRJSession.cpp | 14 +- .../MRJCarbon/plugin/Source/SupportsMixin.cpp | 4 +- 9 files changed, 135 insertions(+), 49 deletions(-) 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!"); } }