Browser Plug-in API: Using the Browser Plug-in API

The Browser Plug-in API enables the user to develop a plug-in application. This API consists of the following parts:

The Browser and plug-ins interact with each other through two interfaces:

Each function in the API has the prefix NPN or NPP to indicate which interface it uses to communicate.

Use Case 1: Initializing and Destroying a Plug-in

The Browser employs a common Netscape Plug-in ECOM interface to interact with any number of Netscape plug-in ECOM implementations. This interface has two abstract methods that closely map to the following Netscape plug-in DLL-level methods:

Each ECOM implementation derives from this interface and implements these two abstract methods to initialize and shutdown the plug-in. When the plug-in is initialized, the Browser and the plug-in exchange function tables.

The Browser calls the functions in the following table to initialize or delete a plug-in instance:

Table 2: Functions that initialize and destroy a plug-in
FunctionDescription
InitializeFuncsInitializes the plug-in

Exchanges function tables between the Browser and the plug-in

NPP_NewCreates a new instance of the plug-in
NPP_DestroyDeletes a plug-in instance
NPP_ShutdownShuts the plug-in down.

Deletes all resources allocated for the plug-in DLL.

When a Netscape ECOM plug-in is initialized, the Browser saves the following data:

The Browser passes a table of function pointers to the plug-in. This table is an allocated but uninitialized structure that contains the API that the plug-in provides to the Browser. The plug-in fills out this table during the initialization call.

The following example shows how to initialize a plug-in:

/** 

* The initialization function of the plug-in 

* exchanges function pointers between the Browser and the 

* plug-in, allowing calls to and from the plug-in. This

* function also initializes plug-in library global data. 

* All unimplemented functions should be set to NULL

* in the function table.

* For example, in the S60 platform, JRI support is not available. Therefore,

* aPpf->javaClass should be set to NULL.

*

* @param aPpf - allocated but uninitialized structure

* containing function pointers to implemented plug-in 

* functions.

*

* @return - an error code, on success returns NPERR_NO_ERROR.

*/



EXPORT_C NPError InitializeFuncs(NPPluginFuncs* aPpf)                               

{

    aPpf->size          = sizeof(NPPluginFuncs);

	 aPpf->version       = 1;

    aPpf->newp          = PluginNew;

    aPpf->destroy       = PluginDestroy;

    aPpf->setwindow     = PluginSetWindow;

    aPpf->newstream     = PluginNewStream;

    aPpf->destroystream = PluginDestroyStream;

    aPpf->asfile        = PluginStreamAsFile;

    aPpf->writeready    = PluginWriteReady;

    aPpf->write         = PluginWrite;

    aPpf->print         = NULL;

    aPpf->event         = PluginHandleEvent;

    aPpf->urlnotify     = PluginURLNotify;

    aPpf->javaClass     = NULL;

    aPpf->getvalue      = NULL;

    aPpf->setvalue      = PluginSetValue;



    return NPERR_NO_ERROR;

}



void CNpEcomMain::ConstructL(NPPluginFuncs* aPluginFuncs)

{

    NPError err;

    err = InitializeFuncs(aPluginFuncs);

}

Use Case 2: Creating a Plug-in Instance

The Browser calls the NPP_New function to create a plug-in instance for a particular MIME type. Instance-specific private data can be allocated at this time. This call does not pass windowing information to the plug-in constructor. The Browser then calls the NPP_SetWindow function to provide the windowing information required to embed the plug-in within the parent Web page.

Table 3: Functions that create a plug-in instance
FunctionDescription
NPP_NewCreates a new instance of a plug-in
NPP_SetWindowSets the parent window and the size of the plug-in. The coordinates are always relative to the parent window.

The following example shows how create a plug-in instance:

/** 

* The Browser calls this function to create a plug-in 

* instance based on a MIME type. The plug-in instance created

* can store its private data as a member (pdata) of the 

* instance argument passed.

*

* @param pluginType - the MIME type of the plug-in.

*

* @param instance - the pdata member variable is used by the 

* plug-in to store instance-specific private data. Commonly 

* used to store a pointer to an object, which is used for 

* operating on the plugin in the future.

*

* @param mode - identifies the display mode in which the plug-in

* was invoked.

* NP_EMBED – specifies that the plug-in was created using an

* embed tag within a Web document and that the plug-in is to be

* displayed within a Web document;

*

* NP_FULL - specifies that the plug-in was created by opening

* a document requiring plug-in support for display

* as the top level document and consumes 

* the entire document window.

*

* @param argn - a string list containing all the names of all 

* parameters included within the document embed tag.

*

* @param argv - a string list containing values corresponding 

* to the parameters passed in the argn by means of the embed 

* tag.

*

* @param saved — Not supported.

*

* @return - an error code. Upon success, returns 

* NPERR_NO_ERROR.

*/



