Mozilla/mozilla/java/webclient/src_moz/NativeBrowserControl.cpp
edburns%acm.org 80626eaa13 This checkin enables MouseListener functionality. You can add a
MouseListener to the EventRegistration or BrowserControlCanvas and be
notified of events on the browser canvas.  You can snoop for onMouseOver
information such as links.  Next step is to cvs remove unused classes
relating to mouse events, for example WCMouseListenerImpl and
WCEventListenerWrapper.

A webclient/test/automated/src/classes/org/mozilla/webclient/MouseListenerTest.java

- exercise mouseListener added to BrowserControlCanvas and to
  EventRegistration.

M webclient/build-tests.xml

- hook up new test

M webclient/classes_spec/org/mozilla/webclient/BrowserControlCanvas.java

- enable adding the MouseListener from here.

M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/EventRegistrationImpl.java

- absorb the functionality of WCMouseListenerImpl.  Also need to remove
  WCEventListenerWrapper.

- deal with MouseEvents.

- refactor BrowserToJavaEventPump.run() to handle mouse listeners

M webclient/src_moz/EmbedEventListener.cpp
M webclient/src_moz/EmbedEventListener.h

- absorb functionality from CBrowserContainer relating to mouse events.

M webclient/src_moz/NativeBrowserControl.cpp

- set the EventRegistration into the EmbedEventListener instance.

M webclient/test/manual/src/classes/org/mozilla/webclient/test/TestBrowser.java

- add mouseover url updating to status bar.


git-svn-id: svn://10.0.0.236/trunk@164481 18797224-902f-48f8-a5cc-f745e15eee43
2004-10-27 01:33:57 +00:00

