# Plug-ins Support in Amaya

Plug-ins allow Amaya to be extended by embedding external application. Two main motivations lead us to add a support for plug-ins into Amaya:

- To make new experiments with HTML Cougar especially with the OBJECT element,,

- To allow users to use new image formats, to support audio/video applications, to run some new web applications such as control applications (electronic payment for example), etc.

Amaya Plug-ins support is developed according to the Netscape Plug-in API.

## Usage of Plug-ins

There is no difficulty for installing plug-ins for Amaya. One just have to create a plug-in directory, in which the dynamic code of plug-ins have to be stpred, and to define the environment variable AMAYA_PLUGIN_DIR that gives the plug-in directory. For example:

    > mkdir /users/guetari/plugindir

    > setenv AMAYA_PLUGIN_DIR /users/guetari/plugindir

If the environment variable AMAYA_PLUGIN_DIR does not exist, Amaya uses the default directory $(HOME)/.amaya/plugins to look for dynamic code of plug-ins when it starts up.

Some other files may need to be installed and/or other environment variables have to be set (according to plug-ins installation instructions).

At the present time, plug-ins are developed for commercial web browser and may have assisted automatic installation procedures. These latter are not yet valid for Amaya, only manual installation is right.

The plug-in button when pressed shows the list of all installed plug-ins. For each of them we can see the Mime type it handles.

There is a major difference between Amaya and other web browsers supporting plug-ins mechanism. Plug-ins are encapsulated in HTML pages using the OBJECT element and not the EMBED element which is not recognized in ani W3C HTML DTD. OBJECT is a part of the HTML Cougar norm.

At least three parameters are required for each plug-in:

- DATA which is a URL to the object's (plug-in) data,

- WIDTH which gives the suggested width of a box enclosing the visible area of the object (plug-in),

- HEIGHT which gives the suggested height of a box enclosing the visible area of the object (plug-in)

    <OBJECT DATA="http://www.location/plugindatadir/datafile.ext" HEIGHT=400, WIDTH=200>

    </OBJECT>

In addition to these three parameters, plug-ins may need other attributes to communicate information between the HTML page and its code. These private attributes have to be introduced using the PARAM element of the OBJECT element.

## Amaya Plug-in API

When Amaya starts up, it looks for all available plug-ins into the amaya plug-in directory. For each plug-in, it initializes a structure (PluginInfo) which indicates the path and the name of the dynamic code of the plug-in, its mime type, its identifier, and the functions supplied by Amaya. These functions allow the plug-in to communicate with Amaya:

    struct PluginInfo {

       char* pluginDL;       /* Location of the plug-in dynamic code */

       char* pluginMimeType; /*Mime type of the plug-in */

       char* pluginID;       /* plug-in identifier */

       char* pluginURL;      /* Where data needed by plug-in is stored */

       char* fileExt;        /* Suffix of files supported by the plug-in */

       void* pluginHandle ;  /* Address of the dynamic code of the plug-in when loaded */

       NPPluginFuncs* pluginFunctionTable; /* Functions supplied by the plug-in */

};

For each plug-in a driver is added into the PictureHandlerTable. It indicates the coordinates, the height and the width of the box where the visible part of the plug-in will be displayed, the name of the data file needed by the plug-in, the pointer on the instance of the plug-in when created. An instance of a given plug-in is created when Amaya encounters in a HTML file data of a Mime type registered for the plug-in.

### TtaBrowsePluginDirectory:

This function browses the amaya plug-in directory mentioned by the environment variable AMAYA_PLUGIN_DIR (or the directory $(HOME)/.amaya/plugins by default). For each plug-in, it initializes the structure PluginInfo and store it into the pluginTable. Then it calls the function InitPluginHandlers. TtaBrowsePluginDirectory requires no parameters:

    TtaBrowsePluginDirectory ()

### InitPluginHandlers:

This function initializes a driver for the plug-in and stores it in the table of the image drivers (PictureHandlerTable). This driver shows the coordinates, the height and the width of the box where the visible part of the plug-in will be displayed, a pointer to an instance of the plug-in, the data file name needed by the plug-in, etc. This function requires two parameters:

    InitPluginHandlers (boolean printing, int indexHandler)

- `printing` is a boolean variable which indicates if the driver supports printing. At the present time, it is always set to FALSE.

- `indexHandler` is the index of the plug-in in the pluginTable.

### Ap_InitializePlugin:

This function loads the dynamic code of the plug-in, determines its Mime type and indicates to the plug-in the functions supplied by Amaya. These functions are needed by the plug-in to communicate with Amaya. This function requires two parameters:

    Ap_InitializePlugin (char* path, int indexHandler)

- `path` indicates the directory of the dynamic code of the plug-in and the name of the library (for example: `"/users/guetari/.amaya/plugins/mypluginlib.so"`)

- `indexHandler` is the index of the plug-in in the pluginTable.

## Creating instances and displaying plug-ins

When Amaya encounters data of a Mime type registered for a given plug-in, it creates an instance of the plug-in, displays it and transmit the data to the plug-in.

