ns4xPluginInstance.cpp - Revision 1.50

There were 12 changes made.
Legend
   Added lines
   Changed lines
   Removed lines

ns4xPluginInstance.cpp,1.50
.
Disk File
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
.
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 *
.
 *
 * The contents of this file are subject to the Netscape Public
.
 * The contents of this file are subject to the Netscape Public
 * License Version 1.1 (the "License"); you may not use this file
.
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
.
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/NPL/
.
 * the License at http://www.mozilla.org/NPL/
 *
.
 *
 * Software distributed under the License is distributed on an "AS
.
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
.
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
.
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
.
 * rights and limitations under the License.
 *
.
 *
 * The Original Code is mozilla.org code.
.
 * The Original Code is mozilla.org code.
 *
.
 *
 * The Initial Developer of the Original Code is Netscape
.
 * The Initial Developer of the Original Code is Netscape
 * Communications Corporation.  Portions created by Netscape are
.
 * Communications Corporation.  Portions created by Netscape are
 * Copyright (C) 1998 Netscape Communications Corporation. All
.
 * Copyright (C) 1998 Netscape Communications Corporation. All
 * Rights Reserved.
.
 * Rights Reserved.
 *
.
 *
 * Contributor(s): 
.
 * Contributor(s): 
 */
.
 */
 
.
 
#include "ns4xPluginInstance.h"
.
#include "ns4xPluginInstance.h"
#include "nsIPluginStreamListener.h"
.
#include "ns4xPluginStreamListener.h"
#include "nsPluginHostImpl.h"
.
#include "nsPluginHostImpl.h"
 
.
 
#include "prlog.h"
.
#include "prlog.h"
#include "prmem.h"
.
#include "prmem.h"
#include "nscore.h"
.
#include "nscore.h"
 
.
 
#if defined(MOZ_WIDGET_GTK)
.
#if defined(MOZ_WIDGET_GTK)
#include <gdk/gdk.h>
.
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
.
#include <gdk/gdkx.h>
#include "gtkxtbin.h"
.
#include "gtkxtbin.h"
#endif
.
#endif
 
.
 
#include "nsPluginSafety.h"
.
#include "nsPluginSafety.h"
#include "nsIPref.h" // needed for NS_TRY_SAFE_CALL_*
.
#include "nsIPref.h" // needed for NS_TRY_SAFE_CALL_*
 
.
 
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); // needed for NS_TRY_SAFE_
CALL_*
.
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); // needed for NS_TRY_SAFE_
CALL_*
static NS_DEFINE_IID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
.
static NS_DEFINE_IID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
 
.
 
#define MAX_PLUGIN_NECKO_BUFFER 16384
.
 
 
.
 
class ns4xPluginStreamListener : public nsIPluginStreamListener {
.
 
 
.
 
public:
.
 
 
.
 
  NS_DECL_ISUPPORTS
.
 
 
.
 
  ///////////////////////////////////////////////////////////////////////////
.
 
  // from nsIPluginStreamListener:
.
 
 
.
 
  NS_IMETHOD OnStartBinding(nsIPluginStreamInfo* pluginInfo);
.
 
 
.
 
  NS_IMETHOD OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* 
input, 
.
 
 
                             PRUint32 length);
.
 
 
.
 
  NS_IMETHOD OnFileAvailable( nsIPluginStreamInfo* pluginInfo, const char* fil
eName);
.
 
 
 
.
 
  NS_IMETHOD OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status);
.
 
 
.
 
  NS_IMETHOD GetStreamType(nsPluginStreamType *result);
.
 
 
.
 
  ///////////////////////////////////////////////////////////////////////////
.
 
  // ns4xPluginStreamListener specific methods:
.
 
 
.
 
  ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData);
.
 
  virtual ~ns4xPluginStreamListener(void);
.
 
  PRBool IsStarted(void);
.
 
 
.
 
protected:
.
 
 
.
 
  void* mNotifyData;
.
 
  char* mStreamBuffer;
.
 
  ns4xPluginInstance* mInst;
.
 
  NPStream mNPStream;
.
 
  PRUint32 mPosition;
.
 
  nsPluginStreamType mStreamType;
.
 
};
.
 
 
.
 
 
.
 
//////////////////////////////////////////////////////////////////////////////
/
.
//////////////////////////////////////////////////////////////////////////////
/
// ns4xPluginStreamListener Methods
.
// ns4xPluginStreamListener Methods
//////////////////////////////////////////////////////////////////////////////
/
.
//////////////////////////////////////////////////////////////////////////////
/
 
.
 
static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
.
static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
 
.
 
ns4xPluginStreamListener::ns4xPluginStreamListener(nsIPluginInstance* inst, 
.
ns4xPluginStreamListener::ns4xPluginStreamListener(nsIPluginInstance* inst, 
                                                   void* notifyData)
.
                                                   void* notifyData)
    : mNotifyData(notifyData)
.
    : mNotifyData(notifyData),
 
.
      mStreamInfo(nsnull)
{
.
{
    NS_INIT_REFCNT();
.
    NS_INIT_REFCNT();
	mInst = (ns4xPluginInstance*) inst;
.
	mInst = (ns4xPluginInstance*) inst;
	mPosition = 0;
.
	mStreamBuffer=nsnull;
  mStreamBuffer=nsnull;
.
    mPosition = 0;
 
.
 
    // Initialize the 4.x interface structure
.
    // Initialize the 4.x interface structure
    memset(&mNPStream, 0, sizeof(mNPStream));
.
    memset(&mNPStream, 0, sizeof(mNPStream));
 
.
 
	NS_IF_ADDREF(mInst);
.
	NS_IF_ADDREF(mInst);
}
.
}
 
.
 
ns4xPluginStreamListener::~ns4xPluginStreamListener(void)
.
ns4xPluginStreamListener::~ns4xPluginStreamListener(void)
{
.
{
	NS_IF_RELEASE(mInst);
.
	NS_IF_RELEASE(mInst);
}
.
}
 
.
 
