зеркало из https://github.com/mozilla/pjs.git
First Checked In.
This commit is contained in:
Родитель
5819efc4cc
Коммит
a697e8380d
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
AsyncMessage.h
|
||||
|
||||
Base class for messages that are executed asynchronously, during MRJSession idle time.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MRJSession.h"
|
||||
|
||||
class AsyncMessage : public NativeMessage {
|
||||
public:
|
||||
AsyncMessage(MRJSession* session) : mSession(session) {}
|
||||
virtual ~AsyncMessage() {}
|
||||
|
||||
void send();
|
||||
|
||||
protected:
|
||||
MRJSession* mSession;
|
||||
};
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
JNIThread.java
|
||||
|
||||
Provides a communication channel between native threads and Java threads.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
package netscape.oji;
|
||||
|
||||
public class JNIThread extends Thread {
|
||||
private int fSecureEnv;
|
||||
|
||||
public JNIThread(int secureEnv) {
|
||||
super("JNIThread->0x" + Integer.toHexString(secureEnv));
|
||||
fSecureEnv = secureEnv;
|
||||
setPriority(NORM_PRIORITY);
|
||||
// setPriority(MAX_PRIORITY);
|
||||
start();
|
||||
}
|
||||
|
||||
public native void run();
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
JNIUtils.java
|
||||
*/
|
||||
|
||||
package netscape.oji;
|
||||
|
||||
public class JNIUtils {
|
||||
/**
|
||||
* Returns a local reference for a passed-in global reference.
|
||||
*/
|
||||
public static Object NewLocalRef(Object object) {
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently running thread.
|
||||
*/
|
||||
public static Object GetCurrentThread() {
|
||||
return Thread.currentThread();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
JavaMessageQueue.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef JNI_H
|
||||
#include "jni.h"
|
||||
#endif
|
||||
|
||||
class Monitor;
|
||||
|
||||
class JavaMessage {
|
||||
public:
|
||||
JavaMessage() : mNext(NULL) {}
|
||||
virtual ~JavaMessage() {}
|
||||
|
||||
void setNext(JavaMessage* next) { mNext = next; }
|
||||
JavaMessage* getNext() { return mNext; }
|
||||
|
||||
virtual void execute(JNIEnv* env) = 0;
|
||||
|
||||
private:
|
||||
JavaMessage* mNext;
|
||||
};
|
||||
|
||||
class JavaMessageQueue {
|
||||
public:
|
||||
JavaMessageQueue(Monitor* monitor);
|
||||
|
||||
void putMessage(JavaMessage* msg);
|
||||
JavaMessage* getMessage();
|
||||
|
||||
void enter();
|
||||
void exit();
|
||||
|
||||
void wait();
|
||||
void wait(long long millis);
|
||||
void notify();
|
||||
|
||||
private:
|
||||
// Message queue.
|
||||
JavaMessage* mFirst;
|
||||
JavaMessage* mLast;
|
||||
Monitor* mMonitor;
|
||||
};
|
|
@ -0,0 +1,541 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
LiveConnectNativeMethods.cpp
|
||||
*/
|
||||
|
||||
#include "LiveConnectNativeMethods.h"
|
||||
|
||||
#include "nsIPluginManager.h"
|
||||
#include "nsIJVMManager.h"
|
||||
#include "nsILiveconnect.h"
|
||||
|
||||
#include "MRJPlugin.h"
|
||||
#include "MRJContext.h"
|
||||
#include "MRJSession.h"
|
||||
#include "CSecureJNI2.h"
|
||||
#include "JavaMessageQueue.h"
|
||||
#include "MRJMonitor.h"
|
||||
#include "NativeMonitor.h"
|
||||
|
||||
#include "netscape_javascript_JSObject.h" /* javah-generated headers */
|
||||
|
||||
extern nsIPluginManager* thePluginManager;
|
||||
|
||||
static MRJPlugin* theJVMPlugin = NULL;
|
||||
static nsILiveconnect* theLiveConnectManager = NULL;
|
||||
|
||||
static jclass netscape_javascript_JSObject = NULL;
|
||||
static jmethodID netscape_javascript_JSObject_JSObject;
|
||||
static jfieldID netscape_javascript_JSObject_internal;
|
||||
|
||||
static jclass netscape_oji_JNIUtils = NULL;
|
||||
static jmethodID netscape_oji_JNIUtils_NewLocalRef = NULL;
|
||||
static jmethodID netscape_oji_JNIUtils_GetCurrentThread = NULL;
|
||||
|
||||
nsresult InitLiveConnectSupport(MRJPlugin* jvmPlugin)
|
||||
{
|
||||
theJVMPlugin = jvmPlugin;
|
||||
|
||||
NS_DEFINE_IID(kILiveconnectIID, NS_ILIVECONNECT_IID);
|
||||
// QI the LiveConnect interface.
|
||||
nsresult result = thePluginManager->QueryInterface(kILiveconnectIID, &theLiveConnectManager);
|
||||
if (result != NS_OK)
|
||||
return result;
|
||||
|
||||
// Manually load the required native methods.
|
||||
static JNINativeMethod nativeMethods[] = {
|
||||
"getMember", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getMember,
|
||||
"getSlot", "(I)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getSlot,
|
||||
"setMember", "(Ljava/lang/String;Ljava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setMember,
|
||||
"setSlot", "(ILjava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setSlot,
|
||||
"removeMember", "(Ljava/lang/String;)V", (void*)&Java_netscape_javascript_JSObject_removeMember,
|
||||
"call", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_call,
|
||||
"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,
|
||||
};
|
||||
|
||||
JNIEnv* env = NULL;
|
||||
nsrefcnt count = jvmPlugin->GetJNIEnv(&env);
|
||||
if (count > 0 && env != NULL) {
|
||||
jclass classJSObject = env->FindClass("netscape/javascript/JSObject");
|
||||
if (classJSObject != NULL) {
|
||||
// register LiveConnect native methods.
|
||||
netscape_javascript_JSObject = (jclass) env->NewGlobalRef(classJSObject);
|
||||
env->DeleteLocalRef(classJSObject);
|
||||
|
||||
netscape_javascript_JSObject_JSObject = env->GetMethodID(netscape_javascript_JSObject, "<init>", "(I)V");
|
||||
netscape_javascript_JSObject_internal = env->GetFieldID(netscape_javascript_JSObject, "internal", "I");
|
||||
|
||||
env->RegisterNatives(netscape_javascript_JSObject, nativeMethods, sizeof(nativeMethods) / sizeof(JNINativeMethod));
|
||||
if (env->ExceptionOccurred()) {
|
||||
env->ExceptionClear();
|
||||
result = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// load netscape.oji.JNIUtils class.
|
||||
jclass classJNIUtils = env->FindClass("netscape/oji/JNIUtils");
|
||||
if (classJNIUtils != NULL) {
|
||||
netscape_oji_JNIUtils = (jclass) env->NewGlobalRef(classJNIUtils);
|
||||
env->DeleteLocalRef(classJNIUtils);
|
||||
netscape_oji_JNIUtils_NewLocalRef = env->GetStaticMethodID(netscape_oji_JNIUtils, "NewLocalRef", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
netscape_oji_JNIUtils_GetCurrentThread = env->GetStaticMethodID(netscape_oji_JNIUtils, "GetCurrentThread", "()Ljava/lang/Object;");
|
||||
}
|
||||
|
||||
jvmPlugin->ReleaseJNIEnv(env);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult ShutdownLiveConnectSupport()
|
||||
{
|
||||
|
||||
if (theLiveConnectManager != NULL) {
|
||||
theLiveConnectManager->Release();
|
||||
theLiveConnectManager = NULL;
|
||||
}
|
||||
|
||||
if (theJVMPlugin != NULL) {
|
||||
theJVMPlugin = NULL;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
jobject Wrap_JSObject(JNIEnv* env, jsobject js_obj)
|
||||
{
|
||||
jmethodID constructorID = env->GetMethodID(netscape_javascript_JSObject, "<init>", "(I)V");
|
||||
return env->NewObject(netscape_javascript_JSObject, constructorID, js_obj);
|
||||
}
|
||||
|
||||
jsobject Unwrap_JSObject(JNIEnv* env, jobject java_wrapper_obj)
|
||||
{
|
||||
return env->GetIntField(java_wrapper_obj, netscape_javascript_JSObject_internal);
|
||||
}
|
||||
|
||||
static jobject NewLocalRef(JNIEnv* env, jobject global_ref)
|
||||
{
|
||||
return env->CallStaticObjectMethod(netscape_oji_JNIUtils, netscape_oji_JNIUtils_NewLocalRef, global_ref);
|
||||
}
|
||||
|
||||
static jobject GetCurrentThread(JNIEnv* env)
|
||||
{
|
||||
return env->CallStaticObjectMethod(netscape_oji_JNIUtils, netscape_oji_JNIUtils_GetCurrentThread);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message by rendezvousing with an existing JavaScript thread, or creates a new one
|
||||
* if none exists for this thread already.
|
||||
*/
|
||||
static void sendMessage(JNIEnv* env, JavaMessage* msg)
|
||||
{
|
||||
// the main thread gets its own secure env, so it won't contend with other threads. this
|
||||
// is needed to handle finalization, which seems to get called from the main thread sometimes.
|
||||
if (env == theJVMPlugin->getSession()->getMainEnv()) {
|
||||
static CSecureJNI2* mainEnv = NULL;
|
||||
if (mainEnv == NULL) {
|
||||
mainEnv = new CSecureJNI2(NULL, theJVMPlugin, NULL, env);
|
||||
mainEnv->AddRef();
|
||||
}
|
||||
mainEnv->setJavaEnv(env);
|
||||
mainEnv->sendMessageFromJava(env, msg, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is a call back into JavaScript from Java, there will be a secureEnv associated with this thread.
|
||||
jobject thread = GetCurrentThread(env);
|
||||
CSecureJNI2* secureEnv = GetSecureJNI(env, thread);
|
||||
env->DeleteLocalRef(thread);
|
||||
if (secureEnv != NULL) {
|
||||
secureEnv->sendMessageFromJava(env, msg);
|
||||
} else {
|
||||
// spontaneous call in from Java. this communicates with a shared server thread. this is *VERY* slow right now.
|
||||
static MRJMonitor sharedMonitor(theJVMPlugin->getSession());
|
||||
// only 1 Java thread can use this at a time.
|
||||
sharedMonitor.enter();
|
||||
{
|
||||
static CSecureJNI2* sharedEnv = NULL;
|
||||
if (sharedEnv == NULL) {
|
||||
sharedEnv = new CSecureJNI2(NULL, theJVMPlugin, NULL, env);
|
||||
sharedEnv->AddRef();
|
||||
}
|
||||
sharedEnv->setJavaEnv(env);
|
||||
sharedEnv->sendMessageFromJava(env, msg);
|
||||
}
|
||||
sharedMonitor.exit();
|
||||
}
|
||||
}
|
||||
|
||||
/****************** Implementation of methods of JSObject *******************/
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: getMember
|
||||
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_netscape_javascript_JSObject_getMember(JNIEnv* env,
|
||||
jobject java_wrapper_obj,
|
||||
jstring property_name_jstr)
|
||||
{
|
||||
if (property_name_jstr == NULL) {
|
||||
env->ThrowNew(env->FindClass("java/lang/NullPointerException"), "illegal null member name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the Unicode string for the JS property name */
|
||||
jboolean is_copy;
|
||||
const jchar* property_name_ucs2 = env->GetStringChars(property_name_jstr, &is_copy);
|
||||
jsize property_name_len = env->GetStringLength(property_name_jstr);
|
||||
|
||||
jobject member = NULL;
|
||||
nsresult result = theLiveConnectManager->GetMember(env, Unwrap_JSObject(env, java_wrapper_obj), property_name_ucs2, property_name_len,
|
||||
NULL, 0, NULL, &member);
|
||||
if (result != NS_OK) member = NULL;
|
||||
|
||||
env->ReleaseStringChars(property_name_jstr, property_name_ucs2);
|
||||
|
||||
return member;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: getSlot
|
||||
* Signature: (I)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_netscape_javascript_JSObject_getSlot(JNIEnv* env,
|
||||
jobject java_wrapper_obj,
|
||||
jint slot)
|
||||
{
|
||||
jobject member = NULL;
|
||||
nsresult result = theLiveConnectManager->GetSlot(env, Unwrap_JSObject(env, java_wrapper_obj), slot, NULL, 0, NULL, &member);
|
||||
return member;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: setMember
|
||||
* Signature: (Ljava/lang/String;Ljava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_netscape_javascript_JSObject_setMember(JNIEnv* env,
|
||||
jobject java_wrapper_obj,
|
||||
jstring property_name_jstr,
|
||||
jobject java_obj)
|
||||
{
|
||||
if (property_name_jstr == NULL) {
|
||||
env->ThrowNew(env->FindClass("java/lang/NullPointerException"), "illegal null member name");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the Unicode string for the JS property name */
|
||||
jboolean is_copy;
|
||||
const jchar* property_name_ucs2 = env->GetStringChars(property_name_jstr, &is_copy);
|
||||
jsize property_name_len = env->GetStringLength(property_name_jstr);
|
||||
|
||||
jobject member = NULL;
|
||||
nsresult result = theLiveConnectManager->SetMember(env, Unwrap_JSObject(env, java_wrapper_obj), property_name_ucs2, property_name_len, NULL, 0, NULL, java_obj);
|
||||
if (result != NS_OK) member = NULL;
|
||||
|
||||
env->ReleaseStringChars(property_name_jstr, property_name_ucs2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: setSlot
|
||||
* Signature: (ILjava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_netscape_javascript_JSObject_setSlot(JNIEnv* env,
|
||||
jobject java_wrapper_obj,
|
||||
jint slot,
|
||||
jobject java_obj)
|
||||
{
|
||||
nsresult result = theLiveConnectManager->SetSlot(env, Unwrap_JSObject(env, java_wrapper_obj), slot, NULL, 0, NULL, java_obj);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: removeMember
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
|
||||
class RemoveMemberMessage : public JavaMessage {
|
||||
jsobject mObject;
|
||||
const jchar* mPropertyName;
|
||||
jsize mLength;
|
||||
public:
|
||||
RemoveMemberMessage(jsobject obj, const jchar* propertyName, jsize length);
|
||||
|
||||
virtual void execute(JNIEnv* env);
|
||||
};
|
||||
|
||||
RemoveMemberMessage::RemoveMemberMessage(jsobject obj, const jchar* propertyName, jsize length)
|
||||
: mObject(obj), mPropertyName(propertyName), mLength(length)
|
||||
{
|
||||
}
|
||||
|
||||
void RemoveMemberMessage::execute(JNIEnv* env)
|
||||
{
|
||||
nsresult result = theLiveConnectManager->RemoveMember(env, mObject, mPropertyName, mLength, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_netscape_javascript_JSObject_removeMember(JNIEnv* env,
|
||||
jobject java_wrapper_obj,
|
||||
jstring property_name_jstr)
|
||||
{
|
||||
if (property_name_jstr == NULL) {
|
||||
env->ThrowNew(env->FindClass("java/lang/NullPointerException"), "illegal null member name");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the Unicode string for the JS property name */
|
||||
jboolean is_copy;
|
||||
const jchar* property_name_ucs2 = env->GetStringChars(property_name_jstr, &is_copy);
|
||||
jsize property_name_len = env->GetStringLength(property_name_jstr);
|
||||
|
||||
jsobject js_obj = Unwrap_JSObject(env, java_wrapper_obj);
|
||||
RemoveMemberMessage msg(js_obj, property_name_ucs2, property_name_len);
|
||||
sendMessage(env, &msg);
|
||||
|
||||
env->ReleaseStringChars(property_name_jstr, property_name_ucs2);
|
||||
}
|
||||
|
||||
class CallMessage : public JavaMessage {
|
||||
jsobject mObject;
|
||||
const jchar* mFunctionName;
|
||||
jsize mLength;
|
||||
jobjectArray mJavaArgs;
|
||||
jobject* mJavaResult;
|
||||
public:
|
||||
CallMessage(jsobject obj, const jchar* functionName, jsize length, jobjectArray java_args, jobject* javaResult);
|
||||
|
||||
virtual void execute(JNIEnv* env);
|
||||
};
|
||||
|
||||
CallMessage::CallMessage(jsobject obj, const jchar* functionName, jsize length, jobjectArray javaArgs, jobject* javaResult)
|
||||
: mObject(obj), mFunctionName(functionName), mLength(length),
|
||||
mJavaArgs(javaArgs), mJavaResult(javaResult)
|
||||
{
|
||||
}
|
||||
|
||||
void CallMessage::execute(JNIEnv* env)
|
||||
{
|
||||
nsresult status = theLiveConnectManager->Call(env, mObject, mFunctionName, mLength, mJavaArgs, NULL, 0, NULL, mJavaResult);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: call
|
||||
* Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_netscape_javascript_JSObject_call(JNIEnv* env, jobject java_wrapper_obj,
|
||||
jstring function_name_jstr, jobjectArray java_args)
|
||||
{
|
||||
if (function_name_jstr == NULL) {
|
||||
env->ThrowNew(env->FindClass("java/lang/NullPointerException"), "illegal null function name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the Unicode string for the JS function name */
|
||||
jboolean is_copy;
|
||||
const jchar* function_name_ucs2 = env->GetStringChars(function_name_jstr, &is_copy);
|
||||
jsize function_name_len = env->GetStringLength(function_name_jstr);
|
||||
|
||||
jsobject js_obj = Unwrap_JSObject(env, java_wrapper_obj);
|
||||
jobject jresult = NULL;
|
||||
|
||||
CallMessage msg(js_obj, function_name_ucs2, function_name_len, java_args, &jresult);
|
||||
|
||||
sendMessage(env, &msg);
|
||||
|
||||
env->ReleaseStringChars(function_name_jstr, function_name_ucs2);
|
||||
|
||||
return jresult;
|
||||
}
|
||||
|
||||
class EvalMessage : public JavaMessage {
|
||||
JNIEnv* mEnv;
|
||||
jsobject mObject;
|
||||
const jchar* mScript;
|
||||
jsize mLength;
|
||||
jobject* mJavaResult;
|
||||
public:
|
||||
EvalMessage(jsobject obj, const jchar* script, jsize length, jobject* javaResult);
|
||||
|
||||
virtual void execute(JNIEnv* env);
|
||||
};
|
||||
|
||||
EvalMessage::EvalMessage(jsobject obj, const jchar* script, jsize length, jobject* javaResult)
|
||||
: mObject(obj), mScript(script), mLength(length), mJavaResult(javaResult)
|
||||
{
|
||||
}
|
||||
|
||||
void EvalMessage::execute(JNIEnv* env)
|
||||
{
|
||||
nsresult status = theLiveConnectManager->Eval(env, mObject, mScript, mLength, NULL, 0, NULL, mJavaResult);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: eval
|
||||
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_netscape_javascript_JSObject_eval(JNIEnv* env,
|
||||
jobject java_wrapper_obj,
|
||||
jstring script_jstr)
|
||||
{
|
||||
/* Get the Unicode string for the JS function name */
|
||||
if (script_jstr == NULL) {
|
||||
env->ThrowNew(env->FindClass("java/lang/NullPointerException"), "illegal null script string");
|
||||
return NULL;
|
||||
}
|
||||
jboolean is_copy;
|
||||
const jchar* script_ucs2 = env->GetStringChars(script_jstr, &is_copy);
|
||||
jsize script_len = env->GetStringLength(script_jstr);
|
||||
|
||||
/* unwrap the JS object from the Java object. */
|
||||
jsobject js_obj = Unwrap_JSObject(env, java_wrapper_obj);
|
||||
jobject jresult = NULL;
|
||||
|
||||
/* determine the plugin instance so we can obtain its codebase. */
|
||||
MRJPluginInstance* pluginInstance = theJVMPlugin->getPluginInstance(env);
|
||||
if (pluginInstance == NULL) {
|
||||
env->ThrowNew(env->FindClass("java/lang/NullPointerException"), "illegal JNIEnv (can't find plugin)");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EvalMessage msg(js_obj, script_ucs2, script_len, &jresult);
|
||||
sendMessage(env, &msg);
|
||||
|
||||
// Make sure it gets released!
|
||||
pluginInstance->Release();
|
||||
|
||||
env->ReleaseStringChars(script_jstr, script_ucs2);
|
||||
|
||||
return jresult;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: toString
|
||||
* Signature: ()Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_netscape_javascript_JSObject_toString(JNIEnv* env, jobject java_wrapper_obj)
|
||||
{
|
||||
/* unwrap the JS object from the Java object. */
|
||||
jstring jresult = NULL;
|
||||
jsobject js_obj = Unwrap_JSObject(env, java_wrapper_obj);
|
||||
|
||||
class ToStringMessage : public JavaMessage {
|
||||
jsobject mObject;
|
||||
jstring* mStringResult;
|
||||
public:
|
||||
ToStringMessage(jsobject js_obj, jstring* stringResult)
|
||||
: mObject(js_obj), mStringResult(stringResult)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(JNIEnv* env)
|
||||
{
|
||||
nsresult status = theLiveConnectManager->ToString(env, mObject, mStringResult);
|
||||
}
|
||||
} msg(js_obj, &jresult);
|
||||
|
||||
sendMessage(env, &msg);
|
||||
return jresult;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: getWindow
|
||||
* Signature: (Ljava/applet/Applet;)Lnetscape/javascript/JSObject;
|
||||
*/
|
||||
|
||||
class GetWindowMessage : public JavaMessage {
|
||||
nsIPluginInstance* mPluginInstance;
|
||||
jsobject* mWindowResult;
|
||||
public:
|
||||
GetWindowMessage(nsIPluginInstance* pluginInstance, jsobject* windowResult);
|
||||
|
||||
virtual void execute(JNIEnv* env);
|
||||
};
|
||||
|
||||
GetWindowMessage::GetWindowMessage(nsIPluginInstance* pluginInstance, jsobject* windowResult)
|
||||
: mPluginInstance(pluginInstance), mWindowResult(windowResult)
|
||||
{
|
||||
}
|
||||
|
||||
void GetWindowMessage::execute(JNIEnv* env)
|
||||
{
|
||||
nsresult status = theLiveConnectManager->GetWindow(env,mPluginInstance, NULL, 0, NULL, mWindowResult);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_netscape_javascript_JSObject_getWindow(JNIEnv* env,
|
||||
jclass js_object_class,
|
||||
jobject java_applet_obj)
|
||||
{
|
||||
jsobject jswindow = NULL;
|
||||
MRJPluginInstance* pluginInstance = theJVMPlugin->getPluginInstance(java_applet_obj);
|
||||
if (pluginInstance != NULL) {
|
||||
GetWindowMessage msg(pluginInstance, &jswindow);
|
||||
sendMessage(env, &msg);
|
||||
pluginInstance->Release();
|
||||
if (jswindow != NULL)
|
||||
return Wrap_JSObject(env, jswindow);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: finalize
|
||||
* Signature: ()V
|
||||
*/
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_netscape_javascript_JSObject_finalize(JNIEnv* env, jobject java_wrapper_obj)
|
||||
{
|
||||
jsobject jsobj = Unwrap_JSObject(env, java_wrapper_obj);
|
||||
|
||||
class FinalizeMessage : public JavaMessage {
|
||||
jsobject m_jsobj;
|
||||
public:
|
||||
FinalizeMessage(jsobject jsobj)
|
||||
: m_jsobj(jsobj)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(JNIEnv* env)
|
||||
{
|
||||
nsresult result = theLiveConnectManager->FinalizeJSObject(env, m_jsobj);
|
||||
}
|
||||
};
|
||||
FinalizeMessage msg(jsobj);
|
||||
sendMessage(env, &msg);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
LiveConnectNativeMethods.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "nsError.h"
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
class MRJPlugin;
|
||||
|
||||
nsresult InitLiveConnectSupport(MRJPlugin* jvmPlugin);
|
||||
nsresult ShutdownLiveConnectSupport(void);
|
||||
|
||||
jobject Wrap_JSObject(JNIEnv* env, jint js_obj);
|
||||
jint Unwrap_JSObject(JNIEnv* env, jobject java_wrapper_obj);
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
LocalPort.h
|
||||
|
||||
Simple utility class to put a Quickdraw GrafPort into a known state.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Quickdraw.h>
|
||||
|
||||
class LocalPort {
|
||||
public:
|
||||
LocalPort(GrafPtr port)
|
||||
{
|
||||
fPort = port;
|
||||
fOrigin.h = fOrigin.v = 0;
|
||||
}
|
||||
|
||||
LocalPort(GrafPtr port, Point origin)
|
||||
{
|
||||
fPort = port;
|
||||
fOrigin.h = origin.h;
|
||||
fOrigin.v = origin.v;
|
||||
}
|
||||
|
||||
void Enter();
|
||||
void Exit();
|
||||
|
||||
private:
|
||||
GrafPtr fPort;
|
||||
Point fOrigin;
|
||||
GrafPtr fOldPort;
|
||||
Point fOldOrigin;
|
||||
};
|
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJConsole.cpp
|
||||
|
||||
Implements the JVM console interface.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include <Appearance.h>
|
||||
#include <Gestalt.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "MRJConsole.h"
|
||||
#include "MRJPlugin.h"
|
||||
#include "MRJSession.h"
|
||||
#include "TopLevelFrame.h"
|
||||
|
||||
#include "nsIPluginManager2.h"
|
||||
|
||||
extern nsIPluginManager2* thePluginManager2;
|
||||
|
||||
MRJConsole* theConsole = NULL;
|
||||
|
||||
nsID MRJConsole::sInterfaceIDs[] = { NS_IJVMCONSOLE_IID };
|
||||
|
||||
MRJConsole::MRJConsole(MRJPlugin* plugin)
|
||||
: SupportsMixin((nsIJVMConsole*)this, sInterfaceIDs, sizeof(sInterfaceIDs) / sizeof(nsID)),
|
||||
mPlugin(plugin), mSession(NULL), mIsInitialized(PR_FALSE),
|
||||
mConsoleClass(NULL), mInitMethod(NULL), mDisposeMethod(NULL),
|
||||
mShowMethod(NULL), mHideMethod(NULL), mVisibleMethod(NULL), mPrintMethod(NULL), mFinishMethod(NULL),
|
||||
mResults(NULL), mContext(NULL), mFrame(NULL)
|
||||
{
|
||||
// Initialize();
|
||||
}
|
||||
|
||||
MRJConsole::~MRJConsole()
|
||||
{
|
||||
theConsole = NULL;
|
||||
|
||||
if (mSession != NULL) {
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
|
||||
if (mConsoleClass != NULL) {
|
||||
if (mDisposeMethod != NULL)
|
||||
env->CallStaticVoidMethod(mConsoleClass, mDisposeMethod);
|
||||
env->DeleteGlobalRef(mConsoleClass);
|
||||
mConsoleClass = NULL;
|
||||
}
|
||||
|
||||
if (mResults != NULL) {
|
||||
env->DeleteGlobalRef(mResults);
|
||||
mResults = NULL;
|
||||
}
|
||||
|
||||
if (mContext != NULL) {
|
||||
JMDisposeAWTContext(mContext);
|
||||
mContext = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD MRJConsole::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
nsresult result = queryInterface(aIID, aInstancePtr);
|
||||
if (result == NS_NOINTERFACE)
|
||||
result = mPlugin->queryInterface(aIID, aInstancePtr);
|
||||
return result;
|
||||
}
|
||||
|
||||
nsrefcnt MRJConsole::AddRef() { return addRef(); }
|
||||
nsrefcnt MRJConsole::Release() { return release(); }
|
||||
|
||||
#pragma mark ***** MRJConsole *****
|
||||
|
||||
NS_METHOD MRJConsole::ShowConsole()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
if (mShowMethod != NULL) {
|
||||
CallConsoleMethod(mShowMethod);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_METHOD MRJConsole::HideConsole()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
if (mHideMethod != NULL) {
|
||||
CallConsoleMethod(mHideMethod);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_METHOD MRJConsole::IsConsoleVisible(PRBool* isVisible)
|
||||
{
|
||||
// don't initialize here, because if we haven't been initialized, it can't be visible.
|
||||
*isVisible = PR_FALSE;
|
||||
if (mVisibleMethod != NULL) {
|
||||
CallConsoleMethod(mVisibleMethod, mResults);
|
||||
jboolean isCopy;
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
jboolean* elements = env->GetBooleanArrayElements(mResults, &isCopy);
|
||||
*isVisible = elements[0];
|
||||
env->ReleaseBooleanArrayElements(mResults, elements, JNI_ABORT);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Prints a message to the Java console. The encodingName specifies the
|
||||
// encoding of the message, and if NULL, specifies the default platform
|
||||
// encoding.
|
||||
|
||||
NS_METHOD MRJConsole::Print(const char* msg, const char* encodingName)
|
||||
{
|
||||
Initialize();
|
||||
|
||||
if (mPrintMethod != NULL) {
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
jstring jmsg = env->NewStringUTF(msg);
|
||||
jvalue args[1]; args[0].l = jmsg;
|
||||
JMExecJNIStaticMethodInContext(mContext, env, mConsoleClass, mPrintMethod, 1, args);
|
||||
env->DeleteLocalRef(jmsg);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Writes a message to the Java console immediately, in the current thread.
|
||||
|
||||
void MRJConsole::write(const void *message, UInt32 messageLengthInBytes)
|
||||
{
|
||||
if (mPrintMethod != NULL) {
|
||||
char* buffer = new char[messageLengthInBytes + 1];
|
||||
if (buffer != NULL) {
|
||||
memcpy(buffer, message, messageLengthInBytes);
|
||||
buffer[messageLengthInBytes] = '\0';
|
||||
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
jstring jmsg = env->NewStringUTF(buffer);
|
||||
if (jmsg != NULL) {
|
||||
env->CallStaticVoidMethod(mConsoleClass, mPrintMethod, jmsg);
|
||||
env->DeleteLocalRef(jmsg);
|
||||
}
|
||||
|
||||
delete buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD MRJConsole::HandleEvent(nsPluginEvent* pluginEvent, PRBool* eventHandled)
|
||||
{
|
||||
*eventHandled = PR_TRUE;
|
||||
|
||||
if (pluginEvent != NULL) {
|
||||
EventRecord* event = pluginEvent->event;
|
||||
|
||||
if (event->what == nullEvent) {
|
||||
// Give MRJ another quantum of time.
|
||||
MRJSession* session = mPlugin->getSession();
|
||||
session->idle(kDefaultJMTime);
|
||||
} else {
|
||||
TopLevelFrame* frame = mFrame;
|
||||
if (frame != NULL) {
|
||||
switch (event->what) {
|
||||
case nsPluginEventType_GetFocusEvent:
|
||||
frame->focusEvent(true);
|
||||
break;
|
||||
|
||||
case nsPluginEventType_LoseFocusEvent:
|
||||
frame->focusEvent(false);
|
||||
break;
|
||||
|
||||
case nsPluginEventType_AdjustCursorEvent:
|
||||
frame->idle(event->modifiers);
|
||||
break;
|
||||
|
||||
case nsPluginEventType_MenuCommandEvent:
|
||||
frame->menuSelected(event->message, event->modifiers);
|
||||
break;
|
||||
|
||||
default:
|
||||
*eventHandled = frame->handleEvent(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
OSStatus MRJConsole::CallConsoleMethod(jmethodID method)
|
||||
{
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
OSStatus status = JMExecJNIStaticMethodInContext(mContext, env, mConsoleClass, method, 0, NULL);
|
||||
env->CallStaticVoidMethod(mConsoleClass, mFinishMethod);
|
||||
return status;
|
||||
}
|
||||
|
||||
OSStatus MRJConsole::CallConsoleMethod(jmethodID method, jobject arg)
|
||||
{
|
||||
jvalue args[1];
|
||||
args[0].l = arg;
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
OSStatus status = JMExecJNIStaticMethodInContext(mContext, env, mConsoleClass, method, 1, args);
|
||||
env->CallStaticVoidMethod(mConsoleClass, mFinishMethod);
|
||||
return status;
|
||||
}
|
||||
|
||||
static OSStatus requestFrame(JMAWTContextRef contextRef, JMFrameRef frameRef, JMFrameKind kind,
|
||||
const Rect* initialBounds, Boolean resizeable, JMFrameCallbacks* cb)
|
||||
{
|
||||
extern JMFrameCallbacks theFrameCallbacks;
|
||||
// set up the viewer frame's callbacks.
|
||||
BlockMoveData(&theFrameCallbacks, cb, sizeof(theFrameCallbacks));
|
||||
|
||||
MRJConsole* thisConsole = NULL;
|
||||
OSStatus status = ::JMGetAWTContextData(contextRef, (JMClientData*)&thisConsole);
|
||||
if (status == noErr && thePluginManager2 != NULL) {
|
||||
// Can only do this safely if we are using the new API.
|
||||
TopLevelFrame* frame = new TopLevelFrame(thisConsole, frameRef, kind, initialBounds, resizeable);
|
||||
status = ::JMSetFrameData(frameRef, frame);
|
||||
thisConsole->setFrame(frame);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static OSStatus releaseFrame(JMAWTContextRef contextRef, JMFrameRef frameRef)
|
||||
{
|
||||
MRJConsole* thisConsole = NULL;
|
||||
OSStatus status = ::JMGetAWTContextData(contextRef, (JMClientData*)&thisConsole);
|
||||
MRJFrame* thisFrame = NULL;
|
||||
status = ::JMGetFrameData(frameRef, (JMClientData*)&thisFrame);
|
||||
if (thisFrame != NULL) {
|
||||
status = ::JMSetFrameData(frameRef, NULL);
|
||||
thisConsole->setFrame(NULL);
|
||||
delete thisFrame;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static SInt16 getUniqueMenuID(JMAWTContextRef contextRef, Boolean isSubmenu)
|
||||
{
|
||||
MRJConsole* thisConsole = NULL;
|
||||
OSStatus status = ::JMGetAWTContextData(contextRef, (JMClientData*)&thisConsole);
|
||||
if (thePluginManager2 != NULL) {
|
||||
PRInt16 menuID;
|
||||
if (thePluginManager2->AllocateMenuID(thisConsole, isSubmenu, &menuID) == NS_OK)
|
||||
return menuID;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static Boolean appearanceManagerExists()
|
||||
{
|
||||
long response = 0;
|
||||
return (Gestalt(gestaltAppearanceAttr, &response) == noErr && (response & (1 << gestaltAppearanceExists)));
|
||||
}
|
||||
|
||||
static OSStatus JMTextToStr255(JMTextRef textRef, Str255 str)
|
||||
{
|
||||
UInt32 length = 0;
|
||||
OSStatus status = JMGetTextBytes(textRef, kTextEncodingMacRoman, &str[1], sizeof(Str255) - 1, &length);
|
||||
if (status == noErr)
|
||||
str[0] = (unsigned char)(status == noErr ? length : 0);
|
||||
return status;
|
||||
}
|
||||
|
||||
inline int min(int x, int y) { return (x <= y ? x : y); }
|
||||
|
||||
static void push(StringPtr dest, StringPtr str)
|
||||
{
|
||||
int length = dest[0];
|
||||
int newLength = min(255, length + str[0]);
|
||||
if (newLength > length)
|
||||
::BlockMoveData(&str[1], &dest[1] + length, newLength - length);
|
||||
}
|
||||
|
||||
static void exceptionOccurred(JMAWTContextRef context, JMTextRef exceptionName, JMTextRef exceptionMsg, JMTextRef stackTrace)
|
||||
{
|
||||
// why not display this using the Appearance Manager's wizzy new alert?
|
||||
if (appearanceManagerExists()) {
|
||||
OSStatus status;
|
||||
Str255 preason = { '\0' }, pmessage = { '\0'}, ptrace = { '\0' };
|
||||
if (exceptionName != NULL) {
|
||||
status = ::JMTextToStr255(exceptionName, preason);
|
||||
if (exceptionMsg != NULL) {
|
||||
status = ::JMTextToStr255(exceptionMsg, pmessage);
|
||||
push(preason, "\p (");
|
||||
push(preason, pmessage);
|
||||
push(preason, "\p)");
|
||||
}
|
||||
}
|
||||
|
||||
if (stackTrace != NULL)
|
||||
status = ::JMTextToStr255(stackTrace, ptrace);
|
||||
|
||||
SInt16 itemHit = 0;
|
||||
OSErr result = ::StandardAlert(kAlertPlainAlert, preason, ptrace, NULL, &itemHit);
|
||||
}
|
||||
}
|
||||
|
||||
void MRJConsole::Initialize()
|
||||
{
|
||||
if (mIsInitialized)
|
||||
return;
|
||||
|
||||
mSession = mPlugin->getSession();
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
|
||||
jclass consoleClass = env->FindClass("netscape/oji/MRJConsole");
|
||||
if (consoleClass == NULL) return;
|
||||
mConsoleClass = (jclass) env->NewGlobalRef(consoleClass);
|
||||
|
||||
mInitMethod = env->GetStaticMethodID(consoleClass, "init", "()V");
|
||||
mDisposeMethod = env->GetStaticMethodID(consoleClass, "dispose", "()V");
|
||||
mShowMethod = env->GetStaticMethodID(consoleClass, "show", "()V");
|
||||
mHideMethod = env->GetStaticMethodID(consoleClass, "hide", "()V");
|
||||
mVisibleMethod = env->GetStaticMethodID(consoleClass, "visible", "([Z)V");
|
||||
mPrintMethod = env->GetStaticMethodID(consoleClass, "print", "(Ljava/lang/String;)V");
|
||||
mFinishMethod = env->GetStaticMethodID(consoleClass, "finish", "()V");
|
||||
|
||||
jbooleanArray results = env->NewBooleanArray(1);
|
||||
mResults = (jbooleanArray) env->NewGlobalRef(results);
|
||||
env->DeleteLocalRef(results);
|
||||
|
||||
// Create an AWT context to work in.
|
||||
|
||||
JMAWTContextCallbacks callbacks = {
|
||||
kJMVersion, /* should be set to kJMVersion */
|
||||
&requestFrame, /* a new frame is being created. */
|
||||
&releaseFrame, /* an existing frame is being destroyed. */
|
||||
&getUniqueMenuID, /* a new menu will be created with this id. */
|
||||
&exceptionOccurred, /* just some notification that some recent operation caused an exception. You can't do anything really from here. */
|
||||
};
|
||||
OSStatus status = ::JMNewAWTContext(&mContext, mSession->getSessionRef(), &callbacks, this);
|
||||
|
||||
// Finally, call the Java initialize method, and wait for it to complete.
|
||||
|
||||
if (mInitMethod != NULL && status == noErr) {
|
||||
status = JMExecJNIStaticMethodInContext(mContext, env, consoleClass, mInitMethod, 0, NULL);
|
||||
env->CallStaticVoidMethod(mConsoleClass, mFinishMethod);
|
||||
}
|
||||
env->DeleteLocalRef(consoleClass);
|
||||
|
||||
mIsInitialized = (status == noErr);
|
||||
|
||||
if (mIsInitialized)
|
||||
theConsole = this;
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJConsole.h
|
||||
|
||||
Implements the JVM console interface.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include "nsIJVMConsole.h"
|
||||
#include "nsIEventHandler.h"
|
||||
#include "SupportsMixin.h"
|
||||
|
||||
#include <jni.h>
|
||||
#include <JManager.h>
|
||||
|
||||
class MRJPlugin;
|
||||
class MRJSession;
|
||||
class TopLevelFrame;
|
||||
|
||||
class MRJConsole : public nsIJVMConsole,
|
||||
public nsIEventHandler,
|
||||
public SupportsMixin {
|
||||
public:
|
||||
MRJConsole(MRJPlugin* plugin);
|
||||
virtual ~MRJConsole();
|
||||
|
||||
// NS_DECL_ISUPPORTS
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
|
||||
// nsIJVMConsole methods.
|
||||
|
||||
NS_IMETHOD
|
||||
ShowConsole(void);
|
||||
|
||||
NS_IMETHOD
|
||||
HideConsole(void);
|
||||
|
||||
NS_IMETHOD
|
||||
IsConsoleVisible(PRBool* isVisible);
|
||||
|
||||
// Prints a message to the Java console. The encodingName specifies the
|
||||
// encoding of the message, and if NULL, specifies the default platform
|
||||
// encoding.
|
||||
NS_IMETHOD
|
||||
Print(const char* msg, const char* encodingName = NULL);
|
||||
|
||||
NS_IMETHOD
|
||||
HandleEvent(nsPluginEvent* event, PRBool* eventHandled);
|
||||
|
||||
// Private implementation methods.
|
||||
|
||||
void setFrame(TopLevelFrame* frame) { mFrame = frame; }
|
||||
|
||||
void write(const void *message, UInt32 messageLengthInBytes);
|
||||
|
||||
private:
|
||||
// Private implementation methods.
|
||||
OSStatus CallConsoleMethod(jmethodID method);
|
||||
OSStatus CallConsoleMethod(jmethodID method, jobject arg);
|
||||
|
||||
void Initialize();
|
||||
|
||||
private:
|
||||
MRJPlugin* mPlugin;
|
||||
MRJSession* mSession;
|
||||
PRBool mIsInitialized;
|
||||
|
||||
jclass mConsoleClass;
|
||||
jmethodID mInitMethod;
|
||||
jmethodID mDisposeMethod;
|
||||
jmethodID mShowMethod;
|
||||
jmethodID mHideMethod;
|
||||
jmethodID mVisibleMethod;
|
||||
jmethodID mPrintMethod;
|
||||
jmethodID mFinishMethod;
|
||||
|
||||
jbooleanArray mResults;
|
||||
|
||||
JMAWTContextRef mContext;
|
||||
TopLevelFrame* mFrame;
|
||||
|
||||
// support for nsISupports.
|
||||
static nsID sInterfaceIDs[];
|
||||
};
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MJRConsole.java
|
||||
|
||||
Simple Java console for MRJ.
|
||||
|
||||
All methods are called asynchronously, using JMExecJNIStaticMethodInContext(). After posting
|
||||
each call this way, MRJConsole.finish() is called, which waits on MRJConsole.class. Each
|
||||
public method calls MRJConsole.done(), which notifies. This should probably be changed
|
||||
to a pure Java approach.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
package netscape.oji;
|
||||
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
class ConsoleWindow extends Frame {
|
||||
TextArea text;
|
||||
|
||||
ConsoleWindow(String title) {
|
||||
super("Java Console");
|
||||
|
||||
addWindowListener(
|
||||
new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
add(text = new TextArea());
|
||||
setSize(300, 200);
|
||||
|
||||
ActionListener dumpThreadsListener =
|
||||
new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
dumpThreads();
|
||||
}
|
||||
};
|
||||
|
||||
// Create a console menu.
|
||||
MenuBar menuBar = new MenuBar();
|
||||
Menu consoleMenu = new Menu("Console");
|
||||
consoleMenu.add(newItem("Dump Threads", dumpThreadsListener));
|
||||
|
||||
menuBar.add(consoleMenu);
|
||||
setMenuBar(menuBar);
|
||||
}
|
||||
|
||||
private MenuItem newItem(String title, ActionListener listener) {
|
||||
MenuItem item = new MenuItem(title);
|
||||
item.addActionListener(listener);
|
||||
return item;
|
||||
}
|
||||
|
||||
public void dumpThreads() {
|
||||
System.out.println("Dumping threads...");
|
||||
}
|
||||
}
|
||||
|
||||
public class MRJConsole {
|
||||
// Save primordial System streams.
|
||||
private static InputStream in;
|
||||
private static PrintStream out;
|
||||
private static PrintStream err;
|
||||
private static ConsoleWindow window;
|
||||
|
||||
native static int readLine(byte[] buffer, int offset, int length);
|
||||
native static void writeLine(byte[] buffer, int offset, int length);
|
||||
|
||||
private static class Input extends InputStream {
|
||||
byte[] buffer = new byte[1024];
|
||||
int position = 0;
|
||||
int count = 0;
|
||||
|
||||
private void fillBuffer() throws EOFException {
|
||||
// int length = readLine(buffer, 0, buffer.length);
|
||||
int length = 1024;
|
||||
if (length == -1)
|
||||
throw new EOFException();
|
||||
count = length;
|
||||
position = 0;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
synchronized(this) {
|
||||
if (position >= count)
|
||||
fillBuffer();
|
||||
return buffer[position++];
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] b, int offset, int length) throws IOException {
|
||||
synchronized(this) {
|
||||
// only fill the buffer at the outset, always returns at most one line of data.
|
||||
if (position >= count)
|
||||
fillBuffer();
|
||||
int initialOffset = offset;
|
||||
while (offset < length && position < count) {
|
||||
b[offset++] = buffer[position++];
|
||||
}
|
||||
return (offset - initialOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Output extends OutputStream implements Runnable {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
public Output() {
|
||||
Thread flusher = new Thread(this, getClass().getName() + "-Flusher");
|
||||
flusher.setDaemon(true);
|
||||
flusher.start();
|
||||
}
|
||||
|
||||
public synchronized void write(int b) throws IOException {
|
||||
this.buffer.append((char)b);
|
||||
notify();
|
||||
}
|
||||
|
||||
public synchronized void write(byte[] buffer, int offset, int count) throws IOException {
|
||||
this.buffer.append(new String(buffer, 0, offset, count));
|
||||
notify();
|
||||
}
|
||||
|
||||
public synchronized void flush() throws IOException {
|
||||
String value = this.buffer.toString();
|
||||
window.text.append(value);
|
||||
this.buffer.setLength(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* When I/O occurs, it is placed in a StringBuffer, which is flushed in a different thread.
|
||||
* This prevents deadlocks that could occur when the AWT itself is printing messages.
|
||||
*/
|
||||
public synchronized void run() {
|
||||
for (;;) {
|
||||
try {
|
||||
wait();
|
||||
flush();
|
||||
} catch (InterruptedException ie) {
|
||||
} catch (IOException ioe) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Error extends Output {}
|
||||
|
||||
public static void init() {
|
||||
in = System.in;
|
||||
out = System.out;
|
||||
err = System.err;
|
||||
|
||||
window = new ConsoleWindow("Java Console");
|
||||
|
||||
System.setIn(new Input());
|
||||
System.setOut(new PrintStream(new Output()));
|
||||
System.setErr(new PrintStream(new Error()));
|
||||
|
||||
done();
|
||||
}
|
||||
|
||||
public static void dispose() {
|
||||
System.setIn(in);
|
||||
System.setOut(out);
|
||||
System.setErr(err);
|
||||
window.dispose();
|
||||
window = null;
|
||||
done();
|
||||
}
|
||||
|
||||
public static void show() {
|
||||
window.show();
|
||||
done();
|
||||
}
|
||||
|
||||
public static void hide() {
|
||||
window.hide();
|
||||
done();
|
||||
}
|
||||
|
||||
public static void visible(boolean[] result) {
|
||||
result[0] = window.isVisible();
|
||||
done();
|
||||
}
|
||||
|
||||
public static void print(String text) {
|
||||
System.out.print(text);
|
||||
done();
|
||||
}
|
||||
|
||||
public static synchronized void finish() {
|
||||
try {
|
||||
MRJConsole.class.wait();
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized void done() {
|
||||
MRJConsole.class.notify();
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJContext.h
|
||||
|
||||
Manages Java content using the MacOS Runtime for Java.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jni.h"
|
||||
#include "JManager.h"
|
||||
#include "nsplugindefs.h"
|
||||
|
||||
//
|
||||
// Instance state information about the plugin.
|
||||
//
|
||||
// *Developers*: Use this struct to hold per-instance
|
||||
// information that youÕll need in the
|
||||
// various functions in this file.
|
||||
//
|
||||
|
||||
class MRJSession;
|
||||
class MRJPluginInstance;
|
||||
class nsIPluginInstancePeer;
|
||||
struct nsPluginWindow;
|
||||
class MRJFrame;
|
||||
class MRJPage;
|
||||
struct MRJPageAttributes;
|
||||
|
||||
class MRJContext {
|
||||
public:
|
||||
MRJContext(MRJSession* session, MRJPluginInstance* instance);
|
||||
~MRJContext();
|
||||
|
||||
void processAppletTag();
|
||||
Boolean createContext();
|
||||
JMAWTContextRef getContextRef();
|
||||
|
||||
Boolean appletLoaded();
|
||||
Boolean loadApplet();
|
||||
Boolean isActive();
|
||||
|
||||
void suspendApplet();
|
||||
void resumeApplet();
|
||||
|
||||
jobject getApplet();
|
||||
|
||||
void idle(short modifiers);
|
||||
void drawApplet();
|
||||
void activate(Boolean active);
|
||||
void resume(Boolean inFront);
|
||||
|
||||
void click(const EventRecord* event, MRJFrame* frame);
|
||||
void keyPress(long message, short modifiers);
|
||||
void keyRelease(long message, short modifiers);
|
||||
|
||||
void setWindow(nsPluginWindow* pluginWindow);
|
||||
Boolean inspectClipping();
|
||||
Boolean inspectWindow();
|
||||
void setClipping(RgnHandle clipRgn);
|
||||
|
||||
MRJFrame* findFrame(WindowRef window);
|
||||
GrafPtr getPort();
|
||||
|
||||
void showFrames();
|
||||
void hideFrames();
|
||||
|
||||
const char* getCodeBase();
|
||||
|
||||
private:
|
||||
void localToFrame(Point* pt);
|
||||
void ensureValidPort();
|
||||
void setVisibility();
|
||||
|
||||
static OSStatus requestFrame(JMAWTContextRef context, JMFrameRef newFrame, JMFrameKind kind,
|
||||
const Rect *initialBounds, Boolean resizeable, JMFrameCallbacks *callbacks);
|
||||
static OSStatus releaseFrame(JMAWTContextRef context, JMFrameRef oldFrame);
|
||||
static SInt16 getUniqueMenuID(JMAWTContextRef context, Boolean isSubmenu);
|
||||
static void exceptionOccurred(JMAWTContextRef context, JMTextRef exceptionName, JMTextRef exceptionMsg, JMTextRef stackTrace);
|
||||
|
||||
static void showDocument(JMAppletViewerRef viewer, JMTextRef urlString, JMTextRef windowName);
|
||||
static void setStatusMessage(JMAppletViewerRef viewer, JMTextRef statusMsg);
|
||||
|
||||
void showURL(const char* url, const char* target);
|
||||
void showStatus(const char* message);
|
||||
SInt16 allocateMenuID(Boolean isSubmenu);
|
||||
|
||||
OSStatus createFrame(JMFrameRef frameRef, JMFrameKind kind, const Rect* initialBounds, Boolean resizeable);
|
||||
|
||||
// Finds a suitable MRJPage object for this document URL, or creates one.
|
||||
MRJPage* findPage(const MRJPageAttributes& attributes);
|
||||
|
||||
private:
|
||||
MRJPluginInstance* mPluginInstance;
|
||||
MRJSession* mSession;
|
||||
JMSessionRef mSessionRef;
|
||||
nsIPluginInstancePeer* mPeer;
|
||||
JMAppletLocatorRef mLocator;
|
||||
JMAWTContextRef mContext;
|
||||
JMAppletViewerRef mViewer;
|
||||
JMFrameRef mViewerFrame;
|
||||
Boolean mIsActive;
|
||||
nsPluginWindow mCache;
|
||||
nsPluginWindow* mPluginWindow;
|
||||
RgnHandle mPluginClipping;
|
||||
char* mCodeBase;
|
||||
MRJPage* mPage;
|
||||
};
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJFrame.cpp
|
||||
|
||||
Encapsulates a JManager frame.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include "MRJFrame.h"
|
||||
#include "LocalPort.h"
|
||||
#include "nsplugindefs.h"
|
||||
|
||||
MRJFrame::MRJFrame(JMFrameRef frameRef)
|
||||
: mFrameRef(frameRef), mActive(false), mFocused(false)
|
||||
{
|
||||
}
|
||||
|
||||
MRJFrame::~MRJFrame()
|
||||
{
|
||||
}
|
||||
|
||||
/* Stub implementations. */
|
||||
void MRJFrame::setSize(const Rect* newSize) {}
|
||||
void MRJFrame::invalRect(const Rect* invalidRect) {}
|
||||
void MRJFrame::showHide(Boolean visible) {}
|
||||
void MRJFrame::setTitle(const StringPtr title) {}
|
||||
void MRJFrame::checkUpdate() {}
|
||||
void MRJFrame::reorder(ReorderRequest request) {}
|
||||
void MRJFrame::setResizeable(Boolean resizeable) {}
|
||||
|
||||
Boolean MRJFrame::handleEvent(const EventRecord* event)
|
||||
{
|
||||
Boolean eventHandled = true;
|
||||
|
||||
switch (event->what) {
|
||||
case nsPluginEventType_AdjustCursorEvent:
|
||||
idle(event->modifiers);
|
||||
break;
|
||||
|
||||
case ::mouseDown:
|
||||
click(event);
|
||||
break;
|
||||
|
||||
case keyDown:
|
||||
case autoKey:
|
||||
keyPress(event->message, event->modifiers);
|
||||
break;
|
||||
|
||||
case keyUp:
|
||||
keyRelease(event->message, event->modifiers);
|
||||
break;
|
||||
|
||||
case updateEvt:
|
||||
update();
|
||||
break;
|
||||
|
||||
case activateEvt:
|
||||
activate((event->modifiers & activeFlag) != 0);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case osEvt:
|
||||
resume((event->message & resumeFlag) != 0);
|
||||
eventHandled = false;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
eventHandled = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return eventHandled;
|
||||
}
|
||||
|
||||
void MRJFrame::idle(SInt16 modifiers)
|
||||
{
|
||||
LocalPort port(getPort());
|
||||
port.Enter();
|
||||
|
||||
Point pt;
|
||||
::GetMouse(&pt);
|
||||
::JMFrameMouseOver(mFrameRef, pt, modifiers);
|
||||
|
||||
port.Exit();
|
||||
}
|
||||
|
||||
void MRJFrame::update()
|
||||
{
|
||||
GrafPtr framePort = getPort();
|
||||
if (framePort != NULL)
|
||||
::JMFrameUpdate(mFrameRef, framePort->clipRgn);
|
||||
}
|
||||
|
||||
void MRJFrame::activate(Boolean active)
|
||||
{
|
||||
if (mActive != active) {
|
||||
mActive = active;
|
||||
::JMFrameActivate(mFrameRef, active);
|
||||
}
|
||||
}
|
||||
|
||||
void MRJFrame::focusEvent(Boolean gotFocus)
|
||||
{
|
||||
if (&::JMFrameFocus != NULL) {
|
||||
if (gotFocus != mFocused) {
|
||||
if (gotFocus) {
|
||||
// HACK, until focus really works.
|
||||
if (mActive != gotFocus) {
|
||||
mActive = gotFocus;
|
||||
::JMFrameActivate(mFrameRef, gotFocus);
|
||||
}
|
||||
}
|
||||
mFocused = gotFocus;
|
||||
::JMFrameFocus(mFrameRef, gotFocus);
|
||||
}
|
||||
} else {
|
||||
if (mActive != gotFocus) {
|
||||
mActive = gotFocus;
|
||||
::JMFrameActivate(mFrameRef, gotFocus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MRJFrame::resume(Boolean inFront)
|
||||
{
|
||||
::JMFrameResume(mFrameRef, inFront);
|
||||
}
|
||||
|
||||
void MRJFrame::click(const EventRecord* event)
|
||||
{
|
||||
// make the frame's port current, and move its origin to (0, 0).
|
||||
// this is needed to transform the mouse click location to frame coordinates.
|
||||
LocalPort port(getPort());
|
||||
port.Enter();
|
||||
|
||||
Point localWhere = event->where;
|
||||
::GlobalToLocal(&localWhere);
|
||||
click(event, localWhere);
|
||||
|
||||
// restore the plugin port's origin, and restore the current port.
|
||||
port.Exit();
|
||||
}
|
||||
|
||||
void MRJFrame::click(const EventRecord* event, Point localWhere)
|
||||
{
|
||||
if (&::JMFrameClickWithEventRecord != NULL)
|
||||
::JMFrameClickWithEventRecord(mFrameRef, localWhere, event);
|
||||
else
|
||||
::JMFrameClick(mFrameRef, localWhere, event->modifiers);
|
||||
}
|
||||
|
||||
void MRJFrame::keyPress(UInt32 message, SInt16 modifiers)
|
||||
{
|
||||
::JMFrameKey(mFrameRef, message & charCodeMask, (message & keyCodeMask) >> 8, modifiers);
|
||||
}
|
||||
|
||||
void MRJFrame::keyRelease(UInt32 message, SInt16 modifiers)
|
||||
{
|
||||
::JMFrameKeyRelease(mFrameRef, message & charCodeMask, (message & keyCodeMask) >> 8, modifiers);
|
||||
}
|
||||
|
||||
void MRJFrame::menuSelected(UInt32 message, SInt16 modifiers)
|
||||
{
|
||||
MenuHandle menu = ::GetMenuHandle(short(message >> 16));
|
||||
if (menu != NULL) {
|
||||
short item = short(message);
|
||||
if (&::JMMenuSelectedWithModifiers != NULL)
|
||||
::JMMenuSelectedWithModifiers(::JMGetFrameContext(mFrameRef), menu, item, modifiers);
|
||||
else
|
||||
::JMMenuSelected(::JMGetFrameContext(mFrameRef), menu, item);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJFrame.h
|
||||
|
||||
Encapsulates a JManager frame.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jni.h"
|
||||
#include "JManager.h"
|
||||
|
||||
struct EventRecord;
|
||||
|
||||
class MRJFrame {
|
||||
public:
|
||||
MRJFrame(JMFrameRef frameRef);
|
||||
virtual ~MRJFrame();
|
||||
|
||||
/** Methods used to implement the JMFrame callback protocol. */
|
||||
virtual void setSize(const Rect* newSize);
|
||||
virtual void invalRect(const Rect* invalidRect);
|
||||
virtual void showHide(Boolean visible);
|
||||
virtual void setTitle(const StringPtr title);
|
||||
virtual void checkUpdate();
|
||||
virtual void reorder(ReorderRequest request);
|
||||
virtual void setResizeable(Boolean resizeable);
|
||||
|
||||
/** Methods to handle various events. */
|
||||
virtual Boolean handleEvent(const EventRecord* event);
|
||||
|
||||
virtual void idle(SInt16 modifiers);
|
||||
virtual void update();
|
||||
virtual void activate(Boolean active);
|
||||
virtual void resume(Boolean inFront);
|
||||
virtual void click(const EventRecord* event);
|
||||
virtual void click(const EventRecord* event, Point localWhere);
|
||||
virtual void keyPress(UInt32 message, SInt16 modifiers);
|
||||
virtual void keyRelease(UInt32 message, SInt16 modifiers);
|
||||
|
||||
virtual void focusEvent(Boolean gotFocus);
|
||||
virtual void menuSelected(UInt32 message, SInt16 modifiers);
|
||||
|
||||
protected:
|
||||
virtual GrafPtr getPort() = 0;
|
||||
|
||||
protected:
|
||||
JMFrameRef mFrameRef;
|
||||
Boolean mActive;
|
||||
Boolean mFocused;
|
||||
};
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJMonitor.cpp
|
||||
|
||||
Provides a C++ interface to Java monitors.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include "MRJMonitor.h"
|
||||
#include "MRJSession.h"
|
||||
|
||||
MRJMonitor::MRJMonitor(MRJSession* session, jobject monitor)
|
||||
: mSession(session), mMonitor(NULL), mWaitMethod(NULL), mNotifyMethod(NULL), mNotifyAllMethod(NULL)
|
||||
{
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
jclass javaLangObject = env->FindClass("java/lang/Object");
|
||||
if (javaLangObject != NULL) {
|
||||
// look up method IDs.
|
||||
mWaitMethod = env->GetMethodID(javaLangObject, "wait", "()V");
|
||||
mTimedWaitMethod = env->GetMethodID(javaLangObject, "wait", "(J)V");
|
||||
mNotifyMethod = env->GetMethodID(javaLangObject, "notify", "()V");
|
||||
mNotifyAllMethod = env->GetMethodID(javaLangObject, "notifyAll", "()V");
|
||||
|
||||
Boolean allocateMonitor = (monitor == NULL);
|
||||
if (allocateMonitor)
|
||||
monitor = env->AllocObject(javaLangObject);
|
||||
|
||||
if (monitor != NULL)
|
||||
mMonitor = env->NewGlobalRef(monitor);
|
||||
|
||||
if (allocateMonitor)
|
||||
env->DeleteLocalRef(monitor);
|
||||
|
||||
env->DeleteLocalRef(javaLangObject);
|
||||
}
|
||||
}
|
||||
|
||||
MRJMonitor::~MRJMonitor()
|
||||
{
|
||||
if (mMonitor != NULL) {
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
env->DeleteGlobalRef(mMonitor);
|
||||
mMonitor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void MRJMonitor::enter()
|
||||
{
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
env->MonitorEnter(mMonitor);
|
||||
}
|
||||
|
||||
void MRJMonitor::exit()
|
||||
{
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
env->MonitorExit(mMonitor);
|
||||
}
|
||||
|
||||
void MRJMonitor::wait()
|
||||
{
|
||||
if (mMonitor != NULL && mWaitMethod != NULL) {
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
env->MonitorEnter(mMonitor);
|
||||
env->CallVoidMethod(mMonitor, mWaitMethod);
|
||||
env->MonitorExit(mMonitor);
|
||||
}
|
||||
}
|
||||
|
||||
void MRJMonitor::wait(long long millis)
|
||||
{
|
||||
if (mMonitor != NULL && mWaitMethod != NULL) {
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
env->MonitorEnter(mMonitor);
|
||||
env->CallVoidMethod(mMonitor, mTimedWaitMethod, jlong(millis));
|
||||
env->MonitorExit(mMonitor);
|
||||
}
|
||||
}
|
||||
|
||||
void MRJMonitor::notify()
|
||||
{
|
||||
if (mMonitor != NULL && mNotifyMethod != NULL) {
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
env->MonitorEnter(mMonitor);
|
||||
env->CallVoidMethod(mMonitor, mNotifyMethod);
|
||||
env->MonitorExit(mMonitor);
|
||||
}
|
||||
}
|
||||
|
||||
void MRJMonitor::notifyAll()
|
||||
{
|
||||
if (mMonitor != NULL && mNotifyAllMethod != NULL) {
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
env->MonitorEnter(mMonitor);
|
||||
env->CallVoidMethod(mMonitor, mNotifyAllMethod);
|
||||
env->MonitorExit(mMonitor);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJMonitor.h
|
||||
|
||||
Provides a C++ interface to Java monitors.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include "Monitor.h"
|
||||
|
||||
#ifndef JNI_H
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
class MRJSession;
|
||||
|
||||
class MRJMonitor : public Monitor {
|
||||
public:
|
||||
MRJMonitor(MRJSession* session, jobject monitor = NULL);
|
||||
~MRJMonitor();
|
||||
|
||||
virtual void enter();
|
||||
virtual void exit();
|
||||
|
||||
virtual void wait();
|
||||
virtual void wait(long long millis);
|
||||
virtual void notify();
|
||||
virtual void notifyAll();
|
||||
|
||||
private:
|
||||
MRJSession* mSession;
|
||||
jobject mMonitor;
|
||||
jmethodID mWaitMethod;
|
||||
jmethodID mTimedWaitMethod;
|
||||
jmethodID mNotifyMethod;
|
||||
jmethodID mNotifyAllMethod;
|
||||
};
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJPage.cpp
|
||||
|
||||
Encapsulates the new MRJ Page API, which loads applets into a common context.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include "MRJPage.h"
|
||||
#include "MRJSession.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
MRJPage::MRJPage(MRJSession* session, UInt32 documentID, const char* codeBase, const char* archive, Boolean mayScript)
|
||||
: mRefCount(0), mNextPage(NULL), mSession(session), mPageRef(NULL),
|
||||
mDocumentID(documentID), mCodeBase(strdup(codeBase)), mArchive(strdup(archive)), mMayScript(mayScript)
|
||||
{
|
||||
pushPage();
|
||||
|
||||
if (&::JMNewAppletPage != NULL) {
|
||||
OSStatus status = ::JMNewAppletPage(&mPageRef, session->getSessionRef());
|
||||
if (status != noErr) mPageRef = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MRJPage::MRJPage(MRJSession* session, const MRJPageAttributes& attributes)
|
||||
: mRefCount(0), mNextPage(NULL), mSession(session), mPageRef(NULL),
|
||||
mDocumentID(attributes.documentID), mCodeBase(strdup(attributes.codeBase)),
|
||||
mArchive(strdup(attributes.archive)), mMayScript(attributes.mayScript)
|
||||
{
|
||||
pushPage();
|
||||
|
||||
if (&::JMNewAppletPage != NULL) {
|
||||
OSStatus status = ::JMNewAppletPage(&mPageRef, session->getSessionRef());
|
||||
if (status != noErr) mPageRef = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MRJPage::~MRJPage()
|
||||
{
|
||||
popPage();
|
||||
|
||||
if (&::JMDisposeAppletPage != NULL && mPageRef != NULL) {
|
||||
OSStatus status = ::JMDisposeAppletPage(mPageRef);
|
||||
mPageRef = NULL;
|
||||
}
|
||||
|
||||
if (mCodeBase != NULL) {
|
||||
delete[] mCodeBase;
|
||||
mCodeBase = NULL;
|
||||
}
|
||||
|
||||
if (mArchive != NULL) {
|
||||
delete[] mArchive;
|
||||
mArchive = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
UInt16 MRJPage::AddRef()
|
||||
{
|
||||
return (++mRefCount);
|
||||
}
|
||||
|
||||
UInt16 MRJPage::Release()
|
||||
{
|
||||
UInt16 result = --mRefCount;
|
||||
if (result == 0) {
|
||||
delete this;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Boolean MRJPage::createContext(JMAWTContextRef* outContext, const JMAWTContextCallbacks * callbacks, JMClientData data)
|
||||
{
|
||||
OSStatus status = noErr;
|
||||
if (&::JMNewAWTContextInPage != NULL && mPageRef != NULL) {
|
||||
status = ::JMNewAWTContextInPage(outContext, mSession->getSessionRef(), mPageRef, callbacks, data);
|
||||
} else {
|
||||
status = ::JMNewAWTContext(outContext, mSession->getSessionRef(), callbacks, data);
|
||||
}
|
||||
return (status == noErr);
|
||||
}
|
||||
|
||||
static MRJPage* thePageList = NULL;
|
||||
|
||||
MRJPage* MRJPage::getFirstPage()
|
||||
{
|
||||
return thePageList;
|
||||
}
|
||||
|
||||
MRJPage* MRJPage::getNextPage()
|
||||
{
|
||||
return mNextPage;
|
||||
}
|
||||
|
||||
void MRJPage::pushPage()
|
||||
{
|
||||
// put this on the global list of pages.
|
||||
mNextPage = thePageList;
|
||||
thePageList = this;
|
||||
}
|
||||
|
||||
void MRJPage::popPage()
|
||||
{
|
||||
// Remove this page from the global list.
|
||||
MRJPage** link = &thePageList;
|
||||
MRJPage* page = *link;
|
||||
while (page != NULL) {
|
||||
if (page == this) {
|
||||
*link = mNextPage;
|
||||
mNextPage = NULL;
|
||||
break;
|
||||
}
|
||||
link = &page->mNextPage;
|
||||
page = *link;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJPage.h
|
||||
|
||||
Encapsulates the MRJ data structure.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#ifndef __TYPES__
|
||||
#include <Types.h>
|
||||
#endif
|
||||
|
||||
#include "JManager.h"
|
||||
|
||||
// For now.
|
||||
typedef struct OpaqueJMAppletPageRef* JMAppletPageRef;
|
||||
|
||||
class MRJSession;
|
||||
|
||||
struct MRJPageAttributes {
|
||||
UInt32 documentID;
|
||||
const char* codeBase;
|
||||
const char* archive;
|
||||
Boolean mayScript;
|
||||
};
|
||||
|
||||
class MRJPage {
|
||||
public:
|
||||
MRJPage(MRJSession* session, UInt32 documentID, const char* codeBase, const char* archive, Boolean mayScript);
|
||||
MRJPage(MRJSession* session, const MRJPageAttributes& attributes);
|
||||
~MRJPage();
|
||||
|
||||
// Pages are reference counted.
|
||||
UInt16 AddRef(void);
|
||||
UInt16 Release(void);
|
||||
|
||||
JMAppletPageRef getPageRef() { return mPageRef; }
|
||||
|
||||
UInt32 getDocumentID() { return mDocumentID; }
|
||||
const char* getCodeBase() { return mCodeBase; }
|
||||
const char* getArchive() { return mArchive; }
|
||||
Boolean getMayScript() { return mMayScript; }
|
||||
|
||||
// Creating AWTContexts.
|
||||
Boolean createContext(JMAWTContextRef* outContext,
|
||||
const JMAWTContextCallbacks * callbacks,
|
||||
JMClientData data);
|
||||
|
||||
// Accessing the list of instances.
|
||||
static MRJPage* getFirstPage(void);
|
||||
MRJPage* getNextPage(void);
|
||||
|
||||
private:
|
||||
void pushPage();
|
||||
void popPage();
|
||||
|
||||
private:
|
||||
UInt16 mRefCount;
|
||||
MRJPage* mNextPage;
|
||||
MRJSession* mSession;
|
||||
JMAppletPageRef mPageRef;
|
||||
UInt32 mDocumentID;
|
||||
char* mCodeBase;
|
||||
char* mArchive;
|
||||
Boolean mMayScript;
|
||||
};
|
|
@ -0,0 +1,658 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJPlugin.cpp
|
||||
|
||||
XP COM Plugin Implementation.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include "MRJPlugin.h"
|
||||
#include "MRJSession.h"
|
||||
#include "MRJContext.h"
|
||||
#include "MRJFrame.h"
|
||||
#include "MRJConsole.h"
|
||||
|
||||
#include "nsIMalloc.h"
|
||||
#include "nsRepository.h"
|
||||
#include "nsIJVMManager.h"
|
||||
#include "nsIPluginManager2.h"
|
||||
#include "nsIPluginInstancePeer.h"
|
||||
#include "nsIWindowlessPlugInstPeer.h"
|
||||
#include "LiveConnectNativeMethods.h"
|
||||
#include "CSecureJNI2.h"
|
||||
|
||||
extern nsIPluginManager* thePluginManager; // now in badaptor.cpp.
|
||||
extern nsIPlugin* thePlugin;
|
||||
|
||||
nsIPluginManager2* thePluginManager2 = NULL;
|
||||
nsIMalloc* theMemoryAllocator = NULL;
|
||||
|
||||
// Common interface IDs.
|
||||
|
||||
static NS_DEFINE_IID(kIPluginIID, NS_IPLUGIN_IID);
|
||||
static NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIPluginManager2IID, NS_IPLUGINMANAGER2_IID);
|
||||
static NS_DEFINE_IID(kIMallocIID, NS_IMALLOC_IID);
|
||||
static NS_DEFINE_IID(kIJVMManagerIID, NS_IJVMMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIThreadManagerIID, NS_ITHREADMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIRunnableIID, NS_IRUNNABLE_IID);
|
||||
static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID);
|
||||
static NS_DEFINE_IID(kIJVMPluginInstanceIID, NS_IJVMPLUGININSTANCE_IID);
|
||||
static NS_DEFINE_IID(kIWindowlessPluginInstancePeerIID, NS_IWINDOWLESSPLUGININSTANCEPEER_IID);
|
||||
|
||||
#pragma export on
|
||||
|
||||
/* NS_METHOD NP_CreatePlugin(NPIPluginManager* manager, NPIPlugin* *result)
|
||||
{
|
||||
thePluginManager = manager;
|
||||
*result = new MRJPlugin(manager);
|
||||
return nsPluginError_NoError;
|
||||
} */
|
||||
|
||||
nsresult NSGetFactory(const nsCID &classID, nsIFactory **aFactory)
|
||||
{
|
||||
if (classID.Equals(kIPluginIID)) {
|
||||
static MRJPlugin thePlugin;
|
||||
*aFactory = &thePlugin;
|
||||
::thePlugin = &thePlugin;
|
||||
// *aFactory = new MRJPlugin();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
#pragma export off
|
||||
|
||||
extern "C" void cfm_NSShutdownPlugin(void);
|
||||
|
||||
void cfm_NSShutdownPlugin()
|
||||
{
|
||||
if (thePlugin != NULL) {
|
||||
nsrefcnt refs = thePlugin->Release();
|
||||
while (refs > 0 && thePlugin != NULL)
|
||||
refs = thePlugin->Release();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// The MEAT of the plugin.
|
||||
//
|
||||
|
||||
#pragma mark *** MRJPlugin ***
|
||||
|
||||
nsID MRJPlugin::sInterfaceIDs[] = { NS_IPLUGIN_IID, NS_IJVMPLUGIN_IID };
|
||||
|
||||
MRJPlugin::MRJPlugin()
|
||||
: SupportsMixin((nsIJVMPlugin*)this, sInterfaceIDs, sizeof(sInterfaceIDs) / sizeof(nsID)),
|
||||
mManager(NULL), mThreadManager(NULL), mSession(NULL), mConsole(NULL), mIsEnabled(false), mPluginThreadID(0)
|
||||
{
|
||||
}
|
||||
|
||||
MRJPlugin::~MRJPlugin()
|
||||
{
|
||||
// make sure the plugin is no longer visible.
|
||||
::thePlugin = NULL;
|
||||
|
||||
// Release the console.
|
||||
if (mConsole != NULL) {
|
||||
mConsole->Release();
|
||||
mConsole = NULL;
|
||||
}
|
||||
|
||||
// tear down the MRJ session, if it exists.
|
||||
if (mSession != NULL) {
|
||||
delete mSession;
|
||||
mSession = NULL;
|
||||
}
|
||||
|
||||
// Release the manager?
|
||||
if (mManager != NULL) {
|
||||
mManager->Release();
|
||||
mManager = NULL;
|
||||
}
|
||||
|
||||
if (mThreadManager != NULL) {
|
||||
mThreadManager->Release();
|
||||
mThreadManager = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// PCB: Metrowerks pre-processor bug? The following macro won't compile.
|
||||
// NS_IMPL_ISUPPORTS(MRJPlugin, NP_IPLUGIN_IID)
|
||||
|
||||
NS_METHOD MRJPlugin::QueryInterface(const nsIID& aIID, void** instancePtr)
|
||||
{
|
||||
if (aIID.Equals(kIRunnableIID)) {
|
||||
*instancePtr = (void*) (nsIRunnable*) this;
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult result = queryInterface(aIID, instancePtr);
|
||||
if (result == NS_NOINTERFACE) {
|
||||
result = mConsole->queryInterface(aIID, instancePtr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsrefcnt MRJPlugin::AddRef(void) { return addRef(); }
|
||||
nsrefcnt MRJPlugin::Release(void) { return release(); }
|
||||
|
||||
NS_METHOD MRJPlugin::CreateInstance(nsISupports *aOuter, const nsIID& aIID, void **aResult)
|
||||
{
|
||||
if (aIID.Equals(kIPluginInstanceIID) || aIID.Equals(kIJVMPluginInstanceIID)) {
|
||||
if (StartupJVM(NULL) == NS_OK) {
|
||||
MRJPluginInstance* instance = new MRJPluginInstance(this);
|
||||
instance->AddRef(); // if not us, then who will take this burden?
|
||||
*aResult = instance;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPlugin::Initialize(nsISupports* browserInterfaces)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
||||
// try to get a plugin manager.
|
||||
if (thePluginManager == NULL) {
|
||||
result = browserInterfaces->QueryInterface(kIPluginManagerIID, &thePluginManager);
|
||||
if (result != NS_OK || thePluginManager == NULL)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// see if the enhanced plugin manager exists.
|
||||
if (thePluginManager2 == NULL) {
|
||||
result = browserInterfaces->QueryInterface(kIPluginManager2IID, &thePluginManager2);
|
||||
if (result != NS_OK)
|
||||
thePluginManager2 = NULL;
|
||||
}
|
||||
|
||||
// see if IMalloc exists.
|
||||
if (theMemoryAllocator == NULL) {
|
||||
result = browserInterfaces->QueryInterface(kIMallocIID, &theMemoryAllocator);
|
||||
if (result != NS_OK)
|
||||
theMemoryAllocator = NULL;
|
||||
}
|
||||
|
||||
// try to get a JVM manager. we have to be able to run without one.
|
||||
result = browserInterfaces->QueryInterface(kIJVMManagerIID, &mManager);
|
||||
if (result != NS_OK)
|
||||
mManager = NULL;
|
||||
|
||||
// try to get a Thread manager.
|
||||
result = browserInterfaces->QueryInterface(kIThreadManagerIID, &mThreadManager);
|
||||
if (result != NS_OK)
|
||||
mThreadManager = NULL;
|
||||
|
||||
if (mThreadManager != NULL)
|
||||
mThreadManager->GetCurrentThread(&mPluginThreadID);
|
||||
|
||||
// create a console, only if we can register windows.
|
||||
if (thePluginManager2 != NULL) {
|
||||
mConsole = new MRJConsole(this);
|
||||
mConsole->AddRef();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPlugin::GetMIMEDescription(const char* *result)
|
||||
{
|
||||
*result = NPJVM_MIME_TYPE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MRJSession* MRJPlugin::getSession()
|
||||
{
|
||||
StartupJVM(NULL);
|
||||
return mSession;
|
||||
}
|
||||
|
||||
nsIJVMManager* MRJPlugin::getManager()
|
||||
{
|
||||
return mManager;
|
||||
}
|
||||
|
||||
nsIThreadManager* MRJPlugin::getThreadManager()
|
||||
{
|
||||
return mThreadManager;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPlugin::StartupJVM(nsJVMInitArgs* initArgs)
|
||||
{
|
||||
if (mSession == NULL) {
|
||||
// start a session with MRJ.
|
||||
mSession = new MRJSession();
|
||||
if (mSession->getStatus() != noErr) {
|
||||
// how can we signal an error?
|
||||
delete mSession;
|
||||
mSession = NULL;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// Apply the initialization args.
|
||||
if (initArgs != NULL && initArgs->version >= nsJVMInitArgs_Version) {
|
||||
const char* classPathAdditions = initArgs->classpathAdditions;
|
||||
if (classPathAdditions != NULL) {
|
||||
// what format will this be in? UNIX paths, separated by ':' characters.
|
||||
char* paths = new char[1 + strlen(classPathAdditions)];
|
||||
if (paths != NULL) {
|
||||
strcpy(paths, classPathAdditions);
|
||||
char* path = strtok(paths, ":");
|
||||
while (path != NULL) {
|
||||
static char urlPrefix[] = { "file://" };
|
||||
char* fileURL = new char[sizeof(urlPrefix) + strlen(path)];
|
||||
if (fileURL != NULL) {
|
||||
strcat(strcpy(fileURL, urlPrefix), path);
|
||||
mSession->addURLToClassPath(fileURL);
|
||||
delete[] fileURL;
|
||||
}
|
||||
path = strtok(NULL, ":");
|
||||
}
|
||||
delete[] paths;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InitLiveConnectSupport(this);
|
||||
|
||||
#if 0
|
||||
// start our idle thread.
|
||||
if (mThreadManager != NULL) {
|
||||
PRUint32 threadID;
|
||||
mThreadManager->CreateThread(&threadID, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
mIsEnabled = true;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPlugin::ShutdownJVM(PRBool fullShutdown)
|
||||
{
|
||||
if (fullShutdown) {
|
||||
if (mSession != NULL) {
|
||||
delete mSession;
|
||||
mSession = NULL;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPlugin::AddToClassPath(const char* dirPath)
|
||||
{
|
||||
if (mSession != NULL) {
|
||||
mSession->addToClassPath(dirPath);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_JVM_ERROR_WRONG_CLASSES;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPlugin::GetClassPath(const char* *result)
|
||||
{
|
||||
char* classPath = mSession->getProperty("java.class.path");
|
||||
*result = classPath;
|
||||
return (classPath != NULL ? NS_OK : NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
NS_METHOD MRJPlugin::GetJavaWrapper(JNIEnv* env, jint jsobj, jobject *jobj)
|
||||
{
|
||||
// use jsobj as key into a table.
|
||||
// if not in the table, then create a new netscape.javascript.JSObject that references this.
|
||||
*jobj = Wrap_JSObject(env, jsobj);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPlugin::GetJavaVM(JavaVM* *result)
|
||||
{
|
||||
*result = NULL;
|
||||
if (StartupJVM(NULL) == NS_OK) {
|
||||
*result = mSession->getJavaVM();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsrefcnt MRJPlugin::GetJNIEnv(JNIEnv* *result)
|
||||
{
|
||||
JNIEnv* env = NULL;
|
||||
if (StartupJVM(NULL) == NS_OK) {
|
||||
#if 1
|
||||
env = mSession->getCurrentEnv();
|
||||
#else
|
||||
JDK1_1AttachArgs args;
|
||||
JavaVM* vm = mSession->getJavaVM();
|
||||
jint result = vm->AttachCurrentThread(&env, &args);
|
||||
if (result != 0)
|
||||
env = NULL;
|
||||
#endif
|
||||
}
|
||||
*result = env;
|
||||
return 1;
|
||||
}
|
||||
|
||||
nsrefcnt MRJPlugin::ReleaseJNIEnv(JNIEnv* env)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPlugin::CreateSecureEnv(JNIEnv* proxyEnv, nsISecureJNI2* *outSecureEnv)
|
||||
{
|
||||
// Need to spawn a new JVM communication thread here.
|
||||
NS_DEFINE_IID(kISecureJNI2IID, NS_ISECUREJNI2_IID);
|
||||
return CSecureJNI2::Create(NULL, this, proxyEnv, kISecureJNI2IID, (void**)outSecureEnv);
|
||||
}
|
||||
|
||||
NS_METHOD MRJPlugin::SpendTime(PRUint32 timeMillis)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
// Only do this if there aren't any plugin instances.
|
||||
// if (true || MRJPluginInstance::getInstances() == NULL) {
|
||||
result = StartupJVM(NULL);
|
||||
if (result == NS_OK)
|
||||
mSession->idle(timeMillis);
|
||||
// }
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPlugin::Run()
|
||||
{
|
||||
while (mSession != NULL) {
|
||||
mSession->idle();
|
||||
mThreadManager->Sleep();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MRJPluginInstance* MRJPlugin::getPluginInstance(jobject applet)
|
||||
{
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
MRJPluginInstance* instance = MRJPluginInstance::getInstances();
|
||||
while (instance != NULL) {
|
||||
jobject object = NULL;
|
||||
if (instance->GetJavaObject(&object) == NS_OK && env->IsSameObject(applet, object)) {
|
||||
instance->AddRef();
|
||||
return instance;
|
||||
}
|
||||
instance = instance->getNextInstance();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MRJPluginInstance* MRJPlugin::getPluginInstance(JNIEnv* jenv)
|
||||
{
|
||||
// Apple will provide an API that maps a JNIEnv to an JMAWTContextRef. We can map this to the MRJContext/Applet/Instance.
|
||||
MRJPluginInstance* instance = MRJPluginInstance::getInstances();
|
||||
if (&::JMJNIToAWTContext != NULL) {
|
||||
JMAWTContextRef contextRef = ::JMJNIToAWTContext(mSession->getSessionRef(), jenv);
|
||||
if (contextRef != NULL) {
|
||||
while (instance != NULL) {
|
||||
if (instance->getContext()->getContextRef() == contextRef) {
|
||||
instance->AddRef();
|
||||
return instance;
|
||||
}
|
||||
instance = instance->getNextInstance();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (instance != NULL) {
|
||||
instance->AddRef();
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Boolean MRJPlugin::inPluginThread()
|
||||
{
|
||||
PRUint32 currentThreadID = -1;
|
||||
if (mThreadManager != NULL)
|
||||
mThreadManager->GetCurrentThread(¤tThreadID);
|
||||
return (mPluginThreadID == currentThreadID);
|
||||
}
|
||||
|
||||
#pragma mark *** MRJPluginInstance ***
|
||||
|
||||
NS_METHOD MRJPluginInstance::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
return queryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
nsrefcnt MRJPluginInstance::AddRef() { return addRef(); }
|
||||
nsrefcnt MRJPluginInstance::Release() { return release(); }
|
||||
|
||||
nsID MRJPluginInstance::sInterfaceIDs[] = { NS_IPLUGININSTANCE_IID, NS_IJVMPLUGININSTANCE_IID };
|
||||
|
||||
MRJPluginInstance::MRJPluginInstance(MRJPlugin* plugin)
|
||||
: SupportsMixin(this, sInterfaceIDs, sizeof(sInterfaceIDs) / sizeof(nsID)),
|
||||
mPeer(NULL), mWindowlessPeer(NULL),
|
||||
mPlugin(plugin), mSession(plugin->getSession()),
|
||||
mContext(NULL), mApplet(NULL),
|
||||
mNext(NULL)
|
||||
{
|
||||
// add this instance to the instance list.
|
||||
pushInstance();
|
||||
|
||||
// Tell the plugin we are retaining a reference.
|
||||
mPlugin->AddRef();
|
||||
}
|
||||
|
||||
MRJPluginInstance::~MRJPluginInstance()
|
||||
{
|
||||
// Remove this instance from the global list.
|
||||
popInstance();
|
||||
|
||||
if (mContext != NULL) {
|
||||
delete mContext;
|
||||
mContext = NULL;
|
||||
}
|
||||
|
||||
if (mPlugin != NULL) {
|
||||
mPlugin->Release();
|
||||
mPlugin = NULL;
|
||||
}
|
||||
|
||||
if (mWindowlessPeer != NULL) {
|
||||
mWindowlessPeer->Release();
|
||||
mWindowlessPeer = NULL;
|
||||
}
|
||||
|
||||
if (mPeer != NULL) {
|
||||
mPeer->Release();
|
||||
mPeer = NULL;
|
||||
}
|
||||
|
||||
if (mApplet != NULL) {
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
env->DeleteGlobalRef(mApplet);
|
||||
mApplet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD MRJPluginInstance::Initialize(nsIPluginInstancePeer* peer)
|
||||
{
|
||||
// Tell the peer we are retaining a reference.
|
||||
mPeer = peer;
|
||||
mPeer->AddRef();
|
||||
|
||||
// See if we have a windowless peer.
|
||||
nsresult result = mPeer->QueryInterface(kIWindowlessPluginInstancePeerIID, &mWindowlessPeer);
|
||||
if (result != NS_OK) mWindowlessPeer = NULL;
|
||||
|
||||
// create a context for the applet we will run.
|
||||
mContext = new MRJContext(mSession, this);
|
||||
|
||||
mContext->processAppletTag();
|
||||
mContext->createContext();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPluginInstance::GetPeer(nsIPluginInstancePeer* *result)
|
||||
{
|
||||
mPeer->AddRef();
|
||||
*result = mPeer;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPluginInstance::Start()
|
||||
{
|
||||
// Take this moment to show the applet's frames (if any).
|
||||
mContext->showFrames();
|
||||
|
||||
mContext->resumeApplet();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPluginInstance::Stop()
|
||||
{
|
||||
// Take this moment to hide the applet's frames.
|
||||
mContext->hideFrames();
|
||||
|
||||
mContext->suspendApplet();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPluginInstance::Destroy()
|
||||
{
|
||||
// Release();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/** FIXME: Need an intelligent way to track changes to the NPPluginWindow. */
|
||||
|
||||
NS_METHOD MRJPluginInstance::SetWindow(nsPluginWindow* pluginWindow)
|
||||
{
|
||||
mContext->setWindow(pluginWindow);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPluginInstance::HandleEvent(nsPluginEvent* pluginEvent, PRBool* eventHandled)
|
||||
{
|
||||
*eventHandled = PR_TRUE;
|
||||
|
||||
if (pluginEvent != NULL) {
|
||||
EventRecord* event = pluginEvent->event;
|
||||
|
||||
// Check for clipping changes.
|
||||
if (event->what == nsPluginEventType_ClippingChangedEvent) {
|
||||
mContext->setClipping(RgnHandle(event->message));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Check for coordinate system changes.
|
||||
// visibilityChanged = mContext->inspectWindow();
|
||||
// assume the browser will generate the correct update events?
|
||||
if (mContext->inspectWindow() && mWindowlessPeer != NULL)
|
||||
mWindowlessPeer->ForceRedraw();
|
||||
|
||||
if (event->what == nullEvent) {
|
||||
// Give MRJ another quantum of time.
|
||||
mSession->idle(kDefaultJMTime); // now SpendTime does this.
|
||||
} else {
|
||||
MRJFrame* frame = mContext->findFrame(WindowRef(pluginEvent->window));
|
||||
if (frame != NULL) {
|
||||
switch (event->what) {
|
||||
case nsPluginEventType_GetFocusEvent:
|
||||
frame->focusEvent(true);
|
||||
break;
|
||||
|
||||
case nsPluginEventType_LoseFocusEvent:
|
||||
frame->focusEvent(false);
|
||||
break;
|
||||
|
||||
case nsPluginEventType_AdjustCursorEvent:
|
||||
frame->idle(event->modifiers);
|
||||
break;
|
||||
|
||||
case nsPluginEventType_MenuCommandEvent:
|
||||
frame->menuSelected(event->message, event->modifiers);
|
||||
break;
|
||||
|
||||
default:
|
||||
*eventHandled = frame->handleEvent(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD MRJPluginInstance::GetJavaObject(jobject *result)
|
||||
{
|
||||
if (mApplet == NULL) {
|
||||
jobject applet = mContext->getApplet();
|
||||
JNIEnv* env = mSession->getCurrentEnv();
|
||||
mApplet = env->NewGlobalRef(applet);
|
||||
}
|
||||
*result = mApplet;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Accessing the list of instances.
|
||||
|
||||
static MRJPluginInstance* theInstances = NULL;
|
||||
|
||||
void MRJPluginInstance::pushInstance()
|
||||
{
|
||||
mNext = theInstances;
|
||||
theInstances = this;
|
||||
}
|
||||
|
||||
void MRJPluginInstance::popInstance()
|
||||
{
|
||||
MRJPluginInstance** link = &theInstances;
|
||||
MRJPluginInstance* instance = *link;
|
||||
while (instance != NULL) {
|
||||
if (instance == this) {
|
||||
*link = mNext;
|
||||
mNext = NULL;
|
||||
break;
|
||||
}
|
||||
link = &instance->mNext;
|
||||
instance = *link;
|
||||
}
|
||||
}
|
||||
|
||||
MRJPluginInstance* MRJPluginInstance::getInstances()
|
||||
{
|
||||
return theInstances;
|
||||
}
|
||||
|
||||
MRJPluginInstance* MRJPluginInstance::getNextInstance()
|
||||
{
|
||||
return mNext;
|
||||
}
|
||||
|
||||
MRJContext* MRJPluginInstance::getContext()
|
||||
{
|
||||
return mContext;
|
||||
}
|
||||
|
||||
MRJSession* MRJPluginInstance::getSession()
|
||||
{
|
||||
return mSession;
|
||||
}
|
|
@ -0,0 +1,330 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJPlugin.h
|
||||
|
||||
MRJPlugin encapsulates the global state of the MRJ plugin as a single COM object.
|
||||
MRJPluginInstance represents an instance of the MRJ plugin.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "nsIJVMPlugin.h"
|
||||
#include "nsIThreadManager.h"
|
||||
#include "nsIJVMPluginInstance.h"
|
||||
#include "SupportsMixin.h"
|
||||
|
||||
class MRJPlugin;
|
||||
class MRJPluginInstance;
|
||||
class MRJSession;
|
||||
class MRJContext;
|
||||
class MRJConsole;
|
||||
|
||||
class nsIJVMManager;
|
||||
|
||||
class MRJPlugin : public nsIJVMPlugin, public nsIRunnable,
|
||||
public SupportsMixin {
|
||||
public:
|
||||
MRJPlugin();
|
||||
virtual ~MRJPlugin();
|
||||
|
||||
// Currently, this is a singleton, statically allocated object.
|
||||
void operator delete(void* ptr) {}
|
||||
|
||||
// NS_DECL_ISUPPORTS
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
|
||||
// The Release method on NPIPlugin corresponds to NPP_Shutdown.
|
||||
|
||||
// The old NPP_New call has been factored into two plugin instance methods:
|
||||
//
|
||||
// NewInstance -- called once, after the plugin instance is created. This
|
||||
// method is used to initialize the new plugin instance (although the actual
|
||||
// plugin instance object will be created by the plugin manager).
|
||||
//
|
||||
// NPIPluginInstance::Start -- called when the plugin instance is to be
|
||||
// started. This happens in two circumstances: (1) after the plugin instance
|
||||
// is first initialized, and (2) after a plugin instance is returned to
|
||||
// (e.g. by going back in the window history) after previously being stopped
|
||||
// by the Stop method.
|
||||
|
||||
// nsIFactory Methods.
|
||||
|
||||
NS_IMETHOD
|
||||
CreateInstance(nsISupports *aOuter, const nsIID& aIID, void **aResult);
|
||||
|
||||
NS_IMETHOD
|
||||
LockFactory(PRBool aLock) { return NS_ERROR_FAILURE; }
|
||||
|
||||
// nsIPlugin Methods.
|
||||
|
||||
// This call initializes the plugin and will be called before any new
|
||||
// instances are created. It is passed browserInterfaces on which QueryInterface
|
||||
// may be used to obtain an nsIPluginManager, and other interfaces.
|
||||
NS_IMETHOD
|
||||
Initialize(nsISupports* browserInterfaces);
|
||||
|
||||
// (Corresponds to NPP_Shutdown.)
|
||||
// Called when the browser is done with the plugin factory, or when
|
||||
// the plugin is disabled by the user.
|
||||
NS_IMETHOD
|
||||
Shutdown(void) { return NS_OK; }
|
||||
|
||||
// (Corresponds to NPP_GetMIMEDescription.)
|
||||
NS_IMETHOD
|
||||
GetMIMEDescription(const char* *result);
|
||||
|
||||
// (Corresponds to NPP_GetValue.)
|
||||
NS_IMETHOD
|
||||
GetValue(nsPluginVariable variable, void *value)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// (Corresponds to NPP_SetValue.)
|
||||
NS_IMETHOD
|
||||
SetValue(nsPluginVariable variable, void *value)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// JVM Plugin Methods.
|
||||
|
||||
// This method us used to start the Java virtual machine.
|
||||
// It sets up any global state necessary to host Java programs.
|
||||
// Note that calling this method is distinctly separate from
|
||||
// initializing the nsIJVMPlugin object (done by the Initialize
|
||||
// method).
|
||||
NS_IMETHOD
|
||||
StartupJVM(nsJVMInitArgs* initargs);
|
||||
|
||||
// This method us used to stop the Java virtual machine.
|
||||
// It tears down any global state necessary to host Java programs.
|
||||
// The fullShutdown flag specifies whether the browser is quitting
|
||||
// (PR_TRUE) or simply whether the JVM is being shut down (PR_FALSE).
|
||||
NS_IMETHOD
|
||||
ShutdownJVM(PRBool fullShutdown);
|
||||
|
||||
// Causes the JVM to append a new directory to its classpath.
|
||||
// If the JVM doesn't support this operation, an error is returned.
|
||||
NS_IMETHOD
|
||||
AddToClassPath(const char* dirPath);
|
||||
|
||||
// Causes the JVM to remove a directory from its classpath.
|
||||
// If the JVM doesn't support this operation, an error is returned.
|
||||
NS_IMETHOD
|
||||
RemoveFromClassPath(const char* dirPath)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Returns the current classpath in use by the JVM.
|
||||
NS_IMETHOD
|
||||
GetClassPath(const char* *result);
|
||||
|
||||
NS_IMETHOD
|
||||
GetJavaWrapper(JNIEnv* env, jint jsobj, jobject *jobj);
|
||||
|
||||
NS_IMETHOD
|
||||
GetJavaVM(JavaVM* *result);
|
||||
|
||||
// nsIJNIPlugin Methods.
|
||||
|
||||
// Find or create a JNIEnv for the current thread.
|
||||
// Returns NULL if an error occurs.
|
||||
NS_IMETHOD_(nsrefcnt)
|
||||
GetJNIEnv(JNIEnv* *result);
|
||||
|
||||
// This method must be called when the caller is done using the JNIEnv.
|
||||
// This decrements a refcount associated with it may free it.
|
||||
NS_IMETHOD_(nsrefcnt)
|
||||
ReleaseJNIEnv(JNIEnv* env);
|
||||
|
||||
/**
|
||||
* This creates a new secure communication channel with Java. The second parameter,
|
||||
* nativeEnv, if non-NULL, will be the actual thread for Java communication.
|
||||
* Otherwise, a new thread should be created.
|
||||
* @param proxyEnv the env to be used by all clients on the browser side
|
||||
* @return outSecureEnv the secure environment used by the proxyEnv
|
||||
*/
|
||||
NS_IMETHOD
|
||||
CreateSecureEnv(JNIEnv* proxyEnv, nsISecureJNI2* *outSecureEnv);
|
||||
|
||||
/**
|
||||
* Gives time to the JVM from the main event loop of the browser. This is
|
||||
* necessary when there aren't any plugin instances around, but Java threads exist.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
SpendTime(PRUint32 timeMillis);
|
||||
|
||||
/**
|
||||
* The Run method gives time to the JVM periodically. This makes SpendTIme() obsolete.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Run();
|
||||
|
||||
// NON-INTERFACE methods, for internal use only.
|
||||
|
||||
MRJSession* getSession();
|
||||
nsIJVMManager* getManager();
|
||||
nsIThreadManager* getThreadManager();
|
||||
|
||||
MRJPluginInstance* getPluginInstance(jobject applet);
|
||||
MRJPluginInstance* getPluginInstance(JNIEnv* jenv);
|
||||
|
||||
Boolean inPluginThread();
|
||||
|
||||
private:
|
||||
nsIJVMManager* mManager;
|
||||
nsIThreadManager* mThreadManager;
|
||||
MRJSession* mSession;
|
||||
MRJConsole* mConsole;
|
||||
PRUint32 mPluginThreadID;
|
||||
Boolean mIsEnabled;
|
||||
|
||||
// support for nsISupports.
|
||||
static nsID sInterfaceIDs[];
|
||||
};
|
||||
|
||||
class MRJPluginInstance : public nsIJVMPluginInstance,
|
||||
private SupportsMixin {
|
||||
public:
|
||||
MRJPluginInstance(MRJPlugin* plugin);
|
||||
virtual ~MRJPluginInstance();
|
||||
|
||||
// NS_DECL_ISUPPORTS
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
|
||||
// (Corresponds to NPP_HandleEvent.)
|
||||
NS_IMETHOD
|
||||
HandleEvent(nsPluginEvent* event, PRBool* handled);
|
||||
|
||||
// The Release method on NPIPluginInstance corresponds to NPP_Destroy.
|
||||
|
||||
NS_IMETHOD
|
||||
Initialize(nsIPluginInstancePeer* peer);
|
||||
|
||||
// Required backpointer to the peer.
|
||||
NS_IMETHOD
|
||||
GetPeer(nsIPluginInstancePeer* *result);
|
||||
|
||||
// See comment for nsIPlugin::CreateInstance, above.
|
||||
NS_IMETHOD
|
||||
Start(void);
|
||||
|
||||
// The old NPP_Destroy call has been factored into two plugin instance
|
||||
// methods:
|
||||
//
|
||||
// Stop -- called when the plugin instance is to be stopped (e.g. by
|
||||
// displaying another plugin manager window, causing the page containing
|
||||
// the plugin to become removed from the display).
|
||||
//
|
||||
// Destroy -- called once, before the plugin instance peer is to be
|
||||
// destroyed. This method is used to destroy the plugin instance.
|
||||
|
||||
NS_IMETHOD
|
||||
Stop(void);
|
||||
|
||||
NS_IMETHOD
|
||||
Destroy(void);
|
||||
|
||||
// (Corresponds to NPP_SetWindow.)
|
||||
NS_IMETHOD
|
||||
SetWindow(nsPluginWindow* window);
|
||||
|
||||
// (Corresponds to NPP_NewStream.)
|
||||
NS_IMETHOD
|
||||
NewStream(nsIPluginStreamPeer* peer, nsIPluginStream* *result)
|
||||
{
|
||||
*result = NULL;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// (Corresponds to NPP_Print.)
|
||||
NS_IMETHOD
|
||||
Print(nsPluginPrint* platformPrint)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// (Corresponds to NPP_URLNotify.)
|
||||
NS_IMETHOD
|
||||
URLNotify(const char* url, const char* target,
|
||||
nsPluginReason reason, void* notifyData)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of a variable associated with the plugin instance.
|
||||
*
|
||||
* @param variable - the plugin instance variable to get
|
||||
* @param value - the address of where to store the resulting value
|
||||
* @result - NS_OK if this operation was successful
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetValue(nsPluginInstanceVariable variable, void *value)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// nsIJVMPluginInstance methods.
|
||||
|
||||
// This method is called when LiveConnect wants to find the Java object
|
||||
// associated with this plugin instance, e.g. the Applet or JavaBean object.
|
||||
NS_IMETHOD
|
||||
GetJavaObject(jobject *result);
|
||||
|
||||
NS_IMETHOD
|
||||
GetText(const char* *result)
|
||||
{
|
||||
*result = NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Accessing the list of instances.
|
||||
static MRJPluginInstance* getInstances(void);
|
||||
MRJPluginInstance* getNextInstance(void);
|
||||
|
||||
MRJContext* getContext(void);
|
||||
MRJSession* getSession(void);
|
||||
|
||||
private:
|
||||
void pushInstance();
|
||||
void popInstance();
|
||||
|
||||
private:
|
||||
nsIPluginInstancePeer* mPeer;
|
||||
nsIWindowlessPluginInstancePeer* mWindowlessPeer;
|
||||
MRJPlugin* mPlugin;
|
||||
MRJSession* mSession;
|
||||
MRJContext* mContext;
|
||||
jobject mApplet;
|
||||
|
||||
// maintain a list of instances.
|
||||
MRJPluginInstance* mNext;
|
||||
|
||||
// support for nsISupports.
|
||||
static nsID sInterfaceIDs[];
|
||||
};
|
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJSession.cpp
|
||||
|
||||
Encapsulates a session with the MacOS Runtime for Java.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include "MRJSession.h"
|
||||
#include "MRJContext.h"
|
||||
#include "MRJConsole.h"
|
||||
#include "MRJMonitor.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <Memory.h>
|
||||
#include <Files.h>
|
||||
#include <Dialogs.h>
|
||||
#include <Appearance.h>
|
||||
|
||||
extern MRJConsole* theConsole;
|
||||
|
||||
static Boolean appearanceManagerExists()
|
||||
{
|
||||
long response = 0;
|
||||
return (Gestalt(gestaltAppearanceAttr, &response) == noErr && (response & (1 << gestaltAppearanceExists)));
|
||||
}
|
||||
|
||||
static void debug_out(StringPtr stream, const void *message, UInt32 messageLengthInBytes)
|
||||
{
|
||||
Str255 pmsg;
|
||||
pmsg[0] = messageLengthInBytes;
|
||||
::BlockMoveData(message, &pmsg[1], pmsg[0]);
|
||||
|
||||
// why not display this using the Appearance Manager's wizzy new alert?
|
||||
if (appearanceManagerExists()) {
|
||||
static AlertStdAlertParamRec params = {
|
||||
false, // Boolean movable; /* Make alert movable modal */
|
||||
false, // Boolean helpButton; /* Is there a help button? */
|
||||
NULL, // ModalFilterUPP filterProc; /* Event filter */
|
||||
"\pOK", // StringPtr defaultText; /* Text for button in OK position */
|
||||
NULL, // StringPtr cancelText; /* Text for button in cancel position */
|
||||
NULL, // StringPtr otherText; /* Text for button in left position */
|
||||
1, // SInt16 defaultButton; /* Which button behaves as the default */
|
||||
0, // SInt16 cancelButton; /* Which one behaves as cancel (can be 0) */
|
||||
kWindowDefaultPosition
|
||||
// UInt16 position; /* Position (kWindowDefaultPosition in this case */
|
||||
/* equals kWindowAlertPositionParentWindowScreen) */
|
||||
};
|
||||
SInt16 itemHit = 0;
|
||||
OSErr result = ::StandardAlert(kAlertPlainAlert, stream, pmsg, ¶ms, &itemHit);
|
||||
} else {
|
||||
::DebugStr(pmsg);
|
||||
}
|
||||
}
|
||||
|
||||
static void java_stdout(JMSessionRef session, const void *message, SInt32 messageLengthInBytes)
|
||||
{
|
||||
// if (theConsole != NULL)
|
||||
// theConsole->write(message, messageLengthInBytes);
|
||||
/* else
|
||||
debug_out("\pSystem.out:", message, messageLengthInBytes); */
|
||||
}
|
||||
|
||||
static void java_stderr(JMSessionRef session, const void *message, SInt32 messageLengthInBytes)
|
||||
{
|
||||
// if (theConsole != NULL)
|
||||
// theConsole->write(message, messageLengthInBytes);
|
||||
/* else
|
||||
debug_out("\pSystem.err:", message, messageLengthInBytes); */
|
||||
}
|
||||
|
||||
static SInt32 java_stdin(JMSessionRef session, void *buffer, SInt32 maxBufferLength)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static Boolean java_exit(JMSessionRef session, SInt32 status)
|
||||
{
|
||||
return false; /* not allowed in a plugin. */
|
||||
}
|
||||
|
||||
static Boolean java_authenticate(JMSessionRef session, const char *url, const char *realm, char userName[255], char password[255])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void java_lowmem(JMSessionRef session)
|
||||
{
|
||||
/* can ask Netscape to purge some memory. */
|
||||
// NPN_MemFlush(512 * 1024);
|
||||
}
|
||||
|
||||
MRJSession::MRJSession()
|
||||
: mSession(NULL), mStatus(noErr), mMainEnv(NULL), mFirst(NULL), mLast(NULL), mMessageMonitor(NULL), mLockCount(0)
|
||||
{
|
||||
// Make sure JManager exists.
|
||||
if (&::JMGetVersion != NULL && ::JMGetVersion() >= kJMVersion) {
|
||||
static JMSessionCallbacks callbacks = {
|
||||
kJMVersion, /* should be set to kJMVersion */
|
||||
&java_stdout, /* JM will route "stdout" to this function. */
|
||||
&java_stderr, /* JM will route "stderr" to this function. */
|
||||
&java_stdin, /* read from console - can be nil for default behavior (no console IO) */
|
||||
&java_exit, /* handle System.exit(int) requests */
|
||||
&java_authenticate, /* present basic authentication dialog */
|
||||
&java_lowmem /* Low Memory notification Proc */
|
||||
};
|
||||
|
||||
mStatus = ::JMOpenSession(&mSession, eJManager2Defaults, eCheckRemoteCode,
|
||||
&callbacks, kTextEncodingMacRoman, NULL);
|
||||
|
||||
// capture the main environment, so it can be distinguished from true Java threads.
|
||||
if (mStatus == noErr) mMainEnv = ::JMGetCurrentEnv(mSession);
|
||||
|
||||
// create a monitor for the message queue to unblock Java threads.
|
||||
mMessageMonitor = new MRJMonitor(this);
|
||||
} else {
|
||||
mStatus = kJMVersionError;
|
||||
}
|
||||
}
|
||||
|
||||
MRJSession::~MRJSession()
|
||||
{
|
||||
if (mMessageMonitor != NULL) {
|
||||
mMessageMonitor->notifyAll();
|
||||
delete mMessageMonitor;
|
||||
}
|
||||
|
||||
if (mSession != NULL) {
|
||||
mStatus = ::JMCloseSession(mSession);
|
||||
mSession = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
JMSessionRef MRJSession::getSessionRef()
|
||||
{
|
||||
return mSession;
|
||||
}
|
||||
|
||||
JNIEnv* MRJSession::getCurrentEnv()
|
||||
{
|
||||
return ::JMGetCurrentEnv(mSession);
|
||||
}
|
||||
|
||||
JNIEnv* MRJSession::getMainEnv()
|
||||
{
|
||||
return mMainEnv;
|
||||
}
|
||||
|
||||
JavaVM* MRJSession::getJavaVM()
|
||||
{
|
||||
JNIEnv* env = ::JMGetCurrentEnv(mSession);
|
||||
JavaVM* vm = NULL;
|
||||
env->GetJavaVM(&vm);
|
||||
return vm;
|
||||
}
|
||||
|
||||
Boolean MRJSession::onMainThread()
|
||||
{
|
||||
JNIEnv* env = ::JMGetCurrentEnv(mSession);
|
||||
return (env == mMainEnv);
|
||||
}
|
||||
|
||||
inline StringPtr c2p(const char* cstr, StringPtr pstr)
|
||||
{
|
||||
pstr[0] = (unsigned char)strlen(cstr);
|
||||
::BlockMoveData(cstr, pstr + 1, pstr[0]);
|
||||
return pstr;
|
||||
}
|
||||
|
||||
Boolean MRJSession::addToClassPath(const char* dirPath)
|
||||
{
|
||||
// Need to convert the path into an FSSpec, and add it MRJ's class path.
|
||||
Str255 path;
|
||||
FSSpec pathSpec;
|
||||
OSStatus status = ::FSMakeFSSpec(0, 0, c2p(dirPath, path), &pathSpec);
|
||||
if (status == noErr)
|
||||
status = ::JMAddToClassPath(mSession, &pathSpec);
|
||||
return (status == noErr);
|
||||
}
|
||||
|
||||
Boolean MRJSession::addURLToClassPath(const char* fileURL)
|
||||
{
|
||||
OSStatus status = noErr;
|
||||
// Need to convert the URL into an FSSpec, and add it MRJ's class path.
|
||||
JMTextRef urlRef = NULL;
|
||||
status = ::JMNewTextRef(mSession, &urlRef, kTextEncodingMacRoman, fileURL, strlen(fileURL));
|
||||
if (status == noErr) {
|
||||
FSSpec pathSpec;
|
||||
status = ::JMURLToFSS(mSession, urlRef, &pathSpec);
|
||||
if (status == noErr)
|
||||
status = ::JMAddToClassPath(mSession, &pathSpec);
|
||||
::JMDisposeTextRef(urlRef);
|
||||
}
|
||||
|
||||
return (status == noErr);
|
||||
}
|
||||
|
||||
char* MRJSession::getProperty(const char* propertyName)
|
||||
{
|
||||
char* result = NULL;
|
||||
OSStatus status = noErr;
|
||||
JMTextRef nameRef = NULL, valueRef = NULL;
|
||||
status = ::JMNewTextRef(mSession, &nameRef, kTextEncodingMacRoman, propertyName, strlen(propertyName));
|
||||
if (status == noErr) {
|
||||
status = ::JMGetSessionProperty(mSession, nameRef, &valueRef);
|
||||
::JMDisposeTextRef(nameRef);
|
||||
if (status == noErr && valueRef != NULL) {
|
||||
UInt32 valueLength = 0;
|
||||
status = ::JMGetTextLengthInBytes(valueRef, kTextEncodingMacRoman, &valueLength);
|
||||
if (status == noErr) {
|
||||
result = new char[valueLength + 1];
|
||||
if (result != NULL) {
|
||||
UInt32 actualLength;
|
||||
status = ::JMGetTextBytes(valueRef, kTextEncodingMacRoman, result, valueLength, &actualLength);
|
||||
result[valueLength] = '\0';
|
||||
}
|
||||
::JMDisposeTextRef(valueRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MRJSession::setStatus(OSStatus status)
|
||||
{
|
||||
mStatus = status;
|
||||
}
|
||||
|
||||
OSStatus MRJSession::getStatus()
|
||||
{
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
void MRJSession::idle(UInt32 milliseconds)
|
||||
{
|
||||
// Each call to idle processes a single message.
|
||||
dispatchMessage();
|
||||
|
||||
// Guard against entering the VM multiple times.
|
||||
if (mLockCount == 0) {
|
||||
lock();
|
||||
mStatus = ::JMIdle(mSession, milliseconds);
|
||||
unlock();
|
||||
}
|
||||
#if 0
|
||||
else {
|
||||
// sleep the current thread.
|
||||
JNIEnv* env = getCurrentEnv();
|
||||
jclass threadClass = env->FindClass("java/lang/Thread");
|
||||
if (threadClass != NULL) {
|
||||
jmethodID sleepMethod = env->GetStaticMethodID(threadClass, "sleep", "(J)V");
|
||||
env->CallStaticVoidMethod(threadClass, sleepMethod, jlong(milliseconds));
|
||||
env->DeleteLocalRef(threadClass);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MRJSession::sendMessage(NativeMessage* message)
|
||||
{
|
||||
// can't block the main env, otherwise messages will never be processed!
|
||||
if (onMainThread()) {
|
||||
message->execute();
|
||||
} else {
|
||||
postMessage(message);
|
||||
mMessageMonitor->wait();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a message on the queue.
|
||||
*/
|
||||
void MRJSession::postMessage(NativeMessage* message)
|
||||
{
|
||||
if (mFirst == NULL) {
|
||||
mFirst = mLast = message;
|
||||
} else {
|
||||
mLast->setNext(message);
|
||||
mLast = message;
|
||||
}
|
||||
message->setNext(NULL);
|
||||
}
|
||||
|
||||
void MRJSession::dispatchMessage()
|
||||
{
|
||||
if (mFirst != NULL) {
|
||||
NativeMessage* message = mFirst;
|
||||
mFirst = message->getNext();
|
||||
if (mFirst == NULL) mLast = NULL;
|
||||
|
||||
message->setNext(NULL);
|
||||
message->execute();
|
||||
mMessageMonitor->notify();
|
||||
}
|
||||
}
|
||||
|
||||
void MRJSession::lock()
|
||||
{
|
||||
++mLockCount;
|
||||
}
|
||||
|
||||
void MRJSession::unlock()
|
||||
{
|
||||
--mLockCount;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
MRJSession.h
|
||||
|
||||
Encapsulates a session with the MacOS Runtime for Java.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jni.h"
|
||||
#include "JManager.h"
|
||||
|
||||
class NativeMessage {
|
||||
public:
|
||||
NativeMessage() : mNext(NULL) {}
|
||||
|
||||
virtual void execute() = 0;
|
||||
|
||||
void setNext(NativeMessage* next) { mNext = next; }
|
||||
NativeMessage* getNext() { return mNext; }
|
||||
|
||||
private:
|
||||
NativeMessage* mNext;
|
||||
};
|
||||
|
||||
// FIXME: need an interface for setting security options, etc.
|
||||
|
||||
class MRJContext;
|
||||
class Monitor;
|
||||
|
||||
class MRJSession {
|
||||
public:
|
||||
MRJSession();
|
||||
virtual ~MRJSession();
|
||||
|
||||
JMSessionRef getSessionRef();
|
||||
|
||||
JNIEnv* getCurrentEnv();
|
||||
JNIEnv* getMainEnv();
|
||||
JavaVM* getJavaVM();
|
||||
|
||||
Boolean onMainThread();
|
||||
|
||||
Boolean addToClassPath(const char* dirPath);
|
||||
Boolean addURLToClassPath(const char* fileURL);
|
||||
|
||||
char* getProperty(const char* propertyName);
|
||||
|
||||
void setStatus(OSStatus status);
|
||||
OSStatus getStatus();
|
||||
|
||||
void idle(UInt32 milliseconds = kDefaultJMTime);
|
||||
|
||||
void sendMessage(NativeMessage* message);
|
||||
|
||||
/**
|
||||
* Used to prevent reentering the VM.
|
||||
*/
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
private:
|
||||
void postMessage(NativeMessage* message);
|
||||
void dispatchMessage();
|
||||
|
||||
private:
|
||||
JMSessionRef mSession;
|
||||
OSStatus mStatus;
|
||||
|
||||
JNIEnv* mMainEnv;
|
||||
|
||||
// Message queue.
|
||||
NativeMessage* mFirst;
|
||||
NativeMessage* mLast;
|
||||
Monitor* mMessageMonitor;
|
||||
|
||||
UInt32 mLockCount;
|
||||
};
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
Monitor.h
|
||||
|
||||
Abstract class representing monitors.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class Monitor {
|
||||
public:
|
||||
virtual ~Monitor() {}
|
||||
|
||||
virtual void enter() = 0;
|
||||
virtual void exit() = 0;
|
||||
|
||||
virtual void wait() = 0;
|
||||
virtual void wait(long long millis) = 0;
|
||||
virtual void notify() = 0;
|
||||
virtual void notifyAll() = 0;
|
||||
};
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
NativeMonitor.cpp
|
||||
|
||||
Provides a C++ interface to native monitors.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include "NativeMonitor.h"
|
||||
#include "MRJSession.h"
|
||||
#include "nsIThreadManager.h"
|
||||
|
||||
NativeMonitor::NativeMonitor(MRJSession* session, nsIThreadManager* manager, void* address)
|
||||
: mSession(session), mManager(manager), mAddress(address)
|
||||
{
|
||||
if (address == NULL)
|
||||
mAddress = this;
|
||||
}
|
||||
|
||||
NativeMonitor::~NativeMonitor() {}
|
||||
|
||||
void NativeMonitor::enter()
|
||||
{
|
||||
mManager->EnterMonitor(mAddress);
|
||||
}
|
||||
|
||||
void NativeMonitor::exit()
|
||||
{
|
||||
mManager->ExitMonitor(mAddress);
|
||||
}
|
||||
|
||||
void NativeMonitor::wait()
|
||||
{
|
||||
// this is weird hackery, but we don't want to let the VM be reentered while we wait on a native monitor.
|
||||
Boolean inJavaThread = (mSession->getMainEnv() != mSession->getCurrentEnv());
|
||||
if (inJavaThread)
|
||||
mSession->lock();
|
||||
|
||||
if (mManager->EnterMonitor(mAddress) == NS_OK) {
|
||||
mManager->Wait(mAddress);
|
||||
mManager->ExitMonitor(mAddress);
|
||||
}
|
||||
|
||||
if (inJavaThread)
|
||||
mSession->unlock();
|
||||
}
|
||||
|
||||
void NativeMonitor::wait(long long millis)
|
||||
{
|
||||
if (mManager->EnterMonitor(mAddress) == NS_OK) {
|
||||
mManager->Wait(mAddress, PRUint32(millis));
|
||||
mManager->ExitMonitor(mAddress);
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMonitor::notify()
|
||||
{
|
||||
if (mManager->EnterMonitor(mAddress) == NS_OK) {
|
||||
mManager->Notify(mAddress);
|
||||
mManager->ExitMonitor(mAddress);
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMonitor::notifyAll()
|
||||
{
|
||||
if (mManager->EnterMonitor(mAddress) == NS_OK) {
|
||||
mManager->NotifyAll(mAddress);
|
||||
mManager->ExitMonitor(mAddress);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
NativeMonitor.h
|
||||
|
||||
Provides a C++ interface to native monitors.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include "Monitor.h"
|
||||
|
||||
class MRJSession;
|
||||
class nsIThreadManager;
|
||||
|
||||
class NativeMonitor : public Monitor {
|
||||
public:
|
||||
NativeMonitor(MRJSession* session, nsIThreadManager* manager, void* address = NULL);
|
||||
virtual ~NativeMonitor();
|
||||
|
||||
virtual void enter();
|
||||
virtual void exit();
|
||||
|
||||
virtual void wait();
|
||||
virtual void wait(long long millis);
|
||||
virtual void notify();
|
||||
virtual void notifyAll();
|
||||
|
||||
private:
|
||||
MRJSession* mSession;
|
||||
nsIThreadManager* mManager;
|
||||
void* mAddress;
|
||||
};
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
PluginNew.cpp
|
||||
|
||||
new & delete operators for plugins.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include <new.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "nsIMalloc.h"
|
||||
|
||||
// Warning: this forces all C++ allocation to go through Navigator's memory allocation
|
||||
// Routines. As such, static constructors that use operator new may not work. This can
|
||||
// be fixed if we delay static construction (see the call to __InitCode__() in npmac.cpp).
|
||||
|
||||
extern nsIMalloc* theMemoryAllocator;
|
||||
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
if (theMemoryAllocator != NULL)
|
||||
return theMemoryAllocator->Alloc(size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void operator delete(void* ptr)
|
||||
{
|
||||
if (ptr != NULL && theMemoryAllocator != NULL)
|
||||
theMemoryAllocator->Free(ptr);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
StringUtils.cpp
|
||||
*/
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
inline unsigned char toupper(unsigned char c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;
|
||||
}
|
||||
|
||||
int strcasecmp(const char * str1, const char * str2)
|
||||
{
|
||||
#if !__POWERPC__
|
||||
|
||||
const unsigned char * p1 = (unsigned char *) str1;
|
||||
const unsigned char * p2 = (unsigned char *) str2;
|
||||
unsigned char c1, c2;
|
||||
|
||||
while (toupper(c1 = *p1++) == toupper(c2 = *p2++))
|
||||
if (!c1)
|
||||
return(0);
|
||||
|
||||
#else
|
||||
|
||||
const unsigned char * p1 = (unsigned char *) str1 - 1;
|
||||
const unsigned char * p2 = (unsigned char *) str2 - 1;
|
||||
unsigned long c1, c2;
|
||||
|
||||
while (toupper(c1 = *++p1) == toupper(c2 = *++p2))
|
||||
if (!c1)
|
||||
return(0);
|
||||
|
||||
#endif
|
||||
|
||||
return(toupper(c1) - toupper(c2));
|
||||
}
|
||||
|
||||
char* strdup(const char* str)
|
||||
{
|
||||
if (str != NULL) {
|
||||
char* result = new char[::strlen(str) + 1];
|
||||
if (result != NULL)
|
||||
::strcpy(result, str);
|
||||
return result;
|
||||
}
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
StringUtils.h
|
||||
|
||||
String utilities.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Case-insensitive string comparison.
|
||||
*/
|
||||
int strcasecmp(const char * str1, const char * str2);
|
||||
|
||||
/**
|
||||
* Duplicates a C string, returns NULL if failed, or passed NULL.
|
||||
*/
|
||||
char* strdup(const char* str);
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
SupportsMixin.cpp
|
||||
|
||||
Experimental way to implement nsISupports interface.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include "SupportsMixin.h"
|
||||
|
||||
// Standard ISupported Method Implementations.
|
||||
|
||||
SupportsMixin::SupportsMixin(nsISupports* instance, nsID* ids, UInt32 idCount)
|
||||
: mInstance(instance), mRefCount(0), mIDs(ids), mIDCount(idCount)
|
||||
{
|
||||
}
|
||||
|
||||
SupportsMixin::~SupportsMixin()
|
||||
{
|
||||
if (mRefCount > 0) {
|
||||
::DebugStr("\pmRefCount > 0!");
|
||||
}
|
||||
}
|
||||
|
||||
nsresult SupportsMixin::queryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (aInstancePtr == NULL) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
// first check to see if it's one of our known interfaces.
|
||||
// need to solve the non-left inheritance graph case.
|
||||
nsID* ids = mIDs;
|
||||
UInt32 count = mIDCount;
|
||||
for (UInt32 i = 0; i < count; i++) {
|
||||
if (aIID.Equals(ids[i])) {
|
||||
*aInstancePtr = (void*) mInstance;
|
||||
addRef();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
// finally, does the interface match nsISupports?
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
if (aIID.Equals(kISupportsIID)) {
|
||||
*aInstancePtr = (void*) mInstance;
|
||||
addRef();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
nsrefcnt SupportsMixin::addRef()
|
||||
{
|
||||
return ++mRefCount;
|
||||
}
|
||||
|
||||
nsrefcnt SupportsMixin::release()
|
||||
{
|
||||
if (--mRefCount == 0) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCount;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
SupportsMixin.h
|
||||
|
||||
Experimental way to implement nsISupports interface.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
class SupportsMixin {
|
||||
public:
|
||||
SupportsMixin(nsISupports* instance, nsID* ids, UInt32 idCount);
|
||||
virtual ~SupportsMixin();
|
||||
|
||||
nsresult queryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
nsrefcnt addRef(void);
|
||||
nsrefcnt release(void);
|
||||
|
||||
protected:
|
||||
nsISupports* mInstance;
|
||||
nsrefcnt mRefCount;
|
||||
nsID* mIDs;
|
||||
UInt32 mIDCount;
|
||||
};
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
TopLevelFrame.cpp
|
||||
|
||||
An MRJFrame sub-class that manages the behavior of a top-level window
|
||||
running inside the Communicator.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include <Controls.h>
|
||||
#include <Events.h>
|
||||
|
||||
#include "TopLevelFrame.h"
|
||||
#include "LocalPort.h"
|
||||
|
||||
#include "nsIPluginManager2.h"
|
||||
|
||||
extern nsIPluginManager2* thePluginManager2;
|
||||
|
||||
static void UnsetPort(GrafPtr port);
|
||||
static short getModifiers();
|
||||
|
||||
TopLevelFrame::TopLevelFrame(nsIEventHandler* handler, JMFrameRef frameRef, JMFrameKind kind,
|
||||
const Rect* initialBounds, Boolean resizeable)
|
||||
: MRJFrame(frameRef),
|
||||
mHandler(handler), mWindow(NULL), mBounds(*initialBounds)
|
||||
{
|
||||
Boolean hasGoAway = true;
|
||||
SInt16 windowProc = documentProc;
|
||||
SInt16 resizeHeight = resizeable ? 15 : 0;
|
||||
|
||||
switch (kind) {
|
||||
case eBorderlessModelessWindowFrame:
|
||||
hasGoAway = false;
|
||||
windowProc = plainDBox;
|
||||
// mBounds.bottom += resizeHeight;
|
||||
resizeable = false;
|
||||
break;
|
||||
case eModelessWindowFrame:
|
||||
case eModelessDialogFrame:
|
||||
hasGoAway = true;
|
||||
windowProc = resizeable ? zoomDocProc : documentProc;
|
||||
// mBounds.bottom += resizeHeight;
|
||||
break;
|
||||
case eModalWindowFrame:
|
||||
hasGoAway = true;
|
||||
// We have to allow resizeable modal windows.
|
||||
windowProc = resizeable ? documentProc : movableDBoxProc;
|
||||
break;
|
||||
}
|
||||
|
||||
mWindow = ::NewCWindow(NULL, &mBounds, "\p", false, windowProc, WindowPtr(-1), hasGoAway, long(this));
|
||||
if (mWindow != NULL) {
|
||||
if (getModifiers() & controlKey) {
|
||||
// hack: Try creating a root control, to see if that messes up MRJ controls.
|
||||
ControlHandle rootControl = NULL;
|
||||
OSErr result = ::GetRootControl(mWindow, &rootControl);
|
||||
if (result != noErr || rootControl == NULL) {
|
||||
result = ::CreateRootControl(mWindow, &rootControl);
|
||||
if (result == noErr && rootControl != NULL) {
|
||||
FSSpec dumpFile = { -1, 2, "\pJava Console Controls" };
|
||||
result = DumpControlHierarchy(mWindow, &dumpFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Point zeroPt = { 0, 0 };
|
||||
::JMSetFrameVisibility(frameRef, mWindow, zeroPt, nil);
|
||||
}
|
||||
}
|
||||
|
||||
TopLevelFrame::~TopLevelFrame()
|
||||
{
|
||||
// make sure the window is hidden (and unregistered with the browser).
|
||||
showHide(false);
|
||||
|
||||
// make sure this port isn't ever current again.
|
||||
::UnsetPort(mWindow);
|
||||
|
||||
if (mWindow != NULL)
|
||||
::DisposeWindow(mWindow);
|
||||
}
|
||||
|
||||
void TopLevelFrame::setSize(const Rect* newSize)
|
||||
{
|
||||
mBounds = *newSize;
|
||||
|
||||
if (mWindow != NULL) {
|
||||
SInt16 width = newSize->right - newSize->left;
|
||||
SInt16 height = newSize->bottom - newSize->top;
|
||||
::SizeWindow(mWindow, width, height, true);
|
||||
::MoveWindow(mWindow, newSize->left, newSize->top, false);
|
||||
}
|
||||
}
|
||||
|
||||
void TopLevelFrame::invalRect(const Rect* invalidRect)
|
||||
{
|
||||
if (mWindow != NULL) {
|
||||
::InvalRect(invalidRect);
|
||||
}
|
||||
}
|
||||
|
||||
void TopLevelFrame::showHide(Boolean visible)
|
||||
{
|
||||
if (mWindow != NULL && visible != IsWindowVisible(mWindow)) {
|
||||
if (visible) {
|
||||
// Have to notify the browser that this window exists, so that it will receive events.
|
||||
thePluginManager2->RegisterWindow(mHandler, mWindow);
|
||||
// the plugin manager takes care of showing the window.
|
||||
// ::ShowWindow(mWindow);
|
||||
// ::SelectWindow(mWindow);
|
||||
} else {
|
||||
// the plugin manager takes care of hiding the window.
|
||||
// ::HideWindow(mWindow);
|
||||
// Let the browser know it doesn't have to send events anymore.
|
||||
thePluginManager2->UnregisterWindow(mHandler, mWindow);
|
||||
}
|
||||
|
||||
// ::ShowHide(mWindow, visible);
|
||||
}
|
||||
}
|
||||
|
||||
void TopLevelFrame::setTitle(const StringPtr title)
|
||||
{
|
||||
if (mWindow != NULL) {
|
||||
::SetWTitle(mWindow, title);
|
||||
}
|
||||
}
|
||||
|
||||
void TopLevelFrame::checkUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
void TopLevelFrame::reorder(ReorderRequest request)
|
||||
{
|
||||
switch (request) {
|
||||
case eBringToFront: /* bring the window to front */
|
||||
break;
|
||||
case eSendToBack: /* send the window to back */
|
||||
break;
|
||||
case eSendBehindFront: /* send the window behind the front window */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TopLevelFrame::setResizeable(Boolean resizeable)
|
||||
{
|
||||
// this might have to recreate the window, no?
|
||||
}
|
||||
|
||||
static void computeBounds(WindowRef window, Rect* bounds)
|
||||
{
|
||||
LocalPort port(window);
|
||||
port.Enter();
|
||||
|
||||
Point position = { 0, 0 };
|
||||
::LocalToGlobal(&position);
|
||||
|
||||
*bounds = window->portRect;
|
||||
|
||||
port.Exit();
|
||||
|
||||
::OffsetRect(bounds, position.h, position.v);
|
||||
}
|
||||
|
||||
void TopLevelFrame::activate(Boolean active)
|
||||
{
|
||||
focusEvent(active);
|
||||
MRJFrame::activate(active);
|
||||
}
|
||||
|
||||
void TopLevelFrame::click(const EventRecord* event)
|
||||
{
|
||||
Point where = event->where;
|
||||
SInt16 modifiers = event->modifiers;
|
||||
WindowRef hitWindow;
|
||||
short partCode = ::FindWindow(where, &hitWindow);
|
||||
switch (partCode) {
|
||||
case inContent:
|
||||
::SelectWindow(mWindow);
|
||||
MRJFrame::click(event);
|
||||
break;
|
||||
case inDrag:
|
||||
Rect bounds = (**GetGrayRgn()).rgnBBox;
|
||||
DragWindow(mWindow, where, &bounds);
|
||||
computeBounds(mWindow, &mBounds);
|
||||
break;
|
||||
case inGrow:
|
||||
Rect limits = { 30, 30, 5000, 5000 };
|
||||
long result = GrowWindow(mWindow, where, &limits);
|
||||
if (result != 0) {
|
||||
short width = (result & 0xFFFF);
|
||||
short height = (result >> 16) & 0xFFFF;
|
||||
Rect newBounds;
|
||||
topLeft(newBounds) = topLeft(mBounds);
|
||||
newBounds.right = newBounds.left + width;
|
||||
newBounds.bottom = newBounds.top + height;
|
||||
::JMSetFrameSize(mFrameRef, &newBounds);
|
||||
}
|
||||
break;
|
||||
case inGoAway:
|
||||
if (::TrackGoAway(mWindow, where))
|
||||
::JMFrameGoAway(mFrameRef);
|
||||
break;
|
||||
case inZoomIn:
|
||||
case inZoomOut:
|
||||
if (::TrackBox(mWindow, where, partCode)) {
|
||||
ZoomWindow(mWindow, partCode, true);
|
||||
computeBounds(mWindow, &mBounds);
|
||||
::JMSetFrameSize(mFrameRef, &mBounds);
|
||||
}
|
||||
break;
|
||||
case inCollapseBox:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WindowRef TopLevelFrame::getWindow()
|
||||
{
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
GrafPtr TopLevelFrame::getPort()
|
||||
{
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
static void UnsetPort(GrafPtr port)
|
||||
{
|
||||
GrafPtr curPort;
|
||||
::GetPort(&curPort);
|
||||
if (curPort == port) {
|
||||
::GetWMgrPort(&port);
|
||||
::SetPort(port);
|
||||
}
|
||||
}
|
||||
|
||||
static short getModifiers()
|
||||
{
|
||||
EventRecord event;
|
||||
::OSEventAvail(0, &event);
|
||||
return event.modifiers;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
TopLevelFrame.h
|
||||
|
||||
An MRJFrame sub-class that manages the behavior of a top-level window
|
||||
running inside the Communicator.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MRJFrame.h"
|
||||
|
||||
#ifndef __MACWINDOWS__
|
||||
#include <MacWindows.h>
|
||||
#endif
|
||||
|
||||
class nsIEventHandler;
|
||||
|
||||
class TopLevelFrame : public MRJFrame {
|
||||
public:
|
||||
TopLevelFrame(nsIEventHandler* handler, JMFrameRef frameRef, JMFrameKind kind, const Rect* initialBounds, Boolean resizeable);
|
||||
virtual ~TopLevelFrame();
|
||||
|
||||
virtual void setSize(const Rect* newSize);
|
||||
virtual void invalRect(const Rect* invalidRect);
|
||||
virtual void showHide(Boolean visible);
|
||||
virtual void setTitle(const StringPtr title);
|
||||
virtual void checkUpdate();
|
||||
virtual void reorder(ReorderRequest request);
|
||||
virtual void setResizeable(Boolean resizeable);
|
||||
|
||||
virtual void activate(Boolean active);
|
||||
virtual void click(const EventRecord* event);
|
||||
|
||||
WindowRef getWindow();
|
||||
|
||||
protected:
|
||||
virtual GrafPtr getPort();
|
||||
|
||||
private:
|
||||
nsIEventHandler* mHandler;
|
||||
WindowRef mWindow;
|
||||
Rect mBounds;
|
||||
};
|
|
@ -0,0 +1,681 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
//
|
||||
// npmac.cpp
|
||||
//
|
||||
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
#include <Processes.h>
|
||||
#include <Gestalt.h>
|
||||
#include <CodeFragments.h>
|
||||
#include <Timer.h>
|
||||
#include <Resources.h>
|
||||
#include <ToolUtils.h>
|
||||
|
||||
#define XP_MAC 1
|
||||
#define NDEBUG 1
|
||||
|
||||
//
|
||||
// A4Stuff.h contains the definition of EnterCodeResource and
|
||||
// EnterCodeResource, used for setting up the code resourceÕs
|
||||
// globals for 68K (analagous to the function SetCurrentA5
|
||||
// defined by the toolbox).
|
||||
//
|
||||
#include <A4Stuff.h>
|
||||
|
||||
#include "jri.h"
|
||||
#include "npapi.h"
|
||||
|
||||
//
|
||||
// The Mixed Mode procInfos defined in npupp.h assume Think C-
|
||||
// style calling conventions. These conventions are used by
|
||||
// Metrowerks with the exception of pointer return types, which
|
||||
// in Metrowerks 68K are returned in A0, instead of the standard
|
||||
// D0. Thus, since NPN_MemAlloc and NPN_UserAgent return pointers,
|
||||
// Mixed Mode will return the values to a 68K plugin in D0, but
|
||||
// a 68K plugin compiled by Metrowerks will expect the result in
|
||||
// A0. The following pragma forces Metrowerks to use D0 instead.
|
||||
//
|
||||
#ifdef __MWERKS__
|
||||
#ifndef powerc
|
||||
#pragma pointers_in_D0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "npupp.h"
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#ifndef powerc
|
||||
#pragma pointers_in_A0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// The following fix for static initializers (which fixes a preious
|
||||
// incompatibility with some parts of PowerPlant, was submitted by
|
||||
// Jan Ulbrich.
|
||||
#ifdef __MWERKS__
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifndef powerc
|
||||
extern void __InitCode__(void);
|
||||
#else
|
||||
extern void __sinit(void);
|
||||
#define __InitCode__ __sinit
|
||||
#endif
|
||||
extern void __destroy_global_chain(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
#endif // __MWERKS__
|
||||
|
||||
//
|
||||
// Define PLUGIN_TRACE to 1 to have the wrapper functions emit
|
||||
// DebugStr messages whenever they are called.
|
||||
//
|
||||
#define PLUGIN_TRACE 0
|
||||
|
||||
#if PLUGIN_TRACE
|
||||
#define PLUGINDEBUGSTR(msg) ::DebugStr(msg)
|
||||
#else
|
||||
#define PLUGINDEBUGSTR
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
QDGlobals* gQDPtr; // Pointer to NetscapeÕs QuickDraw globals
|
||||
short gResFile; // Refnum of the pluginÕs resource file
|
||||
NPNetscapeFuncs gNetscapeFuncs; // Function table for procs in Netscape called by plugin
|
||||
|
||||
|
||||
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
//
|
||||
// Wrapper functions for all calls from the plugin to Netscape.
|
||||
// These functions let the plugin developer just call the APIs
|
||||
// as documented and defined in npapi.h, without needing to know
|
||||
// about the function table and call macros in npupp.h.
|
||||
//
|
||||
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
void NPN_Version(int* plugin_major, int* plugin_minor, int* netscape_major, int* netscape_minor)
|
||||
{
|
||||
*plugin_major = NP_VERSION_MAJOR;
|
||||
*plugin_minor = NP_VERSION_MINOR;
|
||||
*netscape_major = gNetscapeFuncs.version >> 8; // Major version is in high byte
|
||||
*netscape_minor = gNetscapeFuncs.version & 0xFF; // Minor version is in low byte
|
||||
}
|
||||
|
||||
NPError NPN_GetURLNotify(NPP instance, const char* url, const char* window, void* notifyData)
|
||||
{
|
||||
int navMinorVers = gNetscapeFuncs.version & 0xFF;
|
||||
NPError err;
|
||||
|
||||
if( navMinorVers >= NPVERS_HAS_NOTIFICATION )
|
||||
{
|
||||
err = CallNPN_GetURLNotifyProc(gNetscapeFuncs.geturlnotify, instance, url, window, notifyData);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
NPError NPN_GetURL(NPP instance, const char* url, const char* window)
|
||||
{
|
||||
return CallNPN_GetURLProc(gNetscapeFuncs.geturl, instance, url, window);
|
||||
}
|
||||
|
||||
NPError NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData)
|
||||
{
|
||||
int navMinorVers = gNetscapeFuncs.version & 0xFF;
|
||||
NPError err;
|
||||
|
||||
if( navMinorVers >= NPVERS_HAS_NOTIFICATION )
|
||||
{
|
||||
err = CallNPN_PostURLNotifyProc(gNetscapeFuncs.posturlnotify, instance, url,
|
||||
window, len, buf, file, notifyData);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
NPError NPN_PostURL(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file)
|
||||
{
|
||||
return CallNPN_PostURLProc(gNetscapeFuncs.posturl, instance, url, window, len, buf, file);
|
||||
}
|
||||
|
||||
NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
|
||||
{
|
||||
return CallNPN_RequestReadProc(gNetscapeFuncs.requestread, stream, rangeList);
|
||||
}
|
||||
|
||||
NPError NPN_NewStream(NPP instance, NPMIMEType type, const char* window, NPStream** stream)
|
||||
{
|
||||
int navMinorVers = gNetscapeFuncs.version & 0xFF;
|
||||
NPError err;
|
||||
|
||||
if( navMinorVers >= NPVERS_HAS_STREAMOUTPUT )
|
||||
{
|
||||
err = CallNPN_NewStreamProc(gNetscapeFuncs.newstream, instance, type, window, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int32 NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer)
|
||||
{
|
||||
int navMinorVers = gNetscapeFuncs.version & 0xFF;
|
||||
NPError err;
|
||||
|
||||
if( navMinorVers >= NPVERS_HAS_STREAMOUTPUT )
|
||||
{
|
||||
err = CallNPN_WriteProc(gNetscapeFuncs.write, instance, stream, len, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
|
||||
{
|
||||
int navMinorVers = gNetscapeFuncs.version & 0xFF;
|
||||
NPError err;
|
||||
|
||||
if( navMinorVers >= NPVERS_HAS_STREAMOUTPUT )
|
||||
{
|
||||
err = CallNPN_DestroyStreamProc(gNetscapeFuncs.destroystream, instance, stream, reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void NPN_Status(NPP instance, const char* message)
|
||||
{
|
||||
CallNPN_StatusProc(gNetscapeFuncs.status, instance, message);
|
||||
}
|
||||
|
||||
const char* NPN_UserAgent(NPP instance)
|
||||
{
|
||||
return CallNPN_UserAgentProc(gNetscapeFuncs.uagent, instance);
|
||||
}
|
||||
|
||||
#define DEBUG_MEMORY 0
|
||||
|
||||
void* NPN_MemAlloc(uint32 size)
|
||||
{
|
||||
#if DEBUG_MEMORY
|
||||
return (void*) NewPtrClear(size);
|
||||
#else
|
||||
return CallNPN_MemAllocProc(gNetscapeFuncs.memalloc, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void NPN_MemFree(void* ptr)
|
||||
{
|
||||
#if DEBUG_MEMORY
|
||||
DisposePtr(Ptr(ptr));
|
||||
#else
|
||||
CallNPN_MemFreeProc(gNetscapeFuncs.memfree, ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32 NPN_MemFlush(uint32 size)
|
||||
{
|
||||
return CallNPN_MemFlushProc(gNetscapeFuncs.memflush, size);
|
||||
}
|
||||
|
||||
void NPN_ReloadPlugins(NPBool reloadPages)
|
||||
{
|
||||
CallNPN_ReloadPluginsProc(gNetscapeFuncs.reloadplugins, reloadPages);
|
||||
}
|
||||
|
||||
|
||||
JRIEnv* NPN_GetJavaEnv(void)
|
||||
{
|
||||
return CallNPN_GetJavaEnvProc( gNetscapeFuncs.getJavaEnv );
|
||||
}
|
||||
|
||||
jref NPN_GetJavaPeer(NPP instance)
|
||||
{
|
||||
return CallNPN_GetJavaPeerProc( gNetscapeFuncs.getJavaPeer, instance );
|
||||
}
|
||||
|
||||
NPError NPN_GetValue(NPP instance, NPNVariable variable, void *value)
|
||||
{
|
||||
return CallNPN_GetValueProc( gNetscapeFuncs.getvalue, instance, variable, value);
|
||||
}
|
||||
|
||||
NPError NPN_SetValue(NPP instance, NPPVariable variable, void *value)
|
||||
{
|
||||
return CallNPN_SetValueProc( gNetscapeFuncs.setvalue, instance, variable, value);
|
||||
}
|
||||
|
||||
void NPN_InvalidateRect(NPP instance, NPRect *rect)
|
||||
{
|
||||
CallNPN_InvalidateRectProc( gNetscapeFuncs.invalidaterect, instance, rect);
|
||||
}
|
||||
|
||||
void NPN_InvalidateRegion(NPP instance, NPRegion region)
|
||||
{
|
||||
CallNPN_InvalidateRegionProc( gNetscapeFuncs.invalidateregion, instance, region);
|
||||
}
|
||||
|
||||
void NPN_ForceRedraw(NPP instance)
|
||||
{
|
||||
CallNPN_ForceRedrawProc( gNetscapeFuncs.forceredraw, instance);
|
||||
}
|
||||
|
||||
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
//
|
||||
// Wrapper functions for all calls from Netscape to the plugin.
|
||||
// These functions let the plugin developer just create the APIs
|
||||
// as documented and defined in npapi.h, without needing to
|
||||
// install those functions in the function table or worry about
|
||||
// setting up globals for 68K plugins.
|
||||
//
|
||||
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
NPError Private_Initialize(void);
|
||||
void Private_Shutdown(void);
|
||||
NPError Private_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved);
|
||||
NPError Private_Destroy(NPP instance, NPSavedData** save);
|
||||
NPError Private_SetWindow(NPP instance, NPWindow* window);
|
||||
NPError Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype);
|
||||
NPError Private_DestroyStream(NPP instance, NPStream* stream, NPError reason);
|
||||
int32 Private_WriteReady(NPP instance, NPStream* stream);
|
||||
int32 Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer);
|
||||
void Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
|
||||
void Private_Print(NPP instance, NPPrint* platformPrint);
|
||||
int16 Private_HandleEvent(NPP instance, void* event);
|
||||
void Private_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData);
|
||||
jref Private_GetJavaClass(void);
|
||||
|
||||
|
||||
NPError Private_Initialize(void)
|
||||
{
|
||||
NPError err;
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pInitialize;g;");
|
||||
err = NPP_Initialize();
|
||||
ExitCodeResource();
|
||||
return err;
|
||||
}
|
||||
|
||||
void Private_Shutdown(void)
|
||||
{
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pShutdown;g;");
|
||||
NPP_Shutdown();
|
||||
|
||||
__destroy_global_chain();
|
||||
|
||||
ExitCodeResource();
|
||||
}
|
||||
|
||||
|
||||
NPError Private_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved)
|
||||
{
|
||||
EnterCodeResource();
|
||||
NPError ret = NPP_New(pluginType, instance, mode, argc, argn, argv, saved);
|
||||
PLUGINDEBUGSTR("\pNew;g;");
|
||||
ExitCodeResource();
|
||||
return ret;
|
||||
}
|
||||
|
||||
NPError Private_Destroy(NPP instance, NPSavedData** save)
|
||||
{
|
||||
NPError err;
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pDestroy;g;");
|
||||
err = NPP_Destroy(instance, save);
|
||||
ExitCodeResource();
|
||||
return err;
|
||||
}
|
||||
|
||||
NPError Private_SetWindow(NPP instance, NPWindow* window)
|
||||
{
|
||||
NPError err;
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pSetWindow;g;");
|
||||
err = NPP_SetWindow(instance, window);
|
||||
ExitCodeResource();
|
||||
return err;
|
||||
}
|
||||
|
||||
NPError Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
|
||||
{
|
||||
NPError err;
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pNewStream;g;");
|
||||
err = NPP_NewStream(instance, type, stream, seekable, stype);
|
||||
ExitCodeResource();
|
||||
return err;
|
||||
}
|
||||
|
||||
int32 Private_WriteReady(NPP instance, NPStream* stream)
|
||||
{
|
||||
int32 result;
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pWriteReady;g;");
|
||||
result = NPP_WriteReady(instance, stream);
|
||||
ExitCodeResource();
|
||||
return result;
|
||||
}
|
||||
|
||||
int32 Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
|
||||
{
|
||||
int32 result;
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pWrite;g;");
|
||||
result = NPP_Write(instance, stream, offset, len, buffer);
|
||||
ExitCodeResource();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
|
||||
{
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pStreamAsFile;g;");
|
||||
NPP_StreamAsFile(instance, stream, fname);
|
||||
ExitCodeResource();
|
||||
}
|
||||
|
||||
|
||||
NPError Private_DestroyStream(NPP instance, NPStream* stream, NPError reason)
|
||||
{
|
||||
NPError err;
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pDestroyStream;g;");
|
||||
err = NPP_DestroyStream(instance, stream, reason);
|
||||
ExitCodeResource();
|
||||
return err;
|
||||
}
|
||||
|
||||
int16 Private_HandleEvent(NPP instance, void* event)
|
||||
{
|
||||
int16 result;
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pHandleEvent;g;");
|
||||
result = NPP_HandleEvent(instance, event);
|
||||
ExitCodeResource();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Private_Print(NPP instance, NPPrint* platformPrint)
|
||||
{
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pPrint;g;");
|
||||
NPP_Print(instance, platformPrint);
|
||||
ExitCodeResource();
|
||||
}
|
||||
|
||||
void Private_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
|
||||
{
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pURLNotify;g;");
|
||||
NPP_URLNotify(instance, url, reason, notifyData);
|
||||
ExitCodeResource();
|
||||
}
|
||||
|
||||
|
||||
jref Private_GetJavaClass(void)
|
||||
{
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pGetJavaClass;g;");
|
||||
|
||||
jref clazz = NPP_GetJavaClass();
|
||||
ExitCodeResource();
|
||||
if (clazz)
|
||||
{
|
||||
JRIEnv* env = NPN_GetJavaEnv();
|
||||
return (jref)JRI_NewGlobalRef(env, clazz);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void SetUpQD(void);
|
||||
|
||||
void SetUpQD(void)
|
||||
{
|
||||
ProcessSerialNumber PSN;
|
||||
FSSpec myFSSpec;
|
||||
Str63 name;
|
||||
ProcessInfoRec infoRec;
|
||||
OSErr result = noErr;
|
||||
CFragConnectionID connID;
|
||||
Str255 errName;
|
||||
|
||||
//
|
||||
// Memorize the pluginÕs resource file
|
||||
// refnum for later use.
|
||||
//
|
||||
gResFile = CurResFile();
|
||||
|
||||
//
|
||||
// Ask the system if CFM is available.
|
||||
//
|
||||
long response;
|
||||
OSErr err = Gestalt(gestaltCFMAttr, &response);
|
||||
Boolean hasCFM = BitTst(&response, 31-gestaltCFMPresent);
|
||||
|
||||
if (hasCFM)
|
||||
{
|
||||
//
|
||||
// GetProcessInformation takes a process serial number and
|
||||
// will give us back the name and FSSpec of the application.
|
||||
// See the Process Manager in IM.
|
||||
//
|
||||
infoRec.processInfoLength = sizeof(ProcessInfoRec);
|
||||
infoRec.processName = name;
|
||||
infoRec.processAppSpec = &myFSSpec;
|
||||
|
||||
PSN.highLongOfPSN = 0;
|
||||
PSN.lowLongOfPSN = kCurrentProcess;
|
||||
|
||||
result = GetProcessInformation(&PSN, &infoRec);
|
||||
if (result != noErr)
|
||||
PLUGINDEBUGSTR("\pFailed in GetProcessInformation");
|
||||
}
|
||||
else
|
||||
//
|
||||
// If no CFM installed, assume it must be a 68K app.
|
||||
//
|
||||
result = -1;
|
||||
|
||||
if (result == noErr)
|
||||
{
|
||||
//
|
||||
// Now that we know the app name and FSSpec, we can call GetDiskFragment
|
||||
// to get a connID to use in a subsequent call to FindSymbol (it will also
|
||||
// return the address of ÒmainÓ in app, which we ignore). If GetDiskFragment
|
||||
// returns an error, we assume the app must be 68K.
|
||||
//
|
||||
Ptr mainAddr;
|
||||
result = GetDiskFragment(infoRec.processAppSpec, 0L, 0L, infoRec.processName,
|
||||
kReferenceCFrag, &connID, (Ptr*)&mainAddr, errName);
|
||||
}
|
||||
|
||||
if (result == noErr)
|
||||
{
|
||||
//
|
||||
// The app is a PPC code fragment, so call FindSymbol
|
||||
// to get the exported ÒqdÓ symbol so we can access its
|
||||
// QuickDraw globals.
|
||||
//
|
||||
CFragSymbolClass symClass;
|
||||
result = FindSymbol(connID, "\pqd", (Ptr*)&gQDPtr, &symClass);
|
||||
if (result != noErr)
|
||||
PLUGINDEBUGSTR("\pFailed in FindSymbol qd");
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// The app is 68K, so use its A5 to compute the address
|
||||
// of its QuickDraw globals.
|
||||
//
|
||||
gQDPtr = (QDGlobals*)(*((long*)SetCurrentA5()) - (sizeof(QDGlobals) - sizeof(GrafPtr)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
NPError main(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs, NPP_ShutdownUPP* unloadUpp);
|
||||
|
||||
#pragma export on
|
||||
|
||||
#if GENERATINGCFM
|
||||
RoutineDescriptor mainRD = BUILD_ROUTINE_DESCRIPTOR(uppNPP_MainEntryProcInfo, main);
|
||||
#endif
|
||||
|
||||
#pragma export off
|
||||
|
||||
|
||||
NPError main(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs, NPP_ShutdownUPP* unloadUpp)
|
||||
{
|
||||
EnterCodeResource();
|
||||
PLUGINDEBUGSTR("\pmain");
|
||||
|
||||
NPError err = NPERR_NO_ERROR;
|
||||
|
||||
//
|
||||
// Ensure that everything Netscape passed us is valid!
|
||||
//
|
||||
if ((nsTable == NULL) || (pluginFuncs == NULL) || (unloadUpp == NULL))
|
||||
err = NPERR_INVALID_FUNCTABLE_ERROR;
|
||||
|
||||
//
|
||||
// Check the ÒmajorÓ version passed in NetscapeÕs function table.
|
||||
// We wonÕt load if the major version is newer than what we expect.
|
||||
// Also check that the function tables passed in are big enough for
|
||||
// all the functions we need (they could be bigger, if Netscape added
|
||||
// new APIs, but thatÕs OK with us -- weÕll just ignore them).
|
||||
//
|
||||
if (err == NPERR_NO_ERROR)
|
||||
{
|
||||
if ((nsTable->version >> 8) > NP_VERSION_MAJOR) // Major version is in high byte
|
||||
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
|
||||
// if (nsTable->size < sizeof(NPNetscapeFuncs))
|
||||
// err = NPERR_INVALID_FUNCTABLE_ERROR;
|
||||
// if (pluginFuncs->size < sizeof(NPPluginFuncs))
|
||||
// err = NPERR_INVALID_FUNCTABLE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (err == NPERR_NO_ERROR)
|
||||
{
|
||||
//
|
||||
// Copy all the fields of NetscapeÕs function table into our
|
||||
// copy so we can call back into Netscape later. Note that
|
||||
// we need to copy the fields one by one, rather than assigning
|
||||
// the whole structure, because the Netscape function table
|
||||
// could actually be bigger than what we expect.
|
||||
//
|
||||
|
||||
int navMinorVers = nsTable->version & 0xFF;
|
||||
|
||||
gNetscapeFuncs.version = nsTable->version;
|
||||
gNetscapeFuncs.size = nsTable->size;
|
||||
gNetscapeFuncs.posturl = nsTable->posturl;
|
||||
gNetscapeFuncs.geturl = nsTable->geturl;
|
||||
gNetscapeFuncs.requestread = nsTable->requestread;
|
||||
gNetscapeFuncs.newstream = nsTable->newstream;
|
||||
gNetscapeFuncs.write = nsTable->write;
|
||||
gNetscapeFuncs.destroystream = nsTable->destroystream;
|
||||
gNetscapeFuncs.status = nsTable->status;
|
||||
gNetscapeFuncs.uagent = nsTable->uagent;
|
||||
gNetscapeFuncs.memalloc = nsTable->memalloc;
|
||||
gNetscapeFuncs.memfree = nsTable->memfree;
|
||||
gNetscapeFuncs.memflush = nsTable->memflush;
|
||||
gNetscapeFuncs.reloadplugins = nsTable->reloadplugins;
|
||||
if( navMinorVers >= NPVERS_HAS_LIVECONNECT )
|
||||
{
|
||||
gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv;
|
||||
gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer;
|
||||
}
|
||||
if( navMinorVers >= NPVERS_HAS_NOTIFICATION )
|
||||
{
|
||||
gNetscapeFuncs.geturlnotify = nsTable->geturlnotify;
|
||||
gNetscapeFuncs.posturlnotify = nsTable->posturlnotify;
|
||||
}
|
||||
gNetscapeFuncs.getvalue = nsTable->getvalue;
|
||||
gNetscapeFuncs.setvalue = nsTable->setvalue;
|
||||
gNetscapeFuncs.invalidaterect = nsTable->invalidaterect;
|
||||
gNetscapeFuncs.invalidateregion = nsTable->invalidateregion;
|
||||
gNetscapeFuncs.forceredraw = nsTable->forceredraw;
|
||||
|
||||
// defer static constructors until the global functions are initialized.
|
||||
__InitCode__();
|
||||
|
||||
//
|
||||
// Set up the plugin function table that Netscape will use to
|
||||
// call us. Netscape needs to know about our version and size
|
||||
// and have a UniversalProcPointer for every function we implement.
|
||||
//
|
||||
pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
|
||||
pluginFuncs->size = sizeof(NPPluginFuncs);
|
||||
pluginFuncs->newp = NewNPP_NewProc(Private_New);
|
||||
pluginFuncs->destroy = NewNPP_DestroyProc(Private_Destroy);
|
||||
pluginFuncs->setwindow = NewNPP_SetWindowProc(Private_SetWindow);
|
||||
pluginFuncs->newstream = NewNPP_NewStreamProc(Private_NewStream);
|
||||
pluginFuncs->destroystream = NewNPP_DestroyStreamProc(Private_DestroyStream);
|
||||
pluginFuncs->asfile = NewNPP_StreamAsFileProc(Private_StreamAsFile);
|
||||
pluginFuncs->writeready = NewNPP_WriteReadyProc(Private_WriteReady);
|
||||
pluginFuncs->write = NewNPP_WriteProc(Private_Write);
|
||||
pluginFuncs->print = NewNPP_PrintProc(Private_Print);
|
||||
pluginFuncs->event = NewNPP_HandleEventProc(Private_HandleEvent);
|
||||
if( navMinorVers >= NPVERS_HAS_NOTIFICATION )
|
||||
{
|
||||
pluginFuncs->urlnotify = NewNPP_URLNotifyProc(Private_URLNotify);
|
||||
}
|
||||
if( navMinorVers >= NPVERS_HAS_LIVECONNECT )
|
||||
{
|
||||
pluginFuncs->javaClass = (JRIGlobalRef) Private_GetJavaClass();
|
||||
}
|
||||
*unloadUpp = NewNPP_ShutdownProc(Private_Shutdown);
|
||||
SetUpQD();
|
||||
err = Private_Initialize();
|
||||
}
|
||||
|
||||
ExitCodeResource();
|
||||
return err;
|
||||
}
|
Загрузка…
Ссылка в новой задаче