NPError PluginNew(NPMIMEType pluginType, 

                  NPP instance, uint16 mode, 

                  CDesC16Array* argn, 

                  CDesC16Array* argv, 

                  NPSavedData* saved)

   {

    CNpInst* inst = NULL;



    TRAPD(ret, inst = CNpInst::NewL(instance));

    if (ret)

        return NPERR_OUT_OF_MEMORY_ERROR;



    instance->pdata = inst;

    return Inst(instance)->PluginNew(pluginType, 

												 instance, 

                                     mode, 

                                     argn, 

                                     argv, 

                                     saved);

   }





NPError CNpInst::PluginNew(NPMIMEType pluginType, 

                           NPP instance, 

                           uint16 mode, 

                           CDesC16Array* argn, 

                           CDesC16Array* argv, 

                           NPSavedData* )

    {

    if (instance->pdata != this)

        {

        return NPERR_INVALID_INSTANCE_ERROR;

        }



  

    // Do something with the attributes (name, value) passed

    // through argn, argv

                

 

    

    return NPERR_NO_ERROR;

    }

    

Use Case 3: Destroying a Plug-in Instance

The Browser calls the NPP_Destroy function to destroy a plug-in instance. The Browser application calls the NPP_Destroy function when the user performs any of the following actions:

If this is the last instance created by a plug-in, then the Browser calls the NPP_Shutdown function.

The plug-in developer must delete all the resources, including the memory, files, and sockets allocated by the Browser (such as streams) before calling the NPP_Destroy function. This function does not track or delete Browser-created objects.

To destroy a plug-in instance, call the functions in the following table:

Table 4: Functions that destroy a plug-in instance
FunctionDescription
NPP_DestroyDeletes a plug-in instance.
NPP_ShutdownDeletes all resources allocated for the plug-in DLL.

Called only if this is the last instance created by any plug-in.

The following example shows how to delete a plug-in instance.

/** 

* The Browser calls the PluginDestroy function to delete an

* instance of a plug-in previously constructed by NPP_New().

* When this function is called, the browser will have already

* cleaned up all other instance-related objects

* that it created.

*

* @param instance - the instance originally passed to

* NPP_New().

*

* @param save - optional parameter to save data for reuse by a 

* new plug-in instance with the same URL. The saved data is 

* passed to the NP_New() call of the new plug-in instance. The 

* buf field of the save variable should always be allocated 

* using NPN_MemAlloc() because the Browser is responsible for

* deleting this value.

* To ensure that the browser does not crash or leak

* memory when the saved data is discarded, the buf field should

* be a flat structure with no allocated substructures. 

* The browser is not aware of the structure of buf to free the 

* individual allocated members of the structure.

*

* @return - Since this is a destructor function, it should 

* always return NPERR_NO_ERROR.

*

* Inst is a function that returns a reference to the plug-in 

* instance.

*/



NPError PluginDestroy(NPP instance, NPSavedData** save)

    {

    return Inst(instance)->PluginDestroy(save);

    }





NPError CNpInst::PluginDestroy(NPSavedData** )

    {

  

    delete this;

    return NPERR_NO_ERROR;

    }

Use Case 4: Shutting Down a Plug-in

Shutting down a plug-in means:

The Browser does not call this function if any existing plug-in instances or plug-in stream instances are open.

The functions in the following table shutdown a plug-in application.

Table 5: Functions that shutdown a plug-in application
FunctionDescription
NPP_ShutdownShuts down a plug-in application

Be sure to delete all plug-in data before calling this function.

This function is useful for cleaning up data allocated by the NPP_Initialize function.

The following example shows how to implement the NPP_Shutdown function.

/** 

* This function has no input parameters and no return value. 

* It is called to allow the plug-in to clean up its data before

* the plug-in library is unloaded.

*/



EXPORT_C void NP_Shutdown(void)

    {

    CNpMain* npm = (CNpMain*) Dll :: Tls ();

    delete npm;

	  Dll :: SetTls ( NULL );

    }

Use Case 5: Drawing a Plug-in

