/[gcjwebplugin]/gcjwebplugin/src/gcjwebplugin.cc
ViewVC logotype

Diff of /gcjwebplugin/src/gcjwebplugin.cc

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by fitzsim, Mon Sep 15 02:52:00 2003 UTC revision 1.4 by fitzsim, Sat Oct 25 18:03:53 2003 UTC
# Line 1  Line 1 
1  /* gcjwebplugin - Webbrowser plugin to execute Java (tm) applets.  /* gcjwebplugin - web browser plug-in to execute Java (tm) applets
2     Copyright (C) 2003  Michael Koch <konqueror@gmx.de>     Copyright (C) 2003  Michael Koch <konqueror@gmx.de>
3       Copyright (C) 2003  Thomas Fitzsimmons <fitzsim@redhat.com>
4    
5  This program is free software; you can redistribute it and/or modify  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by  it under the terms of the GNU General Public License as published by
# Line 34  obligated to do so.  If you do not wish Line 35  obligated to do so.  If you do not wish
35  exception statement from your version. */  exception statement from your version. */
36    
37    
38    #include <glib.h>
39  #include <npapi.h>  #include <npapi.h>
40  #include <npupp.h>  #include <npupp.h>
41  #include <string.h>  #include <string.h>
42    #include <unistd.h>
43    
44  #include "config.h"  #include "config.h"
45    
46  #define PLUGIN_NAME "GCJ web browser plugin " PACKAGE_VERSION  #define PLUGIN_NAME "GCJ web browser plug-in"
47  #define PLUGIN_DESC "GCJ web browser plugin executes Java applets in Mozilla and other web browsers"  #define PLUGIN_DESC "The " PLUGIN_NAME \
48  #define PLUGIN_MIME_TYPE "application/x-java-applet"    " executes Java applets in Mozilla and other web browsers."
49  #define PLUGIN_MIME_DESC "application/x-java-applet:class,jar:GCJ Java Plugin"  #define PLUGIN_MIME_DESC                                           \
50  #define PLUGIN_FILE_EXTS "class,jar"    "application/x-java-vm:class,jar:GCJ;"                           \
51      "application/x-java-applet:class,jar:GCJ;"                       \
52      "application/x-java-applet;version=1.1:class,jar:GCJ;"           \
53      "application/x-java-applet;version=1.1.1:class,jar:GCJ;"         \
54      "application/x-java-applet;version=1.1.2:class,jar:GCJ;"         \
55      "application/x-java-applet;version=1.1.3:class,jar:GCJ;"         \
56      "application/x-java-applet;version=1.2:class,jar:GCJ;"           \
57      "application/x-java-applet;version=1.2.1:class,jar:GCJ;"         \
58      "application/x-java-applet;version=1.2.2:class,jar:GCJ;"         \
59      "application/x-java-applet;version=1.3:class,jar:GCJ;"           \
60      "application/x-java-applet;version=1.3.1:class,jar:GCJ;"         \
61      "application/x-java-applet;version=1.4:class,jar:GCJ;"           \
62      "application/x-java-applet;version=1.4.1:class,jar:GCJ;"         \
63      "application/x-java-applet;version=1.4.2:class,jar:GCJ;"         \
64      "application/x-java-applet;jpi-version=1.4.2_01:class,jar:GCJ;"  \
65      "application/x-java-bean:class,jar:GCJ;"                         \
66      "application/x-java-bean;version=1.1:class,jar:GCJ;"             \
67      "application/x-java-bean;version=1.1.1:class,jar:GCJ;"           \
68      "application/x-java-bean;version=1.1.2:class,jar:GCJ;"           \
69      "application/x-java-bean;version=1.1.3:class,jar:GCJ;"           \
70      "application/x-java-bean;version=1.2:class,jar:GCJ;"             \
71      "application/x-java-bean;version=1.2.1:class,jar:GCJ;"           \
72      "application/x-java-bean;version=1.2.2:class,jar:GCJ;"           \
73      "application/x-java-bean;version=1.3:class,jar:GCJ;"             \
74      "application/x-java-bean;version=1.3.1:class,jar:GCJ;"           \
75      "application/x-java-bean;version=1.4:class,jar:GCJ;"             \
76      "application/x-java-bean;version=1.4.1:class,jar:GCJ;"           \
77      "application/x-java-bean;version=1.4.2:class,jar:GCJ;"           \
78      "application/x-java-bean;jpi-version=1.4.2_01:class,jar:GCJ;"
79    
80    #define PLUGIN_DEBUG(arg)      g_printerr ("GCJ PLUGIN: %s",          arg)
81    #define PIPE_OUTPUT_DEBUG(arg) g_printerr ("  PIPE: plugin wrote %s\n", arg)
82    #define PIPE_INPUT_DEBUG(arg)  g_printerr ("  PIPE: plugin read %s\n",  arg)
83    
84    static NPNetscapeFuncs browserFunctions;
85    
86  #define PLUGIN_DEBUG(arg) printf("%s", arg)  static gint send_message_to_appletviewer (NPP instance, gchar *name, gchar *value);
87    static gint receive_message_from_appletviewer (NPP instance, gchar *string);
88    
89  struct GCJPluginData  struct GCJPluginData
90  {  {
# Line 54  struct GCJPluginData Line 93  struct GCJPluginData
93    char *archive;    char *archive;
94    char *documentbase;    char *documentbase;
95    char *parameters;    char *parameters;
96    int width;    char *width;
97    int height;    char *height;
98    int xid;    // The xid of the plugin window, encoded in hexadecimal.
99      char *xid;
100      GIOChannel *output_to_appletviewer;
101      GIOChannel *input_from_appletviewer;
102  };  };
103    
 char*  
 NPP_GetMIMEDescription()  
 {  
   PLUGIN_DEBUG ("NPP_GetMimeDescription\n");  
   
   return PLUGIN_MIME_DESC;  
 }  
   
