root/applications/osmozilla/osmo_npapi.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. Osmozilla_GetURL
  2. Osmozilla_SetStatus
  3. NPOsmozilla_New
  4. NPOsmozilla_Destroy
  5. NPOsmozilla_SetWindow
  6. NPOsmozilla_NewStream
  7. NPOsmozilla_WriteReady
  8. NPOsmozilla_Write
  9. NPOsmozilla_DestroyStream
  10. NPOsmozilla_StreamAsFile
  11. NPOsmozilla_Print
  12. NPOsmozilla_URLNotify
  13. NPOsmozilla_GetValue
  14. NPOsmozilla_SetValue
  15. NPOsmozilla_HandleEvent
  16. NP_Shutdown
  17. fillPluginFunctionTable
  18. NS_PluginInitialize
  19. NS_PluginGetValue
  20. NP_GetMIMEDescription
  21. NP_GetValue
  22. NP_Initialize
  23. NP_GetEntryPoints
  24. NP_Initialize
  25. GetFlags
  26. GetImplementationLanguage
  27. GetInterfaces
  28. GetHelperForLanguage
  29. GetContractID
  30. GetClassDescription
  31. GetClassID
  32. GetClassIDNoAlloc
  33. Pause
  34. Play
  35. Stop
  36. Update
  37. QualitySwitch
  38. SetURL
  39. SetInstance
  40. NS_IMETHODIMP_
  41. NS_IMETHODIMP_
  42. QueryInterface
  43. NPOsmozilla_GetServiceManager
  44. NPOsmozilla_ReleaseServiceManager
  45. NPOsmozilla_ShutdownScript
  46. NPOsmozilla_GetPeer
  47. NPOsmozilla_GetPeerIID
  48. OSMOZILLA_Allocate
  49. OSMOZILLA_Deallocate
  50. OSMOZILLA_Invalidate
  51. OSMOZILLA_HasMethod
  52. OSMOZILLA_Invoke
  53. OSMOZILLA_InvokeDefault
  54. OSMOZILLA_HasProperty
  55. OSMOZILLA_GetProperty
  56. OSMOZILLA_SetProperty
  57. OSMOZILLA_RemoveProperty
  58. OSMOZILLA_Enumerate
  59. Osmozilla_InitScripting