The S60 platform supports only windowed plug-ins. This means that the plug-in is drawn inside its own native window on a Web page. The NPWindow structure represents the native window. This structure contains information about coordinate position, size, the state of the plug-in, and a handle to the window. The NPWindow structure is defined by the following code:

typedef struct _NPWindow

    {

    void* window;     // Platform-specific window handle

    int32 x;          // Position of top left corner relative

    int32 y;          // to a Web page.     

    uint32  width;    // Maximum window size

    uint32  height;

    NPRect  clipRect; // MAC - Clipping rectangle in port coordinates

    NPWindowType type;// Only WindowType Window is supported

    NPWindow;

    }

Using the NPP_SetWindow function, the plug-in constructs a CCoeControl object (or an object that inherits from CCoeControl) that is parented to the Web page. The plug-in also gets a pointer to an object that implements the PluginAdapter interface. The plug-in control should inherit from the following classes:

CCoeControlpublic#include<coecntrl.h>
MCoeControlObserverpublic #include<coecntrl.h>
MPluginNotifierpublic#include "Pluginadapterinterface.h" from the plug-in adapter utility

The parameters, plug-in instance, and the NPWindow structure provide all the necessary information to the NPP_SetWindow function call to create a control instance. The NPWindow argument contains information pertaining to the window. The most important data is:

The following function constructs the window for a plug-in application:

Table 6: Function that draws the window for a plug-in application
FunctionDescription
NPP_SetWindowSets the parent window and the size of the plug-in.

The coordinates are always relative to the parent window.

The following example demonstrates the implementation of the NPP_SetWindow function. The CPluginAdapterUtil::ExtractParentControlAndApiL function is called to set the parent control. The adapter object calls the Symbian Window APIs.

/** 

* The Browser calls the PluginSetWindow function to set the

* control parent and the coordinates for the plug-in.

* The first time this function is called, it

* is important to construct the corresponding plug-in control.

* The other times this call is made, it is expected that the

* function simply updates the bounds of the control.

*

* @param instance – the plug-in instance originally used in

* NPP_New().

*

* @param window - a plug-in window structure that contains

* window coordinates and platform-specific window information.

*

      * @return - an error code, on success returns NPERR_NO_ERROR.

*/



NPError PluginSetWindow(NPP instance, NPWindow* window)

    {

    return Inst(instance)->PluginSetWindow(window);

    }





NPError CNpInst::PluginSetWindow(NPWindow* window)

    {

    MPluginAdapterPTR pPluginAdapter = NULL;

    CCoeControlPTR pParentCoeControl = NULL;



    TRAPD(error, 

          CPluginAdapterUtil::ExtractParentControlAndApiL(

                                        window, 

                                        pPluginAdapter, 

                                        pParentCoeControl));

    if (error)

        return NPERR_GENERIC_ERROR;

 

    if (iFirstTime)

        {

        CreateWindowL(pParentCoeControl);

        pPluginAdapter->SetPluginNotifier(this);

        pPluginAdapter->PluginConstructedL(this);

        }

  



    TPoint point (window->x, window->y);

    TSize size(window->width, window->height);

    SetExtent(point, size);

  

    if (iFirstTime)

        {

        ActivateL();

        iFirstTime = EFalse;

        }

    return NPERR_NO_ERROR;

    }

 

Use Case 6: Allocating and Freeing Memory

The plug-in application calls the NPN_MemAlloc function to dynamically allocate a specified amount of memory. The plug-in calls the NPN_MemFree function to de-allocate a block of memory.

Table 7: Functions that allocate and free memory
FunctionDescription
NPN_MemAllocAllocates a specified amount of memory directly from the operating system on behalf of the plug-in
NPN_MemFreeFrees memory that was previously allocated by the Browser

The following example shows how to allocate and free memory for use by a plug-in application:

/** 

* memAlloc and memFree are implemented by the browser.  

* memFlush has an empty implementation in the browser and does 

* nothing when the plug-in calls this function.

*/



void CNpInst::HandleMemory()

    {

    CNpMain* npm = (CNpMain*) Dll :: Tls ();

    void* pMem = NULL;

    TUint32 memLeft = 0;

  

    // Alloc a zero memory size

    pMem = npm->Funcs()->memalloc(0);



 // Free the memory

    (void)npm->Funcs()->memfree(pMem);

 

    // Alloc a small memory size

    pMem = npm->Funcs()->memalloc(2000);

  

    // Free the small memory

    (void)npm->Funcs()->memfree(pMem);

  

    // Alloc a large memory size

    pMem = npm->Funcs()->memalloc(20000000);

  

    // Flush the memory, this function should do nothing

    memLeft = npm->Funcs()->memflush(20000000);

  

    // Free the large memory

    (void)npm->Funcs()->memfree(pMem);   

    }

