"Launch virt-viewer" (new) browser plugin. - Based on npshell from xulrunner 1.9.0. - Includes test page. The file 'npunix.c' is pretty much identical to what is in xulrunner 1.9.0, except that I made a few const-correctness fixes. The file 'npshell.c' is only minimally modified from what is in xulrunner, just changed so that it calls the new plugin entry points. The interesting stuff happens in 'launcher_plugin.c' and 'test.html'. The easiest way to test this is: ./autogen.sh --enable-plugin make cp plugin/virt-viewer-plugin.so ~/.mozilla/plugins/ firefox `pwd`/plugin/test.html Rich. -- Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://et.redhat.com/~rjones/virt-df/
# HG changeset patch # User "Richard W.M. Jones <rjones@xxxxxxxxxx>" # Date 1218201453 -3600 # Node ID a378a0a13abae0ea86d07d2dacc1384f0ac712a8 # Parent dc12fc3a78696ea36adb442ed0aa3304cbf06596 "Launch virt-viewer" (new) browser plugin. - Based on npshell from xulrunner 1.9.0. - Includes test page. diff -r dc12fc3a7869 -r a378a0a13aba plugin/Makefile.am --- a/plugin/Makefile.am Fri Aug 08 11:29:51 2008 +0100 +++ b/plugin/Makefile.am Fri Aug 08 14:17:33 2008 +0100 @@ -1,4 +1,29 @@ if ENABLE_PLUGIN +plugindir = $(libdir)/mozilla/plugins +plugin_LTLIBRARIES = virt-viewer-plugin.la + +virt_viewer_plugin_la_SOURCES = \ + npshell.c npunix.c launcher_plugin.c launcher_plugin.h +virt_viewer_plugin_la_LIBADD = @FIREFOX_PLUGIN_LIBS@ +virt_viewer_plugin_la_LDFLAGS = -module -avoid-version +virt_viewer_plugin_la_CFLAGS = \ + -DENABLE_DEBUG=1 -DDEBUG=1 \ + @FIREFOX_PLUGIN_CFLAGS@ \ + @WARN_CFLAGS@ + +all-local: virt-viewer-plugin.so + +virt-viewer-plugin.so: virt-viewer-plugin.la + cp .libs/virt-viewer-plugin.so $@ + +# Only leave the .so file in the plugins directory. +install-data-hook: + rm -f $(plugindir)/virt-viewer-plugin.a \ + $(plugindir)/virt-viewer-plugin.la + +CLEANFILES = virt-viewer-plugin.so + +EXTRA_DIST = test.html endif diff -r dc12fc3a7869 -r a378a0a13aba plugin/launcher_plugin.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/launcher_plugin.c Fri Aug 08 14:17:33 2008 +0100 @@ -0,0 +1,160 @@ +/* + * Virt Viewer New Browser Plugin + * + * Copyright (C) 2008 Red Hat. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Richard W.M. Jones <rjones@xxxxxxxxxx> + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/wait.h> + +#include <npapi.h> +#include <plstr.h> + +#include "launcher_plugin.h" + +static void startVirtViewerAndExit (PluginInstance *, const char *uri, const char *name, int direct, int waitvnc); + +NPError +launcherRun (PluginInstance *self, + int16 argc, char* argn[], char* argv[]) +{ + int i; + const char *uri = NULL; + const char *name = NULL; + int direct = 0; + int waitvnc = 0; + int pid; + + /* Protect against being called multiple times. */ + if (!self->launched) { + self->launched = TRUE; + + /* Parse the parameters given in <embed ...>. */ + i = argc; + while (i > 0) { + i --; + if (argv[i] != NULL) { + if (!PL_strcasecmp (argn[i], "URI")) + uri = argv[i]; + else if (!PL_strcasecmp (argn[i], "NAME")) + name = argv[i]; + else if (!PL_strcasecmp (argn[i], "DIRECT")) + direct = strcmp (argv[i], "1") == 0; + else if (!PL_strcasecmp (argn[i], "WAITVNC")) + waitvnc = strcmp (argv[i], "1") == 0; + } + } + + /* Create child process. */ + pid = fork (); + if (pid < 0) { + perror ("fork"); + return NPERR_GENERIC_ERROR; + } + if (pid == 0) /* Child. */ + startVirtViewerAndExit (self, uri, name, direct, waitvnc); + else /* Parent. */ + waitpid (pid, NULL, 0); + } + + return NPERR_NO_ERROR; +} + +static void +startVirtViewerAndExit (PluginInstance *self ATTRIBUTE_UNUSED, + const char *uri, const char *name, + int direct, int waitvnc) +{ + int pid; + int i, maxfd, len; + const char **argv; + + /* Fork again to detach ourselves completely from the browser + * process (probably not necessary on Windoze). + */ + pid = fork (); + if (pid < 0) { + perror ("fork"); + return; + } + if (pid > 0) /* Parent. */ + _exit (0); + + /* Child ... Close any open file descriptors, leaving 0, 1 & 2 + * connected so that we'll still see any error messages. + */ + maxfd = sysconf (_SC_OPEN_MAX) - 1; + for (i = 3; i <= maxfd; ++i) + close (i); + + /* Build the argument array. */ + len = 1 + /* "virt-viewer" (argv 0) */ + (uri ? 2 : 0) + /* "-c" uri */ + (direct ? 1 : 0) + /* "-d" */ + (waitvnc ? 1 : 0) + /* "-w" */ + 1 + /* name */ + 1; /* NULL */ + argv = NPN_MemAlloc (sizeof (char *) * len); + if (!argv) { + perror ("malloc"); + goto cleanup; + } + + i = 0; + argv[i++] = "virt-viewer"; + if (uri) { + argv[i++] = "-c"; + argv[i++] = uri; + } + if (direct) + argv[i++] = "-d"; + if (waitvnc) + argv[i++] = "-w"; + argv[i++] = name; + + argv[i++] = NULL; + + if (i != len) { + fprintf (stderr, + "virt-viewer launcher_plugin: internal error: i=%d != len=%d\n", + i, len); + goto cleanup; + } + + execvp ("virt-viewer", argv); + perror ("execvp"); + + cleanup: + _exit (1); +} + +void +launcherDestroy (PluginInstance *self) +{ + /* Nothing to free. Just stop launcherRun from doing anything if + * the browser tries to (incorrectly) call it a second time. Not + * that well-written browsers would do anything like that. Oh no. + */ + self->launched = TRUE; +} diff -r dc12fc3a7869 -r a378a0a13aba plugin/launcher_plugin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/launcher_plugin.h Fri Aug 08 14:17:33 2008 +0100 @@ -0,0 +1,88 @@ +/* + * Virt Viewer New Browser Plugin + * + * Copyright (C) 2008 Red Hat. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Richard W.M. Jones <rjones@xxxxxxxxxx> + */ + +#include <config.h> + +#ifndef LAUNCHER_PLUGIN_H +#define LAUNCHER_PLUGIN_H + +#include <stdarg.h> +#include <npapi.h> + +#define PLUGIN_NAME "Virt-viewer new browser plugin" +#define MIME_TYPES_HANDLED "application/x-virt-viewer:virt-viewer:Virt viewer" +#define PLUGIN_DESCRIPTION "Browser plugin which launches 'virt-viewer' program to display virtual machine consoles." + +struct _PluginInstance { + /* These standard fields are filled in by npshell, based on + * standard parameters given to the plugin (eg. in <embed ...>). + */ + uint16 mode; +#ifdef MOZ_X11 + NPWindow *window; + int32 x, y; + uint32 width, height; +#endif + + NPMIMEType type; + NPP instance; + char *pluginsPageUrl; + char *pluginsFileUrl; + NPBool pluginsHidden; + + /* Custom fields for this plugin. */ + NPBool launched; /* Did we launch the external program yet? */ +}; + +typedef struct _PluginInstance PluginInstance; + +/* These functions in launcher_plugin.c are called from npshell + * when significant events happen in the lifecycle of the plugin + * instance. + */ +extern NPError launcherRun (PluginInstance *, + int16 argc, char* argn[], char* argv[]); +extern void launcherDestroy (PluginInstance *); + +#ifdef __GNUC__ +#define ATTRIBUTE_UNUSED __attribute__((__unused__)) +#else +#define ATTRIBUTE_UNUSED +#endif + +#ifdef ENABLE_DEBUG +static void +debug (const char *msg, ...) +{ + va_list args; + + va_start (args, msg); + vfprintf (stderr, msg, args); + va_end (args); + fprintf (stderr, "\n"); + fflush (stderr); +} +#else +static void debug (const char *msg ATTRIBUTE_UNUSED, ...) { } +#endif + +#endif /* LAUNCHER_PLUGIN_H */ diff -r dc12fc3a7869 -r a378a0a13aba plugin/npshell.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/npshell.c Fri Aug 08 14:17:33 2008 +0100 @@ -0,0 +1,424 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Stephen Mak <smak@xxxxxxx> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * npshell.c + * + * Netscape Client Plugin API + * - Function that need to be implemented by plugin developers + * + * This file defines a "shell" plugin that plugin developers can use + * as the basis for a real plugin. This shell just provides empty + * implementations of all functions that the plugin can implement + * that will be called by Netscape (the NPP_xxx methods defined in + * npapi.h). + * + * dp Suresh <dp@xxxxxxxxxxxx> + * updated 5/1998 <pollmann@xxxxxxxxxxxx> + * updated 9/2000 <smak@xxxxxxx> + * + */ + +#define _BSD_SOURCE 1 /* for strdup */ + +#include <stdio.h> +#include <string.h> + +#include <npapi.h> +#include <plstr.h> + +#include "launcher_plugin.h" + +/*********************************************************************** + * + * Implementations of plugin API functions + * + ***********************************************************************/ + +char * +NPP_GetMIMEDescription(void) +{ + return((char *) MIME_TYPES_HANDLED); +} + +NPError +NPP_GetValue(NPP instance ATTRIBUTE_UNUSED, NPPVariable variable, void *value) +{ + NPError err = NPERR_NO_ERROR; + + switch (variable) { + case NPPVpluginNameString: + *((char **)value) = (char *) PLUGIN_NAME; + break; + case NPPVpluginDescriptionString: + *((char **)value) = (char *) PLUGIN_DESCRIPTION; + break; + default: + err = NPERR_GENERIC_ERROR; + } + return err; +} + +NPError +NPP_Initialize(void) +{ + return NPERR_NO_ERROR; +} + +#ifdef OJI +jref +NPP_GetJavaClass() +{ + return NULL; +} +#endif + +void +NPP_Shutdown(void) +{ +} + +static NPMIMEType +dupMimeType(NPMIMEType type) +{ + NPMIMEType mimetype = NPN_MemAlloc(strlen(type)+1); + if (mimetype) + strcpy(mimetype, type); + return(mimetype); +} + +NPError +NPP_New(NPMIMEType pluginType, + NPP instance, + uint16 mode, + int16 argc, + char* argn[], + char* argv[], + NPSavedData* saved ATTRIBUTE_UNUSED) +{ + PluginInstance* This; + int i; + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + instance->pdata = NPN_MemAlloc(sizeof(PluginInstance)); + + This = (PluginInstance*) instance->pdata; + + if (This == NULL) + { + return NPERR_OUT_OF_MEMORY_ERROR; + } + + memset(This, 0, sizeof(PluginInstance)); + + /* mode is NP_EMBED, NP_FULL, or NP_BACKGROUND (see npapi.h) */ + This->mode = mode; + This->type = dupMimeType(pluginType); + This->instance = instance; + This->pluginsPageUrl = NULL; + + /* Parse argument list passed to plugin instance */ + /* We are interested in these arguments + * PLUGINSPAGE = <url> + */ + i = argc; + while (i > 0) + { + i --; + if (argv[i] != NULL) + { + if (!PL_strcasecmp(argn[i], "PLUGINSPAGE")) + This->pluginsPageUrl = strdup(argv[i]); + else if (!PL_strcasecmp(argn[i], "PLUGINURL")) + This->pluginsFileUrl = strdup(argv[i]); + else if (!PL_strcasecmp(argn[i], "CODEBASE")) + This->pluginsPageUrl = strdup(argv[i]); + else if (!PL_strcasecmp(argn[i], "CLASSID")) + This->pluginsFileUrl = strdup(argv[i]); + else if (!PL_strcasecmp(argn[i], "HIDDEN")) + This->pluginsHidden = (!PL_strcasecmp(argv[i], + "TRUE")); + } + } + + return launcherRun (This, argc, argn, argv); +} + +NPError +NPP_Destroy(NPP instance, NPSavedData** save ATTRIBUTE_UNUSED) +{ + + PluginInstance* This; + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + This = (PluginInstance*) instance->pdata; + + if (This != NULL) { + launcherDestroy (This); + if (This->type) + NPN_MemFree(This->type); + if (This->pluginsPageUrl) + NPN_MemFree(This->pluginsPageUrl); + if (This->pluginsFileUrl) + NPN_MemFree(This->pluginsFileUrl); + NPN_MemFree(instance->pdata); + instance->pdata = NULL; + } + + return NPERR_NO_ERROR; +} + + +NPError +NPP_SetWindow(NPP instance, NPWindow* window) +{ + PluginInstance* This; + NPSetWindowCallbackStruct *ws_info; + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + This = (PluginInstance*) instance->pdata; + + if (This == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + ws_info = (NPSetWindowCallbackStruct *)window->ws_info; + +#ifdef MOZ_X11 + if (This->window == (Window) window->window) { + /* The page with the plugin is being resized. + Save any UI information because the next time + around expect a SetWindow with a new window + id. + */ +#ifdef DEBUG + fprintf(stderr, "Nullplugin: plugin received window resize.\n"); + fprintf(stderr, "Window=(%i)\n", (int)window); + fprintf(stderr, "W=(%i) H=(%i)\n", + (int)window->width, (int)window->height); +#endif + return NPERR_NO_ERROR; + } else { + + This->window = (Window) window->window; + This->x = window->x; + This->y = window->y; + This->width = window->width; + This->height = window->height; + This->display = ws_info->display; + This->visual = ws_info->visual; + This->depth = ws_info->depth; + This->colormap = ws_info->colormap; + makePixmap(This); + makeWidget(This); + } +#endif /* #ifdef MOZ_X11 */ + + return NPERR_NO_ERROR; +} + + +NPError +NPP_NewStream(NPP instance, + NPMIMEType type ATTRIBUTE_UNUSED, + NPStream *stream ATTRIBUTE_UNUSED, + NPBool seekable ATTRIBUTE_UNUSED, + uint16 *stype ATTRIBUTE_UNUSED) +{ + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + return NPERR_NO_ERROR; +} + + +int32 +NPP_WriteReady(NPP instance, NPStream *stream) +{ + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + /* We don't want any data, kill the stream */ + NPN_DestroyStream(instance, stream, NPRES_DONE); + + /* Number of bytes ready to accept in NPP_Write() */ + return -1L; /* don't accept any bytes in NPP_Write() */ +} + + +int32 +NPP_Write(NPP instance, NPStream *stream, + int32 offset ATTRIBUTE_UNUSED, + int32 len ATTRIBUTE_UNUSED, + void *buffer ATTRIBUTE_UNUSED) +{ + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + /* We don't want any data, kill the stream */ + NPN_DestroyStream(instance, stream, NPRES_DONE); + + return -1L; /* don't accept any bytes in NPP_Write() */ +} + + +NPError +NPP_DestroyStream(NPP instance, + NPStream *stream ATTRIBUTE_UNUSED, + NPError reason ATTRIBUTE_UNUSED) +{ + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + /***** Insert NPP_DestroyStream code here *****\ + PluginInstance* This; + This = (PluginInstance*) instance->pdata; + \**********************************************/ + + return NPERR_NO_ERROR; +} + + +void +NPP_StreamAsFile(NPP instance ATTRIBUTE_UNUSED, + NPStream *stream ATTRIBUTE_UNUSED, + const char* fname ATTRIBUTE_UNUSED) +{ + /***** Insert NPP_StreamAsFile code here *****\ + PluginInstance* This; + if (instance != NULL) + This = (PluginInstance*) instance->pdata; + \*********************************************/ +} + + +void +NPP_URLNotify(NPP instance ATTRIBUTE_UNUSED, + const char* url ATTRIBUTE_UNUSED, + NPReason reason ATTRIBUTE_UNUSED, + void* notifyData ATTRIBUTE_UNUSED) +{ + /***** Insert NPP_URLNotify code here *****\ + PluginInstance* This; + if (instance != NULL) + This = (PluginInstance*) instance->pdata; + \*********************************************/ +} + + +void +NPP_Print(NPP instance, NPPrint* printInfo) +{ + if(printInfo == NULL) + return; + + if (instance != NULL) { + /***** Insert NPP_Print code here *****\ + PluginInstance* This = (PluginInstance*) instance->pdata; + \**************************************/ + + if (printInfo->mode == NP_FULL) { + /* + * PLUGIN DEVELOPERS: + * If your plugin would like to take over + * printing completely when it is in full-screen mode, + * set printInfo->pluginPrinted to TRUE and print your + * plugin as you see fit. If your plugin wants Netscape + * to handle printing in this case, set + * printInfo->pluginPrinted to FALSE (the default) and + * do nothing. If you do want to handle printing + * yourself, printOne is true if the print button + * (as opposed to the print menu) was clicked. + * On the Macintosh, platformPrint is a THPrint; on + * Windows, platformPrint is a structure + * (defined in npapi.h) containing the printer name, port, + * etc. + */ + + /***** Insert NPP_Print code here *****\ + void* platformPrint = + printInfo->print.fullPrint.platformPrint; + NPBool printOne = + printInfo->print.fullPrint.printOne; + \**************************************/ + + /* Do the default*/ + printInfo->print.fullPrint.pluginPrinted = FALSE; + } + else { /* If not fullscreen, we must be embedded */ + /* + * PLUGIN DEVELOPERS: + * If your plugin is embedded, or is full-screen + * but you returned false in pluginPrinted above, NPP_Print + * will be called with mode == NP_EMBED. The NPWindow + * in the printInfo gives the location and dimensions of + * the embedded plugin on the printed page. On the + * Macintosh, platformPrint is the printer port; on + * Windows, platformPrint is the handle to the printing + * device context. + */ + + /***** Insert NPP_Print code here *****\ + NPWindow* printWindow = + &(printInfo->print.embedPrint.window); + void* platformPrint = + printInfo->print.embedPrint.platformPrint; + \**************************************/ + } + } +} + +/* + * vim: set tabstop=4: + * vim: set shiftwidth=4: + * vim: set expandtab: + */ +/* + * Local variables: + * indent-tabs-mode: nil + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff -r dc12fc3a7869 -r a378a0a13aba plugin/npunix.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/npunix.c Fri Aug 08 14:17:33 2008 +0100 @@ -0,0 +1,696 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Stephen Mak <smak@xxxxxxx> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * npunix.c + * + * Netscape Client Plugin API + * - Wrapper function to interface with the Netscape Navigator + * + * dp Suresh <dp@xxxxxxxxxxxx> + * + *---------------------------------------------------------------------- + * PLUGIN DEVELOPERS: + * YOU WILL NOT NEED TO EDIT THIS FILE. + *---------------------------------------------------------------------- + */ + +#define XP_UNIX 1 + +#include <stdio.h> +#include "npapi.h" +#include "npupp.h" + +/* + * Define PLUGIN_TRACE to have the wrapper functions print + * messages to stderr whenever they are called. + */ + +#ifdef PLUGIN_TRACE +#include <stdio.h> +#define PLUGINDEBUGSTR(msg) fprintf(stderr, "%s\n", msg) +#else +#define PLUGINDEBUGSTR(msg) +#endif + + +/*********************************************************************** + * + * Globals + * + ***********************************************************************/ + +static NPNetscapeFuncs gNetscapeFuncs; /* Netscape Function table */ + + +/*********************************************************************** + * + * Wrapper functions : plugin calling Netscape Navigator + * + * These functions let the plugin developer just call the APIs + * as documented and defined in npapi.h, without needing to know + * about the function table and call macros in npupp.h. + * + ***********************************************************************/ + +void +NPN_Version(int* plugin_major, int* plugin_minor, + int* netscape_major, int* netscape_minor) +{ + *plugin_major = NP_VERSION_MAJOR; + *plugin_minor = NP_VERSION_MINOR; + + /* Major version is in high byte */ + *netscape_major = gNetscapeFuncs.version >> 8; + /* Minor version is in low byte */ + *netscape_minor = gNetscapeFuncs.version & 0xFF; +} + +NPError +NPN_GetValue(NPP instance, NPNVariable variable, void *r_value) +{ + return CallNPN_GetValueProc(gNetscapeFuncs.getvalue, + instance, variable, r_value); +} + +NPError +NPN_SetValue(NPP instance, NPPVariable variable, void *value) +{ + return CallNPN_SetValueProc(gNetscapeFuncs.setvalue, + instance, variable, value); +} + +NPError +NPN_GetURL(NPP instance, const char* url, const char* window) +{ + return CallNPN_GetURLProc(gNetscapeFuncs.geturl, instance, url, window); +} + +NPError +NPN_GetURLNotify(NPP instance, const char* url, const char* window, void* notifyData) +{ + return CallNPN_GetURLNotifyProc(gNetscapeFuncs.geturlnotify, instance, url, window, notifyData); +} + +NPError +NPN_PostURL(NPP instance, const char* url, const char* window, + uint32 len, const char* buf, NPBool file) +{ + return CallNPN_PostURLProc(gNetscapeFuncs.posturl, instance, + url, window, len, buf, file); +} + +NPError +NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len, + const char* buf, NPBool file, void* notifyData) +{ + return CallNPN_PostURLNotifyProc(gNetscapeFuncs.posturlnotify, + instance, url, window, len, buf, file, notifyData); +} + +NPError +NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) +{ + return CallNPN_RequestReadProc(gNetscapeFuncs.requestread, + stream, rangeList); +} + +NPError +NPN_NewStream(NPP instance, NPMIMEType type, const char *window, + NPStream** stream_ptr) +{ + return CallNPN_NewStreamProc(gNetscapeFuncs.newstream, instance, + type, window, stream_ptr); +} + +int32 +NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer) +{ + return CallNPN_WriteProc(gNetscapeFuncs.write, instance, + stream, len, buffer); +} + +NPError +NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason) +{ + return CallNPN_DestroyStreamProc(gNetscapeFuncs.destroystream, + instance, stream, reason); +} + +void +NPN_Status(NPP instance, const char* message) +{ + CallNPN_StatusProc(gNetscapeFuncs.status, instance, message); +} + +const char* +NPN_UserAgent(NPP instance) +{ + return CallNPN_UserAgentProc(gNetscapeFuncs.uagent, instance); +} + +void* +NPN_MemAlloc(uint32 size) +{ + return CallNPN_MemAllocProc(gNetscapeFuncs.memalloc, size); +} + +void NPN_MemFree(void* ptr) +{ + CallNPN_MemFreeProc(gNetscapeFuncs.memfree, ptr); +} + +uint32 NPN_MemFlush(uint32 size) +{ + return CallNPN_MemFlushProc(gNetscapeFuncs.memflush, size); +} + +void NPN_ReloadPlugins(NPBool reloadPages) +{ + CallNPN_ReloadPluginsProc(gNetscapeFuncs.reloadplugins, reloadPages); +} + +#ifdef OJI +JRIEnv* NPN_GetJavaEnv() +{ + return CallNPN_GetJavaEnvProc(gNetscapeFuncs.getJavaEnv); +} + +jref NPN_GetJavaPeer(NPP instance) +{ + return CallNPN_GetJavaPeerProc(gNetscapeFuncs.getJavaPeer, + instance); +} +#endif + +void +NPN_InvalidateRect(NPP instance, NPRect *invalidRect) +{ + CallNPN_InvalidateRectProc(gNetscapeFuncs.invalidaterect, instance, + invalidRect); +} + +void +NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion) +{ + CallNPN_InvalidateRegionProc(gNetscapeFuncs.invalidateregion, instance, + invalidRegion); +} + +void +NPN_ForceRedraw(NPP instance) +{ + CallNPN_ForceRedrawProc(gNetscapeFuncs.forceredraw, instance); +} + +void NPN_PushPopupsEnabledState(NPP instance, NPBool enabled) +{ + CallNPN_PushPopupsEnabledStateProc(gNetscapeFuncs.pushpopupsenabledstate, + instance, enabled); +} + +void NPN_PopPopupsEnabledState(NPP instance) +{ + CallNPN_PopPopupsEnabledStateProc(gNetscapeFuncs.poppopupsenabledstate, + instance); +} + +NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name) +{ + return CallNPN_GetStringIdentifierProc(gNetscapeFuncs.getstringidentifier, + name); +} + +void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, + NPIdentifier *identifiers) +{ + CallNPN_GetStringIdentifiersProc(gNetscapeFuncs.getstringidentifiers, + names, nameCount, identifiers); +} + +NPIdentifier NPN_GetIntIdentifier(int32_t intid) +{ + return CallNPN_GetIntIdentifierProc(gNetscapeFuncs.getintidentifier, intid); +} + +bool NPN_IdentifierIsString(NPIdentifier identifier) +{ + return CallNPN_IdentifierIsStringProc(gNetscapeFuncs.identifierisstring, + identifier); +} + +NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier) +{ + return CallNPN_UTF8FromIdentifierProc(gNetscapeFuncs.utf8fromidentifier, + identifier); +} + +int32_t NPN_IntFromIdentifier(NPIdentifier identifier) +{ + return CallNPN_IntFromIdentifierProc(gNetscapeFuncs.intfromidentifier, + identifier); +} + +NPObject *NPN_CreateObject(NPP npp, NPClass *aClass) +{ + return CallNPN_CreateObjectProc(gNetscapeFuncs.createobject, npp, aClass); +} + +NPObject *NPN_RetainObject(NPObject *obj) +{ + return CallNPN_RetainObjectProc(gNetscapeFuncs.retainobject, obj); +} + +void NPN_ReleaseObject(NPObject *obj) +{ + CallNPN_ReleaseObjectProc(gNetscapeFuncs.releaseobject, obj); +} + +bool NPN_Invoke(NPP npp, NPObject* obj, NPIdentifier methodName, + const NPVariant *args, uint32_t argCount, NPVariant *result) +{ + return CallNPN_InvokeProc(gNetscapeFuncs.invoke, npp, obj, methodName, + args, argCount, result); +} + +bool NPN_InvokeDefault(NPP npp, NPObject* obj, const NPVariant *args, + uint32_t argCount, NPVariant *result) +{ + return CallNPN_InvokeDefaultProc(gNetscapeFuncs.invokeDefault, npp, obj, + args, argCount, result); +} + +bool NPN_Evaluate(NPP npp, NPObject* obj, NPString *script, + NPVariant *result) +{ + return CallNPN_EvaluateProc(gNetscapeFuncs.evaluate, npp, obj, script, result); +} + +bool NPN_GetProperty(NPP npp, NPObject* obj, NPIdentifier propertyName, + NPVariant *result) +{ + return CallNPN_GetPropertyProc(gNetscapeFuncs.getproperty, npp, obj, + propertyName, result); +} + +bool NPN_SetProperty(NPP npp, NPObject* obj, NPIdentifier propertyName, + const NPVariant *value) +{ + return CallNPN_SetPropertyProc(gNetscapeFuncs.setproperty, npp, obj, + propertyName, value); +} + +bool NPN_RemoveProperty(NPP npp, NPObject* obj, NPIdentifier propertyName) +{ + return CallNPN_RemovePropertyProc(gNetscapeFuncs.removeproperty, npp, obj, + propertyName); +} + +bool NPN_HasProperty(NPP npp, NPObject* obj, NPIdentifier propertyName) +{ + return CallNPN_HasPropertyProc(gNetscapeFuncs.hasproperty, npp, obj, + propertyName); +} + +bool NPN_HasMethod(NPP npp, NPObject* obj, NPIdentifier methodName) +{ + return CallNPN_HasMethodProc(gNetscapeFuncs.hasmethod, npp, obj, methodName); +} + +void NPN_ReleaseVariantValue(NPVariant *variant) +{ + CallNPN_ReleaseVariantValueProc(gNetscapeFuncs.releasevariantvalue, variant); +} + +void NPN_SetException(NPObject* obj, const NPUTF8 *message) +{ + CallNPN_SetExceptionProc(gNetscapeFuncs.setexception, obj, message); +} + + +/*********************************************************************** + * + * Wrapper functions : Netscape Navigator -> plugin + * + * These functions let the plugin developer just create the APIs + * as documented and defined in npapi.h, without needing to + * install those functions in the function table or worry about + * setting up globals for 68K plugins. + * + ***********************************************************************/ + +NPError +Private_New(NPMIMEType pluginType, NPP instance, uint16 mode, + int16 argc, char* argn[], char* argv[], NPSavedData* saved) +{ + NPError ret; + PLUGINDEBUGSTR("New"); + ret = NPP_New(pluginType, instance, mode, argc, argn, argv, saved); + return ret; +} + +NPError +Private_Destroy(NPP instance, NPSavedData** save) +{ + PLUGINDEBUGSTR("Destroy"); + return NPP_Destroy(instance, save); +} + +NPError +Private_SetWindow(NPP instance, NPWindow* window) +{ + NPError err; + PLUGINDEBUGSTR("SetWindow"); + err = NPP_SetWindow(instance, window); + return err; +} + +NPError +Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream, + NPBool seekable, uint16* stype) +{ + NPError err; + PLUGINDEBUGSTR("NewStream"); + err = NPP_NewStream(instance, type, stream, seekable, stype); + return err; +} + +int32 +Private_WriteReady(NPP instance, NPStream* stream) +{ + unsigned int result; + PLUGINDEBUGSTR("WriteReady"); + result = NPP_WriteReady(instance, stream); + return result; +} + +int32 +Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len, + void* buffer) +{ + unsigned int result; + PLUGINDEBUGSTR("Write"); + result = NPP_Write(instance, stream, offset, len, buffer); + return result; +} + +void +Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname) +{ + PLUGINDEBUGSTR("StreamAsFile"); + NPP_StreamAsFile(instance, stream, fname); +} + + +NPError +Private_DestroyStream(NPP instance, NPStream* stream, NPError reason) +{ + NPError err; + PLUGINDEBUGSTR("DestroyStream"); + err = NPP_DestroyStream(instance, stream, reason); + return err; +} + +void +Private_URLNotify(NPP instance, const char* url, + NPReason reason, void* notifyData) + +{ + PLUGINDEBUGSTR("URLNotify"); + NPP_URLNotify(instance, url, reason, notifyData); +} + + + +void +Private_Print(NPP instance, NPPrint* platformPrint) +{ + PLUGINDEBUGSTR("Print"); + NPP_Print(instance, platformPrint); +} + +#ifdef OJI +JRIGlobalRef +Private_GetJavaClass(void) +{ + jref clazz = NPP_GetJavaClass(); + if (clazz) { + JRIEnv* env = NPN_GetJavaEnv(); + return JRI_NewGlobalRef(env, clazz); + } + return NULL; +} +#endif + +/*********************************************************************** + * + * These functions are located automagically by netscape. + * + ***********************************************************************/ + +/* + * NP_GetMIMEDescription + * - Netscape needs to know about this symbol + * - Netscape uses the return value to identify when an object instance + * of this plugin should be created. + */ +char * +NP_GetMIMEDescription(void) +{ + return NPP_GetMIMEDescription(); +} + +/* + * NP_GetValue [optional] + * - Netscape needs to know about this symbol. + * - Interfaces with plugin to get values for predefined variables + * that the navigator needs. + */ +NPError +NP_GetValue(void* future, NPPVariable variable, void *value) +{ + return NPP_GetValue(future, variable, value); +} + +/* + * NP_Initialize + * - Netscape needs to know about this symbol. + * - It calls this function after looking up its symbol before it + * is about to create the first ever object of this kind. + * + * PARAMETERS + * nsTable - The netscape function table. If developers just use these + * wrappers, they don't need to worry about all these function + * tables. + * RETURN + * pluginFuncs + * - This functions needs to fill the plugin function table + * pluginFuncs and return it. Netscape Navigator plugin + * library will use this function table to call the plugin. + * + */ +NPError +NP_Initialize(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs) +{ + NPError err = NPERR_NO_ERROR; + + PLUGINDEBUGSTR("NP_Initialize"); + + /* validate input parameters */ + + if ((nsTable == NULL) || (pluginFuncs == NULL)) + err = NPERR_INVALID_FUNCTABLE_ERROR; + + /* + * Check the major version passed in Netscape's function table. + * We won't load if the major version is newer than what we expect. + * Also check that the function tables passed in are big enough for + * all the functions we need (they could be bigger, if Netscape added + * new APIs, but that's OK with us -- we'll just ignore them). + * + */ + + if (err == NPERR_NO_ERROR) { + if ((nsTable->version >> 8) > NP_VERSION_MAJOR) + err = NPERR_INCOMPATIBLE_VERSION_ERROR; + if (nsTable->size < ((char *)&nsTable->posturlnotify - (char *)nsTable)) + err = NPERR_INVALID_FUNCTABLE_ERROR; + if (pluginFuncs->size < sizeof(NPPluginFuncs)) + err = NPERR_INVALID_FUNCTABLE_ERROR; + } + + + if (err == NPERR_NO_ERROR) { + /* + * Copy all the fields of Netscape function table into our + * copy so we can call back into Netscape later. Note that + * we need to copy the fields one by one, rather than assigning + * the whole structure, because the Netscape function table + * could actually be bigger than what we expect. + */ + gNetscapeFuncs.version = nsTable->version; + gNetscapeFuncs.size = nsTable->size; + gNetscapeFuncs.posturl = nsTable->posturl; + gNetscapeFuncs.geturl = nsTable->geturl; + gNetscapeFuncs.geturlnotify = nsTable->geturlnotify; + gNetscapeFuncs.requestread = nsTable->requestread; + gNetscapeFuncs.newstream = nsTable->newstream; + gNetscapeFuncs.write = nsTable->write; + gNetscapeFuncs.destroystream = nsTable->destroystream; + gNetscapeFuncs.status = nsTable->status; + gNetscapeFuncs.uagent = nsTable->uagent; + gNetscapeFuncs.memalloc = nsTable->memalloc; + gNetscapeFuncs.memfree = nsTable->memfree; + gNetscapeFuncs.memflush = nsTable->memflush; + gNetscapeFuncs.reloadplugins = nsTable->reloadplugins; +#ifdef OJI + gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv; + gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer; +#endif + gNetscapeFuncs.getvalue = nsTable->getvalue; + gNetscapeFuncs.setvalue = nsTable->setvalue; + gNetscapeFuncs.posturlnotify = nsTable->posturlnotify; + + if (nsTable->size >= ((char *)&nsTable->setexception - (char *)nsTable)) + { + gNetscapeFuncs.invalidaterect = nsTable->invalidaterect; + gNetscapeFuncs.invalidateregion = nsTable->invalidateregion; + gNetscapeFuncs.forceredraw = nsTable->forceredraw; + gNetscapeFuncs.getstringidentifier = nsTable->getstringidentifier; + gNetscapeFuncs.getstringidentifiers = nsTable->getstringidentifiers; + gNetscapeFuncs.getintidentifier = nsTable->getintidentifier; + gNetscapeFuncs.identifierisstring = nsTable->identifierisstring; + gNetscapeFuncs.utf8fromidentifier = nsTable->utf8fromidentifier; + gNetscapeFuncs.intfromidentifier = nsTable->intfromidentifier; + gNetscapeFuncs.createobject = nsTable->createobject; + gNetscapeFuncs.retainobject = nsTable->retainobject; + gNetscapeFuncs.releaseobject = nsTable->releaseobject; + gNetscapeFuncs.invoke = nsTable->invoke; + gNetscapeFuncs.invokeDefault = nsTable->invokeDefault; + gNetscapeFuncs.evaluate = nsTable->evaluate; + gNetscapeFuncs.getproperty = nsTable->getproperty; + gNetscapeFuncs.setproperty = nsTable->setproperty; + gNetscapeFuncs.removeproperty = nsTable->removeproperty; + gNetscapeFuncs.hasproperty = nsTable->hasproperty; + gNetscapeFuncs.hasmethod = nsTable->hasmethod; + gNetscapeFuncs.releasevariantvalue = nsTable->releasevariantvalue; + gNetscapeFuncs.setexception = nsTable->setexception; + } + else + { + gNetscapeFuncs.invalidaterect = NULL; + gNetscapeFuncs.invalidateregion = NULL; + gNetscapeFuncs.forceredraw = NULL; + gNetscapeFuncs.getstringidentifier = NULL; + gNetscapeFuncs.getstringidentifiers = NULL; + gNetscapeFuncs.getintidentifier = NULL; + gNetscapeFuncs.identifierisstring = NULL; + gNetscapeFuncs.utf8fromidentifier = NULL; + gNetscapeFuncs.intfromidentifier = NULL; + gNetscapeFuncs.createobject = NULL; + gNetscapeFuncs.retainobject = NULL; + gNetscapeFuncs.releaseobject = NULL; + gNetscapeFuncs.invoke = NULL; + gNetscapeFuncs.invokeDefault = NULL; + gNetscapeFuncs.evaluate = NULL; + gNetscapeFuncs.getproperty = NULL; + gNetscapeFuncs.setproperty = NULL; + gNetscapeFuncs.removeproperty = NULL; + gNetscapeFuncs.hasproperty = NULL; + gNetscapeFuncs.releasevariantvalue = NULL; + gNetscapeFuncs.setexception = NULL; + } + if (nsTable->size >= + ((char *)&nsTable->poppopupsenabledstate - (char *)nsTable)) + { + gNetscapeFuncs.pushpopupsenabledstate = nsTable->pushpopupsenabledstate; + gNetscapeFuncs.poppopupsenabledstate = nsTable->poppopupsenabledstate; + } + else + { + gNetscapeFuncs.pushpopupsenabledstate = NULL; + gNetscapeFuncs.poppopupsenabledstate = NULL; + } + + /* + * 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. + */ + pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; + pluginFuncs->size = sizeof(NPPluginFuncs); + pluginFuncs->newp = NewNPP_NewProc(Private_New); + pluginFuncs->destroy = NewNPP_DestroyProc(Private_Destroy); + pluginFuncs->setwindow = NewNPP_SetWindowProc(Private_SetWindow); + pluginFuncs->newstream = NewNPP_NewStreamProc(Private_NewStream); + pluginFuncs->destroystream = NewNPP_DestroyStreamProc(Private_DestroyStream); + pluginFuncs->asfile = NewNPP_StreamAsFileProc(Private_StreamAsFile); + pluginFuncs->writeready = NewNPP_WriteReadyProc(Private_WriteReady); + pluginFuncs->write = NewNPP_WriteProc(Private_Write); + pluginFuncs->print = NewNPP_PrintProc(Private_Print); + pluginFuncs->urlnotify = NewNPP_URLNotifyProc(Private_URLNotify); + pluginFuncs->event = NULL; +#ifdef OJI + pluginFuncs->javaClass = Private_GetJavaClass(); +#endif + // This function is supposedly loaded magically, but that doesn't + // seem to be true. + pluginFuncs->getvalue = NewNPP_GetValueProc(NP_GetValue); + + err = NPP_Initialize(); + } + + return err; +} + +/* + * NP_Shutdown [optional] + * - Netscape needs to know about this symbol. + * - It calls this function after looking up its symbol after + * the last object of this kind has been destroyed. + * + */ +NPError +NP_Shutdown(void) +{ + PLUGINDEBUGSTR("NP_Shutdown"); + NPP_Shutdown(); + return NPERR_NO_ERROR; +} diff -r dc12fc3a7869 -r a378a0a13aba plugin/test.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/test.html Fri Aug 08 14:17:33 2008 +0100 @@ -0,0 +1,19 @@ +<html> +<body> + + <h1>Virt Viewer new plugin test</h1> + + <p>You will need to edit the source to + set <code>uri</code>, <code>name</code> etc.</p> + + <embed type="application/x-virt-viewer" + hidden="1" + uri="qemu:///system" + name="1"> + </embed> + <!-- also supported: direct="0|1" waitvnc="0|1" --> + + <p>End of page</p> + +</body> +</html>
_______________________________________________ et-mgmt-tools mailing list et-mgmt-tools@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/et-mgmt-tools