aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/native/plugin
diff options
context:
space:
mode:
authorThomas Fitzsimmons <fitzsim@redhat.com>2006-06-09 16:07:07 +0000
committerThomas Fitzsimmons <fitzsim@gcc.gnu.org>2006-06-09 16:07:07 +0000
commit02440ca432f1aa4de7aeda563d2493a20148554b (patch)
tree0802013820f309170e8ae5584b09e9672bab2cb6 /libjava/classpath/native/plugin
parent6c65d7577ca4e36675571fd8bad43ef6d34e2831 (diff)
downloadgcc-02440ca432f1aa4de7aeda563d2493a20148554b.zip
gcc-02440ca432f1aa4de7aeda563d2493a20148554b.tar.gz
gcc-02440ca432f1aa4de7aeda563d2493a20148554b.tar.bz2
String.java, [...]: Merge from GNU Classpath HEAD.
2006-06-09 Thomas Fitzsimmons <fitzsim@redhat.com> * java/lang/String.java, classpath/native/jni/classpath/jcl.h, classpath/native/jni/qt-peer/eventmethods.h, classpath/native/jni/qt-peer/qtmenupeer.cpp, classpath/native/jni/qt-peer/.cvsignore, classpath/native/jni/gtk-peer/gdkdisplay.h, classpath/native/jni/gtk-peer/cairographics2d.h, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c, classpath/native/jni/gtk-peer/.cvsignore, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c, classpath/native/jni/gtk-peer/gtkpeer.h, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c, classpath/native/jni/gtk-peer/Makefile.am, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c, classpath/native/jawt/Makefile.am, classpath/native/jawt/.cvsignore, classpath/native/target/Linux/Makefile.in, classpath/native/plugin/gcjwebplugin.cc, classpath/native/plugin/Makefile.am, classpath/native/plugin/.cvsignore, classpath/resource/Makefile.in, classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java, classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java, classpath/gnu/java/awt/peer/gtk/CairoSurface.java, classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java, classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java, classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java, classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java, classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java, classpath/gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java, classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java, classpath/gnu/java/awt/peer/gtk/GdkGraphics.java, classpath/gnu/java/awt/peer/gtk/GtkToolkit.java, classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java, classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java, classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java, classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java, classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java, classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java, classpath/gnu/java/awt/peer/gtk/GtkImage.java, classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java, classpath/gnu/java/awt/peer/gtk/GdkGlyphVector.java, classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java, classpath/gnu/java/awt/peer/swing/SwingContainerPeer.java, classpath/gnu/java/awt/peer/swing/SwingComponent.java, classpath/gnu/java/awt/peer/swing/SwingTextFieldPeer.java, classpath/gnu/java/awt/peer/swing/SwingMenuBarPeer.java, classpath/gnu/java/awt/peer/swing/SwingFramePeer.java, classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java, classpath/gnu/java/awt/peer/swing/SwingWindowPeer.java, classpath/gnu/java/awt/print/JavaPrinterJob.java, classpath/gnu/java/awt/print/PostScriptGraphics2D.java, classpath/gnu/java/awt/print/SpooledDocument.java, classpath/gnu/java/awt/print/JavaPrinterGraphics.java, classpath/gnu/java/awt/BitwiseXORComposite.java, classpath/gnu/java/awt/font/GNUGlyphVector.java, classpath/gnu/java/awt/font/opentype/NameDecoder.java, classpath/gnu/java/awt/java2d/RasterGraphics.java, classpath/gnu/java/awt/java2d/TexturePaintContext.java, classpath/gnu/java/awt/java2d/PolyEdge.java, classpath/gnu/java/awt/java2d/AbstractGraphics2D.java, classpath/gnu/java/awt/java2d/AlphaCompositeContext.java, classpath/gnu/java/awt/java2d/ImagePaint.java, classpath/gnu/java/awt/Buffers.java, classpath/gnu/classpath/Configuration.java.in, classpath/gnu/javax/swing/text/html/CombinedAttributes.java, classpath/gnu/javax/swing/text/html/CharacterAttributeTranslator.java, classpath/gnu/javax/swing/text/html/parser/htmlAttributeSet.java, classpath/gnu/javax/swing/text/html/parser/SmallHtmlAttributeSet.java, classpath/gnu/javax/swing/text/html/ImageViewIconFactory.java, classpath/tools/toolwrapper.c, classpath/tools/gnu/classpath/tools/native2ascii/Native2ASCII.java, classpath/tools/gnu/classpath/tools/native2ascii/Messages.java, classpath/tools/gnu/classpath/tools/getopt/FileArgumentCallback.java, classpath/tools/gnu/classpath/tools/getopt/OptionGroup.java, classpath/tools/gnu/classpath/tools/getopt/OptionException.java, classpath/tools/gnu/classpath/tools/getopt/Messages.java, classpath/tools/gnu/classpath/tools/getopt/Option.java, classpath/tools/gnu/classpath/tools/getopt/Parser.java, classpath/tools/gnu/classpath/tools/getopt/ClasspathToolParser.java, classpath/tools/gnu/classpath/tools/jarsigner/JarSigner.java, classpath/tools/gnu/classpath/tools/jarsigner/Main.java, classpath/tools/gnu/classpath/tools/jarsigner/Messages.java, classpath/tools/gnu/classpath/tools/jarsigner/package.html, classpath/tools/gnu/classpath/tools/keytool/ListCmd.java, classpath/tools/gnu/classpath/tools/keytool/StorePasswdCmd.java, classpath/tools/gnu/classpath/tools/keytool/ExportCmd.java, classpath/tools/gnu/classpath/tools/keytool/GenKeyCmd.java, classpath/tools/gnu/classpath/tools/keytool/Messages.java, classpath/tools/gnu/classpath/tools/keytool/package.html, classpath/tools/gnu/classpath/tools/keytool/Command.java, classpath/tools/gnu/classpath/tools/keytool/IdentityDBCmd.java, classpath/tools/gnu/classpath/tools/keytool/Main.java, classpath/tools/gnu/classpath/tools/keytool/DeleteCmd.java, classpath/tools/gnu/classpath/tools/keytool/CertReqCmd.java, classpath/tools/gnu/classpath/tools/keytool/SelfCertCmd.java, classpath/tools/gnu/classpath/tools/keytool/KeyCloneCmd.java, classpath/tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java, classpath/tools/gnu/classpath/tools/keytool/ImportCmd.java, classpath/tools/gnu/classpath/tools/keytool/PrintCertCmd.java, classpath/tools/gnu/classpath/tools/rmi/registry/package.html, classpath/tools/gnu/classpath/tools/rmi/RMIC.txt, classpath/tools/gnu/classpath/tools/rmi/RMIC.java, classpath/tools/gnu/classpath/tools/appletviewer/ErrorApplet.java, classpath/tools/gnu/classpath/tools/appletviewer/AppletClassLoader.java, classpath/tools/gnu/classpath/tools/appletviewer/CommonAppletContext.java, classpath/tools/gnu/classpath/tools/appletviewer/StandaloneAppletContext.java, classpath/tools/gnu/classpath/tools/appletviewer/AppletSecurityManager.java, classpath/tools/gnu/classpath/tools/appletviewer/PluginAppletContext.java, classpath/tools/gnu/classpath/tools/appletviewer/AppletWarning.java, classpath/tools/gnu/classpath/tools/appletviewer/StandaloneAppletViewer.java, classpath/tools/gnu/classpath/tools/appletviewer/AppletTag.java, classpath/tools/gnu/classpath/tools/appletviewer/ConsoleDialog.java, classpath/tools/gnu/classpath/tools/appletviewer/Main.java, classpath/tools/gnu/classpath/tools/appletviewer/StandaloneAppletWindow.java, classpath/tools/gnu/classpath/tools/appletviewer/PluginAppletViewer.java, classpath/tools/gnu/classpath/tools/appletviewer/TagParser.java, classpath/tools/gnu/classpath/tools/appletviewer/PluginAppletWindow.java, classpath/tools/gnu/classpath/tools/appletviewer/CommonAppletStub.java, classpath/tools/gnu/classpath/tools/serialver/Messages.java, classpath/tools/gnu/classpath/tools/serialver/SerialVer.java, classpath/tools/gnu/classpath/tools/jar/Creator.java, classpath/tools/gnu/classpath/tools/jar/Entry.java, classpath/tools/gnu/classpath/tools/jar/Lister.java, classpath/tools/gnu/classpath/tools/jar/Main.java, classpath/tools/gnu/classpath/tools/jar/Updater.java, classpath/tools/gnu/classpath/tools/jar/Messages.java, classpath/tools/gnu/classpath/tools/jar/Extractor.java, classpath/tools/gnu/classpath/tools/jar/Action.java, classpath/tools/gnu/classpath/tools/jar/Indexer.java, classpath/tools/gnu/classpath/tools/jar/WorkSet.java, classpath/tools/gnu/classpath/tools/giop/GRMIC.txt, classpath/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java, classpath/tools/gnu/classpath/tools/giop/GRMIC.java, classpath/tools/Makefile.am, classpath/tools/jarsigner.in, classpath/tools/keytool.in, classpath/tools/appletviewer.in, classpath/tools/.cvsignore, classpath/configure.ac, classpath/javax/swing/JTabbedPane.java, classpath/javax/swing/AbstractButton.java, classpath/javax/swing/JViewport.java, classpath/javax/swing/KeyboardManager.java, classpath/javax/swing/JMenuItem.java, classpath/javax/swing/JMenuBar.java, classpath/javax/swing/MenuSelectionManager.java, classpath/javax/swing/JOptionPane.java, classpath/javax/swing/JSpinner.java, classpath/javax/swing/JCheckBoxMenuItem.java, classpath/javax/swing/JEditorPane.java, classpath/javax/swing/JFormattedTextField.java, classpath/javax/swing/JTree.java, classpath/javax/swing/CellRendererPane.java, classpath/javax/swing/JScrollPane.java, classpath/javax/swing/tree/VariableHeightLayoutCache.java, classpath/javax/swing/tree/TreeNode.java, classpath/javax/swing/tree/FixedHeightLayoutCache.java, classpath/javax/swing/tree/DefaultTreeCellEditor.java, classpath/javax/swing/tree/TreePath.java, classpath/javax/swing/tree/RowMapper.java, classpath/javax/swing/tree/DefaultMutableTreeNode.java, classpath/javax/swing/tree/DefaultTreeModel.java, classpath/javax/swing/tree/AbstractLayoutCache.java, classpath/javax/swing/tree/TreeSelectionModel.java, classpath/javax/swing/tree/DefaultTreeSelectionModel.java, classpath/javax/swing/tree/DefaultTreeCellRenderer.java, classpath/javax/swing/tree/ExpandVetoException.java, classpath/javax/swing/JList.java, classpath/javax/swing/table/JTableHeader.java, classpath/javax/swing/table/AbstractTableModel.java, classpath/javax/swing/table/DefaultTableModel.java, classpath/javax/swing/table/TableCellEditor.java, classpath/javax/swing/table/TableCellRenderer.java, classpath/javax/swing/ProgressMonitor.java, classpath/javax/swing/JToolBar.java, classpath/javax/swing/TransferHandler.java, classpath/javax/swing/DefaultCellEditor.java, classpath/javax/swing/DefaultButtonModel.java, classpath/javax/swing/JLayeredPane.java, classpath/javax/swing/text/DefaultEditorKit.java, classpath/javax/swing/text/DefaultCaret.java, classpath/javax/swing/text/FieldView.java, classpath/javax/swing/text/JTextComponent.java, classpath/javax/swing/text/TextAction.java, classpath/javax/swing/text/StyleContext.java, classpath/javax/swing/text/html/HTMLDocument.java, classpath/javax/swing/text/html/MinimalHTMLWriter.java, classpath/javax/swing/text/html/ImageView.java, classpath/javax/swing/text/html/HTMLEditorKit.java, classpath/javax/swing/text/AbstractWriter.java, classpath/javax/swing/text/GapContent.java, classpath/javax/swing/text/Utilities.java, classpath/javax/swing/text/PlainView.java, classpath/javax/swing/UIManager.java, classpath/javax/swing/JSplitPane.java, classpath/javax/swing/JComponent.java, classpath/javax/swing/SwingUtilities.java, classpath/javax/swing/border/AbstractBorder.java, classpath/javax/swing/border/CompoundBorder.java, classpath/javax/swing/border/TitledBorder.java, classpath/javax/swing/border/MatteBorder.java, classpath/javax/swing/border/BevelBorder.java, classpath/javax/swing/RepaintManager.java, classpath/javax/swing/JTable.java, classpath/javax/swing/UIDefaults.java, classpath/javax/swing/DefaultDesktopManager.java, classpath/javax/swing/JMenu.java, classpath/javax/swing/JLabel.java, classpath/javax/swing/JSlider.java, classpath/javax/swing/plaf/basic/BasicToolBarUI.java, classpath/javax/swing/plaf/basic/BasicButtonUI.java, classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java, classpath/javax/swing/plaf/basic/BasicTextAreaUI.java, classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java, classpath/javax/swing/plaf/basic/BasicSpinnerUI.java, classpath/javax/swing/plaf/basic/BasicSliderUI.java, classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java, classpath/javax/swing/plaf/basic/BasicComboPopup.java, classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java, classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java, classpath/javax/swing/plaf/basic/BasicProgressBarUI.java, classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java, classpath/javax/swing/plaf/basic/BasicPanelUI.java, classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java, classpath/javax/swing/plaf/basic/BasicTreeUI.java, classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java, classpath/javax/swing/plaf/basic/BasicFileChooserUI.java, classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java, classpath/javax/swing/plaf/basic/BasicComboBoxUI.java, classpath/javax/swing/plaf/basic/BasicListUI.java, classpath/javax/swing/plaf/basic/BasicIconFactory.java, classpath/javax/swing/plaf/basic/BasicTextUI.java, classpath/javax/swing/plaf/basic/BasicLookAndFeel.java, classpath/javax/swing/plaf/basic/BasicDirectoryModel.java, classpath/javax/swing/plaf/basic/BasicRootPaneUI.java, classpath/javax/swing/plaf/basic/BasicTableUI.java, classpath/javax/swing/plaf/basic/SharedUIDefaults.java, classpath/javax/swing/plaf/multi/MultiComboBoxUI.java, classpath/javax/swing/plaf/multi/MultiListUI.java, classpath/javax/swing/plaf/multi/MultiSplitPaneUI.java, classpath/javax/swing/plaf/multi/MultiFileChooserUI.java, classpath/javax/swing/plaf/multi/MultiOptionPaneUI.java, classpath/javax/swing/plaf/multi/MultiTabbedPaneUI.java, classpath/javax/swing/plaf/multi/MultiLookAndFeel.java, classpath/javax/swing/plaf/metal/MetalSliderUI.java, classpath/javax/swing/plaf/metal/MetalIconFactory.java, classpath/javax/swing/plaf/metal/MetalComboBoxIcon.java, classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java, classpath/javax/swing/plaf/metal/MetalLookAndFeel.java, classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java, classpath/javax/swing/plaf/metal/MetalSeparatorUI.java, classpath/javax/swing/plaf/metal/MetalBorders.java, classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java, classpath/javax/swing/plaf/metal/MetalScrollBarUI.java, classpath/javax/swing/plaf/metal/MetalRootPaneUI.java, classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java, classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java, classpath/javax/swing/plaf/metal/MetalToolTipUI.java, classpath/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java, classpath/javax/swing/plaf/metal/MetalFileChooserUI.java, classpath/javax/swing/plaf/metal/MetalUtils.java, classpath/javax/swing/plaf/metal/MetalComboBoxButton.java, classpath/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java, classpath/javax/swing/plaf/metal/MetalButtonUI.java, classpath/javax/swing/JPopupMenu.java, classpath/javax/swing/JProgressBar.java, classpath/javax/swing/WindowConstants.java, classpath/javax/swing/JFrame.java, classpath/javax/swing/JFileChooser.java, classpath/javax/swing/JComboBox.java, classpath/javax/swing/event/EventListenerList.java, classpath/javax/swing/ListSelectionModel.java, classpath/javax/swing/JScrollBar.java, classpath/java/text/SimpleDateFormat.java, classpath/java/text/NumberFormat.java, classpath/java/text/class-dependencies.conf, classpath/java/awt/image/ColorModel.java, classpath/java/awt/image/BufferedImage.java, classpath/java/awt/Window.java, classpath/java/awt/ContainerOrderFocusTraversalPolicy.java, classpath/java/awt/LightweightDispatcher.java, classpath/java/awt/EventDispatchThread.java, classpath/java/awt/BasicStroke.java, classpath/java/awt/ColorPaintContext.java, classpath/java/awt/Container.java, classpath/java/awt/TexturePaint.java, classpath/java/awt/Component.java, classpath/java/awt/Font.java, classpath/java/awt/GraphicsConfiguration.java, classpath/java/awt/DefaultKeyboardFocusManager.java, classpath/java/awt/print/PrinterJob.java, classpath/java/awt/im/InputContext.java, classpath/java/awt/dnd/DragGestureRecognizer.java, classpath/java/awt/Toolkit.java, classpath/java/awt/font/GraphicAttribute.java, classpath/java/awt/font/ImageGraphicAttribute.java, classpath/java/awt/font/GlyphVector.java, classpath/java/awt/font/GlyphMetrics.java, classpath/java/awt/font/ShapeGraphicAttribute.java, classpath/java/awt/Graphics2D.java, classpath/include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h, classpath/include/gnu_java_awt_peer_gtk_ComponentGraphics.h, classpath/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h, classpath/include/gnu_java_awt_peer_gtk_FreetypeGlyphVector.h, classpath/include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h, classpath/include/config.h.in, classpath/include/gnu_java_awt_peer_gtk_GdkTextLayout.h, classpath/include/gnu_java_awt_peer_gtk_GtkComponentPeer.h, classpath/include/gnu_java_awt_peer_gtk_GdkFontPeer.h, classpath/include/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h, classpath/include/gnu_java_awt_peer_gtk_GtkVolatileImage.h, classpath/include/gnu_java_awt_peer_gtk_GtkImage.h, classpath/include/gnu_java_awt_peer_gtk_CairoSurface.h, classpath/include/gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.h: Merge from GNU Classpath HEAD. From-SVN: r114510
Diffstat (limited to 'libjava/classpath/native/plugin')
-rw-r--r--libjava/classpath/native/plugin/.cvsignore6
-rw-r--r--libjava/classpath/native/plugin/Makefile.am19
-rw-r--r--libjava/classpath/native/plugin/Makefile.in596
-rw-r--r--libjava/classpath/native/plugin/gcjwebplugin.cc1759
4 files changed, 2380 insertions, 0 deletions
diff --git a/libjava/classpath/native/plugin/.cvsignore b/libjava/classpath/native/plugin/.cvsignore
new file mode 100644
index 0000000..17cbfe8
--- /dev/null
+++ b/libjava/classpath/native/plugin/.cvsignore
@@ -0,0 +1,6 @@
+Makefile.in
+.deps
+.libs
+libgcjwebplugin_la-gcjwebplugin.lo
+libgcjwebplugin.la
+Makefile
diff --git a/libjava/classpath/native/plugin/Makefile.am b/libjava/classpath/native/plugin/Makefile.am
new file mode 100644
index 0000000..19c7618
--- /dev/null
+++ b/libjava/classpath/native/plugin/Makefile.am
@@ -0,0 +1,19 @@
+lib_LTLIBRARIES = libgcjwebplugin.la
+
+libgcjwebplugin_la_SOURCES = gcjwebplugin.cc
+
+libgcjwebplugin_la_CXXFLAGS = \
+ -Wall -DAPPLETVIEWER_EXECUTABLE="\"$(bindir)/appletviewer\"" \
+ -DPLUGIN_DATA_DIRECTORY="\"$(PLUGIN_DIR)/gcjwebplugin-data\"" \
+ $(MOZILLA_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS)
+
+libgcjwebplugin_la_LDFLAGS = -avoid-version \
+ $(GLIB_LIBS) $(GTK_LIBS) \
+ -lstdc++
+
+install-plugin: $(lib_LTLIBRARIES)
+ $(INSTALL) -d -m0755 $(DESTDIR)$(PLUGIN_DIR)
+ $(INSTALL) .libs/libgcjwebplugin.so $(DESTDIR)$(PLUGIN_DIR)
+
+uninstall-plugin:
+ rm -f $(DESTDIR)$(PLUGIN_DIR)/libgcjwebplugin.so
diff --git a/libjava/classpath/native/plugin/Makefile.in b/libjava/classpath/native/plugin/Makefile.in
new file mode 100644
index 0000000..22b8d3d
--- /dev/null
+++ b/libjava/classpath/native/plugin/Makefile.in
@@ -0,0 +1,596 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = native/plugin
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../../libtool.m4 \
+ $(top_srcdir)/m4/acattribute.m4 $(top_srcdir)/m4/accross.m4 \
+ $(top_srcdir)/m4/acinclude.m4 \
+ $(top_srcdir)/m4/ax_create_stdint_h.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/include/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libgcjwebplugin_la_LIBADD =
+am_libgcjwebplugin_la_OBJECTS = libgcjwebplugin_la-gcjwebplugin.lo
+libgcjwebplugin_la_OBJECTS = $(am_libgcjwebplugin_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libgcjwebplugin_la_SOURCES)
+DIST_SOURCES = $(libgcjwebplugin_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_CLASS_FILES_FALSE = @BUILD_CLASS_FILES_FALSE@
+BUILD_CLASS_FILES_TRUE = @BUILD_CLASS_FILES_TRUE@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CLASSPATH_CONVENIENCE = @CLASSPATH_CONVENIENCE@
+CLASSPATH_INCLUDES = @CLASSPATH_INCLUDES@
+CLASSPATH_MODULE = @CLASSPATH_MODULE@
+COLLECTIONS_PREFIX = @COLLECTIONS_PREFIX@
+CP = @CP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CREATE_ALSA_LIBRARIES_FALSE = @CREATE_ALSA_LIBRARIES_FALSE@
+CREATE_ALSA_LIBRARIES_TRUE = @CREATE_ALSA_LIBRARIES_TRUE@
+CREATE_API_DOCS_FALSE = @CREATE_API_DOCS_FALSE@
+CREATE_API_DOCS_TRUE = @CREATE_API_DOCS_TRUE@
+CREATE_COLLECTIONS_FALSE = @CREATE_COLLECTIONS_FALSE@
+CREATE_COLLECTIONS_TRUE = @CREATE_COLLECTIONS_TRUE@
+CREATE_CORE_JNI_LIBRARIES_FALSE = @CREATE_CORE_JNI_LIBRARIES_FALSE@
+CREATE_CORE_JNI_LIBRARIES_TRUE = @CREATE_CORE_JNI_LIBRARIES_TRUE@
+CREATE_DSSI_LIBRARIES_FALSE = @CREATE_DSSI_LIBRARIES_FALSE@
+CREATE_DSSI_LIBRARIES_TRUE = @CREATE_DSSI_LIBRARIES_TRUE@
+CREATE_GTK_PEER_LIBRARIES_FALSE = @CREATE_GTK_PEER_LIBRARIES_FALSE@
+CREATE_GTK_PEER_LIBRARIES_TRUE = @CREATE_GTK_PEER_LIBRARIES_TRUE@
+CREATE_JNI_HEADERS_FALSE = @CREATE_JNI_HEADERS_FALSE@
+CREATE_JNI_HEADERS_TRUE = @CREATE_JNI_HEADERS_TRUE@
+CREATE_JNI_LIBRARIES_FALSE = @CREATE_JNI_LIBRARIES_FALSE@
+CREATE_JNI_LIBRARIES_TRUE = @CREATE_JNI_LIBRARIES_TRUE@
+CREATE_PLUGIN_FALSE = @CREATE_PLUGIN_FALSE@
+CREATE_PLUGIN_TRUE = @CREATE_PLUGIN_TRUE@
+CREATE_QT_PEER_LIBRARIES_FALSE = @CREATE_QT_PEER_LIBRARIES_FALSE@
+CREATE_QT_PEER_LIBRARIES_TRUE = @CREATE_QT_PEER_LIBRARIES_TRUE@
+CREATE_WRAPPERS_FALSE = @CREATE_WRAPPERS_FALSE@
+CREATE_WRAPPERS_TRUE = @CREATE_WRAPPERS_TRUE@
+CREATE_XMLJ_LIBRARY_FALSE = @CREATE_XMLJ_LIBRARY_FALSE@
+CREATE_XMLJ_LIBRARY_TRUE = @CREATE_XMLJ_LIBRARY_TRUE@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATE = @DATE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECJ = @ECJ@
+EGREP = @EGREP@
+ENABLE_LOCAL_SOCKETS_FALSE = @ENABLE_LOCAL_SOCKETS_FALSE@
+ENABLE_LOCAL_SOCKETS_TRUE = @ENABLE_LOCAL_SOCKETS_TRUE@
+ERROR_CFLAGS = @ERROR_CFLAGS@
+EXAMPLESDIR = @EXAMPLESDIR@
+EXEEXT = @EXEEXT@
+FASTJAR = @FASTJAR@
+FIND = @FIND@
+FOUND_CACAO_FALSE = @FOUND_CACAO_FALSE@
+FOUND_CACAO_TRUE = @FOUND_CACAO_TRUE@
+FOUND_ECJ_FALSE = @FOUND_ECJ_FALSE@
+FOUND_ECJ_TRUE = @FOUND_ECJ_TRUE@
+FOUND_GCJX_FALSE = @FOUND_GCJX_FALSE@
+FOUND_GCJX_TRUE = @FOUND_GCJX_TRUE@
+FOUND_GCJ_FALSE = @FOUND_GCJ_FALSE@
+FOUND_GCJ_TRUE = @FOUND_GCJ_TRUE@
+FOUND_JIKES_FALSE = @FOUND_JIKES_FALSE@
+FOUND_JIKES_TRUE = @FOUND_JIKES_TRUE@
+FOUND_KJC_FALSE = @FOUND_KJC_FALSE@
+FOUND_KJC_TRUE = @FOUND_KJC_TRUE@
+FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@
+FREETYPE2_LIBS = @FREETYPE2_LIBS@
+GCJ = @GCJ@
+GCJX = @GCJX@
+GJDOC = @GJDOC@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_LIBS = @GLIB_LIBS@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+INIT_LOAD_LIBRARY = @INIT_LOAD_LIBRARY@
+INSTALL_CLASS_FILES_FALSE = @INSTALL_CLASS_FILES_FALSE@
+INSTALL_CLASS_FILES_TRUE = @INSTALL_CLASS_FILES_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_GLIBJ_ZIP_FALSE = @INSTALL_GLIBJ_ZIP_FALSE@
+INSTALL_GLIBJ_ZIP_TRUE = @INSTALL_GLIBJ_ZIP_TRUE@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION = @JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION@
+JAY = @JAY@
+JAY_SKELETON = @JAY_SKELETON@
+JIKES = @JIKES@
+JIKESENCODING = @JIKESENCODING@
+JIKESWARNINGS = @JIKESWARNINGS@
+KJC = @KJC@
+LDFLAGS = @LDFLAGS@
+LIBDEBUG = @LIBDEBUG@
+LIBICONV = @LIBICONV@
+LIBMAGIC = @LIBMAGIC@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBVERSION = @LIBVERSION@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MKDIR = @MKDIR@
+MOC = @MOC@
+MOZILLA_CFLAGS = @MOZILLA_CFLAGS@
+MOZILLA_LIBS = @MOZILLA_LIBS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@
+PANGOFT2_LIBS = @PANGOFT2_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PATH_TO_GLIBJ_ZIP = @PATH_TO_GLIBJ_ZIP@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PLUGIN_DIR = @PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
+RANLIB = @RANLIB@
+REGEN_PARSERS_FALSE = @REGEN_PARSERS_FALSE@
+REGEN_PARSERS_TRUE = @REGEN_PARSERS_TRUE@
+REMOVE = @REMOVE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRICT_WARNING_CFLAGS = @STRICT_WARNING_CFLAGS@
+STRIP = @STRIP@
+USER_CLASSLIB = @USER_CLASSLIB@
+USER_JAVAH = @USER_JAVAH@
+USER_SPECIFIED_CLASSLIB_FALSE = @USER_SPECIFIED_CLASSLIB_FALSE@
+USER_SPECIFIED_CLASSLIB_TRUE = @USER_SPECIFIED_CLASSLIB_TRUE@
+USER_SPECIFIED_JAVAH_FALSE = @USER_SPECIFIED_JAVAH_FALSE@
+USER_SPECIFIED_JAVAH_TRUE = @USER_SPECIFIED_JAVAH_TRUE@
+USE_PREBUILT_GLIBJ_ZIP_FALSE = @USE_PREBUILT_GLIBJ_ZIP_FALSE@
+USE_PREBUILT_GLIBJ_ZIP_TRUE = @USE_PREBUILT_GLIBJ_ZIP_TRUE@
+VERSION = @VERSION@
+VM_BINARY = @VM_BINARY@
+WARNING_CFLAGS = @WARNING_CFLAGS@
+XML_CFLAGS = @XML_CFLAGS@
+XML_LIBS = @XML_LIBS@
+XSLT_CFLAGS = @XSLT_CFLAGS@
+XSLT_LIBS = @XSLT_LIBS@
+XTEST_LIBS = @XTEST_LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+ZIP = @ZIP@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+default_toolkit = @default_toolkit@
+exec_prefix = @exec_prefix@
+glibjdir = @glibjdir@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nativeexeclibdir = @nativeexeclibdir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+vm_classes = @vm_classes@
+lib_LTLIBRARIES = libgcjwebplugin.la
+libgcjwebplugin_la_SOURCES = gcjwebplugin.cc
+libgcjwebplugin_la_CXXFLAGS = \
+ -Wall -DAPPLETVIEWER_EXECUTABLE="\"$(bindir)/appletviewer\"" \
+ -DPLUGIN_DATA_DIRECTORY="\"$(PLUGIN_DIR)/gcjwebplugin-data\"" \
+ $(MOZILLA_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS)
+
+libgcjwebplugin_la_LDFLAGS = -avoid-version \
+ $(GLIB_LIBS) $(GTK_LIBS) \
+ -lstdc++
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu native/plugin/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu native/plugin/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libgcjwebplugin.la: $(libgcjwebplugin_la_OBJECTS) $(libgcjwebplugin_la_DEPENDENCIES)
+ $(CXXLINK) -rpath $(libdir) $(libgcjwebplugin_la_LDFLAGS) $(libgcjwebplugin_la_OBJECTS) $(libgcjwebplugin_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcjwebplugin_la-gcjwebplugin.Plo@am__quote@
+
+.cc.o:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+libgcjwebplugin_la-gcjwebplugin.lo: gcjwebplugin.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcjwebplugin_la_CXXFLAGS) $(CXXFLAGS) -MT libgcjwebplugin_la-gcjwebplugin.lo -MD -MP -MF "$(DEPDIR)/libgcjwebplugin_la-gcjwebplugin.Tpo" -c -o libgcjwebplugin_la-gcjwebplugin.lo `test -f 'gcjwebplugin.cc' || echo '$(srcdir)/'`gcjwebplugin.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libgcjwebplugin_la-gcjwebplugin.Tpo" "$(DEPDIR)/libgcjwebplugin_la-gcjwebplugin.Plo"; else rm -f "$(DEPDIR)/libgcjwebplugin_la-gcjwebplugin.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='gcjwebplugin.cc' object='libgcjwebplugin_la-gcjwebplugin.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcjwebplugin_la_CXXFLAGS) $(CXXFLAGS) -c -o libgcjwebplugin_la-gcjwebplugin.lo `test -f 'gcjwebplugin.cc' || echo '$(srcdir)/'`gcjwebplugin.cc
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-info-am \
+ uninstall-libLTLIBRARIES
+
+
+install-plugin: $(lib_LTLIBRARIES)
+ $(INSTALL) -d -m0755 $(DESTDIR)$(PLUGIN_DIR)
+ $(INSTALL) .libs/libgcjwebplugin.so $(DESTDIR)$(PLUGIN_DIR)
+
+uninstall-plugin:
+ rm -f $(DESTDIR)$(PLUGIN_DIR)/libgcjwebplugin.so
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libjava/classpath/native/plugin/gcjwebplugin.cc b/libjava/classpath/native/plugin/gcjwebplugin.cc
new file mode 100644
index 0000000..deae810
--- /dev/null
+++ b/libjava/classpath/native/plugin/gcjwebplugin.cc
@@ -0,0 +1,1759 @@
+/* gcjwebplugin.cc -- web browser plugin to execute Java applets
+ Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+// System includes.
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+// Netscape plugin API includes.
+#include <npapi.h>
+#include <npupp.h>
+
+// GLib includes.
+#include <glib.h>
+#include <glib/gstdio.h>
+
+// GTK includes.
+#include <gtk/gtk.h>
+
+// gcjwebplugin includes.
+#include "config.h"
+
+// Documentbase retrieval includes.
+#include <nsIPluginInstance.h>
+#include <nsIPluginInstancePeer.h>
+#include <nsIPluginTagInfo2.h>
+
+// Debugging macros.
+#define PLUGIN_DEBUG(message) \
+ g_print ("GCJ PLUGIN: thread %p: %s\n", g_thread_self (), message)
+
+#define PLUGIN_DEBUG_TWO(first, second) \
+ g_print ("GCJ PLUGIN: thread %p: %s %s\n", g_thread_self (), \
+ first, second)
+
+// Error reporting macros.
+#define PLUGIN_ERROR(message) \
+ g_printerr ("%s:%d: thread %p: Error: %s\n", __FILE__, __LINE__, \
+ g_thread_self (), message)
+
+#define PLUGIN_ERROR_TWO(first, second) \
+ g_printerr ("%s:%d: thread %p: Error: %s: %s\n", __FILE__, __LINE__, \
+ g_thread_self (), first, second)
+
+// Plugin information passed to about:plugins.
+#define PLUGIN_NAME "GCJ Web Browser Plugin"
+#define PLUGIN_DESC "The " PLUGIN_NAME " executes Java applets."
+#define PLUGIN_MIME_DESC \
+ "application/x-java-vm:class,jar:GCJ;" \
+ "application/x-java-applet:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.1:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.1.1:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.1.2:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.1.3:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.2:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.2.1:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.2.2:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.3:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.3.1:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.4:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.4.1:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.4.2:class,jar:GCJ;" \
+ "application/x-java-applet;jpi-version=1.4.2_01:class,jar:GCJ;" \
+ "application/x-java-bean:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.1:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.1.1:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.1.2:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.1.3:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.2:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.2.1:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.2.2:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.3:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.3.1:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.4:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.4.1:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.4.2:class,jar:GCJ;" \
+ "application/x-java-bean;jpi-version=1.4.2_01:class,jar:GCJ;"
+#define PLUGIN_URL NS_INLINE_PLUGIN_CONTRACTID_PREFIX NS_JVM_MIME_TYPE
+#define PLUGIN_MIME_TYPE "application/x-java-vm"
+#define PLUGIN_FILE_EXTS "class,jar,zip"
+#define PLUGIN_MIME_COUNT 1
+
+// Security dialog messages.
+#define RESPONSE_TRUST_APPLET "Trust Applet"
+#define RESPONSE_TRUST_APPLET_ADD_TO_LIST "Trust Applet and Add to Whitelist"
+#define WHITELIST_FILENAME PLUGIN_DATA_DIRECTORY "/whitelist.txt"
+#define SECURITY_WARNING \
+ "%s wants to load an applet.\n" \
+ "GNU Classpath's security implementation is not complete.\n" \
+ "HOSTILE APPLETS WILL STEAL AND/OR DESTROY YOUR DATA!\n"
+#define SECURITY_DESCRIPTION \
+ "Click \"Cancel\" if you do not trust the source of this applet.\n" \
+ "Click \"Trust Applet\" to load and run this applet now.\n" \
+ "Click \"Trust Applet and Add To Whitelist\" to always load" \
+ " and run this applet from now on, without asking.\n" \
+ "The whitelist is a list of the URLs from which you trust" \
+ " applets.\n" \
+ "Your whitelist file is \"" WHITELIST_FILENAME "\"."
+#define FAILURE_MESSAGE \
+ "This page wants to load an applet.\n" \
+ "The appletviewer is missing or not installed properly in \"" \
+ APPLETVIEWER_EXECUTABLE "\"."
+
+// Documentbase retrieval required definition.
+static NS_DEFINE_IID (kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID);
+
+// Browser function table.
+static NPNetscapeFuncs browserFunctions;
+
+// Keeps track of initialization. NP_Initialize should only be
+// called once.
+bool initialized = false;
+
+// GCJPluginData stores all the data associated with a single plugin
+// instance. A separate plugin instance is created for each <APPLET>
+// tag. For now, each plugin instance spawns its own applet viewer
+// process but this may need to change if we find pages containing
+// multiple applets that expect to be running in the same VM.
+struct GCJPluginData
+{
+ // A unique identifier for this plugin window.
+ gchar* instance_string;
+ // Applet viewer input pipe name.
+ gchar* in_pipe_name;
+ // Applet viewer input channel.
+ GIOChannel* in_from_appletviewer;
+ // Applet viewer input watch source.
+ gint in_watch_source;
+ // Applet viewer output pipe name.
+ gchar* out_pipe_name;
+ // Applet viewer output channel.
+ GIOChannel* out_to_appletviewer;
+ // Applet viewer output watch source.
+ gint out_watch_source;
+ // Mutex to protect appletviewer_alive.
+ GMutex* appletviewer_mutex;
+ // Back-pointer to the plugin instance to which this data belongs.
+ // This should not be freed but instead simply set to NULL.
+ NPP owner;
+ // FALSE if the applet viewer process has died. All code
+ // communicating with the applet viewer should check this flag
+ // before attempting to read from/write to the applet viewer pipes.
+ gboolean appletviewer_alive;
+ // The address of the plugin window. This should not be freed but
+ // instead simply set to NULL.
+ gpointer window_handle;
+ // The last plugin window width sent to us by the browser.
+ guint32 window_width;
+ // The last plugin window height sent to us by the browser.
+ guint32 window_height;
+};
+
+// Documentbase retrieval type-punning union.
+typedef union
+{
+ void** void_field;
+ nsIPluginTagInfo2** info_field;
+} info_union;
+
+// Static instance helper functions.
+// Have the browser allocate a new GCJPluginData structure.
+static void plugin_data_new (GCJPluginData** data);
+// Documentbase retrieval.
+static gchar* plugin_get_documentbase (NPP instance);
+// plugin failure handling.
+static bool plugin_failed ();
+// Whitelist handling.
+static bool plugin_user_trusts_documentbase (char* documentbase);
+static bool plugin_ask_user_about_documentbase (char* documentbase);
+static void plugin_add_documentbase_to_whitelist (char* documentbase);
+// Callback used to monitor input pipe status.
+static gboolean plugin_in_pipe_callback (GIOChannel* source,
+ GIOCondition condition,
+ gpointer plugin_data);
+// Callback used to monitor output pipe status.
+static gboolean plugin_out_pipe_callback (GIOChannel* source,
+ GIOCondition condition,
+ gpointer plugin_data);
+static NPError plugin_start_appletviewer (GCJPluginData* data);
+static gchar* plugin_create_applet_tag (int16 argc, char* argn[],
+ char* argv[]);
+static void plugin_send_message_to_appletviewer (GCJPluginData* data,
+ gchar const* message);
+static void plugin_stop_appletviewer (GCJPluginData* data);
+// Uninitialize GCJPluginData structure and delete pipes.
+static void plugin_data_destroy (GCJPluginData** data);
+
+// Global instance counter.
+// Mutex to protect plugin_instance_counter.
+static GMutex* plugin_instance_mutex = NULL;
+// A counter used to create uniquely named pipes.
+static gulong plugin_instance_counter = 0;
+// The user's documentbase whitelist.
+static GIOChannel* whitelist_file = NULL;
+// A global variable for reporting GLib errors. This must be free'd
+// and set to NULL after each use.
+static GError* channel_error = NULL;
+
+// Functions prefixed by GCJ_ are instance functions. They are called
+// by the browser and operate on instances of GCJPluginData.
+// Functions prefixed by plugin_ are static helper functions.
+// Functions prefixed by NP_ are factory functions. They are called
+// by the browser and provide functionality needed to create plugin
+// instances.
+
+// INSTANCE FUNCTIONS
+
+// Creates a new gcjwebplugin instance. This function creates a
+// GCJPluginData* and stores it in instance->pdata. The following
+// GCJPluginData fiels are initialized: instance_string, in_pipe_name,
+// in_from_appletviewer, in_watch_source, out_pipe_name,
+// out_to_appletviewer, out_watch_source, appletviewer_mutex, owner,
+// appletviewer_alive. In addition two pipe files are created. All
+// of those fields must be properly destroyed, and the pipes deleted,
+// by GCJ_Destroy. If an error occurs during initialization then this
+// function will free anything that's been allocated so far, set
+// instance->pdata to NULL and return an error code.
+NPError
+GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
+ int16 argc, char* argn[], char* argv[],
+ NPSavedData* saved)
+{
+ PLUGIN_DEBUG ("GCJ_New");
+
+ NPError np_error = NPERR_NO_ERROR;
+ GCJPluginData* data = NULL;
+
+ gchar* documentbase = NULL;
+ gchar* read_message = NULL;
+ gchar* applet_tag = NULL;
+ gchar* tag_message = NULL;
+
+ if (!instance)
+ {
+ PLUGIN_ERROR ("Browser-provided instance pointer is NULL.");
+ np_error = NPERR_INVALID_INSTANCE_ERROR;
+ goto cleanup_done;
+ }
+
+ // Initialize threads (needed for mutexes).
+ if (!g_thread_supported ())
+ g_thread_init (NULL);
+
+ // data
+ plugin_data_new (&data);
+ if (data == NULL)
+ {
+ PLUGIN_ERROR ("Failed to allocate plugin data.");
+ np_error = NPERR_OUT_OF_MEMORY_ERROR;
+ goto cleanup_done;
+ }
+
+ // Initialize data->instance_string.
+ //
+ // instance_string should be unique for this process so we use a
+ // combination of getpid and plugin_instance_counter.
+ //
+ // Critical region. Reference and increment plugin_instance_counter
+ // global.
+ g_mutex_lock (plugin_instance_mutex);
+
+ // data->instance_string
+ data->instance_string = g_strdup_printf ("instance-%d-%ld",
+ getpid (),
+ plugin_instance_counter++);
+
+ g_mutex_unlock (plugin_instance_mutex);
+
+ // data->appletviewer_mutex
+ data->appletviewer_mutex = g_mutex_new ();
+
+ // Documentbase retrieval.
+ documentbase = plugin_get_documentbase (instance);
+ if (!documentbase)
+ {
+ PLUGIN_ERROR ("Documentbase retrieval failed."
+ " Browser not Mozilla-based?");
+ goto cleanup_appletviewer_mutex;
+ }
+
+ if (!plugin_user_trusts_documentbase (documentbase))
+ {
+ PLUGIN_ERROR ("User does not trust applet.");
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_appletviewer_mutex;
+ }
+
+ // Create appletviewer-to-plugin pipe which we refer to as the input
+ // pipe.
+
+ // data->in_pipe_name
+ data->in_pipe_name = g_strdup_printf (PLUGIN_DATA_DIRECTORY
+ "/gcj-%s-appletviewer-to-plugin",
+ data->instance_string);
+ if (!data->in_pipe_name)
+ {
+ PLUGIN_ERROR ("Failed to create input pipe name.");
+ np_error = NPERR_OUT_OF_MEMORY_ERROR;
+ // If data->in_pipe_name is NULL then the g_free at
+ // cleanup_in_pipe_name will simply return.
+ goto cleanup_in_pipe_name;
+ }
+
+ if (mkfifo (data->in_pipe_name, 0700) == -1 && errno != EEXIST)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create input pipe", strerror (errno));
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_in_pipe_name;
+ }
+
+ // Create plugin-to-appletviewer pipe which we refer to as the
+ // output pipe.
+
+ // data->out_pipe_name
+ data->out_pipe_name = g_strdup_printf (PLUGIN_DATA_DIRECTORY
+ "/gcj-%s-plugin-to-appletviewer",
+ data->instance_string);
+
+ if (!data->out_pipe_name)
+ {
+ PLUGIN_ERROR ("Failed to create output pipe name.");
+ np_error = NPERR_OUT_OF_MEMORY_ERROR;
+ goto cleanup_out_pipe_name;
+ }
+
+ if (mkfifo (data->out_pipe_name, 0700) == -1 && errno != EEXIST)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create output pipe", strerror (errno));
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_out_pipe_name;
+ }
+
+ // Start a separate appletviewer process for each applet, even if
+ // there are multiple applets in the same page. We may need to
+ // change this behaviour if we find pages with multiple applets that
+ // rely on being run in the same VM.
+
+ // Critical region. Hold appletviewer_mutex while we start the
+ // appletviewer, create the IO channels and install the channel
+ // watch callbacks.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ np_error = plugin_start_appletviewer (data);
+
+ // If the appletviewer is not installed, then a dialog box will
+ // show up and the plugin will be killed.
+ if (np_error != NPERR_NO_ERROR)
+ {
+ if (plugin_failed ())
+ goto cleanup_applet_failure;
+ }
+
+ // Create plugin-to-appletviewer channel. The default encoding for
+ // the file is UTF-8.
+ // data->out_to_appletviewer
+ data->out_to_appletviewer = g_io_channel_new_file (data->out_pipe_name,
+ "w", &channel_error);
+ if (!data->out_to_appletviewer)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create output channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to create output channel");
+
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_out_to_appletviewer;
+ }
+
+ // Watch for hangup and error signals on the output pipe.
+ data->out_watch_source =
+ g_io_add_watch (data->out_to_appletviewer,
+ (GIOCondition) (G_IO_ERR | G_IO_HUP),
+ plugin_out_pipe_callback, (gpointer) data);
+
+ // Create appletviewer-to-plugin channel. The default encoding for
+ // the file is UTF-8.
+ // data->in_from_appletviewer
+ data->in_from_appletviewer = g_io_channel_new_file (data->in_pipe_name,
+ "r", &channel_error);
+ if (!data->in_from_appletviewer)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create input channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to create input channel");
+
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_in_from_appletviewer;
+ }
+
+ // Watch for hangup and error signals on the input pipe.
+ data->in_watch_source =
+ g_io_add_watch (data->in_from_appletviewer,
+ (GIOCondition) (G_IO_IN | G_IO_ERR | G_IO_HUP),
+ plugin_in_pipe_callback, (gpointer) data);
+
+ // Wait until we receive confirmation that the appletviewer has
+ // started.
+ if (g_io_channel_read_line (data->in_from_appletviewer,
+ &read_message, NULL, NULL,
+ &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Receiving confirmation from appletviewer failed",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Receiving confirmation from appletviewer failed");
+
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_in_watch_source;
+ }
+
+ PLUGIN_DEBUG ("GCJ_New: got confirmation that appletviewer is running.");
+ data->appletviewer_alive = TRUE;
+
+ // Send applet tag message to appletviewer.
+ applet_tag = plugin_create_applet_tag (argc, argn, argv);
+ tag_message = g_strconcat ("tag ", documentbase, " ", applet_tag, NULL);
+
+ plugin_send_message_to_appletviewer (data, data->instance_string);
+ plugin_send_message_to_appletviewer (data, tag_message);
+
+ g_mutex_unlock (data->appletviewer_mutex);
+
+ // If initialization succeeded entirely then we store the plugin
+ // data in the instance structure and return. Otherwise we free the
+ // data we've allocated so far and set instance->pdata to NULL.
+
+ // Set back-pointer to owner instance.
+ data->owner = instance;
+ instance->pdata = data;
+ goto cleanup_done;
+
+ // An error occurred while initializing the plugin data or spawning
+ // the appletviewer so we free the data we've already allocated.
+
+ cleanup_in_watch_source:
+ // Removing a source is harmless if it fails since it just means the
+ // source has already been removed.
+ g_source_remove (data->in_watch_source);
+ data->in_watch_source = 0;
+
+ cleanup_in_from_appletviewer:
+ if (data->in_from_appletviewer)
+ g_io_channel_unref (data->in_from_appletviewer);
+ data->in_from_appletviewer = NULL;
+
+ // cleanup_out_watch_source:
+ g_source_remove (data->out_watch_source);
+ data->out_watch_source = 0;
+
+ cleanup_out_to_appletviewer:
+ if (data->out_to_appletviewer)
+ g_io_channel_unref (data->out_to_appletviewer);
+ data->out_to_appletviewer = NULL;
+
+ // cleanup_out_pipe:
+ // Delete output pipe.
+ unlink (data->out_pipe_name);
+
+ cleanup_applet_failure:
+ cleanup_out_pipe_name:
+ g_free (data->out_pipe_name);
+ data->out_pipe_name = NULL;
+
+ // cleanup_in_pipe:
+ // Delete input pipe.
+ unlink (data->in_pipe_name);
+
+ cleanup_in_pipe_name:
+ g_free (data->in_pipe_name);
+ data->in_pipe_name = NULL;
+
+ cleanup_appletviewer_mutex:
+ g_free (data->appletviewer_mutex);
+ data->appletviewer_mutex = NULL;
+
+ // cleanup_instance_string:
+ g_free (data->instance_string);
+ data->instance_string = NULL;
+
+ // cleanup_data:
+ // Eliminate back-pointer to plugin instance.
+ data->owner = NULL;
+ (*browserFunctions.memfree) (data);
+ data = NULL;
+
+ // Initialization failed so return a NULL pointer for the browser
+ // data.
+ instance->pdata = NULL;
+
+ cleanup_done:
+ g_free (tag_message);
+ tag_message = NULL;
+ g_free (applet_tag);
+ applet_tag = NULL;
+ g_free (read_message);
+ read_message = NULL;
+ g_free (documentbase);
+ documentbase = NULL;
+
+ PLUGIN_DEBUG ("GCJ_New return");
+
+ return np_error;
+}
+
+NPError
+GCJ_GetValue (NPP instance, NPPVariable variable, void* value)
+{
+ PLUGIN_DEBUG ("GCJ_GetValue");
+
+ NPError np_error = NPERR_NO_ERROR;
+
+ switch (variable)
+ {
+ // This plugin needs XEmbed support.
+ case NPPVpluginNeedsXEmbed:
+ {
+ PLUGIN_DEBUG ("GCJ_GetValue: returning TRUE for NeedsXEmbed.");
+ PRBool* bool_value = (PRBool*) value;
+ *bool_value = PR_TRUE;
+ }
+ break;
+
+ default:
+ PLUGIN_ERROR ("Unknown plugin value requested.");
+ np_error = NPERR_GENERIC_ERROR;
+ break;
+ }
+
+ PLUGIN_DEBUG ("GCJ_GetValue return");
+
+ return np_error;
+}
+
+NPError
+GCJ_Destroy (NPP instance, NPSavedData** save)
+{
+ PLUGIN_DEBUG ("GCJ_Destroy");
+
+ GCJPluginData* data = (GCJPluginData*) instance->pdata;
+
+ if (data)
+ {
+ // Critical region. Stop the appletviewer.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ // Tell the appletviewer to destroy its embedded plugin window.
+ plugin_send_message_to_appletviewer (data, "destroy");
+ // Shut down the appletviewer.
+ plugin_stop_appletviewer (data);
+
+ g_mutex_unlock (data->appletviewer_mutex);
+
+ // Free plugin data.
+ plugin_data_destroy (&data);
+ }
+
+ PLUGIN_DEBUG ("GCJ_Destroy return");
+
+ return NPERR_NO_ERROR;
+}
+
+NPError
+GCJ_SetWindow (NPP instance, NPWindow* window)
+{
+ PLUGIN_DEBUG ("GCJ_SetWindow");
+
+ if (instance == NULL)
+ {
+ PLUGIN_ERROR ("Invalid instance.");
+
+ return NPERR_INVALID_INSTANCE_ERROR;
+ }
+
+ GCJPluginData* data = (GCJPluginData*) instance->pdata;
+
+ // Simply return if we receive a NULL window.
+ if ((window == NULL) || (window->window == NULL))
+ {
+ PLUGIN_DEBUG ("GCJ_SetWindow: got NULL window.");
+
+ return NPERR_NO_ERROR;
+ }
+
+ if (data->window_handle)
+ {
+ // The window already exists.
+ if (data->window_handle == window->window)
+ {
+ // The parent window is the same as in previous calls.
+ PLUGIN_DEBUG ("GCJ_SetWindow: window already exists.");
+
+ // Critical region. Read data->appletviewer_mutex and send
+ // a message to the appletviewer.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ if (data->appletviewer_alive)
+ {
+ // The window is the same as it was for the last
+ // SetWindow call.
+ if (window->width != data->window_width)
+ {
+ PLUGIN_DEBUG ("GCJ_SetWindow: window width changed.");
+ // The width of the plugin window has changed.
+
+ // Send the new width to the appletviewer.
+ plugin_send_message_to_appletviewer (data,
+ data->instance_string);
+ gchar* width_message = g_strdup_printf ("width %d",
+ window->width);
+ plugin_send_message_to_appletviewer (data, width_message);
+ g_free (width_message);
+ width_message = NULL;
+
+ // Store the new width.
+ data->window_width = window->width;
+ }
+
+ if (window->height != data->window_height)
+ {
+ PLUGIN_DEBUG ("GCJ_SetWindow: window height changed.");
+ // The height of the plugin window has changed.
+
+ // Send the new height to the appletviewer.
+ plugin_send_message_to_appletviewer (data,
+ data->instance_string);
+ gchar* height_message = g_strdup_printf ("height %d",
+ window->height);
+ plugin_send_message_to_appletviewer (data, height_message);
+ g_free (height_message);
+ height_message = NULL;
+
+ // Store the new height.
+ data->window_height = window->height;
+ }
+ }
+ else
+ {
+ // The appletviewer is not running.
+ PLUGIN_DEBUG ("GCJ_SetWindow: appletviewer is not running.");
+ }
+
+ g_mutex_unlock (data->appletviewer_mutex);
+ }
+ else
+ {
+ // The parent window has changed. This branch does run but
+ // doing nothing in response seems to be sufficient.
+ PLUGIN_DEBUG ("GCJ_SetWindow: parent window changed.");
+ }
+ }
+ else
+ {
+ PLUGIN_DEBUG ("GCJ_SetWindow: setting window.");
+
+ // Critical region. Send messages to appletviewer.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ plugin_send_message_to_appletviewer (data, data->instance_string);
+ gchar *window_message = g_strdup_printf ("handle %ld",
+ (gulong) window->window);
+ plugin_send_message_to_appletviewer (data, window_message);
+ g_free (window_message);
+ window_message = NULL;
+
+ g_mutex_unlock (data->appletviewer_mutex);
+
+ // Store the window handle.
+ data->window_handle = window->window;
+ }
+
+ PLUGIN_DEBUG ("GCJ_SetWindow return");
+
+ return NPERR_NO_ERROR;
+}
+
+NPError
+GCJ_NewStream (NPP instance, NPMIMEType type, NPStream* stream,
+ NPBool seekable, uint16* stype)
+{
+ PLUGIN_DEBUG ("GCJ_NewStream");
+
+ PLUGIN_DEBUG ("GCJ_NewStream return");
+
+ return NPERR_NO_ERROR;
+}
+
+void
+GCJ_StreamAsFile (NPP instance, NPStream* stream, const char* filename)
+{
+ PLUGIN_DEBUG ("GCJ_StreamAsFile");
+
+ PLUGIN_DEBUG ("GCJ_StreamAsFile return");
+}
+
+NPError
+GCJ_DestroyStream (NPP instance, NPStream* stream, NPReason reason)
+{
+ PLUGIN_DEBUG ("GCJ_DestroyStream");
+
+ PLUGIN_DEBUG ("GCJ_DestroyStream return");
+
+ return NPERR_NO_ERROR;
+}
+
+int32
+GCJ_WriteReady (NPP instance, NPStream* stream)
+{
+ PLUGIN_DEBUG ("GCJ_WriteReady");
+
+ PLUGIN_DEBUG ("GCJ_WriteReady return");
+
+ return 0;
+}
+
+int32
+GCJ_Write (NPP instance, NPStream* stream, int32 offset, int32 len,
+ void* buffer)
+{
+ PLUGIN_DEBUG ("GCJ_Write");
+
+ PLUGIN_DEBUG ("GCJ_Write return");
+
+ return 0;
+}
+
+void
+GCJ_Print (NPP instance, NPPrint* platformPrint)
+{
+ PLUGIN_DEBUG ("GCJ_Print");
+
+ PLUGIN_DEBUG ("GCJ_Print return");
+}
+
+int16
+GCJ_HandleEvent (NPP instance, void* event)
+{
+ PLUGIN_DEBUG ("GCJ_HandleEvent");
+
+ PLUGIN_DEBUG ("GCJ_HandleEvent return");
+
+ return 0;
+}
+
+void
+GCJ_URLNotify (NPP instance, const char* url, NPReason reason,
+ void* notifyData)
+{
+ PLUGIN_DEBUG ("GCJ_URLNotify");
+
+ PLUGIN_DEBUG ("GCJ_URLNotify return");
+}
+
+jref
+GCJ_GetJavaClass (void)
+{
+ PLUGIN_DEBUG ("GCJ_GetJavaClass");
+
+ PLUGIN_DEBUG ("GCJ_GetJavaClass return");
+
+ return 0;
+}
+
+// HELPER FUNCTIONS
+
+static void
+plugin_data_new (GCJPluginData** data)
+{
+ PLUGIN_DEBUG ("plugin_data_new");
+
+ *data = (GCJPluginData*)
+ (*browserFunctions.memalloc) (sizeof (struct GCJPluginData));
+
+ // appletviewer_alive is false until the applet viewer is spawned.
+ if (*data)
+ memset (*data, 0, sizeof (struct GCJPluginData));
+
+ PLUGIN_DEBUG ("plugin_data_new return");
+}
+
+// Documentbase retrieval. This function gets the current document's
+// documentbase. This function relies on browser-private data so it
+// will only work when the plugin is loaded in a Mozilla-based
+// browser. We could not find a way to retrieve the documentbase
+// using the original Netscape plugin API so we use the XPCOM API
+// instead.
+static gchar*
+plugin_get_documentbase (NPP instance)
+{
+ PLUGIN_DEBUG ("plugin_get_documentbase");
+
+ nsIPluginInstance* xpcom_instance = NULL;
+ nsIPluginInstancePeer* peer = NULL;
+ nsresult result = 0;
+ nsIPluginTagInfo2* pluginTagInfo2 = NULL;
+ info_union u = { NULL };
+ char const* documentbase = NULL;
+ gchar* documentbase_copy = NULL;
+
+ xpcom_instance = (nsIPluginInstance*) (instance->ndata);
+ if (!xpcom_instance)
+ {
+ PLUGIN_ERROR ("xpcom_instance is NULL.");
+ goto cleanup_done;
+ }
+
+ xpcom_instance->GetPeer (&peer);
+ if (!peer)
+ {
+ PLUGIN_ERROR ("peer is NULL.");
+ goto cleanup_done;
+ }
+
+ u.info_field = &pluginTagInfo2;
+
+ result = peer->QueryInterface (kIPluginTagInfo2IID,
+ u.void_field);
+ if (result || !pluginTagInfo2)
+ {
+ PLUGIN_ERROR ("pluginTagInfo2 retrieval failed.");
+ goto cleanup_peer;
+ }
+
+ pluginTagInfo2->GetDocumentBase (&documentbase);
+
+ if (!documentbase)
+ {
+ PLUGIN_ERROR ("documentbase is NULL.");
+ goto cleanup_plugintaginfo2;
+ }
+
+ documentbase_copy = g_strdup (documentbase);
+
+ // Release references.
+ cleanup_plugintaginfo2:
+ NS_RELEASE (pluginTagInfo2);
+
+ cleanup_peer:
+ NS_RELEASE (peer);
+
+ cleanup_done:
+ PLUGIN_DEBUG ("plugin_get_documentbase return");
+
+ return documentbase_copy;
+}
+
+// This function shows a error message if the appletviewer has
+// not been installed. It returns true, if the user presses the
+// ok button.
+static bool
+plugin_failed ()
+{
+ GtkWidget* dialog = NULL;
+ GtkWidget* ok_button = NULL;
+
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ FAILURE_MESSAGE);
+ ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK);
+ gtk_widget_show_all (dialog);
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
+ {
+ gtk_widget_destroy (dialog);
+ return true;
+ }
+ return false;
+}
+
+// plugin_user_trusts_documentbase returns true if the given
+// documentbase is in the documentbase whitelist. Otherwise it asks
+// the user if he trusts the given documentbase by calling
+// plugin_ask_user_about_documentbase.
+static bool
+plugin_user_trusts_documentbase (char* documentbase)
+{
+ bool applet_in_whitelist = false;
+
+ // Check if documentbase is in whitelist.
+ while (true)
+ {
+ gchar* whitelist_entry = NULL;
+ gchar* newline_documentbase = NULL;
+
+ // If reading fails, break out of this loop with
+ // applet_in_whitelist still set to false.
+ if (g_io_channel_read_line (whitelist_file, &whitelist_entry,
+ NULL, NULL, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to read line from whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to open whitelist file.");
+ g_free (whitelist_entry);
+ whitelist_entry = NULL;
+ break;
+ }
+
+ newline_documentbase = g_strdup_printf ("%s\n", documentbase);
+ if (!strcmp (newline_documentbase, whitelist_entry))
+ {
+ applet_in_whitelist = true;
+ g_free (newline_documentbase);
+ newline_documentbase = NULL;
+ g_free (whitelist_entry);
+ whitelist_entry = NULL;
+ break;
+ }
+ g_free (whitelist_entry);
+ whitelist_entry = NULL;
+ g_free (newline_documentbase);
+ newline_documentbase = NULL;
+ }
+
+ return applet_in_whitelist ? true
+ : plugin_ask_user_about_documentbase (documentbase);
+}
+
+// plugin_add_documentbase_to_whitelist adds the given documentbase to
+// the user's documentbase whitelist.
+static void
+plugin_add_documentbase_to_whitelist (char* documentbase)
+{
+ gsize bytes_written = 0;
+ char* newline_documentbase = NULL;
+ GIOStatus status = G_IO_STATUS_NORMAL;
+
+ newline_documentbase = g_strdup_printf ("%s\n", documentbase);
+ status = g_io_channel_write_chars (whitelist_file,
+ newline_documentbase, -1, &bytes_written,
+ &channel_error);
+ g_free (newline_documentbase);
+ newline_documentbase = NULL;
+
+ if (status != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Error writing to whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Error writing to whitelist file.");
+ }
+
+ if (g_io_channel_flush (whitelist_file, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write whitelist file.");
+ }
+
+ if (g_io_channel_shutdown (whitelist_file, TRUE, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to close whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to close whitelist file.");
+ }
+}
+
+// plugin_ask_user_about_documentbase puts up a dialog box that asks if the
+// user trusts applets from this documentbase. The user has three
+// options: "Cancel", "Trust Applet" and "Trust Applet and Add to
+// Whitelist". If the user selects Cancel (the default) then a
+// generic error code is returned from GCJ_New, telling the browser
+// that the applet failed to load. If the user selects "Trust Applet"
+// then plugin loading proceeds. If the user selects "Trust Applet
+// and Add to Whitelist" then this documentbase is added to the user's
+// applet whitelist and plugin loading proceeds.
+static bool
+plugin_ask_user_about_documentbase (char* documentbase)
+{
+ GtkWidget* dialog = NULL;
+ GtkWidget* ok_button = NULL;
+ GtkWidget* cancel_button = NULL;
+ GtkWidget* whitelist_button = NULL;
+ gint dialog_response = GTK_RESPONSE_NONE;
+
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ SECURITY_WARNING,
+ documentbase);
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ SECURITY_DESCRIPTION);
+
+ cancel_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
+ ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ RESPONSE_TRUST_APPLET,
+ GTK_RESPONSE_OK);
+ whitelist_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ RESPONSE_TRUST_APPLET_ADD_TO_LIST,
+ GTK_RESPONSE_APPLY);
+ gtk_widget_grab_focus (cancel_button);
+
+ gtk_widget_show_all (dialog);
+ dialog_response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ if (dialog_response == GTK_RESPONSE_CANCEL)
+ {
+ // The user does not trust this documentbase.
+ return false;
+ }
+ else if (dialog_response == GTK_RESPONSE_APPLY)
+ {
+ // The user wants this documentbase added to his documentbase
+ // whitelist.
+ plugin_add_documentbase_to_whitelist (documentbase);
+ }
+ // The user trusts this documentbase.
+ return true;
+}
+
+// plugin_in_pipe_callback is called when data is available on the
+// input pipe, or when the appletviewer crashes or is killed. It may
+// be called after data has been destroyed in which case it simply
+// returns FALSE to remove itself from the glib main loop.
+static gboolean
+plugin_in_pipe_callback (GIOChannel* source,
+ GIOCondition condition,
+ gpointer plugin_data)
+{
+ PLUGIN_DEBUG ("plugin_in_pipe_callback");
+
+ GCJPluginData* data = (GCJPluginData*) plugin_data;
+ gboolean keep_installed = TRUE;
+
+ // If data is NULL then GCJ_Destroy has already been called and
+ // plugin_in_pipe_callback is being called after plugin
+ // destruction. In that case all we need to do is return FALSE so
+ // that the plugin_in_pipe_callback watch is removed.
+ if (data)
+ {
+ // Critical region. Set or clear data->appletviewer_alive.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ if (condition & G_IO_IN)
+ {
+ gchar* message = NULL;
+
+ if (g_io_channel_read_line (data->in_from_appletviewer,
+ &message, NULL, NULL,
+ &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to read line from input channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to read line from input channel");
+ }
+ else
+ {
+ if (g_str_has_prefix (message, "url "))
+ {
+ gchar** parts = g_strsplit (message, " ", 3);
+ PLUGIN_DEBUG_TWO ("plugin_in_pipe_callback:"
+ " opening URL", parts[1]);
+ PLUGIN_DEBUG_TWO ("plugin_in_pipe_callback:"
+ " URL target", parts[2]);
+ // Open the URL in a new browser window.
+ NPError np_error =
+ (*browserFunctions.geturl) (data->owner, parts[1], parts[2]);
+ if (np_error != NPERR_NO_ERROR)
+ PLUGIN_ERROR ("Failed to load URL.");
+ g_strfreev (parts);
+ parts = NULL;
+ }
+ else if (g_str_has_prefix (message, "status "))
+ {
+ gchar** parts = g_strsplit (message, " ", 2);
+
+ PLUGIN_DEBUG_TWO ("plugin_in_pipe_callback:"
+ " setting status", parts[1]);
+ (*browserFunctions.status) (data->owner, parts[1]);
+ g_strfreev (parts);
+ parts = NULL;
+ }
+ g_print (" PIPE: plugin read %s\n", message);
+ }
+
+ g_free (message);
+ message = NULL;
+
+ keep_installed = TRUE;
+ }
+
+ if (condition & (G_IO_ERR | G_IO_HUP))
+ {
+ PLUGIN_DEBUG ("appletviewer has stopped.");
+ data->appletviewer_alive = FALSE;
+ keep_installed = FALSE;
+ }
+ g_mutex_unlock (data->appletviewer_mutex);
+ }
+
+ PLUGIN_DEBUG ("plugin_in_pipe_callback return");
+
+ return keep_installed;
+}
+
+// plugin_out_pipe_callback is called when the appletviewer crashes or
+// is killed. It may be called after data has been destroyed in which
+// case it simply returns FALSE to remove itself from the glib main
+// loop.
+static gboolean
+plugin_out_pipe_callback (GIOChannel* source,
+ GIOCondition condition,
+ gpointer plugin_data)
+{
+ PLUGIN_DEBUG ("plugin_out_pipe_callback");
+
+ GCJPluginData* data = (GCJPluginData*) plugin_data;
+
+ // If data is NULL then GCJ_Destroy has already been called and
+ // plugin_out_pipe_callback is being called after plugin
+ // destruction. In that case all we need to do is return FALSE so
+ // that the plugin_out_pipe_callback watch is removed.
+ if (data)
+ {
+ // Critical region. Clear data->appletviewer_alive.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ PLUGIN_DEBUG ("plugin_out_pipe_callback: appletviewer has stopped.");
+ data->appletviewer_alive = FALSE;
+
+ g_mutex_unlock (data->appletviewer_mutex);
+ }
+
+ PLUGIN_DEBUG ("plugin_out_pipe_callback return");
+
+ return FALSE;
+}
+
+static NPError
+plugin_start_appletviewer (GCJPluginData* data)
+{
+ PLUGIN_DEBUG ("plugin_start_appletviewer");
+ NPError error = NPERR_NO_ERROR;
+
+ if (!data->appletviewer_alive)
+ {
+ gchar* command_line[3] = { NULL, NULL, NULL };
+
+ command_line[0] = g_strdup (APPLETVIEWER_EXECUTABLE);
+ // Output from plugin's perspective is appletviewer's input.
+ // Input from plugin's perspective is appletviewer's output.
+ command_line[1] = g_strdup_printf ("--plugin=%s,%s",
+ data->out_pipe_name,
+ data->in_pipe_name);
+ command_line[2] = NULL;
+
+ if (!g_spawn_async (NULL, command_line, NULL, (GSpawnFlags) 0,
+ NULL, NULL, NULL, &channel_error))
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to spawn applet viewer",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to spawn applet viewer");
+ error = NPERR_GENERIC_ERROR;
+ goto cleanup;
+ }
+
+ cleanup:
+ g_free (command_line[0]);
+ command_line[0] = NULL;
+ g_free (command_line[1]);
+ command_line[1] = NULL;
+ g_free (command_line[2]);
+ command_line[2] = NULL;
+ }
+
+ PLUGIN_DEBUG ("plugin_start_appletviewer return");
+ return error;
+}
+
+// Build up the applet tag string that we'll send to the applet
+// viewer.
+static gchar*
+plugin_create_applet_tag (int16 argc, char* argn[], char* argv[])
+{
+ PLUGIN_DEBUG ("plugin_create_applet_tag");
+
+ gchar* applet_tag = g_strdup ("<EMBED ");
+ gchar* parameters = g_strdup ("");
+
+ for (int16 i = 0; i < argc; i++)
+ {
+ if (!g_ascii_strcasecmp (argn[i], "code"))
+ {
+ gchar* code = g_strdup_printf ("CODE=\"%s\" ", argv[i]);
+ applet_tag = g_strconcat (applet_tag, code, NULL);
+ g_free (code);
+ code = NULL;
+ }
+ else if (!g_ascii_strcasecmp (argn[i], "codebase"))
+ {
+ gchar* codebase = g_strdup_printf ("CODEBASE=\"%s\" ", argv[i]);
+ applet_tag = g_strconcat (applet_tag, codebase, NULL);
+ g_free (codebase);
+ codebase = NULL;
+ }
+ else if (!g_ascii_strcasecmp (argn[i], "archive"))
+ {
+ gchar* archive = g_strdup_printf ("ARCHIVE=\"%s\" ", argv[i]);
+ applet_tag = g_strconcat (applet_tag, archive, NULL);
+ g_free (archive);
+ archive = NULL;
+ }
+ else if (!g_ascii_strcasecmp (argn[i], "width"))
+ {
+ gchar* width = g_strdup_printf ("WIDTH=\"%s\" ", argv[i]);
+ applet_tag = g_strconcat (applet_tag, width, NULL);
+ g_free (width);
+ width = NULL;
+ }
+ else if (!g_ascii_strcasecmp (argn[i], "height"))
+ {
+ gchar* height = g_strdup_printf ("HEIGHT=\"%s\" ", argv[i]);
+ applet_tag = g_strconcat (applet_tag, height, NULL);
+ g_free (height);
+ height = NULL;
+ }
+ else
+ {
+ // Escape the parameter value so that line termination
+ // characters will pass through the pipe.
+ if (argv[i] != '\0')
+ {
+ gchar* escaped = NULL;
+
+ escaped = g_strescape (argv[i], NULL);
+ parameters = g_strconcat (parameters, "<PARAM NAME=\"", argn[i],
+ "\" VALUE=\"", escaped, "\">", NULL);
+
+ g_free (escaped);
+ escaped = NULL;
+ }
+ }
+ }
+
+ applet_tag = g_strconcat (applet_tag, ">", parameters, "</EMBED>", NULL);
+
+ g_free (parameters);
+ parameters = NULL;
+
+ PLUGIN_DEBUG ("plugin_create_applet_tag return");
+
+ return applet_tag;
+}
+
+// plugin_send_message_to_appletviewer must be called while holding
+// data->appletviewer_mutex.
+static void
+plugin_send_message_to_appletviewer (GCJPluginData* data, gchar const* message)
+{
+ PLUGIN_DEBUG ("plugin_send_message_to_appletviewer");
+
+ if (data->appletviewer_alive)
+ {
+ gchar* newline_message = NULL;
+ gsize bytes_written = 0;
+
+ // Send message to appletviewer.
+ newline_message = g_strdup_printf ("%s\n", message);
+
+ // g_io_channel_write_chars will return something other than
+ // G_IO_STATUS_NORMAL if not all the data is written. In that
+ // case we fail rather than retrying.
+ if (g_io_channel_write_chars (data->out_to_appletviewer,
+ newline_message, -1, &bytes_written,
+ &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write bytes to output channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write bytes to output channel");
+ }
+
+ if (g_io_channel_flush (data->out_to_appletviewer, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to flush bytes to output channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to flush bytes to output channel");
+ }
+ g_free (newline_message);
+ newline_message = NULL;
+
+ g_print (" PIPE: plugin wrote %s\n", message);
+ }
+
+ PLUGIN_DEBUG ("plugin_send_message_to_appletviewer return");
+}
+
+// Stop the appletviewer process. When this is called the
+// appletviewer can be in any of three states: running, crashed or
+// hung. If the appletviewer is running then sending it "shutdown"
+// will cause it to exit. This will cause
+// plugin_out_pipe_callback/plugin_in_pipe_callback to be called and
+// the input and output channels to be shut down. If the appletviewer
+// has crashed then plugin_out_pipe_callback/plugin_in_pipe_callback
+// would already have been called and data->appletviewer_alive cleared
+// in which case this function simply returns. If the appletviewer is
+// hung then this function will be successful and the input and output
+// watches will be removed by plugin_data_destroy.
+// plugin_stop_appletviewer must be called with
+// data->appletviewer_mutex held.
+static void
+plugin_stop_appletviewer (GCJPluginData* data)
+{
+ PLUGIN_DEBUG ("plugin_stop_appletviewer");
+
+ if (data->appletviewer_alive)
+ {
+ // Shut down the appletviewer.
+ gsize bytes_written = 0;
+
+ if (data->out_to_appletviewer)
+ {
+ if (g_io_channel_write_chars (data->out_to_appletviewer, "shutdown",
+ -1, &bytes_written, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write shutdown message to"
+ " appletviewer", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write shutdown message to");
+ }
+
+ if (g_io_channel_flush (data->out_to_appletviewer, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write shutdown message to"
+ " appletviewer", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write shutdown message to");
+ }
+
+ if (g_io_channel_shutdown (data->out_to_appletviewer,
+ TRUE, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to shut down appletviewer"
+ " output channel", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to shut down appletviewer");
+ }
+ }
+
+ if (data->in_from_appletviewer)
+ {
+ if (g_io_channel_shutdown (data->in_from_appletviewer,
+ TRUE, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to shut down appletviewer"
+ " input channel", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to shut down appletviewer");
+ }
+ }
+ }
+
+ PLUGIN_DEBUG ("plugin_stop_appletviewer return");
+}
+
+static void
+plugin_data_destroy (GCJPluginData** data)
+{
+ PLUGIN_DEBUG ("plugin_data_destroy");
+
+ GCJPluginData* tofree = *data;
+
+ tofree->window_handle = NULL;
+ tofree->window_height = 0;
+ tofree->window_width = 0;
+
+ // Copied from GCJ_New.
+
+ // cleanup_in_watch_source:
+ // Removing a source is harmless if it fails since it just means the
+ // source has already been removed.
+ g_source_remove (tofree->in_watch_source);
+ tofree->in_watch_source = 0;
+
+ // cleanup_in_from_appletviewer:
+ if (tofree->in_from_appletviewer)
+ g_io_channel_unref (tofree->in_from_appletviewer);
+ tofree->in_from_appletviewer = NULL;
+
+ // cleanup_out_watch_source:
+ g_source_remove (tofree->out_watch_source);
+ tofree->out_watch_source = 0;
+
+ // cleanup_out_to_appletviewer:
+ if (tofree->out_to_appletviewer)
+ g_io_channel_unref (tofree->out_to_appletviewer);
+ tofree->out_to_appletviewer = NULL;
+
+ // cleanup_out_pipe:
+ // Delete output pipe.
+ unlink (tofree->out_pipe_name);
+
+ // cleanup_out_pipe_name:
+ g_free (tofree->out_pipe_name);
+ tofree->out_pipe_name = NULL;
+
+ // cleanup_in_pipe:
+ // Delete input pipe.
+ unlink (tofree->in_pipe_name);
+
+ // cleanup_in_pipe_name:
+ g_free (tofree->in_pipe_name);
+ tofree->in_pipe_name = NULL;
+
+ // cleanup_appletviewer_mutex:
+ g_free (tofree->appletviewer_mutex);
+ tofree->appletviewer_mutex = NULL;
+
+ // cleanup_instance_string:
+ g_free (tofree->instance_string);
+ tofree->instance_string = NULL;
+
+ // cleanup_data:
+ // Eliminate back-pointer to plugin instance.
+ tofree->owner = NULL;
+ (*browserFunctions.memfree) (tofree);
+ tofree = NULL;
+
+ PLUGIN_DEBUG ("plugin_data_destroy return");
+}
+
+// FACTORY FUNCTIONS
+
+// Provides the browser with pointers to the plugin functions that we
+// implement and initializes a local table with browser functions that
+// we may wish to call. Called once, after browser startup and before
+// the first plugin instance is created.
+// The field 'initialized' is set to true once this function has
+// finished. If 'initialized' is already true at the beginning of
+// this function, then it is evident that NP_Initialize has already
+// been called. There is no need to call this function more than once and
+// this workaround avoids any duplicate calls.
+NPError
+NP_Initialize (NPNetscapeFuncs* browserTable, NPPluginFuncs* pluginTable)
+{
+ PLUGIN_DEBUG ("NP_Initialize");
+
+ if (initialized)
+ return NPERR_NO_ERROR;
+ else if ((browserTable == NULL) || (pluginTable == NULL))
+ {
+ PLUGIN_ERROR ("Browser or plugin function table is NULL.");
+
+ return NPERR_INVALID_FUNCTABLE_ERROR;
+ }
+
+ // Ensure that the major version of the plugin API that the browser
+ // expects is not more recent than the major version of the API that
+ // we've implemented.
+ if ((browserTable->version >> 8) > NP_VERSION_MAJOR)
+ {
+ PLUGIN_ERROR ("Incompatible version.");
+
+ return NPERR_INCOMPATIBLE_VERSION_ERROR;
+ }
+
+ // Ensure that the plugin function table we've received is large
+ // enough to store the number of functions that we may provide.
+ if (pluginTable->size < sizeof (NPPluginFuncs))
+ {
+ PLUGIN_ERROR ("Invalid plugin function table.");
+
+ return NPERR_INVALID_FUNCTABLE_ERROR;
+ }
+
+ // Ensure that the browser function table is large enough to store
+ // the number of browser functions that we may use.
+ if (browserTable->size < sizeof (NPNetscapeFuncs))
+ {
+ PLUGIN_ERROR ("Invalid browser function table.");
+
+ return NPERR_INVALID_FUNCTABLE_ERROR;
+ }
+
+ // Make sure the plugin data directory exists, creating it if
+ // necessary.
+ if (!g_file_test (PLUGIN_DATA_DIRECTORY,
+ (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+ {
+ int file_error = 0;
+
+ file_error = g_mkdir (PLUGIN_DATA_DIRECTORY, 0700);
+ if (file_error != 0)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create data directory "
+ PLUGIN_DATA_DIRECTORY " ",
+ strerror (errno));
+ return NPERR_GENERIC_ERROR;
+ }
+ }
+
+ // Open the user's documentbase whitelist.
+ whitelist_file = g_io_channel_new_file (WHITELIST_FILENAME,
+ "a+", &channel_error);
+ if (!whitelist_file)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to open whitelist file "
+ WHITELIST_FILENAME " ",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to open whitelist file "
+ WHITELIST_FILENAME);
+
+ return NPERR_GENERIC_ERROR;
+ }
+
+ // Store in a local table the browser functions that we may use.
+ browserFunctions.version = browserTable->version;
+ browserFunctions.size = browserTable->size;
+ browserFunctions.posturl = browserTable->posturl;
+ browserFunctions.geturl = browserTable->geturl;
+ browserFunctions.geturlnotify = browserTable->geturlnotify;
+ browserFunctions.requestread = browserTable->requestread;
+ browserFunctions.newstream = browserTable->newstream;
+ browserFunctions.write = browserTable->write;
+ browserFunctions.destroystream = browserTable->destroystream;
+ browserFunctions.status = browserTable->status;
+ browserFunctions.uagent = browserTable->uagent;
+ browserFunctions.memalloc = browserTable->memalloc;
+ browserFunctions.memfree = browserTable->memfree;
+ browserFunctions.memflush = browserTable->memflush;
+ browserFunctions.reloadplugins = browserTable->reloadplugins;
+ browserFunctions.getvalue = browserTable->getvalue;
+
+ // Return to the browser the plugin functions that we implement.
+ pluginTable->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
+ pluginTable->size = sizeof (NPPluginFuncs);
+ pluginTable->newp = NewNPP_NewProc (GCJ_New);
+ pluginTable->destroy = NewNPP_DestroyProc (GCJ_Destroy);
+ pluginTable->setwindow = NewNPP_SetWindowProc (GCJ_SetWindow);
+ pluginTable->newstream = NewNPP_NewStreamProc (GCJ_NewStream);
+ pluginTable->destroystream = NewNPP_DestroyStreamProc (GCJ_DestroyStream);
+ pluginTable->asfile = NewNPP_StreamAsFileProc (GCJ_StreamAsFile);
+ pluginTable->writeready = NewNPP_WriteReadyProc (GCJ_WriteReady);
+ pluginTable->write = NewNPP_WriteProc (GCJ_Write);
+ pluginTable->print = NewNPP_PrintProc (GCJ_Print);
+ pluginTable->urlnotify = NewNPP_URLNotifyProc (GCJ_URLNotify);
+ pluginTable->getvalue = NewNPP_GetValueProc (GCJ_GetValue);
+
+ initialized = true;
+ plugin_instance_mutex = g_mutex_new ();
+
+ PLUGIN_DEBUG ("NP_Initialize: using " APPLETVIEWER_EXECUTABLE ".");
+
+ PLUGIN_DEBUG ("NP_Initialize return");
+
+ return NPERR_NO_ERROR;
+}
+
+// Returns a string describing the MIME type that this plugin
+// handles.
+char*
+NP_GetMIMEDescription (void)
+{
+ PLUGIN_DEBUG ("NP_GetMIMEDescription");
+
+ PLUGIN_DEBUG ("NP_GetMIMEDescription return");
+
+ return (char*) PLUGIN_MIME_DESC;
+}
+
+// Returns a value relevant to the plugin as a whole. The browser
+// calls this function to obtain information about the plugin.
+NPError
+NP_GetValue (void* future, NPPVariable variable, void* value)
+{
+ PLUGIN_DEBUG ("NP_GetValue");
+
+ NPError result = NPERR_NO_ERROR;
+ gchar** char_value = (gchar**) value;
+
+ switch (variable)
+ {
+ case NPPVpluginNameString:
+ PLUGIN_DEBUG ("NP_GetValue: returning plugin name.");
+ *char_value = g_strdup (PLUGIN_NAME " " PACKAGE_VERSION);
+ break;
+
+ case NPPVpluginDescriptionString:
+ PLUGIN_DEBUG ("NP_GetValue: returning plugin description.");
+ *char_value = g_strdup (PLUGIN_DESC);
+ break;
+
+ default:
+ PLUGIN_ERROR ("Unknown plugin value requested.");
+ result = NPERR_GENERIC_ERROR;
+ break;
+ }
+
+ PLUGIN_DEBUG ("NP_GetValue return");
+
+ return result;
+}
+
+// Shuts down the plugin. Called after the last plugin instance is
+// destroyed.
+NPError
+NP_Shutdown (void)
+{
+ PLUGIN_DEBUG ("NP_Shutdown");
+
+ // Free mutex.
+ if (plugin_instance_mutex)
+ {
+ g_mutex_free (plugin_instance_mutex);
+ plugin_instance_mutex = NULL;
+ }
+
+ if (whitelist_file)
+ {
+ g_io_channel_close (whitelist_file);
+ whitelist_file = NULL;
+ }
+
+ initialized = false;
+
+ PLUGIN_DEBUG ("NP_Shutdown return");
+
+ return NPERR_NO_ERROR;
+}