/*
*                       GPAC - Multimedia Framework C SDK
*
 *                      Authors: Jean Le Feuvre
 *                      Copyright (c) Telecom ParisTech 2000-2012
*                                       All rights reserved
*
*  This file is part of GPAC / Osmozilla NPAPI plugin
*
*  GPAC is free software; you can redistribute it and/or modify
*  it under the terms of the GNU Lesser General Public License as published by
*  the Free Software Foundation; either version 2, or (at your option)
*  any later version.
*
*  GPAC is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; see the file COPYING.  If not, write to
*  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/


////////////////////////////////////////////////////////////
//
// Implementation of Netscape entry points (NPN_*)
//
#include "osmo_npapi.h"
#include "osmozilla.h"

#if defined(XP_UNIX) && !defined(XP_MACOS)
#include <malloc.h>
#include <string.h>
#endif

NPNetscapeFuncs *sBrowserFunctions = NULL;

NPError Osmozilla_GetURL(NPP instance, const char *url, const char *target)
{
        if (!sBrowserFunctions) return NPERR_INVALID_FUNCTABLE_ERROR;
        return sBrowserFunctions->geturl(instance, url, target);
}

void Osmozilla_SetStatus(NPP instance, const char *message)
{
        if (!sBrowserFunctions) return;
        sBrowserFunctions->status(instance, message);
}

#ifndef GECKO_XPCOM
void Osmozilla_InitScripting(Osmozilla *osmo);
#endif

NPError NPOsmozilla_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved)
{
        Osmozilla *osmo;
        NPError rv = NPERR_NO_ERROR;
        if (instance == NULL)
                return NPERR_INVALID_INSTANCE_ERROR;

        osmo = (Osmozilla *) malloc(sizeof(Osmozilla));
        memset(osmo, 0, sizeof(Osmozilla));

        osmo->np_instance = instance;
        // associate the plugin instance object with NPP instance
        instance->pdata = (void *)osmo;

        osmo->supports_xembed = 0;
        sBrowserFunctions->getvalue(NULL, NPNVSupportsXEmbedBool, (void *)&osmo->supports_xembed);

        Osmozilla_Initialize(osmo, argc, argn, argv);

#ifndef GECKO_XPCOM
        Osmozilla_InitScripting(osmo);
#endif

        return rv;
}

// here is the place to clean up and destroy the nsPluginInstance object
NPError NPOsmozilla_Destroy (NPP instance, NPSavedData** save)
{
        NPError rv = NPERR_NO_ERROR;
        Osmozilla *osmozilla;
        if(instance == NULL)
                return NPERR_INVALID_INSTANCE_ERROR;

        osmozilla = (Osmozilla*)instance->pdata;
        if (osmozilla != NULL) {
                Osmozilla_Shutdown(osmozilla);
#ifdef GECKO_XPCOM
                NPOsmozilla_ShutdownScript(osmozilla);
#else
                if (osmozilla->script_obj) sBrowserFunctions->releaseobject(osmozilla->script_obj);
                osmozilla->script_obj = NULL;
#endif

                free(osmozilla);
        }
        instance->pdata = NULL;
        return rv;
}

// during this call we know when the plugin window is ready or
// is about to be destroyed so we can do some gui specific
// initialization and shutdown
NPError NPOsmozilla_SetWindow (NPP instance, NPWindow* pNPWindow)
{
        Osmozilla *osmozilla;
        void *os_wnd_handle, *os_wnd_display;
        NPError rv = NPERR_NO_ERROR;

        if (!instance || !instance->pdata) return NPERR_INVALID_INSTANCE_ERROR;
        if (pNPWindow == NULL) return NPERR_GENERIC_ERROR;
        osmozilla = (Osmozilla *)instance->pdata;

        // window just created
        if (!osmozilla->window_set) {
                if (pNPWindow->window == NULL) return NPERR_GENERIC_ERROR;

#ifdef XP_WIN
                os_wnd_handle = pNPWindow->window;
                os_wnd_display = NULL;
#elif defined(XP_MAXOS)
                os_wnd_handle = pNPWindow->window;
                os_wnd_display = NULL;
#elif defined(XP_UNIX)
                os_wnd_handle = pNPWindow->window;
                /*HACK - although we don't use the display in the X11 plugin, this is used to signal that
                the user is mozilla and prevent some X11 calls crashing the browser in file playing mode
                (eg, "firefox myfile.mp4" )*/
                os_wnd_display =((NPSetWindowCallbackStruct *)pNPWindow->ws_info)->display;
#endif

                if (! Osmozilla_SetWindow(osmozilla, os_wnd_handle, os_wnd_display, pNPWindow->width, pNPWindow->height) ) {
                        return NPERR_MODULE_LOAD_FAILED_ERROR;
                }

        }

#if 0
        // window goes away
        if((pNPWindow->window == NULL) && plugin->isInitialized())
                return plugin->SetWindow(pNPWindow);

        // window resized?
        if(plugin->isInitialized() && (pNPWindow->window != NULL))
                return plugin->SetWindow(pNPWindow);

        // this should not happen, nothing to do
        if((pNPWindow->window == NULL) && !plugin->isInitialized())
                return plugin->SetWindow(pNPWindow);
#endif

        return rv;
}

NPError NPOsmozilla_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t *stype)
{
        Osmozilla *osmozilla;
        if(instance == NULL)
                return NPERR_INVALID_INSTANCE_ERROR;

        osmozilla = (Osmozilla *)instance->pdata;
        if(osmozilla== NULL)
                return NPERR_GENERIC_ERROR;

        Osmozilla_ConnectTo(osmozilla, stream->url);
        *stype = NP_SEEK;
        return NPERR_NO_ERROR;
}

