Plugins Netscape pour LINUX

Pierre Ficheux (pficheux@com1.fr)

Juin 1999


0. Résumé

Cet article est une introduction au développement de plugins pour Netscape Communicator sous LINUX. L'article présente un exemple complet de plugin afin de permettre au lecteur de réaliser simplement et rapidement des plugins pour Netscape. La lecture de cet articles nécessite une bonne compréhension du langage C et quelques notions sur X Window System (X11).

1. Quelques rappels sur les documents du WWW

La lecture d'un document du WWW (World Wide Web) depuis un navigateur (par exemple Netscape) sur un serveur utilise le protocole HTTP (Hyper Text Transport Protocol). Le principe du HTTP est extrèmement simple:
  1. Le navigateur demande un document sur un serveur (requète GET)
  2. Si le document existe, le serveur le type MIME du document suivi du contenu de celui-ci
  3. Le navigateur affiche (si possible) le document
  4. Lorsque le document est transmis le serveur coupe la connexion

Voici une petite exemple de dialogue d'un navigateur Netscape sous LINUX avec un serveur http. Voici la requète du navigateur:

GET / HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/3.04Gold (X11; I; Linux 2.0.27 i586)
Host: vclive.atlantel.fr:2222
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
et la réponse du serveur:
HTTP/1.0 200 OK
Content-Type: video/x-vcr

...

Le champs Content-Type retourné par le serveur indique le type MIME (Multimedia Internet Mail Extension) des données qui suivent.

Ce type permet de classifier les documents transportés sur le réseau. Il est exprimé sous la forme famille/type.

Voici quelques exemples de types MIME:

image/gif Fichier image GIF
text/html Document HTML
audio/x-wav Fichier audio .wav
video/x-vcr Fichier vidéo VCR COM One

Dans les derniers types x-wav et x-vcr, la lettre x signifie généralement qu'il s'agit d'un type étendu (eXtended) le plus souvent lu par un lecteur externe ou bien un module ajouté au navigateur (un plugin). Si le navigateur ne dispose par du module de lecture adéquat, il affichera en vrac les données dans la page ou au mieux proposera de sauver le fichier sur le disque.

2. Configuration des types traités par le navigateur

On peut éditer les types MIME traités par le navigateur Netscape en ouvrant le menu Edit/Preferences/Navigator/Applications. On obtient alors la fenêtre ci-dessous:

On peut connaitre la description complète du type MIME en cliquant sur Edit:

Dans ce cas, le document sera traité par un plugin.

3. Qu'est-ce qu'un plugin pour Netscape ?

