Mozilla/mozilla/java/pluggable-jvm/wf_moz6/src/nsAppletHTMLObject.cpp
jwalden%mit.edu 3cb05eec64 Bug 348748 - Remove casts from java/. r=bsmedberg on the script, a=NPOTB+no-functionality-change
git-svn-id: svn://10.0.0.236/trunk@233910 18797224-902f-48f8-a5cc-f745e15eee43
2007-09-05 07:25:16 +00:00

461 lines
13 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: nsAppletHTMLObject.cpp,v 1.4 2007-09-05 07:25:16 jwalden%mit.edu Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#include "nsAppletHTMLObject.h"
#include "nsJavaHTMLObject.h"
#include "nsJavaObjectInfo.h"
#include "nsIPluginTagInfo.h"
#include "nsIProxyObjectManager.h"
#include "nsIServiceManager.h"
#include "nsIPluginManager2.h"
#include "nsIJavaPluginInstanceProxy.h"
#include "nsIWFInstanceWrapper.h"
#include "nsIJVMPluginInstance.h"
#include "wf_moz6_common.h"
#include "nsIThread.h"
static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
static NS_DEFINE_CID(kPluginManagerCID, NS_PLUGINMANAGER_CID);
static NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID);
static NS_DEFINE_IID(kIPluginManager2IID, NS_IPLUGINMANAGER2_IID);
static NS_DEFINE_IID(kIPluginInstancePeerIID, NS_IPLUGININSTANCEPEER_IID);
static NS_DEFINE_IID(kIPluginInstancePeer2IID, NS_IPLUGININSTANCEPEER2_IID);
static NS_DEFINE_IID(kIPluginTagInfoIID, NS_IPLUGINTAGINFO_IID);
static NS_DEFINE_IID(kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID);
NS_IMPL_THREADSAFE_ISUPPORTS3(nsAppletHTMLObject,
nsIPluginInstance,
nsIWFInstanceWrapper,
nsIJVMPluginInstance)
nsAppletHTMLObject::nsAppletHTMLObject(nsJavaHTMLObjectFactory *factory)
{
NS_INIT_ISUPPORTS();
m_factory = factory;
m_mgr = nsnull;
NS_ADDREF(m_factory);
m_peer = m_peer2 = nsnull;
m_dead = PR_FALSE;
nsCOMPtr<nsIThread> mainIThread;
nsIThread::GetMainThread(getter_AddRefs(mainIThread));
mainIThread->GetPRThread(&m_mainThread);
}
nsAppletHTMLObject::~nsAppletHTMLObject(void) {
OJI_LOG("nsAppletHTMLObject::~nsAppletHTMLObject");
if (m_factory) NS_RELEASE(m_factory);
}
NS_IMETHODIMP
nsAppletHTMLObject::Initialize(nsIPluginInstancePeer *peer)
{
nsresult res;
OJI_LOG("nsAppletHTMLObject::Initialize");
m_peer = peer;
NS_ADDREF(m_peer);
peer->QueryInterface(kIPluginInstancePeer2IID,
(void **)&m_peer2);
m_jobject = new nsJavaHTMLObject(m_factory);
NS_ADDREF(m_jobject);
res = nsServiceManager::GetService(kPluginManagerCID,
kIPluginManagerIID,
getter_AddRefs(m_mgr));
if (NS_FAILED(res)) return res;
m_id = 0;
if (NS_FAILED(res = m_factory->GetJVM(&m_jvm))) return res;
if (NS_FAILED(res = m_jvm->GetJNIEnv(&m_env))) return res;
if (NS_FAILED(res = m_jobject->Initialize(peer, m_jvm))) return res;
// find out applet information from our peer and explain it
// to nsJavaHTMLObject
// in new API nsJavaHTMLObject should get everything needed
// from peer
nsJavaObjectInfo* info =
new nsJavaObjectInfo((nsIWFInstanceWrapper*)this);
NS_ADDREF(info);
nsIPluginTagInfo *tagInfo;
if (NS_SUCCEEDED(res = peer->QueryInterface(kIPluginTagInfoIID,
(void **)&tagInfo)))
{
PRUint16 argc = 0, i;
char **keys, **vals;
tagInfo->GetAttributes(argc, (const char* const* &)keys,
(const char* const* &) vals);
for (i=0; i<argc; i++)
info->AddParameter(keys[i], vals[i]);
NS_RELEASE(tagInfo);
}
nsIPluginTagInfo2 *extTagInfo;
if (NS_SUCCEEDED(res = peer->QueryInterface(kIPluginTagInfo2IID,
(void **)&extTagInfo)))
{
nsPluginTagType tagType = nsPluginTagType_Unknown;
if (NS_SUCCEEDED(extTagInfo->GetTagType(&tagType)))
{
if (tagType == nsPluginTagType_Applet ||
tagType == nsPluginTagType_Object)
{
PRUint16 argc = 0, i;
char **keys, **vals;
extTagInfo->GetParameters(argc,
(const char*const*&)keys,
(const char*const*&) vals);
for (i=0; i<argc; i++)
info->AddParameter(keys[i], vals[i]);
}
nsJavaObjectType type = mapType(tagType);
info->SetType(type);
if (NS_FAILED(res = m_jobject->SetType(type)))
return res;
}
const char *docbase = NULL;
if (NS_FAILED(res = extTagInfo->GetDocumentBase(&docbase)))
{
OJI_LOG("Failed to obtain doc base");
}
if (docbase != NULL)
{
char *slash = strrchr((char*)docbase, '/');
if (slash != NULL) *(slash+1) = 0;
OJI_LOG2("real docbase is %s", docbase);
info->SetDocBase(docbase);
}
NS_RELEASE(extTagInfo);
}
// really it's crucial to call SetType() _before_ passing Java object info
// otherwise parameters will be passed to wrapper - and silently ignored
res = m_jobject->SetJavaObjectInfo(info);
NS_RELEASE(info);
return res;
}
NS_IMETHODIMP
nsAppletHTMLObject::GetPeer(nsIPluginInstancePeer* *resultingPeer)
{
//OJI_LOG("nsAppletHTMLObject::GetPeer");
if (m_dead) return NS_ERROR_FAILURE;
*resultingPeer = m_peer;
NS_ADDREF(m_peer);
return NS_OK;
}
NS_IMETHODIMP
nsAppletHTMLObject::Start(void)
{
OJI_LOG("nsAppletHTMLObject::Start");
m_dead = PR_FALSE;
return m_jobject->Start();
}
NS_IMETHODIMP
nsAppletHTMLObject::Stop(void)
{
OJI_LOG("nsAppletHTMLObject::Stop");
if (m_jobject) m_jobject->Stop();
if (m_id && m_jvm) m_jvm->UnregisterWindow(m_id);
m_id = 0;
m_dead = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsAppletHTMLObject::Destroy(void)
{
OJI_LOG("nsAppletHTMLObject::Destroy");
m_dead = PR_TRUE;
if (m_jobject)
{
m_jobject->Destroy();
NS_RELEASE(m_jobject);
}
if (m_peer) NS_RELEASE(m_peer);
if (m_peer2) NS_RELEASE(m_peer2);
if (m_jvm) NS_RELEASE(m_jvm);
//OJI_LOG2("mRefCnt=%d",mRefCnt);
return NS_OK;
}
// XXX: for now, this code can leak window descriptors,
// as not unregisters old window, if new one has come
// with another native handle.
// SetWindow() with size changing hopefully works well
NS_IMETHODIMP
nsAppletHTMLObject::SetWindow(nsPluginWindow* window)
{
OJI_LOG2("nsAppletHTMLObject::SetWindow(%p)",
window != nsnull ? (void*)window->window : 0x0);
nsresult res = NS_OK;
if (m_jvm == NULL)
{
OJI_LOG("m_jvm is NULL");
return NS_ERROR_FAILURE;
}
if (window != NULL)
{
jint new_id;
res = m_jvm->RegisterWindow(window, &new_id);
if (NS_FAILED(res)) return res;
//if (m_id != 0 && new_id != m_id) m_jvm->UnregisterWindow(m_id);
m_id = new_id;
}
else
{
if (m_id != 0) m_jvm->UnregisterWindow(m_id);
m_id = 0;
}
return m_jobject->SetWindow(m_id);
}
NS_IMETHODIMP
nsAppletHTMLObject::NewStream(nsIPluginStreamListener** listener)
{
OJI_LOG("nsAppletHTMLObject::NewStream");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsAppletHTMLObject::Print(nsPluginPrint* platformPrint)
{
OJI_LOG("nsAppletHTMLObject::Print");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsAppletHTMLObject::GetValue(nsPluginInstanceVariable variable, void *value)
{
OJI_LOG2("nsAppletHTMLObject::GetValue: %d", variable);
if (variable == nsPluginInstanceVariable_DoCacheBool)
{
//OJI_LOG("SET NO PLUGIN CACHING");
*(PRBool*)value = PR_FALSE;
return NS_OK;
}
return NS_OK;
}
NS_IMETHODIMP
nsAppletHTMLObject::HandleEvent(nsPluginEvent* event, PRBool* handled)
{
OJI_LOG("nsAppletHTMLObject::HandleEvent");
return NS_ERROR_NOT_IMPLEMENTED;
}
nsJavaObjectType
nsAppletHTMLObject::mapType(nsPluginTagType pluginType)
{
switch (pluginType)
{
case nsPluginTagType_Applet:
return nsJavaObjectType_Applet;
case nsPluginTagType_Object:
return nsJavaObjectType_Object;
case nsPluginTagType_Embed:
return nsJavaObjectType_Embed;
default:
return nsJavaObjectType_Unknown;
}
}
/* HERE INTERTHREAD PROXY STUFF FOLLOWS */
// utility proxy class
class nsJavaPluginInstanceProxy : public nsIJavaPluginInstanceProxy
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIJAVAPLUGININSTANCEPROXY
nsJavaPluginInstanceProxy();
virtual ~nsJavaPluginInstanceProxy();
NS_IMETHOD Init(nsAppletHTMLObject* owner);
protected:
nsAppletHTMLObject* m_owner;
};
NS_IMPL_THREADSAFE_ISUPPORTS1(nsJavaPluginInstanceProxy,
nsIJavaPluginInstanceProxy);
nsJavaPluginInstanceProxy::nsJavaPluginInstanceProxy()
{
NS_INIT_ISUPPORTS();
}
NS_IMETHODIMP
nsJavaPluginInstanceProxy::Init(nsAppletHTMLObject* owner)
{
m_owner = owner;
NS_ADDREF(owner);
return NS_OK;
}
nsJavaPluginInstanceProxy::~nsJavaPluginInstanceProxy()
{
NS_RELEASE(m_owner);
}
NS_IMETHODIMP
nsJavaPluginInstanceProxy::ShowDocument(const char* url,
const char* target)
{
return m_owner->doShowDocument(url, target);
}
NS_IMETHODIMP
nsJavaPluginInstanceProxy::ShowStatus(const char* status)
{
return m_owner->doShowStatus(status);
}
NS_IMETHODIMP
nsJavaPluginInstanceProxy::GetJSThread(jint* jstid)
{
return m_owner->doGetJSThread(jstid);
}
// Here follows thread-safe versions of methods of plugin API
NS_IMETHODIMP
nsAppletHTMLObject::ShowStatus(const char* status)
{
nsresult rv = NS_OK;
if (m_dead) return NS_ERROR_FAILURE;
if (PR_GetCurrentThread() == m_mainThread) return doShowStatus(status);
nsCOMPtr<nsJavaPluginInstanceProxy> inst =
new nsJavaPluginInstanceProxy();
inst->Init(this);
nsCOMPtr<nsIJavaPluginInstanceProxy> instProxy;
nsCOMPtr<nsIProxyObjectManager> proxyObjectManager =
do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = proxyObjectManager->
GetProxyForObject(NS_UI_THREAD_EVENTQ,
NS_GET_IID(nsIJavaPluginInstanceProxy),
static_cast<nsISupports*>(inst),
PROXY_ASYNC | PROXY_ALWAYS,
getter_AddRefs(instProxy));
if (NS_FAILED(rv)) return rv;
//OJI_LOG(">>>>>>>>>>>>>>>>>>>");
rv = instProxy->ShowStatus(status);
//OJI_LOG2("ShowStatus(%s) done ", status);
return rv;
}
NS_IMETHODIMP
nsAppletHTMLObject::ShowDocument(const char* url,
const char* target)
{
nsresult rv = NS_OK;
if (m_dead) return NS_ERROR_FAILURE;
if (PR_GetCurrentThread() == m_mainThread)
return doShowDocument(url, target);
nsCOMPtr<nsJavaPluginInstanceProxy> inst =
new nsJavaPluginInstanceProxy();
inst->Init(this);
nsCOMPtr<nsIJavaPluginInstanceProxy> instProxy;
nsCOMPtr<nsIProxyObjectManager> proxyObjectManager =
do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv);
rv = proxyObjectManager->
GetProxyForObject(NS_UI_THREAD_EVENTQ,
NS_GET_IID(nsIJavaPluginInstanceProxy),
static_cast<nsISupports*>(inst),
PROXY_SYNC | PROXY_ALWAYS,
getter_AddRefs(instProxy));
if (NS_FAILED(rv)) return rv;
rv = instProxy->ShowDocument(url, target);
return rv;
}
NS_IMETHODIMP
nsAppletHTMLObject::GetJSThread(jint* jstid)
{
PRUint32 jsThreadID = 0;
if (m_dead) return NS_ERROR_FAILURE;
if (NS_SUCCEEDED(m_peer2->GetJSThread(&jsThreadID)))
*jstid = (jint)(jsThreadID);
return NS_OK;
/*
nsresult rv = NS_OK;
if (m_dead) return NS_ERROR_FAILURE;
nsCOMPtr<nsJavaPluginInstanceProxy> inst =
new nsJavaPluginInstanceProxy();
inst->Init(this);
nsCOMPtr<nsIJavaPluginInstanceProxy> instProxy;
NS_WITH_SERVICE(nsIProxyObjectManager, proxyObjectManager,
kProxyObjectManagerCID, &rv);
rv = proxyObjectManager->
GetProxyForObject(NS_UI_THREAD_EVENTQ,
NS_GET_IID(nsIJavaPluginInstanceProxy),
static_cast<nsISupports*>(inst),
PROXY_SYNC | PROXY_ALWAYS,
getter_AddRefs(instProxy));
if (NS_FAILED(rv)) return rv;
rv = instProxy->GetJSThread(jstid);
return rv; */
}
// Here follows thread-unsafe versions of methods of plugin API
NS_IMETHODIMP
nsAppletHTMLObject::doShowStatus(const char* status)
{
if (m_dead) return NS_ERROR_FAILURE;
return m_peer->ShowStatus(status);
}
NS_IMETHODIMP
nsAppletHTMLObject::doShowDocument(const char* url,
const char* target)
{
if (m_dead) return NS_ERROR_FAILURE;
return m_mgr->GetURL((nsIPluginInstance*)this, url, target,
NULL, NULL, NULL, PR_FALSE);
}
NS_IMETHODIMP
nsAppletHTMLObject::doGetJSThread(jint* jstid)
{
PRUint32 jsThreadID = 0;
if (m_dead) return NS_ERROR_FAILURE;
if (NS_SUCCEEDED(m_peer2->GetJSThread(&jsThreadID)))
*jstid = (jint)(jsThreadID);
return NS_OK;
}
NS_IMETHODIMP
nsAppletHTMLObject::GetJavaObject(jobject *result)
{
if (!result || !m_jobject) return NS_ERROR_FAILURE;
return m_jobject->GetJavaPeer(result);
}
NS_IMETHODIMP
nsAppletHTMLObject::GetText(const char* *result)
{
OJI_LOG("nsAppletHTMLObject::GetText");
return NS_OK;
}