NS_IMPL_ISUPPORTS(ns4xPluginStreamListener, kIPluginStreamListenerIID);
.
NS_IMPL_ISUPPORTS(ns4xPluginStreamListener, kIPluginStreamListenerIID);
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
ns4xPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo)
.
ns4xPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo)
{
.
{
  if(!mInst)
.
  if(!mInst)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  NPP npp;
.
  NPP npp;
  const NPPluginFuncs *callbacks = nsnull;
.
  const NPPluginFuncs *callbacks = nsnull;
 
.
 
  mInst->GetCallbacks(&callbacks);
.
  mInst->GetCallbacks(&callbacks);
  mInst->GetNPP(&npp);
.
  mInst->GetNPP(&npp);
 
.
 
  if(!callbacks || !npp->pdata || !mInst->IsStarted())
.
  if(!callbacks || !npp->pdata || !mInst->IsStarted())
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  PRBool seekable;
.
  PRBool seekable;
  nsMIMEType contentType;
.
  nsMIMEType contentType;
  PRUint16 streamType = NP_NORMAL;
.
  PRUint16 streamType = NP_NORMAL;
  NPError error;
.
  NPError error;
 
.
 
  mNPStream.ndata = (void*) this;
.
  mNPStream.ndata = (void*) this;
  pluginInfo->GetURL(&mNPStream.url);
.
  pluginInfo->GetURL(&mNPStream.url);
  mNPStream.notifyData = mNotifyData;
.
  mNPStream.notifyData = mNotifyData;
 
.
 
  pluginInfo->GetLength((PRUint32*)&(mNPStream.end));
.
  pluginInfo->GetLength((PRUint32*)&(mNPStream.end));
  pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified));
.
  pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified));
  pluginInfo->IsSeekable(&seekable);
.
  pluginInfo->IsSeekable(&seekable);
  pluginInfo->GetContentType(&contentType);
.
  pluginInfo->GetContentType(&contentType);
 
.
 
 
.
  mStreamInfo = pluginInfo;
 
.
 
  PRLibrary* lib = mInst->fLibrary;
.
  PRLibrary* lib = mInst->fLibrary;
 
.
 
  // if we don't know the end of the stream, use 0 instead of -1. bug 59571
.
  // if we don't know the end of the stream, use 0 instead of -1. bug 59571
  if (mNPStream.end == -1)
.
  if (mNPStream.end == -1)
    mNPStream.end = 0;
.
    mNPStream.end = 0;
 
.
 
  NS_TRY_SAFE_CALL_RETURN(error, CallNPP_NewStreamProc(callbacks->newstream,
.
  NS_TRY_SAFE_CALL_RETURN(error, CallNPP_NewStreamProc(callbacks->newstream,
                                                       npp,
.
                                                       npp,
                                                       (char *)contentType,
.
                                                       (char *)contentType,
                                                       &mNPStream,
.
                                                       &mNPStream,
                                                       seekable,
.
                                                       seekable,
                                                       &streamType), lib);
.
                                                       &streamType), lib);
  if(error != NPERR_NO_ERROR)
.
  if(error != NPERR_NO_ERROR)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  // translate the old 4x style stream type to the new one
.
  // translate the old 4x style stream type to the new one
  switch(streamType)
.
  switch(streamType)
  {
.
  {
    case NP_NORMAL:
.
    case NP_NORMAL:
      mStreamType = nsPluginStreamType_Normal; 
.
      mStreamType = nsPluginStreamType_Normal; 
      break;
.
      break;
    case NP_ASFILEONLY:
.
    case NP_ASFILEONLY:
      mStreamType = nsPluginStreamType_AsFileOnly; 
.
      mStreamType = nsPluginStreamType_AsFileOnly; 
      break;
.
      break;
    case NP_ASFILE:
.
    case NP_ASFILE:
      mStreamType = nsPluginStreamType_AsFile; 
.
      mStreamType = nsPluginStreamType_AsFile; 
      break;
.
      break;
    case NP_SEEK:
.
    case NP_SEEK:
      mStreamType = nsPluginStreamType_Seek; 
.
      mStreamType = nsPluginStreamType_Seek; 
      break;
.
      break;
    default:
.
    default:
      return NS_ERROR_FAILURE;
.
      return NS_ERROR_FAILURE;
  }
.
  }
 
.
 
  // create buffer for stream here because we know the size
.
  // create buffer for stream here because we know the size
  mStreamBuffer = (char*) PR_Malloc((PRUint32)MAX_PLUGIN_NECKO_BUFFER);
.
  mStreamBuffer = (char*) PR_Malloc((PRUint32)MAX_PLUGIN_NECKO_BUFFER);
  if (!mStreamBuffer)
.
  if (!mStreamBuffer)
  {
.
  {
    NS_ASSERTION(PR_FALSE,"failed to create 4.x plugin stream buffer or size M
AX_PLUGIN_NECKO_BUFFER");
.
    NS_ASSERTION(PR_FALSE,"failed to create 4.x plugin stream buffer or size M
AX_PLUGIN_NECKO_BUFFER");
    return NS_ERROR_OUT_OF_MEMORY;
.
    return NS_ERROR_OUT_OF_MEMORY;
  }
.
  }
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
.
ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
                                          nsIInputStream* input,
.
                                          nsIInputStream* input,
 
.
                                          PRUint32 sourceOffset, 
                                          PRUint32 length)
.
                                          PRUint32 length)
{
.
{
  if (!mInst || !mInst->IsStarted())
.
  if (!mInst || !mInst->IsStarted())
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  const NPPluginFuncs *callbacks = nsnull;
.
  const NPPluginFuncs *callbacks = nsnull;
  NPP npp;
.
  NPP npp;
 
.
 
  mInst->GetCallbacks(&callbacks);
.
  mInst->GetCallbacks(&callbacks);
  mInst->GetNPP(&npp);
.
  mInst->GetNPP(&npp);
 
.
 
  if(!callbacks || !npp->pdata)
.
  if(!callbacks || !npp->pdata)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  PRUint32  numtowrite = 0;
.
  PRUint32  numtowrite = 0;
  PRUint32  amountRead = 0;
.
  PRUint32  amountRead = 0;
  PRInt32   writeCount = 0;
.
  PRInt32   writeCount = 0;
  PRUint32  leftToRead = 0;         // just in case OnDataaAvail tries to over
flow our buffer
.
  PRUint32  leftToRead = 0;         // just in case OnDataaAvail tries to over
flow our buffer
  PRBool   createdHere = PR_FALSE;  // we did malloc in locally, so we must fr
ee locally
.
  PRBool   createdHere = PR_FALSE;  // we did malloc in locally, so we must fr
ee locally
 
.
 
 
 
.
  // we are getting a range request, reset mPosition since postion passed to p
lugin will
 
.
  // be relative to the absolute position of the file.
 
.
  if (sourceOffset != 0)
 
.
    mPosition = 0;
 
.
 
  pluginInfo->GetURL(&mNPStream.url);
.
  pluginInfo->GetURL(&mNPStream.url);
  pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified));
.
  pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified));
 
.
 
  if (callbacks->write == nsnull || length == 0)
.
  if (callbacks->write == nsnull || length == 0)
    return NS_OK; // XXX ?
