diff --git a/mozilla/java/webclient/src_moz/DocumentLoaderObserverImpl.cpp b/mozilla/java/webclient/src_moz/DocumentLoaderObserverImpl.cpp index 008adccd5cf..24857a85c83 100644 --- a/mozilla/java/webclient/src_moz/DocumentLoaderObserverImpl.cpp +++ b/mozilla/java/webclient/src_moz/DocumentLoaderObserverImpl.cpp @@ -1,360 +1,370 @@ -/* -*- 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 RaptorCanvas. - * - * The Initial Developer of the Original Code is Kirk Baker and - * Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are - * Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All - * Rights Reserved. - * - * Contributor(s): Kirk Baker - * Ian Wilkinson - * Mark Lin - * Mark Goddard - * Ed Burns - * Ann Sunhachawee - */ - -#include "DocumentLoaderObserverImpl.h" - -#include "nsString.h" -#include "jni_util.h" -#include "dom_util.h" -#include "nsActions.h" - -#include "nsIDOMDocument.h" -#include "nsIDOMEventTarget.h" - -#include "prlog.h" // for PR_ASSERT - -jlong DocumentLoaderObserverImpl::maskValues[] = { -1L }; - -char *DocumentLoaderObserverImpl::maskNames[] = { - "START_DOCUMENT_LOAD_EVENT_MASK", - "END_DOCUMENT_LOAD_EVENT_MASK", - "START_URL_LOAD_EVENT_MASK", - "END_URL_LOAD_EVENT_MASK", - "PROGRESS_URL_LOAD_EVENT_MASK", - "STATUS_URL_LOAD_EVENT_MASK", - "UNKNOWN_CONTENT_EVENT_MASK", - "FETCH_INTERRUPT_EVENT_MASK", - nsnull -}; - -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); -static NS_DEFINE_IID(kIDocumentLoaderObserverIID, NS_IDOCUMENT_LOADER_OBSERVER_IID); -static NS_DEFINE_IID(kIDocumentLoaderObserverImplIID, NS_IDOCLOADEROBSERVERIMPL_IID); - -NS_IMPL_ADDREF(DocumentLoaderObserverImpl); -NS_IMPL_RELEASE(DocumentLoaderObserverImpl); - -DocumentLoaderObserverImpl::DocumentLoaderObserverImpl() : mRefCnt(1), -mTarget(nsnull), mMouseListener(nsnull) { -} - -DocumentLoaderObserverImpl::DocumentLoaderObserverImpl(JNIEnv *env, - WebShellInitContext *yourInitContext) : - mJNIEnv(env), mInitContext(yourInitContext), mTarget(nsnull), - mMouseListener(nsnull) -{ - if (nsnull == gVm) { // declared in jni_util.h - ::util_GetJavaVM(env, &gVm); // save this vm reference away for the callback! - } -#ifndef BAL_INTERFACE - PR_ASSERT(gVm); -#endif - - if (-1 == maskValues[0]) { - util_InitializeEventMaskValuesFromClass("org/mozilla/webclient/DocumentLoadEvent", - maskNames, maskValues); - } - mRefCnt = 1; // PENDING(edburns): not sure about how right this is to do. -} - -NS_IMETHODIMP DocumentLoaderObserverImpl::QueryInterface(REFNSIID aIID, - void** aInstance) -{ - if (nsnull == aInstance) - return NS_ERROR_NULL_POINTER; - - *aInstance = nsnull; - - - if (aIID.Equals(kIDocumentLoaderObserverIID)) { - *aInstance = (void*) ((nsIDocumentLoaderObserver*)this); - NS_ADDREF_THIS(); - return NS_OK; - } - else if (aIID.Equals(kIDocumentLoaderObserverImplIID)) { - *aInstance = (void*) ((DocumentLoaderObserverImpl*)this); - NS_ADDREF_THIS(); - return NS_OK; - } - - return NS_NOINTERFACE; -} - - - /* nsIDocumentLoaderObserver methods */ -NS_IMETHODIMP DocumentLoaderObserverImpl::OnStartDocumentLoad(nsIDocumentLoader* loader, - nsIURI* aURL, - const char* aCommand) -{ -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("DocumentLoaderObserverImpl.cpp: OnStartDocumentLoad\n")); - } -#endif - // If we don't have a target, don't take any action - if (nsnull == mTarget) { - return NS_OK; - } - - char *urlStr = nsnull; - jobject urlJStr = nsnull; - if (nsnull != aURL) { - - // IMPORTANT: do not use initContext->env here since it comes - // from another thread. Use JNU_GetEnv instead. - - JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION_1_2); - - aURL->GetSpec(&urlStr); - if (nsnull != urlStr) { - urlJStr = (jobject) ::util_NewStringUTF(env, urlStr); - ::Recycle(urlStr); - } - } - util_SendEventToJava(mInitContext->env, - mInitContext->nativeEventThread, mTarget, - maskValues[START_DOCUMENT_LOAD_EVENT_MASK], urlJStr); - - if (urlJStr) { - ::util_DeleteStringUTF(mInitContext->env, (jstring) urlJStr); - } - - return NS_OK; -} - -NS_IMETHODIMP DocumentLoaderObserverImpl::OnEndDocumentLoad(nsIDocumentLoader* loader, - nsIChannel* channel, - nsresult aStatus) -{ -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("!!DocumentLoaderObserverImpl.cpp: OnEndDocumentLoad\n")); - } -#endif - // if we have a mouse listener - if (mMouseListener) { - // install the mouse listener into mozilla - - nsCOMPtr doc; - PR_ASSERT(mMouseListener); - - if (nsnull == loader) { - // NOT really ok, but we can't do anything. - return NS_OK; - } - - if (!(doc = dom_getDocumentFromLoader(loader))) { - // NOT really ok, but we can't do anything. - return NS_OK; - } - nsCOMPtr domEventTarget; - nsresult rv; - - rv = doc->QueryInterface(NS_GET_IID(nsIDOMEventTarget), - getter_AddRefs(domEventTarget)); - if (NS_FAILED(rv) || !domEventTarget) { - return NS_OK; - } - nsAutoString eType("mouseover"); - domEventTarget->AddEventListener(eType, mMouseListener, PR_FALSE); - - } // end of "install mouse listener" - - // If we don't have a target, don't take any action - if (nsnull == mTarget) { - return NS_OK; - } - - util_SendEventToJava(mInitContext->env, - mInitContext->nativeEventThread, mTarget, - maskValues[END_DOCUMENT_LOAD_EVENT_MASK], nsnull); - return NS_OK; -} - -NS_IMETHODIMP DocumentLoaderObserverImpl::OnStartURLLoad(nsIDocumentLoader* loader, - nsIChannel* channel) -{ -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("!DocumentLoaderObserverImpl: OnStartURLLoad\n")); - } -#endif - // If we don't have a target, don't take any action - if (nsnull == mTarget) { - return NS_OK; - } - - util_SendEventToJava(mInitContext->env, mInitContext->nativeEventThread, mTarget, - maskValues[START_URL_LOAD_EVENT_MASK], nsnull); - - return NS_OK; -} - -NS_IMETHODIMP DocumentLoaderObserverImpl::OnProgressURLLoad(nsIDocumentLoader* loader, - nsIChannel* channel, - PRUint32 aProgress, - PRUint32 aProgressMax) -{ -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("!DocumentLoaderObserverImpl: OnProgressURLLoad\n")); - } -#endif - // If we don't have a target, don't take any action - if (nsnull == mTarget) { - return NS_OK; - } - - util_SendEventToJava(mInitContext->env, mInitContext->nativeEventThread, mTarget, - maskValues[PROGRESS_URL_LOAD_EVENT_MASK], nsnull); - - - return NS_OK; -} - -NS_IMETHODIMP DocumentLoaderObserverImpl::OnStatusURLLoad(nsIDocumentLoader* loader, - nsIChannel* channel, - nsString& aMsg) -{ -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("!DocumentLoaderObserverImpl: OnStatusURLLoad: %S\n", - aMsg.GetUnicode())); - } -#endif - // If we don't have a target, don't take any action - if (nsnull == mTarget) { - return NS_OK; - } - - int length = aMsg.Length(); - - // IMPORTANT: do not use initContext->env here since it comes - // from another thread. Use JNU_GetEnv instead. - - JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION_1_2); - jstring statusMessage = ::util_NewString(env, (const jchar *) - aMsg.GetUnicode(), length); - - util_SendEventToJava(mInitContext->env, mInitContext->nativeEventThread, mTarget, - maskValues[STATUS_URL_LOAD_EVENT_MASK], (jobject) statusMessage); - - if (statusMessage) { - ::util_DeleteString(mInitContext->env, statusMessage); - } - return NS_OK; -} - -NS_IMETHODIMP DocumentLoaderObserverImpl::OnEndURLLoad(nsIDocumentLoader* loader, - nsIChannel* channel, - nsresult aStatus) -{ -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("!DocumentLoaderObserverImpl: OnEndURLLoad\n")); - } -#endif - // If we don't have a target, don't take any action - if (nsnull == mTarget) { - return NS_OK; - } - - util_SendEventToJava(mInitContext->env, mInitContext->nativeEventThread, mTarget, - maskValues[END_URL_LOAD_EVENT_MASK], nsnull); - - return NS_OK; -} - -NS_IMETHODIMP DocumentLoaderObserverImpl::HandleUnknownContentType(nsIDocumentLoader* loader, - nsIChannel* channel, - const char *aContentType, - const char *aCommand) -{ -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("!DocumentLoaderObserverImpl: HandleUnknownContentType\n")); - } -#endif - // If we don't have a target, don't take any action - if (nsnull == mTarget) { - return NS_OK; - } - - util_SendEventToJava(mInitContext->env, mInitContext->nativeEventThread, mTarget, - maskValues[UNKNOWN_CONTENT_EVENT_MASK], nsnull); - - return NS_OK; -} - -// -// Methods from DocumentLoaderObserverImpl -// - -NS_IMETHODIMP DocumentLoaderObserverImpl::AddMouseListener(nsCOMPtr toAdd) -{ - nsresult rv = NS_ERROR_FAILURE; - - if (nsnull == toAdd) { - return rv; - } - - mMouseListener = toAdd; - - return NS_OK; -} - -NS_IMETHODIMP DocumentLoaderObserverImpl::RemoveMouseListener(nsCOMPtr toRemove) -{ - nsresult rv = NS_ERROR_FAILURE; - - return rv; -} - -NS_IMETHODIMP DocumentLoaderObserverImpl::SetTarget(jobject yourTarget) -{ - nsresult rv = NS_OK; - - mTarget = yourTarget; - - return rv; -} - -NS_IMETHODIMP DocumentLoaderObserverImpl::ClearTarget(void) -{ - nsresult rv = NS_OK; - - mTarget = nsnull; - - return rv; -} +/* -*- 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 RaptorCanvas. + * + * The Initial Developer of the Original Code is Kirk Baker and + * Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are + * Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All + * Rights Reserved. + * + * Contributor(s): Kirk Baker + * Ian Wilkinson + * Mark Lin + * Mark Goddard + * Ed Burns + * Ann Sunhachawee + */ + +#include "DocumentLoaderObserverImpl.h" + +#include "nsString.h" +#include "jni_util.h" +#include "dom_util.h" +#include "nsActions.h" + +#include "nsIDOMDocument.h" + +#include "prlog.h" // for PR_ASSERT + +jlong DocumentLoaderObserverImpl::maskValues[] = { -1L }; + +char *DocumentLoaderObserverImpl::maskNames[] = { + "START_DOCUMENT_LOAD_EVENT_MASK", + "END_DOCUMENT_LOAD_EVENT_MASK", + "START_URL_LOAD_EVENT_MASK", + "END_URL_LOAD_EVENT_MASK", + "PROGRESS_URL_LOAD_EVENT_MASK", + "STATUS_URL_LOAD_EVENT_MASK", + "UNKNOWN_CONTENT_EVENT_MASK", + "FETCH_INTERRUPT_EVENT_MASK", + nsnull +}; + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_IID(kIDocumentLoaderObserverIID, NS_IDOCUMENT_LOADER_OBSERVER_IID); +static NS_DEFINE_IID(kIDocumentLoaderObserverImplIID, NS_IDOCLOADEROBSERVERIMPL_IID); + +NS_IMPL_ADDREF(DocumentLoaderObserverImpl); +NS_IMPL_RELEASE(DocumentLoaderObserverImpl); + +DocumentLoaderObserverImpl::DocumentLoaderObserverImpl() : mRefCnt(1), +mTarget(nsnull), mMouseListener(nsnull), mDomEventTarget(nsnull) { +} + +DocumentLoaderObserverImpl::DocumentLoaderObserverImpl(JNIEnv *env, + WebShellInitContext *yourInitContext) : + mJNIEnv(env), mInitContext(yourInitContext), mTarget(nsnull), + mMouseListener(nsnull) +{ + if (nsnull == gVm) { // declared in jni_util.h + ::util_GetJavaVM(env, &gVm); // save this vm reference away for the callback! + } +#ifndef BAL_INTERFACE + PR_ASSERT(gVm); +#endif + + if (-1 == maskValues[0]) { + util_InitializeEventMaskValuesFromClass("org/mozilla/webclient/DocumentLoadEvent", + maskNames, maskValues); + } + mRefCnt = 1; // PENDING(edburns): not sure about how right this is to do. +} + +DocumentLoaderObserverImpl::~DocumentLoaderObserverImpl() +{ + RemoveMouseListener(); +} + +NS_IMETHODIMP DocumentLoaderObserverImpl::QueryInterface(REFNSIID aIID, + void** aInstance) +{ + if (nsnull == aInstance) + return NS_ERROR_NULL_POINTER; + + *aInstance = nsnull; + + + if (aIID.Equals(kIDocumentLoaderObserverIID)) { + *aInstance = (void*) ((nsIDocumentLoaderObserver*)this); + NS_ADDREF_THIS(); + return NS_OK; + } + else if (aIID.Equals(kIDocumentLoaderObserverImplIID)) { + *aInstance = (void*) ((DocumentLoaderObserverImpl*)this); + NS_ADDREF_THIS(); + return NS_OK; + } + + return NS_NOINTERFACE; +} + + + /* nsIDocumentLoaderObserver methods */ +NS_IMETHODIMP DocumentLoaderObserverImpl::OnStartDocumentLoad(nsIDocumentLoader* loader, + nsIURI* aURL, + const char* aCommand) +{ +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("DocumentLoaderObserverImpl.cpp: OnStartDocumentLoad\n")); + } +#endif + // If we don't have a target, don't take any action + if (nsnull == mTarget) { + return NS_OK; + } + + char *urlStr = nsnull; + jobject urlJStr = nsnull; + if (nsnull != aURL) { + + // IMPORTANT: do not use initContext->env here since it comes + // from another thread. Use JNU_GetEnv instead. + + JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION_1_2); + + aURL->GetSpec(&urlStr); + if (nsnull != urlStr) { + urlJStr = (jobject) ::util_NewStringUTF(env, urlStr); + ::Recycle(urlStr); + } + } + util_SendEventToJava(mInitContext->env, + mInitContext->nativeEventThread, mTarget, + maskValues[START_DOCUMENT_LOAD_EVENT_MASK], urlJStr); + + if (urlJStr) { + ::util_DeleteStringUTF(mInitContext->env, (jstring) urlJStr); + } + + return NS_OK; +} + +NS_IMETHODIMP DocumentLoaderObserverImpl::OnEndDocumentLoad(nsIDocumentLoader* loader, + nsIChannel* channel, + nsresult aStatus) +{ +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("!!DocumentLoaderObserverImpl.cpp: OnEndDocumentLoad\n")); + } +#endif + // if we have a mouse listener + if (mMouseListener) { + // install the mouse listener into mozilla + + nsCOMPtr doc; + PR_ASSERT(mMouseListener); + + if (nsnull == loader) { + // NOT really ok, but we can't do anything. + return NS_OK; + } + + if (!(doc = dom_getDocumentFromLoader(loader))) { + // NOT really ok, but we can't do anything. + return NS_OK; + } + nsresult rv; + + rv = doc->QueryInterface(NS_GET_IID(nsIDOMEventTarget), + getter_AddRefs(mDomEventTarget)); + if (NS_FAILED(rv) || !mDomEventTarget) { + return NS_OK; + } + nsAutoString eType("mouseover"); + mDomEventTarget->AddEventListener(eType, mMouseListener, PR_FALSE); + + } // end of "install mouse listener" + + // If we don't have a target, don't take any action + if (nsnull == mTarget) { + return NS_OK; + } + + util_SendEventToJava(mInitContext->env, + mInitContext->nativeEventThread, mTarget, + maskValues[END_DOCUMENT_LOAD_EVENT_MASK], nsnull); + return NS_OK; +} + +NS_IMETHODIMP DocumentLoaderObserverImpl::OnStartURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel) +{ +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("!DocumentLoaderObserverImpl: OnStartURLLoad\n")); + } +#endif + // If we don't have a target, don't take any action + if (nsnull == mTarget) { + return NS_OK; + } + + util_SendEventToJava(mInitContext->env, mInitContext->nativeEventThread, mTarget, + maskValues[START_URL_LOAD_EVENT_MASK], nsnull); + + return NS_OK; +} + +NS_IMETHODIMP DocumentLoaderObserverImpl::OnProgressURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel, + PRUint32 aProgress, + PRUint32 aProgressMax) +{ +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("!DocumentLoaderObserverImpl: OnProgressURLLoad\n")); + } +#endif + // If we don't have a target, don't take any action + if (nsnull == mTarget) { + return NS_OK; + } + + util_SendEventToJava(mInitContext->env, mInitContext->nativeEventThread, mTarget, + maskValues[PROGRESS_URL_LOAD_EVENT_MASK], nsnull); + + + return NS_OK; +} + +NS_IMETHODIMP DocumentLoaderObserverImpl::OnStatusURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel, + nsString& aMsg) +{ +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("!DocumentLoaderObserverImpl: OnStatusURLLoad: %S\n", + aMsg.GetUnicode())); + } +#endif + // If we don't have a target, don't take any action + if (nsnull == mTarget) { + return NS_OK; + } + + int length = aMsg.Length(); + + // IMPORTANT: do not use initContext->env here since it comes + // from another thread. Use JNU_GetEnv instead. + + JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION_1_2); + jstring statusMessage = ::util_NewString(env, (const jchar *) + aMsg.GetUnicode(), length); + + util_SendEventToJava(mInitContext->env, mInitContext->nativeEventThread, mTarget, + maskValues[STATUS_URL_LOAD_EVENT_MASK], (jobject) statusMessage); + + if (statusMessage) { + ::util_DeleteString(mInitContext->env, statusMessage); + } + return NS_OK; +} + +NS_IMETHODIMP DocumentLoaderObserverImpl::OnEndURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel, + nsresult aStatus) +{ +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("!DocumentLoaderObserverImpl: OnEndURLLoad\n")); + } +#endif + // If we don't have a target, don't take any action + if (nsnull == mTarget) { + return NS_OK; + } + + util_SendEventToJava(mInitContext->env, mInitContext->nativeEventThread, mTarget, + maskValues[END_URL_LOAD_EVENT_MASK], nsnull); + + return NS_OK; +} + +NS_IMETHODIMP DocumentLoaderObserverImpl::HandleUnknownContentType(nsIDocumentLoader* loader, + nsIChannel* channel, + const char *aContentType, + const char *aCommand) +{ +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("!DocumentLoaderObserverImpl: HandleUnknownContentType\n")); + } +#endif + // If we don't have a target, don't take any action + if (nsnull == mTarget) { + return NS_OK; + } + + util_SendEventToJava(mInitContext->env, mInitContext->nativeEventThread, mTarget, + maskValues[UNKNOWN_CONTENT_EVENT_MASK], nsnull); + + return NS_OK; +} + +// +// Methods from DocumentLoaderObserverImpl +// + +NS_IMETHODIMP DocumentLoaderObserverImpl::AddMouseListener(nsCOMPtr toAdd) +{ + nsresult rv = NS_ERROR_FAILURE; + + if (nsnull == toAdd) { + return rv; + } + + mMouseListener = toAdd; + + return NS_OK; +} + +NS_IMETHODIMP DocumentLoaderObserverImpl::RemoveMouseListener() +{ + nsresult rv = NS_OK; + + if (mDomEventTarget && mMouseListener) { + nsAutoString eType("mouseover"); + mDomEventTarget->RemoveEventListener(eType, mMouseListener, PR_FALSE); + mDomEventTarget = nsnull; + mMouseListener = nsnull; + } + + return rv; +} + +NS_IMETHODIMP DocumentLoaderObserverImpl::SetTarget(jobject yourTarget) +{ + nsresult rv = NS_OK; + + mTarget = yourTarget; + + return rv; +} + +NS_IMETHODIMP DocumentLoaderObserverImpl::ClearTarget(void) +{ + nsresult rv = NS_OK; + + mTarget = nsnull; + + return rv; +} diff --git a/mozilla/java/webclient/src_moz/EventRegistration.cpp b/mozilla/java/webclient/src_moz/EventRegistration.cpp index e07a9c4c879..d711bd69baf 100644 --- a/mozilla/java/webclient/src_moz/EventRegistration.cpp +++ b/mozilla/java/webclient/src_moz/EventRegistration.cpp @@ -1,143 +1,161 @@ -/* -*- 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 RaptorCanvas. - * - * The Initial Developer of the Original Code is Kirk Baker and - * Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are - * Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All - * Rights Reserved. - * - * Contributor(s): Kirk Baker - * Ian Wilkinson - * Mark Lin - * Mark Goddard - * Ed Burns - * Ann Sunhachawee - */ - -#include "EventRegistration.h" - -#include "nsActions.h" -#include "nsCOMPtr.h" -#include "DocumentLoaderObserverImpl.h" -#include "DOMMouseListenerImpl.h" - -static NS_DEFINE_IID(kIDocumentLoaderObserverImplIID, NS_IDOCLOADEROBSERVERIMPL_IID); - -void addDocumentLoadListener(JNIEnv *env, WebShellInitContext *initContext, - jobject listener) -{ - if (initContext == nsnull) { - ::util_ThrowExceptionToJava(env, "Exception: null initContext passed toaddDocumentLoadListener"); - return; - } - - if (initContext->initComplete) { - - - PR_ASSERT(initContext->nativeEventThread); - nsresult rv; - nsCOMPtr curObserver; - nsCOMPtr myListener = nsnull; - - PR_ASSERT(nsnull != initContext->docShell); - - // tricky logic to accomodate "piggybacking" a mouseListener. - - // See if there already is a DocListener - rv = initContext->docShell->GetDocLoaderObserver(getter_AddRefs(curObserver)); - if (NS_FAILED(rv) || !curObserver) { - // if there is no listener, we need to create and add it now - - // create the c++ "peer" for the DocumentLoadListener, which is an - // nsIDocumentLoaderObserver. - curObserver = new DocumentLoaderObserverImpl(env, initContext); - if (nsnull == curObserver) { - return; - } - - wsAddDocLoaderObserverEvent *actionEvent = - new wsAddDocLoaderObserverEvent(initContext->docShell, - curObserver); - - PLEvent * event = (PLEvent*) *actionEvent; - - ::util_PostSynchronousEvent(initContext, event); - } - - if (curObserver) { - // if we have an observer (either just created, or from mozilla), - // install the target. - - rv = curObserver->QueryInterface(kIDocumentLoaderObserverImplIID, - getter_AddRefs(myListener)); - if (NS_SUCCEEDED(rv) && myListener) { - myListener->SetTarget(listener); - } - } - } -} - -void addMouseListener(JNIEnv *env, WebShellInitContext *initContext, - jobject listener) -{ - if (initContext == nsnull) { - ::util_ThrowExceptionToJava(env, "Exception: null initContext passed toaddDocumentLoadListener"); - return; - } - - if (initContext->initComplete) { - nsresult rv; - nsCOMPtr curObserver; - nsCOMPtr myListener = nsnull; - - PR_ASSERT(nsnull != initContext->docShell); - - // See if there already is a DocListener - rv = initContext->docShell->GetDocLoaderObserver(getter_AddRefs(curObserver)); - if (NS_SUCCEEDED(rv) && curObserver) { - - // if so, se if it's something we added - rv = curObserver->QueryInterface(kIDocumentLoaderObserverImplIID, - getter_AddRefs(myListener)); - } - else { - - // if not, we need to create a listener - myListener = new DocumentLoaderObserverImpl(env, initContext); - // note that we don't call setTarget, since this - // DocumentLoaderObserver is just for getting mouse events - - // install our listener into mozilla - wsAddDocLoaderObserverEvent *actionEvent = - new wsAddDocLoaderObserverEvent(initContext->docShell, - myListener); - - PLEvent * event = (PLEvent*) *actionEvent; - - ::util_PostSynchronousEvent(initContext, event); - } - - if (nsnull == myListener) { - // either the new failed, or the currently installed listener - // wasn't installed by us. Either way, do nothing. - return; - } - // we have a listener - - nsCOMPtr mouseListener = - new DOMMouseListenerImpl(env, initContext, listener); - - myListener->AddMouseListener(mouseListener); - } -} +/* -*- 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 RaptorCanvas. + * + * The Initial Developer of the Original Code is Kirk Baker and + * Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are + * Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All + * Rights Reserved. + * + * Contributor(s): Kirk Baker + * Ian Wilkinson + * Mark Lin + * Mark Goddard + * Ed Burns + * Ann Sunhachawee + */ + +#include "EventRegistration.h" + +#include "nsActions.h" +#include "nsCOMPtr.h" +#include "DocumentLoaderObserverImpl.h" +#include "DOMMouseListenerImpl.h" + +static NS_DEFINE_IID(kIDocumentLoaderObserverImplIID, NS_IDOCLOADEROBSERVERIMPL_IID); + +void addDocumentLoadListener(JNIEnv *env, WebShellInitContext *initContext, + jobject listener) +{ + if (initContext->initComplete) { + + + PR_ASSERT(initContext->nativeEventThread); + nsresult rv; + nsCOMPtr curObserver; + nsCOMPtr myListener = nsnull; + + PR_ASSERT(nsnull != initContext->docShell); + + // tricky logic to accomodate "piggybacking" a mouseListener. + + // See if there already is a DocListener + rv = initContext->docShell->GetDocLoaderObserver(getter_AddRefs(curObserver)); + if (NS_FAILED(rv) || !curObserver) { + // if there is no listener, we need to create and add it now + + // create the c++ "peer" for the DocumentLoadListener, which is an + // nsIDocumentLoaderObserver. + curObserver = new DocumentLoaderObserverImpl(env, initContext); + if (nsnull == curObserver) { + return; + } + + wsAddDocLoaderObserverEvent *actionEvent = + new wsAddDocLoaderObserverEvent(initContext->docShell, + curObserver); + + PLEvent * event = (PLEvent*) *actionEvent; + + ::util_PostSynchronousEvent(initContext, event); + } + + if (curObserver) { + // if we have an observer (either just created, or from mozilla), + // install the target. + + rv = curObserver->QueryInterface(kIDocumentLoaderObserverImplIID, + getter_AddRefs(myListener)); + if (NS_SUCCEEDED(rv) && myListener) { + myListener->SetTarget(listener); + } + } + } +} + +void addMouseListener(JNIEnv *env, WebShellInitContext *initContext, + jobject listener) +{ + if (initContext->initComplete) { + nsresult rv; + nsCOMPtr curObserver; + nsCOMPtr myListener = nsnull; + + PR_ASSERT(nsnull != initContext->docShell); + + // See if there already is a DocListener + rv = initContext->docShell->GetDocLoaderObserver(getter_AddRefs(curObserver)); + if (NS_SUCCEEDED(rv) && curObserver) { + + // if so, se if it's something we added + rv = curObserver->QueryInterface(kIDocumentLoaderObserverImplIID, + getter_AddRefs(myListener)); + } + else { + + // if not, we need to create a listener + myListener = new DocumentLoaderObserverImpl(env, initContext); + // note that we don't call setTarget, since this + // DocumentLoaderObserver is just for getting mouse events + + // install our listener into mozilla + wsAddDocLoaderObserverEvent *actionEvent = + new wsAddDocLoaderObserverEvent(initContext->docShell, + myListener); + + PLEvent * event = (PLEvent*) *actionEvent; + + ::util_PostSynchronousEvent(initContext, event); + } + + if (nsnull == myListener) { + // either the new failed, or the currently installed listener + // wasn't installed by us. Either way, do nothing. + return; + } + // we have a listener + + nsCOMPtr mouseListener = + new DOMMouseListenerImpl(env, initContext, listener); + + myListener->AddMouseListener(mouseListener); + } +} + +void removeAllListeners(JNIEnv *env, WebShellInitContext *initContext) +{ + if (initContext->initComplete) { + nsresult rv; + nsCOMPtr curObserver; + nsCOMPtr myListener = nsnull; + + PR_ASSERT(nsnull != initContext->docShell); + + // See if there already is a DocListener + rv = initContext->docShell->GetDocLoaderObserver(getter_AddRefs(curObserver)); + if (NS_SUCCEEDED(rv) && curObserver) { + + // if so, see if it's something we added + rv = curObserver->QueryInterface(kIDocumentLoaderObserverImplIID, + getter_AddRefs(myListener)); + } + if (myListener) { + // remove the doc listener from the docShell + rv = initContext->docShell->SetDocLoaderObserver(nsnull); + // remove the mouse listener from the doc listener + myListener->RemoveMouseListener(); + myListener = nsnull; + } + } + +} diff --git a/mozilla/java/webclient/src_moz/NativeEventThread.cpp b/mozilla/java/webclient/src_moz/NativeEventThread.cpp index cf2f7de18ea..4c9f59f0908 100644 --- a/mozilla/java/webclient/src_moz/NativeEventThread.cpp +++ b/mozilla/java/webclient/src_moz/NativeEventThread.cpp @@ -1,525 +1,539 @@ -/* -*- 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 RaptorCanvas. - * - * The Initial Developer of the Original Code is Kirk Baker and - * Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are - * Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All - * Rights Reserved. - * - * Contributor(s): Kirk Baker - * Ian Wilkinson - * Mark Lin - * Mark Goddard - * Ed Burns - * Ann Sunhachawee - */ - -#include "NativeEventThread.h" - -#include "jni_util.h" -#include "EventRegistration.h" // event callbacks - - - -#ifdef XP_PC -#include -#endif - -#include "nsAppShellCIDs.h" // for NS_SESSIONHISTORY_CID -#include "nsIBaseWindow.h" // to get methods like SetVisibility -#include "nsCOMPtr.h" // to get nsIBaseWindow from webshell -//nsIDocShell is included in jni_util.h -#include "nsIEventQueueService.h" // for PLEventQueue -#include "nsIPref.h" // for preferences -#include "nsRepository.h" -#include "nsIServiceManager.h" // for do_GetService -#include "nsISessionHistory.h" // for history -#include "nsIThread.h" // for PRThread -//nsIWebShell is included in jni_util.h - -#include "prlog.h" // for PR_ASSERT - -#ifdef XP_UNIX -#include -#include "gdksuperwin.h" -#include "gtkmozarea.h" -#endif - -static NS_DEFINE_IID(kWebShellCID, NS_WEB_SHELL_CID); -static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID); - -static NS_DEFINE_IID(kISessionHistoryIID, NS_ISESSIONHISTORY_IID); -static NS_DEFINE_CID(kSessionHistoryCID, NS_SESSIONHISTORY_CID); - -// -// Local functions -// - -/** - - * Called from InitMozillaStuff(). - - */ - -int processEventLoop(WebShellInitContext * initContext); - -/** - - * Called from Java nativeInitialize to create the webshell, history, - * prefs, and other mozilla things, then start the event loop. - - */ - -nsresult InitMozillaStuff (WebShellInitContext * arg); - -// -// Local data -// - -nsISessionHistory *gHistory = nsnull; - -char * errorMessages[] = { - "No Error", - "Could not obtain the event queue service.", - "Unable to create the WebShell instance.", - "Unable to initialize the WebShell instance.", - "Unable to show the WebShell." -}; - -/** - - * a null terminated array of listener interfaces we support. - - * PENDING(): this should probably live in EventRegistration.h - - * PENDING(edburns): need to abstract this out so we can use it from uno - * and JNI. - - */ - -const char *gSupportedListenerInterfaces[] = { - "org/mozilla/webclient/DocumentLoadListener", - "java/awt/event/MouseListener", - nsnull -}; - -// these index into the gSupportedListenerInterfaces array, this should -// also live in EventRegistration.h - -typedef enum { - DOCUMENT_LOAD_LISTENER = 0, - MOUSE_LISTENER, - LISTENER_NOT_FOUND -} LISTENER_CLASSES; - - -// -// JNI methods -// - -JNIEXPORT void JNICALL Java_org_mozilla_webclient_wrapper_1native_NativeEventThread_nativeInitialize -(JNIEnv *env, jobject obj, jint webShellPtr) -{ - nsresult rv = NS_ERROR_FAILURE; - WebShellInitContext * initContext = (WebShellInitContext *) webShellPtr; - - if (nsnull == initContext) { - ::util_ThrowExceptionToJava(env, - "NULL webShellPtr passed to nativeInitialize."); - return; - } - if (nsnull == gVm) { // declared in jni_util.h - ::util_GetJavaVM(env, &gVm); // save this vm reference - } - - rv = InitMozillaStuff(initContext); - if (NS_FAILED(rv)) { - ::util_ThrowExceptionToJava(env, - errorMessages[initContext->initFailCode]); - return; - } - - while (initContext->initComplete == FALSE) { - - ::PR_Sleep(PR_INTERVAL_NO_WAIT); - - if (initContext->initFailCode != 0) { - ::util_ThrowExceptionToJava(env, errorMessages[initContext->initFailCode]); - return; - } - } -} - -JNIEXPORT void JNICALL Java_org_mozilla_webclient_wrapper_1native_NativeEventThread_nativeProcessEvents -(JNIEnv *env, jobject obj, jint webShellPtr) -{ - WebShellInitContext * initContext = (WebShellInitContext *) webShellPtr; - - if (nsnull == initContext) { - ::util_ThrowExceptionToJava(env, - "NULL webShellPtr passed to nativeProcessEvents."); - return; - } - processEventLoop(initContext); -} - -/** - - *

