mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
5a6317b8a5
This removes all call-sites I can currently fix. Tomorrow I'll try to get someone to checkin my changes to security/ and I'll get some help with the Netscape side of things. nsString::GetUnicode()'s final death-blow will be dealt soon. Please keep this in mind as you add new code :-)
1337 lines
34 KiB
C++
1337 lines
34 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape 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/NPL/
|
|
*
|
|
* 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 Mozilla Communicator client code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Dan Rosen <dr@netscape.com>
|
|
*/
|
|
|
|
#include "nsCOMPtr.h"
|
|
#include "nscore.h"
|
|
#include "nsCRT.h"
|
|
#include "nsIContentViewer.h"
|
|
#include "nsIPluginHost.h"
|
|
#include "nsIPluginInstance.h"
|
|
#include "nsIStreamListener.h"
|
|
#include "nsIURL.h"
|
|
#include "nsIChannel.h"
|
|
#include "nsNetUtil.h"
|
|
#include "nsIComponentManager.h"
|
|
#include "nsWidgetsCID.h"
|
|
#include "nsILinkHandler.h"
|
|
#include "nsIWebShell.h"
|
|
#include "nsIContentViewerEdit.h"
|
|
#include "nsIContentViewerFile.h"
|
|
#include "nsIContent.h"
|
|
#include "nsIDocument.h"
|
|
#include "nsIInterfaceRequestor.h"
|
|
#include "nsIDocShellTreeItem.h"
|
|
#include "nsIDocShellTreeOwner.h"
|
|
#include "nsIWebBrowserChrome.h"
|
|
#include "nsIDOMDocument.h"
|
|
#include "nsPluginViewer.h"
|
|
#include "nsIPluginViewer.h"
|
|
|
|
|
|
#include "nsITimer.h"
|
|
#include "nsITimerCallback.h"
|
|
|
|
// Class IDs
|
|
static NS_DEFINE_IID(kChildWindowCID, NS_CHILD_CID);
|
|
static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID);
|
|
|
|
// Interface IDs
|
|
static NS_DEFINE_IID(kIContentViewerIID, NS_ICONTENTVIEWER_IID);
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
static NS_DEFINE_IID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
|
|
static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID);
|
|
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
|
|
|
|
|
|
class PluginViewerImpl;
|
|
|
|
class PluginListener : public nsIStreamListener {
|
|
public:
|
|
PluginListener(PluginViewerImpl* aViewer);
|
|
virtual ~PluginListener();
|
|
|
|
// nsISupports
|
|
NS_DECL_ISUPPORTS
|
|
|
|
// nsIRequestObserver methods:
|
|
NS_DECL_NSIREQUESTOBSERVER
|
|
|
|
// nsIStreamListener methods:
|
|
NS_DECL_NSISTREAMLISTENER
|
|
|
|
PluginViewerImpl* mViewer;
|
|
nsIStreamListener* mNextStream;
|
|
};
|
|
|
|
|
|
class pluginInstanceOwner : public nsIPluginInstanceOwner,
|
|
public nsITimerCallback
|
|
{
|
|
public:
|
|
pluginInstanceOwner();
|
|
virtual ~pluginInstanceOwner();
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
//nsIPluginInstanceOwner interface
|
|
|
|
NS_IMETHOD SetInstance(nsIPluginInstance *aInstance);
|
|
|
|
NS_IMETHOD GetInstance(nsIPluginInstance *&aInstance);
|
|
|
|
NS_IMETHOD GetWindow(nsPluginWindow *&aWindow);
|
|
|
|
NS_IMETHOD GetMode(nsPluginMode *aMode);
|
|
|
|
NS_IMETHOD CreateWidget(void);
|
|
|
|
NS_IMETHOD GetURL(const char *aURL, const char *aTarget,
|
|
void *aPostData, PRUint32 aPostDataLen,
|
|
void *aHeadersData, PRUint32 aHeadersDataLen);
|
|
|
|
NS_IMETHOD ShowStatus(const char *aStatusMsg);
|
|
|
|
NS_IMETHOD GetDocument(nsIDocument* *aDocument);
|
|
|
|
NS_IMETHOD InvalidateRect(nsPluginRect *invalidRect);
|
|
|
|
NS_IMETHOD InvalidateRegion(nsPluginRegion invalidRegion);
|
|
|
|
NS_IMETHOD ForceRedraw();
|
|
|
|
NS_IMETHOD GetValue(nsPluginInstancePeerVariable variable, void *value);
|
|
|
|
//nsIEventListener interface
|
|
nsEventStatus ProcessEvent(const nsGUIEvent & anEvent);
|
|
|
|
//locals
|
|
|
|
NS_IMETHOD Init(PluginViewerImpl *aViewer, nsIWidget *aWindow);
|
|
|
|
// nsITimerCallback interface
|
|
NS_IMETHOD_(void) Notify(nsITimer *timer);
|
|
void CancelTimer();
|
|
|
|
#ifdef XP_MAC
|
|
void GUItoMacEvent(const nsGUIEvent& anEvent, EventRecord& aMacEvent);
|
|
nsPluginPort* GetPluginPort();
|
|
void FixUpPluginWindow();
|
|
#endif
|
|
|
|
private:
|
|
nsPluginWindow mPluginWindow;
|
|
nsIPluginInstance *mInstance;
|
|
nsIWidget *mWindow; //we do not addref this...
|
|
PluginViewerImpl *mViewer; //we do not addref this...
|
|
nsCOMPtr<nsITimer> mPluginTimer;
|
|
};
|
|
|
|
static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY,
|
|
nsRect& aClipRect);
|
|
|
|
|
|
class PluginViewerImpl : public nsIPluginViewer,
|
|
public nsIContentViewer,
|
|
public nsIContentViewerEdit,
|
|
public nsIContentViewerFile
|
|
{
|
|
public:
|
|
PluginViewerImpl(const char* aCommand);
|
|
nsresult Init(nsIStreamListener** aDocListener);
|
|
|
|
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
|
|
|
// nsISupports
|
|
NS_DECL_ISUPPORTS
|
|
|
|
// nsIPluginViewer
|
|
NS_IMETHOD StartLoad(nsIRequest* request, nsIStreamListener*& aResult);
|
|
|
|
// nsIContentViewer
|
|
NS_IMETHOD Init(nsIWidget* aParentWidget,
|
|
nsIDeviceContext* aDeviceContext,
|
|
const nsRect& aBounds);
|
|
NS_IMETHOD SetContainer(nsISupports* aContainer);
|
|
NS_IMETHOD GetContainer(nsISupports** aContainerResult);
|
|
NS_IMETHOD LoadStart(nsISupports* aDoc);
|
|
NS_IMETHOD LoadComplete(nsresult aStatus);
|
|
NS_IMETHOD Destroy(void);
|
|
NS_IMETHOD Stop(void);
|
|
NS_IMETHOD GetDOMDocument(nsIDOMDocument **aResult);
|
|
NS_IMETHOD SetDOMDocument(nsIDOMDocument *aDocument);
|
|
NS_IMETHOD GetBounds(nsRect& aResult);
|
|
NS_IMETHOD SetBounds(const nsRect& aBounds);
|
|
NS_IMETHOD GetPreviousViewer(nsIContentViewer** aViewer);
|
|
NS_IMETHOD SetPreviousViewer(nsIContentViewer* aViewer);
|
|
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
|
|
NS_IMETHOD Show();
|
|
NS_IMETHOD Hide();
|
|
NS_IMETHOD Validate();
|
|
NS_IMETHOD SetEnableRendering(PRBool aOn);
|
|
NS_IMETHOD GetEnableRendering(PRBool* aResult);
|
|
|
|
// nsIContentViewerEdit
|
|
NS_DECL_NSICONTENTVIEWEREDIT
|
|
|
|
// nsIContentViewerFile
|
|
NS_DECL_NSICONTENTVIEWERFILE
|
|
|
|
virtual ~PluginViewerImpl();
|
|
|
|
nsresult CreatePlugin(nsIRequest* request, nsIPluginHost* aHost, const nsRect& aBounds,
|
|
nsIStreamListener*& aResult);
|
|
|
|
nsresult MakeWindow(nsNativeWidget aParent,
|
|
nsIDeviceContext* aDeviceContext,
|
|
const nsRect& aBounds);
|
|
|
|
void ForceRefresh(void);
|
|
|
|
nsresult GetURI(nsIURI* *aURI);
|
|
|
|
nsresult GetDocument(nsIDocument* *aDocument);
|
|
|
|
nsIWidget* mWindow;
|
|
nsIDocument* mDocument;
|
|
nsCOMPtr<nsISupports> mContainer;
|
|
nsIChannel* mChannel;
|
|
pluginInstanceOwner *mOwner;
|
|
PRBool mEnableRendering;
|
|
|
|
};
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
nsresult
|
|
NS_NewPluginContentViewer(const char* aCommand,
|
|
nsIStreamListener** aDocListener,
|
|
nsIContentViewer** aDocViewer)
|
|
{
|
|
PluginViewerImpl* it = new PluginViewerImpl(aCommand);
|
|
if (nsnull == it) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
nsresult rv = it->Init(aDocListener);
|
|
if (NS_FAILED(rv)) {
|
|
delete it;
|
|
return rv;
|
|
}
|
|
return it->QueryInterface(kIContentViewerIID, (void**) aDocViewer);
|
|
}
|
|
|
|
// Note: operator new zeros our memory
|
|
PluginViewerImpl::PluginViewerImpl(const char* aCommand)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
mEnableRendering = PR_TRUE;
|
|
}
|
|
|
|
nsresult
|
|
PluginViewerImpl::Init(nsIStreamListener** aDocListener)
|
|
{
|
|
nsIStreamListener* it = new PluginListener(this);
|
|
if (it == nsnull)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
NS_ADDREF(it);
|
|
*aDocListener = it;
|
|
return NS_OK;
|
|
}
|
|
|
|
// ISupports implementation...
|
|
NS_IMPL_ADDREF(PluginViewerImpl)
|
|
NS_IMPL_RELEASE(PluginViewerImpl)
|
|
NS_IMPL_QUERY_INTERFACE4(PluginViewerImpl,
|
|
nsIPluginViewer,
|
|
nsIContentViewer,
|
|
nsIContentViewerEdit,
|
|
nsIContentViewerFile)
|
|
|
|
|
|
PluginViewerImpl::~PluginViewerImpl()
|
|
{
|
|
#ifdef XP_MAC
|
|
if (mOwner) mOwner->CancelTimer();
|
|
#endif
|
|
|
|
NS_IF_RELEASE(mOwner);
|
|
if (nsnull != mWindow) {
|
|
mWindow->Destroy();
|
|
NS_RELEASE(mWindow);
|
|
}
|
|
NS_IF_RELEASE(mDocument);
|
|
NS_IF_RELEASE(mChannel);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::SetContainer(nsISupports* aContainer)
|
|
{
|
|
mContainer = aContainer;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetContainer(nsISupports** aResult)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
*aResult = mContainer;
|
|
NS_IF_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Init(nsIWidget* aParentWidget,
|
|
nsIDeviceContext* aDeviceContext,
|
|
const nsRect& aBounds)
|
|
{
|
|
nsresult rv = MakeWindow(aParentWidget->GetNativeData(NS_NATIVE_WIDGET),
|
|
aDeviceContext, aBounds);
|
|
if (NS_OK == rv) {
|
|
mOwner = new pluginInstanceOwner();
|
|
if (nsnull != mOwner) {
|
|
NS_ADDREF(mOwner);
|
|
rv = mOwner->Init(this, mWindow);
|
|
}
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::StartLoad(nsIRequest* request, nsIStreamListener*& aResult)
|
|
{
|
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
|
if (!channel) return NS_ERROR_FAILURE;
|
|
|
|
NS_IF_RELEASE(mChannel);
|
|
mChannel = channel;
|
|
NS_ADDREF(mChannel);
|
|
|
|
#ifdef DEBUG
|
|
char* contentType;
|
|
channel->GetContentType(&contentType);
|
|
printf("PluginViewerImpl::StartLoad: content-type=%s\n", contentType);
|
|
nsCRT::free(contentType);
|
|
#endif
|
|
|
|
aResult = nsnull;
|
|
|
|
// Only instantiate the plugin if our container can host it
|
|
nsCOMPtr<nsIPluginHost> host;
|
|
|
|
host = do_GetService(kCPluginManagerCID);
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
if(host)
|
|
{
|
|
nsRect r;
|
|
mWindow->GetClientBounds(r);
|
|
rv = CreatePlugin(request, host, nsRect(0, 0, r.width, r.height), aResult);
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
PluginViewerImpl::CreatePlugin(nsIRequest* request, nsIPluginHost* aHost, const nsRect& aBounds,
|
|
nsIStreamListener*& aResult)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
|
|
if (nsnull != mOwner) {
|
|
nsPluginWindow *win;
|
|
|
|
mOwner->GetWindow(win);
|
|
|
|
win->x = aBounds.x;
|
|
win->y = aBounds.y;
|
|
win->width = aBounds.width;
|
|
win->height = aBounds.height;
|
|
win->clipRect.top = aBounds.y;
|
|
win->clipRect.left = aBounds.x;
|
|
win->clipRect.bottom = aBounds.YMost();
|
|
win->clipRect.right = aBounds.XMost();
|
|
#ifdef XP_UNIX
|
|
win->ws_info = nsnull; //XXX need to figure out what this is. MMP
|
|
#endif
|
|
|
|
nsIURI* uri;
|
|
rv = mChannel->GetURI(&uri);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
char* spec;
|
|
rv = uri->GetSpec(&spec);
|
|
NS_RELEASE(uri);
|
|
if (NS_FAILED(rv)) return rv;
|
|
nsAutoString str; str.AssignWithConversion(spec);
|
|
nsCRT::free(spec);
|
|
|
|
char* ct;
|
|
|
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
|
channel->GetContentType(&ct);
|
|
if (NS_FAILED(rv)) return rv;
|
|
rv = aHost->InstantiateFullPagePlugin(ct, str, aResult, mOwner);
|
|
|
|
delete[] ct;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Stop(void)
|
|
{
|
|
// XXX write this
|
|
return NS_OK;
|
|
}
|
|
|
|
/*
|
|
* This method is called by the Document Loader once a document has
|
|
* been created for a particular data stream... The content viewer
|
|
* must cache this document for later use when Init(...) is called.
|
|
*/
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::LoadStart(nsISupports *aDoc)
|
|
{
|
|
#ifdef NS_DEBUG
|
|
printf("PluginViewerImpl::LoadStart\n");
|
|
#endif
|
|
return aDoc->QueryInterface(kIDocumentIID, (void**)&mDocument);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::LoadComplete(nsresult aStatus)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Destroy(void)
|
|
{
|
|
// XXX ripped off from nsObjectFrame::Destroy()
|
|
|
|
// we need to finish with the plugin before native window is destroyed
|
|
// doing this in the destructor is too late.
|
|
if(mOwner != nsnull)
|
|
{
|
|
nsIPluginInstance *inst;
|
|
if(NS_OK == mOwner->GetInstance(inst))
|
|
{
|
|
PRBool doCache = PR_TRUE;
|
|
PRBool doCallSetWindowAfterDestroy = PR_FALSE;
|
|
|
|
// first, determine if the plugin wants to be cached
|
|
inst->GetValue(nsPluginInstanceVariable_DoCacheBool,
|
|
(void *) &doCache);
|
|
if (!doCache) {
|
|
// then determine if the plugin wants Destroy to be called after
|
|
// Set Window. This is for bug 50547.
|
|
inst->GetValue(nsPluginInstanceVariable_CallSetWindowAfterDestroyBool,
|
|
(void *) &doCallSetWindowAfterDestroy);
|
|
!doCallSetWindowAfterDestroy ? inst->SetWindow(nsnull) : 0;
|
|
inst->Stop();
|
|
inst->Destroy();
|
|
doCallSetWindowAfterDestroy ? inst->SetWindow(nsnull) : 0; }
|
|
else {
|
|
inst->SetWindow(nsnull);
|
|
inst->Stop();
|
|
}
|
|
NS_RELEASE(inst);
|
|
}
|
|
}
|
|
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetDOMDocument(nsIDOMDocument **aResult)
|
|
{
|
|
return (mDocument) ? CallQueryInterface(mDocument, aResult) : NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsEventStatus PR_CALLBACK
|
|
HandlePluginEvent(nsGUIEvent *aEvent)
|
|
{
|
|
if (aEvent == nsnull || aEvent->widget == nsnull) //null pointer check
|
|
return nsEventStatus_eIgnore;
|
|
|
|
#ifdef XP_WIN
|
|
// on Windows, the mouse click is converted to an NS_PLUGIN_ACTIVATE
|
|
if( aEvent->message == NS_PLUGIN_ACTIVATE)
|
|
(nsIWidget*)(aEvent->widget)->SetFocus(); // send focus to child window
|
|
#else
|
|
// the Mac, and presumably others, send NS_MOUSE_ACTIVATE
|
|
if (aEvent->message == NS_MOUSE_ACTIVATE) {
|
|
(nsIWidget*)(aEvent->widget)->SetFocus(); // send focus to child window
|
|
#ifdef XP_MAC
|
|
// furthermore on the Mac nsMacEventHandler sends the NS_PLUGIN_ACTIVATE
|
|
// followed by the mouse down event, so we need to handle this
|
|
} else {
|
|
// on Mac, we store a pointer to this class as native data in the widget
|
|
PluginViewerImpl * pluginViewer;
|
|
(nsIWidget*)(aEvent->widget)->GetClientData((PluginViewerImpl *)pluginViewer);
|
|
if (pluginViewer != nsnull && pluginViewer->mOwner != nsnull)
|
|
return pluginViewer->mOwner->ProcessEvent(*aEvent);
|
|
#endif // XP_MAC
|
|
}
|
|
#endif // else XP_WIN
|
|
return nsEventStatus_eIgnore;
|
|
}
|
|
|
|
|
|
nsresult
|
|
PluginViewerImpl::MakeWindow(nsNativeWidget aParent,
|
|
nsIDeviceContext* aDeviceContext,
|
|
const nsRect& aBounds)
|
|
{
|
|
nsresult rv =
|
|
nsComponentManager::CreateInstance(kChildWindowCID, nsnull, kIWidgetIID,
|
|
(void**)&mWindow);
|
|
if (NS_OK != rv) {
|
|
return rv;
|
|
}
|
|
|
|
|
|
mWindow->Create(aParent, aBounds,HandlePluginEvent, aDeviceContext);
|
|
mWindow->SetClientData(this);
|
|
Show();
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetBounds(nsRect& aResult)
|
|
{
|
|
NS_PRECONDITION(nsnull != mWindow, "null window");
|
|
if (nsnull != mWindow) {
|
|
mWindow->GetBounds(aResult);
|
|
}
|
|
else {
|
|
aResult.SetRect(0, 0, 0, 0);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer)
|
|
{
|
|
*aViewer = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Validate()
|
|
{
|
|
if (mWindow)
|
|
mWindow->Validate();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::SetBounds(const nsRect& aBounds)
|
|
{
|
|
NS_PRECONDITION(nsnull != mWindow, "null window");
|
|
if (nsnull != mWindow) {
|
|
// Don't have the widget repaint. Layout will generate repaint requests
|
|
// during reflow
|
|
nsIPluginInstance *inst;
|
|
mWindow->Resize(aBounds.x, aBounds.y, aBounds.width, aBounds.height, PR_FALSE);
|
|
if ((nsnull != mOwner) && (NS_OK == mOwner->GetInstance(inst)) && (nsnull != inst)) {
|
|
nsPluginWindow *win;
|
|
if (NS_OK == mOwner->GetWindow(win)) {
|
|
win->x = aBounds.x;
|
|
win->y = aBounds.y;
|
|
win->width = aBounds.width;
|
|
win->height = aBounds.height;
|
|
win->clipRect.top = aBounds.y;
|
|
win->clipRect.left = aBounds.x;
|
|
win->clipRect.bottom = aBounds.YMost();
|
|
win->clipRect.right = aBounds.XMost();
|
|
|
|
inst->SetWindow(win);
|
|
}
|
|
NS_RELEASE(inst);
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Move(PRInt32 aX, PRInt32 aY)
|
|
{
|
|
NS_PRECONDITION(nsnull != mWindow, "null window");
|
|
if (nsnull != mWindow) {
|
|
nsIPluginInstance *inst;
|
|
mWindow->Move(aX, aY);
|
|
if ((nsnull != mOwner) && (NS_OK == mOwner->GetInstance(inst)) && (nsnull != inst)) {
|
|
nsPluginWindow *win;
|
|
if (NS_OK == mOwner->GetWindow(win)) {
|
|
win->x = aX;
|
|
win->y = aY;
|
|
win->clipRect.bottom = (win->clipRect.bottom - win->clipRect.top) + aY;
|
|
win->clipRect.right = (win->clipRect.right - win->clipRect.left) + aX;
|
|
win->clipRect.top = aY;
|
|
win->clipRect.left = aX;
|
|
|
|
inst->SetWindow(win);
|
|
}
|
|
NS_RELEASE(inst);
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Show()
|
|
{
|
|
NS_PRECONDITION(nsnull != mWindow, "null window");
|
|
if (nsnull != mWindow) {
|
|
mWindow->Show(PR_TRUE);
|
|
}
|
|
|
|
// XXX should we call SetWindow here?
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Hide()
|
|
{
|
|
NS_PRECONDITION(nsnull != mWindow, "null window");
|
|
if (nsnull != mWindow) {
|
|
mWindow->Show(PR_FALSE);
|
|
}
|
|
|
|
// should we call SetWindow(nsnull) here?
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::SetEnableRendering(PRBool aOn)
|
|
{
|
|
mEnableRendering = aOn;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetEnableRendering(PRBool* aResult)
|
|
{
|
|
NS_PRECONDITION(nsnull != aResult, "null OUT ptr");
|
|
if (aResult) {
|
|
*aResult = mEnableRendering;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
PluginViewerImpl::ForceRefresh()
|
|
{
|
|
mWindow->Invalidate(PR_TRUE);
|
|
}
|
|
|
|
nsresult PluginViewerImpl::GetURI(nsIURI* *aURI)
|
|
{
|
|
return mChannel->GetURI(aURI);
|
|
}
|
|
|
|
nsresult PluginViewerImpl::GetDocument(nsIDocument* *aDocument)
|
|
{
|
|
NS_IF_ADDREF(mDocument);
|
|
*aDocument = mDocument;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner::InvalidateRect(nsPluginRect *invalidRect)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner::InvalidateRegion(nsPluginRegion invalidRegion)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner::ForceRedraw()
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner::GetValue(nsPluginInstancePeerVariable variable, void *value)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
/* ========================================================================================
|
|
* nsIContentViewerFile
|
|
* ======================================================================================== */
|
|
|
|
NS_IMETHODIMP PluginViewerImpl::Search()
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP PluginViewerImpl::GetSearchable(PRBool *aSearchable)
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP PluginViewerImpl::ClearSelection()
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP PluginViewerImpl::SelectAll()
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP PluginViewerImpl::CopySelection()
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP PluginViewerImpl::GetCopyable(PRBool *aCopyable)
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP PluginViewerImpl::CutSelection()
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP PluginViewerImpl::GetCutable(PRBool *aCutable)
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP PluginViewerImpl::Paste()
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP PluginViewerImpl::GetPasteable(PRBool *aPasteable)
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
/* ========================================================================================
|
|
* nsIContentViewerEdit
|
|
* ======================================================================================== */
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Save()
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetSaveable(PRBool *aSaveable)
|
|
{
|
|
NS_ASSERTION(0, "NOT IMPLEMENTED");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Print(PRBool aSilent,FILE *aFile, nsIPrintListener *aPrintListener)
|
|
{
|
|
return NS_OK; // XXX: hey, plug in guys! implement me!
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetPrintable(PRBool *aPrintable)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aPrintable);
|
|
|
|
*aPrintable = PR_FALSE; // XXX: hey, plug in guys! implement me!
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::PrintContent(nsIWebShell * aParent,
|
|
nsIDeviceContext * aDContext,
|
|
nsIDOMWindow * aDOMWin,
|
|
PRBool aIsSubDoc)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aParent);
|
|
NS_ENSURE_ARG_POINTER(aDContext);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetInLink(PRBool* aInLink)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aInLink);
|
|
*aInLink = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetInImage(PRBool* aInImage)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aInImage);
|
|
*aInImage = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::CopyLinkLocation()
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::CopyImageLocation()
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::CopyImageContents()
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
PluginListener::PluginListener(PluginViewerImpl* aViewer)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
mViewer = aViewer;
|
|
NS_ADDREF(aViewer);
|
|
}
|
|
|
|
PluginListener::~PluginListener()
|
|
{
|
|
NS_RELEASE(mViewer);
|
|
NS_IF_RELEASE(mNextStream);
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(PluginListener, kIStreamListenerIID)
|
|
|
|
NS_IMETHODIMP
|
|
PluginListener::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
|
{
|
|
nsresult rv;
|
|
char* contentType = nsnull;
|
|
|
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
|
rv = channel->GetContentType(&contentType);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
rv = mViewer->StartLoad(request, mNextStream);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
if (nsnull == mNextStream)
|
|
return NS_ERROR_FAILURE;
|
|
return mNextStream->OnStartRequest(request, ctxt);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginListener::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
|
nsresult status)
|
|
{
|
|
if (nsnull == mNextStream) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
return mNextStream->OnStopRequest(request, ctxt, status);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginListener::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
|
|
nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count)
|
|
{
|
|
if (nsnull == mNextStream) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
return mNextStream->OnDataAvailable(request, ctxt, inStr, sourceOffset, count);
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
pluginInstanceOwner :: pluginInstanceOwner()
|
|
{
|
|
NS_INIT_REFCNT();
|
|
|
|
memset(&mPluginWindow, 0, sizeof(mPluginWindow));
|
|
mInstance = nsnull;
|
|
mWindow = nsnull;
|
|
mViewer = nsnull;
|
|
}
|
|
|
|
pluginInstanceOwner :: ~pluginInstanceOwner()
|
|
{
|
|
// shut off the timer.
|
|
if (mPluginTimer != nsnull) {
|
|
mPluginTimer->Cancel();
|
|
}
|
|
|
|
if (nsnull != mInstance)
|
|
{
|
|
PRBool doCache = PR_TRUE;
|
|
|
|
// determine if the plugin wants to be cached
|
|
mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool,
|
|
(void *) &doCache);
|
|
mInstance->Stop();
|
|
if (!doCache) {
|
|
// if not, destroy the instance
|
|
mInstance->Destroy();
|
|
}
|
|
else {
|
|
nsCOMPtr<nsIPluginHost> host;
|
|
host = do_GetService(kCPluginManagerCID);
|
|
if(host)
|
|
host->StopPluginInstance(mInstance);
|
|
}
|
|
NS_IF_RELEASE(mInstance);
|
|
}
|
|
|
|
mWindow = nsnull;
|
|
mViewer = nsnull;
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS2(pluginInstanceOwner, nsIPluginInstanceOwner,nsITimerCallback);
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: SetInstance(nsIPluginInstance *aInstance)
|
|
{
|
|
NS_IF_RELEASE(mInstance);
|
|
mInstance = aInstance;
|
|
NS_IF_ADDREF(mInstance);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: GetInstance(nsIPluginInstance *&aInstance)
|
|
{
|
|
NS_IF_ADDREF(mInstance);
|
|
aInstance = mInstance;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: GetWindow(nsPluginWindow *&aWindow)
|
|
{
|
|
aWindow = &mPluginWindow;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: GetMode(nsPluginMode *aMode)
|
|
{
|
|
*aMode = nsPluginMode_Full;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: CreateWidget(void)
|
|
{
|
|
PRBool windowless;
|
|
nsresult rv = NS_OK;
|
|
|
|
if (nsnull != mInstance)
|
|
{
|
|
#if defined(XP_MAC)
|
|
// start a periodic timer to provide null events to the plugin instance.
|
|
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
|
if (rv == NS_OK)
|
|
rv = mPluginTimer->Init(this, 1000 / 60, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
|
|
#endif
|
|
|
|
|
|
mInstance->GetValue(nsPluginInstanceVariable_WindowlessBool, (void *)&windowless);
|
|
|
|
if (PR_TRUE == windowless)
|
|
{
|
|
mPluginWindow.window = nsnull; //XXX this needs to be a HDC
|
|
mPluginWindow.type = nsPluginWindowType_Drawable;
|
|
}
|
|
else if (nsnull != mWindow)
|
|
{
|
|
mPluginWindow.window = (nsPluginPort *)mWindow->GetNativeData(NS_NATIVE_PLUGIN_PORT);
|
|
mPluginWindow.type = nsPluginWindowType_Window;
|
|
}
|
|
else
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
else
|
|
return NS_ERROR_FAILURE;
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: GetURL(const char *aURL, const char *aTarget, void *aPostData, PRUint32 aPostDataLen, void *aHeadersData,
|
|
PRUint32 aHeadersDataLen)
|
|
{
|
|
nsresult rv;
|
|
|
|
if (nsnull != mViewer)
|
|
{
|
|
nsCOMPtr<nsISupports> cont;
|
|
|
|
rv = mViewer->GetContainer(getter_AddRefs(cont));
|
|
|
|
if (NS_OK == rv)
|
|
{
|
|
nsCOMPtr<nsILinkHandler> lh(do_QueryInterface(cont));
|
|
|
|
if (lh)
|
|
{
|
|
nsCOMPtr<nsIURI> uri;
|
|
rv = mViewer->GetURI(getter_AddRefs(uri));
|
|
|
|
if (NS_OK == rv)
|
|
{
|
|
// Create an absolute URL
|
|
char* absURIStr;
|
|
rv = NS_MakeAbsoluteURI(&absURIStr, aURL, uri);
|
|
nsAutoString fullurl; fullurl.AssignWithConversion(absURIStr);
|
|
nsCRT::free(absURIStr);
|
|
|
|
if (NS_OK == rv) {
|
|
nsAutoString unitarget; unitarget.AssignWithConversion(aTarget);
|
|
rv = lh->OnLinkClick(nsnull, eLinkVerb_Replace, fullurl.get(), unitarget.get(), nsnull);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: ShowStatus(const char *aStatusMsg)
|
|
{
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
if (nsnull != mViewer)
|
|
{
|
|
nsCOMPtr<nsISupports> cont;
|
|
|
|
rv = mViewer->GetContainer(getter_AddRefs(cont));
|
|
|
|
if ((NS_OK == rv) && (nsnull != cont))
|
|
{
|
|
nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(cont));
|
|
|
|
if (docShellItem)
|
|
{
|
|
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
|
docShellItem->GetTreeOwner(getter_AddRefs(treeOwner));
|
|
|
|
if(treeOwner)
|
|
{
|
|
nsCOMPtr<nsIWebBrowserChrome> browserChrome(do_GetInterface(treeOwner));
|
|
|
|
if(browserChrome)
|
|
{
|
|
nsAutoString msg; msg.AssignWithConversion(aStatusMsg);
|
|
browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_SCRIPT, msg.get());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: GetDocument(nsIDocument* *aDocument)
|
|
{
|
|
return mViewer->GetDocument(aDocument);
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: Init(PluginViewerImpl *aViewer, nsIWidget *aWindow)
|
|
{
|
|
//do not addref
|
|
mWindow = aWindow;
|
|
mViewer = aViewer;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
// Here's where we forward events to plugins.
|
|
|
|
#ifdef XP_MAC
|
|
|
|
#if TARGET_CARBON
|
|
inline Boolean OSEventAvail(EventMask mask, EventRecord* event) { return EventAvail(mask, event); }
|
|
#endif
|
|
|
|
void pluginInstanceOwner::GUItoMacEvent(const nsGUIEvent& anEvent, EventRecord& aMacEvent)
|
|
{
|
|
::OSEventAvail(0, &aMacEvent);
|
|
switch (anEvent.message) {
|
|
case NS_GOTFOCUS:
|
|
case NS_FOCUS_EVENT_START:
|
|
aMacEvent.what = nsPluginEventType_GetFocusEvent;
|
|
break;
|
|
case NS_LOSTFOCUS:
|
|
case NS_MOUSE_EXIT:
|
|
aMacEvent.what = nsPluginEventType_LoseFocusEvent;
|
|
break;
|
|
case NS_MOUSE_MOVE:
|
|
case NS_MOUSE_ENTER:
|
|
mWindow->SetFocus();
|
|
aMacEvent.what = nsPluginEventType_AdjustCursorEvent;
|
|
break;
|
|
case NS_PAINT:
|
|
aMacEvent.what = updateEvt;
|
|
break;
|
|
case NS_KEY_DOWN:
|
|
case NS_KEY_PRESS:
|
|
break;
|
|
|
|
default:
|
|
aMacEvent.what = nullEvent;
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
nsEventStatus pluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
|
|
{
|
|
nsEventStatus rv = nsEventStatus_eIgnore;
|
|
if (!mInstance) // if mInstance is null, we shouldn't be here
|
|
return rv;
|
|
|
|
#ifdef XP_MAC
|
|
//if (mWidget != NULL) { // check for null mWidget
|
|
EventRecord* event = (EventRecord*)anEvent.nativeMsg;
|
|
if (event == NULL || event->what == nullEvent) {
|
|
EventRecord macEvent;
|
|
GUItoMacEvent(anEvent, macEvent);
|
|
event = &macEvent;
|
|
if (event->what == updateEvt) {
|
|
nsPluginPort* pluginPort = GetPluginPort();
|
|
// Add in child windows absolute position to get make the dirty rect
|
|
// relative to the top-level window.
|
|
nscoord absWidgetX = 0;
|
|
nscoord absWidgetY = 0;
|
|
nsRect widgetClip(0,0,0,0);
|
|
GetWidgetPosAndClip(mWindow,absWidgetX,absWidgetY,widgetClip);
|
|
//mViewer->GetBounds(widgetClip);
|
|
//absWidgetX = widgetClip.x;
|
|
//absWidgetY = widgetClip.y;
|
|
|
|
// set the port
|
|
mPluginWindow.x = absWidgetX;
|
|
mPluginWindow.y = absWidgetY;
|
|
|
|
|
|
// fix up the clipping region
|
|
mPluginWindow.clipRect.top = widgetClip.y;
|
|
mPluginWindow.clipRect.left = widgetClip.x;
|
|
mPluginWindow.clipRect.bottom = mPluginWindow.clipRect.top + widgetClip.height;
|
|
mPluginWindow.clipRect.right = mPluginWindow.clipRect.left + widgetClip.width;
|
|
|
|
EventRecord updateEvent;
|
|
::OSEventAvail(0, &updateEvent);
|
|
updateEvent.what = updateEvt;
|
|
updateEvent.message = UInt32(pluginPort->port);
|
|
|
|
nsPluginEvent pluginEvent = { &updateEvent, nsPluginPlatformWindowRef(pluginPort->port) };
|
|
PRBool eventHandled = PR_FALSE;
|
|
mInstance->HandleEvent(&pluginEvent, &eventHandled);
|
|
}
|
|
|
|
return nsEventStatus_eConsumeNoDefault;
|
|
|
|
}
|
|
//nsPluginPort* port = (nsPluginPort*)mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
|
|
nsPluginPort* port = (nsPluginPort*)mWindow->GetNativeData(NS_NATIVE_PLUGIN_PORT);
|
|
nsPluginEvent pluginEvent = { event, nsPluginPlatformWindowRef(port->port) };
|
|
PRBool eventHandled = PR_FALSE;
|
|
mInstance->HandleEvent(&pluginEvent, &eventHandled);
|
|
if (eventHandled && anEvent.message != NS_MOUSE_LEFT_BUTTON_DOWN)
|
|
rv = nsEventStatus_eConsumeNoDefault;
|
|
// }
|
|
#endif
|
|
|
|
//~~~
|
|
#ifdef XP_WIN
|
|
nsPluginEvent * pPluginEvent = (nsPluginEvent *)anEvent.nativeMsg;
|
|
PRBool eventHandled = PR_FALSE;
|
|
mInstance->HandleEvent(pPluginEvent, &eventHandled);
|
|
if (eventHandled)
|
|
rv = nsEventStatus_eConsumeNoDefault;
|
|
#endif
|
|
|
|
return rv;
|
|
}
|
|
|
|
|
|
// Here's how we give idle time to plugins.
|
|
|
|
NS_IMETHODIMP_(void) pluginInstanceOwner::Notify(nsITimer* /* timer */)
|
|
{
|
|
#ifdef XP_MAC
|
|
// validate the plugin clipping information by syncing the plugin window info to
|
|
// reflect the current widget location. This makes sure that everything is updated
|
|
// correctly in the event of scrolling in the window.
|
|
FixUpPluginWindow();
|
|
if (mInstance != NULL) {
|
|
EventRecord idleEvent;
|
|
::OSEventAvail(0, &idleEvent);
|
|
idleEvent.what = nullEvent;
|
|
|
|
nsPluginPort* pluginPort = GetPluginPort();
|
|
nsPluginEvent pluginEvent = { &idleEvent, nsPluginPlatformWindowRef(pluginPort->port) };
|
|
|
|
PRBool eventHandled = PR_FALSE;
|
|
mInstance->HandleEvent(&pluginEvent, &eventHandled);
|
|
}
|
|
|
|
#ifndef REPEATING_TIMERS
|
|
// reprime the timer? currently have to create a new timer for each call, which is
|
|
// kind of wasteful. need to get periodic timers working on all platforms.
|
|
nsresult rv;
|
|
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
|
if (NS_SUCCEEDED(rv))
|
|
mPluginTimer->Init(this, 1000 / 60);
|
|
#endif // REPEATING_TIMERS
|
|
#endif // XP_MAC
|
|
}
|
|
|
|
|
|
void pluginInstanceOwner::CancelTimer()
|
|
{
|
|
if (mPluginTimer) {
|
|
mPluginTimer->Cancel();
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef XP_MAC
|
|
nsPluginPort* pluginInstanceOwner::GetPluginPort()
|
|
{
|
|
|
|
nsPluginPort* result = NULL;
|
|
if (mWindow != NULL)
|
|
result = (nsPluginPort*) mWindow->GetNativeData(NS_NATIVE_PLUGIN_PORT);
|
|
return result;
|
|
}
|
|
|
|
// calculate the absolute position and clip for a widget
|
|
// and use other windows in calculating the clip
|
|
static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY,
|
|
nsRect& aClipRect)
|
|
{
|
|
aWidget->GetBounds(aClipRect);
|
|
aAbsX = aClipRect.x;
|
|
aAbsY = aClipRect.y;
|
|
|
|
nscoord ancestorX = -aClipRect.x, ancestorY = -aClipRect.y;
|
|
// Calculate clipping relative to the widget passed in
|
|
aClipRect.x = 0;
|
|
aClipRect.y = 0;
|
|
|
|
// Gather up the absolute position of the widget
|
|
// + clip window
|
|
nsCOMPtr<nsIWidget> widget = getter_AddRefs(aWidget->GetParent());
|
|
while (widget != nsnull) {
|
|
nsRect wrect;
|
|
widget->GetClientBounds(wrect);
|
|
nscoord wx, wy;
|
|
wx = wrect.x;
|
|
wy = wrect.y;
|
|
wrect.x = ancestorX;
|
|
wrect.y = ancestorY;
|
|
aClipRect.IntersectRect(aClipRect, wrect);
|
|
aAbsX += wx;
|
|
aAbsY += wy;
|
|
widget = getter_AddRefs(widget->GetParent());
|
|
if (widget == nsnull) {
|
|
// Don't include the top-level windows offset
|
|
// printf("Top level window offset %d %d\n", wx, wy);
|
|
aAbsX -= wx;
|
|
aAbsY -= wy;
|
|
}
|
|
ancestorX -=wx;
|
|
ancestorY -=wy;
|
|
}
|
|
|
|
aClipRect.x += aAbsX;
|
|
aClipRect.y += aAbsY;
|
|
|
|
//printf("--------------\n");
|
|
//printf("Widget clip X %d Y %d rect %d %d %d %d\n", aAbsX, aAbsY, aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height );
|
|
//printf("--------------\n");
|
|
}
|
|
|
|
|
|
void pluginInstanceOwner::FixUpPluginWindow()
|
|
{
|
|
if (mWindow) {
|
|
nscoord absWidgetX = 0;
|
|
nscoord absWidgetY = 0;
|
|
nsRect widgetClip(0,0,0,0);
|
|
GetWidgetPosAndClip(mWindow,absWidgetX,absWidgetY,widgetClip);
|
|
|
|
// set the port coordinates
|
|
mPluginWindow.x = absWidgetX;
|
|
mPluginWindow.y = absWidgetY;
|
|
|
|
// fix up the clipping region
|
|
mPluginWindow.clipRect.top = widgetClip.y;
|
|
mPluginWindow.clipRect.left = widgetClip.x;
|
|
mPluginWindow.clipRect.bottom = mPluginWindow.clipRect.top + widgetClip.height;
|
|
mPluginWindow.clipRect.right = mPluginWindow.clipRect.left + widgetClip.width;
|
|
}
|
|
}
|
|
|
|
#endif
|