### Ap_CreatePluginInstance:

This functions creates an instance of the given plug-in and a stream with the data file. Then it calls the plug-in function NPP_NEW. This function requires three parameters:

    void Ap_CreatePluginInstance (PictInfo* imageDesc, Display* display, int type)

- `imageDesc` gives the information about the plug-in: X and Y coordinates, width and height of a box enclosing the visible area of the plug-in, the data file name and a pointer which will be set to the address of the instance,

- `display` (for unix platforms),

- `type` allows to determine the index of the plug-in in the pluginTable.

When the instance is created, it interacts with Amaya: Amaya may call plug-in functions and vice versa. The Amaya functions called by the plug-in are:

### Ap_MemAlloc:

Allocates memory from Amaya side. It requires one parameters the size of block memory to be allocated.

void* Ap_MemAlloc (uint32 size)

### Ap_MemFlush:

At the present time, `Ap_MemFlush` calls `Ap_MemAlloc` and does nothing else. It requires one parameter:

    void* Ap_MemFlush (uint32 size)

### Ap_MemFree:

Deallocate the block of memory specified by `ptr`. Its parameter is the pointer to deallocate:

    void Ap_MemFree (void* ptr).

### Ap_DestroyStream:

Closes and deletes a stream. It requires three parameters:

    NPError Ap_DestroyStream (NPP instance, NPStream* stream NPError reason)

- `instance` is the instance of the plug-in concerned by the stream to be destroyed,

- `stream` is the stream to destroy

- `reason` indicates why the stream has to be destroyed

### Ap_GetJavaEnv:

Not yet implemented

### Ap_GetJavaPeer:

Not yet implemented

### Ap_URLNotify:

Notifies a plug-in instance of the completion of a URL request. It requires four parameters:

    void Ap_URLNotify (NPP instance, const char* url, NPReason reason, void* notifyData)

- `url` is the location of the data needed by the stream,

- `reason` is the reason of the notification: the data is completely transmitted, the stop button is pushed, etc.

- `notifyData` is a plug-in private value used to uniquely identify the request.

### Ap_GetURL:

Requests that a new stream be created with the contents of the given URL. It requires three parameters:

    NPError Ap_GetURL (NPP instance instance, const char* url, const char* target)

- `instance` is the plug-in instance which require the creation of the new stream,

- `url` is the location of the data needed by the created stream,

- `target` indicates the target of the stream. If target is non-NULL, the stream is sent to Amaya, otherwise, the stream is sent to the plug-in.

### Ap_GetURLNotify:

Does the same thing then `Ap_GetURL` but notifies to the plug-in the end of the stream by calling`Ap_GetURLNotify`. It requires a parameters more than `Ap_GetURL` which is `notifyData`. This latter is a plug-in private value used to uniquely identify the request.

    NPError Ap_GetURLNotify (NPP instance instance, const char* url, const char* target, void* notifyData)

### Ap_NewStream:

Requests the creation of a new stream of data produced by the plug-in and consumed by Amaya. This function is, at the present time partially implemented into Amaya. It requires four parameters:

    Ap_NewStream (NPP instance, NPMIMEType type, const char* target, NPStream** stream_ptr)

- `type` is the mime type of the stream to be created,

- `target` indicates the window or the frame where the result of the stream will be displayed,

- `stream_ptr` is a pointer on the stream which will be created.

### Ap_PostURL:

Post data from a file to a given URL. This function is partially implemented at the present time and requires six parameters:

    Ap_PostURL (NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file)

- `buf` contains the data to be posted,

- `len` is the length of the buffer to be posted,

- `file` is a boolean. If it is TRUE, the data is stored in a file else it is stored in a bloc memory.

### Ap_PostURLNotify:

It behaves exactly like `Ap_PostURL` but notifies the plug-in at the end of the post operation (by calling `Ap_URLNotify`). In addition to the parameters of `Ap_PostURL`, it requires a parameter of type `void*` which is plug-in private value used to uniquely identify the request (`notifyData`).

    Ap_PostURL (NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file, void* notifyData)

### Ap_RequestRead:

Request a range of bytes for a seekable stream. It requires two parameters a stream and list of types `NPByteRange` which is a linked list of objects, each of which indicates an offset and a length into the stream:

    NPError Ap_RequestRead (NPStream* stream, NPByteRange list)

### Ap_GetValue:

Only for Unix platform. It requires three parameters: `instance` (of the plug-in), variable (of type `NPNVariable`) and `r_value` (of type `void*`). `instance` and `variable` are input parameters and `r_value` is an output parameter. If variable is set to `NPNVxDisplay`, `r_value` is set to the value of the Display. If variable value is `NPNVxtAppContext`, `r_value` is set to the value of the application context.

    void Ap_GetValue (NPP instance, NPNVariable var, void* r_value)

## Examples of plugins

- Try the tcl plug-in here

- Here you can play with the webxpresso plug-in

- Examples of vosaic plug-in are here

Your comments are welcome.