Use Case 7: Sending a Stream From the Browser to a Plug-in

Streams are objects that represent data generated from a URL or data sent by a plug-in without an associated URL. Streams are produced by the Browser and consumed by a plug-in instance. A stream object has an associated MIME type, which identifies the format of the data in the stream. Each stream object is associated with a single plug-in, and a plug-in can hold multiple stream objects.

It is not possible to send a data stream from a plug-in application to the Browser.

The Browser performs the following tasks when sending a data stream to the plug-in:

  1. Creates a stream and informs the plug-in

    To inform a plug-in when a new stream is created, the Browser calls the NPP_NewStream function. This function also determines which mode the Browser should use to send data to the plug-in. The Browser can create a stream for the following types of data:

  2. Finds out from the plug-in how much data it can accept

    After calling the NPP_NewStream function and before writing data to the plug-in, the Browser calls the NPP_WriteReady function to determine the maximum number of bytes that the plug-in can accept. This function allows the Browser to send only as much data to the plug-in as it can handle at one time, and it helps both the Browser and the plug-in to use their resources efficiently.

  3. Writes data to the stream object

    The Browser pushes data into the stream by using a series of calls to the NPP_WriteReady and the NPP_Write functions. The NPP_Write function returns the number of bytes consumed by the plug-in instance. If this is a negative number, the Browser calls the NPP_DestroyStream function to destroy the stream. If the number returned is smaller than the size of the buffer, then the Browser sends the remaining data in the buffer to the plug-in through repeated calls to the NPP_WriteReady and NPP_Write functions.

  4. Notifies the plug-in and deletes the stream

    After it sends the stream to the plug-in, the Browser calls the NPP_DestroyStream function whether or not the stream arrived successfully. After the plug-in returns from this function, the Browser deletes the NPStream object.

    The plug-in stores private data associated with the stream in stream→pdata. Any resources that the plug-in allocated for that stream should be deleted when the stream is destroyed. The Browser stores private data in stream→ndata. The plug-in should not change the value of ndata.

The following table contains functions that implement streams.

Table 8: Functions that implement streams
FunctionDescription
NPP_NewStreamNotifies a plug-in instance of a new data stream
NPP_WriteReadyReturns the maximum data size that the plug-in can handle
NPP_WriteWrites a chunk of data to the plug-in
NPP_DestroyStreamDestroys the stream that was previously created to stream data to the plug-in application
NPP_StreamAsFilePasses the name of the file in which the stream data is stored to the plug-in application

The following example demonstrates how the Browser uses stream functions to send data to the plug-in.

/** 

* Stream functions are used by the browser to send data to the

* plug-in.

*/

NPError PluginNewStream (NPP instance, 

                         NPMIMEType type, 

                         NPStream* stream, 

                         NPBool seekable, 

                         uint16* stype)

    {

    return Inst(instance)->PluginNewStream(type, 

                                           stream, 

                                           seekable, 

                                           stype);

    }





NPError PluginDestroyStream (NPP instance, 

                             NPStream* stream, 

                             NPReason reason)

    {

    return Inst(instance)->PluginDestroyStream(stream, 

                                               reason);

    }





void PluginStreamAsFile (NPP instance, 

                         NPStream* stream, 

                         const TDesC16& fname)

    {

    Inst(instance)->PluginStreamAsFile(stream, fname);

    }





int32 PluginWrite (NPP instance, 

                   NPStream* stream, 

                   int32 offset, 

                   int32 len, 

                   void* buffer)

    {



    return Inst(instance)->PluginWrite(stream, 

                                       offset, 

                                       len, 

                                       buffer);

    }





int32 PluginWriteReady (NPP instance, NPStream* stream)

    {

    return Inst(instance)->PluginWriteReady(stream);

    }



/** 

* The plug-in class showing the definitions of the stream 

* functions and its implementations is given below. The Draw()

* function is shown for completeness; it is overridden by the 

* plug-in to display the bitmap received from the browser 

* using the stream functions. 

*/



class CNpInst : public CCoeControl, 

                public MCoeControlObserver, 

                public MPluginNotifier