.
    return NS_OK; // XXX ?
 
.
 
  if (nsnull == mStreamBuffer)
.
  if (nsnull == mStreamBuffer)
  {
.
  {
    // create the buffer here because we failed in OnStartBinding
.
    // create the buffer here because we failed in OnStartBinding
    // XXX why don't we always get an OnStartBinding? This will protect us.
.
    // XXX why don't we always get an OnStartBinding? This will protect us.
    mStreamBuffer = (char*) PR_Malloc(length);
.
    mStreamBuffer = (char*) PR_Malloc(length);
    if (!mStreamBuffer)
.
    if (!mStreamBuffer)
    return NS_ERROR_OUT_OF_MEMORY;
.
    return NS_ERROR_OUT_OF_MEMORY;
    createdHere = PR_TRUE;
.
    createdHere = PR_TRUE;
  }
.
  }
 
.
 
  if (length > MAX_PLUGIN_NECKO_BUFFER)  // what if Necko gives us a lot of da
ta?
.
  if (length > MAX_PLUGIN_NECKO_BUFFER)  // what if Necko gives us a lot of da
ta?
  {
.
  {
    leftToRead = length - MAX_PLUGIN_NECKO_BUFFER; // break it up
.
    leftToRead = length - MAX_PLUGIN_NECKO_BUFFER; // break it up
    length     = MAX_PLUGIN_NECKO_BUFFER;
.
    length     = MAX_PLUGIN_NECKO_BUFFER;
  }
.
  }
  nsresult rv = input->Read(mStreamBuffer, length, &amountRead);
.
  nsresult rv = input->Read(mStreamBuffer, length, &amountRead);
  if (NS_FAILED(rv))
.
  if (NS_FAILED(rv))
    goto error;
.
    goto error;
 
.
 
  // amountRead tells us how many bytes were put in the buffer
.
  // amountRead tells us how many bytes were put in the buffer
  // WriteReady returns to us how many bytes the plugin is 
.
  // WriteReady returns to us how many bytes the plugin is 
  // ready to handle  - we have to keep calling WriteReady and
.
  // ready to handle  - we have to keep calling WriteReady and
  // Write until the buffer is empty
.
  // Write until the buffer is empty
  while (amountRead > 0)
.
  while (amountRead > 0)
  {
.
  {
    if (callbacks->writeready != NULL)
.
    if (callbacks->writeready != NULL)
    {
.
    {
      PRLibrary* lib = nsnull;
.
      PRLibrary* lib = nsnull;
      PRBool started = PR_FALSE;
.
      PRBool started = PR_FALSE;
      lib = mInst->fLibrary;
.
      lib = mInst->fLibrary;
 
.
 
      NS_TRY_SAFE_CALL_RETURN(numtowrite, CallNPP_WriteReadyProc(callbacks->wr
iteready,
.
      NS_TRY_SAFE_CALL_RETURN(numtowrite, CallNPP_WriteReadyProc(callbacks->wr
iteready,
                                                                   npp,
.
                                                                   npp,
                                                                   &mNPStream)
, lib);
.
                                                                   &mNPStream)
, lib);
 
.
 
      // if WriteReady returned 0, the plugin is not ready to handle 
.
      // if WriteReady returned 0, the plugin is not ready to handle 
      // the data, return FAILURE for now
.
      // the data, return FAILURE for now
      if (numtowrite <= 0) {
.
      if (numtowrite <= 0) {
        rv = NS_ERROR_FAILURE;
.
        rv = NS_ERROR_FAILURE;
        goto error;
.
        goto error;
      }
.
      }
 
.
 
      if (numtowrite > amountRead)
.
      if (numtowrite > amountRead)
        numtowrite = amountRead;
.
        numtowrite = amountRead;
    }
.
    }
    else 
.
    else 
    {
.
    {
      // if WriteReady is not supported by the plugin, 
.
      // if WriteReady is not supported by the plugin, 
      // just write the whole buffer
.
      // just write the whole buffer
      numtowrite = length;
.
      numtowrite = length;
    }
.
    }
 
.
 
    if (numtowrite > 0)
.
    if (numtowrite > 0)
    {
.
    {
      PRLibrary* lib = mInst->fLibrary;
.
      PRLibrary* lib = mInst->fLibrary;
 
.
 
 
.
#ifdef DEBUG_dougt
 
 
.
      printf(">  %d - %d \n", sourceOffset + writeCount + mPosition, numtowrit
e);
 
.
#if 0
 
.
      nsCString x; 
 
.
      x.Append("d:\\parts\\");
 
.
      x.AppendInt(sourceOffset);
 
.
 
 
.
      PRFileDesc* fd;
 
.
      fd = PR_Open(x, PR_CREATE_FILE |PR_SYNC| PR_APPEND | PR_RDWR, 777);
 
.
      PR_Write(fd, mStreamBuffer, numtowrite);
 
.
      PR_Close(fd);
 
.
#endif
 
.
#endif
 
.
 
      NS_TRY_SAFE_CALL_RETURN(writeCount, CallNPP_WriteProc(callbacks->write,
.
      NS_TRY_SAFE_CALL_RETURN(writeCount, CallNPP_WriteProc(callbacks->write,
                                                            npp,
.
                                                            npp,
                                                            &mNPStream, 
.
                                                            &mNPStream, 
                                                            mPosition,
 
.
                                                            sourceOffset + wri
teCount + mPosition,
                                                            numtowrite,
.
                                                            numtowrite,
                                                            (void *)mStreamBuf
fer), lib);
.
                                                            (void *)mStreamBuf
fer), lib);
      if (writeCount < 0) {
.
      if (writeCount < 0) {
        rv = NS_ERROR_FAILURE;
.
        rv = NS_ERROR_FAILURE;
        goto error;
.
        goto error;
      }
.
      }
 
.
 
 
.
      if (sourceOffset == 0)
 
.
          mPosition += numtowrite;
 
.
 
      amountRead -= numtowrite;
.
      amountRead -= numtowrite;
      mPosition += numtowrite;
.
 
    }
.
    }
  }
.
  }
 
.
 
  rv = NS_OK;
.
  rv = NS_OK;
 
.
 
error:
.
error:
  if (PR_TRUE == createdHere) // cleanup buffer if we made it locally
.
  if (PR_TRUE == createdHere) // cleanup buffer if we made it locally
  {
.
  {
    PR_Free(mStreamBuffer);
.
    PR_Free(mStreamBuffer);
    mStreamBuffer=nsnull;
.
    mStreamBuffer=nsnull;
  }
.
  }
 
.
 
  if (leftToRead > 0)  // if we have more to read in this pass, do it recursiv