NPINT32 NPOsmozilla_WriteReady (NPP instance, NPStream *stream)
{
        return 0x0fffffff;
}

NPINT32 NPOsmozilla_Write (NPP instance, NPStream *stream, NPINT32 offset, NPINT32 len, void *buffer)
{
        return len;
}

NPError NPOsmozilla_DestroyStream (NPP instance, NPStream *stream, NPError reason)
{
        return NPERR_NO_ERROR;
}

void NPOsmozilla_StreamAsFile (NPP instance, NPStream* stream, const char* fname)
{
}

void NPOsmozilla_Print (NPP instance, NPPrint* printInfo)
{
        Osmozilla *osmozilla;
        if(instance == NULL)
                return;

        osmozilla = (Osmozilla *)instance->pdata;
        if(osmozilla== NULL)
                return;

        Osmozilla_Print(osmozilla, (printInfo->mode == NP_EMBED) ? 1 : 0, printInfo->print.embedPrint.platformPrint,
                        printInfo->print.embedPrint.window.x, printInfo->print.embedPrint.window.y,
                        printInfo->print.embedPrint.window.width, printInfo->print.embedPrint.window.height);
}

void NPOsmozilla_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
{
        return;
}

NPError NPOsmozilla_GetValue(NPP instance, NPPVariable variable, void *value)
{
        NPError rv = NPERR_NO_ERROR;
        Osmozilla *osmozilla;
        if(instance == NULL)
                return NPERR_INVALID_INSTANCE_ERROR;

        osmozilla = (Osmozilla *)instance->pdata;
        if(osmozilla== NULL) return NPERR_GENERIC_ERROR;

        switch (variable) {
#ifdef GECKO_XPCOM
        case NPPVpluginScriptableInstance:
                rv = NPOsmozilla_GetPeer(osmozilla, value);
                break;

        case NPPVpluginScriptableIID:
                rv = NPOsmozilla_GetPeerIID(osmozilla, value);
                break;
#else

        case NPPVpluginScriptableNPObject:
                sBrowserFunctions->retainobject(osmozilla->script_obj);
                * (void **)value = osmozilla->script_obj;
                break;

#endif
        case NPPVpluginNeedsXEmbed:
                *((int *)value) = 1;
                break;
        case NPPVpluginNameString :
                *(const char**)value = "Osmozilla/GPAC plugin for NPAPI";
                break;
        default:
                break;
        }

        return rv;
}



NPError NPOsmozilla_SetValue(NPP instance, NPNVariable variable, void *value)
{
        return NPERR_NO_ERROR;
}

int16_t NPOsmozilla_HandleEvent(NPP instance, void* event)
{
        /*we hacked the proc*/
        return 0;
}


NPError OSCALL NP_Shutdown()
{
#ifdef GECKO_XPCOM
        NPOsmozilla_ReleaseServiceManager();
#endif
        return NPERR_NO_ERROR;
}

static NPError fillPluginFunctionTable(NPPluginFuncs* aNPPFuncs)
{
        if(aNPPFuncs == NULL)
                return NPERR_INVALID_FUNCTABLE_ERROR;

        // Set up the plugin function table that Netscape will use to
        // call us. Netscape needs to know about our version and size
        // and have a UniversalProcPointer for every function we implement.

        aNPPFuncs->version       = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
        aNPPFuncs->newp          = NPOsmozilla_New;
        aNPPFuncs->destroy       = NPOsmozilla_Destroy;
        aNPPFuncs->setwindow     = NPOsmozilla_SetWindow;
        aNPPFuncs->newstream     = NPOsmozilla_NewStream;
        aNPPFuncs->destroystream = NPOsmozilla_DestroyStream;
        aNPPFuncs->asfile        = NPOsmozilla_StreamAsFile;
        aNPPFuncs->writeready    = NPOsmozilla_WriteReady;
        aNPPFuncs->write         = NPOsmozilla_Write;
        aNPPFuncs->print         = NPOsmozilla_Print;
        aNPPFuncs->event         = NPOsmozilla_HandleEvent;
        aNPPFuncs->urlnotify     = NPOsmozilla_URLNotify;
        aNPPFuncs->getvalue      = NPOsmozilla_GetValue;
        aNPPFuncs->setvalue      = NPOsmozilla_SetValue;
        return NPERR_NO_ERROR;
}