Un plugin est un extension aux fonctionnalités de Netscape. Concrètement, le plugin est une bibliothèque partagée (un .so ou shared object) respectant l'API définie par Netscape. Le navigateur alloue une fenêtre de travail au plugin (la taille celle-ci pouvant être spécifiée par l'utilisateur dans la page HTML utilisant le plugin). Cette fenêtre est associée à un widget Xt, le plugin aura donc accès à la plupart des fonctions de la Xlib et de la Xt (affichage, traitement d'évènements dont souris, clavier, etc...). Il est donc possible de construire une vraie application X incrustée (embedded) dans une zône de la fenêtre de navigation.

Les plugins existent pour certains UNIX (dont LINUX) depuis la version 3.0 de Netscape. Ils seront placés à des endroits bien définis dans l'arboresence de votre disque, le plus souvent:

L'installation du plugin se résume le plus souvent à la copie du fichier .so dans le répertoire des plugins, exemple:

      cp vcplug.so /opt/netscape/plugins

Vous pouvez connaitre à tout moment la listes des plugins installés en ouvrant l'URL about:plugins.

4. Comment développer un plugin pour Netscape ?

Le développement d'un plugin nécessite les trois ingrédients suivants:
  1. Le Kit de développement pour UNIX disponible auprès de Netscape Communication sur l'URL ftp://ftp.netscape.com/pub/sdk/plugin/unix/unix-sdk-3.0b5.tar.Z

  2. Une bonne connaissance du langage C

  3. Une assez bonne connaissance de la programmation de l'interface X11, utilisée par la version UNIX de Netscape

L'extraction du SDK se fait simplement par un tar xzvf unix-sdk-3.0b5.tar.Z, on obtient alors les répertoires suivants:

Documentation La documentation complète en HTML, indispendable !
bin Les versions binaires des exemples, sans intérêt !
classes Quelques classes JAVA, sans grand intérêt et sûrement très obsolète !
common Contient l'indispensable fichier npunix.c
examples Quelques exemples en sources, avec pages HTML de test, utile...
include Les includes utilisés par l'API des plugins, indispensable !

4. Principe de fonctionnement d'un plugin

Le plugin correspond à une bibliothèque partagée qui sera ajoutée dynamiquement lors de l'exécution du navigateur. Ce module contient des points d'entrée qui seront exécutés par le navigateur au cours des différentes étapes de la vie du plugin:

Le développeur ne doit jamais perdre de vue le fait qu'il puisse exister plusieurs instances de son plugin dans une même session du navigateur ce qui nécessite une certaine rigueur de programmation. La méthodologie d'écriture d'un plugin est similaire à celle de la réalisation d'un driver ou bien d'un widget Xt.

Une type de donné étendu sera intégré à une page HTML en utilisant la balise EMBED (embedded). Si par exemple je désire ajouter une vidéo VCR à ma page HTML j'écrirai la ligne:

        <EMBED SRC="monfichier.vcr" WIDTH=320 HEIGHT=240 LOOP=true>

Lorsque le navigateur rencontre la balise EMBED il charge le plugin adéquat (suivant le type du fichier). Les paramètres du plugin, comme la taille de fenêtre allouée au plugin seront définies dans les options passées dans la ligne (ici WIDTH, HEIGHT et LOOP). Le dernier paramètre LOOP est spécifique à ce plugin et devra être traité par du code ajouté par le programmeur. Lorsque l'utilisateur quitte la page, la mémoire utilisée par le plugin est libérée.

5. Un exemple complet de plugin

Dans la suite de l'article, on se propose d'écrire un plugin bidon destiné à traiter le type MIME application/x-bid correspondant à des fichiers suffixés .bid. L'archive des sources du plugin est disponible sur: http://www.com1.fr/~pficheux/articles/lmf/plugins/exemple/bidplug.tar.gz.

Un fichier .bid est au format texte et contient une suite de points (un point par ligne):

100 200
50 240
150 180
0 0
Le plugin traitera ce fichier en lisant les points et en traçant les segments correspondants dans la fenêtre de navigation. En plus de cela, le plugin accepte les évènements d'entrée souris et clavier:

La première tâche à effectuer est de créer le répertoire des sources du plugin à partir des fichiers livrés dans le SDK:

Le fichier npunix.c ne doit pas être modifié comme indiqué au début du fichier:

 *----------------------------------------------------------------------
 * PLUGIN DEVELOPERS:
 *	YOU WILL NOT NEED TO EDIT THIS FILE.
 *----------------------------------------------------------------------

Les modifications seront exclusivement effectuées sur le fichier bidplug.c. Bien que celle-ci soit écrite en C, l'API des plugins Netscape utilise une approche objet similaire à celle utilisée par les widgets Xt. Chaque instance du plugin est définie par une structure PluginInstance dont les champs ne sont pas visibles depuis une autre instance:

typedef struct _PluginInstance
{
  NPWindow*		fWindow;
  uint16		fMode;

  Window window;
  Display *display;
  Colormap cmap;
  Visual *visual;
  GC gc;
  Widget widget;
  XFontStruct *fs;
  Boolean debug;
  uint32 x, y;
  uint32 width, height;
  int x_write, y_write;
  int x_old, y_old;
  FILE *fp_debug;
} PluginInstance;
De ce fait, l'utilisation de variables globales pour définir des paramètres du plugin est fortement déconseillée !

Le plugin utilise également des méthodes appelées au cours des étapes de son utilisation. Les principales méthodes utilisées (à adapter par le programmeur) sont:

NPP_New appelée lorsque le navigateur rencontre la balise EMBED. Cette méthode permettra en particulier de lire les options passées à la ligne EMBED.
NPP_Destroy appelée lorsque le navigateur quitte la page HTML. On procèdera alors aux libérations de mémoire nécessaires
NPP_SetWindow appelée lors de la création de la fenêtre de travail du plugin. C'est dans cette méthode que l'on pourra procèder à la récupération de la fenêtre (Window) et du widget associés à l'instance du plugin.
NPP_Write appelée lorsque le navigateur dispose de données à traiter par le plugin. C'est la méthode de base permettant le traitement des données reçues. Le navigateur passera en paramètre un pointeur vers les données envoyées au plugin ainsi que le nombre d'octets transmis. Le plugin doit retourner le nombre d'octets traités.
NPP_WriteReady indique au navigateur le nombre d'octets susceptibles d'être acceptés par le plugin. Si la plugin est capable de traiter toutes les données reçues, la méthode retournera une valeur très grande (STREAMBUFSIZE = 0x0FFFFFFF). Si le plugin doit travailler par bloc, la variable STREAMBUFSIZE vaudra la taille maxi du bloc à traiter.

Le plugin est identifié par le navigateur par trois valeurs constantes que l'on pourra par exemple définir dans un fichier desc.h:

#define PLUGIN_NAME		"Bidon Plug-in"
#define PLUGIN_DESCRIPTION 	"This Plugin is used for bidon files"
#define DESCRIPTION		"application/x-bid:bid:Bidon Plug-in"
La constante DESCRIPTION est particulièrement utile puisque c'est elle qui définit le type MIME traité par le plugin.

Le plugin sera compilé en utilisant un fichier Makefile ressemblant à celui-ci:

PLUGIN_DEFINES= -DUNIX -DXP_UNIX -I./include

CC= gcc
OPTIMIZER=  -g
CFLAGS=  $(OPTIMIZER) $(PLUGIN_DEFINES) -I. -I/usr/X11R6/include

OBJS= bidplug.o npunix.o

SHAREDTARGET=bidplug.so

default all: $(SHAREDTARGET)

$(SHAREDTARGET): $(OBJS)
	$(LD) -shared -o $(SHAREDTARGET) $(OBJS) $(LIBVCR) $(LDFLAGS)

clean:
	$(RM) $(OBJS) $(SHAREDTARGET) *~

$(OBJS): desc.h
Sous LINUX, on peut très simplement générer une bibliothèque partagée en utilisant l'option -shared du linker ld. Un fois le fichier .so généré par:
make 
gcc -g -DUNIX -DXP_UNIX -I./include -I. -I/usr/X11R6/include   -c bidplug.c -o bidplug.o
gcc -g -DUNIX -DXP_UNIX -I./include -I. -I/usr/X11R6/include   -c npunix.c -o npunix.o
ld -shared -o bidplug.so bidplug.o npunix.o
On installera simplement le plugin en faisant:
cp bidplug.so /opt/netscape/plugins
Il est alors nécessaire de QUITTER Netscape pour charger le nouveau plugin. Une fois Netscape relancé, on doit voir apparaitre le nouveau plugin en utilisant le menu Help/About plugins:

Vous pouvez également vérifier la présence du plugin à l'aide du menu Edit/Preferences/Navigator/Applications (voir paragraphe 2). Si vous éditez le type application/x-bid vérifiez bien la présence de la chaine bid dans le champ Suffixe.

Lorque le plugin est correctement installé, vous pouvez tester la page d'exemple HTML sur http://www.com1.fr/~pficheux/articles/lmf/plugins/exemple/html/bidon.html.

6. En cas de problème: comment debugger un plugin ?

Pour debugger un plugin vous devez:

7. Bibliographie