ly
.
  if (leftToRead > 0)  // if we have more to read in this pass, do it recursiv
ly
  {
.
  {
    OnDataAvailable(pluginInfo, input, leftToRead);
.
    OnDataAvailable(pluginInfo, input, sourceOffset, leftToRead);
  }
.
  }
 
.
 
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
ns4xPluginStreamListener::OnFileAvailable(nsIPluginStreamInfo* pluginInfo, 
.
ns4xPluginStreamListener::OnFileAvailable(nsIPluginStreamInfo* pluginInfo, 
                                          const char* fileName)
.
                                          const char* fileName)
{
.
{
  if(!mInst || !mInst->IsStarted())
.
  if(!mInst || !mInst->IsStarted())
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  NPP npp;
.
  NPP npp;
  const NPPluginFuncs *callbacks = nsnull;
.
  const NPPluginFuncs *callbacks = nsnull;
 
.
 
  mInst->GetCallbacks(&callbacks);
.
  mInst->GetCallbacks(&callbacks);
  mInst->GetNPP(&npp);
.
  mInst->GetNPP(&npp);
 
.
 
  if(!callbacks || !npp->pdata)
.
  if(!callbacks || !npp->pdata)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  pluginInfo->GetURL(&mNPStream.url);
.
  pluginInfo->GetURL(&mNPStream.url);
 
.
 
  if (callbacks->asfile == NULL)
.
  if (callbacks->asfile == NULL)
    return NS_OK;
.
    return NS_OK;
 
.
 
  PRLibrary* lib = nsnull;
.
  PRLibrary* lib = nsnull;
  lib = mInst->fLibrary;
.
  lib = mInst->fLibrary;
 
.
 
  NS_TRY_SAFE_CALL_VOID(CallNPP_StreamAsFileProc(callbacks->asfile,
.
  NS_TRY_SAFE_CALL_VOID(CallNPP_StreamAsFileProc(callbacks->asfile,
                                                   npp,
.
                                                   npp,
                                                   &mNPStream,
.
                                                   &mNPStream,
                                                   fileName), lib);
.
                                                   fileName), lib);
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
ns4xPluginStreamListener::OnStopBinding(nsIPluginStreamInfo* pluginInfo, 
.
ns4xPluginStreamListener::OnStopBinding(nsIPluginStreamInfo* pluginInfo, 
                                        nsresult status)
.
                                        nsresult status)
{
.
{
  if(!mInst || !mInst->IsStarted())
.
  if(!mInst || !mInst->IsStarted())
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  NPP npp;
.
  NPP npp;
  const NPPluginFuncs *callbacks = nsnull;
.
  const NPPluginFuncs *callbacks = nsnull;
 
.
 
  mInst->GetCallbacks(&callbacks);
.
  mInst->GetCallbacks(&callbacks);
  mInst->GetNPP(&npp);
.
  mInst->GetNPP(&npp);
 
.
 
  if(!callbacks || !npp->pdata)
.
  if(!callbacks || !npp->pdata)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  NPError error;
.
  NPError error;
 
.
 
  pluginInfo->GetURL(&mNPStream.url);
.
  pluginInfo->GetURL(&mNPStream.url);
  pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified));
.
  pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified));
 
.
 
  if (callbacks->destroystream != NULL)
.
  if (callbacks->destroystream != NULL)
  {
.
  {
    // XXX need to convert status to NPReason
.
    // XXX need to convert status to NPReason
    PRLibrary* lib = nsnull;
.
    PRLibrary* lib = nsnull;
    lib = mInst->fLibrary;
.
    lib = mInst->fLibrary;
 
.
 
    NS_TRY_SAFE_CALL_RETURN(error, CallNPP_DestroyStreamProc(callbacks->destro
ystream,
.
    NS_TRY_SAFE_CALL_RETURN(error, CallNPP_DestroyStreamProc(callbacks->destro
ystream,
                                                               npp,
.
                                                               npp,
                                                               &mNPStream,
.
                                                               &mNPStream,
                                                               NPRES_DONE), li
b);
.
                                                               NPRES_DONE), li
b);
    if(error != NPERR_NO_ERROR)
.
    if(error != NPERR_NO_ERROR)
      return NS_ERROR_FAILURE;
.
      return NS_ERROR_FAILURE;
  }
.
  }
 
.
 
  // check to see if we have a call back
.
  // check to see if we have a call back
  if (callbacks->urlnotify != NULL && mNotifyData != nsnull)
.
  if (callbacks->urlnotify != NULL && mNotifyData != nsnull)
  {
.
  {
    PRLibrary* lib = nsnull;
.
    PRLibrary* lib = nsnull;
    lib = mInst->fLibrary;
.
    lib = mInst->fLibrary;
 
.
 
    NS_TRY_SAFE_CALL_VOID(CallNPP_URLNotifyProc(callbacks->urlnotify,
.
    NS_TRY_SAFE_CALL_VOID(CallNPP_URLNotifyProc(callbacks->urlnotify,
                                                npp,
.
                                                npp,
                                                mNPStream.url,
.
                                                mNPStream.url,
                                                nsPluginReason_Done,
.
                                                nsPluginReason_Done,
                                                mNotifyData), lib);
.
                                                mNotifyData), lib);
  }
.
  }
 
.
 
 
.
 
  // lets get rid of the buffer if we made one globally
.
  // lets get rid of the buffer if we made one globally
  if (mStreamBuffer)