static NPError NS_PluginInitialize()
{
#ifdef GECKO_XPCOM
        NPOsmozilla_GetServiceManager();
#endif
        return NPERR_NO_ERROR;
}

// get values per plugin
NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue)
{
        NPError err = NPERR_NO_ERROR;
        switch (aVariable) {
        case NPPVpluginNameString:
                *((char **)aValue) = (char *) "Osmozilla";
                break;
        case NPPVpluginDescriptionString:
                *((char **)aValue) = Osmozilla_GetVersion();
                break;
        default:
                err = NPERR_INVALID_PARAM;
                break;
        }
        return err;
}




#define GPAC_PLUGIN_MIMETYPES \
        "audio/mpeg:mp2,mp3,mpga,mpega:MP3 Music;" \
        "audio/x-mpeg:mp2,mp3,mpga,mpega:MP3 Music;" \
        "audio/amr:amr,awb:AMR Audio;" \
        "audio/mp4:mp4,mpg4,mpeg4,m4a:MPEG-4 Audio;" \
        "audio/aac:aac:MPEG-4 AAC Music;" \
        "audio/aacp:aac:MPEG-4 AACPlus Music;" \
        "audio/basic:snd,au:Basic Audio;"       \
        "audio/x-wav:wav:WAV Audio;"    \
        "audio/3gpp:3gp,3gpp:3GPP/MMS Music;"   \
        "audio/3gpp2:3g2,3gp2:3GPP2/MMS Music;" \
        "video/mpeg:mpg,mpeg,mpe,mpv2:MPEG Video;" \
        "video/x-mpeg:mpg,mpeg,mpe,mpv2:MPEG Video;" \
        "video/mpeg-system:mpg,mpeg,mpe,vob,mpv2:MPEG Video;" \
        "video/x-mpeg-system:mpg,mpeg,mpe,vob,mpv2:MPEG Video;" \
        "video/avi:avi:AVI Video;" \
        "video/quicktime:mov,qt:QuickTime Movies;" \
        "video/x-ms-asf:asf,asx:Windows Media Video;" \
        "video/x-ms-wmv:wmv:Windows Media;" \
        "video/mp4:mp4,mpg4:MPEG-4 Video;" \
        "video/3gpp:3gp,3gpp:3GPP/MMS Video;" \
        "video/3gpp2:3g2,3gp2:3GPP2/MMS Video;" \
        "image/jpeg:jpeg,jpg:JPEG Images;"      \
        "image/png:png:PNG Images;"     \
        "image/bmp:bmp:MS Bitmap Images;"       \
        "image/svg+xml:svg,svg.gz,svgz:SVG Document;"   \
        "image/x-svgm:svgm:SVGM Document;"      \
        "x-subtitle/srt:srt:SRT SubTitles;"     \
        "x-subtitle/sub:sub:SUB SubTitles;"     \
        "x-subtitle/ttxt:ttxt:GPAC 3GPP TimedText;"     \
        "model/vrml:wrl,wrl.gz:VRML World;"     \
        "model/x3d+vrml:x3dv,x3dv.gz,x3dvz:X3D/VRML World;"     \
        "model/x3d+xml:x3d,x3d.gz,x3dz:X3D/XML World;" \
        "application/ogg:ogg:Ogg Media;" \
        "application/x-ogg:ogg:Ogg Media;" \
        "application/x-bt:bt,bt.gz,btz:MPEG-4 Text (BT);"       \
        "application/x-xmt:xmt,xmt.gz,xmtz:MPEG-4 Text (XMT);"  \
        "application/mp4:mp4,mpg4:MPEG-4 Movies;" \
        "application/sdp:sdp:Streaming Media Session;" \
        /* explicit plugin call */ \
        "application/x-gpac::GPAC plugin;" \
 