104  NPError  NPError
105  NPP_GetValue (NPP instance, NPPVariable variable, void* value)  GCJ_GetValue (NPP instance, NPPVariable variable, void* value)
106  {  {
107    PLUGIN_DEBUG ("NPP_GetValue\n");    PLUGIN_DEBUG ("GCJ_GetValue\n");
   
   NPError result = NPERR_NO_ERROR;  
108    
109    switch (variable)    switch (variable)
110      {      {
111      case NPPVpluginNameString:      // This plug-in needs XEmbed support.
     case NPPVpluginDescriptionString:  
       *((char**) value) = "GCJ web browser plugin " VERSION;  
       break;  
   
     case NPPVpluginWindowBool:  
       *(PRBool*) value = PR_FALSE;  
       break;  
   
     case NPPVpluginTransparentBool:  
       *(PRBool*) value = PR_FALSE;  
       break;  
   
112      case NPPVpluginNeedsXEmbed:      case NPPVpluginNeedsXEmbed:
113        *(PRBool*) value = PR_TRUE;        PLUGIN_DEBUG ("GCJ_GetValue: Returning Plug-in NeedsXEmbed value\n");
114          *((PRBool*) value) = PR_TRUE;
115        break;        break;
116    
117      default:      default:
118        result = NPERR_GENERIC_ERROR;        PLUGIN_DEBUG ("GCJ_GetValue: Unknown Plug-in value requested\n");
119          return NPERR_GENERIC_ERROR;
120        break;        break;
121      }      }
   
   return result;  
 }  
   
 NPError  
 NPP_Initialize()  
 {  
   PLUGIN_DEBUG ("NPP_Initialize\n");  
   
122    return NPERR_NO_ERROR;    return NPERR_NO_ERROR;
123  }  }
124    
 void  
 NPP_Shutdown()  
 {  
   PLUGIN_DEBUG ("NPP_Shutdown\n");  
 }  
   