.
  if (mStreamBuffer)
  {
.
  {
    PR_Free(mStreamBuffer);
.
    PR_Free(mStreamBuffer);
    mStreamBuffer=nsnull;
.
    mStreamBuffer=nsnull;
  }
.
  }
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
ns4xPluginStreamListener::GetStreamType(nsPluginStreamType *result)
.
ns4xPluginStreamListener::GetStreamType(nsPluginStreamType *result)
{
.
{
  *result = mStreamType;
.
  *result = mStreamType;
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
ns4xPluginInstance :: ns4xPluginInstance(NPPluginFuncs* callbacks, PRLibrary* 
aLibrary)
.
ns4xPluginInstance :: ns4xPluginInstance(NPPluginFuncs* callbacks, PRLibrary* 
aLibrary)
    : fCallbacks(callbacks)
.
    : fCallbacks(callbacks)
{
.
{
    NS_INIT_REFCNT();
.
    NS_INIT_REFCNT();
 
.
 
    NS_ASSERTION(fCallbacks != NULL, "null callbacks");
.
    NS_ASSERTION(fCallbacks != NULL, "null callbacks");
 
.
 
    // Initialize the NPP structure.
.
    // Initialize the NPP structure.
 
.
 
    fNPP.pdata = NULL;
.
    fNPP.pdata = NULL;
    fNPP.ndata = this;
.
    fNPP.ndata = this;
 
.
 
    fLibrary = aLibrary;
.
    fLibrary = aLibrary;
    mWindowless = PR_FALSE;
.
    mWindowless = PR_FALSE;
    mTransparent = PR_FALSE;
.
    mTransparent = PR_FALSE;
    mStarted = PR_FALSE;
.
    mStarted = PR_FALSE;
}
.
}
 
.
 
 
.
 
ns4xPluginInstance :: ~ns4xPluginInstance(void)
.
ns4xPluginInstance :: ~ns4xPluginInstance(void)
{
.
{
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("ns4xPluginInstance::~ns4xPluginInstance()\n");
.
  printf("ns4xPluginInstance::~ns4xPluginInstance()\n");
#endif
.
#endif
#if defined(MOZ_WIDGET_GTK)
.
#if defined(MOZ_WIDGET_GTK)
  if (mXtBin)
.
  if (mXtBin)
    gtk_widget_destroy(mXtBin);
.
    gtk_widget_destroy(mXtBin);
#endif
.
#endif
}
.
}
 
.
 
PRBool
.
PRBool
ns4xPluginInstance :: IsStarted(void)
.
ns4xPluginInstance :: IsStarted(void)
{
.
{
    return mStarted;
.
    return mStarted;
}
.
}
 
.
 
////////////////////////////////////////////////////////////////////////
.
////////////////////////////////////////////////////////////////////////
 
.
 
NS_IMPL_ISUPPORTS2(ns4xPluginInstance, nsIPluginInstance, nsIScriptablePlugin)
.
NS_IMPL_ISUPPORTS2(ns4xPluginInstance, nsIPluginInstance, nsIScriptablePlugin)
 
.
 
static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID); 
.
static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID); 
static NS_DEFINE_IID(kIPluginTagInfoIID, NS_IPLUGINTAGINFO_IID); 
.
static NS_DEFINE_IID(kIPluginTagInfoIID, NS_IPLUGINTAGINFO_IID); 
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
.
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
 
.
 
 
.
 
////////////////////////////////////////////////////////////////////////
.
////////////////////////////////////////////////////////////////////////
 
.
 
NS_IMETHODIMP ns4xPluginInstance::Initialize(nsIPluginInstancePeer* peer)
.
NS_IMETHODIMP ns4xPluginInstance::Initialize(nsIPluginInstancePeer* peer)
{
.
{
#ifdef MOZ_WIDGET_GTK
.
#ifdef MOZ_WIDGET_GTK
  mXtBin = nsnull;
.
  mXtBin = nsnull;
#endif
.
#endif
  return InitializePlugin(peer);
.
  return InitializePlugin(peer);
}
.
}
 
.
 