char * NP_GetMIMEDescription(void)
{
        return (char *) GPAC_PLUGIN_MIMETYPES;
}


NPError NP_GetValue(void *future, NPPVariable aVariable, void *aValue)
{
        return NS_PluginGetValue(aVariable, aValue);
}


#if defined(XP_WIN) || defined(XP_MACOS)

NPError OSCALL NP_Initialize(NPNetscapeFuncs* aNPNFuncs)
{
        sBrowserFunctions = aNPNFuncs;

        return NS_PluginInitialize();
}

NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* aNPPFuncs)
{
        return fillPluginFunctionTable(aNPPFuncs);
}


#elif defined(XP_UNIX)

NPError OSCALL NP_Initialize(NPNetscapeFuncs* aNPNFuncs, NPPluginFuncs* aNPPFuncs)
{
        NPError rv;
        sBrowserFunctions = aNPNFuncs;
        rv = fillPluginFunctionTable(aNPPFuncs);
        if(rv != NPERR_NO_ERROR)
                return rv;

        return NS_PluginInitialize();
}
#endif


#ifdef GECKO_XPCOM


#include <nsIServiceManager.h>
#include <nsIMemory.h>
#include <nsISupportsUtils.h>
#include <nsISupports.h>
#include <nsMemory.h>

#include "nsIOsmozilla.h"

#include "osmozilla.h"


nsIServiceManager *gServiceManager = NULL;


// We must implement nsIClassInfo because it signals the
// Mozilla Security Manager to allow calls from JavaScript.
// helper class to implement all necessary nsIClassInfo method stubs
// and to set flags used by the security system

class nsClassInfoMixin : public nsIClassInfo
{
        // These flags are used by the DOM and security systems to signal that
        // JavaScript callers are allowed to call this object's scritable methods.
        NS_IMETHOD GetFlags(PRUint32 *aFlags)
        {       *aFlags = nsIClassInfo::PLUGIN_OBJECT | nsIClassInfo::DOM_OBJECT;
                return NS_OK;
        }

        NS_IMETHOD GetImplementationLanguage(PRUint32 *aImplementationLanguage)
        {       *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
                return NS_OK;
        }

        // The rest of the methods can safely return error codes...
        NS_IMETHOD GetInterfaces(PRUint32 *count, nsIID ***array)
        {
                return NS_ERROR_NOT_IMPLEMENTED;
        }
        NS_IMETHOD GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
        {
                return NS_ERROR_NOT_IMPLEMENTED;
        }
        NS_IMETHOD GetContractID(char **aContractID)
        {
                return NS_ERROR_NOT_IMPLEMENTED;
        }
        NS_IMETHOD GetClassDescription(char **aClassDescription)
        {
                return NS_ERROR_NOT_IMPLEMENTED;
        }
        NS_IMETHOD GetClassID(nsCID **aClassID)
        {
                return NS_ERROR_NOT_IMPLEMENTED;
        }
        NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
        {
                return NS_ERROR_NOT_IMPLEMENTED;
        }
};


class nsOsmozillaPeer : public nsIOsmozilla , public nsClassInfoMixin
{
public:
        nsOsmozillaPeer(Osmozilla *osmo);
        virtual ~nsOsmozillaPeer();

        // methods from nsISupports
        NS_IMETHOD QueryInterface(const nsIID & aIID, void **aInstancePtr);
        NS_IMETHOD_(nsrefcnt) AddRef();
        NS_IMETHOD_(nsrefcnt) Release();

public:
        NS_DECL_NSIOSMOZILLA
        void SetInstance(Osmozilla *osmo);

protected:
        nsrefcnt mRefCnt;
        Osmozilla *mPlugin;
};


static NS_DEFINE_IID(kIZillaPluginIID, NS_IOSMOZILLA_IID);
static NS_DEFINE_IID(kIClassInfoIID, NS_ICLASSINFO_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);

