From bd0f3345a938b35ce6a12f6150373b0955b8dd12 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 10 Jul 2011 15:24:15 -0500 Subject: Add Qt3 development HEAD version --- extensions/extensions.pro | 6 + extensions/nsplugin/doc/index.doc | 112 ++ extensions/nsplugin/examples/grapher/graph.cgi | 7 + extensions/nsplugin/examples/grapher/graph.g1n | 8 + extensions/nsplugin/examples/grapher/grapher.cpp | 619 +++++++ extensions/nsplugin/examples/grapher/grapher.def | 9 + extensions/nsplugin/examples/grapher/grapher.doc | 64 + extensions/nsplugin/examples/grapher/grapher.pro | 12 + extensions/nsplugin/examples/grapher/grapher.rc | 36 + extensions/nsplugin/examples/trivial/trivial.cpp | 67 + extensions/nsplugin/examples/trivial/trivial.def | 9 + extensions/nsplugin/examples/trivial/trivial.doc | 22 + extensions/nsplugin/examples/trivial/trivial.pro | 12 + extensions/nsplugin/examples/trivial/trivial.rc | 36 + extensions/nsplugin/src/jri.h | 638 +++++++ extensions/nsplugin/src/jri_md.h | 500 ++++++ extensions/nsplugin/src/jritypes.h | 180 ++ extensions/nsplugin/src/npapi.h | 392 ++++ extensions/nsplugin/src/npunix.c | 407 +++++ extensions/nsplugin/src/npupp.h | 995 +++++++++++ extensions/nsplugin/src/npwin.cpp | 367 ++++ extensions/nsplugin/src/qnp.cpp | 2071 ++++++++++++++++++++++ extensions/nsplugin/src/qnp.h | 186 ++ extensions/nsplugin/src/qnp.pro | 14 + 24 files changed, 6769 insertions(+) create mode 100644 extensions/extensions.pro create mode 100644 extensions/nsplugin/doc/index.doc create mode 100755 extensions/nsplugin/examples/grapher/graph.cgi create mode 100644 extensions/nsplugin/examples/grapher/graph.g1n create mode 100644 extensions/nsplugin/examples/grapher/grapher.cpp create mode 100644 extensions/nsplugin/examples/grapher/grapher.def create mode 100644 extensions/nsplugin/examples/grapher/grapher.doc create mode 100644 extensions/nsplugin/examples/grapher/grapher.pro create mode 100644 extensions/nsplugin/examples/grapher/grapher.rc create mode 100644 extensions/nsplugin/examples/trivial/trivial.cpp create mode 100644 extensions/nsplugin/examples/trivial/trivial.def create mode 100644 extensions/nsplugin/examples/trivial/trivial.doc create mode 100644 extensions/nsplugin/examples/trivial/trivial.pro create mode 100644 extensions/nsplugin/examples/trivial/trivial.rc create mode 100644 extensions/nsplugin/src/jri.h create mode 100644 extensions/nsplugin/src/jri_md.h create mode 100644 extensions/nsplugin/src/jritypes.h create mode 100644 extensions/nsplugin/src/npapi.h create mode 100644 extensions/nsplugin/src/npunix.c create mode 100644 extensions/nsplugin/src/npupp.h create mode 100644 extensions/nsplugin/src/npwin.cpp create mode 100644 extensions/nsplugin/src/qnp.cpp create mode 100644 extensions/nsplugin/src/qnp.h create mode 100644 extensions/nsplugin/src/qnp.pro (limited to 'extensions') diff --git a/extensions/extensions.pro b/extensions/extensions.pro new file mode 100644 index 0000000..c779854 --- /dev/null +++ b/extensions/extensions.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs + +contains( QT_PRODUCT, qt-(enterprise|internal|eval) ) { + win32: SUBDIRS = activeqt + x11: SUBDIRS = motif +} diff --git a/extensions/nsplugin/doc/index.doc b/extensions/nsplugin/doc/index.doc new file mode 100644 index 0000000..8390349 --- /dev/null +++ b/extensions/nsplugin/doc/index.doc @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Index page +** +** Copyright (C) 1995-2008 Trolltech ASA. All rights reserved. +** +*****************************************************************************/ + +#if defined(QT_DEBUG) +#endif + +/*! \page netscape-plugin.html + +\title Qt Netscape Plugin Extension +\keyword Netscape + +The Qt Netscape Plugin software makes it easy to write browser plugins +that can be used on both Unix/Linux and MS-Windows, in Netscape, +Mozilla, and any other web browser supporting Netscape's LiveConnect +protocol. Modern versions of MSIE do not support this protocol. Use +the ActiveQt Framework to develop plugins for these browsers. + +\section1 Information + +The Netscape Plugin Extension consists of the follow classes: +\list +\i \l QNPlugin +\i \l QNPInstance +\i \l QNPWidget +\i \l QNPStream +\endlist + +\section1 How-to + +\list 1 + \i Download the + \link http://home.netscape.com/comprod/development_partners/plugin_api/index.html + Plugin SDK from Netscape \endlink, and copy the following files from there to + \c{$QTDIR/extensions/nsplugin/src} + \list + \i \c common/npwin.cpp + \i \c common/npunix.c + \i \c include/npapi.h + \i \c include/npupp.h + \i \c include/jri.h + \i \c include/jri_md.h + \i \c include/jritypes.h + \endlist + \i Build the Netscape Plugin extension library, found in the + \c{extensions/nsplugin/src} directory of your Qt distribution. + This produces a static library to be linked with your plugin code. + \i Read the \link qnplugin.html plugin class documentation \endlink, and + examine the \link nsplugin-examples.html example plugins \endlink. + \i Do most of your development as a stand-alone Qt application - debugging + Netscape Plugins is cumbersome. You may want to use \c{signal(2)} + in your plugin to enable core-dumps if your browser disables them. + \i Note the platform-specific build steps below. + \i Read about the raw plugin interface + \link http://developer.netscape.com/docs/manuals/communicator/plugin/index.htm + in Netscape's handbook. \endlink + \i If files viewed by a plugin are provided by an HTTP server + (using a \c{http://...} URL) then + the server must be configured to send the correct MIME type + for the file, e.g. by editing Apache's \c{mime.types} file. + If the files are viewed via a \c{file://...} + URL, then the browser will use the filename extension to decide + the file type (and hence the plugin to load) - the user may need + to set the filename extension in the Helpers or Applications + section of their browser preferences. +\endlist + + +\section2 Building under X11 + +\list + \i The Makefiles in the examples are appropriate for UNIX/X11. + \i The user must install the resulting Shared Object in the Plugins + directory of the browser. +\endlist + +\section2 Building under Windows + +\list + \i For Netscape plugins to work, Qt needs to be in the system DLL + path or be compiled into the plugin as a static library. + \i Plugins must be named \c{np}\e{name}\c{.dll}, + or the browser will ignore them. + \i The link step must include: + \list + \i \c{/def:}\e{name}\c{.def} + \i \c{/dll} + \i a compiled resource file defining the + file/MIME types accepted by the plugin. + \endlist + \i The user must install the resulting DLL in the Plugins directory + of the browser. +\endlist + +\section1 Known Bugs and Limitations + +The Qt-based LiveConnect Plugin binding code has a number of bugs and +limitations, but is sufficiently stable for many production +applications. + +\list + \i Keyboard input only works in secondary windows (e.g. dialogs created by the plugin). + \i You should not expect modality between the plugin and the browser to work. + \i Netscape 4.78 on Unix/X11 tends to terminate with a bus error. + \i Opaque resize behaviour is erratic due to browser behavior. +\endlist + +*/ diff --git a/extensions/nsplugin/examples/grapher/graph.cgi b/extensions/nsplugin/examples/grapher/graph.cgi new file mode 100755 index 0000000..91445c8 --- /dev/null +++ b/extensions/nsplugin/examples/grapher/graph.cgi @@ -0,0 +1,7 @@ +#!/bin/sh + +echo "Content-type: application/x-graphable" +echo + +cat graph.g1n +# ./slowcat < graph.g1n diff --git a/extensions/nsplugin/examples/grapher/graph.g1n b/extensions/nsplugin/examples/grapher/graph.g1n new file mode 100644 index 0000000..d366327 --- /dev/null +++ b/extensions/nsplugin/examples/grapher/graph.g1n @@ -0,0 +1,8 @@ +num label +10 A +24 B +12 C +7 D +34 E +15 F +19 G diff --git a/extensions/nsplugin/examples/grapher/grapher.cpp b/extensions/nsplugin/examples/grapher/grapher.cpp new file mode 100644 index 0000000..84633e4 --- /dev/null +++ b/extensions/nsplugin/examples/grapher/grapher.cpp @@ -0,0 +1,619 @@ +// Include Qt Netscape Plugin classes. +#include "qnp.h" + +// Include other Qt classes. +#include +#include +#include +#include +#include +#include +#include +#include + +// Include some C library functions. +#include +#include + +#ifndef M_PI // Some math.h don't include this. +#define M_PI 3.14159265358979323846264338327950288 +#endif + + + +// +// GraphModel is a simple abstract class that describes +// a table of numeric and text data. +// + +class GraphModel { +public: + enum ColType { Numeric, Label }; + + union Datum { + double dbl; + QString* str; + }; + + virtual QPtrList& graphData()=0; + virtual ColType colType(int col) const=0; + virtual int nCols() const=0; +}; + + +// +// Graph is a widget subclass that displays a GraphModel. +// Since the widget is a QNPWidget, it can be used as a plugin window, +// returned by Grapher::newWindow() below. +// + +class Graph : public QNPWidget { + Q_OBJECT +public: + // Constructs a Graph to display a GraphModel + // + Graph(GraphModel&); + ~Graph(); + + // Two styles are available - Pie and Bar graph + // + enum Style { Pie, Bar }; + static const char* styleName[]; + void setStyle(Style); + void setStyle(const char*); + + // Timer event processing rotates the pie graph + // + void timerEvent(QTimerEvent*); + + // These functions are provided by QNPWidget - we override + // them to hide and show the plugin menubar. + // + void enterInstance(); + void leaveInstance(); + + // Paint the graph... + // + void paintEvent(QPaintEvent*); + // + // ... as either a "Loading" message, a Bar graph, a Pie graph, + // or an error message. + // + void paintWait(QPaintEvent*); + void paintBar(QPaintEvent*); + void paintPie(QPaintEvent*); + void paintError(const char*); + +signals: + // Signals emitted when the Help menus are selected. + void aboutPlugin(); + void aboutData(); + +private: + GraphModel& model; + QMenuBar *menubar; + Style style; + QPopupMenu* stylemenu; + int pieRotationTimer; + int pieRotation; + QPixmap pm; + +private slots: + void setStyleFromMenu(int id); +}; + + +Graph::Graph( GraphModel& mdl ) : + model(mdl), + style(Bar), + pieRotationTimer(0), + pieRotation(0) +{ + // Create a menubar for the widget + // + menubar = new QMenuBar( this ); + stylemenu = new QPopupMenu; + stylemenu->setCheckable(TRUE); + for ( Style s = Pie; styleName[s]; s = Style(s+1)) { + stylemenu->insertItem(styleName[s], s+100); + } + connect(stylemenu, SIGNAL(activated(int)), + this, SLOT(setStyleFromMenu(int))); + setStyle(Pie); + + menubar->insertItem("Style", stylemenu); + menubar->insertSeparator(); + + QPopupMenu* help = new QPopupMenu; + help->insertItem( "About plugin...", this, SIGNAL(aboutPlugin()) ); + help->insertItem( "About data...", this, SIGNAL(aboutData()) ); + menubar->insertItem("Help", help); + menubar->hide(); +} + +Graph::~Graph() +{ +} + +void Graph::setStyle(Style s) +{ + if (style != s) { + if (pieRotationTimer) + killTimer(pieRotationTimer); + stylemenu->setItemChecked(100+style, FALSE); + style = s; + if ( style == Pie ) + pieRotationTimer = startTimer( 80 ); + else + pieRotationTimer = 0; + stylemenu->setItemChecked(100+style, TRUE); + update(); + } +} + +void Graph::timerEvent(QTimerEvent*) +{ + pieRotation = ( pieRotation + 6 ) % 360; repaint(FALSE); +} + +void Graph::setStyle(const char* stext) +{ + for ( Style s = Pie; styleName[s]; s = Style(s+1) ) { + if ( qstricmp(stext,styleName[s])==0 ) { + setStyle(s); + return; + } + } +} + +void Graph::enterInstance() +{ + menubar->show(); +} + +void Graph::leaveInstance() +{ + menubar->hide(); +} + +void Graph::paintError(const char* e) +{ + QPainter p(this); + int w = width(); + p.drawText(w/8, 0, w-w/4, height(), AlignCenter|WordBreak, e); +} + +void Graph::paintBar(QPaintEvent* event) +{ + if ( model.colType(0) != GraphModel::Numeric ) { + paintError("First column not numeric, cannot draw bar graph\n"); + return; + } + + QPtrList& data = model.graphData(); + + double max = 0.0; + + for (GraphModel::Datum* rowdata = data.first(); + rowdata; rowdata = data.next()) + { + if (rowdata[0].dbl > max) max = rowdata[0].dbl; + } + + const uint w = width(); + const uint h = height(); + + QPainter p(this); + + p.setClipRect(event->rect()); + + if ( w > data.count() ) { + // More pixels than data + int x = 0; + int i = 0; + QFontMetrics fm=fontMetrics(); + int fh = fm.height(); + + for (GraphModel::Datum* rowdata = data.first(); + rowdata; rowdata = data.next()) + { + QColor c; + c.setHsv( (i * 255)/data.count(), 255, 255 );// rainbow effect + p.setBrush(c); + int bw = (w-w/4-x)/(data.count()-i); + int bh = int((h-h/4-1)*rowdata[0].dbl/max); + p.drawRect( w/8+x, h-h/8-1-bh, bw, bh ); + + i++; + x+=bw; + } + } else { + // More data than pixels + int x = 0; + int i = 0; + double av = 0.0; + int n = 0; + for (GraphModel::Datum* rowdata = data.first(); rowdata; + rowdata = data.next()) + { + int bx = i*w/data.count(); + + if (bx > x) { + QColor c; + c.setHsv( (x * 255)/w, 255, 255 );// rainbow effect + p.setPen(c); + int bh = int(h*av/n/max); + + p.drawLine(x,h-1,x,h-bh); + + av = 0.0; + n = 0; + x = bx; + } + + av += rowdata[0].dbl; + n++; + + i++; + } + } +} + +void Graph::paintPie(QPaintEvent* event) +{ + if ( model.colType(0) != GraphModel::Numeric ) { + paintError("First column not numeric, cannot draw pie graph\n"); + return; + } + + QPtrList& data = model.graphData(); + + double total = 0.0; + + GraphModel::Datum* rowdata; + + for (rowdata = data.first(); + rowdata; rowdata = data.next()) + { + total += rowdata[0].dbl; + } + + // Only use first column for pie chart + if ( !total ) return; + + int apos = (pieRotation-90)*16; + + const int w = width(); + const int h = height(); + + const int xd = w - w/5; + const int yd = h - h/5; + + pm.resize(width(),height()); + pm.fill(backgroundColor()); + QPainter p(&pm); + p.setFont(font()); + + p.setClipRect(event->rect()); + + int i = 0; + + for (rowdata = data.first(); + rowdata; rowdata = data.next()) + { + QColor c; + + c.setHsv( ( i * 255)/data.count(), 255, 255 );// rainbow effect + p.setBrush( c ); // solid fill with color c + + int a = int(( rowdata[0].dbl * 360.0 ) / total * 16.0 + 0.5); + p.drawPie( w/10, h/10, xd, yd, -apos, -a ); + apos += a; + i++; + } + + if (model.colType(1) == GraphModel::Label) { + double apos = (pieRotation-90)*M_PI/180; + + for (rowdata = data.first(); + rowdata; rowdata = data.next()) + { + double a = rowdata[0].dbl * 360 / total * M_PI / 180; + int x = int(cos(apos+a/2)*w*5/16 + w/2 + 0.5); + int y = int(sin(apos+a/2)*h*5/16 + h/2 + 0.5); + + // ### This causes a crash, so comment out for now + /*p.drawText(x-w/8, y-h/8, w/4, h/4, + WordBreak|AlignCenter, + *rowdata[1].str);*/ + apos += a; + } + } + + QPainter p2(this); + p2.setClipRect(event->rect()); + p2.drawPixmap(0,0,pm); +} + +void Graph::paintWait(QPaintEvent*) +{ + QPainter p(this); + p.drawText(rect(), AlignCenter, "Loading..."); +} + +void Graph::paintEvent(QPaintEvent* event) +{ + if (!model.nCols()) { + paintWait(event); + } else { + switch (style) { + case Pie: + paintPie(event); + break; + case Bar: + paintBar(event); + break; + } + } +} + +void Graph::setStyleFromMenu(int id) +{ + setStyle(Style(id-100)); +} + +const char* Graph::styleName[] = { "Pie", "Bar", 0 }; + + +// +// Grapher is a subclass of QNPInstance, and so it can be returned +// by GrapherPlugin::newInstance(). A QNPInstance represents the +// plugin, distinctly from the plugin window. +// +// Grapher is also a GraphModel, because it loads graph data from +// the net. When Grapher creates a window in newWindow(), it creates +// a Graph widget to display the GraphModel that is the Grapher itself. +// + +class Grapher : public QNPInstance, GraphModel { + Q_OBJECT +public: + // Create a Grapher - all Grapher plugins are created + // by one GrapherPlugin object. + // + Grapher(); + ~Grapher(); + + // We override this QNPInstance function to create our + // own subclass of QNPWidget, a Graph widget. + // + QNPWidget* newWindow(); + + // We override this QNPInstance function to process the + // incoming graph data. + // + int write(QNPStream* /*str*/, int /*offset*/, int len, void* buffer); + +private: + // Grapher is a GraphModel, so it implements the pure virtual + // functions of that class. + // + QPtrList& graphData(); + ColType colType(int col) const; + int nCols() const; + + void consumeLine(); + QPtrList data; + QBuffer line; + int ncols; + ColType *coltype; + +private slots: + // Slots that are connected to the Graph menu items. + // + void aboutPlugin(); + void aboutData(); +}; + +Grapher::Grapher() +{ + data.setAutoDelete(TRUE); + ncols = 0; + line.open(IO_WriteOnly|IO_Truncate); +} + +Grapher::~Grapher() +{ +} + +QPtrList& Grapher::graphData() +{ + return data; +} + +GraphModel::ColType Grapher::colType(int col) const +{ + return coltype[col]; +} + +int Grapher::nCols() const +{ + return ncols; +} + + +QNPWidget* Grapher::newWindow() +{ + // Create a Graph - our subclass of QNPWidget. + Graph *graph = new Graph(*this); + + // Look at the arguments from the EMBED tag. + // GRAPHSTYLE chooses pie or bar + // FONTFAMILY and FONTSIZE choose the font + // + const char* style = arg("GRAPHSTYLE"); + if ( style ) graph->setStyle(style); + + const char* fontfamily = arg("FONTFAMILY"); + const char* fontsize = arg("FONTSIZE"); + int ptsize = fontsize ? atoi(fontsize) : graph->font().pointSize(); + if (fontfamily) graph->setFont(QFont(fontfamily, ptsize)); + + connect(graph, SIGNAL(aboutPlugin()), this, SLOT(aboutPlugin())); + connect(graph, SIGNAL(aboutData()), this, SLOT(aboutData())); + + return graph; +} + +void Grapher::consumeLine() +{ + line.close(); + line.open(IO_ReadOnly); + + QTextStream ts( &line ); + + if (ncols == 0 ) { + ncols=0; + QPtrList typelist; + typelist.setAutoDelete(TRUE); + do { + QString typestr; + ts >> typestr >> ws; + ColType* t = 0; + if ( typestr == "num" ) { + t = new ColType(Numeric); + } else if ( typestr == "label" ) { + t = new ColType(Label); + } + if (t) typelist.append(t); + } while (!ts.atEnd()); + coltype = new ColType[ncols]; + for (ColType* t = typelist.first(); t; t = typelist.next()) { + coltype[ncols++] = *t; + } + } else { + int col=0; + Datum *rowdata = new Datum[ncols]; + while ( col < ncols && !ts.atEnd() ) { + switch (coltype[col]) { + case Numeric: { + double value; + ts >> value >> ws; + rowdata[col].dbl = value; + break; + } + case Label: { + QString* value = new QString; + ts >> *value >> ws; + rowdata[col].str = value; + break; + } + } + col++; + } + + data.append(rowdata); + } + + line.close(); + line.open(IO_WriteOnly|IO_Truncate); +} + +int Grapher::write(QNPStream* /*str*/, int /*offset*/, int len, void* buffer) +{ + // The browser calls this function when data is available on one + // of the streams the plugin has requested. Since we are only + // processing one stream - the URL in the SRC argument of the EMBED + // tag, we assume the QNPStream is that one. Also, since we do not + // override QNPInstance::writeReady(), we must accepts ALL the data + // that is sent to this function. + // + char* txt = (char*)buffer; + for (int i=0; iupdate(); + + return len; +} + +void Grapher::aboutPlugin() +{ + getURL( "http://doc.trolltech.com/netscape-plugin.html", "_blank" ); +} + +void Grapher::aboutData() +{ + const char* page = arg("DATAPAGE"); + if (page) + getURL( page, "_blank" ); + else + QMessageBox::message("Help", "No help for this data"); +} + + +// +// GrapherPlugin is the start of everything. It is a QNPlugin subclass, +// and it is responsible for describing the plugin to the browser, and +// creating instances of the plugin when it appears in web page. +// + +class GrapherPlugin : public QNPlugin { +public: + GrapherPlugin() + { + } + + QNPInstance* newInstance() + { + // Make a new Grapher, our subclass of QNPInstance. + return new Grapher; + } + + const char* getMIMEDescription() const + { + // Describe the MIME types which this plugin can + // process. Just the concocted "application/x-graphable" + // type, with the "g1n" filename extension. + // + return "application/x-graphable:g1n:Graphable ASCII numeric data"; + } + + const char * getPluginNameString() const + { + // The name of the plugin. This is the title string used in + // the "About Plugins" page of the browser. + // + return "Qt-based Graph Plugin"; + } + + const char * getPluginDescriptionString() const + { + // A longer description of the plugin. + // + return "A Qt-based LiveConnected plug-in that graphs numeric data"; + } + +}; + +// +// Finally, we provide the implementation of QNPlugin::create(), to +// provide our subclass of QNPlugin. +// + +QNPlugin* QNPlugin::create() +{ + return new GrapherPlugin; +} + +#include "grapher.moc" diff --git a/extensions/nsplugin/examples/grapher/grapher.def b/extensions/nsplugin/examples/grapher/grapher.def new file mode 100644 index 0000000..e71dd47 --- /dev/null +++ b/extensions/nsplugin/examples/grapher/grapher.def @@ -0,0 +1,9 @@ +LIBRARY npgrapher.dll + +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD SINGLE + +EXPORTS + NP_GetEntryPoints @1 + NP_Initialize @2 + NP_Shutdown @3 diff --git a/extensions/nsplugin/examples/grapher/grapher.doc b/extensions/nsplugin/examples/grapher/grapher.doc new file mode 100644 index 0000000..4ef8778 --- /dev/null +++ b/extensions/nsplugin/examples/grapher/grapher.doc @@ -0,0 +1,64 @@ +/*! \page grapher-nsplugin-example.html + \ingroup nsplugin-examples + + \title Grapher Plugin + + This example graphs data from a simple text file. It + demonstrates the use of the QNPInstance::writeReady() + and QNPInstance::write() functions. + + To build the example, you must first build the + Qt Netscape Plugin Extension library. + Then type make in extensions/nsplugin/examples/grapher/ + and copy the resulting grapher.so or npgrapher.dll + to the Plugins directory of your WWW browser. + + + + The text file it accepts as input has a title line, then + a sequence of lines with a number, then a string. The + plugin displays a pie chart of the numbers, each segment + labelled by the associated string. The user can select + a bar chart view of the same data by selecting from the + menu that appears when they point at the plugin. + + The HTML tag used to embed the graph is: + +
+  <EMBED
+    SRC=graph.g1n
+    ALIGN=LEFT
+    WIDTH=49% HEIGHT=300
+    graphstyle=pie fontfamily=times
+    fontsize=18>
+
+
+ Note that some HTML arguments (which we have capitalized here) + are interpreted by the browser, while others are used by the + plugin. + +
+With the simplicity and cross-platform nature of Qt-based plugins, +pages like Netcraft's +Server Graphs can be provided much more efficiently for both +the service provider and consumer. Data need not be converted +to an image at the server. + +
+
+ Implementation: + + \include grapher/grapher.cpp +*/ + +/*! \plainpage graph.g1n +num label +10 A +24 B +12 C +7 D +34 E +15 F +19 G +*/ diff --git a/extensions/nsplugin/examples/grapher/grapher.pro b/extensions/nsplugin/examples/grapher/grapher.pro new file mode 100644 index 0000000..6f05b54 --- /dev/null +++ b/extensions/nsplugin/examples/grapher/grapher.pro @@ -0,0 +1,12 @@ +TEMPLATE = lib +TARGET = grapher +win32:TARGET = npgrapher + +CONFIG += qt dll release +LIBS += -lqnp +unix:LIBS += -lXt + +HEADERS = +SOURCES = grapher.cpp +DEF_FILE = grapher.def +RC_FILE = grapher.rc diff --git a/extensions/nsplugin/examples/grapher/grapher.rc b/extensions/nsplugin/examples/grapher/grapher.rc new file mode 100644 index 0000000..558c738 --- /dev/null +++ b/extensions/nsplugin/examples/grapher/grapher.rc @@ -0,0 +1,36 @@ + +1 VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "Trolltech\0" + VALUE "FileDescription", "grapher\0" + VALUE "FileExtents", "g1n\0" + VALUE "FileOpenName", "Graphable data (*.g1n)\0" + VALUE "FileVersion", "1, 0, 0, 1\0" + VALUE "InternalName", "grapher\0" + VALUE "LegalCopyright", "Copyright © 1997-2008 Trolltech ASA\0" + VALUE "MIMEType", "application/x-graphable\0" + VALUE "OriginalFilename", "grapher.dll\0" + VALUE "ProductName", "Trolltech grapher\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END diff --git a/extensions/nsplugin/examples/trivial/trivial.cpp b/extensions/nsplugin/examples/trivial/trivial.cpp new file mode 100644 index 0000000..6db691d --- /dev/null +++ b/extensions/nsplugin/examples/trivial/trivial.cpp @@ -0,0 +1,67 @@ +// Qt stuff +#include "qnp.h" +#include +#include + +class Trivial : public QNPWidget { + Q_OBJECT +public: + void mouseReleaseEvent(QMouseEvent* event) + { + QMessageBox::aboutQt(this); + } + + void paintEvent(QPaintEvent* event) + { + QPainter p(this); + p.setClipRect(event->rect()); + int w = width(); + p.drawRect(rect()); + p.drawText(w/8, 0, w-w/4, height(), AlignCenter|WordBreak, "Trivial!"); + } +}; + +class TrivialInstance : public QNPInstance { + Q_OBJECT +public: + QNPWidget* newWindow() + { + return new Trivial; + } + + void print(QPainter* p) + { + p->drawText(0,0,"Hello"); + } +}; + +class TrivialPlugin : public QNPlugin { +public: + QNPInstance* newInstance() + { + return new TrivialInstance; + } + + const char* getMIMEDescription() const + { + return "trivial/very:xxx:Trivial and useless"; + } + + const char * getPluginNameString() const + { + return "Trivial Qt-based Plugin"; + } + + const char * getPluginDescriptionString() const + { + return "A Qt-based LiveConnected plug-in that does nothing"; + } + +}; + +QNPlugin* QNPlugin::create() +{ + return new TrivialPlugin; +} + +#include "trivial.moc" diff --git a/extensions/nsplugin/examples/trivial/trivial.def b/extensions/nsplugin/examples/trivial/trivial.def new file mode 100644 index 0000000..1732fc6 --- /dev/null +++ b/extensions/nsplugin/examples/trivial/trivial.def @@ -0,0 +1,9 @@ +LIBRARY nptrivial.dll + +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD SINGLE + +EXPORTS + NP_GetEntryPoints @1 + NP_Initialize @2 + NP_Shutdown @3 diff --git a/extensions/nsplugin/examples/trivial/trivial.doc b/extensions/nsplugin/examples/trivial/trivial.doc new file mode 100644 index 0000000..14325c9 --- /dev/null +++ b/extensions/nsplugin/examples/trivial/trivial.doc @@ -0,0 +1,22 @@ +/*! \page trivial-nsplugin-example.html + \ingroup nsplugin-examples + + \title Trivial Example + + This example is trivial, and thus useful for + investigating problems you might have installing the + extension. + + To build the example, you must first build the + \link netscape-plugin.html Qt Netscape Plugin Extension\endlink library. + Then type \c{make} in \c{extensions/nsplugin/examples/trivial/} + and copy the resulting \c{trivial.so} or \c{nptrivial.dll} + to the Plugins directory of your WWW browser. + + + +
+ Implementation: + + \include trivial/trivial.cpp +*/ diff --git a/extensions/nsplugin/examples/trivial/trivial.pro b/extensions/nsplugin/examples/trivial/trivial.pro new file mode 100644 index 0000000..d61bf78 --- /dev/null +++ b/extensions/nsplugin/examples/trivial/trivial.pro @@ -0,0 +1,12 @@ +TEMPLATE = lib +TARGET = trivial +win32:TARGET = nptrivial + +CONFIG += qt dll release +LIBS += -lqnp +unix:LIBS += -lXt + +HEADERS = +SOURCES = trivial.cpp +DEF_FILE = trivial.def +RC_FILE = trivial.rc diff --git a/extensions/nsplugin/examples/trivial/trivial.rc b/extensions/nsplugin/examples/trivial/trivial.rc new file mode 100644 index 0000000..481cf08 --- /dev/null +++ b/extensions/nsplugin/examples/trivial/trivial.rc @@ -0,0 +1,36 @@ + +1 VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "Trolltech\0" + VALUE "FileDescription", "trivial\0" + VALUE "FileExtents", "xxx\0" + VALUE "FileOpenName", "Nothing (*.xxx)\0" + VALUE "FileVersion", "1, 0, 0, 1\0" + VALUE "InternalName", "trivial\0" + VALUE "LegalCopyright", "Copyright © 1997-2006 Trolltech ASA\0" + VALUE "MIMEType", "trivial/very\0" + VALUE "OriginalFilename", "trivial.dll\0" + VALUE "ProductName", "Trolltech trivial\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END diff --git a/extensions/nsplugin/src/jri.h b/extensions/nsplugin/src/jri.h new file mode 100644 index 0000000..d2bf291 --- /dev/null +++ b/extensions/nsplugin/src/jri.h @@ -0,0 +1,638 @@ +/* -*- Mode: C; tab-width: 4; -*- */ +/******************************************************************************* + * Java Runtime Interface + * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. + ******************************************************************************/ + +#ifndef JRI_H +#define JRI_H + +#include "jritypes.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************* + * JRIEnv + ******************************************************************************/ + +/* The type of the JRIEnv interface. */ +typedef struct JRIEnvInterface JRIEnvInterface; + +/* The type of a JRIEnv instance. */ +typedef const JRIEnvInterface* JRIEnv; + +/******************************************************************************* + * JRIEnv Operations + ******************************************************************************/ + +#define JRI_LoadClass(env, buf, bufLen) \ + (((*(env))->LoadClass)(env, JRI_LoadClass_op, buf, bufLen)) + +#define JRI_FindClass(env, name) \ + (((*(env))->FindClass)(env, JRI_FindClass_op, name)) + +#define JRI_Throw(env, obj) \ + (((*(env))->Throw)(env, JRI_Throw_op, obj)) + +#define JRI_ThrowNew(env, clazz, message) \ + (((*(env))->ThrowNew)(env, JRI_ThrowNew_op, clazz, message)) + +#define JRI_ExceptionOccurred(env) \ + (((*(env))->ExceptionOccurred)(env, JRI_ExceptionOccurred_op)) + +#define JRI_ExceptionDescribe(env) \ + (((*(env))->ExceptionDescribe)(env, JRI_ExceptionDescribe_op)) + +#define JRI_ExceptionClear(env) \ + (((*(env))->ExceptionClear)(env, JRI_ExceptionClear_op)) + +#define JRI_NewGlobalRef(env, ref) \ + (((*(env))->NewGlobalRef)(env, JRI_NewGlobalRef_op, ref)) + +#define JRI_DisposeGlobalRef(env, gref) \ + (((*(env))->DisposeGlobalRef)(env, JRI_DisposeGlobalRef_op, gref)) + +#define JRI_GetGlobalRef(env, gref) \ + (((*(env))->GetGlobalRef)(env, JRI_GetGlobalRef_op, gref)) + +#define JRI_SetGlobalRef(env, gref, ref) \ + (((*(env))->SetGlobalRef)(env, JRI_SetGlobalRef_op, gref, ref)) + +#define JRI_IsSameObject(env, a, b) \ + (((*(env))->IsSameObject)(env, JRI_IsSameObject_op, a, b)) + +#define JRI_NewObject(env) ((*(env))->NewObject) +#define JRI_NewObjectV(env, clazz, methodID, args) \ + (((*(env))->NewObjectV)(env, JRI_NewObject_op_va_list, clazz, methodID, args)) +#define JRI_NewObjectA(env, clazz, method, args) \ + (((*(env))->NewObjectA)(env, JRI_NewObject_op_array, clazz, methodID, args)) + +#define JRI_GetObjectClass(env, obj) \ + (((*(env))->GetObjectClass)(env, JRI_GetObjectClass_op, obj)) + +#define JRI_IsInstanceOf(env, obj, clazz) \ + (((*(env))->IsInstanceOf)(env, JRI_IsInstanceOf_op, obj, clazz)) + +#define JRI_GetMethodID(env, clazz, name, sig) \ + (((*(env))->GetMethodID)(env, JRI_GetMethodID_op, clazz, name, sig)) + +#define JRI_CallMethod(env) ((*(env))->CallMethod) +#define JRI_CallMethodV(env, obj, methodID, args) \ + (((*(env))->CallMethodV)(env, JRI_CallMethod_op_va_list, obj, methodID, args)) +#define JRI_CallMethodA(env, obj, methodID, args) \ + (((*(env))->CallMethodA)(env, JRI_CallMethod_op_array, obj, methodID, args)) + +#define JRI_CallMethodBoolean(env) ((*(env))->CallMethodBoolean) +#define JRI_CallMethodBooleanV(env, obj, methodID, args) \ + (((*(env))->CallMethodBooleanV)(env, JRI_CallMethodBoolean_op_va_list, obj, methodID, args)) +#define JRI_CallMethodBooleanA(env, obj, methodID, args) \ + (((*(env))->CallMethodBooleanA)(env, JRI_CallMethodBoolean_op_array, obj, methodID, args)) + +#define JRI_CallMethodByte(env) ((*(env))->CallMethodByte) +#define JRI_CallMethodByteV(env, obj, methodID, args) \ + (((*(env))->CallMethodByteV)(env, JRI_CallMethodByte_op_va_list, obj, methodID, args)) +#define JRI_CallMethodByteA(env, obj, methodID, args) \ + (((*(env))->CallMethodByteA)(env, JRI_CallMethodByte_op_array, obj, methodID, args)) + +#define JRI_CallMethodChar(env) ((*(env))->CallMethodChar) +#define JRI_CallMethodCharV(env, obj, methodID, args) \ + (((*(env))->CallMethodCharV)(env, JRI_CallMethodChar_op_va_list, obj, methodID, args)) +#define JRI_CallMethodCharA(env, obj, methodID, args) \ + (((*(env))->CallMethodCharA)(env, JRI_CallMethodChar_op_array, obj, methodID, args)) + +#define JRI_CallMethodShort(env) ((*(env))->CallMethodShort) +#define JRI_CallMethodShortV(env, obj, methodID, args) \ + (((*(env))->CallMethodShortV)(env, JRI_CallMethodShort_op_va_list, obj, methodID, args)) +#define JRI_CallMethodShortA(env, obj, methodID, args) \ + (((*(env))->CallMethodShortA)(env, JRI_CallMethodShort_op_array, obj, methodID, args)) + +#define JRI_CallMethodInt(env) ((*(env))->CallMethodInt) +#define JRI_CallMethodIntV(env, obj, methodID, args) \ + (((*(env))->CallMethodIntV)(env, JRI_CallMethodInt_op_va_list, obj, methodID, args)) +#define JRI_CallMethodIntA(env, obj, methodID, args) \ + (((*(env))->CallMethodIntA)(env, JRI_CallMethodInt_op_array, obj, methodID, args)) + +#define JRI_CallMethodLong(env) ((*(env))->CallMethodLong) +#define JRI_CallMethodLongV(env, obj, methodID, args) \ + (((*(env))->CallMethodLongV)(env, JRI_CallMethodLong_op_va_list, obj, methodID, args)) +#define JRI_CallMethodLongA(env, obj, methodID, args) \ + (((*(env))->CallMethodLongA)(env, JRI_CallMethodLong_op_array, obj, methodID, args)) + +#define JRI_CallMethodFloat(env) ((*(env))->CallMethodFloat) +#define JRI_CallMethodFloatV(env, obj, methodID, args) \ + (((*(env))->CallMethodFloatV)(env, JRI_CallMethodFloat_op_va_list, obj, methodID, args)) +#define JRI_CallMethodFloatA(env, obj, methodID, args) \ + (((*(env))->CallMethodFloatA)(env, JRI_CallMethodFloat_op_array, obj, methodID, args)) + +#define JRI_CallMethodDouble(env) ((*(env))->CallMethodDouble) +#define JRI_CallMethodDoubleV(env, obj, methodID, args) \ + (((*(env))->CallMethodDoubleV)(env, JRI_CallMethodDouble_op_va_list, obj, methodID, args)) +#define JRI_CallMethodDoubleA(env, obj, methodID, args) \ + (((*(env))->CallMethodDoubleA)(env, JRI_CallMethodDouble_op_array, obj, methodID, args)) + +#define JRI_GetFieldID(env, clazz, name, sig) \ + (((*(env))->GetFieldID)(env, JRI_GetFieldID_op, clazz, name, sig)) + +#define JRI_GetField(env, obj, fieldID) \ + (((*(env))->GetField)(env, JRI_GetField_op, obj, fieldID)) + +#define JRI_GetFieldBoolean(env, obj, fieldID) \ + (((*(env))->GetFieldBoolean)(env, JRI_GetFieldBoolean_op, obj, fieldID)) + +#define JRI_GetFieldByte(env, obj, fieldID) \ + (((*(env))->GetFieldByte)(env, JRI_GetFieldByte_op, obj, fieldID)) + +#define JRI_GetFieldChar(env, obj, fieldID) \ + (((*(env))->GetFieldChar)(env, JRI_GetFieldChar_op, obj, fieldID)) + +#define JRI_GetFieldShort(env, obj, fieldID) \ + (((*(env))->GetFieldShort)(env, JRI_GetFieldShort_op, obj, fieldID)) + +#define JRI_GetFieldInt(env, obj, fieldID) \ + (((*(env))->GetFieldInt)(env, JRI_GetFieldInt_op, obj, fieldID)) + +#define JRI_GetFieldLong(env, obj, fieldID) \ + (((*(env))->GetFieldLong)(env, JRI_GetFieldLong_op, obj, fieldID)) + +#define JRI_GetFieldFloat(env, obj, fieldID) \ + (((*(env))->GetFieldFloat)(env, JRI_GetFieldFloat_op, obj, fieldID)) + +#define JRI_GetFieldDouble(env, obj, fieldID) \ + (((*(env))->GetFieldDouble)(env, JRI_GetFieldDouble_op, obj, fieldID)) + +#define JRI_SetField(env, obj, fieldID, value) \ + (((*(env))->SetField)(env, JRI_SetField_op, obj, fieldID, value)) + +#define JRI_SetFieldBoolean(env, obj, fieldID, value) \ + (((*(env))->SetFieldBoolean)(env, JRI_SetFieldBoolean_op, obj, fieldID, value)) + +#define JRI_SetFieldByte(env, obj, fieldID, value) \ + (((*(env))->SetFieldByte)(env, JRI_SetFieldByte_op, obj, fieldID, value)) + +#define JRI_SetFieldChar(env, obj, fieldID, value) \ + (((*(env))->SetFieldChar)(env, JRI_SetFieldChar_op, obj, fieldID, value)) + +#define JRI_SetFieldShort(env, obj, fieldID, value) \ + (((*(env))->SetFieldShort)(env, JRI_SetFieldShort_op, obj, fieldID, value)) + +#define JRI_SetFieldInt(env, obj, fieldID, value) \ + (((*(env))->SetFieldInt)(env, JRI_SetFieldInt_op, obj, fieldID, value)) + +#define JRI_SetFieldLong(env, obj, fieldID, value) \ + (((*(env))->SetFieldLong)(env, JRI_SetFieldLong_op, obj, fieldID, value)) + +#define JRI_SetFieldFloat(env, obj, fieldID, value) \ + (((*(env))->SetFieldFloat)(env, JRI_SetFieldFloat_op, obj, fieldID, value)) + +#define JRI_SetFieldDouble(env, obj, fieldID, value) \ + (((*(env))->SetFieldDouble)(env, JRI_SetFieldDouble_op, obj, fieldID, value)) + +#define JRI_IsSubclassOf(env, a, b) \ + (((*(env))->IsSubclassOf)(env, JRI_IsSubclassOf_op, a, b)) + +#define JRI_GetStaticMethodID(env, clazz, name, sig) \ + (((*(env))->GetStaticMethodID)(env, JRI_GetStaticMethodID_op, clazz, name, sig)) + +#define JRI_CallStaticMethod(env) ((*(env))->CallStaticMethod) +#define JRI_CallStaticMethodV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodV)(env, JRI_CallStaticMethod_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodA)(env, JRI_CallStaticMethod_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodBoolean(env) ((*(env))->CallStaticMethodBoolean) +#define JRI_CallStaticMethodBooleanV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodBooleanV)(env, JRI_CallStaticMethodBoolean_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodBooleanA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodBooleanA)(env, JRI_CallStaticMethodBoolean_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodByte(env) ((*(env))->CallStaticMethodByte) +#define JRI_CallStaticMethodByteV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodByteV)(env, JRI_CallStaticMethodByte_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodByteA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodByteA)(env, JRI_CallStaticMethodByte_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodChar(env) ((*(env))->CallStaticMethodChar) +#define JRI_CallStaticMethodCharV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodCharV)(env, JRI_CallStaticMethodChar_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodCharA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodCharA)(env, JRI_CallStaticMethodChar_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodShort(env) ((*(env))->CallStaticMethodShort) +#define JRI_CallStaticMethodShortV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodShortV)(env, JRI_CallStaticMethodShort_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodShortA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodShortA)(env, JRI_CallStaticMethodShort_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodInt(env) ((*(env))->CallStaticMethodInt) +#define JRI_CallStaticMethodIntV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodIntV)(env, JRI_CallStaticMethodInt_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodIntA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodIntA)(env, JRI_CallStaticMethodInt_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodLong(env) ((*(env))->CallStaticMethodLong) +#define JRI_CallStaticMethodLongV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodLongV)(env, JRI_CallStaticMethodLong_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodLongA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodLongA)(env, JRI_CallStaticMethodLong_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodFloat(env) ((*(env))->CallStaticMethodFloat) +#define JRI_CallStaticMethodFloatV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodFloatV)(env, JRI_CallStaticMethodFloat_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodFloatA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodFloatA)(env, JRI_CallStaticMethodFloat_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodDouble(env) ((*(env))->CallStaticMethodDouble) +#define JRI_CallStaticMethodDoubleV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodDoubleV)(env, JRI_CallStaticMethodDouble_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodDoubleA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodDoubleA)(env, JRI_CallStaticMethodDouble_op_array, clazz, methodID, args)) + +#define JRI_GetStaticFieldID(env, clazz, name, sig) \ + (((*(env))->GetStaticFieldID)(env, JRI_GetStaticFieldID_op, clazz, name, sig)) + +#define JRI_GetStaticField(env, clazz, fieldID) \ + (((*(env))->GetStaticField)(env, JRI_GetStaticField_op, clazz, fieldID)) + +#define JRI_GetStaticFieldBoolean(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldBoolean)(env, JRI_GetStaticFieldBoolean_op, clazz, fieldID)) + +#define JRI_GetStaticFieldByte(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldByte)(env, JRI_GetStaticFieldByte_op, clazz, fieldID)) + +#define JRI_GetStaticFieldChar(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldChar)(env, JRI_GetStaticFieldChar_op, clazz, fieldID)) + +#define JRI_GetStaticFieldShort(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldShort)(env, JRI_GetStaticFieldShort_op, clazz, fieldID)) + +#define JRI_GetStaticFieldInt(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldInt)(env, JRI_GetStaticFieldInt_op, clazz, fieldID)) + +#define JRI_GetStaticFieldLong(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldLong)(env, JRI_GetStaticFieldLong_op, clazz, fieldID)) + +#define JRI_GetStaticFieldFloat(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldFloat)(env, JRI_GetStaticFieldFloat_op, clazz, fieldID)) + +#define JRI_GetStaticFieldDouble(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldDouble)(env, JRI_GetStaticFieldDouble_op, clazz, fieldID)) + +#define JRI_SetStaticField(env, clazz, fieldID, value) \ + (((*(env))->SetStaticField)(env, JRI_SetStaticField_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldBoolean(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldBoolean)(env, JRI_SetStaticFieldBoolean_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldByte(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldByte)(env, JRI_SetStaticFieldByte_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldChar(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldChar)(env, JRI_SetStaticFieldChar_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldShort(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldShort)(env, JRI_SetStaticFieldShort_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldInt(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldInt)(env, JRI_SetStaticFieldInt_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldLong(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldLong)(env, JRI_SetStaticFieldLong_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldFloat(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldFloat)(env, JRI_SetStaticFieldFloat_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldDouble(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldDouble)(env, JRI_SetStaticFieldDouble_op, clazz, fieldID, value)) + +#define JRI_NewString(env, unicode, len) \ + (((*(env))->NewString)(env, JRI_NewString_op, unicode, len)) + +#define JRI_GetStringLength(env, string) \ + (((*(env))->GetStringLength)(env, JRI_GetStringLength_op, string)) + +#define JRI_GetStringChars(env, string) \ + (((*(env))->GetStringChars)(env, JRI_GetStringChars_op, string)) + +#define JRI_NewStringUTF(env, utf, len) \ + (((*(env))->NewStringUTF)(env, JRI_NewStringUTF_op, utf, len)) + +#define JRI_GetStringUTFLength(env, string) \ + (((*(env))->GetStringUTFLength)(env, JRI_GetStringUTFLength_op, string)) + +#define JRI_GetStringUTFChars(env, string) \ + (((*(env))->GetStringUTFChars)(env, JRI_GetStringUTFChars_op, string)) + +#define JRI_NewScalarArray(env, length, elementSig, initialElements) \ + (((*(env))->NewScalarArray)(env, JRI_NewScalarArray_op, length, elementSig, initialElements)) + +#define JRI_GetScalarArrayLength(env, array) \ + (((*(env))->GetScalarArrayLength)(env, JRI_GetScalarArrayLength_op, array)) + +#define JRI_GetScalarArrayElements(env, array) \ + (((*(env))->GetScalarArrayElements)(env, JRI_GetScalarArrayElements_op, array)) + +#define JRI_NewObjectArray(env, length, elementClass, initialElement) \ + (((*(env))->NewObjectArray)(env, JRI_NewObjectArray_op, length, elementClass, initialElement)) + +#define JRI_GetObjectArrayLength(env, array) \ + (((*(env))->GetObjectArrayLength)(env, JRI_GetObjectArrayLength_op, array)) + +#define JRI_GetObjectArrayElement(env, array, index) \ + (((*(env))->GetObjectArrayElement)(env, JRI_GetObjectArrayElement_op, array, index)) + +#define JRI_SetObjectArrayElement(env, array, index, value) \ + (((*(env))->SetObjectArrayElement)(env, JRI_SetObjectArrayElement_op, array, index, value)) + +#define JRI_RegisterNatives(env, clazz, nameAndSigArray, nativeProcArray) \ + (((*(env))->RegisterNatives)(env, JRI_RegisterNatives_op, clazz, nameAndSigArray, nativeProcArray)) + +#define JRI_UnregisterNatives(env, clazz) \ + (((*(env))->UnregisterNatives)(env, JRI_UnregisterNatives_op, clazz)) + +/******************************************************************************* + * JRIEnv Interface + ******************************************************************************/ + +struct java_lang_Class; +struct java_lang_Throwable; +struct java_lang_Object; +struct java_lang_String; + +struct JRIEnvInterface { + void* reserved0; + void* reserved1; + void* reserved2; + struct java_lang_Class* (*LoadClass)(JRIEnv* env, jint op, jbyte* a, jsize aLen); + struct java_lang_Class* (*FindClass)(JRIEnv* env, jint op, const char* a); + void (*Throw)(JRIEnv* env, jint op, struct java_lang_Throwable* a); + void (*ThrowNew)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b); + struct java_lang_Throwable* (*ExceptionOccurred)(JRIEnv* env, jint op); + void (*ExceptionDescribe)(JRIEnv* env, jint op); + void (*ExceptionClear)(JRIEnv* env, jint op); + jglobal (*NewGlobalRef)(JRIEnv* env, jint op, void* a); + void (*DisposeGlobalRef)(JRIEnv* env, jint op, jglobal a); + void* (*GetGlobalRef)(JRIEnv* env, jint op, jglobal a); + void (*SetGlobalRef)(JRIEnv* env, jint op, jglobal a, void* b); + jbool (*IsSameObject)(JRIEnv* env, jint op, void* a, void* b); + void* (*NewObject)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + void* (*NewObjectV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + void* (*NewObjectA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + struct java_lang_Class* (*GetObjectClass)(JRIEnv* env, jint op, void* a); + jbool (*IsInstanceOf)(JRIEnv* env, jint op, void* a, struct java_lang_Class* b); + jint (*GetMethodID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); + void* (*CallMethod)(JRIEnv* env, jint op, void* a, jint b, ...); + void* (*CallMethodV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + void* (*CallMethodA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jbool (*CallMethodBoolean)(JRIEnv* env, jint op, void* a, jint b, ...); + jbool (*CallMethodBooleanV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jbool (*CallMethodBooleanA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jbyte (*CallMethodByte)(JRIEnv* env, jint op, void* a, jint b, ...); + jbyte (*CallMethodByteV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jbyte (*CallMethodByteA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jchar (*CallMethodChar)(JRIEnv* env, jint op, void* a, jint b, ...); + jchar (*CallMethodCharV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jchar (*CallMethodCharA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jshort (*CallMethodShort)(JRIEnv* env, jint op, void* a, jint b, ...); + jshort (*CallMethodShortV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jshort (*CallMethodShortA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jint (*CallMethodInt)(JRIEnv* env, jint op, void* a, jint b, ...); + jint (*CallMethodIntV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jint (*CallMethodIntA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jlong (*CallMethodLong)(JRIEnv* env, jint op, void* a, jint b, ...); + jlong (*CallMethodLongV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jlong (*CallMethodLongA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jfloat (*CallMethodFloat)(JRIEnv* env, jint op, void* a, jint b, ...); + jfloat (*CallMethodFloatV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jfloat (*CallMethodFloatA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jdouble (*CallMethodDouble)(JRIEnv* env, jint op, void* a, jint b, ...); + jdouble (*CallMethodDoubleV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jdouble (*CallMethodDoubleA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jint (*GetFieldID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); + void* (*GetField)(JRIEnv* env, jint op, void* a, jint b); + jbool (*GetFieldBoolean)(JRIEnv* env, jint op, void* a, jint b); + jbyte (*GetFieldByte)(JRIEnv* env, jint op, void* a, jint b); + jchar (*GetFieldChar)(JRIEnv* env, jint op, void* a, jint b); + jshort (*GetFieldShort)(JRIEnv* env, jint op, void* a, jint b); + jint (*GetFieldInt)(JRIEnv* env, jint op, void* a, jint b); + jlong (*GetFieldLong)(JRIEnv* env, jint op, void* a, jint b); + jfloat (*GetFieldFloat)(JRIEnv* env, jint op, void* a, jint b); + jdouble (*GetFieldDouble)(JRIEnv* env, jint op, void* a, jint b); + void (*SetField)(JRIEnv* env, jint op, void* a, jint b, void* c); + void (*SetFieldBoolean)(JRIEnv* env, jint op, void* a, jint b, jbool c); + void (*SetFieldByte)(JRIEnv* env, jint op, void* a, jint b, jbyte c); + void (*SetFieldChar)(JRIEnv* env, jint op, void* a, jint b, jchar c); + void (*SetFieldShort)(JRIEnv* env, jint op, void* a, jint b, jshort c); + void (*SetFieldInt)(JRIEnv* env, jint op, void* a, jint b, jint c); + void (*SetFieldLong)(JRIEnv* env, jint op, void* a, jint b, jlong c); + void (*SetFieldFloat)(JRIEnv* env, jint op, void* a, jint b, jfloat c); + void (*SetFieldDouble)(JRIEnv* env, jint op, void* a, jint b, jdouble c); + jbool (*IsSubclassOf)(JRIEnv* env, jint op, struct java_lang_Class* a, struct java_lang_Class* b); + jint (*GetStaticMethodID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); + void* (*CallStaticMethod)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + void* (*CallStaticMethodV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + void* (*CallStaticMethodA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jbool (*CallStaticMethodBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jbool (*CallStaticMethodBooleanV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jbool (*CallStaticMethodBooleanA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jbyte (*CallStaticMethodByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jbyte (*CallStaticMethodByteV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jbyte (*CallStaticMethodByteA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jchar (*CallStaticMethodChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jchar (*CallStaticMethodCharV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jchar (*CallStaticMethodCharA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jshort (*CallStaticMethodShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jshort (*CallStaticMethodShortV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jshort (*CallStaticMethodShortA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jint (*CallStaticMethodInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jint (*CallStaticMethodIntV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jint (*CallStaticMethodIntA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jlong (*CallStaticMethodLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jlong (*CallStaticMethodLongV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jlong (*CallStaticMethodLongA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jfloat (*CallStaticMethodFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jfloat (*CallStaticMethodFloatV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jfloat (*CallStaticMethodFloatA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jdouble (*CallStaticMethodDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jdouble (*CallStaticMethodDoubleV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jdouble (*CallStaticMethodDoubleA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jint (*GetStaticFieldID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); + void* (*GetStaticField)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jbool (*GetStaticFieldBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jbyte (*GetStaticFieldByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jchar (*GetStaticFieldChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jshort (*GetStaticFieldShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jint (*GetStaticFieldInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jlong (*GetStaticFieldLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jfloat (*GetStaticFieldFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jdouble (*GetStaticFieldDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + void (*SetStaticField)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, void* c); + void (*SetStaticFieldBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jbool c); + void (*SetStaticFieldByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jbyte c); + void (*SetStaticFieldChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jchar c); + void (*SetStaticFieldShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jshort c); + void (*SetStaticFieldInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jint c); + void (*SetStaticFieldLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jlong c); + void (*SetStaticFieldFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jfloat c); + void (*SetStaticFieldDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jdouble c); + struct java_lang_String* (*NewString)(JRIEnv* env, jint op, const jchar* a, jint b); + jint (*GetStringLength)(JRIEnv* env, jint op, struct java_lang_String* a); + const jchar* (*GetStringChars)(JRIEnv* env, jint op, struct java_lang_String* a); + struct java_lang_String* (*NewStringUTF)(JRIEnv* env, jint op, const jbyte* a, jint b); + jint (*GetStringUTFLength)(JRIEnv* env, jint op, struct java_lang_String* a); + const jbyte* (*GetStringUTFChars)(JRIEnv* env, jint op, struct java_lang_String* a); + void* (*NewScalarArray)(JRIEnv* env, jint op, jint a, const char* b, const jbyte* c); + jint (*GetScalarArrayLength)(JRIEnv* env, jint op, void* a); + jbyte* (*GetScalarArrayElements)(JRIEnv* env, jint op, void* a); + void* (*NewObjectArray)(JRIEnv* env, jint op, jint a, struct java_lang_Class* b, void* c); + jint (*GetObjectArrayLength)(JRIEnv* env, jint op, void* a); + void* (*GetObjectArrayElement)(JRIEnv* env, jint op, void* a, jint b); + void (*SetObjectArrayElement)(JRIEnv* env, jint op, void* a, jint b, void* c); + void (*RegisterNatives)(JRIEnv* env, jint op, struct java_lang_Class* a, char** b, void** c); + void (*UnregisterNatives)(JRIEnv* env, jint op, struct java_lang_Class* a); +}; + +/******************************************************************************* + * JRIEnv Operation IDs + ******************************************************************************/ + +typedef enum JRIEnvOperations { + JRI_Reserved0_op, + JRI_Reserved1_op, + JRI_Reserved2_op, + JRI_LoadClass_op, + JRI_FindClass_op, + JRI_Throw_op, + JRI_ThrowNew_op, + JRI_ExceptionOccurred_op, + JRI_ExceptionDescribe_op, + JRI_ExceptionClear_op, + JRI_NewGlobalRef_op, + JRI_DisposeGlobalRef_op, + JRI_GetGlobalRef_op, + JRI_SetGlobalRef_op, + JRI_IsSameObject_op, + JRI_NewObject_op, + JRI_NewObject_op_va_list, + JRI_NewObject_op_array, + JRI_GetObjectClass_op, + JRI_IsInstanceOf_op, + JRI_GetMethodID_op, + JRI_CallMethod_op, + JRI_CallMethod_op_va_list, + JRI_CallMethod_op_array, + JRI_CallMethodBoolean_op, + JRI_CallMethodBoolean_op_va_list, + JRI_CallMethodBoolean_op_array, + JRI_CallMethodByte_op, + JRI_CallMethodByte_op_va_list, + JRI_CallMethodByte_op_array, + JRI_CallMethodChar_op, + JRI_CallMethodChar_op_va_list, + JRI_CallMethodChar_op_array, + JRI_CallMethodShort_op, + JRI_CallMethodShort_op_va_list, + JRI_CallMethodShort_op_array, + JRI_CallMethodInt_op, + JRI_CallMethodInt_op_va_list, + JRI_CallMethodInt_op_array, + JRI_CallMethodLong_op, + JRI_CallMethodLong_op_va_list, + JRI_CallMethodLong_op_array, + JRI_CallMethodFloat_op, + JRI_CallMethodFloat_op_va_list, + JRI_CallMethodFloat_op_array, + JRI_CallMethodDouble_op, + JRI_CallMethodDouble_op_va_list, + JRI_CallMethodDouble_op_array, + JRI_GetFieldID_op, + JRI_GetField_op, + JRI_GetFieldBoolean_op, + JRI_GetFieldByte_op, + JRI_GetFieldChar_op, + JRI_GetFieldShort_op, + JRI_GetFieldInt_op, + JRI_GetFieldLong_op, + JRI_GetFieldFloat_op, + JRI_GetFieldDouble_op, + JRI_SetField_op, + JRI_SetFieldBoolean_op, + JRI_SetFieldByte_op, + JRI_SetFieldChar_op, + JRI_SetFieldShort_op, + JRI_SetFieldInt_op, + JRI_SetFieldLong_op, + JRI_SetFieldFloat_op, + JRI_SetFieldDouble_op, + JRI_IsSubclassOf_op, + JRI_GetStaticMethodID_op, + JRI_CallStaticMethod_op, + JRI_CallStaticMethod_op_va_list, + JRI_CallStaticMethod_op_array, + JRI_CallStaticMethodBoolean_op, + JRI_CallStaticMethodBoolean_op_va_list, + JRI_CallStaticMethodBoolean_op_array, + JRI_CallStaticMethodByte_op, + JRI_CallStaticMethodByte_op_va_list, + JRI_CallStaticMethodByte_op_array, + JRI_CallStaticMethodChar_op, + JRI_CallStaticMethodChar_op_va_list, + JRI_CallStaticMethodChar_op_array, + JRI_CallStaticMethodShort_op, + JRI_CallStaticMethodShort_op_va_list, + JRI_CallStaticMethodShort_op_array, + JRI_CallStaticMethodInt_op, + JRI_CallStaticMethodInt_op_va_list, + JRI_CallStaticMethodInt_op_array, + JRI_CallStaticMethodLong_op, + JRI_CallStaticMethodLong_op_va_list, + JRI_CallStaticMethodLong_op_array, + JRI_CallStaticMethodFloat_op, + JRI_CallStaticMethodFloat_op_va_list, + JRI_CallStaticMethodFloat_op_array, + JRI_CallStaticMethodDouble_op, + JRI_CallStaticMethodDouble_op_va_list, + JRI_CallStaticMethodDouble_op_array, + JRI_GetStaticFieldID_op, + JRI_GetStaticField_op, + JRI_GetStaticFieldBoolean_op, + JRI_GetStaticFieldByte_op, + JRI_GetStaticFieldChar_op, + JRI_GetStaticFieldShort_op, + JRI_GetStaticFieldInt_op, + JRI_GetStaticFieldLong_op, + JRI_GetStaticFieldFloat_op, + JRI_GetStaticFieldDouble_op, + JRI_SetStaticField_op, + JRI_SetStaticFieldBoolean_op, + JRI_SetStaticFieldByte_op, + JRI_SetStaticFieldChar_op, + JRI_SetStaticFieldShort_op, + JRI_SetStaticFieldInt_op, + JRI_SetStaticFieldLong_op, + JRI_SetStaticFieldFloat_op, + JRI_SetStaticFieldDouble_op, + JRI_NewString_op, + JRI_GetStringLength_op, + JRI_GetStringChars_op, + JRI_NewStringUTF_op, + JRI_GetStringUTFLength_op, + JRI_GetStringUTFChars_op, + JRI_NewScalarArray_op, + JRI_GetScalarArrayLength_op, + JRI_GetScalarArrayElements_op, + JRI_NewObjectArray_op, + JRI_GetObjectArrayLength_op, + JRI_GetObjectArrayElement_op, + JRI_SetObjectArrayElement_op, + JRI_RegisterNatives_op, + JRI_UnregisterNatives_op +} JRIEnvOperations; + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* JRI_H */ +/******************************************************************************/ diff --git a/extensions/nsplugin/src/jri_md.h b/extensions/nsplugin/src/jri_md.h new file mode 100644 index 0000000..5ef37f2 --- /dev/null +++ b/extensions/nsplugin/src/jri_md.h @@ -0,0 +1,500 @@ +/* -*- Mode: C; tab-width: 4; -*- */ +/******************************************************************************* + * Java Runtime Interface - Machine Dependent Types + * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. + ******************************************************************************/ + +#ifndef JRI_MD_H +#define JRI_MD_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * WHAT'S UP WITH THIS FILE? + * + * This is where we define the mystical JRI_PUBLIC_API macro that works on all + * platforms. If you're running with Visual C++, Symantec C, or Borland's + * development environment on the PC, you're all set. Or if you're on the Mac + * with Metrowerks, Symantec or MPW with SC you're ok too. For UNIX it shouldn't + * matter. + * + * On UNIX though you probably care about a couple of other symbols though: + * IS_LITTLE_ENDIAN must be defined for little-endian systems + * HAVE_LONG_LONG must be defined on systems that have 'long long' integers + * HAVE_ALIGNED_LONGLONGS must be defined if long-longs must be 8 byte aligned + * HAVE_ALIGNED_DOUBLES must be defined if doubles must be 8 byte aligned + * IS_64 must be defined on 64-bit machines (like Dec Alpha) + ******************************************************************************/ + +/* DLL Entry modifiers... */ + +/* PC */ +#if defined(XP_PC) || defined(_WINDOWS) || defined(WIN32) || defined(_WIN32) +# include +# if defined(_MSC_VER) +# if defined(WIN32) || defined(_WIN32) +# define JRI_PUBLIC_API(ResultType) _declspec(dllexport) ResultType +# define JRI_CALLBACK +# else /* !_WIN32 */ +# if defined(_WINDLL) +# define JRI_PUBLIC_API(ResultType) ResultType __cdecl __export __loadds +# define JRI_CALLBACK __loadds +# else /* !WINDLL */ +# define JRI_PUBLIC_API(ResultType) ResultType __cdecl __export +# define JRI_CALLBACK __export +# endif /* !WINDLL */ +# endif /* !_WIN32 */ +# elif defined(__BORLANDC__) +# if defined(WIN32) || defined(_WIN32) +# define JRI_PUBLIC_API(ResultType) __export ResultType +# define JRI_CALLBACK +# else /* !_WIN32 */ +# define JRI_PUBLIC_API(ResultType) ResultType _cdecl _export _loadds +# define JRI_CALLBACK _loadds +# endif +# else +# error Unsupported PC development environment. +# endif +# ifndef IS_LITTLE_ENDIAN +# define IS_LITTLE_ENDIAN +# endif + +/* Mac */ +#elif macintosh || Macintosh || THINK_C +# if defined(__MWERKS__) /* Metrowerks */ +# if !__option(enumsalwaysint) +# error You need to define 'Enums Always Int' for your project. +# endif +# if defined(GENERATING68K) && !GENERATINGCFM +# if !__option(fourbyteints) +# error You need to define 'Struct Alignment: 68k' for your project. +# endif +# endif /* !GENERATINGCFM */ +# elif defined(__SC__) /* Symantec */ +# error What are the Symantec defines? (warren@netscape.com) +# elif macintosh && applec /* MPW */ +# error Please upgrade to the latest MPW compiler (SC). +# else +# error Unsupported Mac development environment. +# endif +# define JRI_PUBLIC_API(ResultType) ResultType +# define JRI_CALLBACK + +/* Unix or else */ +#else +# define JRI_PUBLIC_API(ResultType) ResultType +# define JRI_CALLBACK +#endif + +#ifndef FAR /* for non-Win16 */ +#define FAR +#endif + +/******************************************************************************/ + +/* Java Scalar Types */ + +typedef unsigned char jbool; +typedef char jbyte; +typedef short jchar; +typedef short jshort; +#ifdef IS_64 /* XXX ok for alpha, but not right on all 64-bit architectures */ +typedef unsigned int juint; +typedef int jint; +#else +typedef unsigned long juint; +typedef long jint; +#endif +typedef float jfloat; +typedef double jdouble; + +typedef juint jsize; + +/******************************************************************************* + * jlong : long long (64-bit signed integer type) support. + ******************************************************************************/ + +/* +** Bit masking macros. (n must be <= 31 to be portable) +*/ +#define JRI_BIT(n) ((juint)1 << (n)) +#define JRI_BITMASK(n) (JRI_BIT(n) - 1) + +#ifdef HAVE_LONG_LONG + +#if !(defined(WIN32) || defined(_WIN32)) +typedef long long jlong; +typedef unsigned long long julong; + +#define jlong_MAXINT 0x7fffffffffffffffLL +#define jlong_MININT 0x8000000000000000LL +#define jlong_ZERO 0x0LL + +#else +typedef LONGLONG jlong; +typedef DWORDLONG julong; + +#define jlong_MAXINT 0x7fffffffffffffffi64 +#define jlong_MININT 0x8000000000000000i64 +#define jlong_ZERO 0x0i64 + +#endif + +#define jlong_IS_ZERO(a) ((a) == 0) +#define jlong_EQ(a, b) ((a) == (b)) +#define jlong_NE(a, b) ((a) != (b)) +#define jlong_GE_ZERO(a) ((a) >= 0) +#define jlong_CMP(a, op, b) ((a) op (b)) + +#define jlong_AND(r, a, b) ((r) = (a) & (b)) +#define jlong_OR(r, a, b) ((r) = (a) | (b)) +#define jlong_XOR(r, a, b) ((r) = (a) ^ (b)) +#define jlong_OR2(r, a) ((r) = (r) | (a)) +#define jlong_NOT(r, a) ((r) = ~(a)) + +#define jlong_NEG(r, a) ((r) = -(a)) +#define jlong_ADD(r, a, b) ((r) = (a) + (b)) +#define jlong_SUB(r, a, b) ((r) = (a) - (b)) + +#define jlong_MUL(r, a, b) ((r) = (a) * (b)) +#define jlong_DIV(r, a, b) ((r) = (a) / (b)) +#define jlong_MOD(r, a, b) ((r) = (a) % (b)) + +#define jlong_SHL(r, a, b) ((r) = (a) << (b)) +#define jlong_SHR(r, a, b) ((r) = (a) >> (b)) +#define jlong_USHR(r, a, b) ((r) = (julong)(a) >> (b)) +#define jlong_ISHL(r, a, b) ((r) = ((jlong)(a)) << (b)) + +#define jlong_L2I(i, l) ((i) = (int)(l)) +#define jlong_L2UI(ui, l) ((ui) =(unsigned int)(l)) +#define jlong_L2F(f, l) ((f) = (l)) +#define jlong_L2D(d, l) ((d) = (l)) + +#define jlong_I2L(l, i) ((l) = (i)) +#define jlong_UI2L(l, ui) ((l) = (ui)) +#define jlong_F2L(l, f) ((l) = (f)) +#define jlong_D2L(l, d) ((l) = (d)) + +#define jlong_UDIVMOD(qp, rp, a, b) \ + (*(qp) = ((julong)(a) / (b)), \ + *(rp) = ((julong)(a) % (b))) + +#else /* !HAVE_LONG_LONG */ + +typedef struct { +#ifdef IS_LITTLE_ENDIAN + juint lo, hi; +#else + juint hi, lo; +#endif +} jlong; +typedef jlong julong; + +extern jlong jlong_MAXINT, jlong_MININT, jlong_ZERO; + +#define jlong_IS_ZERO(a) (((a).hi == 0) && ((a).lo == 0)) +#define jlong_EQ(a, b) (((a).hi == (b).hi) && ((a).lo == (b).lo)) +#define jlong_NE(a, b) (((a).hi != (b).hi) || ((a).lo != (b).lo)) +#define jlong_GE_ZERO(a) (((a).hi >> 31) == 0) + +/* + * NB: jlong_CMP and jlong_UCMP work only for strict relationals (<, >). + */ +#define jlong_CMP(a, op, b) (((int32)(a).hi op (int32)(b).hi) || \ + (((a).hi == (b).hi) && ((a).lo op (b).lo))) +#define jlong_UCMP(a, op, b) (((a).hi op (b).hi) || \ + (((a).hi == (b).hi) && ((a).lo op (b).lo))) + +#define jlong_AND(r, a, b) ((r).lo = (a).lo & (b).lo, \ + (r).hi = (a).hi & (b).hi) +#define jlong_OR(r, a, b) ((r).lo = (a).lo | (b).lo, \ + (r).hi = (a).hi | (b).hi) +#define jlong_XOR(r, a, b) ((r).lo = (a).lo ^ (b).lo, \ + (r).hi = (a).hi ^ (b).hi) +#define jlong_OR2(r, a) ((r).lo = (r).lo | (a).lo, \ + (r).hi = (r).hi | (a).hi) +#define jlong_NOT(r, a) ((r).lo = ~(a).lo, \ + (r).hi = ~(a).hi) + +#define jlong_NEG(r, a) ((r).lo = -(int32)(a).lo, \ + (r).hi = -(int32)(a).hi - ((r).lo != 0)) +#define jlong_ADD(r, a, b) { \ + jlong _a, _b; \ + _a = a; _b = b; \ + (r).lo = _a.lo + _b.lo; \ + (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \ +} + +#define jlong_SUB(r, a, b) { \ + jlong _a, _b; \ + _a = a; _b = b; \ + (r).lo = _a.lo - _b.lo; \ + (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \ +} \ + +/* + * Multiply 64-bit operands a and b to get 64-bit result r. + * First multiply the low 32 bits of a and b to get a 64-bit result in r. + * Then add the outer and inner products to r.hi. + */ +#define jlong_MUL(r, a, b) { \ + jlong _a, _b; \ + _a = a; _b = b; \ + jlong_MUL32(r, _a.lo, _b.lo); \ + (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \ +} + +/* XXX _jlong_lo16(a) = ((a) << 16 >> 16) is better on some archs (not on mips) */ +#define _jlong_lo16(a) ((a) & JRI_BITMASK(16)) +#define _jlong_hi16(a) ((a) >> 16) + +/* + * Multiply 32-bit operands a and b to get 64-bit result r. + * Use polynomial expansion based on primitive field element (1 << 16). + */ +#define jlong_MUL32(r, a, b) { \ + juint _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \ + _a1 = _jlong_hi16(a), _a0 = _jlong_lo16(a); \ + _b1 = _jlong_hi16(b), _b0 = _jlong_lo16(b); \ + _y0 = _a0 * _b0; \ + _y1 = _a0 * _b1; \ + _y2 = _a1 * _b0; \ + _y3 = _a1 * _b1; \ + _y1 += _jlong_hi16(_y0); /* can't carry */ \ + _y1 += _y2; /* might carry */ \ + if (_y1 < _y2) _y3 += 1 << 16; /* propagate */ \ + (r).lo = (_jlong_lo16(_y1) << 16) + _jlong_lo16(_y0); \ + (r).hi = _y3 + _jlong_hi16(_y1); \ +} + +/* + * Divide 64-bit unsigned operand a by 64-bit unsigned operand b, setting *qp + * to the 64-bit unsigned quotient, and *rp to the 64-bit unsigned remainder. + * Minimize effort if one of qp and rp is null. + */ +#define jlong_UDIVMOD(qp, rp, a, b) jlong_udivmod(qp, rp, a, b) + +extern JRI_PUBLIC_API(void) +jlong_udivmod(julong *qp, julong *rp, julong a, julong b); + +#define jlong_DIV(r, a, b) { \ + jlong _a, _b; \ + juint _negative = (int32)(a).hi < 0; \ + if (_negative) { \ + jlong_NEG(_a, a); \ + } else { \ + _a = a; \ + } \ + if ((int32)(b).hi < 0) { \ + _negative ^= 1; \ + jlong_NEG(_b, b); \ + } else { \ + _b = b; \ + } \ + jlong_UDIVMOD(&(r), 0, _a, _b); \ + if (_negative) \ + jlong_NEG(r, r); \ +} + +#define jlong_MOD(r, a, b) { \ + jlong _a, _b; \ + juint _negative = (int32)(a).hi < 0; \ + if (_negative) { \ + jlong_NEG(_a, a); \ + } else { \ + _a = a; \ + } \ + if ((int32)(b).hi < 0) { \ + jlong_NEG(_b, b); \ + } else { \ + _b = b; \ + } \ + jlong_UDIVMOD(0, &(r), _a, _b); \ + if (_negative) \ + jlong_NEG(r, r); \ +} + +/* + * NB: b is a juint, not jlong or julong, for the shift ops. + */ +#define jlong_SHL(r, a, b) { \ + if (b) { \ + jlong _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = _a.lo << (b); \ + (r).hi = (_a.hi << (b)) | (_a.lo >> (32 - (b))); \ + } else { \ + (r).lo = 0; \ + (r).hi = _a.lo << ((b) & 31); \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +/* a is an int32, b is int32, r is jlong */ +#define jlong_ISHL(r, a, b) { \ + if (b) { \ + jlong _a; \ + _a.lo = (a); \ + _a.hi = 0; \ + if ((b) < 32) { \ + (r).lo = (a) << (b); \ + (r).hi = ((a) >> (32 - (b))); \ + } else { \ + (r).lo = 0; \ + (r).hi = (a) << ((b) & 31); \ + } \ + } else { \ + (r).lo = (a); \ + (r).hi = 0; \ + } \ +} + +#define jlong_SHR(r, a, b) { \ + if (b) { \ + jlong _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> (b)); \ + (r).hi = (int32)_a.hi >> (b); \ + } else { \ + (r).lo = (int32)_a.hi >> ((b) & 31); \ + (r).hi = (int32)_a.hi >> 31; \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +#define jlong_USHR(r, a, b) { \ + if (b) { \ + jlong _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> (b)); \ + (r).hi = _a.hi >> (b); \ + } else { \ + (r).lo = _a.hi >> ((b) & 31); \ + (r).hi = 0; \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +#define jlong_L2I(i, l) ((i) = (l).lo) +#define jlong_L2UI(ui, l) ((ui) = (l).lo) +#define jlong_L2F(f, l) { double _d; jlong_L2D(_d, l); (f) = (float) _d; } + +#define jlong_L2D(d, l) { \ + int32 _negative; \ + jlong _absval; \ + \ + _negative = (l).hi >> 31; \ + if (_negative) { \ + jlong_NEG(_absval, l); \ + } else { \ + _absval = l; \ + } \ + (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \ + if (_negative) \ + (d) = -(d); \ +} + +#define jlong_I2L(l, i) ((l).hi = (i) >> 31, (l).lo = (i)) +#define jlong_UI2L(l, ui) ((l).hi = 0, (l).lo = (ui)) +#define jlong_F2L(l, f) { double _d = (double) f; jlong_D2L(l, _d); } + +#define jlong_D2L(l, d) { \ + int _negative; \ + double _absval, _d_hi; \ + jlong _lo_d; \ + \ + _negative = ((d) < 0); \ + _absval = _negative ? -(d) : (d); \ + \ + (l).hi = (juint)(_absval / 4.294967296e9); \ + (l).lo = 0; \ + jlong_L2D(_d_hi, l); \ + _absval -= _d_hi; \ + _lo_d.hi = 0; \ + if (_absval < 0) { \ + _lo_d.lo = (juint) -_absval; \ + jlong_SUB(l, l, _lo_d); \ + } else { \ + _lo_d.lo = (juint) _absval; \ + jlong_ADD(l, l, _lo_d); \ + } \ + \ + if (_negative) \ + jlong_NEG(l, l); \ +} + +#endif /* !HAVE_LONG_LONG */ + +/******************************************************************************/ +/* +** JDK Stuff -- This stuff is still needed while we're using the JDK +** dynamic linking strategy to call native methods. +*/ + +typedef union JRI_JDK_stack_item { + /* Non pointer items */ + jint i; + jfloat f; + jint o; + /* Pointer items */ + void *h; + void *p; + unsigned char *addr; +#ifdef IS_64 + double d; + long l; /* == 64bits! */ +#endif +} JRI_JDK_stack_item; + +typedef union JRI_JDK_Java8Str { + jint x[2]; + jdouble d; + jlong l; + void *p; + float f; +} JRI_JDK_Java8; + +#ifdef HAVE_ALIGNED_LONGLONGS +#define JRI_GET_INT64(_t,_addr) ( ((_t).x[0] = ((jint*)(_addr))[0]), \ + ((_t).x[1] = ((jint*)(_addr))[1]), \ + (_t).l ) +#define JRI_SET_INT64(_t, _addr, _v) ( (_t).l = (_v), \ + ((jint*)(_addr))[0] = (_t).x[0], \ + ((jint*)(_addr))[1] = (_t).x[1] ) +#else +#define JRI_GET_INT64(_t,_addr) (*(jlong*)(_addr)) +#define JRI_SET_INT64(_t, _addr, _v) (*(jlong*)(_addr) = (_v)) +#endif + +/* If double's must be aligned on doubleword boundaries then define this */ +#ifdef HAVE_ALIGNED_DOUBLES +#define JRI_GET_DOUBLE(_t,_addr) ( ((_t).x[0] = ((jint*)(_addr))[0]), \ + ((_t).x[1] = ((jint*)(_addr))[1]), \ + (_t).d ) +#define JRI_SET_DOUBLE(_t, _addr, _v) ( (_t).d = (_v), \ + ((jint*)(_addr))[0] = (_t).x[0], \ + ((jint*)(_addr))[1] = (_t).x[1] ) +#else +#define JRI_GET_DOUBLE(_t,_addr) (*(jdouble*)(_addr)) +#define JRI_SET_DOUBLE(_t, _addr, _v) (*(jdouble*)(_addr) = (_v)) +#endif + +/******************************************************************************/ +#ifdef __cplusplus +} +#endif +#endif /* JRI_MD_H */ +/******************************************************************************/ diff --git a/extensions/nsplugin/src/jritypes.h b/extensions/nsplugin/src/jritypes.h new file mode 100644 index 0000000..fad21c7 --- /dev/null +++ b/extensions/nsplugin/src/jritypes.h @@ -0,0 +1,180 @@ +/* -*- Mode: C; tab-width: 4; -*- */ +/******************************************************************************* + * Java Runtime Interface + * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. + ******************************************************************************/ + +#ifndef JRITYPES_H +#define JRITYPES_H + +#include "jri_md.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Types + ******************************************************************************/ + +struct JRIEnvInterface; + +typedef void* JRIRef; +typedef void* JRIGlobalRef; + +typedef jint JRIInterfaceID[4]; +typedef jint JRIFieldID; +typedef jint JRIMethodID; + +/* synonyms: */ +typedef JRIGlobalRef jglobal; +typedef JRIRef jref; + +typedef union JRIValue { + jbool z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong l; + jfloat f; + jdouble d; + jref r; +} JRIValue; + +typedef JRIValue jvalue; + +typedef enum JRIBoolean { + JRIFalse = 0, + JRITrue = 1 +} JRIBoolean; + +typedef enum JRIConstant { + JRIUninitialized = -1 +} JRIConstant; + +/* convenience types: */ +typedef JRIRef jbooleanArray; +typedef JRIRef jbyteArray; +typedef JRIRef jcharArray; +typedef JRIRef jshortArray; +typedef JRIRef jintArray; +typedef JRIRef jlongArray; +typedef JRIRef jfloatArray; +typedef JRIRef jdoubleArray; +typedef JRIRef jobjectArray; +typedef JRIRef jstringArray; +typedef JRIRef jarrayArray; + +#define JRIConstructorMethodName "" + +/******************************************************************************* + * Signature Construction Macros + ******************************************************************************/ + +/* +** These macros can be used to construct signature strings. Hopefully their names +** are a little easier to remember than the single character they correspond to. +** For example, to specify the signature of the method: +** +** public int read(byte b[], int off, int len); +** +** you could write something like this in C: +** +** char* readSig = JRISigMethod(JRISigArray(JRISigByte) +** JRISigInt +** JRISigInt) JRISigInt; +** +** Of course, don't put commas between the types. +*/ +#define JRISigArray(T) "[" T +#define JRISigByte "B" +#define JRISigChar "C" +#define JRISigClass(name) "L" name ";" +#define JRISigFloat "F" +#define JRISigDouble "D" +#define JRISigMethod(args) "(" args ")" +#define JRISigNoArgs "" +#define JRISigInt "I" +#define JRISigLong "J" +#define JRISigShort "S" +#define JRISigVoid "V" +#define JRISigBoolean "Z" + +/******************************************************************************* + * Environments + ******************************************************************************/ + +extern JRI_PUBLIC_API(const struct JRIEnvInterface**) +JRI_GetCurrentEnv(void); + +/******************************************************************************* + * Specific Scalar Array Types + ******************************************************************************/ + +/* +** The JRI Native Method Interface does not support boolean arrays. This +** is to allow Java runtime implementations to optimize boolean array +** storage. Using the ScalarArray operations on boolean arrays is bound +** to fail, so convert any boolean arrays to byte arrays in Java before +** passing them to a native method. +*/ + +#define JRI_NewByteArray(env, length, initialValues) \ + JRI_NewScalarArray(env, length, JRISigByte, (jbyte*)(initialValues)) +#define JRI_GetByteArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetByteArrayElements(env, array) \ + JRI_GetScalarArrayElements(env, array) + +#define JRI_NewCharArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jchar)), JRISigChar, (jbyte*)(initialValues)) +#define JRI_GetCharArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetCharArrayElements(env, array) \ + ((jchar*)JRI_GetScalarArrayElements(env, array)) + +#define JRI_NewShortArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jshort)), JRISigShort, (jbyte*)(initialValues)) +#define JRI_GetShortArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetShortArrayElements(env, array) \ + ((jshort*)JRI_GetScalarArrayElements(env, array)) + +#define JRI_NewIntArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jint)), JRISigInt, (jbyte*)(initialValues)) +#define JRI_GetIntArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetIntArrayElements(env, array) \ + ((jint*)JRI_GetScalarArrayElements(env, array)) + +#define JRI_NewLongArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jlong)), JRISigLong, (jbyte*)(initialValues)) +#define JRI_GetLongArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetLongArrayElements(env, array) \ + ((jlong*)JRI_GetScalarArrayElements(env, array)) + +#define JRI_NewFloatArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jfloat)), JRISigFloat, (jbyte*)(initialValues)) +#define JRI_GetFloatArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetFloatArrayElements(env, array) \ + ((jfloat*)JRI_GetScalarArrayElements(env, array)) + +#define JRI_NewDoubleArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jdouble)), JRISigDouble, (jbyte*)(initialValues)) +#define JRI_GetDoubleArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetDoubleArrayElements(env, array) \ + ((jdouble*)JRI_GetScalarArrayElements(env, array)) + +/******************************************************************************/ +#ifdef __cplusplus +} +#endif +#endif /* JRITYPES_H */ +/******************************************************************************/ diff --git a/extensions/nsplugin/src/npapi.h b/extensions/nsplugin/src/npapi.h new file mode 100644 index 0000000..b757ff3 --- /dev/null +++ b/extensions/nsplugin/src/npapi.h @@ -0,0 +1,392 @@ +/* -*- Mode: C; tab-width: 4; -*- */ +/* + * npapi.h $Revision: 1.1 $ + * Netscape client plug-in API spec + */ + +#ifndef _NPAPI_H_ +#define _NPAPI_H_ + +#include "jri.h" /* Java Runtime Interface */ + + +/* XXX this needs to get out of here */ +#if defined(__MWERKS__) +#ifndef XP_MAC +#define XP_MAC +#endif +#endif + + + +/*----------------------------------------------------------------------*/ +/* Plugin Version Constants */ +/*----------------------------------------------------------------------*/ + +#define NP_VERSION_MAJOR 0 +#define NP_VERSION_MINOR 9 + + + +/*----------------------------------------------------------------------*/ +/* Definition of Basic Types */ +/*----------------------------------------------------------------------*/ + +#ifndef _UINT16 +typedef unsigned short uint16; +#endif +#ifndef _UINT32 +#if defined(__alpha) +typedef unsigned int uint32; +#else /* __alpha */ +typedef unsigned long uint32; +#endif /* __alpha */ +#endif +#ifndef _INT16 +typedef short int16; +#endif +#ifndef _INT32 +#if defined(__alpha) +typedef int int32; +#else /* __alpha */ +typedef long int32; +#endif /* __alpha */ +#endif + +#ifndef FALSE +#define FALSE (0) +#endif +#ifndef TRUE +#define TRUE (1) +#endif +#ifndef NULL +#define NULL (0L) +#endif + +typedef unsigned char NPBool; +typedef void* NPEvent; +typedef int16 NPError; +typedef int16 NPReason; +typedef char* NPMIMEType; + + + +/*----------------------------------------------------------------------*/ +/* Structures and definitions */ +/*----------------------------------------------------------------------*/ + +/* + * NPP is a plug-in's opaque instance handle + */ +typedef struct _NPP +{ + void* pdata; /* plug-in private data */ + void* ndata; /* netscape private data */ +} NPP_t; + +typedef NPP_t* NPP; + + +typedef struct _NPStream +{ + void* pdata; /* plug-in private data */ + void* ndata; /* netscape private data */ + const char* url; + uint32 end; + uint32 lastmodified; + void* notifyData; +} NPStream; + + +typedef struct _NPByteRange +{ + int32 offset; /* negative offset means from the end */ + uint32 length; + struct _NPByteRange* next; +} NPByteRange; + + +typedef struct _NPSavedData +{ + int32 len; + void* buf; +} NPSavedData; + + +typedef struct _NPRect +{ + uint16 top; + uint16 left; + uint16 bottom; + uint16 right; +} NPRect; + + +#ifdef XP_UNIX +/* + * Unix specific structures and definitions + */ +#include + +/* + * Callback Structures. + * + * These are used to pass additional platform specific information. + */ +enum { + NP_SETWINDOW = 1 +}; + +typedef struct +{ + int32 type; +} NPAnyCallbackStruct; + +typedef struct +{ + int32 type; + Display* display; + Visual* visual; + Colormap colormap; + unsigned int depth; +} NPSetWindowCallbackStruct; + +/* + * List of variable names for which NPP_GetValue shall be implemented + */ +typedef enum { + NPPVpluginNameString = 1, + NPPVpluginDescriptionString +} NPPVariable; + +/* + * List of variable names for which NPN_GetValue is implemented by Mozilla + */ +typedef enum { + NPNVxDisplay = 1, + NPNVxtAppContext +} NPNVariable; + +#endif /* XP_UNIX */ + + +typedef struct _NPWindow +{ + void* window; /* Platform specific window handle */ + uint32 x; /* Position of top left corner relative */ + uint32 y; /* to a netscape page. */ + uint32 width; /* Maximum window size */ + uint32 height; + NPRect clipRect; /* Clipping rectangle in port coordinates */ + /* Used by MAC only. */ +#ifdef XP_UNIX + void * ws_info; /* Platform-dependent additonal data */ +#endif /* XP_UNIX */ +} NPWindow; + + +typedef struct _NPFullPrint +{ + NPBool pluginPrinted; /* Set TRUE if plugin handled fullscreen */ + /* printing */ + NPBool printOne; /* TRUE if plugin should print one copy */ + /* to default printer */ + void* platformPrint; /* Platform-specific printing info */ +} NPFullPrint; + +typedef struct _NPEmbedPrint +{ + NPWindow window; + void* platformPrint; /* Platform-specific printing info */ +} NPEmbedPrint; + +typedef struct _NPPrint +{ + uint16 mode; /* NP_FULL or NP_EMBED */ + union + { + NPFullPrint fullPrint; /* if mode is NP_FULL */ + NPEmbedPrint embedPrint; /* if mode is NP_EMBED */ + } print; +} NPPrint; + + +#ifdef XP_MAC +/* + * Mac-specific structures and definitions. + */ + +#include +#include + +typedef struct NP_Port +{ + CGrafPtr port; /* Grafport */ + int32 portx; /* position inside the topmost window */ + int32 porty; +} NP_Port; + +/* + * Non-standard event types that can be passed to HandleEvent + */ +#define getFocusEvent (osEvt + 16) +#define loseFocusEvent (osEvt + 17) +#define adjustCursorEvent (osEvt + 18) + +#endif /* XP_MAC */ + + +/* + * Values for mode passed to NPP_New: + */ +#define NP_EMBED 1 +#define NP_FULL 2 + +/* + * Values for stream type passed to NPP_NewStream: + */ +#define NP_NORMAL 1 +#define NP_SEEK 2 +#define NP_ASFILE 3 +#define NP_ASFILEONLY 4 + +#define NP_MAXREADY (((unsigned)(~0)<<1)>>1) + + + +/*----------------------------------------------------------------------*/ +/* Error and Reason Code definitions */ +/*----------------------------------------------------------------------*/ + +/* + * Values of type NPError: + */ +#define NPERR_BASE 0 +#define NPERR_NO_ERROR (NPERR_BASE + 0) +#define NPERR_GENERIC_ERROR (NPERR_BASE + 1) +#define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2) +#define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3) +#define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4) +#define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5) +#define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6) +#define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7) +#define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8) +#define NPERR_INVALID_PARAM (NPERR_BASE + 9) +#define NPERR_INVALID_URL (NPERR_BASE + 10) +#define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11) +#define NPERR_NO_DATA (NPERR_BASE + 12) +#define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13) + +/* + * Values of type NPReason: + */ +#define NPRES_BASE 0 +#define NPRES_DONE (NPRES_BASE + 0) +#define NPRES_NETWORK_ERR (NPRES_BASE + 1) +#define NPRES_USER_BREAK (NPRES_BASE + 2) + +/* + * Don't use these obsolete error codes any more. + */ +#define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR +#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR +#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK + +/* + * Version feature information + */ +#define NPVERS_HAS_STREAMOUTPUT 8 +#define NPVERS_HAS_NOTIFICATION 9 +#define NPVERS_HAS_LIVECONNECT 9 + + +/*----------------------------------------------------------------------*/ +/* Function Prototypes */ +/*----------------------------------------------------------------------*/ + +#if defined(_WINDOWS) && !defined(WIN32) +#define NP_LOADDS _loadds +#else +#define NP_LOADDS +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * NPP_* functions are provided by the plugin and called by the navigator. + */ + +#ifdef XP_UNIX +char* NPP_GetMIMEDescription(void); +NPError NPP_GetValue(void *instance, NPPVariable variable, + void *value); +#endif /* XP_UNIX */ +NPError NPP_Initialize(void); +void NPP_Shutdown(void); +NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance, + uint16 mode, int16 argc, char* argn[], + char* argv[], NPSavedData* saved); +NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save); +NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window); +NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type, + NPStream* stream, NPBool seekable, + uint16* stype); +NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream, + NPReason reason); +int32 NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream); +int32 NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32 offset, + int32 len, void* buffer); +void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream, + const char* fname); +void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint); +int16 NPP_HandleEvent(NPP instance, void* event); +void NPP_URLNotify(NPP instance, const char* url, + NPReason reason, void* notifyData); +jref NPP_GetJavaClass(void); + + +/* + * NPN_* functions are provided by the navigator and called by the plugin. + */ + +#ifdef XP_UNIX +NPError NPN_GetValue(NPP instance, NPNVariable variable, + void *value); +#endif /* XP_UNIX */ +void NPN_Version(int* plugin_major, int* plugin_minor, + int* netscape_major, int* netscape_minor); +NPError NPN_GetURLNotify(NPP instance, const char* url, + const char* target, void* notifyData); +NPError NPN_GetURL(NPP instance, const char* url, + const char* target); +NPError NPN_PostURLNotify(NPP instance, const char* url, + const char* target, uint32 len, + const char* buf, NPBool file, + void* notifyData); +NPError NPN_PostURL(NPP instance, const char* url, + const char* target, uint32 len, + const char* buf, NPBool file); +NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList); +NPError NPN_NewStream(NPP instance, NPMIMEType type, + const char* target, NPStream** stream); +int32 NPN_Write(NPP instance, NPStream* stream, int32 len, + void* buffer); +NPError NPN_DestroyStream(NPP instance, NPStream* stream, + NPReason reason); +void NPN_Status(NPP instance, const char* message); +const char* NPN_UserAgent(NPP instance); +void* NPN_MemAlloc(uint32 size); +void NPN_MemFree(void* ptr); +uint32 NPN_MemFlush(uint32 size); +void NPN_ReloadPlugins(NPBool reloadPages); +JRIEnv* NPN_GetJavaEnv(void); +jref NPN_GetJavaPeer(NPP instance); + + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +#endif /* _NPAPI_H_ */ diff --git a/extensions/nsplugin/src/npunix.c b/extensions/nsplugin/src/npunix.c new file mode 100644 index 0000000..0f9ae9b --- /dev/null +++ b/extensions/nsplugin/src/npunix.c @@ -0,0 +1,407 @@ +/* + * npunix.c + * + * Netscape Client Plugin API + * - Wrapper function to interface with the Netscape Navigator + * + * dp Suresh + * + *---------------------------------------------------------------------- + * PLUGIN DEVELOPERS: + * YOU WILL NOT NEED TO EDIT THIS FILE. + *---------------------------------------------------------------------- + */ + +#define XP_UNIX 1 + +#include +#include "npapi.h" +#include "npupp.h" + +/* + * Define PLUGIN_TRACE to have the wrapper functions print + * messages to fd 3 or 4 (cannot use stderr - ns3 grabs that) + * whenever they are called. + */ + +#ifdef PLUGIN_TRACE +#include +#define PLUGINDEBUGSTR(msg) fprintf(out(), "%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_GetURL(NPP instance, const char* url, const char* window) +{ + return CallNPN_GetURLProc(gNetscapeFuncs.geturl, instance, url, window); +} + +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_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); +} + +JRIEnv* NPN_GetJavaEnv() +{ + return CallNPN_GetJavaEnvProc(gNetscapeFuncs.getJavaEnv); +} + +jref NPN_GetJavaPeer(NPP instance) +{ + return CallNPN_GetJavaPeerProc(gNetscapeFuncs.getJavaPeer, + instance); +} + + +/*********************************************************************** + * + * 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_Print(NPP instance, NPPrint* platformPrint) +{ + PLUGINDEBUGSTR("Print"); + NPP_Print(instance, platformPrint); +} + +JRIGlobalRef +Private_GetJavaClass(void) +{ + jref clazz = NPP_GetJavaClass(); + if (clazz) { + JRIEnv* env = NPN_GetJavaEnv(); + return JRI_NewGlobalRef(env, clazz); + } + return NULL; +} + +/*********************************************************************** + * + * 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 dont 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 < sizeof(NPNetscapeFuncs)) + 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.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; + gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv; + gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer; + gNetscapeFuncs.getvalue = nsTable->getvalue; + + /* + * 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->event = NULL; + pluginFuncs->javaClass = Private_GetJavaClass(); + + 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 --git a/extensions/nsplugin/src/npupp.h b/extensions/nsplugin/src/npupp.h new file mode 100644 index 0000000..eb68194 --- /dev/null +++ b/extensions/nsplugin/src/npupp.h @@ -0,0 +1,995 @@ +/* -*- Mode: C; tab-width: 4; -*- */ +/* + * npupp.h $Revision: 1.1 $ + * function call mecahnics needed by platform specific glue code. + */ + + +#ifndef _NPUPP_H_ +#define _NPUPP_H_ + +#ifndef GENERATINGCFM +#define GENERATINGCFM 0 +#endif + +#ifndef _NPAPI_H_ +#include "npapi.h" +#endif + +#include "jri.h" + +/****************************************************************************************** + plug-in function table macros + for each function in and out of the plugin API we define + typedef NPP_FooUPP + #define NewNPP_FooProc + #define CallNPP_FooProc + for mac, define the UPP magic for PPC/68K calling + *******************************************************************************************/ + + +/* NPP_Initialize */ + +#if GENERATINGCFM +typedef UniversalProcPtr NPP_InitializeUPP; + +enum { + uppNPP_InitializeProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(0)) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPP_InitializeProc(FUNC) \ + (NPP_InitializeUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_InitializeProcInfo, GetCurrentArchitecture()) +#define CallNPP_InitializeProc(FUNC) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_InitializeProcInfo) + +#else + +typedef void (*NPP_InitializeUPP)(void); +#define NewNPP_InitializeProc(FUNC) \ + ((NPP_InitializeUPP) (FUNC)) +#define CallNPP_InitializeProc(FUNC) \ + (*(FUNC))() + +#endif + + +/* NPP_Shutdown */ + +#if GENERATINGCFM +typedef UniversalProcPtr NPP_ShutdownUPP; + +enum { + uppNPP_ShutdownProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(0)) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPP_ShutdownProc(FUNC) \ + (NPP_ShutdownUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_ShutdownProcInfo, GetCurrentArchitecture()) +#define CallNPP_ShutdownProc(FUNC) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_ShutdownProcInfo) + +#else + +typedef void (*NPP_ShutdownUPP)(void); +#define NewNPP_ShutdownProc(FUNC) \ + ((NPP_ShutdownUPP) (FUNC)) +#define CallNPP_ShutdownProc(FUNC) \ + (*(FUNC))() + +#endif + + +/* NPP_New */ + +#if GENERATINGCFM +typedef UniversalProcPtr NPP_NewUPP; + +enum { + uppNPP_NewProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPMIMEType))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(uint16))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(int16))) + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(char **))) + | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(char **))) + | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(NPSavedData *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; + +#define NewNPP_NewProc(FUNC) \ + (NPP_NewUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_NewProcInfo, GetCurrentArchitecture()) +#define CallNPP_NewProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_NewProcInfo, \ + (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) +#else + +typedef NPError (*NPP_NewUPP)(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved); +#define NewNPP_NewProc(FUNC) \ + ((NPP_NewUPP) (FUNC)) +#define CallNPP_NewProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) + +#endif + + +/* NPP_Destroy */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_DestroyUPP; +enum { + uppNPP_DestroyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPSavedData **))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_DestroyProc(FUNC) \ + (NPP_DestroyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_DestroyProcInfo, GetCurrentArchitecture()) +#define CallNPP_DestroyProc(FUNC, ARG1, ARG2) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_DestroyProcInfo, (ARG1), (ARG2)) +#else + +typedef NPError (*NPP_DestroyUPP)(NPP instance, NPSavedData** save); +#define NewNPP_DestroyProc(FUNC) \ + ((NPP_DestroyUPP) (FUNC)) +#define CallNPP_DestroyProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +#endif + + +/* NPP_SetWindow */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_SetWindowUPP; +enum { + uppNPP_SetWindowProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPWindow *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_SetWindowProc(FUNC) \ + (NPP_SetWindowUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_SetWindowProcInfo, GetCurrentArchitecture()) +#define CallNPP_SetWindowProc(FUNC, ARG1, ARG2) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_SetWindowProcInfo, (ARG1), (ARG2)) + +#else + +typedef NPError (*NPP_SetWindowUPP)(NPP instance, NPWindow* window); +#define NewNPP_SetWindowProc(FUNC) \ + ((NPP_SetWindowUPP) (FUNC)) +#define CallNPP_SetWindowProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +#endif + + +/* NPP_NewStream */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_NewStreamUPP; +enum { + uppNPP_NewStreamProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPMIMEType))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(NPBool))) + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(uint16 *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_NewStreamProc(FUNC) \ + (NPP_NewStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_NewStreamProcInfo, GetCurrentArchitecture()) +#define CallNPP_NewStreamProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_NewStreamProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) +#else + +typedef NPError (*NPP_NewStreamUPP)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype); +#define NewNPP_NewStreamProc(FUNC) \ + ((NPP_NewStreamUPP) (FUNC)) +#define CallNPP_NewStreamProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) +#endif + + +/* NPP_DestroyStream */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_DestroyStreamUPP; +enum { + uppNPP_DestroyStreamProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_DestroyStreamProc(FUNC) \ + (NPP_DestroyStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_DestroyStreamProcInfo, GetCurrentArchitecture()) +#define CallNPP_DestroyStreamProc(FUNC, NPParg, NPStreamPtr, NPReasonArg) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_DestroyStreamProcInfo, (NPParg), (NPStreamPtr), (NPReasonArg)) + +#else + +typedef NPError (*NPP_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason); +#define NewNPP_DestroyStreamProc(FUNC) \ + ((NPP_DestroyStreamUPP) (FUNC)) +#define CallNPP_DestroyStreamProc(FUNC, NPParg, NPStreamPtr, NPReasonArg) \ + (*(FUNC))((NPParg), (NPStreamPtr), (NPReasonArg)) + +#endif + + +/* NPP_WriteReady */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_WriteReadyUPP; +enum { + uppNPP_WriteReadyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | RESULT_SIZE(SIZE_CODE(sizeof(int32))) +}; +#define NewNPP_WriteReadyProc(FUNC) \ + (NPP_WriteReadyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_WriteReadyProcInfo, GetCurrentArchitecture()) +#define CallNPP_WriteReadyProc(FUNC, NPParg, NPStreamPtr) \ + (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_WriteReadyProcInfo, (NPParg), (NPStreamPtr)) + +#else + +typedef int32 (*NPP_WriteReadyUPP)(NPP instance, NPStream* stream); +#define NewNPP_WriteReadyProc(FUNC) \ + ((NPP_WriteReadyUPP) (FUNC)) +#define CallNPP_WriteReadyProc(FUNC, NPParg, NPStreamPtr) \ + (*(FUNC))((NPParg), (NPStreamPtr)) + +#endif + + +/* NPP_Write */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_WriteUPP; +enum { + uppNPP_WriteProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(int32))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(int32))) + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(void*))) + | RESULT_SIZE(SIZE_CODE(sizeof(int32))) +}; +#define NewNPP_WriteProc(FUNC) \ + (NPP_WriteUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_WriteProcInfo, GetCurrentArchitecture()) +#define CallNPP_WriteProc(FUNC, NPParg, NPStreamPtr, offsetArg, lenArg, bufferPtr) \ + (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_WriteProcInfo, (NPParg), (NPStreamPtr), (offsetArg), (lenArg), (bufferPtr)) + +#else + +typedef int32 (*NPP_WriteUPP)(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer); +#define NewNPP_WriteProc(FUNC) \ + ((NPP_WriteUPP) (FUNC)) +#define CallNPP_WriteProc(FUNC, NPParg, NPStreamPtr, offsetArg, lenArg, bufferPtr) \ + (*(FUNC))((NPParg), (NPStreamPtr), (offsetArg), (lenArg), (bufferPtr)) + +#endif + + +/* NPP_StreamAsFile */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_StreamAsFileUPP; +enum { + uppNPP_StreamAsFileProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char *))) + | RESULT_SIZE(SIZE_CODE(0)) +}; +#define NewNPP_StreamAsFileProc(FUNC) \ + (NPP_StreamAsFileUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_StreamAsFileProcInfo, GetCurrentArchitecture()) +#define CallNPP_StreamAsFileProc(FUNC, ARG1, ARG2, ARG3) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_StreamAsFileProcInfo, (ARG1), (ARG2), (ARG3)) + +#else + +typedef void (*NPP_StreamAsFileUPP)(NPP instance, NPStream* stream, const char* fname); +#define NewNPP_StreamAsFileProc(FUNC) \ + ((NPP_StreamAsFileUPP) (FUNC)) +#define CallNPP_StreamAsFileProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) +#endif + + +/* NPP_Print */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_PrintUPP; +enum { + uppNPP_PrintProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPPrint *))) + | RESULT_SIZE(SIZE_CODE(0)) +}; +#define NewNPP_PrintProc(FUNC) \ + (NPP_PrintUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_PrintProcInfo, GetCurrentArchitecture()) +#define CallNPP_PrintProc(FUNC, NPParg, voidPtr) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_PrintProcInfo, (NPParg), (voidPtr)) + +#else + +typedef void (*NPP_PrintUPP)(NPP instance, NPPrint* platformPrint); +#define NewNPP_PrintProc(FUNC) \ + ((NPP_PrintUPP) (FUNC)) +#define CallNPP_PrintProc(FUNC, NPParg, NPPrintArg) \ + (*(FUNC))((NPParg), (NPPrintArg)) + +#endif + + +/* NPP_HandleEvent */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_HandleEventUPP; +enum { + uppNPP_HandleEventProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(void *))) + | RESULT_SIZE(SIZE_CODE(sizeof(int16))) +}; +#define NewNPP_HandleEventProc(FUNC) \ + (NPP_HandleEventUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_HandleEventProcInfo, GetCurrentArchitecture()) +#define CallNPP_HandleEventProc(FUNC, NPParg, voidPtr) \ + (int16)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_HandleEventProcInfo, (NPParg), (voidPtr)) + +#else + +typedef int16 (*NPP_HandleEventUPP)(NPP instance, void* event); +#define NewNPP_HandleEventProc(FUNC) \ + ((NPP_HandleEventUPP) (FUNC)) +#define CallNPP_HandleEventProc(FUNC, NPParg, voidPtr) \ + (*(FUNC))((NPParg), (voidPtr)) + +#endif + + +/* NPP_URLNotify */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_URLNotifyUPP; +enum { + uppNPP_URLNotifyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*))) + | RESULT_SIZE(SIZE_CODE(SIZE_CODE(0))) +}; +#define NewNPP_URLNotifyProc(FUNC) \ + (NPP_URLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_URLNotifyProcInfo, GetCurrentArchitecture()) +#define CallNPP_URLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_URLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4)) + +#else + +typedef void (*NPP_URLNotifyUPP)(NPP instance, const char* url, NPReason reason, void* notifyData); +#define NewNPP_URLNotifyProc(FUNC) \ + ((NPP_URLNotifyUPP) (FUNC)) +#define CallNPP_URLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) + +#endif + + + + +/* + * Netscape entry points + */ + +#ifdef XP_UNIX + +/* NPN_GetValue */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_GetValueUPP; +enum { + uppNPN_GetValueProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPNVariable))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_GetValueProc(FUNC) \ + (NPN_GetValueUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetValueProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetURNotifyLProc(FUNC, ARG1, ARG2, ARG3) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetValueProcInfo, (ARG1), (ARG2), (ARG3)) +#else + +typedef NPError (*NPN_GetValueUPP)(NPP instance, NPNVariable variable, void *ret_alue); +#define NewNPN_GetValueProc(FUNC) \ + ((NPN_GetValueUPP) (FUNC)) +#define CallNPN_GetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) +#endif + +#endif /* XP_UNIX */ + + + +/* NPN_GetUrlNotify */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_GetURLNotifyUPP; +enum { + uppNPN_GetURLNotifyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_GetURLNotifyProc(FUNC) \ + (NPN_GetURLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetURLNotifyProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetURLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4)) +#else + +typedef NPError (*NPN_GetURLNotifyUPP)(NPP instance, const char* url, const char* window, void* notifyData); +#define NewNPN_GetURLNotifyProc(FUNC) \ + ((NPN_GetURLNotifyUPP) (FUNC)) +#define CallNPN_GetURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) +#endif + + +/* NPN_PostUrlNotify */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_PostURLNotifyUPP; +enum { + uppNPN_PostURLNotifyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(uint32))) + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(NPBool))) + | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(void*))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_PostURLNotifyProc(FUNC) \ + (NPN_PostURLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_PostURLNotifyProcInfo, GetCurrentArchitecture()) +#define CallNPN_PostURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_PostURLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) +#else + +typedef NPError (*NPN_PostURLNotifyUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData); +#define NewNPN_PostURLNotifyProc(FUNC) \ + ((NPN_PostURLNotifyUPP) (FUNC)) +#define CallNPN_PostURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) +#endif + + +/* NPN_GetUrl */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_GetURLUPP; +enum { + uppNPN_GetURLProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_GetURLProc(FUNC) \ + (NPN_GetURLUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetURLProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetURLProc(FUNC, ARG1, ARG2, ARG3) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetURLProcInfo, (ARG1), (ARG2), (ARG3)) +#else + +typedef NPError (*NPN_GetURLUPP)(NPP instance, const char* url, const char* window); +#define NewNPN_GetURLProc(FUNC) \ + ((NPN_GetURLUPP) (FUNC)) +#define CallNPN_GetURLProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) +#endif + + +/* NPN_PostUrl */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_PostURLUPP; +enum { + uppNPN_PostURLProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(uint32))) + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(NPBool))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_PostURLProc(FUNC) \ + (NPN_PostURLUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_PostURLProcInfo, GetCurrentArchitecture()) +#define CallNPN_PostURLProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_PostURLProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6)) +#else + +typedef NPError (*NPN_PostURLUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file); +#define NewNPN_PostURLProc(FUNC) \ + ((NPN_PostURLUPP) (FUNC)) +#define CallNPN_PostURLProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6)) +#endif + + +/* NPN_RequestRead */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_RequestReadUPP; +enum { + uppNPN_RequestReadProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPByteRange *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_RequestReadProc(FUNC) \ + (NPN_RequestReadUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_RequestReadProcInfo, GetCurrentArchitecture()) +#define CallNPN_RequestReadProc(FUNC, stream, range) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_RequestReadProcInfo, (stream), (range)) + +#else + +typedef NPError (*NPN_RequestReadUPP)(NPStream* stream, NPByteRange* rangeList); +#define NewNPN_RequestReadProc(FUNC) \ + ((NPN_RequestReadUPP) (FUNC)) +#define CallNPN_RequestReadProc(FUNC, stream, range) \ + (*(FUNC))((stream), (range)) + +#endif + + +/* NPN_NewStream */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_NewStreamUPP; +enum { + uppNPN_NewStreamProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPMIMEType))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char *))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(NPStream **))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_NewStreamProc(FUNC) \ + (NPN_NewStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_NewStreamProcInfo, GetCurrentArchitecture()) +#define CallNPN_NewStreamProc(FUNC, npp, type, window, stream) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_NewStreamProcInfo, (npp), (type), (window), (stream)) + +#else + +typedef NPError (*NPN_NewStreamUPP)(NPP instance, NPMIMEType type, const char* window, NPStream** stream); +#define NewNPN_NewStreamProc(FUNC) \ + ((NPN_NewStreamUPP) (FUNC)) +#define CallNPN_NewStreamProc(FUNC, npp, type, window, stream) \ + (*(FUNC))((npp), (type), (window), (stream)) + +#endif + + +/* NPN_Write */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_WriteUPP; +enum { + uppNPN_WriteProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(int32))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*))) + | RESULT_SIZE(SIZE_CODE(sizeof(int32))) +}; +#define NewNPN_WriteProc(FUNC) \ + (NPN_WriteUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_WriteProcInfo, GetCurrentArchitecture()) +#define CallNPN_WriteProc(FUNC, npp, stream, len, buffer) \ + (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_WriteProcInfo, (npp), (stream), (len), (buffer)) + +#else + +typedef int32 (*NPN_WriteUPP)(NPP instance, NPStream* stream, int32 len, void* buffer); +#define NewNPN_WriteProc(FUNC) \ + ((NPN_WriteUPP) (FUNC)) +#define CallNPN_WriteProc(FUNC, npp, stream, len, buffer) \ + (*(FUNC))((npp), (stream), (len), (buffer)) + +#endif + + +/* NPN_DestroyStream */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_DestroyStreamUPP; +enum { + uppNPN_DestroyStreamProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP ))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_DestroyStreamProc(FUNC) \ + (NPN_DestroyStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_DestroyStreamProcInfo, GetCurrentArchitecture()) +#define CallNPN_DestroyStreamProc(FUNC, npp, stream, reason) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_DestroyStreamProcInfo, (npp), (stream), (reason)) + +#else + +typedef NPError (*NPN_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason); +#define NewNPN_DestroyStreamProc(FUNC) \ + ((NPN_DestroyStreamUPP) (FUNC)) +#define CallNPN_DestroyStreamProc(FUNC, npp, stream, reason) \ + (*(FUNC))((npp), (stream), (reason)) + +#endif + + +/* NPN_Status */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_StatusUPP; +enum { + uppNPN_StatusProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(char *))) +}; + +#define NewNPN_StatusProc(FUNC) \ + (NPN_StatusUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_StatusProcInfo, GetCurrentArchitecture()) +#define CallNPN_StatusProc(FUNC, npp, msg) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_StatusProcInfo, (npp), (msg)) + +#else + +typedef void (*NPN_StatusUPP)(NPP instance, const char* message); +#define NewNPN_StatusProc(FUNC) \ + ((NPN_StatusUPP) (FUNC)) +#define CallNPN_StatusProc(FUNC, npp, msg) \ + (*(FUNC))((npp), (msg)) + +#endif + + +/* NPN_UserAgent */ +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_UserAgentUPP; +enum { + uppNPN_UserAgentProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | RESULT_SIZE(SIZE_CODE(sizeof(const char *))) +}; + +#define NewNPN_UserAgentProc(FUNC) \ + (NPN_UserAgentUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_UserAgentProcInfo, GetCurrentArchitecture()) +#define CallNPN_UserAgentProc(FUNC, ARG1) \ + (const char*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_UserAgentProcInfo, (ARG1)) + +#else + +typedef const char* (*NPN_UserAgentUPP)(NPP instance); +#define NewNPN_UserAgentProc(FUNC) \ + ((NPN_UserAgentUPP) (FUNC)) +#define CallNPN_UserAgentProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + +/* NPN_MemAlloc */ +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_MemAllocUPP; +enum { + uppNPN_MemAllocProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(uint32))) + | RESULT_SIZE(SIZE_CODE(sizeof(void *))) +}; + +#define NewNPN_MemAllocProc(FUNC) \ + (NPN_MemAllocUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemAllocProcInfo, GetCurrentArchitecture()) +#define CallNPN_MemAllocProc(FUNC, ARG1) \ + (void*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemAllocProcInfo, (ARG1)) + +#else + +typedef void* (*NPN_MemAllocUPP)(uint32 size); +#define NewNPN_MemAllocProc(FUNC) \ + ((NPN_MemAllocUPP) (FUNC)) +#define CallNPN_MemAllocProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + +/* NPN__MemFree */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_MemFreeUPP; +enum { + uppNPN_MemFreeProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(void *))) +}; + +#define NewNPN_MemFreeProc(FUNC) \ + (NPN_MemFreeUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemFreeProcInfo, GetCurrentArchitecture()) +#define CallNPN_MemFreeProc(FUNC, ARG1) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemFreeProcInfo, (ARG1)) + +#else + +typedef void (*NPN_MemFreeUPP)(void* ptr); +#define NewNPN_MemFreeProc(FUNC) \ + ((NPN_MemFreeUPP) (FUNC)) +#define CallNPN_MemFreeProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + +/* NPN_MemFlush */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_MemFlushUPP; +enum { + uppNPN_MemFlushProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(uint32))) + | RESULT_SIZE(SIZE_CODE(sizeof(uint32))) +}; + +#define NewNPN_MemFlushProc(FUNC) \ + (NPN_MemFlushUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemFlushProcInfo, GetCurrentArchitecture()) +#define CallNPN_MemFlushProc(FUNC, ARG1) \ + (uint32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemFlushProcInfo, (ARG1)) + +#else + +typedef uint32 (*NPN_MemFlushUPP)(uint32 size); +#define NewNPN_MemFlushProc(FUNC) \ + ((NPN_MemFlushUPP) (FUNC)) +#define CallNPN_MemFlushProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + + +/* NPN_ReloadPlugins */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_ReloadPluginsUPP; +enum { + uppNPN_ReloadPluginsProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPBool))) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPN_ReloadPluginsProc(FUNC) \ + (NPN_ReloadPluginsUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_ReloadPluginsProcInfo, GetCurrentArchitecture()) +#define CallNPN_ReloadPluginsProc(FUNC, ARG1) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_ReloadPluginsProcInfo, (ARG1)) + +#else + +typedef void (*NPN_ReloadPluginsUPP)(NPBool reloadPages); +#define NewNPN_ReloadPluginsProc(FUNC) \ + ((NPN_ReloadPluginsUPP) (FUNC)) +#define CallNPN_ReloadPluginsProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + +/* NPN_GetJavaEnv */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_GetJavaEnvUPP; +enum { + uppNPN_GetJavaEnvProcInfo = kThinkCStackBased + | RESULT_SIZE(SIZE_CODE(sizeof(JRIEnv*))) +}; + +#define NewNPN_GetJavaEnvProc(FUNC) \ + (NPN_GetJavaEnvUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetJavaEnvProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetJavaEnvProc(FUNC) \ + (JRIEnv*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetJavaEnvProcInfo) + +#else + +typedef JRIEnv* (*NPN_GetJavaEnvUPP)(void); +#define NewNPN_GetJavaEnvProc(FUNC) \ + ((NPN_GetJavaEnvUPP) (FUNC)) +#define CallNPN_GetJavaEnvProc(FUNC) \ + (*(FUNC))() + +#endif + + +/* NPN_GetJavaPeer */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_GetJavaPeerUPP; +enum { + uppNPN_GetJavaPeerProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | RESULT_SIZE(SIZE_CODE(sizeof(jref))) +}; + +#define NewNPN_GetJavaPeerProc(FUNC) \ + (NPN_GetJavaPeerUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetJavaPeerProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetJavaPeerProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetJavaPeerProcInfo, (ARG1)) + +#else + +typedef jref (*NPN_GetJavaPeerUPP)(NPP instance); +#define NewNPN_GetJavaPeerProc(FUNC) \ + ((NPN_GetJavaPeerUPP) (FUNC)) +#define CallNPN_GetJavaPeerProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + + + +/****************************************************************************************** + * The actual plugin function table definitions + *******************************************************************************************/ + +typedef struct _NPPluginFuncs { + uint16 size; + uint16 version; + NPP_NewUPP newp; + NPP_DestroyUPP destroy; + NPP_SetWindowUPP setwindow; + NPP_NewStreamUPP newstream; + NPP_DestroyStreamUPP destroystream; + NPP_StreamAsFileUPP asfile; + NPP_WriteReadyUPP writeready; + NPP_WriteUPP write; + NPP_PrintUPP print; + NPP_HandleEventUPP event; + NPP_URLNotifyUPP urlnotify; + JRIGlobalRef javaClass; +} NPPluginFuncs; + +typedef struct _NPNetscapeFuncs { + uint16 size; + uint16 version; + NPN_GetURLUPP geturl; + NPN_PostURLUPP posturl; + NPN_RequestReadUPP requestread; + NPN_NewStreamUPP newstream; + NPN_WriteUPP write; + NPN_DestroyStreamUPP destroystream; + NPN_StatusUPP status; + NPN_UserAgentUPP uagent; + NPN_MemAllocUPP memalloc; + NPN_MemFreeUPP memfree; + NPN_MemFlushUPP memflush; + NPN_ReloadPluginsUPP reloadplugins; + NPN_GetJavaEnvUPP getJavaEnv; + NPN_GetJavaPeerUPP getJavaPeer; + NPN_GetURLNotifyUPP geturlnotify; + NPN_PostURLNotifyUPP posturlnotify; +#ifdef XP_UNIX + NPN_GetValueUPP getvalue; +#endif /* XP_UNIX */ +} NPNetscapeFuncs; + + + +#ifdef XP_MAC +/****************************************************************************************** + * Mac platform-specific plugin glue stuff + *******************************************************************************************/ + +/* + * Main entry point of the plugin. + * This routine will be called when the plugin is loaded. The function + * tables are passed in and the plugin fills in the NPPluginFuncs table + * and NPPShutdownUPP for Netscape's use. + */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_MainEntryUPP; +enum { + uppNPP_MainEntryProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPNetscapeFuncs*))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPPluginFuncs*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPP_ShutdownUPP*))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_MainEntryProc(FUNC) \ + (NPP_MainEntryUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_MainEntryProcInfo, GetCurrentArchitecture()) +#define CallNPP_MainEntryProc(FUNC, netscapeFunc, pluginFunc, shutdownUPP) \ + CallUniversalProc((UniversalProcPtr)(FUNC), (ProcInfoType)uppNPP_MainEntryProcInfo, (netscapeFunc), (pluginFunc), (shutdownUPP)) + +#else + +typedef NPError (*NPP_MainEntryUPP)(NPNetscapeFuncs*, NPPluginFuncs*, NPP_ShutdownUPP*); +#define NewNPP_MainEntryProc(FUNC) \ + ((NPP_MainEntryUPP) (FUNC)) +#define CallNPP_MainEntryProc(FUNC, netscapeFunc, pluginFunc, shutdownUPP) \ + (*(FUNC))((netscapeFunc), (pluginFunc), (shutdownUPP)) + +#endif +#endif /* MAC */ + + +#ifdef _WINDOWS + +#ifdef __cplusplus +extern "C" { +#endif + +/* plugin meta member functions */ + +NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* pFuncs); + +NPError WINAPI NP_Initialize(NPNetscapeFuncs* pFuncs); + +NPError WINAPI NP_Shutdown(); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS */ + +#ifdef XP_UNIX + +#ifdef __cplusplus +extern "C" { +#endif + +/* plugin meta member functions */ + +char* NP_GetMIMEDescription(void); +NPError NP_Initialize(NPNetscapeFuncs*, NPPluginFuncs*); +NPError NP_Shutdown(void); + +#ifdef __cplusplus +} +#endif + +#endif /* XP_UNIX */ + +#endif /* _NPUPP_H_ */ diff --git a/extensions/nsplugin/src/npwin.cpp b/extensions/nsplugin/src/npwin.cpp new file mode 100644 index 0000000..45a7122 --- /dev/null +++ b/extensions/nsplugin/src/npwin.cpp @@ -0,0 +1,367 @@ +/* npwin.cpp */ + +//\\// INCLUDE +//#include "StdAfx.h" + +// netscape +#ifndef _NPAPI_H_ +#include "npapi.h" +#endif +#ifndef _NPUPP_H_ +#include "npupp.h" +#endif + +//\\// DEFINE +#ifdef WIN32 + #define NP_EXPORT //__declspec( dllexport ) +#else + #define NP_EXPORT _export +#endif + +//\\// GLOBAL DATA +NPNetscapeFuncs* g_pNavigatorFuncs = NULL; + +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +// Private_GetJavaClass (global function) +// +// Given a Java class reference (thru NPP_GetJavaClass) inform JRT +// of this class existence +// +JRIGlobalRef +Private_GetJavaClass(void) +{ + jref clazz = NPP_GetJavaClass(); + if (clazz) { + JRIEnv* env = NPN_GetJavaEnv(); + return JRI_NewGlobalRef(env, clazz); + } + return NULL; +} + +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +// PLUGIN DLL entry points +// +// These are the Windows specific DLL entry points. They must be exoprted +// + +// we need these to be global since we have to fill one of its field +// with a data (class) which requires knowlwdge of the navigator +// jump-table. This jump table is known at Initialize time (NP_Initialize) +// which is called after NP_GetEntryPoint +static NPPluginFuncs* g_pluginFuncs; + +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +// NP_GetEntryPoints +// +// fills in the func table used by Navigator to call entry points in +// plugin DLL. Note that these entry points ensure that DS is loaded +// by using the NP_LOADDS macro, when compiling for Win16 +// +NPError WINAPI NP_EXPORT +NP_GetEntryPoints(NPPluginFuncs* pFuncs) +{ + // trap a NULL ptr + if(pFuncs == NULL) + return NPERR_INVALID_FUNCTABLE_ERROR; + + // if the plugin's function table is smaller than the plugin expects, + // then they are incompatible, and should return an error + + pFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; + pFuncs->newp = NPP_New; + pFuncs->destroy = NPP_Destroy; + pFuncs->setwindow = NPP_SetWindow; + pFuncs->newstream = NPP_NewStream; + pFuncs->destroystream = NPP_DestroyStream; + pFuncs->asfile = NPP_StreamAsFile; + pFuncs->writeready = NPP_WriteReady; + pFuncs->write = NPP_Write; + pFuncs->print = NPP_Print; + pFuncs->event = NULL; /// reserved + + g_pluginFuncs = pFuncs; + + return NPERR_NO_ERROR; +} + +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +// NP_Initialize +// +// called immediately after the plugin DLL is loaded +// +NPError WINAPI NP_EXPORT +NP_Initialize(NPNetscapeFuncs* pFuncs) +{ + // trap a NULL ptr + if(pFuncs == NULL) + return NPERR_INVALID_FUNCTABLE_ERROR; + + g_pNavigatorFuncs = pFuncs; // save it for future reference + + // if the plugin's major ver level is lower than the Navigator's, + // then they are incompatible, and should return an error + if(HIBYTE(pFuncs->version) > NP_VERSION_MAJOR) + return NPERR_INCOMPATIBLE_VERSION_ERROR; + + // We have to defer these assignments until g_pNavigatorFuncs is set + int navMinorVers = g_pNavigatorFuncs->version & 0xFF; + + + if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) { + + g_pluginFuncs->urlnotify = NPP_URLNotify; + + } + + if( navMinorVers >= NPVERS_HAS_LIVECONNECT ) { + + g_pluginFuncs->javaClass = Private_GetJavaClass(); + + } + + + // NPP_Initialize is a standard (cross-platform) initialize function. + return NPP_Initialize(); +} + +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +// NP_Shutdown +// +// called immediately before the plugin DLL is unloaded. +// This functio shuold check for some ref count on the dll to see if it is +// unloadable or it needs to stay in memory. +// +NPError WINAPI NP_EXPORT +NP_Shutdown() +{ + NPP_Shutdown(); + + g_pNavigatorFuncs = NULL; + + return NPERR_NO_ERROR; +} + +// END - PLUGIN DLL entry points +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. + +/* NAVIGATOR Entry points */ + +/* These entry points expect to be called from within the plugin. The + noteworthy assumption is that DS has already been set to point to the + plugin's DLL data segment. Don't call these functions from outside + the plugin without ensuring DS is set to the DLLs data segment first, + typically using the NP_LOADDS macro +*/ + +/* returns the major/minor version numbers of the Plugin API for the plugin + and the Navigator +*/ +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; + *netscape_major = HIBYTE(g_pNavigatorFuncs->version); + *netscape_minor = LOBYTE(g_pNavigatorFuncs->version); +} + +/* causes the specified URL to be fetched and streamed in +*/ +NPError NPN_GetURLNotify(NPP instance, const char *url, const char *target, void* notifyData) + +{ + + int navMinorVers = g_pNavigatorFuncs->version & 0xFF; + + NPError err; + + if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) { + + err = g_pNavigatorFuncs->geturlnotify(instance, url, target, notifyData); + + } + + else { + + err = NPERR_INCOMPATIBLE_VERSION_ERROR; + + } + + return err; + +} + + +NPError NPN_GetURL(NPP instance, const char *url, const char *target) +{ + return g_pNavigatorFuncs->geturl(instance, url, target); +} + +NPError NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData) + +{ + + int navMinorVers = g_pNavigatorFuncs->version & 0xFF; + + NPError err; + + if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) { + + err = g_pNavigatorFuncs->posturlnotify(instance, url, window, len, buf, file, notifyData); + + } + + else { + + err = NPERR_INCOMPATIBLE_VERSION_ERROR; + + } + + return err; + +} + + +NPError NPN_PostURL(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file) +{ + return g_pNavigatorFuncs->posturl(instance, url, window, len, buf, file); +} + +/* Requests that a number of bytes be provided on a stream. Typically + this would be used if a stream was in "pull" mode. An optional + position can be provided for streams which are seekable. +*/ +NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) +{ + return g_pNavigatorFuncs->requestread(stream, rangeList); +} + +/* Creates a new stream of data from the plug-in to be interpreted + by Netscape in the current window. +*/ +NPError NPN_NewStream(NPP instance, NPMIMEType type, + const char* target, NPStream** stream) +{ + + int navMinorVersion = g_pNavigatorFuncs->version & 0xFF; + + NPError err; + + + if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) { + + err = g_pNavigatorFuncs->newstream(instance, type, target, stream); + + } + + else { + + err = NPERR_INCOMPATIBLE_VERSION_ERROR; + + } + + return err; +} + +/* Provides len bytes of data. +*/ +int32 NPN_Write(NPP instance, NPStream *stream, + int32 len, void *buffer) +{ + int navMinorVersion = g_pNavigatorFuncs->version & 0xFF; + + int32 result; + + + if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) { + + result = g_pNavigatorFuncs->write(instance, stream, len, buffer); + + } + + else { + result = -1; + + } + + return result; + +} + +/* Closes a stream object. +reason indicates why the stream was closed. +*/ +NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason) +{ + int navMinorVersion = g_pNavigatorFuncs->version & 0xFF; + + NPError err; + + + if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) { + + err = g_pNavigatorFuncs->destroystream(instance, stream, reason); + + } + else { + + err = NPERR_INCOMPATIBLE_VERSION_ERROR; + + } + + return err; + +} + +/* Provides a text status message in the Netscape client user interface +*/ +void NPN_Status(NPP instance, const char *message) +{ + g_pNavigatorFuncs->status(instance, message); +} + +/* returns the user agent string of Navigator, which contains version info +*/ +const char* NPN_UserAgent(NPP instance) +{ + return g_pNavigatorFuncs->uagent(instance); +} + +/* allocates memory from the Navigator's memory space. Necessary so that + saved instance data may be freed by Navigator when exiting. +*/ + + +void* NPN_MemAlloc(uint32 size) +{ + return g_pNavigatorFuncs->memalloc(size); +} + +/* reciprocal of MemAlloc() above +*/ +void NPN_MemFree(void* ptr) +{ + g_pNavigatorFuncs->memfree(ptr); +} + +/* private function to Netscape. do not use! +*/ +void NPN_ReloadPlugins(NPBool reloadPages) +{ + g_pNavigatorFuncs->reloadplugins(reloadPages); +} + +JRIEnv* NPN_GetJavaEnv(void) +{ + return g_pNavigatorFuncs->getJavaEnv(); +} + +jref NPN_GetJavaPeer(NPP instance) +{ + return g_pNavigatorFuncs->getJavaPeer(instance); +} diff --git a/extensions/nsplugin/src/qnp.cpp b/extensions/nsplugin/src/qnp.cpp new file mode 100644 index 0000000..5a5eb5c --- /dev/null +++ b/extensions/nsplugin/src/qnp.cpp @@ -0,0 +1,2071 @@ +/**************************************************************************** +** +** Implementation of Qt extension classes for Netscape Plugin support. +** +** Created : 970601 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + + +// Remaining Q_WS_X11 considerations: +// - What if !piApp upon NPP_NewStream? Are we safe? +// - Yes, but users need to know of this: that no GUI can be +// done until after setWindow is called. +// - Use NPN_GetValue in Communicator4.0 to get the display earlier! +// - For ClientMessage events, trap them, and if they are not for us, +// untrap them and retransmit them and set a timer to retrap them +// after N seconds. + +// Remaining Q_WS_WIN considerations: +// - we need to activateZeroTimers() at some time. +// - we need to call winEventFilter on events +// - timers: +// if ( msg.message == WM_TIMER ) { // timer message received +// activateTimer( msg.wParam ); +// return TRUE; +// } +// if ( msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ) { +// if ( translateKeyCode(msg.wParam) == 0 ) { +// TranslateMessage( &msg ); // translate to WM_CHAR +// return TRUE; +// } +// } +// - qWinProcessConfigRequests? + +// Remaining general stuff: +// - Provide the "reason" parameter to streamDestroyed + +// Qt stuff +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qnp.h" + +#include // Must be here for Borland C++ +#include +#include +#include +#include + +#ifdef Q_WS_X11 +#include + +class QNPXtPrivate; + +class QNPXt : public QEventLoop +{ +public: + QNPXt( const char *applicationClass, XtAppContext context = NULL, XrmOptionDescRec *options = 0, int numOptions = 0); + ~QNPXt(); + + XtAppContext applicationContext() const; + + void registerSocketNotifier( QSocketNotifier * ); + void unregisterSocketNotifier( QSocketNotifier * ); + + static void registerWidget( QWidget* ); + static void unregisterWidget( QWidget* ); + static bool redeliverEvent( XEvent *event ); + static XEvent* lastEvent(); + +protected: + bool processEvents( ProcessEventsFlags flags ); + +private: + void appStartingUp(); + void appClosingDown(); + QNPXtPrivate *d; + +}; + +#define GC GC_QQQ +#endif + +extern "C" { +// +// Netscape plugin API +// +#ifdef Q_WS_WIN +#ifndef _WINDOWS +#define _WINDOWS +#endif +#endif +#ifdef Q_WS_X11 +#define XP_UNIX +#endif + + +// This is to allow mingw support on windows without altering the sun header files +#if defined(Q_CC_GNU) && defined(Q_WS_WIN) && !defined(_MSC_VER) +#define _MSC_VER 1 +#include "npapi.h" +#undef _MSC_VER +#else +#include "npapi.h" +#endif + +#ifdef Q_WS_X11 +#undef XP_UNIX +#include "npunix.c" +#endif + +// +// Stuff for the NPP_SetWindow function: +// +#ifdef Q_WS_X11 +#include +#include +#include // for XtCreateWindow +#include +#include +#include +#include +//#include +#endif +#ifdef Q_WS_WIN +#include +#endif +} + +#ifdef Q_WS_WIN +#include "npwin.cpp" +#endif + +static QEventLoop* event_loop = 0; +static QApplication* application = 0; + +struct _NPInstance +{ + uint16 fMode; + +#ifdef Q_WS_WIN + HWND window; +#endif + + NPP npp; + +#ifdef Q_WS_X11 + Window window; + Display *display; +#endif + + uint32 x, y; + uint32 width, height; + + QNPWidget* widget; + QNPInstance* instance; + + int16 argc; + QString *argn; + QString *argv; +}; + + + +// The single global plugin +static QNPlugin *qNP=0; +static int instance_count=0; + +// Temporary parameter passed `around the side' of calls to user functions +static _NPInstance* next_pi=0; + +// To avoid looping when browser OR plugin can delete streams +static int qnps_no_call_back = 0; + +#ifdef Q_WS_WIN +// defined in qapplication_win.cpp +Q_EXPORT extern bool qt_win_use_simple_timers; +Q_EXPORT void qWinProcessConfigRequests(); +static HHOOK hhook = 0; + +LRESULT CALLBACK FilterProc( int nCode, WPARAM wParam, LPARAM lParam ) +{ + if ( qApp ) { + qApp->sendPostedEvents(); + qApp->eventLoop()->activateSocketNotifiers(); + qWinProcessConfigRequests(); + } + + return CallNextHookEx( hhook, nCode, wParam, lParam ); +} + +#endif + +#ifdef Q_WS_X11 +static int (*original_x_errhandler)( Display *dpy, XErrorEvent * ) = 0; +static int dummy_x_errhandler( Display *, XErrorEvent * ) +{ + return 0; +} +#endif + +/****************************************************************************** + * Plug-in Calls - these are called by Netscape + *****************************************************************************/ + + +// Instance state information about the plugin. + +#ifdef Q_WS_X11 + +extern "C" char* +NPP_GetMIMEDescription(void) +{ + if (!qNP) qNP = QNPlugin::create(); + return (char*)qNP->getMIMEDescription(); +} + + + +extern "C" NPError +NPP_GetValue(void * /*future*/, NPPVariable variable, void *value) +{ + if (!qNP) qNP = QNPlugin::create(); + NPError err = NPERR_NO_ERROR; + if (variable == NPPVpluginNameString) + *((const char **)value) = qNP->getPluginNameString(); + else if (variable == NPPVpluginDescriptionString) + *((const char **)value) = qNP->getPluginDescriptionString(); + else + err = NPERR_GENERIC_ERROR; + + return err; +} + +#endif + +/* +** NPP_Initialize is called when your DLL is being loaded to do any +** DLL-specific initialization. +*/ +extern "C" NPError +NPP_Initialize(void) +{ +#ifdef Q_WS_WIN + qt_win_use_simple_timers = TRUE; + // Nothing more - we do it in DLLMain +#endif + + if (!qNP) qNP = QNPlugin::create(); + return NPERR_NO_ERROR; +} + +static jref plugin_java_class = 0; + +/* +** NPP_GetJavaClass is called during initialization to ask your plugin +** what its associated Java class is. If you don't have one, just return +** NULL. Otherwise, use the javah-generated "use_" function to both +** initialize your class and return it. If you can't find your class, an +** error will be signalled by "use_" and will cause the Navigator to +** complain to the user. +*/ +extern "C" jref +NPP_GetJavaClass(void) +{ + if (!qNP) qNP = QNPlugin::create(); + plugin_java_class = (jref)qNP->getJavaClass(); + return plugin_java_class; +} + +/* +** NPP_Shutdown is called when your DLL is being unloaded to do any +** DLL-specific shut-down. You should be a good citizen and declare that +** you're not using your java class any more. This allows java to unload +** it, freeing up memory. +*/ +extern "C" void +NPP_Shutdown(void) +{ + if (qNP) { + if (plugin_java_class) + qNP->unuseJavaClass(); + delete qNP; + qNP = 0; + } + +#ifdef Q_WS_X11 + if ( original_x_errhandler ) + XSetErrorHandler( original_x_errhandler ); +#endif + if ( qApp) { +#ifdef Q_WS_WIN32 + if ( hhook ) + UnhookWindowsHookEx( hhook ); + hhook = 0; +#endif + delete application; + delete event_loop; + } + +} + + +struct NS_Private { + uchar* a; + uchar* b; +}; + +/* +** NPP_New is called when your plugin is instantiated (i.e. when an EMBED +** tag appears on a page). +*/ +extern "C" NPError +NPP_New(NPMIMEType /*pluginType*/, + NPP instance, + uint16 mode, + int16 argc, + char* argn[], + char* argv[], + NPSavedData* /*saved*/) +{ + NPError result = NPERR_NO_ERROR; + _NPInstance* This; + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + instance->pdata = new _NPInstance; + + This = (_NPInstance*) instance->pdata; + + if (This == NULL) + return NPERR_OUT_OF_MEMORY_ERROR; + + This->npp = instance; + + /* mode is NP_EMBED, NP_FULL, or NP_BACKGROUND (see npapi.h) */ + This->fMode = mode; + + This->window = 0; + This->widget = 0; + + This->argc = argc; + This->argn = new QString[argc+1]; + This->argv = new QString[argc+1]; + for (int i=0; iargc; i++) { + This->argn[i] = argn[i]; + This->argv[i] = argv[i]; + } + + // Everything is set up - we can let QNPInstance be created now. + next_pi = This; + qNP->newInstance(); + instance_count++; + + return result; +} + +extern "C" NPError +NPP_Destroy(NPP instance, NPSavedData** /*save*/) +{ + _NPInstance* This; + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + This = (_NPInstance*) instance->pdata; + + if (This != NULL) { + delete This->widget; + delete This->instance; + delete [] This->argn; + delete [] This->argv; + + delete This; + instance->pdata = NULL; + + instance_count--; + } + + return NPERR_NO_ERROR; +} + +extern "C" NPError +NPP_SetWindow(NPP instance, NPWindow* window) +{ + if (!qNP) qNP = QNPlugin::create(); + NPError result = NPERR_NO_ERROR; + _NPInstance* This; + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + This = (_NPInstance*) instance->pdata; + + + // take a shortcut if all that was changed is the geometry + if ( This->widget && window +#ifdef Q_WS_X11 + && This->window == (Window) window->window +#endif +#ifdef Q_WS_WIN + && This->window == (HWND) window->window +#endif + ) { + This->x = window->x; + This->y = window->y; + This->width = window->width; + This->height = window->height; + This->widget->resize( This->width, This->height ); + return result; + } + + delete This->widget; + + if ( !window ) + return result; + +#ifdef Q_WS_X11 + This->window = (Window) window->window; + This->display = + ((NPSetWindowCallbackStruct *)window->ws_info)->display; +#endif +#ifdef Q_WS_WIN + This->window = (HWND) window->window; +#endif + + This->x = window->x; + This->y = window->y; + This->width = window->width; + This->height = window->height; + + + if (!qApp) { +#ifdef Q_WS_X11 + // We are the first Qt-based plugin to arrive + event_loop = new QNPXt( "qnp", XtDisplayToApplicationContext(This->display) ); + application = new QApplication(This->display); +#endif +#ifdef Q_WS_WIN + static int argc=0; + static char **argv={ 0 }; + application = new QApplication( argc, argv ); +#ifdef UNICODE + if ( qWinVersion() & Qt::WV_NT_based ) + hhook = SetWindowsHookExW( WH_GETMESSAGE, FilterProc, 0, GetCurrentThreadId() ); + else +#endif + hhook = SetWindowsHookExA( WH_GETMESSAGE, FilterProc, 0, GetCurrentThreadId() ); +#endif + } + +#ifdef Q_WS_X11 + if ( !original_x_errhandler ) + original_x_errhandler = XSetErrorHandler( dummy_x_errhandler ); +#endif + + // New widget on this new window. + next_pi = This; + /* This->widget = */ // (happens sooner - in QNPWidget constructor) + This->instance->newWindow(); + + if ( !This->widget ) + return result; + +#ifdef Q_WS_X11 + This->widget->resize( This->width, This->height ); + XReparentWindow( This->widget->x11Display(), This->widget->winId(), This->window, 0, 0 ); + XSync( This->widget->x11Display(), False ); +#endif +#ifdef Q_WS_WIN + LONG oldLong = GetWindowLong(This->window, GWL_STYLE); + ::SetWindowLong(This->window, GWL_STYLE, oldLong | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + ::SetWindowLong( This->widget->winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ); + ::SetParent( This->widget->winId(), This->window ); + This->widget->raise(); + This->widget->setGeometry( 0, 0, This->width, This->height ); +#endif + This->widget->show(); + return result; +} + + +extern "C" NPError +NPP_NewStream(NPP instance, + NPMIMEType type, + NPStream *stream, + NPBool seekable, + uint16 *stype) +{ + _NPInstance* This; + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + This = (_NPInstance*) instance->pdata; + + if ( This ) { + QNPStream* qnps = new QNPStream(This->instance,type,stream,seekable); + stream->pdata = qnps; + QNPInstance::StreamMode sm = (QNPInstance::StreamMode)*stype; + if (!This->instance->newStreamCreated(qnps, sm)) { + return NPERR_GENERIC_ERROR; + } + *stype = sm; + } + + return NPERR_NO_ERROR; +} + + +int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile + * mode so we can take any size stream in our + * write call (since we ignore it) */ + +extern "C" int32 +NPP_WriteReady(NPP instance, NPStream *stream) +{ + _NPInstance* This; + if (instance != NULL) { + This = (_NPInstance*) instance->pdata; + } else { + // Yikes, that's unusual! + return 0; + } + + if (This) { + return This->instance->writeReady((QNPStream*)stream->pdata); + } + + /* Number of bytes ready to accept in NPP_Write() */ + return STREAMBUFSIZE; +} + + +extern "C" int32 +NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer) +{ + if (instance != NULL) + { + _NPInstance* This = (_NPInstance*) instance->pdata; + + if (This) { + return This->instance->write((QNPStream*)stream->pdata, + offset, len, buffer); + } + } + + return len; /* The number of bytes accepted */ +} + + +extern "C" NPError +NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason) +{ + _NPInstance* This; + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + if (!qnps_no_call_back) { + This = (_NPInstance*) instance->pdata; + + QNPStream* qnps = (QNPStream*)stream->pdata; + if ( qnps ) + switch (reason) { + case NPRES_DONE: + qnps->setComplete(TRUE); + break; + case NPRES_USER_BREAK: + break; + case NPRES_NETWORK_ERR: + qnps->setOkay(FALSE); + break; + } + + if (This) { + // Give the instance a chance to do something + This->instance->streamDestroyed(qnps); + } + + qnps_no_call_back++; + delete qnps; + qnps_no_call_back--; + } + + return NPERR_NO_ERROR; +} + + +extern "C" void +NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname) +{ + _NPInstance* This; + + if (instance == NULL) return; + + This = (_NPInstance*) instance->pdata; + + if ( This ) { + QNPStream* qnps = (QNPStream*)stream->pdata; + This->instance->streamAsFile(qnps, fname); + } +} + +typedef struct +{ + int32 type; + FILE* fp; +} NPPrintCallbackStruct; + +#ifdef Q_WS_X11 + +class QNPPrinter : public QPrinter { + QFile file; +public: + QNPPrinter(FILE* fp) + { + file.open(IO_WriteOnly, fp); + QPDevCmdParam param; + param.device = &file; + cmd(PdcSetdev, 0, ¶m); + } + void end() + { + QPDevCmdParam param; + param.device = 0; + cmd(PdcSetdev, 0, ¶m); + } +}; +#endif + +extern "C" void +NPP_Print(NPP instance, NPPrint* printInfo) +{ + if(printInfo == NULL) + return; + + if (instance != NULL) { + _NPInstance* This = (_NPInstance*) instance->pdata; + + if (printInfo->mode == NP_FULL) { + printInfo->print.fullPrint.pluginPrinted = + This->instance->printFullPage(); + } else if (printInfo->mode == NP_EMBED) { +#ifdef Q_WS_X11 + void* platformPrint = + printInfo->print.embedPrint.platformPrint; + FILE* outfile = ((NPPrintCallbackStruct*)platformPrint)->fp; + if (ftell(outfile)) { +// NPWindow* w = +// &(printInfo->print.embedPrint.window); + QNPPrinter prn(outfile); + QPainter painter(&prn); + // #### config viewport with w->{x,y,width,height} + This->instance->print(&painter); + prn.end(); + } else { + // Why does the browser make spurious NPP_Print calls? + } +#endif +#ifdef Q_WS_WIN + NPWindow* printWindow = + &(printInfo->print.embedPrint.window); + void* platformPrint = + printInfo->print.embedPrint.platformPrint; + // #### Nothing yet. +#endif + } + } +} + +extern "C" void +NPP_URLNotify(NPP instance, + const char* url, + NPReason reason, + void* notifyData) +{ + if (instance != NULL) { + QNPInstance::Reason r; + switch (reason) { + case NPRES_DONE: + r = QNPInstance::ReasonDone; + break; + case NPRES_USER_BREAK: + r = QNPInstance::ReasonBreak; + break; + case NPRES_NETWORK_ERR: + r = QNPInstance::ReasonError; + break; + default: + r = QNPInstance::ReasonUnknown; + break; + } + _NPInstance* This = (_NPInstance*) instance->pdata; + This->instance->notifyURL(url, r, notifyData); + } +} + + + +#ifdef Q_WS_WIN + +BOOL WINAPI DllMain (HANDLE hInst, + ULONG ul_reason_for_call, + LPVOID lpReserved) +{ + return TRUE; +} + +#endif + + + +/*! + \class QNPWidget qnp.h + \brief The QNPWidget class provides a QWidget that is a web browser plugin window. + + \extension Netscape Plugin + + Derive from QNPWidget to create a widget that can be used as a + web browser plugin window, or create one and add child widgets. + Instances of QNPWidget may only be created when + QNPInstance::newWindow() is called by the browser. + + A common way to develop a plugin widget is to develop it as a + stand-alone application window, then make it a \e child of a + plugin widget to use it as a browser plugin. The technique is: + +\code +class MyPluginWindow : public QNPWidget +{ + QWidget* child; +public: + MyPluginWindow() + { + // Some widget that is normally used as a top-level widget + child = new MyIndependentlyDevelopedWidget(); + + // Use the background color of the web page + child->setBackgroundColor( backgroundColor() ); + + // Fill the plugin widget + child->setGeometry( 0, 0, width(), height() ); + } + + void resizeEvent(QResizeEvent*) + { + // Fill the plugin widget + child->resize(size()); + } +}; +\endcode + + The default implementation is an empty window. +*/ + +/*! + Creates a QNPWidget. +*/ +QNPWidget::QNPWidget() : + pi(next_pi) +{ + if (!next_pi) { + qFatal("QNPWidget must only be created within call to newWindow"); + } + next_pi->widget = this; + next_pi = 0; + +#ifdef Q_WS_WIN + clearWFlags( WStyle_NormalBorder | WStyle_Title | WStyle_MinMax | WStyle_SysMenu ); + topData()->ftop = 0; + topData()->fright = 0; + topData()->fleft = 0; + topData()->fbottom = 0; +#endif +} + +/*! + Destroys the window. This will be called by the plugin binding + code when the window is no longer required. The web browser will + delete windows when they leave the page. The bindings will change + the QWidget::winId() of the window when the window is resized, but + this should not affect normal widget behavior. +*/ +QNPWidget::~QNPWidget() +{ +#ifdef Q_WS_X11 + destroy( FALSE, FALSE ); // X has destroyed all windows +#endif +} + + +/*!\internal */ +void QNPWidget::enterEvent(QEvent*) +{ + enterInstance(); +} + +/*!\internal */ +void QNPWidget:: leaveEvent(QEvent*) +{ + if ( !QApplication::activePopupWidget() ) + leaveInstance(); +} + +/*! + Called when the mouse enters the plugin window. Does nothing by + default. +*/ +void QNPWidget::enterInstance() +{ +} + +/*! + Called when the mouse leaves the plugin window. Does nothing by + default. +*/ +void QNPWidget::leaveInstance() +{ +} + +/*! + Returns the instance for which this widget is the plugin window. +*/ +QNPInstance* QNPWidget::instance() +{ + return pi->instance; +} + + + + + +/*! + \class QNPInstance qnp.h + \brief The QNPInstance class provides a QObject that is a web browser plugin. + + \extension Netscape Plugin + + Deriving from QNPInstance creates an object that represents a + single \c{} tag in an HTML document. + + The QNPInstance is responsible for creating an appropriate + QNPWidget window if required (not all plugins have windows), and + for interacting with the input/output facilities intrinsic to + plugins. + + Note that there is \e{absolutely no guarantee} regarding the order + in which functions are called. Sometimes the browser will call + newWindow() first, at other times, newStreamCreated() will be + called first (assuming the \c{} tag has a SRC parameter). + + \e{None of Qt's GUI functionality} may be used until after the + first call to newWindow(). This includes any use of QPaintDevice + (i.e. QPixmap, QWidget, and all subclasses), QApplication, anything + related to QPainter (QBrush, etc.), fonts, QMovie, QToolTip, etc. + Useful classes which specifically \e can be used are QImage, + QFile, and QBuffer. + + This restriction can easily be accommodated by structuring your + plugin so that the task of the QNPInstance is to gather data, + while the task of the QNPWidget is to provide a graphical + interface to that data. +*/ + +/*! + \enum QNPInstance::InstanceMode + + This enum type provides Qt-style names for three #defines in + \c npapi.h: + + \value Embed - corresponds to NP_EMBED + \value Full - corresponds to NP_FULL + \value Background - corresponds to NP_BACKGROUND + +*/ + +/*! + \enum QNPInstance::Reason + + \value ReasonDone + \value ReasonBreak + \value ReasonError + \value ReasonUnknown +*/ + +/*! + \enum QNPInstance::StreamMode + + \value Normal + \value Seek + \value AsFile + \value AsFileOnly +*/ + +/*! + Creates a QNPInstance. + + Can only be called from within a derived class created within + QNPlugin::newInstance(). +*/ +QNPInstance::QNPInstance() : + pi(next_pi) +{ + if (!next_pi) { + qFatal("QNPInstance must only be created within call to newInstance"); + } + next_pi->instance = this; + next_pi = 0; +} + +/*! + Called when the plugin instance is about to be deleted. +*/ +QNPInstance::~QNPInstance() +{ +} + +/*! + Called at most once, at some time after the QNPInstance is + created. If the plugin requires a window, this function should + return a derived class of QNPWidget that provides the required + interface. +*/ +QNPWidget* QNPInstance::newWindow() +{ + // No window by default + next_pi = 0; + return 0; +} + +/*! + Returns the plugin window created by newWindow(), if any. +*/ +QNPWidget* QNPInstance::widget() +{ + return pi->widget; +} + +/*! + \fn bool QNPInstance::newStreamCreated(QNPStream*, StreamMode& smode) + + This function is called when a new stream has been created. The + instance should return TRUE if it accepts the processing of the + stream. If the instance requires the stream as a file, it should + set \a smode to \c AsFileOnly, in which case the data will be + delivered some time later to the streamAsFile() function. + Otherwise, the data will be delivered in chunks to the write() + function, which must consume at least as much data as returned + by the most recent call to writeReady(). + + Note that the \c AsFileOnly method is not supported by Netscape + 2.0 and MSIE 3.0. + + The default implementation accepts any stream. +*/ +bool QNPInstance::newStreamCreated(QNPStream*, StreamMode&) +{ + return TRUE; +} + +/*! + Called when a stream is delivered as a single file called \a fname + rather than as chunks. This may be simpler for a plugin to deal + with, but precludes any incremental behavior. + + Note that the \c AsFileOnly method is not supported by Netscape + 2.0 and MSIE 3.0. + + \sa newStreamCreated(), newStream() +*/ +void QNPInstance::streamAsFile(QNPStream*, const char* fname) +{ +} + +/*! + Called when a stream is destroyed. At this point, the stream may + be complete() and okay(). If it is not okay(), then an error has + occurred. If it is okay(), but not complete(), then the user has + cancelled the transmission; do not give an error message in this + case. +*/ +void QNPInstance::streamDestroyed(QNPStream*) +{ +} + +/*! + Returns the minimum amount of data the instance is willing to + receive from the given stream. + + The default returns a very large value. +*/ +int QNPInstance::writeReady(QNPStream*) +{ + // Yes, we can handle any amount of data at once. + return 0X0FFFFFFF; +} + +/*! + \fn int QNPInstance::write(QNPStream*, int offset, int len, void* buffer) + + Called when incoming data is available for processing by the + instance. The instance \e must consume at least the amount that it + returned in the most recent call to writeReady(), but it may + consume up to the amount given by \a len. \a buffer is the data + available for consumption. The \a offset argument is merely an + informational value indicating the total amount of data that has + been consumed in prior calls. + + This function should return the amount of data actually consumed. +*/ +int QNPInstance::write(QNPStream*, int, int len, void*) +{ + // Yes, we processed it all... into the bit bucket. + return len; +} + +/*! + Requests that the \a url be retrieved and sent to the named \a + window. See Netscape's JavaScript documentation for an explanation + of window names. +*/ +void QNPInstance::getURL(const char* url, const char* window) +{ + NPN_GetURL( pi->npp, url, window ); +} + +/*! + \preliminary + + This function is \e{not tested}. + + It is an interface to the NPN_PostURL function of the Netscape + Plugin API. + + Passes \a url, \a window, \a buf, \a len, and \a file to + NPN_PostURL. +*/ +void QNPInstance::postURL(const char* url, const char* window, + uint len, const char* buf, bool file) +{ + NPN_PostURL( pi->npp, url, window, len, buf, file ); +} + +/*! + Requests that the given \a url be retrieved and sent to + the named \a window. See Netscape's JavaScript documentation for + an explanation of window names. Passes the arguments including \a + data to NPN_GetURLNotify. + + \sa + \link http://developer.netscape.com/docs/manuals/communicator/plugin/refpgur.htm#npngeturlnotify + Netscape: NPN_GetURLNotify method\endlink +*/ +void QNPInstance::getURLNotify(const char* url, const char* window, void*data) +{ +#ifdef Q_WS_WIN // Only on Windows? + NPN_GetURLNotify( pi->npp, url, window, data ); +#else + Q_UNUSED( url ); + Q_UNUSED( window ); + Q_UNUSED( data ); +#endif +} + +/*! + \preliminary + + This function is \e{not tested}. + + It is an encapsulation of the NPP_Print function of the Netscape + Plugin API. +*/ +bool QNPInstance::printFullPage() +{ + return FALSE; +} + +/*! + \preliminary + + This function is \e{not tested}. + + Print the instance embedded in a page. + + It is an encapsulation of the NPP_Print function of the Netscape + Plugin API. +*/ +void QNPInstance::print(QPainter*) +{ + // ### default could redirected-print the window. +} + +/*! + Returns the number of arguments to the instance. Note that you + should not normally rely on the ordering of arguments, and + note that the SGML specification does not permit multiple + arguments with the same name. + + \sa arg(), argn() +*/ +int QNPInstance::argc() const +{ + return pi->argc; +} + +/*! + Returns the name of the \a{i}-th argument. + + \sa argc(), argv() +*/ +const char* QNPInstance::argn(int i) const +{ + return pi->argn[i]; +} + +/*! + \preliminary + + This function is \e{not tested}. + + Called whenever a \a url is notified after a call to + NPN_GetURLNotify with \a notifyData. The reason is given in \a r. + + It is an encapsulation of the NPP_URLNotify function of the + Netscape Plugin API. + + See also: + \link http://developer.netscape.com/docs/manuals/communicator/plugin/refpgur.htm#nppurlnotify + Netscape: NPP_URLNotify method\endlink +*/ +void QNPInstance::notifyURL(const char*, Reason, void*) +{ +} + +/*! + Returns the value of the \a{i}-th argument. + + \as argc(), arg() +*/ +const char* QNPInstance::argv(int i) const +{ + return pi->argv[i]; +} + +/*! + Returns the mode of the plugin. +*/ +QNPInstance::InstanceMode QNPInstance::mode() const +{ + return (QNPInstance::InstanceMode)pi->fMode; +} + +/*! + Returns the value of the named arguments, or 0 if no argument + called \a name appears in the \c{} tag of this instance. + If the argument appears, but has no value assigned, the empty + string is returned. In summary: + + \table + \header \i Tag \i Result + \row \i \c{} \i arg("FOO") == 0 + \row \i \c{} \i arg("FOO") == "" + \row \i \c{} \i arg("FOO") == "BAR" + \endtable +*/ +const char* QNPInstance::arg(const char* name) const +{ + for (int i=0; iargc; i++) { + // SGML: names are case insensitive + if ( qstricmp( name, pi->argn[i] ) == 0 ) { + if (pi->argv[i].isEmpty()) + return ""; + else + return pi->argv[i]; + } + } + return 0; +} + +/*! + Returns the user agent (browser name) containing this instance. +*/ +const char* QNPInstance::userAgent() const +{ + return NPN_UserAgent(pi->npp); +} + +/*! + \preliminary + + This function is \e{not tested}. + + Requests the creation of a new data stream \e from the plugin. + The MIME type and window are passed in \a mimetype and \a window. + \a as_file holds the \c AsFileOnly flag. It is an interface to the + NPN_NewStream function of the Netscape Plugin API. +*/ +QNPStream* QNPInstance::newStream(const char* mimetype, const char* window, + bool as_file) +{ + NPStream* s=0; + NPError err = NPN_NewStream(pi->npp, (char*)mimetype, window, &s); + if (err != NPERR_NO_ERROR) return 0; + return s ? new QNPStream(this, mimetype, s, as_file) : 0; +} + +/*! + Sets the status message in the browser containing this instance to + \a msg. +*/ +void QNPInstance::status(const char* msg) +{ + NPN_Status(pi->npp, msg); +} + + +/*! + Returns the Java object associated with the plugin instance, an + object of the \link QNPlugin::getJavaClass() plugin's Java + class\endlink, or 0 if the plug-in does not have a Java class, + Java is disabled, or an error occurred. + + The return value is actually a \c{jref} we use \c{void*} so as to + avoid burdening plugins which do not require Java. + + \sa QNPlugin::getJavaClass(), QNPlugin::getJavaEnv(), getJavaPeer() +*/ +void* QNPInstance::getJavaPeer() const +{ + return NPN_GetJavaPeer(pi->npp); +} + + +/*! + \class QNPStream qnp.h + \brief The QNPStream class provides a stream of data provided to a QNPInstance by the browser. + + \extension Netscape Plugin + + Note that this is neither a QTextStream nor a QDataStream. + + \sa QNPInstance::write(), QNPInstance::newStreamCreated() +*/ + +/*! + Creates a stream. Plugins should not call this; they should call + QNPInstance::newStream() if they need a stream. + + Takes a QNPInstance \a in, MIME type \a mt, a pointer to an + _NPStream \a st and a seekable flag \a se. +*/ +QNPStream::QNPStream(QNPInstance* in,const char* mt, _NPStream* st, bool se) : + inst(in), + stream(st), + mtype(mt), + seek(se) +{ + isokay = TRUE; + iscomplete = FALSE; +} + +/*! + Destroys the stream. +*/ +QNPStream::~QNPStream() +{ + if (!qnps_no_call_back) { + qnps_no_call_back++; + NPN_DestroyStream(inst->pi->npp, stream, NPRES_USER_BREAK); + qnps_no_call_back--; + } +} + +/*! + \fn QNPInstance* QNPStream::instance() + + Returns the QNPInstance for which this stream was created. +*/ + +/*! + Returns the URL from which the stream was created. +*/ +const char* QNPStream::url() const +{ + return stream->url; +} + +/*! + Returns the length of the stream in bytes. The function might + return 0 for streams of unknown length. +*/ +uint QNPStream::end() const +{ + return stream->end; +} + +/*! + Returns the time when the source of the stream was last modified. +*/ +uint QNPStream::lastModified() const +{ + return stream->lastmodified; +} + +/*! + Returns the MIME type of the stream. +*/ +const char* QNPStream::type() const +{ + return mtype; +} + +/*! + Returns TRUE if the stream is seekable; otherwise returns FALSE. +*/ +bool QNPStream::seekable() const +{ + return seek; +} + +/*! + \internal +*/ +void QNPStream::setOkay(bool y) +{ + isokay = y; +} + +/*! + \internal +*/ +void QNPStream::setComplete(bool y) +{ + iscomplete = y; +} + +/*! + Returns TRUE if no errors have occurred on the stream; otherwise + returns FALSE. +*/ +bool QNPStream::okay() const +{ + return isokay; +} + +/*! + Returns TRUE if the stream has received all the data from the + source; otherwise returns FALSE. +*/ +bool QNPStream::complete() const +{ + return iscomplete; +} + +/*! + Requests the section of the stream, of \a length bytes from \a + offset, be sent to the QNPInstance::write() function of the + instance() of this stream. +*/ +void QNPStream::requestRead(int offset, uint length) +{ + NPByteRange range; + range.offset = offset; + range.length = length; + range.next = 0; // ### Only one supported at this time + NPN_RequestRead(stream, &range); +} + +/*! + Writes \a len bytes from \a buffer \e to the stream. +*/ +int QNPStream::write( int len, void* buffer ) +{ + return NPN_Write(inst->pi->npp, stream, len, buffer); +} + + + +/****************************************************************************** + * The plugin itself - only one ever exists, created by QNPlugin::create() + *****************************************************************************/ + + +/*! + \class QNPlugin qnp.h + \brief The QNPlugin class provides the main factory for plugin objects. + + \extension Netscape Plugin + + This class is the heart of the plugin. One instance of this object + is created when the plugin is \e first needed, by calling + QNPlugin::create(), which must be implemented in your plugin code + to return some derived class of QNPlugin. The one QNPlugin object + creates all QNPInstance instances for a web browser running in a + single process. + + Additionally, if Qt is linked to the plugin as a dynamic library, + only one instance of QApplication will exist \e{across all plugins + that have been made with Qt}. So, your plugin should tread lightly + on global settings. Do not, for example, use + QApplication::setFont() - that will change the font in every + widget of every Qt-based plugin currently loaded! +*/ + +/*! + \fn QNPlugin* QNPlugin::create() + + This function must be implemented by your plugin code. It should return a + derived class of QNPlugin. +*/ + +/*! + Returns the plugin most recently returned by QNPlugin::create(). +*/ +QNPlugin* QNPlugin::actual() +{ + return qNP; +} + +/*! + Creates a QNPlugin. This may only be used by the constructor + of the class, derived from QNPlugin, that is returned by your + plugin's implementation of the QNPlugin::create() function. +*/ +QNPlugin::QNPlugin() +{ + // Encourage linker to include stuff. + static void* a; + a = (void*)NP_Initialize; + a = (void*)NP_Shutdown; +} + +/*! + Destroys the QNPlugin. This is called by the plugin binding code + just before the plugin is about to be unloaded from memory. If + newWindow() has been called, a QApplication will still exist at + this time, but will be deleted shortly after, just before the plugin + is deleted. +*/ +QNPlugin::~QNPlugin() +{ +} + +/*! + Populates \e *\a plugin_major and \e *\a plugin_minor with the + version of the plugin API and populates \e *\a browser_major and + \e *\a browser_minor with the version of the web browser. +*/ +void QNPlugin::getVersionInfo(int& plugin_major, int& plugin_minor, + int& browser_major, int& browser_minor) +{ + NPN_Version(&plugin_major, &plugin_minor, &browser_major, &browser_minor); +} + +/*! + \fn QNPInstance* QNPlugin::newInstance() + + Override this function to return an appropriate derived class of + QNPInstance. +*/ + +/*! + \fn const char* QNPlugin::getMIMEDescription() const + + Override this function to return the MIME description of the data formats + supported by your plugin. The format of this string is shown by + the following example: + +\code + const char* getMIMEDescription() const + { + return "image/x-png:png:PNG Image;" + "image/png:png:PNG Image;" + "image/x-portable-bitmap:pbm:PBM Image;" + "image/x-portable-graymap:pgm:PGM Image;" + "image/x-portable-pixmap:ppm:PPM Image;" + "image/bmp:bmp:BMP Image;" + "image/x-ms-bmp:bmp:BMP Image;" + "image/x-xpixmap:xpm:XPM Image;" + "image/xpm:xpm:XPM Image"; + } +\endcode +*/ + +/*! + \fn const char* QNPlugin::getPluginNameString() const + + Returns a pointer to the plain-text name of the plugin. +*/ + +/*! + \fn const char* QNPlugin::getPluginDescriptionString() const + + Returns a pointer to the plain-text description of the plugin. +*/ + +/*! + Override this function to return a reference to the Java class that represents + the plugin. The default returns 0, indicating no class. + + If you override this class, you must also override + QNPlugin::unuseJavaClass(). + + The return value is actually a \c{jref}; we use \c{void*} so as to + avoid burdening plugins which do not require Java. + + \sa getJavaEnv(), QNPInstance::getJavaPeer() +*/ +void* QNPlugin::getJavaClass() +{ + return NULL; +} + +/*! + This function is called when the plugin is shutting down. The + function should \e unuse the Java class returned earlier by + getJavaClass(). +*/ +void QNPlugin::unuseJavaClass() +{ + qFatal("QNPlugin::unuseJavaClass() must be overridden along with getJavaClass()"); +} + +/*! + Returns a pointer to the Java execution environment, or 0 if + either Java is disabled or an error occurred. + + The return value is actually a \c{JRIEnv*}; we use \c{void*} so as + to avoid burdening plugins which do not require Java. + + \sa getJavaClass(), QNPInstance::getJavaPeer() +*/ +void* QNPlugin::getJavaEnv() const +{ + return NPN_GetJavaEnv(); +} + +#ifdef Q_WS_X11 + +#include +#include + +// resolve the conflict between X11's FocusIn and QEvent::FocusIn +const int XFocusOut = FocusOut; +const int XFocusIn = FocusIn; +#undef FocusOut +#undef FocusIn + +const int XKeyPress = KeyPress; +const int XKeyRelease = KeyRelease; +#undef KeyPress +#undef KeyRelease + +Boolean qnpxt_event_dispatcher( XEvent *event ); +static void qnpxt_keep_alive(); +void qnpxt_timeout_handler( XtPointer, XtIntervalId * ); + +class QNPXtPrivate +{ +public: + QNPXtPrivate(); + + void hookMeUp(); + void unhook(); + + XtAppContext appContext, ownContext; + QMemArray dispatchers; + QWidgetIntDict mapper; + + QIntDict socknotDict; + uint pending_socknots; + bool activate_timers; + int timerid; + + // arguments for Xt display initialization + const char* applicationClass; + XrmOptionDescRec* options; + int numOptions; +}; +static QNPXtPrivate *static_d = 0; +static XEvent* last_xevent = 0; + + +bool QNPXt::redeliverEvent( XEvent *event ) +{ + // redeliver the event to Xt, NOT through Qt + if ( static_d->dispatchers[ event->type ]( event ) ) { + // qDebug( "Xt: redelivered event" ); + return TRUE; + } + return FALSE; +}; + + +XEvent* QNPXt::lastEvent() +{ + return last_xevent; +} + + +QNPXtPrivate::QNPXtPrivate() + : appContext(NULL), ownContext(NULL), + pending_socknots(0), activate_timers(FALSE), timerid(-1) +{ +} + +void QNPXtPrivate::hookMeUp() +{ + // worker to plug Qt into Xt (event dispatchers) + // and Xt into Qt (QNPXtEventLoop) + + // ### TODO extensions? + dispatchers.resize( LASTEvent ); + dispatchers.fill( 0 ); + int et; + for ( et = 2; et < LASTEvent; et++ ) + dispatchers[ et ] = + XtSetEventDispatcher( QPaintDevice::x11AppDisplay(), + et, ::qnpxt_event_dispatcher ); +} + +void QNPXtPrivate::unhook() +{ + // unhook Qt from Xt (event dispatchers) + // unhook Xt from Qt? (QNPXtEventLoop) + + // ### TODO extensions? + int et; + for ( et = 2; et < LASTEvent; et++ ) + (void) XtSetEventDispatcher( QPaintDevice::x11AppDisplay(), + et, dispatchers[ et ] ); + dispatchers.resize( 0 ); + + /* + We cannot destroy the app context here because it closes the X + display, something QApplication does as well a bit later. + if ( ownContext ) + XtDestroyApplicationContext( ownContext ); + */ + appContext = ownContext = 0; +} + +extern bool qt_try_modal( QWidget *, XEvent * ); // defined in qapplication_x11.cpp +Boolean qnpxt_event_dispatcher( XEvent *event ) +{ + static bool grabbed = FALSE; + + QApplication::sendPostedEvents(); + + QWidgetIntDict *mapper = &static_d->mapper; + QWidget* qnpxt = mapper->find( event->xany.window ); + if ( !qnpxt && QWidget::find( event->xany.window) == 0 ) { + // event is not for Qt, try Xt + Widget w = XtWindowToWidget( QPaintDevice::x11AppDisplay(), + event->xany.window ); + while ( w && ! ( qnpxt = mapper->find( XtWindow( w ) ) ) ) { + if ( XtIsShell( w ) ) { + break; + } + w = XtParent( w ); + } + + if ( qnpxt && ( event->type == XKeyPress || + event->type == XKeyRelease ) ) { + // remap key events to keep accelerators working + event->xany.window = qnpxt->winId(); + } + + if ( w ) { + if ( !grabbed && ( event->type == XFocusIn && + event->xfocus.mode == NotifyGrab ) ) { + // qDebug( "Xt: grab started" ); + grabbed = TRUE; + } else if ( grabbed && ( event->type == XFocusOut && + event->xfocus.mode == NotifyUngrab ) ) { + // qDebug( "Xt: grab ended" ); + grabbed = FALSE; + } + } + } + + /* + If the mouse has been grabbed for a window that we don't know + about, we shouldn't deliver any pointer events, since this will + intercept the event that ends the mouse grab that Xt/Motif + started. + */ + bool do_deliver = TRUE; + if ( grabbed && ( event->type == ButtonPress || + event->type == ButtonRelease || + event->type == MotionNotify || + event->type == EnterNotify || + event->type == LeaveNotify ) ) + do_deliver = FALSE; + + last_xevent = event; + bool delivered = do_deliver && ( qApp->x11ProcessEvent( event ) != -1 ); + last_xevent = 0; + if ( qnpxt ) { + switch ( event->type ) { + case EnterNotify: + case LeaveNotify: + event->xcrossing.focus = False; + delivered = FALSE; + break; + case XKeyPress: + case XKeyRelease: + delivered = TRUE; + break; + case XFocusIn: + case XFocusOut: + delivered = FALSE; + break; + default: + delivered = FALSE; + break; + } + } + + qnpxt_keep_alive(); + + if ( delivered ) { + // qDebug( "Qt: delivered event" ); + return True; + } + + // discard user input events when we have an active popup widget + if ( QApplication::activePopupWidget() ) { + switch ( event->type ) { + case ButtonPress: // disallow mouse/key events + case ButtonRelease: + case MotionNotify: + case XKeyPress: + case XKeyRelease: + case EnterNotify: + case LeaveNotify: + case ClientMessage: + // qDebug( "Qt: active popup - discarding event" ); + return True; + + default: + break; + } + } + + if ( QApplication::activeModalWidget() ) { + if ( qnpxt ) { + // send event through Qt modality handling... + if ( !qt_try_modal( qnpxt, event ) ) { + // qDebug( "Qt: active modal widget discarded event" ); + return True; + } + } else if ( !grabbed ) { + // we could have a pure Xt shell as a child of the active + // modal widget + QWidget *qw = 0; + Widget xw = XtWindowToWidget( QPaintDevice::x11AppDisplay(), + event->xany.window ); + while ( xw && !( qw = mapper->find( XtWindow( xw ) ) ) ) + xw = XtParent( xw ); + + while ( qw && qw != QApplication::activeModalWidget() ) + qw = qw->parentWidget(); + + if ( !qw ) { + // event is destined for an Xt widget, but since Qt has an + // active modal widget, we stop here... + switch ( event->type ) { + case ButtonPress: // disallow mouse/key events + case ButtonRelease: + case MotionNotify: + case XKeyPress: + case XKeyRelease: + case EnterNotify: + case LeaveNotify: + case ClientMessage: + // qDebug( "Qt: active modal widget discarded unknown event" ); + return True; + default: + break; + } + } + } + } + + if ( static_d->dispatchers[ event->type ]( event ) ) { + // qDebug( "Xt: delivered event" ); + // Xt handled the event. + return True; + } + + return False; +} + + + +QNPXt::QNPXt( const char *applicationClass, XtAppContext context, + XrmOptionDescRec *options , int numOptions) +{ +#if defined(QT_CHECK_STATE) + if ( static_d ) + qWarning( "QNPXt: should only have one QNPXt instance!" ); +#endif + + d = static_d = new QNPXtPrivate; + XtToolkitInitialize(); + if ( context ) + d->appContext = context; + else + d->ownContext = d->appContext = XtCreateApplicationContext(); + + d->applicationClass = applicationClass; + d->options = options; + d->numOptions = numOptions; +} + + +QNPXt::~QNPXt() +{ + delete d; + static_d = 0; +} + +XtAppContext QNPXt::applicationContext() const +{ + return d->appContext; +} + + +void QNPXt::appStartingUp() +{ + /* + QApplication could be using a Display from an outside source, so + we should only initialize the display if the current application + context does not contain the QApplication display + */ + + bool display_found = FALSE; + Display **displays; + Cardinal x, count; + XtGetDisplays( d->appContext, &displays, &count ); + for ( x = 0; x < count && ! display_found; ++x ) { + if ( displays[x] == QPaintDevice::x11AppDisplay() ) + display_found = TRUE; + } + if ( displays ) + XtFree( (char *) displays ); + + if ( ! display_found ) { + int argc = qApp->argc(); + XtDisplayInitialize( d->appContext, + QPaintDevice::x11AppDisplay(), + qApp->name(), + d->applicationClass, + d->options, + d->numOptions, + &argc, + qApp->argv() ); + } + + d->hookMeUp(); + + // start a zero-timer to get the timer keep-alive working + d->timerid = XtAppAddTimeOut( d->appContext, 0, qnpxt_timeout_handler, 0 ); +} + +void QNPXt::appClosingDown() +{ + if ( d->timerid != -1 ) + XtRemoveTimeOut( d->timerid ); + d->timerid = -1; + + d->unhook(); +} + + +void QNPXt::registerWidget( QWidget* w ) +{ + if ( !static_d ) + return; + static_d->mapper.insert( w->winId(), w ); +} + + +void QNPXt::unregisterWidget( QWidget* w ) +{ + if ( !static_d ) + return; + static_d->mapper.remove( w->winId() ); +} + + +void qnpxt_socknot_handler( XtPointer pointer, int *, XtInputId *id ) +{ + QNPXt *eventloop = (QNPXt *) pointer; + QSocketNotifier *socknot = static_d->socknotDict.find( *id ); + if ( ! socknot ) // this shouldn't happen + return; + eventloop->setSocketNotifierPending( socknot ); + if ( ++static_d->pending_socknots > static_d->socknotDict.count() ) { + /* + We have too many pending socket notifiers. Since Xt prefers + socket notifiers over X events, we should go ahead and + activate all our pending socket notifiers so that the event + loop doesn't freeze up because of this. + */ + eventloop->activateSocketNotifiers(); + static_d->pending_socknots = 0; + } +} + +void QNPXt::registerSocketNotifier( QSocketNotifier *notifier ) +{ + XtInputMask mask; + switch ( notifier->type() ) { + case QSocketNotifier::Read: + mask = XtInputReadMask; + break; + + case QSocketNotifier::Write: + mask = XtInputWriteMask; + break; + + case QSocketNotifier::Exception: + mask = XtInputExceptMask; + break; + + default: + qWarning( "QNPXtEventLoop: socket notifier has invalid type" ); + return; + } + + XtInputId id = XtAppAddInput( d->appContext, + notifier->socket(), (XtPointer) mask, + qnpxt_socknot_handler, this ); + d->socknotDict.insert( id, notifier ); + + QEventLoop::registerSocketNotifier( notifier ); +} + +void QNPXt::unregisterSocketNotifier( QSocketNotifier *notifier ) +{ + QIntDictIterator it( d->socknotDict ); + while ( it.current() && notifier != it.current() ) + ++it; + if ( ! it.current() ) { + // this shouldn't happen + qWarning( "QNPXtEventLoop: failed to unregister socket notifier" ); + return; + } + + XtRemoveInput( it.currentKey() ); + d->socknotDict.remove( it.currentKey() ); + + QEventLoop::unregisterSocketNotifier( notifier ); +} + +static void qnpxt_keep_alive() { + // make sure we fire off Qt's timers + int ttw = QApplication::eventLoop()->timeToWait(); + if ( static_d->timerid != -1 ) + XtRemoveTimeOut( static_d->timerid ); + static_d->timerid = -1; + if ( ttw != -1 ) { + static_d->timerid = + XtAppAddTimeOut( static_d->appContext, ttw, qnpxt_timeout_handler, 0 ); + } +} + +void qnpxt_timeout_handler( XtPointer, XtIntervalId * ) +{ + static_d->timerid = -1; + + if ( ! QApplication::eventLoop()->loopLevel() ) { + /* + when the Qt eventloop is not running, make sure that Qt + timers still work with an Xt keep-alive timer + */ + QApplication::eventLoop()->activateTimers(); + static_d->activate_timers = FALSE; + + qnpxt_keep_alive(); + } else { + static_d->activate_timers = TRUE; + } +} + +bool QNPXt::processEvents( ProcessEventsFlags flags ) +{ + // Qt uses posted events to do lots of delayed operations, like + // repaints... these need to be delivered before we go to sleep + QApplication::sendPostedEvents(); + + bool canWait = ( flags & WaitForMore ); + + qnpxt_keep_alive(); + + // get the pending event mask from Xt and process the next event + XtInputMask pendingmask = XtAppPending( d->appContext ); + XtInputMask mask = pendingmask; + if ( pendingmask & XtIMTimer ) { + mask &= ~XtIMTimer; + // zero timers will starve the Xt X event dispatcher... so + // process something *instead* of a timer first... + if ( mask != 0 ) + XtAppProcessEvent( d->appContext, mask ); + // and process a timer afterwards + mask = pendingmask & XtIMTimer; + } + + if ( canWait ) + XtAppProcessEvent( d->appContext, XtIMAll ); + else + XtAppProcessEvent( d->appContext, mask ); + + int nevents = 0; + if ( ! ( flags & ExcludeSocketNotifiers ) ) { + nevents += activateSocketNotifiers(); + d->pending_socknots = 0; + } + + if ( d->activate_timers ) { + nevents += activateTimers(); + } + d->activate_timers = FALSE; + + return ( canWait || ( pendingmask != 0 ) || nevents > 0 ); +} + + +#endif // Q_WS_X11 diff --git a/extensions/nsplugin/src/qnp.h b/extensions/nsplugin/src/qnp.h new file mode 100644 index 0000000..ba2d708 --- /dev/null +++ b/extensions/nsplugin/src/qnp.h @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Definition of Qt extension classes for Netscape Plugin support. +** +** Created : 970601 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QNP_H +#define QNP_H + +#ifndef QT_H +#include "qwidget.h" +#endif // QT_H + + +struct _NPInstance; +struct _NPStream; +class QNPInstance; + +class QNPStream { +public: + ~QNPStream(); + + const char* url() const; + uint end() const; + uint lastModified() const; + + const char* type() const; + bool seekable() const; + bool okay() const; + bool complete() const; + + void requestRead(int offset, uint length); + int write( int len, void* buffer ); + + QNPInstance* instance() { return inst; } + QNPStream(QNPInstance*,const char*,_NPStream*,bool); + void setOkay(bool); + void setComplete(bool); + +private: + QNPInstance* inst; + _NPStream* stream; + QString mtype; + int seek:1; + int isokay:1; + int iscomplete:1; +}; + +class QNPWidget : public QWidget { + Q_OBJECT +public: + QNPWidget(); + ~QNPWidget(); + void enterEvent(QEvent*); + void leaveEvent(QEvent*); + + virtual void enterInstance(); + virtual void leaveInstance(); + + QNPInstance* instance(); + +private: + _NPInstance* pi; +}; + +class QNPInstance : public QObject { + Q_OBJECT +public: + ~QNPInstance(); + + // Arguments passed to EMBED + int argc() const; + const char* argn(int) const; + const char* argv(int) const; + enum Reason { + ReasonDone = 0, + ReasonBreak = 1, + ReasonError = 2, + ReasonUnknown = -1 + }; + const char* arg(const char* name) const; + enum InstanceMode { Embed=1, Full=2, Background=3 }; + InstanceMode mode() const; + + // The browser's name + const char* userAgent() const; + + // Your window. + virtual QNPWidget* newWindow(); + QNPWidget* widget(); + + // Incoming streams (SRC=... tag). + // Defaults ignore data. + enum StreamMode { Normal=1, Seek=2, AsFile=3, AsFileOnly=4 }; + virtual bool newStreamCreated(QNPStream*, StreamMode& smode); + virtual int writeReady(QNPStream*); + virtual int write(QNPStream*, int offset, int len, void* buffer); + virtual void streamDestroyed(QNPStream*); + + void status(const char* msg); + void getURLNotify(const char* url, const char* window=0, void*data=0); + + void getURL(const char* url, const char* window=0); + void postURL(const char* url, const char* window, + uint len, const char* buf, bool file); + + QNPStream* newStream(const char* mimetype, const char* window, + bool as_file=FALSE); + virtual void streamAsFile(QNPStream*, const char* fname); + + void* getJavaPeer() const; + + virtual void notifyURL(const char* url, Reason r, void* notifyData); + virtual bool printFullPage(); + virtual void print(QPainter*); + +protected: + QNPInstance(); + +private: + friend class QNPStream; + _NPInstance* pi; +}; + + +class QNPlugin { +public: + // Write this to return your QNPlugin derived class. + static QNPlugin* create(); + + static QNPlugin* actual(); + + virtual ~QNPlugin(); + + void getVersionInfo(int& plugin_major, int& plugin_minor, + int& browser_major, int& browser_minor); + + virtual QNPInstance* newInstance()=0; + virtual const char* getMIMEDescription() const=0; + virtual const char* getPluginNameString() const=0; + virtual const char* getPluginDescriptionString() const=0; + + virtual void* getJavaClass(); + virtual void unuseJavaClass(); + void* getJavaEnv() const; + +protected: + QNPlugin(); +}; + + +#endif // QNP_H diff --git a/extensions/nsplugin/src/qnp.pro b/extensions/nsplugin/src/qnp.pro new file mode 100644 index 0000000..1aedef5 --- /dev/null +++ b/extensions/nsplugin/src/qnp.pro @@ -0,0 +1,14 @@ +TEMPLATE = lib +TARGET = qnp + +CONFIG -= dll +CONFIG += qt x11 release staticlib +DESTDIR = ../../../lib +VERSION = 0.4 + +SOURCES = qnp.cpp +unix:HEADERS += qnp.h +win32:HEADERS = ../../../include/qnp.h +win32:LIBS += -lqtmain +MOC_DIR = . +DESTINCDIR = ../../../include -- cgit v1.2.3