NS_IMETHODIMP ns4xPluginInstance::GetPeer(nsIPluginInstancePeer* *resultingPee
r)
.
NS_IMETHODIMP ns4xPluginInstance::GetPeer(nsIPluginInstancePeer* *resultingPee
r)
{
.
{
  *resultingPeer = mPeer;
.
  *resultingPeer = mPeer;
  NS_IF_ADDREF(*resultingPeer);
.
  NS_IF_ADDREF(*resultingPeer);
  
.
  
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP ns4xPluginInstance::Start(void)
.
NS_IMETHODIMP ns4xPluginInstance::Start(void)
{
.
{
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("Inside ns4xPluginInstance::Start(void)...\n");
.
  printf("Inside ns4xPluginInstance::Start(void)...\n");
#endif
.
#endif
 
.
 
  if(mStarted)
.
  if(mStarted)
    return NS_OK;
.
    return NS_OK;
  else
.
  else
    return InitializePlugin(mPeer); 
.
    return InitializePlugin(mPeer); 
}
.
}
 
.
 
NS_IMETHODIMP ns4xPluginInstance::Stop(void)
.
NS_IMETHODIMP ns4xPluginInstance::Stop(void)
{
.
{
  if (fNPP.pdata == nsnull)
.
  if (fNPP.pdata == nsnull)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  NPError error;
.
  NPError error;
 
.
 
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("ns4xPluginInstance::Stop()\n");
.
  printf("ns4xPluginInstance::Stop()\n");
#endif
.
#endif
 
.
 
#ifdef MOZ_WIDGET_GTK
.
#ifdef MOZ_WIDGET_GTK
  if (mXtBin)
.
  if (mXtBin)
    gtk_widget_destroy(mXtBin);
.
    gtk_widget_destroy(mXtBin);
#endif
.
#endif
 
.
 
  if(!mStarted)
.
  if(!mStarted)
    return NS_OK;
.
    return NS_OK;
 
.
 
  if (fCallbacks->destroy == NULL)
.
  if (fCallbacks->destroy == NULL)
    return NS_ERROR_FAILURE; // XXX right error?
.
    return NS_ERROR_FAILURE; // XXX right error?
 
.
 
  NPSavedData *sdata;
.
  NPSavedData *sdata;
 
.
 
  NS_TRY_SAFE_CALL_RETURN(error, CallNPP_DestroyProc(fCallbacks->destroy, &fNP
P, &sdata), fLibrary);
.
  NS_TRY_SAFE_CALL_RETURN(error, CallNPP_DestroyProc(fCallbacks->destroy, &fNP
P, &sdata), fLibrary);
 
.
 
  mStarted = PR_FALSE;
.
  mStarted = PR_FALSE;
  if(error != NPERR_NO_ERROR)
.
  if(error != NPERR_NO_ERROR)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
  else
.
  else
    return NS_OK;
.
    return NS_OK;
}
.
}
 
.
 
nsresult ns4xPluginInstance::InitializePlugin(nsIPluginInstancePeer* peer)
.
nsresult ns4xPluginInstance::InitializePlugin(nsIPluginInstancePeer* peer)
{
.
{
  PRUint16 count = 0;
.
  PRUint16 count = 0;
  const char* const* names = nsnull;
.
  const char* const* names = nsnull;
  const char* const* values = nsnull;
.
  const char* const* values = nsnull;
  nsresult rv;
.
  nsresult rv;
  NPError error;
.
  NPError error;
 
.
 
  
.
  
  NS_ASSERTION(peer != NULL, "null peer");
.
  NS_ASSERTION(peer != NULL, "null peer");
 
.
 
  mPeer = peer;
.
  mPeer = peer;
 
.
 
  nsCOMPtr<nsIPluginTagInfo> taginfo = do_QueryInterface(mPeer, &rv);
.
  nsCOMPtr<nsIPluginTagInfo> taginfo = do_QueryInterface(mPeer, &rv);
 
.
 
  if (NS_SUCCEEDED(rv))
.
  if (NS_SUCCEEDED(rv))
    taginfo->GetAttributes(count, names, values);
.
    taginfo->GetAttributes(count, names, values);
 
.
 
  if (fCallbacks->newp == nsnull)
.
  if (fCallbacks->newp == nsnull)
    return NS_ERROR_FAILURE; // XXX right error?
.
    return NS_ERROR_FAILURE; // XXX right error?
  
.
  
  // XXX Note that the NPPluginType_* enums were crafted to be
.
  // XXX Note that the NPPluginType_* enums were crafted to be
  // backward compatible...
.
  // backward compatible...
  
.
  
  nsPluginMode  mode;
.
  nsPluginMode  mode;
  nsMIMEType    mimetype;
.
  nsMIMEType    mimetype;
 
.
 
  mPeer->GetMode(&mode);
.
  mPeer->GetMode(&mode);
  mPeer->GetMIMEType(&mimetype);
.
  mPeer->GetMIMEType(&mimetype);
 
.
 
  NS_TRY_SAFE_CALL_RETURN(error, CallNPP_NewProc(fCallbacks->newp,
.
  NS_TRY_SAFE_CALL_RETURN(error, CallNPP_NewProc(fCallbacks->newp,
                                          (char *)mimetype,
.
                                          (char *)mimetype,
                                          &fNPP,
.
                                          &fNPP,
                                          (PRUint16)mode,
.
                                          (PRUint16)mode,
                                          count,
.
                                          count,
                                          (char**)names,
.
                                          (char**)names,
                                          (char**)values,
.
                                          (char**)values,
                                          NULL), fLibrary);
.
                                          NULL), fLibrary);
  
.
  
  if(error != NPERR_NO_ERROR)
.
  if(error != NPERR_NO_ERROR)
    rv = NS_ERROR_FAILURE;
.
    rv = NS_ERROR_FAILURE;
  
.
  
  mStarted = PR_TRUE;
.
  mStarted = PR_TRUE;
  
.
  
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP ns4xPluginInstance::Destroy(void)
.
NS_IMETHODIMP ns4xPluginInstance::Destroy(void)
{
.
{
  // destruction is handled in the Stop call
.
  // destruction is handled in the Stop call
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window)
.
NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window)
{
.
{
  if (fNPP.pdata == nsnull)
.
  if (fNPP.pdata == nsnull)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
#ifdef MOZ_WIDGET_GTK
.
#ifdef MOZ_WIDGET_GTK
  NPSetWindowCallbackStruct *ws;
.
  NPSetWindowCallbackStruct *ws;
#endif
.
#endif
 
.
 
  // XXX 4.x plugins don't want a SetWindow(NULL).
.
  // XXX 4.x plugins don't want a SetWindow(NULL).
 
.
 
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("Inside ns4xPluginInstance::SetWindow(%p)...\n", window);
.
  printf("Inside ns4xPluginInstance::SetWindow(%p)...\n", window);
#endif
.
#endif
 
.
 
  if (!window || !mStarted)
.
  if (!window || !mStarted)
    return NS_OK;
.
    return NS_OK;
  
.
  
  NPError error;
.
  NPError error;
  
.
  
#ifdef MOZ_WIDGET_GTK
.
#ifdef MOZ_WIDGET_GTK
  // Allocate and fill out the ws_info data
.
  // Allocate and fill out the ws_info data
  if (!window->ws_info) {
.
  if (!window->ws_info) {
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
    printf("About to create new ws_info...\n");
.
    printf("About to create new ws_info...\n");
#endif    
.
#endif    
 
.
 
    // allocate a new NPSetWindowCallbackStruct structure at ws_info
.
    // allocate a new NPSetWindowCallbackStruct structure at ws_info
    window->ws_info = (NPSetWindowCallbackStruct *)PR_MALLOC(sizeof(NPSetWindo
wCallbackStruct));
.
    window->ws_info = (NPSetWindowCallbackStruct *)PR_MALLOC(sizeof(NPSetWindo
wCallbackStruct));
 
.
 
    if (!window->ws_info)
.
    if (!window->ws_info)
      return NS_ERROR_OUT_OF_MEMORY;
.
      return NS_ERROR_OUT_OF_MEMORY;
 
.
 
    ws = (NPSetWindowCallbackStruct *)window->ws_info;
.
    ws = (NPSetWindowCallbackStruct *)window->ws_info;
 
.
 
    GdkWindow *win = gdk_window_lookup((XID)window->window);
.
    GdkWindow *win = gdk_window_lookup((XID)window->window);
    if (win)
.
    if (win)
    {
.
    {
#ifdef NS_DEBUG      
.
#ifdef NS_DEBUG      
      printf("About to create new xtbin of %i X %i from %p...\n",
.
      printf("About to create new xtbin of %i X %i from %p...\n",
             window->width, window->height, win);
.
             window->width, window->height, win);
#endif
.
#endif
 
.
 
#if 1
.
#if 1
      // if we destroyed the plugin when we left the page, we could remove thi
s
.
      // if we destroyed the plugin when we left the page, we could remove thi
s
      // code (i believe) the problem here is that the window gets destroyed w
hen
.
      // code (i believe) the problem here is that the window gets destroyed w
hen
      // its parent, etc does by changing a page the plugin instance is being
.
      // its parent, etc does by changing a page the plugin instance is being
      // held on to, so when we return to the page, we have a mXtBin, but it i
s
.
      // held on to, so when we return to the page, we have a mXtBin, but it i
s
      // in a not-so-good state.
.
      // in a not-so-good state.
      // --
.
      // --
      // this is lame.  we shouldn't be destroying this everytime, but I can't
 find
.
      // this is lame.  we shouldn't be destroying this everytime, but I can't
 find
      // a good way to tell if we need to destroy/recreate the xtbin or not
.
      // a good way to tell if we need to destroy/recreate the xtbin or not
      // what if the plugin wants to change the window and not just resize it?
?
.
      // what if the plugin wants to change the window and not just resize it?
?
      // (pav)
.
      // (pav)
 
.
 
      if (mXtBin) {
.
      if (mXtBin) {
        gtk_widget_destroy(mXtBin);
.
        gtk_widget_destroy(mXtBin);
        mXtBin = NULL;
.
        mXtBin = NULL;
      }
.
      }
#endif
.
#endif
 
.
 
 
.
 
      if (!mXtBin) {
.
      if (!mXtBin) {
        mXtBin = gtk_xtbin_new(win, 0);
.
        mXtBin = gtk_xtbin_new(win, 0);
      } 
.
      } 
 
.
 
      gtk_widget_set_usize(mXtBin, window->width, window->height);
.
      gtk_widget_set_usize(mXtBin, window->width, window->height);
 
.
 
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
      printf("About to show xtbin(%p)...\n", mXtBin); fflush(NULL);
.
      printf("About to show xtbin(%p)...\n", mXtBin); fflush(NULL);
#endif
.
#endif
      gtk_widget_show(mXtBin);
.
      gtk_widget_show(mXtBin);
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
      printf("completed gtk_widget_show(%p)\n", mXtBin); fflush(NULL);
.
      printf("completed gtk_widget_show(%p)\n", mXtBin); fflush(NULL);
#endif
.
#endif
    }
.
    }
 
.
 
    // fill in window info structure 
.
    // fill in window info structure 
    ws->type = 0; // OK, that was a guess!!
.
    ws->type = 0; // OK, that was a guess!!
    ws->depth = gdk_rgb_get_visual()->depth;
.
    ws->depth = gdk_rgb_get_visual()->depth;
    ws->display = GTK_XTBIN(mXtBin)->xtdisplay;
.
    ws->display = GTK_XTBIN(mXtBin)->xtdisplay;
    ws->visual = GDK_VISUAL_XVISUAL(gdk_rgb_get_visual());
.
    ws->visual = GDK_VISUAL_XVISUAL(gdk_rgb_get_visual());
    ws->colormap = GDK_COLORMAP_XCOLORMAP(gdk_window_get_colormap(win));
.
    ws->colormap = GDK_COLORMAP_XCOLORMAP(gdk_window_get_colormap(win));
 
.
 
    XFlush(ws->display);
.
    XFlush(ws->display);
  } // !window->ws_info
.
  } // !window->ws_info
 
.
 
  // And now point the NPWindow structures window 
.
  // And now point the NPWindow structures window 
  // to the actual X window
.
  // to the actual X window
  window->window = (nsPluginPort *)GTK_XTBIN(mXtBin)->xtwindow;
.
  window->window = (nsPluginPort *)GTK_XTBIN(mXtBin)->xtwindow;
#endif // MOZ_WIDGET_GTK
.
#endif // MOZ_WIDGET_GTK
 
.
 
  if (fCallbacks->setwindow) {
.
  if (fCallbacks->setwindow) {
    // XXX Turns out that NPPluginWindow and NPWindow are structurally
.
    // XXX Turns out that NPPluginWindow and NPWindow are structurally
    // identical (on purpose!), so there's no need to make a copy.
.
    // identical (on purpose!), so there's no need to make a copy.
      
.
      
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
    printf("About to call CallNPP_SetWindowProc()...\n");
.
    printf("About to call CallNPP_SetWindowProc()...\n");
    fflush(NULL);
.
    fflush(NULL);
#endif
.
#endif
 
.
 
    NS_TRY_SAFE_CALL_RETURN(error, CallNPP_SetWindowProc(fCallbacks->setwindow
,
.
    NS_TRY_SAFE_CALL_RETURN(error, CallNPP_SetWindowProc(fCallbacks->setwindow
,
                                  &fNPP,
.
                                  &fNPP,
                                  (NPWindow*) window), fLibrary);
.
                                  (NPWindow*) window), fLibrary);
 
.
 
      
.
      
    // XXX In the old code, we'd just ignore any errors coming
.
    // XXX In the old code, we'd just ignore any errors coming
    // back from the plugin's SetWindow(). Is this the correct
.
    // back from the plugin's SetWindow(). Is this the correct
    // behavior?!?
.
    // behavior?!?
  }
.
  }
  
.
  
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("Falling out of ns4xPluginInstance::SetWindow()...\n");
.
  printf("Falling out of ns4xPluginInstance::SetWindow()...\n");
#endif
.
#endif
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
/* NOTE: the caller must free the stream listener */
.
/* NOTE: the caller must free the stream listener */
 
.
 
NS_IMETHODIMP ns4xPluginInstance::NewStream(nsIPluginStreamListener** listener
)
.
NS_IMETHODIMP ns4xPluginInstance::NewStream(nsIPluginStreamListener** listener
)
{
.
{
  ns4xPluginStreamListener* stream = new ns4xPluginStreamListener(this, 
.
  ns4xPluginStreamListener* stream = new ns4xPluginStreamListener(this, 
                                                                  nsnull);
.
                                                                  nsnull);
 
.
 
	if(stream == nsnull)
.
	if(stream == nsnull)
		return NS_ERROR_OUT_OF_MEMORY;
.
		return NS_ERROR_OUT_OF_MEMORY;
 
.
 
	NS_ADDREF(stream);  // Stabilize
.
	NS_ADDREF(stream);  // Stabilize
    
.
    
    nsresult res = stream->QueryInterface(kIPluginStreamListenerIID, (void**)l
istener);
.
    nsresult res = stream->QueryInterface(kIPluginStreamListenerIID, (void**)l
istener);
 
.
 
    // Destabilize and avoid leaks. 
.
    // Destabilize and avoid leaks. 
    // Avoid calling delete <interface pointer>
.
    // Avoid calling delete <interface pointer>
	NS_RELEASE(stream);
.
	NS_RELEASE(stream);
 
.
 
	return res;
.
	return res;
}
.
}
 
.
 
nsresult ns4xPluginInstance::NewNotifyStream(nsIPluginStreamListener** listene
r, void* notifyData)
.
nsresult ns4xPluginInstance::NewNotifyStream(nsIPluginStreamListener** listene
r, void* notifyData)
{
.
{
  *listener = new ns4xPluginStreamListener(this, notifyData);
.
  *listener = new ns4xPluginStreamListener(this, notifyData);
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP ns4xPluginInstance::Print(nsPluginPrint* platformPrint)
.
NS_IMETHODIMP ns4xPluginInstance::Print(nsPluginPrint* platformPrint)
{
.
{
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP ns4xPluginInstance::HandleEvent(nsPluginEvent* event, PRBool* ha
ndled)
.
NS_IMETHODIMP ns4xPluginInstance::HandleEvent(nsPluginEvent* event, PRBool* ha
ndled)
{
.
{
  if(!mStarted)
.
  if(!mStarted)
    return NS_OK;
.
    return NS_OK;
 
.
 
  if (fNPP.pdata == nsnull || event == nsnull)
.
  if (fNPP.pdata == nsnull || event == nsnull)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  PRInt16 res = 0;
.
  PRInt16 res = 0;
  
.
  
  if (fCallbacks->event)
.
  if (fCallbacks->event)
    {
.
    {
#ifdef XP_MAC
.
#ifdef XP_MAC
      res = CallNPP_HandleEventProc(fCallbacks->event,
.
      res = CallNPP_HandleEventProc(fCallbacks->event,
                                    &fNPP,
.
                                    &fNPP,
                                    (void*) event->event);
.
                                    (void*) event->event);
#endif
.
#endif
 
.
 
#if defined(XP_WIN) || defined(XP_OS2)
.
#if defined(XP_WIN) || defined(XP_OS2)
      NPEvent npEvent;
.
      NPEvent npEvent;
      npEvent.event = event->event;
.
      npEvent.event = event->event;
      npEvent.wParam = event->wParam;
.
      npEvent.wParam = event->wParam;
      npEvent.lParam = event->lParam;
.
      npEvent.lParam = event->lParam;
 
.
 
      NS_TRY_SAFE_CALL_RETURN(res, CallNPP_HandleEventProc(fCallbacks->event,
.
      NS_TRY_SAFE_CALL_RETURN(res, CallNPP_HandleEventProc(fCallbacks->event,
                                    &fNPP,
.
                                    &fNPP,
                                    (void*)&npEvent), fLibrary);
.
                                    (void*)&npEvent), fLibrary);
#endif
.
#endif
      
.
      
      *handled = res;
.
      *handled = res;
    }
.
    }
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP ns4xPluginInstance :: GetValue(nsPluginInstanceVariable variable
,
.
NS_IMETHODIMP ns4xPluginInstance :: GetValue(nsPluginInstanceVariable variable
,
                                             void *value)
.
                                             void *value)
{
.
{
  if(!mStarted)
.
  if(!mStarted)
    return NS_OK;
.
    return NS_OK;
 
.
 
  nsresult  res = NS_OK;
.
  nsresult  res = NS_OK;
 
.
 
  switch (variable)
.
  switch (variable)
  {
.
  {
    case nsPluginInstanceVariable_WindowlessBool:
.
    case nsPluginInstanceVariable_WindowlessBool:
      *(PRBool *)value = mWindowless;
.
      *(PRBool *)value = mWindowless;
      break;
.
      break;
 
.
 
    case nsPluginInstanceVariable_TransparentBool:
.
    case nsPluginInstanceVariable_TransparentBool:
      *(PRBool *)value = mTransparent;
.
      *(PRBool *)value = mTransparent;
      break;
.
      break;
 
.
 
    default:
.
    default:
      if(fCallbacks->getvalue)
.
      if(fCallbacks->getvalue)
      {
.
      {
        NS_TRY_SAFE_CALL_RETURN(res, 
.
        NS_TRY_SAFE_CALL_RETURN(res, 
                                CallNPP_GetValueProc(fCallbacks->getvalue, 
.
                                CallNPP_GetValueProc(fCallbacks->getvalue, 
                                                     &fNPP, 
.
                                                     &fNPP, 
                                                     (NPPVariable)variable, 
.
                                                     (NPPVariable)variable, 
                                                     value), 
.
                                                     value), 
                                fLibrary);
.
                                fLibrary);
      }
.
      }
  }
.
  }
 
.
 
  return res;
.
  return res;
}
.
}
 
.
 
nsresult ns4xPluginInstance::GetNPP(NPP* aNPP) 
.
nsresult ns4xPluginInstance::GetNPP(NPP* aNPP) 
{
.
{
  if(aNPP != nsnull)
.
  if(aNPP != nsnull)
    *aNPP = &fNPP;
.
    *aNPP = &fNPP;
  else
.
  else
    return NS_ERROR_NULL_POINTER;
.
    return NS_ERROR_NULL_POINTER;
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
nsresult ns4xPluginInstance::GetCallbacks(const NPPluginFuncs ** aCallbacks)
.
nsresult ns4xPluginInstance::GetCallbacks(const NPPluginFuncs ** aCallbacks)
{
.
{
  if(aCallbacks != nsnull)
.
  if(aCallbacks != nsnull)
    *aCallbacks = fCallbacks;
.
    *aCallbacks = fCallbacks;
  else
.
  else
    return NS_ERROR_NULL_POINTER;
.
    return NS_ERROR_NULL_POINTER;
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
nsresult ns4xPluginInstance :: SetWindowless(PRBool aWindowless)
.
nsresult ns4xPluginInstance :: SetWindowless(PRBool aWindowless)
{
.
{
  mWindowless = aWindowless;
.
  mWindowless = aWindowless;
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
nsresult ns4xPluginInstance :: SetTransparent(PRBool aTransparent)
.
nsresult ns4xPluginInstance :: SetTransparent(PRBool aTransparent)
{
.
{
  mTransparent = aTransparent;
.
  mTransparent = aTransparent;
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
/* readonly attribute nsQIResult scriptablePeer; */
.
/* readonly attribute nsQIResult scriptablePeer; */
NS_IMETHODIMP ns4xPluginInstance :: GetScriptablePeer(void * *aScriptablePeer)
.
NS_IMETHODIMP ns4xPluginInstance :: GetScriptablePeer(void * *aScriptablePeer)
{
.
{
  if (!aScriptablePeer)
.
  if (!aScriptablePeer)
    return NS_ERROR_NULL_POINTER;
.
    return NS_ERROR_NULL_POINTER;
 
.
 
  *aScriptablePeer = nsnull;
.
  *aScriptablePeer = nsnull;
  return GetValue(nsPluginInstanceVariable_ScriptableInstance, aScriptablePeer
);
.
  return GetValue(nsPluginInstanceVariable_ScriptableInstance, aScriptablePeer
);
}
.
}
 
.
 
/* readonly attribute nsIIDPtr scriptableInterface; */
.
/* readonly attribute nsIIDPtr scriptableInterface; */
NS_IMETHODIMP ns4xPluginInstance :: GetScriptableInterface(nsIID * *aScriptabl
eInterface)
.
NS_IMETHODIMP ns4xPluginInstance :: GetScriptableInterface(nsIID * *aScriptabl
eInterface)
{
.
{
  if (!aScriptableInterface)
.
  if (!aScriptableInterface)
    return NS_ERROR_NULL_POINTER;
.
    return NS_ERROR_NULL_POINTER;
 
.
 
  *aScriptableInterface = nsnull;
.
  *aScriptableInterface = nsnull;
  return GetValue(nsPluginInstanceVariable_ScriptableIID, (void*)aScriptableIn
terface);
.
  return GetValue(nsPluginInstanceVariable_ScriptableIID, (void*)aScriptableIn
terface);
}
.
}