{

public:

    static CNpInst* NewL (NPP aNpp);



    ~CNpInst();

  

    NPError PluginNewStream (NPMIMEType type, 

                            NPStream* stream, 

                            NPBool seekable, 

                            uint16* stype);



    NPError PluginDestroyStream (NPStream* stream, 

                                 NPReason reason);

  

    void PluginStreamAsFile (NPStream* stream, 

                             const TDesC16& fname);

  

    int32 PluginWrite (NPStream* stream, 

                       int32 offset, 

                       int32 len, 

                       void* buffer);

  

    int32 PluginWriteReady (NPStream* stream);



      …etc…



		private:

			TInt iStype;

  			NPStream* iStream;

  			TInt iWriteReady;

	HBufC* iFileName;



	void Draw(const TRect& aRect)const;



		…etc…  



};





NPError CNpInst::PluginNewStream (NPMIMEType mimeType, 

                                  NPStream* stream, 

                                  NPBool , 

                                  uint16* stype)

    {

    // set the stream type as NP_ASFILE so that the data is 

    // delivered to the plug-in as it is saved to a file.

    *stype = NP_ASFILE;

    iStream = stream;

    iStream->pdata = this;



    return NPERR_NO_ERROR;

    }





NPError CNpInst::PluginDestroyStream (NPStream* stream, 

                                      NPReason reason)

    {

    return NPERR_NO_ERROR;

    }





void CNpInst::PluginStreamAsFile (NPStream* stream, 

                                  const TDesC16& fname)

    {

    if ((stream->pdata != this) || (stream != iStream))

        {

        return;

        }



    if(iFileName)

        {

	     delete iFileName;

	     iFileName = NULL;

        }



    iFileName = fname.AllocL();

  

    }





int32 CNpInst::PluginWrite (NPStream* stream, 

                            int32 offset, 

                            int32 len, 

                            void* /*buffer*/)

    {

    if (stream->pdata != this || stream != iStream)

        {

        return 0;

        }



    return len;

    }





int32 CNpInst::PluginWriteReady (NPStream* stream)

    {

    return iWriteReady;

    }





void CNpInst::Draw ( const TRect& aRect ) const

    {



    CFbsBitmap* iBitmap = new (ELeave) CFbsBitmap();



    if(iFlipBitmap)

        {

        User::LeaveIfError(iBitmap->Load(

                            iFileName->Des(),  

                            EMbmAllbitmapsPinkflower, ETrue));

        }

    else

        {

        User::LeaveIfError(iBitmap->Load(

                            iFileName->Des(),  

                            EMbmAllbitmapsRedflower, ETrue));

        }



    SystemGc().Clear();

    SystemGc().DrawBitmap(aRect, iBitmap);

    delete(iBitmap);

    iBitmap = NULL;

  

    CNpMain* npm = (CNpMain*) Dll :: Tls ();

    TPtrC uaPtr = *(npm->Funcs()->uagent(iNpp));

    TUint16* ua16 = CopyPtrAndZeroTerminate(uaPtr);

    npm->Funcs()->status(iNpp, uaPtr);

    delete ua16;

}

Use Case 8: Handling URLs

A plug-in can request and receive the data associated with any type of URL that the Browser can handle.

Retrieving Data From a URL

The plug-in calls the NPN_GetURL function to ask the Browser to perform one of the following actions:

If the Browser cannot locate the URL or retrieve the data, it does not create a stream for the plug-in. The developer can call the NPN_GetURLNotify function to notify the plug-in that the data was not retrieved.

The Browser calls the NPP_URLNotify function to notify the plug-in. The Browser then passes the notifyData value to the plug-in. The notifyData parameter contains the private plug-in data passed to the corresponding call to the NPN_GetURLNotify function. The value of notifyData may be used to track multiple requests.

The NPN_GetURLNotify function handles the URL request asynchronously. It returns immediately and only later handles the request and calls the NPP_URLNotify function. The plug-in must receive this notification in order to determine whether a request with a null target failed or whether a request with a non-null target completed successfully.