125  NPError  NPError
126  NPP_New (NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved)  GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
127             int16 argc, char* argn[], char* argv[],
128             NPSavedData* saved)
129  {  {
130    PLUGIN_DEBUG ("NPP_New\n");    PLUGIN_DEBUG ("GCJ_New\n");
131    
132    if (!instance)    if (!instance)
133      return NPERR_INVALID_INSTANCE_ERROR;      return NPERR_INVALID_INSTANCE_ERROR;
134    
135    GCJPluginData* data =    GCJPluginData* data =
136      (GCJPluginData*) NPN_MemAlloc (sizeof (struct GCJPluginData));      (GCJPluginData*) (* browserFunctions.memalloc) (sizeof (struct GCJPluginData));
137    
138    if (!data)    if (!data)
139      return NPERR_OUT_OF_MEMORY_ERROR;      return NPERR_OUT_OF_MEMORY_ERROR;
140    
141      // FIXME: size this dynamically.
142      gchar *command_line[50];
143    
144      // Allocate memory for the appletviewer name, --plugin option, each
145      // applet tag attribute and a terminating NULL.
146    
147      command_line[0] = g_strdup ("/home/fitzsim/build/plugin-bld/src/appletviewer");
148      command_line[1] = g_strdup ("--plugin");
149    
150      int arg_count = 2;
151    
152    for (int i = 0; i < argc; i++)    for (int i = 0; i < argc; i++)
153      {      {
154        // FIXME: Use glib functions here.        // FIXME: Use glib functions here.
155        if (!strcmp (argn[i], "code"))        if (!g_ascii_strcasecmp (argn[i], "code"))
156          data->code = argv[i];          data->code = g_strdup (argv[i]);
157        else if (!strcmp (argn[i], "codebase"))        else if (!g_ascii_strcasecmp (argn[i], "codebase"))
158          data->codebase = argv[i];          data->codebase = g_strdup (argv[i]);
159        else if (!strcmp (argn[i], "archive"))        else if (!g_ascii_strcasecmp (argn[i], "archive"))
160          data->archive = argv[i];          data->archive = g_strdup (argv[i]);
161        else if (!strcmp (argn[i], "documentbase"))        else if (!g_ascii_strcasecmp (argn[i], "documentbase"))
162          data->documentbase = argv[i];          data->documentbase = g_strdup (argv[i]);
163        else if (!strcmp (argn[i], "parameters"))        else if (!g_ascii_strcasecmp (argn[i], "parameters"))
164          // FIXME: need to handle multiple params          {
165          data->documentbase = argv[i];            // FIXME: need to handle multiple params
166        else if (!strcmp (argn[i], "width"))            data->documentbase = g_strdup (argv[i]);
167          data->width = atoi (argv[i]);            g_printerr ("THESE ARE THE PARAMETERS: %s\n", argv[i]);
168        else if (!strcmp (argn[i], "height"))          }
169          data->width = atoi (argv[i]);        else if (!g_ascii_strcasecmp (argn[i], "width"))
170            data->width = g_strdup (argv[i]);
171          else if (!g_ascii_strcasecmp (argn[i], "height"))
172            data->height = g_strdup (argv[i]);
173        else        else
174          printf ("GCJWebPlugin: unrecognized tag\n");          {
175              g_printerr ("GCJWebPlugin: unrecognized attribute\n");
176              continue;
177            }
178          command_line[arg_count++] = g_strdup_printf ("--%s=%s", argn[i], argv[i]);
179        }
180      command_line[arg_count] = NULL;
181    
182      GError *err = NULL;
183      gint output_to_appletviewer = 0;
184      gint input_from_appletviewer = 0;
185      if (!g_spawn_async_with_pipes (NULL,
186                                     command_line,
187                                     NULL,
188                                     (GSpawnFlags) 0,
189                                     NULL,
190                                     NULL,
191                                     NULL,
192                                     &output_to_appletviewer,
193                                     &input_from_appletviewer,
194                                     NULL,
195                                     &err))
196        {
197          g_printerr ("GCJ_New: Error: %s\n", err->message);
198          return NPERR_GENERIC_ERROR;
199      }      }
200    
201      // FIXME: Free command_line.
202    
203      data->output_to_appletviewer = g_io_channel_unix_new (output_to_appletviewer);
204      data->input_from_appletviewer = g_io_channel_unix_new (input_from_appletviewer);
205    
206    instance->pdata = data;    instance->pdata = data;
207    
208    return NPERR_GENERIC_ERROR;    NPError np_error;
209      if ((np_error = receive_message_from_appletviewer (instance, "running")) != NPERR_NO_ERROR)
210        return np_error;
211    
212      return NPERR_NO_ERROR;
213  }  }
214    
215  NPError  NPError
216  NPP_Destroy (NPP instance, NPSavedData** save)  GCJ_Destroy (NPP instance, NPSavedData** save)
217  {  {
218    PLUGIN_DEBUG ("NPP_Destroy\n");    PLUGIN_DEBUG ("GCJ_Destroy\n");
   
   // FIXME: Do we need to free the memory for NPP->pdata here ?  
219    
220    return NPERR_NO_ERROR;    // FIXME: Free NPP->pdata structures.
221      return send_message_to_appletviewer (instance, "shutdown", NULL);
222  }  }
223    
224  NPError  NPError
225  NPP_SetWindow (NPP instance, NPWindow* window)  GCJ_SetWindow (NPP instance, NPWindow* window)
226  {  {
227    PLUGIN_DEBUG ("NPP_SetWindow\n");    PLUGIN_DEBUG ("GCJ_SetWindow\n");
228    
229    jmethodID embeddedWindow_init;    GCJPluginData* data = (GCJPluginData *)instance->pdata;
   GCJPluginData* data = (GCJPluginData*) instance->pdata;  
230    
231    data->xid = (int) window->window;    if (data->width)
232        g_free (data->width);
233    
234    return NPERR_NO_ERROR;    data->width = g_strdup_printf ("%d", window->width);
235      data->height = g_strdup_printf ("%d", window->height);
236      data->xid = g_strdup_printf ("0x%x", (int)(window->window));
237    
238      return send_message_to_appletviewer (instance, "xid", data->xid);
239  }  }
240    
241  NPError  NPError
242  NPP_NewStream (NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)  GCJ_NewStream (NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
243  {  {
244    PLUGIN_DEBUG ("NPP_NewStream\n");    PLUGIN_DEBUG ("GCJ_NewStream\n");
245    
246    // Tell the web browser to download the file and notify the plugin when ready.    // Tell the web browser to download the file and notify the plugin when ready.
247    *stype = NP_ASFILEONLY;    *stype = NP_ASFILEONLY;
# Line 191  NPP_NewStream (NPP instance, NPMIMEType Line 250  NPP_NewStream (NPP instance, NPMIMEType
250  }  }
251    
252  void  void
253  NPP_StreamAsFile (NPP instance, NPStream* stream, const char* filename)  GCJ_StreamAsFile (NPP instance, NPStream* stream, const char* filename)
254  {  {
255    PLUGIN_DEBUG ("NPP_StreamAsFile\n");    PLUGIN_DEBUG ("GCJ_StreamAsFile\n");
256    
257    if (filename != NULL)    if (filename != NULL)
258      {      {
# Line 202  NPP_StreamAsFile (NPP instance, NPStream Line 261  NPP_StreamAsFile (NPP instance, NPStream
261  }  }
262    
263  NPError  NPError
264  NPP_DestroyStream (NPP instance, NPStream* stream, NPReason reason)  GCJ_DestroyStream (NPP instance, NPStream* stream, NPReason reason)
265  {  {
266    PLUGIN_DEBUG ("NPP_DestroyStream\n");    PLUGIN_DEBUG ("GCJ_DestroyStream\n");
267    
268    return NPERR_NO_ERROR;    return NPERR_NO_ERROR;
269  }  }
270    
271  int32  int32
272  NPP_WriteReady (NPP instance, NPStream* stream)  GCJ_WriteReady (NPP instance, NPStream* stream)
273  {  {
274    PLUGIN_DEBUG ("NPP_WriteReady\n");    PLUGIN_DEBUG ("GCJ_WriteReady\n");
275    
276    return 0;    return 0;
277  }  }
278    
279  int32  int32
280  NPP_Write (NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)  GCJ_Write (NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
281  {  {
282    PLUGIN_DEBUG ("NPP_Write\n");    PLUGIN_DEBUG ("GCJ_Write\n");
283    
284    return 0;    return 0;
285  }  }
286    
287  void  void
288  NPP_Print (NPP instance, NPPrint* platformPrint)  GCJ_Print (NPP instance, NPPrint* platformPrint)
289  {  {
290    PLUGIN_DEBUG ("NPP_Print\n");    PLUGIN_DEBUG ("GCJ_Print\n");
291  }  }
292    
293  int16  int16
294  NPP_HandleEvent (NPP instance, void* event)  GCJ_HandleEvent (NPP instance, void* event)
295  {  {
296    PLUGIN_DEBUG ("NPP_HandleEvent\n");    PLUGIN_DEBUG ("GCJ_HandleEvent\n");
297    
298    return 0;    return 0;
299  }  }
300    
301  void  void
302  NPP_URLNotify (NPP instance, const char* url, NPReason reason, void* notifyData)  GCJ_URLNotify (NPP instance, const char* url, NPReason reason, void* notifyData)
303  {  {
304    PLUGIN_DEBUG ("NPP_URLNotify\n");    PLUGIN_DEBUG ("GCJ_URLNotify\n");
305  }  }
306    
307  jref  jref
308  NPP_GetJavaClass ()  GCJ_GetJavaClass (void)
309  {  {
310    PLUGIN_DEBUG ("NPP_GetJavaClass\n");    PLUGIN_DEBUG ("GCJ_GetJavaClass\n");
311    
312    return 0;    return 0;
313  }  }
314    
315    static gint
316    send_message_to_appletviewer (NPP instance, gchar *name, gchar *value)
317    {
318      GError *err = NULL;
319      gsize bytes_written;
320      GCJPluginData* data = (GCJPluginData *)instance->pdata;
321      NPError np_error;
322    
323      // Send name of attribute to appletviewer.
324      gchar *name_buf = g_strdup_printf ("%s\n", name);
325    
326      if (g_io_channel_write_chars (data->output_to_appletviewer,
327                                    name_buf, -1, &bytes_written, &err)
328          != G_IO_STATUS_NORMAL)
329        {
330          g_printerr ("send_message_to_appletviewer: Error: %s\n", err->message);
331          return NPERR_GENERIC_ERROR;
332        }
333      if (err)
334        g_error_free (err);
335      err = NULL;
336    
337      g_io_channel_flush (data->output_to_appletviewer, &err);
338      if (err)
339        g_error_free (err);
340      err = NULL;
341      PIPE_OUTPUT_DEBUG (name);
342    
343      if ((np_error = receive_message_from_appletviewer (instance, name)) != NPERR_NO_ERROR)
344        return np_error;
345    
346      if (value)
347        {
348          // Send value of attribute to appletviewer.
349          gchar *value_buf = g_strdup_printf ("%s\n", value);
350          if (g_io_channel_write_chars (data->output_to_appletviewer,
351                                        value_buf, -1, &bytes_written, &err)
352              != G_IO_STATUS_NORMAL)
353            {
354              g_printerr ("send_message_to_appletviewer: Error: %s\n", err->message);
355              return NPERR_GENERIC_ERROR;
356            }
357          if (err)
358            g_error_free (err);
359          err = NULL;
360          PIPE_OUTPUT_DEBUG (value);
361          
362          g_io_channel_flush (data->output_to_appletviewer, &err);
363          if (err)
364            g_error_free (err);
365          err = NULL;
366    
367          if ((np_error = receive_message_from_appletviewer (instance, value)) != NPERR_NO_ERROR)
368            return np_error;
369        }
370    
371      g_printerr ("send_message_to_appletviewer: Success: %s, %s\n", name, value);
372    
373      return NPERR_NO_ERROR;
374    }
375    
376    static gint
377    receive_message_from_appletviewer (NPP instance, gchar *str)
378    {
379      GError *err = NULL;
380      GCJPluginData* data = (GCJPluginData *)instance->pdata;
381    
382      // Receive message from appletviewer.
383      gchar *read_buf;
384      if (g_io_channel_read_line (data->input_from_appletviewer,
385                                  &read_buf, NULL, NULL, &err)
386          != G_IO_STATUS_NORMAL)
387        {
388          g_printerr ("receive_message_from_appletviewer: Error: %s\n", err->message);
389          return NPERR_GENERIC_ERROR;
390        }
391    
392      PIPE_INPUT_DEBUG (read_buf);
393    
394      read_buf = g_strchomp (read_buf);
395    
396      str = g_strchomp (str);
397    
398      if (g_ascii_strcasecmp (str, read_buf))
399        {
400          g_printerr ("receive_message_from_appletviewer: "
401                      "Error: did not receive expected confirmation from appletviewer\n");
402          return NPERR_GENERIC_ERROR;
403        }
404    
405      return NPERR_NO_ERROR;
406    }
407    
408    // Factory functions.  Functions prefixed by NP_ provide functionality
409    // that is common to the plug-in as a whole.  Instance functions
410    // prefixed by GCJ_ operate on specific instances of GCJPluginData.
411    
412    // Provides the browser with pointers to the plug-in functions that we
413    // implement and initializes a local table with browser functions that
414    // we may wish to call.  Called once, after browser startup and before
415    // the first plug-in instance is created.
416    NPError
417    NP_Initialize(NPNetscapeFuncs* browserTable, NPPluginFuncs* pluginTable)
418    {
419      PLUGIN_DEBUG ("NP_Initialize\n");
420    
421      if ((browserTable == NULL) || (pluginTable == NULL))
422        return NPERR_INVALID_FUNCTABLE_ERROR;
423    
424      // Ensure that the major version of the plug-in API that the browser
425      // expects is not more recent than the major version of the API that
426      // we've implemented.
427      if ((browserTable->version >> 8) > NP_VERSION_MAJOR)
428        return NPERR_INCOMPATIBLE_VERSION_ERROR;
429    
430      // Ensure that the plug-in function table we've received is large
431      // enough to store the number of functions that we may provide.
432      if (pluginTable->size < sizeof(NPPluginFuncs))      
433        return NPERR_INVALID_FUNCTABLE_ERROR;
434    
435      // Ensure that the browser function table is large enough to store
436      // the number of browser functions that we may use.
437      if (browserTable->size < sizeof(NPNetscapeFuncs))
438        return NPERR_INVALID_FUNCTABLE_ERROR;
439    
440      // Store in a local table the browser functions that we may use.
441      browserFunctions.version = browserTable->version;
442      browserFunctions.size = browserTable->size;
443      browserFunctions.posturl = browserTable->posturl;
444      browserFunctions.geturl = browserTable->geturl;
445      browserFunctions.geturlnotify = browserTable->geturlnotify;
446      browserFunctions.requestread = browserTable->requestread;
447      browserFunctions.newstream = browserTable->newstream;
448      browserFunctions.write = browserTable->write;
449      browserFunctions.destroystream = browserTable->destroystream;
450      browserFunctions.status = browserTable->status;
451      browserFunctions.uagent = browserTable->uagent;
452      browserFunctions.memalloc = browserTable->memalloc;
453      browserFunctions.memfree = browserTable->memfree;
454      browserFunctions.memflush = browserTable->memflush;
455      browserFunctions.reloadplugins = browserTable->reloadplugins;
456      browserFunctions.getvalue = browserTable->getvalue;
457    
458      // Return to the browser the plug-in functions that we implement.
459      pluginTable->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
460      pluginTable->size = sizeof(NPPluginFuncs);
461      pluginTable->newp = NewNPP_NewProc(GCJ_New);
462      pluginTable->destroy = NewNPP_DestroyProc(GCJ_Destroy);
463      pluginTable->setwindow = NewNPP_SetWindowProc(GCJ_SetWindow);
464      pluginTable->newstream = NewNPP_NewStreamProc(GCJ_NewStream);
465      pluginTable->destroystream = NewNPP_DestroyStreamProc(GCJ_DestroyStream);
466      pluginTable->asfile = NewNPP_StreamAsFileProc(GCJ_StreamAsFile);
467      pluginTable->writeready = NewNPP_WriteReadyProc(GCJ_WriteReady);
468      pluginTable->write = NewNPP_WriteProc(GCJ_Write);
469      pluginTable->print = NewNPP_PrintProc(GCJ_Print);
470      pluginTable->urlnotify = NewNPP_URLNotifyProc(GCJ_URLNotify);
471      pluginTable->getvalue = NewNPP_GetValueProc(GCJ_GetValue);
472    
473      return NPERR_NO_ERROR;
474    }
475    
476    // Returns a string describing the MIME type that this plug-in
477    // handles.
478    char *
479    NP_GetMIMEDescription(void)
480    {
481      PLUGIN_DEBUG ("NP_GetMimeDescription\n");
482    
483      return PLUGIN_MIME_DESC;
484    }
485    
486    // Returns a value relevant to the plug-in as a whole.  The browser
487    // calls this function to obtain information about the plug-in.
488    NPError
489    NP_GetValue(void* future, NPPVariable variable, void *value)
490    {
491      PLUGIN_DEBUG ("NP_GetValue\n");
492    
493      NPError result = NPERR_NO_ERROR;
494    
495      switch (variable)
496        {
497        case NPPVpluginNameString:
498          PLUGIN_DEBUG ("NP_GetValue: Returning plug-in NameString value\n");
499          *((char**) value) = PLUGIN_NAME " " PACKAGE_VERSION;
500          break;
501    
502        case NPPVpluginDescriptionString:
503          PLUGIN_DEBUG ("NP_GetValue: Returning plug-in DescriptionString value\n");
504          *((char**) value) = PLUGIN_DESC;
505          break;
506    
507        default:
508          PLUGIN_DEBUG ("NP_GetValue: Unknown plug-in value requested\n");
509          result = NPERR_GENERIC_ERROR;
510          break;
511        }
512      return result;
513    }
514    
515    // Shuts down the plug-in.  Called after the last plug-in instance is
516    // destroyed.
517    NPError
518    NP_Shutdown(void)
519    {
520      PLUGIN_DEBUG ("NP_Shutdown\n");
521    
522      return NPERR_NO_ERROR;
523    }

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26