nsOsmozillaPeer::nsOsmozillaPeer(Osmozilla *osmo)
{
        mPlugin=osmo;
        mRefCnt = 0;
}

nsOsmozillaPeer::~nsOsmozillaPeer()
{
}
// Notice that we expose our claim to implement nsIClassInfo.
//NS_IMPL_ISUPPORTS2(nsOsmozillaPeer, nsITestPlugin, nsIClassInfo)

// the following method will be callable from JavaScript
NS_IMETHODIMP nsOsmozillaPeer::Pause() {
        Osmozilla_Pause(mPlugin);
        return NS_OK;
}
NS_IMETHODIMP nsOsmozillaPeer::Play() {
        Osmozilla_Play(mPlugin);
        return NS_OK;
}
NS_IMETHODIMP nsOsmozillaPeer::Stop() {
        Osmozilla_Stop(mPlugin);
        return NS_OK;
}

NS_IMETHODIMP nsOsmozillaPeer::Update(const char *type, const char *commands)
{
        Osmozilla_Update(mPlugin, type, commands);
        return NS_OK;
}

NS_IMETHODIMP nsOsmozillaPeer::QualitySwitch(int switch_up)
{
        Osmozilla_QualitySwitch(mPlugin, switch_up);
        return NS_OK;
}

NS_IMETHODIMP nsOsmozillaPeer::SetURL(const char *url)
{
        Osmozilla_SetURL(mPlugin, url);
        return NS_OK;
}

void nsOsmozillaPeer::SetInstance(Osmozilla *osmo)
{
        mPlugin = osmo;
}

NS_IMETHODIMP_(nsrefcnt) nsOsmozillaPeer::AddRef()
{
        ++mRefCnt;
        return mRefCnt;
}

NS_IMETHODIMP_(nsrefcnt) nsOsmozillaPeer::Release()
{
        --mRefCnt;
        if (mRefCnt == 0) {
                delete this;
                return 0;
        }
        return mRefCnt;
}

// here nsOsmozillaPeer should return three interfaces it can be asked for by their iid's
// static casts are necessary to ensure that correct pointer is returned
NS_IMETHODIMP nsOsmozillaPeer::QueryInterface(const nsIID & aIID,
        void **aInstancePtr)
{
        if (!aInstancePtr)
                return NS_ERROR_NULL_POINTER;

        if (aIID.Equals(kIZillaPluginIID)) {
                *aInstancePtr = NS_STATIC_CAST(nsIOsmozilla *, this);
                AddRef();
                return NS_OK;
        }

        if (aIID.Equals(kIClassInfoIID)) {
                *aInstancePtr = NS_STATIC_CAST(nsIClassInfo *, this);
                AddRef();
                return NS_OK;
        }

        if (aIID.Equals(kISupportsIID)) {
                *aInstancePtr = NS_STATIC_CAST(nsISupports *, (NS_STATIC_CAST (nsIOsmozilla *, this)));
                AddRef();
                return NS_OK;
        }
        return NS_NOINTERFACE;
}

extern NPNetscapeFuncs *sBrowserFunctions;

void NPOsmozilla_GetServiceManager()
{
        // this is probably a good place to get the service manager
        // note that Mozilla will add reference, so do not forget to release
        nsISupports *sm = NULL;

        if (!sBrowserFunctions) return;
        sBrowserFunctions->getvalue(NULL, NPNVserviceManager, &sm);

        // Mozilla returns nsIServiceManager so we can use it directly; doing QI on
        // nsISupports here can still be more appropriate in case something is changed
        // in the future so we don't need to do casting of any sort.
        if (sm) {
                sm->QueryInterface(NS_GET_IID(nsIServiceManager), (void **) &gServiceManager);
                NS_RELEASE(sm);
        }
}

void NPOsmozilla_ReleaseServiceManager()
{
#ifdef GECKO_XPCOM
        // we should release the service manager
        NS_IF_RELEASE(gServiceManager);
        gServiceManager = NULL;
#endif
}