Table 9: Functions`that retrieve data from a URL
FunctionDescription
NPN_GetURLRequests that the Browser load a specified URL
NPN_GetURLNotifyRequests that the Browser load a specified URL. The plug-in initiating the request is informed when the load completes. There is no way for the Browser to ensure that the server received the load request.
NPP_URLNotifyNotifies the plug-in that the specified URL request completed in one of the following ways:
  • Normal completion -- all data was sent to the plug-in
  • User canceled the stream
  • Stream failed due to network problems, disk I/O error, lack of memory, or some other problem

Posting URL Data

The plug-in calls the NPN_PostURL function to post data from a file or buffer to a URL. After posting the data, the NPN_PostURL function either displays the server response in the target window or delivers it to the plug-in.

The NPN_PostURLNotify function has the same capabilities as the NPN_PostURL function, with the following exceptions:

Table 10: Functions that post data to a URL
FunctionDescription
NPN_PostURLRequests that the Browser post information and display the result or pass it to the named target window or frame. If a name is not specified, then the target is assumed to be the plug-in itself.
NPN_PostURLNotifyRequests that the Browser post information to a specified URL. The Browser informs the plug-in when the load request is completed.
NPP_URLNotifyNotifies the plug-in that the specified URL request completed in one of the following ways:
  • Normal completion -- all data was sent to the plug-in
  • User canceled the stream
  • Stream failed due to network problems, disk I/O error, lack of memory, or some other problem

The following example demonstrates how the plug-in requests that the Browser load content from and post data to a specified URL.

/** 

* These functions show how the plug-in asks the browser to get 

* data from a URL or to post data to a URL. If the plug-in

* calls the geturlnotify() function or the

* posturlnotify() function, it receives 

* notification from the browser about the status of the call. 

*/

void CNpInst::HandleGet()

    {

    CNpMain* npm = (CNpMain*) Dll :: Tls ();

    NPError err = 0;

    TPtrC url('\0', 0);

    TPtrC urlStr(KNullString);

    TPtrC target('\0', 0);

    TPtrC targetStr(KNullString);



    if (iNewUrl)

        {

        // iNewUrl is non-null

        url.Set(iNewUrl);

        urlStr.Set(iNewUrl);

        }



    if (iWindow)

        {

        // iWindow is non-null

        target.Set(iWindow);

        targetStr.Set(iWindow);

        }



    if (iWindow)

        {

        err = npm->Funcs()->geturl(iNpp, url, &target);

        }

    else

        {

        err = npm->Funcs()->geturl(iNpp, url, NULL);

        }

    }





void CNpInst::HandlePost()

    {

    CNpMain* npm = (CNpMain*) Dll :: Tls ();

    RFile file;

    RFs rfs;

    TFileName fileName;

    NPError err = 0;

    TPtrC url('\0', 0);

    TPtrC urlStr(KNullString);

    TPtrC target('\0', 0);

    TPtrC targetStr(KNullString);



    if (iNewUrl)

        {

        // iNewUrl is non-null

        url.Set(iNewUrl);

        urlStr.Set(iNewUrl);

        }



    if (iWindow)

        {

        // iWindow is non-null

        target.Set(iWindow);

        targetStr.Set(iWindow);

        }

  

    if (iFromFile)

        {

        if (rfs.Connect() == KErrNone)

            {

            if (file.Temp(rfs, 

                    KTempPath(), 

                    fileName, 

                    EFileWrite) == KErrNone)

                {

                if (file.Write(KPostData8) == KErrNone)

                    {

                    fileName.ZeroTerminate();



                    if (iWindow)

                        {

                        err = npm->Funcs()->posturl(iNpp, 

                                                    url, 

                                                    &target, 

                                                    fileName, 

                                                    ETrue);

                        }

                    else

                        {

                        err = npm->Funcs()->posturl(iNpp, 

                                                    url, 

                                                    NULL, 

                                                    fileName, 

                                                    ETrue);

                        }

                    }

                file.Close();

                }

            rfs.Close();

            }

        }    

    else

        {

        // iFromFile == EFalse

        if (iWindow)

            {

            err = npm->Funcs()->posturl(iNpp, 

                                        url, 

                                        &target, 

                                        KPostData, 

                                        EFalse);

            }

        else

            {

            err = npm->Funcs()->posturl(iNpp, 

                                        url, 

                                        NULL, 

                                        KPostData, 

                                        EFalse);

            }

        }

    }





void CNpInst::HandleGetNotify()

    {

    CNpMain* npm = (CNpMain*) Dll :: Tls ();

    NPError err = 0;

    TPtrC url('\0', 0);

    TPtrC urlStr(KNullString);

    TPtrC target('\0', 0);

    TPtrC targetStr(KNullString);



    if (iNewUrl)

        {

        // iNewUrl is non-null

        url.Set(iNewUrl);

        urlStr.Set(iNewUrl);

        } 



    if (iWindow)

        {

        // iWindow is non-null

        target.Set(iWindow);

        targetStr.Set(iWindow);

        }

  

    if (iWindow)

        {

        err = npm->Funcs()->geturlnotify(iNpp, 

                                         url, 

                                         &target,

                                        (void*)(&KNotifyData));

        }

    else

        {

        err = npm->Funcs()->geturlnotify(iNpp, 

                                         url, 

                                         NULL, 

                                        (void*)(&KNotifyData);

        }

    }





void CNpInst::HandlePostNotify()

    {

    CNpMain* npm = (CNpMain*) Dll :: Tls ();

    RFile file;

    RFs rfs;

    TFileName fileName;

    NPError err = 0;

    TPtrC url('\0', 0);

    TPtrC urlStr(KNullString);

    TPtrC target('\0', 0);

    TPtrC targetStr(KNullString);



    if (iNewUrl)

        {

        // iNewUrl is non-null

        url.Set(iNewUrl);

        urlStr.Set(iNewUrl);

        }



    if (iWindow)

        {

        // iWindow is non-null

        target.Set(iWindow);

        targetStr.Set(iWindow);

        }



    if (iFromFile)

        {

        if (rfs.Connect() == KErrNone)

            {

            if (file.Temp(rfs, 

                          KTempPath(), 

                          fileName, 

                          EFileWrite) == KErrNone)

                {

                if (file.Write(KPostData8) == KErrNone)

                    {

                    fileName.ZeroTerminate();

                    if (iWindow)

                        {

                        err = npm->Funcs()->posturlnotify(

                                      iNpp, 

                                      url, 

                                      &target, 

                                      fileName, 

                                      ETrue, 

                                      (void*)(&KNotifyData));

                        }

                    else

                        {

                        err = npm->Funcs()->posturlnotify(

                                      iNpp, 

                                      url, 

                                      NULL, 

                                      fileName, 

                                      ETrue, 

                                      (void*)(&KNotifyData));

                        }

                    }

                file.Close();

                }

            rfs.Close();

            }

        }

     else

         {

         if (iWindow)

             {

                 err = npm->Funcs()->posturlnotify(iNpp, 

                                        url, 

                                        &target, 

                                        KPostData, 

                                        EFalse, 

                                        (void*)(&KNotifyData));

             }

         else

             {

                 err = npm->Funcs()->posturlnotify(iNpp, 

                                        url, 

                                        NULL, 

                                        KPostData, 

                                        EFalse, 

                                        (void*)(&KNotifyData));

             }

         }

     }

Use Case 9: Communicating With Java

The Web Browser for S60 does not support Java communication functions.

Use Case 10: Displaying Version, Status, and User Agent Information

The following utility functions enable a plug-in to display the current version of the Browser Plug-in API, the current Browser status, the current User Agent, and any newly installed plug-ins:

Table 11: Utility Functions
FunctionDescription
NPN_VersionReturns version information for the Browser Plug-in API.

The Browser does not support the NPN_Version function. Therefore, the plug-in should use the version parameter of the NPNetscapeFuncs class during initialization to:

  • Check that its version of the plug-in API is compatible with the Browser version
  • Determine whether a particular feature exists in the Browser version in which the plug-in runs

NPN_StatusReturns the current Browser status by displaying a message window in the top right corner of the screen
NPN_UserAgentReturns information about the currently configured User Agent to the plug-in. This information includes the name, version, and operating system on which the UA runs. The HTTP servers with which the Browser communicates may require this information.
NPN_ReloadPluginsSends a request to the Browser to rescan the file system for newly installed plug-ins.

The Browser searches all drives from A: to Z: for new plug-ins.

The Browser installs any new plug-ins it finds into the <A to Z>/apps/plugin/ directory and loads them without restarting.

Use Case 11: Building Plug-ins

To build the plug-in component, follow these steps:

  1. Add the following to the plug-in mmp file:

    USERINCLUDE   \epoc32\include\BrowserInterfaces\pluginInterface
    
    LIBRARY         PluginAdapterUtil.lib
  2. The NPP_SetWindow function must make a call to the ExtractParentControlAndApiL function API to extract the platform-dependent window:

    NPError NPP_SetWindow(NPP instance, NPWindow* window) 
    
        {
    
        TRAPD(error, 
    
              CPluginAdapterUtil::ExtractParentControlAndApiL(
    
                                /*in*/ window,
    
                                /*out*/iAdaptor,
    
                                      /*out*/iParentControl));
    
    
    
        //Error processing based on error
    
        //…and so on…
    
        }

Use Case 12: Installing Plug-ins

To install a plug-in application, follow these steps:

  1. Build the .sis file
  2. Create the .pkg file
  3. Assign a platform identification code
  4. List the files to install

Building the .sis File

To build the .sis file for installation using Infrared or Bluetooth communications, follow these steps:

  1. Create an installation file using the following command:

    makesis <plugin.pkg>

    Alternatively, the developer could create a .sis file by using the Sisar tool available with the S60 SDK. The Sisar tool packages all the application files into one .sis file and stores the installation details in a file with a .sisar extension.

  2. Send the newly created <plugin.sis> file to the phone by means of Infrared or Bluetooth communications.
  3. In the device, open the new message. Agree to everything it says, and the plug-in will install.

    Your operator may prohibit installation of uncertified applications.

  4. Restart the Browser in order for it to find the new plug-in DLLs.

    C:\apps\plugin is the default installation folder for plug-in DLLs.

Creating the .pkg File

The .pkg file specifies the executable code files and other resources needed to install an application onto a debive. The executable code files for the plug-in are the Dynamic Link Library (DLL) files.

To create the .pkg file, follow these steps:

  1. Specify the language
    : Languages
    
    &EN

    English is the default language. The syntax of the rest of the file should provide options for each supported language and locale.

  2. Create the package header

    The package header contains the following parts:

    An example of a .pkg header is as follows:

    ; Name/caption needed for each language, caption file used
    
    ; if supplied
    
    ; Name, Component ID, Major Version, Minor Version, Build,
    
    ; Package type
    
    #{"Test plugin"}, (0x0F6444), 1, 0, 0, TYPE+SISAPP

Assigning a Platform Identification Code

The platform identification code (platform UID) is a 32-bit number assigned to identify a specific version of a particular device. It enables a built-in system mechanism to issue a warning if the user attempts to install incompatible software into the device. For example:

; Platform UID code for recognition by a compatible device

; at installation time

(0x101F6F88), 0, 0, 0, {Series60ProductID"}

Listing the Files to Install

Each component to be installed is listed by its source file name followed by the location and name of the destination file. For example:

"\epoc32\release\thumb\urel\testplugin.dll" -

"!:\system\apps\plugin\testplugin.dll"

; End of file

Error handling

The NPError status code is as follows:

Memory overhead

The Browser requests each plug-in application to supply a buffer. The Browser uses this buffer to write the requested data to the plug-in. The typical buffer size is 1 - 5 Kbytes.

Extensions to the API

The following functionality extends the Netscape Plug-in API:

MPluginAdapter class

The plug-in can use this interface to communicate with the Browser. It exposes the following functions:

FunctionDescription
GetVersionGets the pointer to the minor version number of the Browser Plug-in API
PluginConstructedLCalled when plug-in creation is complete
PluginFinishedLCalled after the plug-in has been deleted
GetParentControlPoints to the parent control window
GetParentControlObserverObserver that the plug-in can use to send events to the Browser
SetPluginNotifierSets the plug-in notifier, which enables the plug-in to control portions of the Browser
SetOptionMenuHandlerSets the plug-in option menu handler, which enables the plug-in to handle custom menu commands from the Browser

Structures

The following structures are supported by the S60 platform:

NPPThe Browser creates an NPP structure for each plug-in instance and passes a pointer to it to the NPP_New function. This pointer identifies the instance on which API calls should operate and represents the opaque instance handle of a plug-in. NPP contains private instance data for both the plug-in and the Browser.

The NPP_Destroy function informs the plug-in when the NPP instance is about to be deleted. After this call returns, the NPP pointer is no longer valid.

NPRectDefines the area of the plug-in window to be updated, painted, invalidated, or clipped to.
NPStreamThe Browser allocates and initializes the NPStream object and passes it to the plug-in instance as a parameter of the NPP_NewStream function. The Browser cannot delete the object until after it calls the NPP_DestroyStream function.
NPWindowRepresents the native window. It contains information about coordinate position, size, and some platform-specific information.

A windowed plug-in is drawn into a native window (or portion of a native window) on a Web page. For windowed plug-ins, the Browser calls the NPP_SetWindow function with an NPWindow structure that represents a drawable (a pointer to an NPWindow allocated by the Browser). This window is valid until NPP_SetWindow is called again with a different window or the instance is destroyed.


Copyright © Nokia Corporation 2001-2008
Back to top