This method takes the typedListener, which is a - * WebclientEventListener java subclass, figures out what type of - * subclass it is, using the gSupportedListenerInterfaces array, and - * calls the appropriate add*Listener local function.

- - *

PENDING(): we could do away with the switch statement using - * function pointers, or some other mechanism.

- - *

the NewGlobalRef call is very important, since the argument - * typedListener is used to call back into java, at another time, as a - * result of the a mozilla event being fired.

- - * PENDING(): implement nativeRemoveListener, which must call - * RemoveGlobalRef. - - * See the comments for EventRegistration.h:addDocumentLoadListener - - */ - -JNIEXPORT void JNICALL Java_org_mozilla_webclient_wrapper_1native_NativeEventThread_nativeAddListener -(JNIEnv *env, jobject obj, jint webShellPtr, jobject typedListener) -{ - WebShellInitContext *initContext = (WebShellInitContext *)webShellPtr; - - if (initContext == nsnull) { - ::util_ThrowExceptionToJava(env, "Exception: null initContext passed tonativeAddListener"); - return; - } - - if (nsnull == initContext->nativeEventThread) { - // store the java EventRegistrationImpl class in the initContext - initContext->nativeEventThread = - ::util_NewGlobalRef(env, obj); // VERY IMPORTANT!! - - // This enables the listener to call back into java - } - - jclass clazz = nsnull; - int listenerType = 0; - - while (nsnull != gSupportedListenerInterfaces[listenerType]) { - if (nsnull == - (clazz = - ::util_FindClass(env, - gSupportedListenerInterfaces[listenerType]))) { - return; - } - if (::util_IsInstanceOf(env, typedListener, clazz)) { - // We've got a winner! - break; - } - listenerType++; - } - - if (LISTENER_NOT_FOUND == (LISTENER_CLASSES) listenerType) { - ::util_ThrowExceptionToJava(env, "Exception: NativeEventThread.nativeAddListener(): can't find listener \n\tclass for argument"); - return; - } - - jobject globalRef = nsnull; - - // PENDING(edburns): make sure do DeleteGlobalRef on the removeListener - if (nsnull == (globalRef = ::util_NewGlobalRef(env, typedListener))) { - ::util_ThrowExceptionToJava(env, "Exception: NativeEventThread.nativeAddListener(): can't create NewGlobalRef\n\tfor argument"); - return; - } - - switch(listenerType) { - case DOCUMENT_LOAD_LISTENER: - addDocumentLoadListener(env, initContext, globalRef); - break; - case MOUSE_LISTENER: - addMouseListener(env, initContext, globalRef); - break; - } -} - -/** - - * This function processes methods inserted into WebShellInitContext's - * actionQueue. It is called once during the initialization of the - * NativeEventThread java thread, and infinitely in - * NativeEventThread.run()'s event loop. The call to PL_HandleEvent - * below, ends up calling the nsActionEvent subclass's handleEvent() - * method. After which it calls nsActionEvent::destroyEvent(). - - */ - -int processEventLoop(WebShellInitContext * initContext) -{ -#ifdef XP_UNIX - while(gtk_events_pending()) { - gtk_main_iteration(); - } -#else - // PENDING(mark): Does this work on the Mac? - MSG msg; - - if (::PeekMessage(&msg, nsnull, 0, 0, PM_NOREMOVE)) { - if (::GetMessage(&msg, nsnull, 0, 0)) { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - } -#endif - ::PR_Sleep(PR_INTERVAL_NO_WAIT); - - if ((initContext->initComplete) && (initContext->actionQueue)) { - - PL_ENTER_EVENT_QUEUE_MONITOR(initContext->actionQueue); - - if (::PL_EventAvailable(initContext->actionQueue)) { - - PLEvent * event = ::PL_GetEvent(initContext->actionQueue); - - if (event != nsnull) { - ::PL_HandleEvent(event); - } - } - - PL_EXIT_EVENT_QUEUE_MONITOR(initContext->actionQueue); - - } - if (initContext->stopThread) { - initContext->stopThread++; - - return 0; - } - return 1; -} - -// Ashu -#ifdef XP_UNIX -static void event_processor_callback(gpointer data, - gint source, - GdkInputCondition condition) { -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - "EventHandler: event_processor_callback()\n"); - } -#endif - nsIEventQueue *eventQueue = (nsIEventQueue*)data; - eventQueue->ProcessPendingEvents(); -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, "EventHandler: Done processing pending events\n"); - } -#endif -} -#endif -// - -nsresult InitMozillaStuff (WebShellInitContext * initContext) -{ - PR_ASSERT(gComponentManager); - - nsCOMPtr - aEventQService = do_GetService(NS_EVENTQUEUESERVICE_PROGID); - - // if we get here, we know that aEventQService is not null. - nsresult rv = NS_ERROR_FAILURE; - PRBool allowPlugins = PR_FALSE; - - //TODO Add tracing from nspr. - -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("InitMozillaStuff(%lx): Create the Event Queue for the UI thread...\n", - initContext)); - } -#endif - - // Create the Event Queue for the UI thread... - if (!aEventQService) { - initContext->initFailCode = kEventQueueError; - return rv; - } - - // Create the event queue. - rv = aEventQService->CreateThreadEventQueue(); - - initContext->embeddedThread = PR_GetCurrentThread(); - - // Create the action queue - if (initContext->embeddedThread) { - -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, ("InitMozillaStuff(%lx): embeddedThread != nsnull\n", initContext)); - } -#endif - if (initContext->actionQueue == nsnull) { -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, ("InitMozillaStuff(%lx): Create the action queue\n", initContext)); - } -#endif - // We need to do something different for Unix - nsIEventQueue * EQueue = nsnull; - - rv = aEventQService->GetThreadEventQueue(initContext->embeddedThread, - &EQueue); - if (NS_FAILED(rv)) { - initContext->initFailCode = kCreateWebShellError; - return rv; - } - -#ifdef XP_UNIX - gdk_input_add(EQueue->GetEventQueueSelectFD(), - GDK_INPUT_READ, - event_processor_callback, - EQueue); -#endif - - PLEventQueue * plEventQueue = nsnull; - - EQueue->GetPLEventQueue(&plEventQueue); - initContext->actionQueue = plEventQueue; - } - } - else { - initContext->initFailCode = kCreateWebShellError; - return NS_ERROR_UNEXPECTED; - } - -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("InitMozillaStuff(%lx): Create the WebShell...\n", initContext)); - } -#endif - // Create the WebShell. - rv = nsRepository::CreateInstance(kWebShellCID, nsnull, kIWebShellIID, getter_AddRefs(initContext->webShell)); - if (NS_FAILED(rv)) { - initContext->initFailCode = kCreateWebShellError; - return rv; - } - -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("InitMozillaStuff(%lx): Init the WebShell...\n", initContext)); - } -#endif - -#ifdef XP_UNIX - GdkSuperWin * superwin; - GtkMozArea * mozarea; - mozarea = (GtkMozArea *) initContext->gtkWinPtr; - superwin = mozarea->superwin; - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, ("Ashu Debugs - Inside InitMozillaStuff(%lx): - before Init Call...\n", initContext)); - } - rv = initContext->webShell->Init((nsNativeWidget *)superwin, initContext->x, initContext->y, initContext->w, initContext->h); - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, ("Ashu Debugs - Inside InitMozillaStuff(%lx): - after Init Call...\n", initContext)); - } -#else - rv = initContext->webShell->Init((nsNativeWidget *)initContext->parentHWnd, - initContext->x, initContext->y, initContext->w, initContext->h); -#endif - - - if (NS_FAILED(rv)) { - initContext->initFailCode = kInitWebShellError; - return rv; - } - -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("InitMozillaStuff(%lx): Install Prefs in the Webshell...\n", initContext)); - } -#endif - - nsCOMPtr prefs = do_GetService(NS_PREF_PROGID); - - if (prefs) { - if (nsnull == gComponentManager) { // only do this once per app. - prefs->ReadUserPrefs(); - } - // Set the prefs in the outermost webshell. - initContext->webShell->SetPrefs(prefs); - } - - if (nsnull == gHistory) { - rv = gComponentManager->CreateInstance(kSessionHistoryCID, nsnull, - kISessionHistoryIID, - (void**)&gHistory); - if (NS_FAILED(rv)) { - initContext->initFailCode = kHistoryWebShellError; - return rv; - } - } - initContext->webShell->SetSessionHistory(gHistory); - - // set the sessionHistory in the initContexn - initContext->sessionHistory = gHistory; - -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("InitMozillaStuff(%lx): Show the WebShell...\n", initContext)); - } -#endif - - nsCOMPtr baseWindow; - - rv = initContext->webShell->QueryInterface(NS_GET_IID(nsIBaseWindow), - getter_AddRefs(baseWindow)); - - if (NS_FAILED(rv)) { - initContext->initFailCode = kShowWebShellError; - return rv; - } - rv = baseWindow->SetVisibility(PR_TRUE); - if (NS_FAILED(rv)) { - initContext->initFailCode = kShowWebShellError; - return rv; - } - - // set the docShell - rv = initContext->webShell->QueryInterface(NS_GET_IID(nsIDocShell), - getter_AddRefs(initContext->docShell)); - - if (NS_FAILED(rv)) { - initContext->initFailCode = kHistoryWebShellError; - return rv; - } - - - initContext->initComplete = TRUE; - -#if DEBUG_RAPTOR_CANVAS - if (prLogModuleInfo) { - PR_LOG(prLogModuleInfo, 3, - ("InitMozillaStuff(%lx): enter event loop\n", initContext)); - } -#endif - - // Just need to loop once to clear out events before returning - processEventLoop(initContext); - - return rv; -} +/* -*- 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 RaptorCanvas. + * + * The Initial Developer of the Original Code is Kirk Baker and + * Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are + * Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All + * Rights Reserved. + * + * Contributor(s): Kirk Baker + * Ian Wilkinson + * Mark Lin + * Mark Goddard + * Ed Burns + * Ann Sunhachawee + */ + +#include "NativeEventThread.h" + +#include "jni_util.h" +#include "EventRegistration.h" // event callbacks + + + +#ifdef XP_PC +#include +#endif + +#include "nsAppShellCIDs.h" // for NS_SESSIONHISTORY_CID +#include "nsIBaseWindow.h" // to get methods like SetVisibility +#include "nsCOMPtr.h" // to get nsIBaseWindow from webshell +//nsIDocShell is included in jni_util.h +#include "nsIEventQueueService.h" // for PLEventQueue +#include "nsIPref.h" // for preferences +#include "nsRepository.h" +#include "nsIServiceManager.h" // for do_GetService +#include "nsISessionHistory.h" // for history +#include "nsIThread.h" // for PRThread +//nsIWebShell is included in jni_util.h + +#include "prlog.h" // for PR_ASSERT + +#ifdef XP_UNIX +#include +#include "gdksuperwin.h" +#include "gtkmozarea.h" +#endif + +static NS_DEFINE_IID(kWebShellCID, NS_WEB_SHELL_CID); +static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID); + +static NS_DEFINE_IID(kISessionHistoryIID, NS_ISESSIONHISTORY_IID); +static NS_DEFINE_CID(kSessionHistoryCID, NS_SESSIONHISTORY_CID); + +// +// Local functions +// + +/** + + * Called from InitMozillaStuff(). + + */ + +int processEventLoop(WebShellInitContext * initContext); + +/** + + * Called from Java nativeInitialize to create the webshell, history, + * prefs, and other mozilla things, then start the event loop. + + */ + +nsresult InitMozillaStuff (WebShellInitContext * arg); + +// +// Local data +// + +nsISessionHistory *gHistory = nsnull; + +char * errorMessages[] = { + "No Error", + "Could not obtain the event queue service.", + "Unable to create the WebShell instance.", + "Unable to initialize the WebShell instance.", + "Unable to show the WebShell." +}; + +/** + + * a null terminated array of listener interfaces we support. + + * PENDING(): this should probably live in EventRegistration.h + + * PENDING(edburns): need to abstract this out so we can use it from uno + * and JNI. + + */ + +const char *gSupportedListenerInterfaces[] = { + "org/mozilla/webclient/DocumentLoadListener", + "java/awt/event/MouseListener", + nsnull +}; + +// these index into the gSupportedListenerInterfaces array, this should +// also live in EventRegistration.h + +typedef enum { + DOCUMENT_LOAD_LISTENER = 0, + MOUSE_LISTENER, + LISTENER_NOT_FOUND +} LISTENER_CLASSES; + + +// +// JNI methods +// + +JNIEXPORT void JNICALL Java_org_mozilla_webclient_wrapper_1native_NativeEventThread_nativeInitialize +(JNIEnv *env, jobject obj, jint webShellPtr) +{ + nsresult rv = NS_ERROR_FAILURE; + WebShellInitContext * initContext = (WebShellInitContext *) webShellPtr; + + if (nsnull == initContext) { + ::util_ThrowExceptionToJava(env, + "NULL webShellPtr passed to nativeInitialize."); + return; + } + if (nsnull == gVm) { // declared in jni_util.h + ::util_GetJavaVM(env, &gVm); // save this vm reference + } + + rv = InitMozillaStuff(initContext); + if (NS_FAILED(rv)) { + ::util_ThrowExceptionToJava(env, + errorMessages[initContext->initFailCode]); + return; + } + + while (initContext->initComplete == FALSE) { + + ::PR_Sleep(PR_INTERVAL_NO_WAIT); + + if (initContext->initFailCode != 0) { + ::util_ThrowExceptionToJava(env, errorMessages[initContext->initFailCode]); + return; + } + } +} + +JNIEXPORT void JNICALL Java_org_mozilla_webclient_wrapper_1native_NativeEventThread_nativeProcessEvents +(JNIEnv *env, jobject obj, jint webShellPtr) +{ + WebShellInitContext * initContext = (WebShellInitContext *) webShellPtr; + + if (nsnull == initContext) { + ::util_ThrowExceptionToJava(env, + "NULL webShellPtr passed to nativeProcessEvents."); + return; + } + processEventLoop(initContext); +} + +/** + + *

This method takes the typedListener, which is a + * WebclientEventListener java subclass, figures out what type of + * subclass it is, using the gSupportedListenerInterfaces array, and + * calls the appropriate add*Listener local function.

+ + *

PENDING(): we could do away with the switch statement using + * function pointers, or some other mechanism.

+ + *

the NewGlobalRef call is very important, since the argument + * typedListener is used to call back into java, at another time, as a + * result of the a mozilla event being fired.

+ + * PENDING(): implement nativeRemoveListener, which must call + * RemoveGlobalRef. + + * See the comments for EventRegistration.h:addDocumentLoadListener + + */ + +JNIEXPORT void JNICALL Java_org_mozilla_webclient_wrapper_1native_NativeEventThread_nativeAddListener +(JNIEnv *env, jobject obj, jint webShellPtr, jobject typedListener) +{ + WebShellInitContext *initContext = (WebShellInitContext *)webShellPtr; + + if (initContext == nsnull) { + ::util_ThrowExceptionToJava(env, "Exception: null initContext passed tonativeAddListener"); + return; + } + + if (nsnull == initContext->nativeEventThread) { + // store the java EventRegistrationImpl class in the initContext + initContext->nativeEventThread = + ::util_NewGlobalRef(env, obj); // VERY IMPORTANT!! + + // This enables the listener to call back into java + } + + jclass clazz = nsnull; + int listenerType = 0; + + while (nsnull != gSupportedListenerInterfaces[listenerType]) { + if (nsnull == + (clazz = + ::util_FindClass(env, + gSupportedListenerInterfaces[listenerType]))) { + return; + } + if (::util_IsInstanceOf(env, typedListener, clazz)) { + // We've got a winner! + break; + } + listenerType++; + } + + if (LISTENER_NOT_FOUND == (LISTENER_CLASSES) listenerType) { + ::util_ThrowExceptionToJava(env, "Exception: NativeEventThread.nativeAddListener(): can't find listener \n\tclass for argument"); + return; + } + + jobject globalRef = nsnull; + + // PENDING(edburns): make sure do DeleteGlobalRef on the removeListener + if (nsnull == (globalRef = ::util_NewGlobalRef(env, typedListener))) { + ::util_ThrowExceptionToJava(env, "Exception: NativeEventThread.nativeAddListener(): can't create NewGlobalRef\n\tfor argument"); + return; + } + + switch(listenerType) { + case DOCUMENT_LOAD_LISTENER: + addDocumentLoadListener(env, initContext, globalRef); + break; + case MOUSE_LISTENER: + addMouseListener(env, initContext, globalRef); + break; + } +} + +JNIEXPORT void JNICALL +Java_org_mozilla_webclient_wrapper_1native_NativeEventThread_nativeRemoveAllListeners(JNIEnv *env, jobject obj, jint webShellPtr) +{ + WebShellInitContext *initContext = (WebShellInitContext *)webShellPtr; + + if (initContext == nsnull) { + ::util_ThrowExceptionToJava(env, "Exception: null initContext passed tonativeRemoveAllListeners"); + return; + } + + removeAllListeners(env, initContext); +} + + +/** + + * This function processes methods inserted into WebShellInitContext's + * actionQueue. It is called once during the initialization of the + * NativeEventThread java thread, and infinitely in + * NativeEventThread.run()'s event loop. The call to PL_HandleEvent + * below, ends up calling the nsActionEvent subclass's handleEvent() + * method. After which it calls nsActionEvent::destroyEvent(). + + */ + +int processEventLoop(WebShellInitContext * initContext) +{ +#ifdef XP_UNIX + while(gtk_events_pending()) { + gtk_main_iteration(); + } +#else + // PENDING(mark): Does this work on the Mac? + MSG msg; + + if (::PeekMessage(&msg, nsnull, 0, 0, PM_NOREMOVE)) { + if (::GetMessage(&msg, nsnull, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + } +#endif + ::PR_Sleep(PR_INTERVAL_NO_WAIT); + + if ((initContext->initComplete) && (initContext->actionQueue)) { + + PL_ENTER_EVENT_QUEUE_MONITOR(initContext->actionQueue); + + if (::PL_EventAvailable(initContext->actionQueue)) { + + PLEvent * event = ::PL_GetEvent(initContext->actionQueue); + + if (event != nsnull) { + ::PL_HandleEvent(event); + } + } + + PL_EXIT_EVENT_QUEUE_MONITOR(initContext->actionQueue); + + } + if (initContext->stopThread) { + initContext->stopThread++; + + return 0; + } + return 1; +} + +// Ashu +#ifdef XP_UNIX +static void event_processor_callback(gpointer data, + gint source, + GdkInputCondition condition) { +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + "EventHandler: event_processor_callback()\n"); + } +#endif + nsIEventQueue *eventQueue = (nsIEventQueue*)data; + eventQueue->ProcessPendingEvents(); +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, "EventHandler: Done processing pending events\n"); + } +#endif +} +#endif +// + +nsresult InitMozillaStuff (WebShellInitContext * initContext) +{ + PR_ASSERT(gComponentManager); + + nsCOMPtr + aEventQService = do_GetService(NS_EVENTQUEUESERVICE_PROGID); + + // if we get here, we know that aEventQService is not null. + nsresult rv = NS_ERROR_FAILURE; + PRBool allowPlugins = PR_FALSE; + + //TODO Add tracing from nspr. + +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("InitMozillaStuff(%lx): Create the Event Queue for the UI thread...\n", + initContext)); + } +#endif + + // Create the Event Queue for the UI thread... + if (!aEventQService) { + initContext->initFailCode = kEventQueueError; + return rv; + } + + // Create the event queue. + rv = aEventQService->CreateThreadEventQueue(); + + initContext->embeddedThread = PR_GetCurrentThread(); + + // Create the action queue + if (initContext->embeddedThread) { + +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, ("InitMozillaStuff(%lx): embeddedThread != nsnull\n", initContext)); + } +#endif + if (initContext->actionQueue == nsnull) { +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, ("InitMozillaStuff(%lx): Create the action queue\n", initContext)); + } +#endif + // We need to do something different for Unix + nsIEventQueue * EQueue = nsnull; + + rv = aEventQService->GetThreadEventQueue(initContext->embeddedThread, + &EQueue); + if (NS_FAILED(rv)) { + initContext->initFailCode = kCreateWebShellError; + return rv; + } + +#ifdef XP_UNIX + gdk_input_add(EQueue->GetEventQueueSelectFD(), + GDK_INPUT_READ, + event_processor_callback, + EQueue); +#endif + + PLEventQueue * plEventQueue = nsnull; + + EQueue->GetPLEventQueue(&plEventQueue); + initContext->actionQueue = plEventQueue; + } + } + else { + initContext->initFailCode = kCreateWebShellError; + return NS_ERROR_UNEXPECTED; + } + +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("InitMozillaStuff(%lx): Create the WebShell...\n", initContext)); + } +#endif + // Create the WebShell. + rv = nsRepository::CreateInstance(kWebShellCID, nsnull, kIWebShellIID, getter_AddRefs(initContext->webShell)); + if (NS_FAILED(rv)) { + initContext->initFailCode = kCreateWebShellError; + return rv; + } + +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("InitMozillaStuff(%lx): Init the WebShell...\n", initContext)); + } +#endif + +#ifdef XP_UNIX + GdkSuperWin * superwin; + GtkMozArea * mozarea; + mozarea = (GtkMozArea *) initContext->gtkWinPtr; + superwin = mozarea->superwin; + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, ("Ashu Debugs - Inside InitMozillaStuff(%lx): - before Init Call...\n", initContext)); + } + rv = initContext->webShell->Init((nsNativeWidget *)superwin, initContext->x, initContext->y, initContext->w, initContext->h); + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, ("Ashu Debugs - Inside InitMozillaStuff(%lx): - after Init Call...\n", initContext)); + } +#else + rv = initContext->webShell->Init((nsNativeWidget *)initContext->parentHWnd, + initContext->x, initContext->y, initContext->w, initContext->h); +#endif + + + if (NS_FAILED(rv)) { + initContext->initFailCode = kInitWebShellError; + return rv; + } + +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("InitMozillaStuff(%lx): Install Prefs in the Webshell...\n", initContext)); + } +#endif + + nsCOMPtr prefs = do_GetService(NS_PREF_PROGID); + + if (prefs) { + if (nsnull == gComponentManager) { // only do this once per app. + prefs->ReadUserPrefs(); + } + // Set the prefs in the outermost webshell. + initContext->webShell->SetPrefs(prefs); + } + + if (nsnull == gHistory) { + rv = gComponentManager->CreateInstance(kSessionHistoryCID, nsnull, + kISessionHistoryIID, + (void**)&gHistory); + if (NS_FAILED(rv)) { + initContext->initFailCode = kHistoryWebShellError; + return rv; + } + } + initContext->webShell->SetSessionHistory(gHistory); + + // set the sessionHistory in the initContexn + initContext->sessionHistory = gHistory; + +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("InitMozillaStuff(%lx): Show the WebShell...\n", initContext)); + } +#endif + + nsCOMPtr baseWindow; + + rv = initContext->webShell->QueryInterface(NS_GET_IID(nsIBaseWindow), + getter_AddRefs(baseWindow)); + + if (NS_FAILED(rv)) { + initContext->initFailCode = kShowWebShellError; + return rv; + } + rv = baseWindow->SetVisibility(PR_TRUE); + if (NS_FAILED(rv)) { + initContext->initFailCode = kShowWebShellError; + return rv; + } + + // set the docShell + rv = initContext->webShell->QueryInterface(NS_GET_IID(nsIDocShell), + getter_AddRefs(initContext->docShell)); + + if (NS_FAILED(rv)) { + initContext->initFailCode = kHistoryWebShellError; + return rv; + } + + + initContext->initComplete = TRUE; + +#if DEBUG_RAPTOR_CANVAS + if (prLogModuleInfo) { + PR_LOG(prLogModuleInfo, 3, + ("InitMozillaStuff(%lx): enter event loop\n", initContext)); + } +#endif + + // Just need to loop once to clear out events before returning + processEventLoop(initContext); + + return rv; +}