void NPOsmozilla_ShutdownScript(Osmozilla *osmo)
{
        nsOsmozillaPeer *peer = (nsOsmozillaPeer *) osmo->scriptable_peer;
        if (peer != NULL) {
                peer->SetInstance(NULL);
                NS_IF_RELEASE(peer);
        }
}


NPError NPOsmozilla_GetPeer(Osmozilla *osmo, void *value)
{
        if (!osmo->scriptable_peer) {
                osmo->scriptable_peer = new nsOsmozillaPeer(osmo);
                if (!osmo->scriptable_peer) return NPERR_OUT_OF_MEMORY_ERROR;
                NS_ADDREF( (nsOsmozillaPeer *) osmo->scriptable_peer);
        }

        NS_ADDREF( (nsOsmozillaPeer *)osmo->scriptable_peer);
        *(nsISupports **) value = (nsISupports *) osmo->scriptable_peer;
        return NPERR_NO_ERROR;
}

NPError NPOsmozilla_GetPeerIID(Osmozilla *osmo, void *value)
{
        static nsIID scriptableIID = NS_IOSMOZILLA_IID;
        if (!sBrowserFunctions) return NPERR_OUT_OF_MEMORY_ERROR;

        nsIID *ptr = (nsIID *) sBrowserFunctions->memalloc( sizeof(nsIID) );
        if (! ptr) return NPERR_OUT_OF_MEMORY_ERROR;

        *ptr = scriptableIID;
        *(nsIID **) value = ptr;
        return NPERR_NO_ERROR;
}

#else

enum
{
        kOSMOZILLA_ID_METHOD_PLAY = 0,
        kOSMOZILLA_ID_METHOD_PAUSE,
        kOSMOZILLA_ID_METHOD_STOP,
        kOSMOZILLA_ID_METHOD_UPDATE,
        kOSMOZILLA_ID_METHOD_QUALITY_SWITCH,
        kOSMOZILLA_ID_METHOD_SET_URL,

        kOSMOZILLA_NUM_METHODS
};

NPIdentifier    v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_NUM_METHODS];
const NPUTF8 *  v_OSMOZILLA_MethodNames[kOSMOZILLA_NUM_METHODS] = {
        "Play",
        "Pause",
        "Stop",
        "Update",
        "QualitySwitch",
        "SetURL",
};

NPClass osmozilla_script_class;

typedef struct {
        NPClass *_class;
        uint32_t referenceCount;
        Osmozilla *osmo;
} OsmozillaObject;

NPObject *OSMOZILLA_Allocate(NPP npp, NPClass *theClass)
{
        OsmozillaObject *obj = NULL;

        sBrowserFunctions->getstringidentifiers(v_OSMOZILLA_MethodNames, kOSMOZILLA_NUM_METHODS, v_OSMOZILLA_MethodIdentifiers);
        obj = (OsmozillaObject *)malloc(sizeof(OsmozillaObject));
        obj->osmo = (Osmozilla *) npp->pdata;
        return (NPObject *)obj;
}

void OSMOZILLA_Deallocate(NPObject* obj)
{
        free(obj);
        return;
}

void OSMOZILLA_Invalidate(NPObject* obj)
{
        return;
}

bool OSMOZILLA_HasMethod(NPObject* obj, NPIdentifier name)
{
        int i = 0;
        while (i < kOSMOZILLA_NUM_METHODS) {
                if ( name == v_OSMOZILLA_MethodIdentifiers[i] ) {
                        return 1;
                }
                i++;
        }
        return 0;
}