428 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 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 <kbaker@eb.com>
* Ian Wilkinson <iw@ennoble.com>
* Mark Lin <mark.lin@eng.sun.com>
* Mark Goddard
* Ed Burns <edburns@acm.org>
* Ashutosh Kulkarni <ashuk@eng.sun.com>
* Ann Sunhachawee
*/
#include "nsIEventQueueService.h" // for PLEventQueue
#include "nsIServiceManager.h" // for do_GetService
#include "nsEmbedAPI.h" // for NS_HandleEmbeddingEvent
#include <nsIWindowWatcher.h> // for initializing our window watcher service
#include "EmbedWindow.h"
#include "WindowCreator.h"
#include "EmbedProgress.h"
#include "EmbedEventListener.h"
#include "NativeBrowserControl.h"
#include "ns_util.h"
// all of the crap that we need for event listeners
// and when chrome windows finish loading
#include <nsIDOMWindow.h>
#include <nsPIDOMWindow.h>
#include <nsIDOMWindowInternal.h>
#include <nsIChromeEventHandler.h>
NativeBrowserControl::NativeBrowserControl(void)
{
parentHWnd = nsnull;
mNavigation = nsnull;
mSessionHistory = nsnull;
mWindow = nsnull;
mJavaBrowserControl = nsnull;
mChromeMask = 0;
mIsChrome = PR_FALSE;
mChromeLoaded = PR_FALSE;
mIsDestroyed = PR_FALSE;
mListenersAttached = PR_FALSE;
}
NativeBrowserControl::~NativeBrowserControl()
{
// PENDING(edburns): assert that this widget has been destroyed
mChromeMask = 0;
mIsChrome = PR_FALSE;
mChromeLoaded = PR_FALSE;
mJavaBrowserControl = nsnull;
}
nsresult
NativeBrowserControl::Init(NativeWrapperFactory *yourWrapperFactory)
{
if (!util_StringConstantsAreInitialized()) {
util_InitStringConstants();
}
wrapperFactory = yourWrapperFactory;
// Create our embed window, and create an owning reference to it and
// initialize it. It is assumed that this window will be destroyed
// when we go out of scope.
mWindow = new EmbedWindow();
mWindowGuard = NS_STATIC_CAST(nsIWebBrowserChrome *, mWindow);
mWindow->Init(this);
// Create our progress listener object, make an owning reference,
// and initialize it. It is assumed that this progress listener
// will be destroyed when we go out of scope.
mProgress = new EmbedProgress();
mProgressGuard = NS_STATIC_CAST(nsIWebProgressListener *,
mProgress);
mProgress->Init(this);
// Create our key listener object and initialize it. It is assumed
// that this will be destroyed before we go out of scope.
mEventListener = new EmbedEventListener();
mEventListenerGuard =
NS_STATIC_CAST(nsISupports *, NS_STATIC_CAST(nsIDOMKeyListener *,
mEventListener));
mEventListener->Init(this);
nsCOMPtr<nsIWebBrowser> webBrowser;
mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
// get a handle on the navigation object
mNavigation = do_QueryInterface(webBrowser);
//
// create the WindowCreator: see
WindowCreator *creator = new WindowCreator(this);
nsCOMPtr<nsIWindowCreator> windowCreator;
windowCreator = NS_STATIC_CAST(nsIWindowCreator *, creator);
// Attach it via the watcher service
nsCOMPtr<nsIWindowWatcher> watcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
if (watcher) {
watcher->SetWindowCreator(windowCreator);
}
return NS_OK;
}
nsresult
NativeBrowserControl::Realize(jobject javaBrowserControl,
void *parentWinPtr, PRBool *aAlreadyRealized,
PRUint32 width, PRUint32 height)
{
mJavaBrowserControl = javaBrowserControl;
// Create our session history object and tell the navigation object
// to use it. We need to do this before we create the web browser
// window.
mSessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID);
mNavigation->SetSessionHistory(mSessionHistory);
#ifdef XP_UNIX
PR_ASSERT(PR_FALSE);
GtkWidget *ownerAsWidget (GTK_WIDGET(parentWinPtr));
parentHWnd = ownerAsWidget;
width = ownerAsWidget->allocation.width;
height = ownerAsWidget->allocation.height;
#else
parentHWnd = (HWND) parentWinPtr;
#endif
// create the window
mWindow->CreateWindow_(width, height);
// bind the progress listener to the browser object
nsCOMPtr<nsISupportsWeakReference> supportsWeak;
supportsWeak = do_QueryInterface(mProgressGuard);
nsCOMPtr<nsIWeakReference> weakRef;
supportsWeak->GetWeakReference(getter_AddRefs(weakRef));
mWindow->AddWebBrowserListener(weakRef,
nsIWebProgressListener::GetIID());
// set the eventRegistration into the progress listener
jobject eventRegistration =
this->QueryInterfaceJava(EVENT_REGISTRATION_INDEX);
if (nsnull != eventRegistration) {
mProgress->SetEventRegistration(eventRegistration);
mEventListener->SetEventRegistration(eventRegistration);
}
else {
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
::util_ThrowExceptionToJava(env, "Can't get EventRegistration from BrowserControl");
}
return NS_OK;
}
void
NativeBrowserControl::Unrealize(void)
{
}
void
NativeBrowserControl::Show(void)
{
// Get the nsIWebBrowser object for our embedded window.
nsCOMPtr<nsIWebBrowser> webBrowser;
mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
// and set the visibility on the thing
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(webBrowser);
baseWindow->SetVisibility(PR_TRUE);
}
void
NativeBrowserControl::Hide(void)
{
// Get the nsIWebBrowser object for our embedded window.
nsCOMPtr<nsIWebBrowser> webBrowser;
mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
// and set the visibility on the thing
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(webBrowser);
baseWindow->SetVisibility(PR_FALSE);
}
void
NativeBrowserControl::Resize(PRUint32 x, PRUint32 y,
PRUint32 aWidth, PRUint32 aHeight)
{
mWindow->SetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION |
nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER,
x, y, aWidth, aHeight);
}
void
NativeBrowserControl::Destroy(void)
{
mIsDestroyed = PR_TRUE;
// PENDING(edburns): take over the stuff from
// WindowControlActionEvents
// wsDeallocateInitContextEvent::handleEvent()
// This flag might have been set from
// EmbedWindow::DestroyBrowserWindow() as well if someone used a
// window.close() or something or some other script action to close
// the window. No harm setting it again.
// Get the nsIWebBrowser object for our embedded window.
nsCOMPtr<nsIWebBrowser> webBrowser;
mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
// detach our event listeners and release the event receiver
DetachListeners();
if (mEventReceiver)
mEventReceiver = nsnull;
// destroy our child window
mWindow->ReleaseChildren();
// release navigation
mNavigation = nsnull;
// Release our progress listener
nsCOMPtr<nsISupportsWeakReference> supportsWeak;
supportsWeak = do_QueryInterface(mProgressGuard);
nsCOMPtr<nsIWeakReference> weakRef;
supportsWeak->GetWeakReference(getter_AddRefs(weakRef));
webBrowser->RemoveWebBrowserListener(weakRef,
nsIWebProgressListener::GetIID());
weakRef = nsnull;
supportsWeak = nsnull;
// Now that we have removed the listener, release our progress
// object
mProgressGuard = nsnull;
mProgress = nsnull;
fflush(stdout);
parentHWnd = nsnull;
}
NativeWrapperFactory *NativeBrowserControl::GetWrapperFactory()
{
return wrapperFactory;
}
jobject NativeBrowserControl::QueryInterfaceJava(WEBCLIENT_INTERFACES interface)
{
PR_ASSERT(nsnull != mJavaBrowserControl);
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
jobject result = nsnull;
jstring interfaceJStr = ::util_NewStringUTF(env,
gImplementedInterfaces[interface]);
jclass clazz = env->GetObjectClass(mJavaBrowserControl);
jmethodID mid = env->GetMethodID(clazz, "queryInterface",
"(Ljava/lang/String;)Ljava/lang/Object;");
if (nsnull != mid) {
result = env->CallObjectMethod(mJavaBrowserControl, mid,
interfaceJStr);
}
else {
::util_ThrowExceptionToJava(env, "Can't QueryInterface BrowserControl");
}
::util_DeleteStringUTF(env, interfaceJStr);
return result;
}
void
NativeBrowserControl::ContentStateChange(void)
{
// we don't attach listeners to chrome
if (mListenersAttached && !mIsChrome) {
return;
}
GetListener();
if (!mEventReceiver) {
return;
}
AttachListeners();
}
void
NativeBrowserControl::GetListener()
{
if (mEventReceiver) {
return;
}
nsCOMPtr<nsPIDOMWindow> piWin;
GetPIDOMWindow(getter_AddRefs(piWin));
if (!piWin) {
return;
}
nsCOMPtr<nsIChromeEventHandler> chromeHandler;
piWin->GetChromeEventHandler(getter_AddRefs(chromeHandler));
mEventReceiver = do_QueryInterface(chromeHandler);
}
void
NativeBrowserControl::AttachListeners()
{
if (!mEventReceiver || mListenersAttached) {
return;
}
nsIDOMEventListener *eventListener =
NS_STATIC_CAST(nsIDOMEventListener *,
NS_STATIC_CAST(nsIDOMKeyListener *, mEventListener));
// add the key listener
nsresult rv;
rv = mEventReceiver->AddEventListenerByIID(eventListener,
NS_GET_IID(nsIDOMKeyListener));
if (NS_FAILED(rv)) {
NS_WARNING("Failed to add key listener\n");
return;
}
rv = mEventReceiver->AddEventListenerByIID(eventListener,
NS_GET_IID(nsIDOMMouseListener));
if (NS_FAILED(rv)) {
NS_WARNING("Failed to add mouse listener\n");
return;
}
// ok, all set.
mListenersAttached = PR_TRUE;
}
void
NativeBrowserControl::DetachListeners()
{
if (!mListenersAttached || !mEventReceiver) {
return;
}
nsIDOMEventListener *eventListener =
NS_STATIC_CAST(nsIDOMEventListener *,
NS_STATIC_CAST(nsIDOMKeyListener *, mEventListener));
nsresult rv;
rv = mEventReceiver->RemoveEventListenerByIID(eventListener,
NS_GET_IID(nsIDOMKeyListener));
if (NS_FAILED(rv)) {
NS_WARNING("Failed to remove key listener\n");
return;
}
rv =
mEventReceiver->RemoveEventListenerByIID(eventListener,
NS_GET_IID(nsIDOMMouseListener));
if (NS_FAILED(rv)) {
NS_WARNING("Failed to remove mouse listener\n");
return;
}
mListenersAttached = PR_FALSE;
}
nsresult
NativeBrowserControl::GetPIDOMWindow(nsPIDOMWindow **aPIWin)
{
*aPIWin = nsnull;
// get the web browser
nsCOMPtr<nsIWebBrowser> webBrowser;
mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
// get the content DOM window for that web browser
nsCOMPtr<nsIDOMWindow> domWindow;
webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
if (!domWindow) {
return NS_ERROR_FAILURE;
}
// get the private DOM window
nsCOMPtr<nsPIDOMWindow> domWindowPrivate = do_QueryInterface(domWindow);
// and the root window for that DOM window
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
domWindowPrivate->GetPrivateRoot(getter_AddRefs(rootWindow));
nsCOMPtr<nsIChromeEventHandler> chromeHandler;
nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(rootWindow));
*aPIWin = piWin.get();
if (*aPIWin) {
NS_ADDREF(*aPIWin);
return NS_OK;
}
return NS_ERROR_FAILURE;
}