bool OSMOZILLA_Invoke(NPObject* obj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
        OsmozillaObject *npo = (OsmozillaObject *)obj;
        if (!npo->osmo) return 0;
        if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_PLAY]) {
                Osmozilla_Play(npo->osmo);
                return 1;
        }
        if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_PAUSE]) {
                Osmozilla_Pause(npo->osmo);
                return 1;
        }
        if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_STOP]) {
                Osmozilla_Stop(npo->osmo);
                return 1;
        }
        if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_UPDATE]) {
                const char *mime = NULL;
                const char *update = NULL;
                if (argCount==2) {
                        mime = (args[0].type==NPVariantType_String) ? args[0].value.stringValue.UTF8Characters : NULL;
                        update = (args[1].type==NPVariantType_String) ? args[1].value.stringValue.UTF8Characters : NULL;
                }
                if (!update) return 0;
                Osmozilla_Update(npo->osmo, mime, update);
                return 1;
        }
        if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_QUALITY_SWITCH]) {
                int up = 1;
                if (argCount==1) {
                        if (args[0].type==NPVariantType_Bool) up = args[0].value.boolValue ? 1 : 0;
                        else if (args[0].type==NPVariantType_Int32) up = args[0].value.intValue ? 1 : 0;
                }
                Osmozilla_QualitySwitch(npo->osmo, up);
                return 1;
        }
        if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_SET_URL]) {
                const char *url = "";
                if (argCount>=1) {
                        if (args[0].type==NPVariantType_String)
                                url = args[0].value.stringValue.UTF8Characters;
                }
                Osmozilla_SetURL(npo->osmo, url);
                return 1;
        }
        return 0;
}

bool OSMOZILLA_InvokeDefault(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
        return 1;
}

bool OSMOZILLA_HasProperty(NPObject* obj, NPIdentifier name)
{
        bool result = 0;
        if ( sBrowserFunctions->identifierisstring(name) )
        {
                NPUTF8 *val = sBrowserFunctions->utf8fromidentifier(name);

                if ( !strcmp(val, "DownloadProgress") )
                {
                        result = 1;
                }

                sBrowserFunctions->memfree(val);
        }
        /*nothing exposed yet*/
        return result;
}

bool OSMOZILLA_GetProperty(NPObject* obj, NPIdentifier name, NPVariant* result)
{
        OsmozillaObject *npo = (OsmozillaObject *)obj;
        if (!npo->osmo) return 0;
        if ( sBrowserFunctions->identifierisstring(name) )
        {
                NPUTF8 *val = sBrowserFunctions->utf8fromidentifier(name);

                if ( !strcmp(val, "DownloadProgress") )
                {
                        int val = Osmozilla_GetDownloadProgress(npo->osmo);
                        INT32_TO_NPVARIANT(val, *result);
                }

                sBrowserFunctions->memfree(val);
        }
        return 1;
}

bool OSMOZILLA_SetProperty(NPObject *obj, NPIdentifier name, const NPVariant *value)
{
        return 1;
}

bool OSMOZILLA_RemoveProperty(NPObject *npobj, NPIdentifier name)
{
        return 1;
}

bool OSMOZILLA_Enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
{
        return 1;
}

void Osmozilla_InitScripting(Osmozilla *osmo)
{
        osmozilla_script_class.allocate          = OSMOZILLA_Allocate;
        osmozilla_script_class.deallocate        = OSMOZILLA_Deallocate;
        osmozilla_script_class.invalidate        = OSMOZILLA_Invalidate;
        osmozilla_script_class.hasMethod         = OSMOZILLA_HasMethod;
        osmozilla_script_class.invoke            = OSMOZILLA_Invoke;
        osmozilla_script_class.invokeDefault     = OSMOZILLA_InvokeDefault;
        osmozilla_script_class.hasProperty       = OSMOZILLA_HasProperty;
        osmozilla_script_class.getProperty       = OSMOZILLA_GetProperty;
        osmozilla_script_class.setProperty       = OSMOZILLA_SetProperty;
        osmozilla_script_class.removeProperty    = OSMOZILLA_RemoveProperty;
        osmozilla_script_class.enumerate         = OSMOZILLA_Enumerate;

        /*create script object*/
        osmo->script_obj = sBrowserFunctions->createobject(osmo->np_instance, &osmozilla_script_class);

}

#endif //GECKO_XPCOM


/* [<][>][^][v][top][bottom][index][help] */